Removed unused files.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34223 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,54 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
|
||||||
// by the OpenBeOS license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include "AddOnImage.h"
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
AddOnImage::AddOnImage()
|
|
||||||
: fID(-1)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
AddOnImage::~AddOnImage()
|
|
||||||
{
|
|
||||||
Unload();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load
|
|
||||||
status_t
|
|
||||||
AddOnImage::Load(const char *path)
|
|
||||||
{
|
|
||||||
Unload();
|
|
||||||
status_t error = (path ? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK) {
|
|
||||||
image_id id = load_add_on(path);
|
|
||||||
if (id >= 0)
|
|
||||||
fID = id;
|
|
||||||
else
|
|
||||||
error = id;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unload
|
|
||||||
void
|
|
||||||
AddOnImage::Unload()
|
|
||||||
{
|
|
||||||
if (fID >= 0) {
|
|
||||||
unload_add_on(fID);
|
|
||||||
fID = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetID
|
|
||||||
void
|
|
||||||
AddOnImage::SetID(image_id id)
|
|
||||||
{
|
|
||||||
Unload();
|
|
||||||
if (id >= 0)
|
|
||||||
fID = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
|
||||||
// by the OpenBeOS license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
#ifndef _ADD_ON_IMAGE_H
|
|
||||||
#define _ADD_ON_IMAGE_H
|
|
||||||
|
|
||||||
#include <image.h>
|
|
||||||
|
|
||||||
namespace BPrivate {
|
|
||||||
|
|
||||||
class AddOnImage {
|
|
||||||
public:
|
|
||||||
AddOnImage();
|
|
||||||
~AddOnImage();
|
|
||||||
|
|
||||||
status_t Load(const char *path);
|
|
||||||
void Unload();
|
|
||||||
|
|
||||||
void SetID(image_id id);
|
|
||||||
image_id ID() const { return fID; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
image_id fID;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace BPrivate
|
|
||||||
|
|
||||||
using BPrivate::AddOnImage;
|
|
||||||
|
|
||||||
#endif // _ADD_ON_IMAGE_H
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
#include "AddOnMonitor.h"
|
|
||||||
#include "AddOnMonitorHandler.h"
|
|
||||||
#include <Message.h>
|
|
||||||
#include <MessageRunner.h>
|
|
||||||
#include <Messenger.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
AddOnMonitor::AddOnMonitor(AddOnMonitorHandler * handler)
|
|
||||||
: BLooper("AddOnMonitor")
|
|
||||||
{
|
|
||||||
fInitCheck = B_NO_INIT;
|
|
||||||
AddHandler(handler);
|
|
||||||
SetPreferredHandler(handler);
|
|
||||||
status_t status;
|
|
||||||
BMessenger messenger(handler, this, &status);
|
|
||||||
if (status != B_OK) {
|
|
||||||
fInitCheck = status;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!messenger.IsValid()) {
|
|
||||||
fInitCheck = B_ERROR;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fPulseMessage = new BMessage(B_PULSE);
|
|
||||||
fPulseRunner = new BMessageRunner(messenger, fPulseMessage, 1000000);
|
|
||||||
status = fPulseRunner->InitCheck();
|
|
||||||
if (status != B_OK) {
|
|
||||||
fInitCheck = status;
|
|
||||||
fprintf(stderr, "AddOnMonitor() : bad status returned by fPulseRunner->InitCheck()\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
thread_id id = Run();
|
|
||||||
if (id < 0) {
|
|
||||||
fInitCheck = (status_t)id;
|
|
||||||
fprintf(stderr, "AddOnMonitor() : bad id returned by Run()\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fInitCheck = B_OK;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* virtual */
|
|
||||||
AddOnMonitor::~AddOnMonitor()
|
|
||||||
{
|
|
||||||
delete fPulseMessage;
|
|
||||||
delete fPulseRunner;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ status_t
|
|
||||||
AddOnMonitor::InitCheck()
|
|
||||||
{
|
|
||||||
return fInitCheck;
|
|
||||||
}
|
|
||||||
@@ -1,558 +0,0 @@
|
|||||||
#include "AddOnMonitorHandler.h"
|
|
||||||
#include <Directory.h>
|
|
||||||
|
|
||||||
#ifndef ADD_ON_STABLE_SECONDS
|
|
||||||
#define ADD_ON_STABLE_SECONDS 15
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* public functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
AddOnMonitorHandler::AddOnMonitorHandler(const char * name)
|
|
||||||
: NodeMonitorHandler(name)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
AddOnMonitorHandler::~AddOnMonitorHandler()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ void
|
|
||||||
AddOnMonitorHandler::MessageReceived(BMessage * msg)
|
|
||||||
{
|
|
||||||
if (msg->what == B_PULSE) {
|
|
||||||
HandlePulse();
|
|
||||||
}
|
|
||||||
inherited::MessageReceived(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ status_t
|
|
||||||
AddOnMonitorHandler::AddDirectory(const node_ref * nref)
|
|
||||||
{
|
|
||||||
// ignore directories added twice
|
|
||||||
std::list<add_on_directory_info>::iterator diter = directories.begin();
|
|
||||||
for( ; diter != directories.end() ; diter++) {
|
|
||||||
if (diter->nref == *nref) {
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BDirectory directory(nref);
|
|
||||||
status_t status = directory.InitCheck();
|
|
||||||
if (status != B_OK) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
add_on_directory_info dir_info;
|
|
||||||
dir_info.nref = *nref;
|
|
||||||
directories.push_back(dir_info);
|
|
||||||
|
|
||||||
status = watch_node(nref, B_WATCH_DIRECTORY, this);
|
|
||||||
if (status != B_OK) {
|
|
||||||
directories.pop_back();
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
BEntry entry;
|
|
||||||
while (directory.GetNextEntry(&entry, true) == B_OK) {
|
|
||||||
add_on_entry_info entry_info;
|
|
||||||
if (entry.GetName(entry_info.name) != B_OK) {
|
|
||||||
continue; // discard and proceed
|
|
||||||
}
|
|
||||||
if (entry.GetNodeRef(&entry_info.nref) != B_OK) {
|
|
||||||
continue; // discard and proceed
|
|
||||||
}
|
|
||||||
entry_info.dir_nref = *nref;
|
|
||||||
pending_entries.push_back(entry_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AddOnMonitorHandler hooks
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* virtual */ void
|
|
||||||
AddOnMonitorHandler::AddOnCreated(const add_on_entry_info * entry_info)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ void
|
|
||||||
AddOnMonitorHandler::AddOnEnabled(const add_on_entry_info * entry_info)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ void
|
|
||||||
AddOnMonitorHandler::AddOnDisabled(const add_on_entry_info * entry_info)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ void
|
|
||||||
AddOnMonitorHandler::AddOnRemoved(const add_on_entry_info * entry_info)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NodeMonitorHandler hooks
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ void
|
|
||||||
AddOnMonitorHandler::EntryCreated(const char *name, ino_t directory,
|
|
||||||
dev_t device, ino_t node)
|
|
||||||
{
|
|
||||||
add_on_entry_info entry_info;
|
|
||||||
strncpy(entry_info.name, name, sizeof(entry_info.name));
|
|
||||||
make_node_ref(device, node, &entry_info.nref);
|
|
||||||
make_node_ref(device, directory, &entry_info.dir_nref);
|
|
||||||
pending_entries.push_back(entry_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ void
|
|
||||||
AddOnMonitorHandler::EntryRemoved(ino_t directory, dev_t device, ino_t node)
|
|
||||||
{
|
|
||||||
node_ref entry_nref;
|
|
||||||
make_node_ref(device, node, &entry_nref);
|
|
||||||
|
|
||||||
// Search pending entries first, which can simply be discarded
|
|
||||||
// We might have this entry in the pending list multiple times,
|
|
||||||
// so we search entire list through, even after finding one.
|
|
||||||
std::list<add_on_entry_info>::iterator eiter = pending_entries.begin();
|
|
||||||
while (eiter != pending_entries.end()) {
|
|
||||||
if (eiter->nref == entry_nref) {
|
|
||||||
eiter = pending_entries.erase(eiter);
|
|
||||||
} else {
|
|
||||||
eiter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
add_on_entry_info info;
|
|
||||||
node_ref dir_nref;
|
|
||||||
make_node_ref(device, directory, &dir_nref);
|
|
||||||
|
|
||||||
// find the entry's info, and the entry's directory info
|
|
||||||
std::list<add_on_directory_info>::iterator diter = directories.begin();
|
|
||||||
for( ; diter != directories.end() ; diter++) {
|
|
||||||
if (diter->nref == dir_nref) {
|
|
||||||
std::list<add_on_entry_info>::iterator eiter = diter->entries.begin();
|
|
||||||
for( ; eiter != diter->entries.end() ; eiter++) {
|
|
||||||
info = *eiter;
|
|
||||||
if (eiter->nref == entry_nref) {
|
|
||||||
info = *eiter;
|
|
||||||
diter->entries.erase(eiter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if it was not found, we're done
|
|
||||||
if (diter == directories.end()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start at the top again, and search until the directory we found
|
|
||||||
// the old add_on in. If we find a add_on with the same name then
|
|
||||||
// the old add_on was not enabled. So we deallocate the old
|
|
||||||
// add_on and return.
|
|
||||||
std::list<add_on_directory_info>::iterator diter2 = directories.begin();
|
|
||||||
for( ; diter2 != diter ; diter2++) {
|
|
||||||
std::list<add_on_entry_info>::iterator eiter = diter2->entries.begin();
|
|
||||||
for( ; eiter != diter2->entries.end() ; eiter++) {
|
|
||||||
if (strcmp(eiter->name, info.name) == 0) {
|
|
||||||
AddOnRemoved(&info);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The active plugin was removed. We need to disable and
|
|
||||||
// then subsequently deallocate it.
|
|
||||||
AddOnDisabled(&info);
|
|
||||||
AddOnRemoved(&info);
|
|
||||||
|
|
||||||
// Continue searching for a add_on below us. If we find a add_on
|
|
||||||
// with the same name, we must enable it.
|
|
||||||
for (diter++ ; diter != directories.end() ; diter++) {
|
|
||||||
std::list<add_on_entry_info>::iterator eiter = diter->entries.begin();
|
|
||||||
for( ; eiter != diter->entries.end() ; eiter++) {
|
|
||||||
if (strcmp(eiter->name, info.name) == 0) {
|
|
||||||
AddOnEnabled(&*eiter);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ void
|
|
||||||
AddOnMonitorHandler::EntryMoved(const char *name, ino_t from_directory,
|
|
||||||
ino_t to_directory, dev_t device, ino_t node)
|
|
||||||
{
|
|
||||||
node_ref from_nref;
|
|
||||||
make_node_ref(device, from_directory, &from_nref);
|
|
||||||
std::list<add_on_directory_info>::iterator from_iter = directories.begin();
|
|
||||||
for ( ; from_iter != directories.end() ; from_iter++) {
|
|
||||||
if (from_iter->nref == from_nref) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
node_ref to_nref;
|
|
||||||
make_node_ref(device, to_directory, &to_nref);
|
|
||||||
std::list<add_on_directory_info>::iterator to_iter = directories.begin();
|
|
||||||
for ( ; to_iter != directories.end() ; to_iter++) {
|
|
||||||
if (to_iter->nref == to_nref) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((from_iter == directories.end()) && (to_iter == directories.end())) {
|
|
||||||
// huh? whatever...
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
add_on_entry_info info;
|
|
||||||
node_ref entry_nref;
|
|
||||||
make_node_ref(device, node, &entry_nref);
|
|
||||||
|
|
||||||
if (to_iter == directories.end()) {
|
|
||||||
// moved out of our view
|
|
||||||
std::list<add_on_entry_info>::iterator eiter = from_iter->entries.begin();
|
|
||||||
for( ; eiter != from_iter->entries.end() ; eiter++) {
|
|
||||||
if (entry_nref == eiter->nref) {
|
|
||||||
// save the info and remove the entry
|
|
||||||
info = *eiter;
|
|
||||||
from_iter->entries.erase(eiter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eiter == from_iter->entries.end()) {
|
|
||||||
// we don't know anything about this entry yet.. ignore it
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the name is the same, save the information about this
|
|
||||||
// add_on into former_entries for later use
|
|
||||||
if (strcmp(info.name, name) == 0) {
|
|
||||||
former_entries.push_back(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start at the top again, and search until the from directory.
|
|
||||||
// If we find a add_on with the same name then the moved add_on
|
|
||||||
// was not enabled. So we are done.
|
|
||||||
std::list<add_on_directory_info>::iterator diter = directories.begin();
|
|
||||||
for( ; diter != from_iter ; diter++) {
|
|
||||||
std::list<add_on_entry_info>::iterator eiter2 = diter->entries.begin();
|
|
||||||
for( ; eiter2 != diter->entries.end() ; eiter2++) {
|
|
||||||
if (strcmp(eiter2->name, info.name) == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// finally disable the add_on
|
|
||||||
AddOnDisabled(&info);
|
|
||||||
|
|
||||||
// Continue searching for a add_on below us. If we find a add_on
|
|
||||||
// with the same name, we must enable it.
|
|
||||||
for (from_iter++ ; from_iter != directories.end() ; from_iter++) {
|
|
||||||
std::list<add_on_entry_info>::iterator eiter2 = from_iter->entries.begin();
|
|
||||||
for( ; eiter2 != from_iter->entries.end() ; eiter2++) {
|
|
||||||
if (strcmp(eiter2->name, info.name) == 0) {
|
|
||||||
AddOnEnabled(&*eiter2);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// finally, if the new name is different, destroy the addon
|
|
||||||
if (strcmp(info.name, name) != 0) {
|
|
||||||
AddOnRemoved(&info);
|
|
||||||
}
|
|
||||||
|
|
||||||
// done
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (from_iter == directories.end()) {
|
|
||||||
// moved into our view
|
|
||||||
std::list<add_on_entry_info>::iterator eiter = former_entries.begin();
|
|
||||||
for( ; eiter != former_entries.end() ; eiter++) {
|
|
||||||
if (entry_nref == eiter->nref) {
|
|
||||||
// save the info and remove the entry
|
|
||||||
info = *eiter;
|
|
||||||
former_entries.erase(eiter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eiter != former_entries.end()) {
|
|
||||||
if (strcmp(info.name, name) != 0) {
|
|
||||||
// name changed on the way in, remove the old one
|
|
||||||
AddOnRemoved(&info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the info
|
|
||||||
strncpy(info.name, name, sizeof(info.name));
|
|
||||||
info.nref = entry_nref;
|
|
||||||
info.dir_nref = to_nref;
|
|
||||||
|
|
||||||
if (eiter == former_entries.end()) {
|
|
||||||
// this add_on was not seen before
|
|
||||||
AddOnCreated(&info);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start at the top again, and search until the to directory.
|
|
||||||
// If we find a add_on with the same name then the moved add_on
|
|
||||||
// is not to be enabled. So we are done.
|
|
||||||
std::list<add_on_directory_info>::iterator diter = directories.begin();
|
|
||||||
for( ; diter != to_iter ; diter++) {
|
|
||||||
std::list<add_on_entry_info>::iterator eiter2 = diter->entries.begin();
|
|
||||||
for( ; eiter2 != diter->entries.end() ; eiter2++) {
|
|
||||||
if (strcmp(eiter2->name, info.name) == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The new add_on should be enabled, but first we check to see
|
|
||||||
// if there is an add_on below us. If we find one, we disable it.
|
|
||||||
bool shadowing = false;
|
|
||||||
for (diter++ ; diter != directories.end() ; diter++) {
|
|
||||||
std::list<add_on_entry_info>::iterator eiter2 = diter->entries.begin();
|
|
||||||
for( ; eiter2 != diter->entries.end() ; eiter2++) {
|
|
||||||
if (strcmp(eiter2->name, info.name) == 0) {
|
|
||||||
AddOnDisabled(&*eiter2);
|
|
||||||
shadowing = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (shadowing) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// enable the new add_on
|
|
||||||
AddOnEnabled(&info);
|
|
||||||
|
|
||||||
// put the new entry into the target directory
|
|
||||||
to_iter->entries.push_back(info);
|
|
||||||
|
|
||||||
// done
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<add_on_entry_info>::iterator eiter = from_iter->entries.begin();
|
|
||||||
for( ; eiter != from_iter->entries.end() ; eiter++) {
|
|
||||||
if (entry_nref == eiter->nref) {
|
|
||||||
// save the old info and remove the entry
|
|
||||||
info = *eiter;
|
|
||||||
from_iter->entries.erase(eiter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(info.name, name) == 0) {
|
|
||||||
// same name moved in heirarchy
|
|
||||||
debugger("add_on moved inside the heirarchy");
|
|
||||||
} else {
|
|
||||||
// check to see if it was formerly enabled
|
|
||||||
bool was_enabled = true;
|
|
||||||
std::list<add_on_directory_info>::iterator old_iter = directories.begin();
|
|
||||||
for( ; old_iter != from_iter ; old_iter++) {
|
|
||||||
std::list<add_on_entry_info>::iterator eiter2 = old_iter->entries.begin();
|
|
||||||
for( ; eiter2 != old_iter->entries.end() ; eiter2++) {
|
|
||||||
if (strcmp(eiter2->name, info.name) == 0) {
|
|
||||||
was_enabled = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!was_enabled) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if it was enabled, disable it and enable the one under us, if it exists
|
|
||||||
if (was_enabled) {
|
|
||||||
AddOnDisabled(&info);
|
|
||||||
bool done = false;
|
|
||||||
for( ; old_iter != directories.end() ; old_iter++) {
|
|
||||||
std::list<add_on_entry_info>::iterator eiter2 = old_iter->entries.begin();
|
|
||||||
for( ; eiter2 != old_iter->entries.end() ; eiter2++) {
|
|
||||||
if (strcmp(eiter2->name, info.name) == 0) {
|
|
||||||
AddOnEnabled(&*eiter2);
|
|
||||||
done = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (done) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// kaboom!
|
|
||||||
AddOnRemoved(&info);
|
|
||||||
|
|
||||||
// set up new addon info
|
|
||||||
strncpy(info.name, name, sizeof(info.name));
|
|
||||||
info.dir_nref = to_nref;
|
|
||||||
|
|
||||||
// presto!
|
|
||||||
AddOnCreated(&info);
|
|
||||||
|
|
||||||
// check to see if we are newly enabled
|
|
||||||
bool is_enabled = true;
|
|
||||||
std::list<add_on_directory_info>::iterator new_iter = directories.begin();
|
|
||||||
for( ; new_iter != to_iter ; new_iter++) {
|
|
||||||
std::list<add_on_entry_info>::iterator eiter2 = new_iter->entries.begin();
|
|
||||||
for( ; eiter2 != new_iter->entries.end() ; eiter2++) {
|
|
||||||
if (strcmp(eiter2->name, info.name) == 0) {
|
|
||||||
is_enabled = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!is_enabled) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if it is newly enabled, check under us for an enabled one, and disable that first
|
|
||||||
if (is_enabled) {
|
|
||||||
bool done = false;
|
|
||||||
for( ; new_iter != directories.end() ; new_iter++) {
|
|
||||||
std::list<add_on_entry_info>::iterator eiter2 = new_iter->entries.begin();
|
|
||||||
for( ; eiter2 != new_iter->entries.end() ; eiter2++) {
|
|
||||||
if (strcmp(eiter2->name, info.name) == 0) {
|
|
||||||
AddOnDisabled(&*eiter2);
|
|
||||||
done = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (done) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AddOnEnabled(&info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// put the new entry into the target directory
|
|
||||||
to_iter->entries.push_back(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* process pending entries
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
AddOnMonitorHandler::HandlePulse()
|
|
||||||
{
|
|
||||||
BDirectory directory;
|
|
||||||
std::list<add_on_entry_info>::iterator iter = pending_entries.begin();
|
|
||||||
while (iter != pending_entries.end()) {
|
|
||||||
add_on_entry_info info = *iter;
|
|
||||||
|
|
||||||
node_ref dir_nref;
|
|
||||||
if ((directory.GetNodeRef(&dir_nref) != B_OK) ||
|
|
||||||
(dir_nref != info.dir_nref)) {
|
|
||||||
if (directory.SetTo(&info.dir_nref) != B_OK) {
|
|
||||||
// invalid directory, discard this pending entry
|
|
||||||
iter = pending_entries.erase(iter);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
dir_nref = info.dir_nref;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct stat st;
|
|
||||||
if (directory.GetStatFor(info.name, &st) != B_OK) {
|
|
||||||
// invalid file name, discard this pending entry
|
|
||||||
iter = pending_entries.erase(iter);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// stat units are seconds, real_time_clock units are seconds
|
|
||||||
if (real_time_clock() - st.st_mtime < ADD_ON_STABLE_SECONDS) {
|
|
||||||
// entry not stable, skip the entry for this pulse
|
|
||||||
iter++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we are going to deal with the stable entry, so remove it
|
|
||||||
iter = pending_entries.erase(iter);
|
|
||||||
|
|
||||||
// put the new entry into the directory info
|
|
||||||
std::list<add_on_directory_info>::iterator diter = directories.begin();
|
|
||||||
for( ; diter != directories.end() ; diter++) {
|
|
||||||
if (diter->nref == dir_nref) {
|
|
||||||
diter->entries.push_back(info);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// report it
|
|
||||||
AddOnCreated(&info);
|
|
||||||
|
|
||||||
// Start at the top again, and search until the directory we put
|
|
||||||
// the new add_on in. If we find a add_on with the same name then
|
|
||||||
// the new add_on should not be enabled.
|
|
||||||
bool enabled = true;
|
|
||||||
std::list<add_on_directory_info>::iterator diter2 = directories.begin();
|
|
||||||
for( ; diter2 != diter ; diter2++) {
|
|
||||||
std::list<add_on_entry_info>::iterator eiter = diter2->entries.begin();
|
|
||||||
for( ; eiter != diter2->entries.end() ; eiter++) {
|
|
||||||
if (strcmp(eiter->name, info.name) == 0) {
|
|
||||||
enabled = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!enabled) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!enabled) {
|
|
||||||
// if we are not enabled, go on to the next pending entry
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The new add_on should be enabled, but first we check to see
|
|
||||||
// if there is an add_on below us. If we find one, we disable it.
|
|
||||||
bool shadowing = false;
|
|
||||||
for (diter++ ; diter != directories.end() ; diter++) {
|
|
||||||
std::list<add_on_entry_info>::iterator eiter = diter->entries.begin();
|
|
||||||
for( ; eiter != diter->entries.end() ; eiter++) {
|
|
||||||
if (strcmp(eiter->name, info.name) == 0) {
|
|
||||||
AddOnDisabled(&*eiter);
|
|
||||||
shadowing = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (shadowing) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// finally, enable the new entry
|
|
||||||
AddOnEnabled(&info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,385 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
|
||||||
// by the OpenBeOS license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include <DiskDevice.h>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <new.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <syscalls.h>
|
|
||||||
|
|
||||||
#include <DiskDevice.h>
|
|
||||||
#include <DiskDeviceVisitor.h>
|
|
||||||
#include <Drivers.h>
|
|
||||||
#include <Message.h>
|
|
||||||
#include <Path.h>
|
|
||||||
|
|
||||||
|
|
||||||
/*! \class BDiskDevice
|
|
||||||
\brief A BDiskDevice object represents a storage device.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
/*! \brief Creates an uninitialized BDiskDevice object.
|
|
||||||
*/
|
|
||||||
BDiskDevice::BDiskDevice()
|
|
||||||
: fDeviceData(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
/*! \brief Frees all resources associated with this object.
|
|
||||||
*/
|
|
||||||
BDiskDevice::~BDiskDevice()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsRemovableMedia
|
|
||||||
/*! \brief Returns whether the device media are removable.
|
|
||||||
\return \c true, if the device media are removable, \c false otherwise.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
BDiskDevice::IsRemovableMedia() const
|
|
||||||
{
|
|
||||||
return (fDeviceData
|
|
||||||
&& fDeviceData->device_flags & B_DISK_DEVICE_REMOVABLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsReadOnlyMedia
|
|
||||||
bool
|
|
||||||
BDiskDevice::IsReadOnlyMedia() const
|
|
||||||
{
|
|
||||||
return (fDeviceData
|
|
||||||
&& fDeviceData->device_flags & B_DISK_DEVICE_READ_ONLY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsWriteOnceMedia
|
|
||||||
bool
|
|
||||||
BDiskDevice::IsWriteOnceMedia() const
|
|
||||||
{
|
|
||||||
return (fDeviceData
|
|
||||||
&& fDeviceData->device_flags & B_DISK_DEVICE_WRITE_ONCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTo
|
|
||||||
status_t
|
|
||||||
BDiskDevice::SetTo(partition_id id)
|
|
||||||
{
|
|
||||||
return _SetTo(id, true, false, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
{
|
|
||||||
return _Update(_IsShadow(), updated);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unset
|
|
||||||
void
|
|
||||||
BDiskDevice::Unset()
|
|
||||||
{
|
|
||||||
BPartition::_Unset();
|
|
||||||
free(fDeviceData);
|
|
||||||
fDeviceData = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitCheck
|
|
||||||
status_t
|
|
||||||
BDiskDevice::InitCheck() const
|
|
||||||
{
|
|
||||||
return (fDeviceData ? B_OK : B_NO_INIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPath
|
|
||||||
status_t
|
|
||||||
BDiskDevice::GetPath(BPath *path) const
|
|
||||||
{
|
|
||||||
if (!path || !fDeviceData)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
return path->SetTo(fDeviceData->path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsModified
|
|
||||||
bool
|
|
||||||
BDiskDevice::IsModified() const
|
|
||||||
{
|
|
||||||
return (InitCheck() == B_OK && _IsShadow()
|
|
||||||
&& _kern_is_disk_device_modified(ID()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrepareModifications
|
|
||||||
status_t
|
|
||||||
BDiskDevice::PrepareModifications()
|
|
||||||
{
|
|
||||||
// check initialization
|
|
||||||
status_t error = InitCheck();
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
if (_IsShadow())
|
|
||||||
return B_ERROR;
|
|
||||||
// ask kernel to prepare for modifications
|
|
||||||
error = _kern_prepare_disk_device_modifications(ID());
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
// update
|
|
||||||
error = _Update(true, NULL);
|
|
||||||
if (error != B_OK) {
|
|
||||||
// bad -- cancelling the modifications is all we can do
|
|
||||||
_kern_cancel_disk_device_modifications(ID());
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CommitModifications
|
|
||||||
status_t
|
|
||||||
BDiskDevice::CommitModifications(bool synchronously,
|
|
||||||
BMessenger progressMessenger,
|
|
||||||
bool receiveCompleteProgressUpdates)
|
|
||||||
{
|
|
||||||
status_t error = InitCheck();
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
if (!_IsShadow())
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
// TODO: Get port and token from the progressMessenger
|
|
||||||
port_id port = -1;
|
|
||||||
int32 token = -1;
|
|
||||||
error = _kern_commit_disk_device_modifications(ID(), port, token,
|
|
||||||
receiveCompleteProgressUpdates);
|
|
||||||
if (error == B_OK)
|
|
||||||
error = _SetTo(ID(), true, false, 0);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CancelModifications
|
|
||||||
status_t
|
|
||||||
BDiskDevice::CancelModifications()
|
|
||||||
{
|
|
||||||
status_t error = InitCheck();
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
if (!_IsShadow())
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
error = _kern_cancel_disk_device_modifications(ID());
|
|
||||||
if (error == B_OK)
|
|
||||||
error = _SetTo(ID(), true, false, 0);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy constructor
|
|
||||||
/*! \brief Privatized copy constructor to avoid usage.
|
|
||||||
*/
|
|
||||||
BDiskDevice::BDiskDevice(const BDiskDevice &)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// =
|
|
||||||
/*! \brief Privatized assignment operator to avoid usage.
|
|
||||||
*/
|
|
||||||
BDiskDevice &
|
|
||||||
BDiskDevice::operator=(const BDiskDevice &)
|
|
||||||
{
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _GetData
|
|
||||||
status_t
|
|
||||||
BDiskDevice::_GetData(partition_id id, bool deviceOnly, bool shadow,
|
|
||||||
size_t neededSize, user_disk_device_data **data)
|
|
||||||
{
|
|
||||||
// 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, deviceOnly, shadow,
|
|
||||||
(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 result / cleanup on error
|
|
||||||
if (error == B_OK)
|
|
||||||
*data = (user_disk_device_data*)buffer;
|
|
||||||
else if (buffer)
|
|
||||||
free(buffer);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _SetTo
|
|
||||||
status_t
|
|
||||||
BDiskDevice::_SetTo(partition_id id, bool deviceOnly, bool shadow,
|
|
||||||
size_t neededSize)
|
|
||||||
{
|
|
||||||
Unset();
|
|
||||||
// get the device data
|
|
||||||
user_disk_device_data *data = NULL;
|
|
||||||
status_t error = _GetData(id, deviceOnly, shadow, neededSize, &data);
|
|
||||||
// set the data
|
|
||||||
if (error == B_OK)
|
|
||||||
error = _SetTo(data);
|
|
||||||
// cleanup on error
|
|
||||||
if (error != B_OK && data)
|
|
||||||
free(data);
|
|
||||||
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) {
|
|
||||||
// If _SetTo() fails, the caller retains ownership of the supplied
|
|
||||||
// data. So, unset fDeviceData before calling Unset().
|
|
||||||
fDeviceData = NULL;
|
|
||||||
Unset();
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _Update
|
|
||||||
status_t
|
|
||||||
BDiskDevice::_Update(bool shadow, bool *updated)
|
|
||||||
{
|
|
||||||
if (InitCheck() != B_OK)
|
|
||||||
return InitCheck();
|
|
||||||
// get the device data
|
|
||||||
user_disk_device_data *data = NULL;
|
|
||||||
status_t error = _GetData(ID(), true, shadow, 0, &data);
|
|
||||||
// set the data
|
|
||||||
if (error == B_OK)
|
|
||||||
error = _Update(data, updated);
|
|
||||||
// cleanup on error
|
|
||||||
if (error != B_OK && data)
|
|
||||||
free(data);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _Update
|
|
||||||
status_t
|
|
||||||
BDiskDevice::_Update(user_disk_device_data *data, bool *updated)
|
|
||||||
{
|
|
||||||
if (!data || !fDeviceData || ID() != data->device_partition_data.id)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
bool _updated;
|
|
||||||
if (!updated)
|
|
||||||
updated = &_updated;
|
|
||||||
*updated = false;
|
|
||||||
// remove obsolete partitions
|
|
||||||
status_t error = _RemoveObsoleteDescendants(&data->device_partition_data,
|
|
||||||
updated);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
// update existing partitions and add new ones
|
|
||||||
error = BPartition::_Update(&data->device_partition_data, updated);
|
|
||||||
if (error == B_OK) {
|
|
||||||
user_disk_device_data *oldData = fDeviceData;
|
|
||||||
fDeviceData = data;
|
|
||||||
// check for changes
|
|
||||||
if (data->device_flags != oldData->device_flags
|
|
||||||
|| strcmp(data->path, oldData->path)) {
|
|
||||||
*updated = true;
|
|
||||||
}
|
|
||||||
free(oldData);
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _AcceptVisitor
|
|
||||||
bool
|
|
||||||
BDiskDevice::_AcceptVisitor(BDiskDeviceVisitor *visitor, int32 level)
|
|
||||||
{
|
|
||||||
return visitor->Visit(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
|
||||||
// by the OpenBeOS license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include <syscalls.h>
|
|
||||||
|
|
||||||
#include <DiskDeviceJob.h>
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
BDiskDeviceJob::BDiskDeviceJob()
|
|
||||||
: fID(B_NO_INIT),
|
|
||||||
fType(B_DISK_DEVICE_JOB_BAD_TYPE),
|
|
||||||
fPartitionID(-1),
|
|
||||||
fDescription()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
BDiskDeviceJob::~BDiskDeviceJob()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitCheck
|
|
||||||
status_t
|
|
||||||
BDiskDeviceJob::InitCheck() const
|
|
||||||
{
|
|
||||||
return (fID >= 0 ? B_OK : fID);
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTo
|
|
||||||
status_t
|
|
||||||
BDiskDeviceJob::SetTo(disk_job_id id)
|
|
||||||
{
|
|
||||||
Unset();
|
|
||||||
user_disk_device_job_info info;
|
|
||||||
status_t error = _kern_get_disk_device_job_info(id, &info);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
return _SetTo(&info);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unset
|
|
||||||
void
|
|
||||||
BDiskDeviceJob::Unset()
|
|
||||||
{
|
|
||||||
fID = B_NO_INIT;
|
|
||||||
fType = B_DISK_DEVICE_JOB_BAD_TYPE;
|
|
||||||
fPartitionID = -1;
|
|
||||||
fDescription.SetTo(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID
|
|
||||||
disk_job_id
|
|
||||||
BDiskDeviceJob::ID() const
|
|
||||||
{
|
|
||||||
return fID;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type
|
|
||||||
uint32
|
|
||||||
BDiskDeviceJob::Type() const
|
|
||||||
{
|
|
||||||
return fType;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PartitionID
|
|
||||||
partition_id
|
|
||||||
BDiskDeviceJob::PartitionID() const
|
|
||||||
{
|
|
||||||
return fPartitionID;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Description
|
|
||||||
const char *
|
|
||||||
BDiskDeviceJob::Description() const
|
|
||||||
{
|
|
||||||
return fDescription.String();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Status
|
|
||||||
uint32
|
|
||||||
BDiskDeviceJob::Status() const
|
|
||||||
{
|
|
||||||
if (InitCheck() != B_OK)
|
|
||||||
return B_DISK_DEVICE_JOB_UNINITIALIZED;
|
|
||||||
disk_device_job_progress_info info;
|
|
||||||
status_t error = _kern_get_disk_device_job_progress_info(fID, &info);
|
|
||||||
if (error != B_OK)
|
|
||||||
return B_DISK_DEVICE_JOB_UNINITIALIZED;
|
|
||||||
return info.status;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Progress
|
|
||||||
float
|
|
||||||
BDiskDeviceJob::Progress() const
|
|
||||||
{
|
|
||||||
if (InitCheck() != B_OK)
|
|
||||||
return 0;
|
|
||||||
disk_device_job_progress_info info;
|
|
||||||
status_t error = _kern_get_disk_device_job_progress_info(fID, &info);
|
|
||||||
if (error != B_OK)
|
|
||||||
return 0;
|
|
||||||
if (info.task_count < 1 || info.task_count <= info.completed_tasks)
|
|
||||||
return 1;
|
|
||||||
if (info.current_task_progress < 0)
|
|
||||||
info.current_task_progress = 0;
|
|
||||||
if (info.current_task_progress > 1)
|
|
||||||
info.current_task_progress = 1;
|
|
||||||
return (info.completed_tasks + info.current_task_progress)
|
|
||||||
/ info.task_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetProgressInfo
|
|
||||||
status_t
|
|
||||||
BDiskDeviceJob::GetProgressInfo(disk_device_job_progress_info *info) const
|
|
||||||
{
|
|
||||||
if (InitCheck() != B_OK)
|
|
||||||
return InitCheck();
|
|
||||||
return _kern_get_disk_device_job_progress_info(fID, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
// InterruptProperties
|
|
||||||
uint32
|
|
||||||
BDiskDeviceJob::InterruptProperties() const
|
|
||||||
{
|
|
||||||
if (InitCheck() != B_OK)
|
|
||||||
return 0;
|
|
||||||
disk_device_job_progress_info info;
|
|
||||||
status_t error = _kern_get_disk_device_job_progress_info(fID, &info);
|
|
||||||
if (error != B_OK)
|
|
||||||
return 0;
|
|
||||||
return info.interrupt_properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancel
|
|
||||||
status_t
|
|
||||||
BDiskDeviceJob::Cancel(bool reverse)
|
|
||||||
{
|
|
||||||
if (InitCheck() != B_OK)
|
|
||||||
return InitCheck();
|
|
||||||
return _kern_cancel_disk_device_job(fID, reverse);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pause
|
|
||||||
status_t
|
|
||||||
BDiskDeviceJob::Pause()
|
|
||||||
{
|
|
||||||
if (InitCheck() != B_OK)
|
|
||||||
return InitCheck();
|
|
||||||
return _kern_pause_disk_device_job(fID);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _SetTo
|
|
||||||
status_t
|
|
||||||
BDiskDeviceJob::_SetTo(user_disk_device_job_info *info)
|
|
||||||
{
|
|
||||||
Unset();
|
|
||||||
if (!info)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
fID = info->id;
|
|
||||||
fType = info->type;
|
|
||||||
fPartitionID = info->partition;
|
|
||||||
fDescription.SetTo(info->description);
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,832 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
|
||||||
// by the OpenBeOS license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include <new.h>
|
|
||||||
|
|
||||||
#include <DiskDevice.h>
|
|
||||||
#include <DiskDeviceList.h>
|
|
||||||
#include <DiskDevicePrivate.h>
|
|
||||||
#include <DiskDeviceRoster.h>
|
|
||||||
#include <Locker.h>
|
|
||||||
#include <Looper.h>
|
|
||||||
#include <ObjectLocker.h>
|
|
||||||
#include <Partition.h>
|
|
||||||
#include <Session.h>
|
|
||||||
|
|
||||||
using BPrivate::BObjectLocker;
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
/*! \brief Creates an empty BDiskDeviceList object.
|
|
||||||
*/
|
|
||||||
BDiskDeviceList::BDiskDeviceList(bool useOwnLocker)
|
|
||||||
: fLocker(NULL),
|
|
||||||
fDevices(20, true),
|
|
||||||
fSubscribed(false)
|
|
||||||
{
|
|
||||||
if (useOwnLocker)
|
|
||||||
fLocker = new(nothrow) BLocker;
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
/*! \brief Frees all resources associated with the object.
|
|
||||||
*/
|
|
||||||
BDiskDeviceList::~BDiskDeviceList()
|
|
||||||
{
|
|
||||||
if (fLocker)
|
|
||||||
delete fLocker;
|
|
||||||
}
|
|
||||||
|
|
||||||
// MessageReceived
|
|
||||||
/*! \brief Implemented to handle notification messages.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::MessageReceived(BMessage *message)
|
|
||||||
{
|
|
||||||
BObjectLocker<BDiskDeviceList> _(this);
|
|
||||||
switch (message->what) {
|
|
||||||
case B_DEVICE_UPDATE:
|
|
||||||
{
|
|
||||||
uint32 event;
|
|
||||||
if (message->FindInt32("event", (int32*)&event) == B_OK) {
|
|
||||||
switch (event) {
|
|
||||||
case B_DEVICE_MOUNT_POINT_MOVED:
|
|
||||||
_MountPointMoved(message);
|
|
||||||
break;
|
|
||||||
case B_DEVICE_PARTITION_MOUNTED:
|
|
||||||
_PartitionMounted(message);
|
|
||||||
break;
|
|
||||||
case B_DEVICE_PARTITION_UNMOUNTED:
|
|
||||||
_PartitionUnmounted(message);
|
|
||||||
break;
|
|
||||||
case B_DEVICE_PARTITION_INITIALIZED:
|
|
||||||
_PartitionInitialized(message);
|
|
||||||
break;
|
|
||||||
case B_DEVICE_PARTITION_RESIZED:
|
|
||||||
_PartitionResized(message);
|
|
||||||
break;
|
|
||||||
case B_DEVICE_PARTITION_MOVED:
|
|
||||||
_PartitionMoved(message);
|
|
||||||
break;
|
|
||||||
case B_DEVICE_PARTITION_CREATED:
|
|
||||||
_PartitionCreated(message);
|
|
||||||
break;
|
|
||||||
case B_DEVICE_PARTITION_DELETED:
|
|
||||||
_PartitionDeleted(message);
|
|
||||||
break;
|
|
||||||
case B_DEVICE_PARTITION_DEFRAGMENTED:
|
|
||||||
_PartitionDefragmented(message);
|
|
||||||
break;
|
|
||||||
case B_DEVICE_PARTITION_REPAIRED:
|
|
||||||
_PartitionRepaired(message);
|
|
||||||
break;
|
|
||||||
case B_DEVICE_MEDIA_CHANGED:
|
|
||||||
_MediaChanged(message);
|
|
||||||
break;
|
|
||||||
case B_DEVICE_ADDED:
|
|
||||||
_DeviceAdded(message);
|
|
||||||
break;
|
|
||||||
case B_DEVICE_REMOVED:
|
|
||||||
_DeviceRemoved(message);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
BHandler::MessageReceived(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetNextHandler
|
|
||||||
/*! \brief Implemented to unsubscribe from notification services when going
|
|
||||||
to be detached from looper.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::SetNextHandler(BHandler *handler)
|
|
||||||
{
|
|
||||||
if (!handler) {
|
|
||||||
BObjectLocker<BDiskDeviceList> _(this);
|
|
||||||
if (fSubscribed)
|
|
||||||
_StopWatching();
|
|
||||||
}
|
|
||||||
BHandler::SetNextHandler(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch
|
|
||||||
/*! \brief Empties the list and refills it according to the current state.
|
|
||||||
|
|
||||||
Furthermore, if added to a looper, the list subscribes to notification
|
|
||||||
services needed to keep the list up-to-date.
|
|
||||||
|
|
||||||
If an error occurs, the list Unset()s itself.
|
|
||||||
|
|
||||||
The object doesn't need to be locked, when this method is invoked. The
|
|
||||||
method does itself try to lock the list, but doesn't fail, if that
|
|
||||||
doesn't succeed. That way an object can be used without locking in a
|
|
||||||
single threaded environment.
|
|
||||||
|
|
||||||
\return \c B_OK, if everything went fine, another error code otherwise.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskDeviceList::Fetch()
|
|
||||||
{
|
|
||||||
Unset();
|
|
||||||
BObjectLocker<BDiskDeviceList> _(this);
|
|
||||||
// register for notifications
|
|
||||||
status_t error = B_OK;
|
|
||||||
if (Looper())
|
|
||||||
error = _StartWatching();
|
|
||||||
// get the devices
|
|
||||||
BDiskDeviceRoster roster;
|
|
||||||
while (error == B_OK) {
|
|
||||||
if (BDiskDevice *device = new(nothrow) BDiskDevice) {
|
|
||||||
status_t status = roster.GetNextDevice(device);
|
|
||||||
if (status == B_OK)
|
|
||||||
fDevices.AddItem(device);
|
|
||||||
else if (status == B_ENTRY_NOT_FOUND)
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
error = status;
|
|
||||||
} else
|
|
||||||
error = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
// cleanup on error
|
|
||||||
if (error != B_OK)
|
|
||||||
Unset();
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unset
|
|
||||||
/*! \brief Empties the list and unsubscribes from all notification services.
|
|
||||||
|
|
||||||
The object doesn't need to be locked, when this method is invoked. The
|
|
||||||
method does itself try to lock the list, but doesn't fail, if that
|
|
||||||
doesn't succeed. That way an object can be used without locking in a
|
|
||||||
single threaded environment.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::Unset()
|
|
||||||
{
|
|
||||||
BObjectLocker<BDiskDeviceList> _(this);
|
|
||||||
// unsubscribe from notification services
|
|
||||||
_StopWatching();
|
|
||||||
// empty the list
|
|
||||||
fDevices.MakeEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lock
|
|
||||||
/*! \brief Locks the list.
|
|
||||||
|
|
||||||
If on construction it had been specified, that the list shall use an
|
|
||||||
own BLocker, then this locker is locked, otherwise LockLooper() is
|
|
||||||
invoked.
|
|
||||||
|
|
||||||
\return \c true, if the list could be locked successfully, \c false
|
|
||||||
otherwise.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
BDiskDeviceList::Lock()
|
|
||||||
{
|
|
||||||
if (fLocker)
|
|
||||||
return fLocker->Lock();
|
|
||||||
return LockLooper();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unlock
|
|
||||||
/*! \brief Unlocks the list.
|
|
||||||
|
|
||||||
If on construction it had been specified, that the list shall use an
|
|
||||||
own BLocker, then this locker is unlocked, otherwise UnlockLooper() is
|
|
||||||
invoked.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::Unlock()
|
|
||||||
{
|
|
||||||
if (fLocker)
|
|
||||||
return fLocker->Unlock();
|
|
||||||
return UnlockLooper();
|
|
||||||
}
|
|
||||||
|
|
||||||
// CountDevices
|
|
||||||
/*! \brief Returns the number of devices in the list.
|
|
||||||
|
|
||||||
The list must be locked.
|
|
||||||
|
|
||||||
\return The number of devices in the list.
|
|
||||||
*/
|
|
||||||
int32
|
|
||||||
BDiskDeviceList::CountDevices() const
|
|
||||||
{
|
|
||||||
return fDevices.CountItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeviceAt
|
|
||||||
/*! \brief Retrieves a device by index.
|
|
||||||
|
|
||||||
The list must be locked.
|
|
||||||
|
|
||||||
\param index The list index of the device to be returned.
|
|
||||||
\return The device with index \a index, or \c NULL, if the list is not
|
|
||||||
locked or \a index is out of range.
|
|
||||||
*/
|
|
||||||
BDiskDevice *
|
|
||||||
BDiskDeviceList::DeviceAt(int32 index) const
|
|
||||||
{
|
|
||||||
return fDevices.ItemAt(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
// VisitEachDevice
|
|
||||||
/*! \brief Iterates through the all devices in the list.
|
|
||||||
|
|
||||||
The supplied visitor's Visit(BDiskDevice*) is invoked for each device.
|
|
||||||
If Visit() returns \c true, the iteration is terminated and this method
|
|
||||||
returns the respective device.
|
|
||||||
|
|
||||||
The list must be locked.
|
|
||||||
|
|
||||||
\param visitor The visitor.
|
|
||||||
\return The respective device, if the iteration was terminated early,
|
|
||||||
\c NULL otherwise.
|
|
||||||
*/
|
|
||||||
BDiskDevice *
|
|
||||||
BDiskDeviceList::VisitEachDevice(BDiskDeviceVisitor *visitor)
|
|
||||||
{
|
|
||||||
if (visitor) {
|
|
||||||
for (int32 i = 0; BDiskDevice *device = DeviceAt(i); i++) {
|
|
||||||
if (visitor->Visit(device))
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VisitEachPartition
|
|
||||||
/*! \brief Iterates through the all devices' partitions.
|
|
||||||
|
|
||||||
The supplied visitor's Visit(BPartition*) is invoked for each partition.
|
|
||||||
If Visit() returns \c true, the iteration is terminated and this method
|
|
||||||
returns the respective partition.
|
|
||||||
|
|
||||||
The list must be locked.
|
|
||||||
|
|
||||||
\param visitor The visitor.
|
|
||||||
\return The respective partition, if the iteration was terminated early,
|
|
||||||
\c NULL otherwise.
|
|
||||||
*/
|
|
||||||
BPartition *
|
|
||||||
BDiskDeviceList::VisitEachPartition(BDiskDeviceVisitor *visitor)
|
|
||||||
{
|
|
||||||
if (visitor) {
|
|
||||||
for (int32 i = 0; BDiskDevice *device = DeviceAt(i); i++) {
|
|
||||||
if (BPartition *partition = device->VisitEachDescendant(visitor))
|
|
||||||
return partition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VisitEachMountedPartition
|
|
||||||
/*! \brief Iterates through the all devices' partitions that are mounted.
|
|
||||||
|
|
||||||
The supplied visitor's Visit(BPartition*) is invoked for each mounted
|
|
||||||
partition.
|
|
||||||
If Visit() returns \c true, the iteration is terminated and this method
|
|
||||||
returns the respective partition.
|
|
||||||
|
|
||||||
The list must be locked.
|
|
||||||
|
|
||||||
\param visitor The visitor.
|
|
||||||
\return The respective partition, if the iteration was terminated early,
|
|
||||||
\c NULL otherwise.
|
|
||||||
*/
|
|
||||||
BPartition *
|
|
||||||
BDiskDeviceList::VisitEachMountedPartition(BDiskDeviceVisitor *visitor)
|
|
||||||
{
|
|
||||||
BPartition *partition = NULL;
|
|
||||||
if (visitor) {
|
|
||||||
struct MountedPartitionFilter : public PartitionFilter {
|
|
||||||
virtual bool Filter(BPartition *partition, int32 level)
|
|
||||||
{ return partition->IsMounted(); }
|
|
||||||
} filter;
|
|
||||||
PartitionFilterVisitor filterVisitor(visitor, &filter);
|
|
||||||
partition = VisitEachPartition(&filterVisitor);
|
|
||||||
}
|
|
||||||
return partition;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VisitEachMountablePartition
|
|
||||||
/*! \brief Iterates through the all devices' partitions that are mountable.
|
|
||||||
|
|
||||||
The supplied visitor's Visit(BPartition*) is invoked for each mountable
|
|
||||||
partition.
|
|
||||||
If Visit() returns \c true, the iteration is terminated and this method
|
|
||||||
returns the respective partition.
|
|
||||||
|
|
||||||
The list must be locked.
|
|
||||||
|
|
||||||
\param visitor The visitor.
|
|
||||||
\return The respective partition, if the iteration was terminated early,
|
|
||||||
\c NULL otherwise.
|
|
||||||
*/
|
|
||||||
BPartition *
|
|
||||||
BDiskDeviceList::VisitEachMountablePartition(BDiskDeviceVisitor *visitor)
|
|
||||||
{
|
|
||||||
BPartition *partition = NULL;
|
|
||||||
if (visitor) {
|
|
||||||
struct MountablePartitionFilter : public PartitionFilter {
|
|
||||||
virtual bool Filter(BPartition *partition, int32 level)
|
|
||||||
{ return partition->ContainsFileSystem(); }
|
|
||||||
} filter;
|
|
||||||
PartitionFilterVisitor filterVisitor(visitor, &filter);
|
|
||||||
partition = VisitEachPartition(&filterVisitor);
|
|
||||||
}
|
|
||||||
return partition;
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeviceWithID
|
|
||||||
/*! \brief Retrieves a device by ID.
|
|
||||||
|
|
||||||
The list must be locked.
|
|
||||||
|
|
||||||
\param id The ID of the device to be returned.
|
|
||||||
\return The device with ID \a id, or \c NULL, if the list is not
|
|
||||||
locked or no device with ID \a id is in the list.
|
|
||||||
*/
|
|
||||||
BDiskDevice *
|
|
||||||
BDiskDeviceList::DeviceWithID(int32 id) const
|
|
||||||
{
|
|
||||||
IDFinderVisitor visitor(id);
|
|
||||||
return const_cast<BDiskDeviceList*>(this)->VisitEachDevice(&visitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PartitionWithID
|
|
||||||
/*! \brief Retrieves a partition by ID.
|
|
||||||
|
|
||||||
The list must be locked.
|
|
||||||
|
|
||||||
\param id The ID of the partition to be returned.
|
|
||||||
\return The partition with ID \a id, or \c NULL, if the list is not
|
|
||||||
locked or no partition with ID \a id is in the list.
|
|
||||||
*/
|
|
||||||
BPartition *
|
|
||||||
BDiskDeviceList::PartitionWithID(int32 id) const
|
|
||||||
{
|
|
||||||
IDFinderVisitor visitor(id);
|
|
||||||
return const_cast<BDiskDeviceList*>(this)->VisitEachPartition(&visitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// MountPointMoved
|
|
||||||
/*! \brief Invoked, when the mount point of a partition has been moved.
|
|
||||||
|
|
||||||
The list is locked, when this method is invoked.
|
|
||||||
|
|
||||||
\param partition The concerned partition.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::MountPointMoved(BPartition *partition)
|
|
||||||
{
|
|
||||||
PartitionChanged(partition, B_DEVICE_MOUNT_POINT_MOVED);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PartitionMounted
|
|
||||||
/*! \brief Invoked, when a partition has been mounted.
|
|
||||||
|
|
||||||
The list is locked, when this method is invoked.
|
|
||||||
|
|
||||||
\param partition The concerned partition.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::PartitionMounted(BPartition *partition)
|
|
||||||
{
|
|
||||||
PartitionChanged(partition, B_DEVICE_PARTITION_MOUNTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PartitionUnmounted
|
|
||||||
/*! \brief Invoked, when a partition has been unmounted.
|
|
||||||
|
|
||||||
The list is locked, when this method is invoked.
|
|
||||||
|
|
||||||
\param partition The concerned partition.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::PartitionUnmounted(BPartition *partition)
|
|
||||||
{
|
|
||||||
PartitionChanged(partition, B_DEVICE_PARTITION_UNMOUNTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PartitionInitialized
|
|
||||||
/*! \brief Invoked, when a partition has been initialized.
|
|
||||||
|
|
||||||
The list is locked, when this method is invoked.
|
|
||||||
|
|
||||||
\param partition The concerned partition.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::PartitionInitialized(BPartition *partition)
|
|
||||||
{
|
|
||||||
PartitionChanged(partition, B_DEVICE_PARTITION_INITIALIZED);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PartitionResized
|
|
||||||
/*! \brief Invoked, when a partition has been resized.
|
|
||||||
|
|
||||||
The list is locked, when this method is invoked.
|
|
||||||
|
|
||||||
\param partition The concerned partition.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::PartitionResized(BPartition *partition)
|
|
||||||
{
|
|
||||||
PartitionChanged(partition, B_DEVICE_PARTITION_RESIZED);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PartitionMoved
|
|
||||||
/*! \brief Invoked, when a partition has been moved.
|
|
||||||
|
|
||||||
The list is locked, when this method is invoked.
|
|
||||||
|
|
||||||
\param partition The concerned partition.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::PartitionMoved(BPartition *partition)
|
|
||||||
{
|
|
||||||
PartitionChanged(partition, B_DEVICE_PARTITION_MOVED);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PartitionCreated
|
|
||||||
/*! \brief Invoked, when a partition has been created.
|
|
||||||
|
|
||||||
The list is locked, when this method is invoked.
|
|
||||||
|
|
||||||
\param partition The concerned partition.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::PartitionCreated(BPartition *partition)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// PartitionDeleted
|
|
||||||
/*! \brief Invoked, when a partition has been deleted.
|
|
||||||
|
|
||||||
The method is called twice for a deleted partition. The first time
|
|
||||||
before the BDiskDevice the partition belongs to has been updated. The
|
|
||||||
\a partition parameter will point to a still valid BPartition object.
|
|
||||||
On the second invocation the device object will have been updated and
|
|
||||||
the partition object will have been deleted -- \a partition will be
|
|
||||||
\c NULL then.
|
|
||||||
|
|
||||||
The list is locked, when this method is invoked.
|
|
||||||
|
|
||||||
\param partition The concerned partition. Only non- \c NULL on the first
|
|
||||||
invocation.
|
|
||||||
\param partitionID The ID of the concerned partition.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::PartitionDeleted(BPartition *partition,
|
|
||||||
partition_id partitionID)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// PartitionDefragmented
|
|
||||||
/*! \brief Invoked, when a partition has been defragmented.
|
|
||||||
|
|
||||||
The list is locked, when this method is invoked.
|
|
||||||
|
|
||||||
\param partition The concerned partition.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::PartitionDefragmented(BPartition *partition)
|
|
||||||
{
|
|
||||||
PartitionChanged(partition, B_DEVICE_PARTITION_DEFRAGMENTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PartitionRepaired
|
|
||||||
/*! \brief Invoked, when a partition has been repaired.
|
|
||||||
|
|
||||||
The list is locked, when this method is invoked.
|
|
||||||
|
|
||||||
\param partition The concerned partition.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::PartitionRepaired(BPartition *partition)
|
|
||||||
{
|
|
||||||
PartitionChanged(partition, B_DEVICE_PARTITION_REPAIRED);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PartitionChanged
|
|
||||||
/*! \brief Catch-all method invoked by the \c Partition*() hooks, save by
|
|
||||||
PartitionCreated() and PartitionDeleted().
|
|
||||||
|
|
||||||
If you're interested only in the fact, that something about the partition
|
|
||||||
changed, you can just override this hook instead of the ones telling you
|
|
||||||
exactly what happened.
|
|
||||||
|
|
||||||
\param partition The concerned partition.
|
|
||||||
\param event The event that occurred, if you are interested in it after all.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::PartitionChanged(BPartition *partition, uint32 event)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// MediaChanged
|
|
||||||
/*! \brief Invoked, when the media of a device has been changed.
|
|
||||||
|
|
||||||
The list is locked, when this method is invoked.
|
|
||||||
|
|
||||||
\param device The concerned device.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::MediaChanged(BDiskDevice *device)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeviceAdded
|
|
||||||
/*! \brief Invoked, when a device has been added.
|
|
||||||
|
|
||||||
The list is locked, when this method is invoked.
|
|
||||||
|
|
||||||
\param device The concerned device.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::DeviceAdded(BDiskDevice *device)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeviceRemoved
|
|
||||||
/*! \brief Invoked, when a device has been removed.
|
|
||||||
|
|
||||||
The supplied object is already removed from the list and is going to be
|
|
||||||
deleted after the hook returns.
|
|
||||||
|
|
||||||
The list is locked, when this method is invoked.
|
|
||||||
|
|
||||||
\param device The concerned device.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::DeviceRemoved(BDiskDevice *device)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// _StartWatching
|
|
||||||
/*! \brief Starts watching for disk device notifications.
|
|
||||||
|
|
||||||
The object must be locked (if possible at all), when this method is
|
|
||||||
invoked.
|
|
||||||
|
|
||||||
\return \c B_OK, if everything went fine, another error code otherwise.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskDeviceList::_StartWatching()
|
|
||||||
{
|
|
||||||
if (!Looper() || fSubscribed)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
status_t error = BDiskDeviceRoster().StartWatching(BMessenger(this));
|
|
||||||
fSubscribed = (error == B_OK);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _StopWatching
|
|
||||||
/*! \brief Stop watching for disk device notifications.
|
|
||||||
|
|
||||||
The object must be locked (if possible at all), when this method is
|
|
||||||
invoked.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::_StopWatching()
|
|
||||||
{
|
|
||||||
if (fSubscribed) {
|
|
||||||
BDiskDeviceRoster().StopWatching(BMessenger(this));
|
|
||||||
fSubscribed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// _MountPointMoved
|
|
||||||
/*! \brief Handles a "mount point moved" message.
|
|
||||||
\param message The respective notification message.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::_MountPointMoved(BMessage *message)
|
|
||||||
{
|
|
||||||
if (BDiskDevice *device = _UpdateDevice(message)) {
|
|
||||||
if (BPartition *partition = _FindPartition(message))
|
|
||||||
MountPointMoved(partition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// _PartitionMounted
|
|
||||||
/*! \brief Handles a "partition mounted" message.
|
|
||||||
\param message The respective notification message.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::_PartitionMounted(BMessage *message)
|
|
||||||
{
|
|
||||||
if (BDiskDevice *device = _UpdateDevice(message)) {
|
|
||||||
if (BPartition *partition = _FindPartition(message))
|
|
||||||
PartitionMounted(partition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// _PartitionUnmounted
|
|
||||||
/*! \brief Handles a "partition unmounted" message.
|
|
||||||
\param message The respective notification message.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::_PartitionUnmounted(BMessage *message)
|
|
||||||
{
|
|
||||||
if (BDiskDevice *device = _UpdateDevice(message)) {
|
|
||||||
if (BPartition *partition = _FindPartition(message))
|
|
||||||
PartitionUnmounted(partition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// _PartitionInitialized
|
|
||||||
/*! \brief Handles a "partition initialized" message.
|
|
||||||
\param message The respective notification message.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::_PartitionInitialized(BMessage *message)
|
|
||||||
{
|
|
||||||
if (BDiskDevice *device = _UpdateDevice(message)) {
|
|
||||||
if (BPartition *partition = _FindPartition(message))
|
|
||||||
PartitionInitialized(partition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// _PartitionResized
|
|
||||||
/*! \brief Handles a "partition resized" message.
|
|
||||||
\param message The respective notification message.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::_PartitionResized(BMessage *message)
|
|
||||||
{
|
|
||||||
if (BDiskDevice *device = _UpdateDevice(message)) {
|
|
||||||
if (BPartition *partition = _FindPartition(message))
|
|
||||||
PartitionResized(partition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// _PartitionMoved
|
|
||||||
/*! \brief Handles a "partition moved" message.
|
|
||||||
\param message The respective notification message.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::_PartitionMoved(BMessage *message)
|
|
||||||
{
|
|
||||||
if (BDiskDevice *device = _UpdateDevice(message)) {
|
|
||||||
if (BPartition *partition = _FindPartition(message))
|
|
||||||
PartitionMoved(partition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// _PartitionCreated
|
|
||||||
/*! \brief Handles a "partition created" message.
|
|
||||||
\param message The respective notification message.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::_PartitionCreated(BMessage *message)
|
|
||||||
{
|
|
||||||
if (BDiskDevice *device = _UpdateDevice(message)) {
|
|
||||||
if (BPartition *partition = _FindPartition(message))
|
|
||||||
PartitionCreated(partition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// _PartitionDeleted
|
|
||||||
/*! \brief Handles a "partition deleted" message.
|
|
||||||
\param message The respective notification message.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::_PartitionDeleted(BMessage *message)
|
|
||||||
{
|
|
||||||
if (BPartition *partition = _FindPartition(message)) {
|
|
||||||
partition_id id = partition->ID();
|
|
||||||
PartitionDeleted(partition, id);
|
|
||||||
if (_UpdateDevice(message))
|
|
||||||
PartitionDeleted(NULL, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// _PartitionDefragmented
|
|
||||||
/*! \brief Handles a "partition defragmented" message.
|
|
||||||
\param message The respective notification message.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::_PartitionDefragmented(BMessage *message)
|
|
||||||
{
|
|
||||||
if (BDiskDevice *device = _UpdateDevice(message)) {
|
|
||||||
if (BPartition *partition = _FindPartition(message))
|
|
||||||
PartitionDefragmented(partition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// _PartitionRepaired
|
|
||||||
/*! \brief Handles a "partition repaired" message.
|
|
||||||
\param message The respective notification message.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::_PartitionRepaired(BMessage *message)
|
|
||||||
{
|
|
||||||
if (BDiskDevice *device = _UpdateDevice(message)) {
|
|
||||||
if (BPartition *partition = _FindPartition(message))
|
|
||||||
PartitionRepaired(partition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// _MediaChanged
|
|
||||||
/*! \brief Handles a "media changed" message.
|
|
||||||
\param message The respective notification message.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::_MediaChanged(BMessage *message)
|
|
||||||
{
|
|
||||||
if (BDiskDevice *device = _UpdateDevice(message))
|
|
||||||
MediaChanged(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _DeviceAdded
|
|
||||||
/*! \brief Handles a "device added" message.
|
|
||||||
\param message The respective notification message.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::_DeviceAdded(BMessage *message)
|
|
||||||
{
|
|
||||||
int32 id;
|
|
||||||
if (message->FindInt32("device_id", &id) == B_OK && !DeviceWithID(id)) {
|
|
||||||
BDiskDevice *device = new(nothrow) BDiskDevice;
|
|
||||||
if (BDiskDeviceRoster().GetDeviceWithID(id, device) == B_OK) {
|
|
||||||
fDevices.AddItem(device);
|
|
||||||
DeviceAdded(device);
|
|
||||||
} else
|
|
||||||
delete device;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// _DeviceRemoved
|
|
||||||
/*! \brief Handles a "device removed" message.
|
|
||||||
\param message The respective notification message.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BDiskDeviceList::_DeviceRemoved(BMessage *message)
|
|
||||||
{
|
|
||||||
if (BDiskDevice *device = _FindDevice(message)) {
|
|
||||||
fDevices.RemoveItem(device, false);
|
|
||||||
DeviceRemoved(device);
|
|
||||||
delete device;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// _FindDevice
|
|
||||||
/*! \brief Returns the device for the ID contained in a motification message.
|
|
||||||
\param message The notification message.
|
|
||||||
\return The device with the ID, or \c NULL, if the ID or the device could
|
|
||||||
not be found.
|
|
||||||
*/
|
|
||||||
BDiskDevice *
|
|
||||||
BDiskDeviceList::_FindDevice(BMessage *message)
|
|
||||||
{
|
|
||||||
BDiskDevice *device = NULL;
|
|
||||||
int32 id;
|
|
||||||
if (message->FindInt32("device_id", &id) == B_OK)
|
|
||||||
device = DeviceWithID(id);
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _FindPartition
|
|
||||||
/*! \brief Returns the partition for the ID contained in a motification
|
|
||||||
message.
|
|
||||||
\param message The notification message.
|
|
||||||
\return The partition with the ID, or \c NULL, if the ID or the partition
|
|
||||||
could not be found.*/
|
|
||||||
BPartition *
|
|
||||||
BDiskDeviceList::_FindPartition(BMessage *message)
|
|
||||||
{
|
|
||||||
BPartition *partition = NULL;
|
|
||||||
int32 id;
|
|
||||||
if (message->FindInt32("partition_id", &id) == B_OK)
|
|
||||||
partition = PartitionWithID(id);
|
|
||||||
return partition;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _UpdateDevice
|
|
||||||
/*! \brief Finds the device for the ID contained in a motification message
|
|
||||||
and updates it.
|
|
||||||
\param message The notification message.
|
|
||||||
\return The device with the ID, or \c NULL, if the ID or the device could
|
|
||||||
not be found.
|
|
||||||
*/
|
|
||||||
BDiskDevice *
|
|
||||||
BDiskDeviceList::_UpdateDevice(BMessage *message)
|
|
||||||
{
|
|
||||||
BDiskDevice *device = _FindDevice(message);
|
|
||||||
if (device) {
|
|
||||||
if (device->Update() != B_OK) {
|
|
||||||
fDevices.RemoveItem(device);
|
|
||||||
device = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
|
||||||
// by the OpenBeOS license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include <DiskDevicePrivate.h>
|
|
||||||
#include <DiskDevice.h>
|
|
||||||
#include <Partition.h>
|
|
||||||
|
|
||||||
// PartitionFilterVisitor
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
PartitionFilterVisitor::PartitionFilterVisitor(BDiskDeviceVisitor *visitor,
|
|
||||||
PartitionFilter *filter)
|
|
||||||
: BDiskDeviceVisitor(),
|
|
||||||
fVisitor(visitor),
|
|
||||||
fFilter(filter)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Visit
|
|
||||||
bool
|
|
||||||
PartitionFilterVisitor::Visit(BDiskDevice *device)
|
|
||||||
{
|
|
||||||
if (fFilter->Filter(device, 0))
|
|
||||||
return fVisitor->Visit(device);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Visit
|
|
||||||
bool
|
|
||||||
PartitionFilterVisitor::Visit(BPartition *partition, int32 level)
|
|
||||||
{
|
|
||||||
if (fFilter->Filter(partition, level))
|
|
||||||
return fVisitor->Visit(partition, level);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
|
||||||
|
|
||||||
// IDFinderVisitor
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
IDFinderVisitor::IDFinderVisitor(int32 id)
|
|
||||||
: BDiskDeviceVisitor(),
|
|
||||||
fID(id)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Visit
|
|
||||||
bool
|
|
||||||
IDFinderVisitor::Visit(BDiskDevice *device)
|
|
||||||
{
|
|
||||||
return (device->ID() == fID);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Visit
|
|
||||||
bool
|
|
||||||
IDFinderVisitor::Visit(BPartition *partition, int32 level)
|
|
||||||
{
|
|
||||||
return (partition->ID() == fID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,870 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
|
||||||
// by the OpenBeOS license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include <syscalls.h>
|
|
||||||
|
|
||||||
#include <Directory.h>
|
|
||||||
#include <DiskDevice.h>
|
|
||||||
#include <DiskDeviceJob.h>
|
|
||||||
#include <DiskDevicePrivate.h>
|
|
||||||
#include <DiskDeviceRoster.h>
|
|
||||||
#include <DiskSystem.h>
|
|
||||||
#include <Entry.h>
|
|
||||||
#include <FindDirectory.h>
|
|
||||||
#include <Message.h>
|
|
||||||
#include <Partition.h>
|
|
||||||
#include <Path.h>
|
|
||||||
|
|
||||||
//#include "AddOnImage.h"
|
|
||||||
|
|
||||||
/*! \class BDiskDeviceRoster
|
|
||||||
\brief An interface for iterating through the disk devices known to the
|
|
||||||
system and for a notification mechanism provided to listen to their
|
|
||||||
changes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! \brief find_directory constants of the add-on dirs to be searched. */
|
|
||||||
static const directory_which kAddOnDirs[] = {
|
|
||||||
B_USER_ADDONS_DIRECTORY,
|
|
||||||
// B_COMMON_ADDONS_DIRECTORY,
|
|
||||||
B_BEOS_ADDONS_DIRECTORY
|
|
||||||
};
|
|
||||||
/*! \brief Size of the kAddOnDirs array. */
|
|
||||||
static const int32 kAddOnDirCount
|
|
||||||
= sizeof(kAddOnDirs) / sizeof(directory_which);
|
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
/*! \brief Creates a BDiskDeviceRoster object.
|
|
||||||
|
|
||||||
The object is ready to be used after construction.
|
|
||||||
*/
|
|
||||||
BDiskDeviceRoster::BDiskDeviceRoster()
|
|
||||||
: fDeviceCookie(0),
|
|
||||||
fDiskSystemCookie(0),
|
|
||||||
fJobCookie(0)
|
|
||||||
// fPartitionAddOnDir(NULL),
|
|
||||||
// fFSAddOnDir(NULL),
|
|
||||||
// fPartitionAddOnDirIndex(0),
|
|
||||||
// fFSAddOnDirIndex(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
/*! \brief Frees all resources associated with the object.
|
|
||||||
*/
|
|
||||||
BDiskDeviceRoster::~BDiskDeviceRoster()
|
|
||||||
{
|
|
||||||
// if (fPartitionAddOnDir)
|
|
||||||
// delete fPartitionAddOnDir;
|
|
||||||
// if (fFSAddOnDir)
|
|
||||||
// delete fFSAddOnDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNextDevice
|
|
||||||
/*! \brief Returns the next BDiskDevice.
|
|
||||||
\param device Pointer to a pre-allocated BDiskDevice to be initialized to
|
|
||||||
represent the next device.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_ENTRY_NOT_FOUND: The end of the list of devices had already been
|
|
||||||
reached.
|
|
||||||
- another error code
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::GetNextDevice(BDiskDevice *device)
|
|
||||||
{
|
|
||||||
if (!device)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
size_t neededSize = 0;
|
|
||||||
partition_id id = _kern_get_next_disk_device_id(&fDeviceCookie,
|
|
||||||
&neededSize);
|
|
||||||
if (id < 0)
|
|
||||||
return id;
|
|
||||||
return device->_SetTo(id, true, false, neededSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// RewindDevices
|
|
||||||
/*! \brief Rewinds the device list iterator.
|
|
||||||
\return \c B_OK, if everything went fine, another error code otherwise.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::RewindDevices()
|
|
||||||
{
|
|
||||||
fDeviceCookie = 0;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNextDiskSystem
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::GetNextDiskSystem(BDiskSystem *system)
|
|
||||||
{
|
|
||||||
if (!system)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
user_disk_system_info info;
|
|
||||||
status_t error = _kern_get_next_disk_system_info(&fDiskSystemCookie,
|
|
||||||
&info);
|
|
||||||
if (error == B_OK)
|
|
||||||
error = system->_SetTo(&info);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// RewindDiskSystems
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::RewindDiskSystems()
|
|
||||||
{
|
|
||||||
fDiskSystemCookie = 0;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNextActiveJob
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::GetNextActiveJob(BDiskDeviceJob *job)
|
|
||||||
{
|
|
||||||
if (!job)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
user_disk_device_job_info info;
|
|
||||||
status_t error = _kern_get_next_disk_device_job_info(&fJobCookie, &info);
|
|
||||||
if (error == B_OK)
|
|
||||||
error = job->_SetTo(&info);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// RewindActiveJobs
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::RewindActiveJobs()
|
|
||||||
{
|
|
||||||
fJobCookie = 0;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterFileDevice
|
|
||||||
partition_id
|
|
||||||
BDiskDeviceRoster::RegisterFileDevice(const char *filename)
|
|
||||||
{
|
|
||||||
if (!filename)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
return _kern_register_file_device(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnregisterFileDevice
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::UnregisterFileDevice(const char *filename)
|
|
||||||
{
|
|
||||||
if (!filename)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
return _kern_unregister_file_device(-1, filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnregisterFileDevice
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::UnregisterFileDevice(partition_id device)
|
|
||||||
{
|
|
||||||
if (device < 0)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
return _kern_unregister_file_device(device, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// VisitEachDevice
|
|
||||||
/*! \brief Iterates through the all devices.
|
|
||||||
|
|
||||||
The supplied visitor's Visit(BDiskDevice*) is invoked for each device.
|
|
||||||
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.
|
|
||||||
|
|
||||||
\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.
|
|
||||||
\return \c true, if the iteration was terminated, \c false otherwise.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
BDiskDeviceRoster::VisitEachDevice(BDiskDeviceVisitor *visitor,
|
|
||||||
BDiskDevice *device)
|
|
||||||
{
|
|
||||||
bool terminatedEarly = false;
|
|
||||||
if (visitor) {
|
|
||||||
int32 oldCookie = fDeviceCookie;
|
|
||||||
fDeviceCookie = 0;
|
|
||||||
BDiskDevice deviceOnStack;
|
|
||||||
BDiskDevice *useDevice = (device ? device : &deviceOnStack);
|
|
||||||
while (!terminatedEarly && GetNextDevice(useDevice) == B_OK)
|
|
||||||
terminatedEarly = visitor->Visit(useDevice);
|
|
||||||
fDeviceCookie = oldCookie;
|
|
||||||
if (!terminatedEarly)
|
|
||||||
useDevice->Unset();
|
|
||||||
}
|
|
||||||
return terminatedEarly;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VisitEachPartition
|
|
||||||
/*! \brief Pre-order traverses the trees spanned by the BDiskDevices and their
|
|
||||||
subobjects.
|
|
||||||
|
|
||||||
The supplied visitor's Visit(BDiskDevice*) method is invoked for each
|
|
||||||
disk device and Visit(BPartition*) for each (non-disk device) partition.
|
|
||||||
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 partition the pointer to the partition 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 partition Pointer to a pre-allocated BPartition pointer to be set
|
|
||||||
to the partition at which the iteration was terminated.
|
|
||||||
May be \c NULL.
|
|
||||||
\return \c true, if the iteration was terminated, \c false otherwise.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
BDiskDeviceRoster::VisitEachPartition(BDiskDeviceVisitor *visitor,
|
|
||||||
BDiskDevice *device,
|
|
||||||
BPartition **partition)
|
|
||||||
{
|
|
||||||
bool terminatedEarly = false;
|
|
||||||
if (visitor) {
|
|
||||||
int32 oldCookie = fDeviceCookie;
|
|
||||||
fDeviceCookie = 0;
|
|
||||||
BDiskDevice deviceOnStack;
|
|
||||||
BDiskDevice *useDevice = (device ? device : &deviceOnStack);
|
|
||||||
BPartition *foundPartition = NULL;
|
|
||||||
while (!foundPartition && GetNextDevice(useDevice) == B_OK)
|
|
||||||
foundPartition = useDevice->VisitEachDescendant(visitor);
|
|
||||||
fDeviceCookie = oldCookie;
|
|
||||||
if (!terminatedEarly)
|
|
||||||
useDevice->Unset();
|
|
||||||
else if (device && partition)
|
|
||||||
*partition = foundPartition;
|
|
||||||
}
|
|
||||||
return terminatedEarly;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VisitEachMountedPartition
|
|
||||||
/*! \brief Iterates through the all devices' partitions that are mounted.
|
|
||||||
|
|
||||||
The supplied visitor's Visit(BPartition*) is invoked for each mounted
|
|
||||||
partition.
|
|
||||||
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 partition the pointer to the partition 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 partition Pointer to a pre-allocated BPartition pointer to be set
|
|
||||||
to the partition at which the iteration was terminated.
|
|
||||||
May be \c NULL.
|
|
||||||
\return \c true, if the iteration was terminated, \c false otherwise.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
BDiskDeviceRoster::VisitEachMountedPartition(BDiskDeviceVisitor *visitor,
|
|
||||||
BDiskDevice *device,
|
|
||||||
BPartition **partition)
|
|
||||||
{
|
|
||||||
bool terminatedEarly = false;
|
|
||||||
if (visitor) {
|
|
||||||
struct MountedPartitionFilter : public PartitionFilter {
|
|
||||||
virtual bool Filter(BPartition *partition, int32)
|
|
||||||
{ return partition->IsMounted(); }
|
|
||||||
} filter;
|
|
||||||
PartitionFilterVisitor filterVisitor(visitor, &filter);
|
|
||||||
terminatedEarly
|
|
||||||
= VisitEachPartition(&filterVisitor, device, partition);
|
|
||||||
}
|
|
||||||
return terminatedEarly;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VisitEachMountablePartition
|
|
||||||
/*! \brief Iterates through the all devices' partitions that are mountable.
|
|
||||||
|
|
||||||
The supplied visitor's Visit(BPartition*) is invoked for each mountable
|
|
||||||
partition.
|
|
||||||
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 partition the pointer to the partition 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 partition Pointer to a pre-allocated BPartition pointer to be set
|
|
||||||
to the partition at which the iteration was terminated.
|
|
||||||
May be \c NULL.
|
|
||||||
\return \c true, if the iteration was terminated, \c false otherwise.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
BDiskDeviceRoster::VisitEachMountablePartition(BDiskDeviceVisitor *visitor,
|
|
||||||
BDiskDevice *device,
|
|
||||||
BPartition **partition)
|
|
||||||
{
|
|
||||||
bool terminatedEarly = false;
|
|
||||||
if (visitor) {
|
|
||||||
struct MountablePartitionFilter : public PartitionFilter {
|
|
||||||
virtual bool Filter(BPartition *partition, int32)
|
|
||||||
{ return partition->ContainsFileSystem(); }
|
|
||||||
} filter;
|
|
||||||
PartitionFilterVisitor filterVisitor(visitor, &filter);
|
|
||||||
terminatedEarly
|
|
||||||
= VisitEachPartition(&filterVisitor, device, partition);
|
|
||||||
}
|
|
||||||
return terminatedEarly;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetDeviceWithID
|
|
||||||
/*! \brief Returns a BDiskDevice for a given ID.
|
|
||||||
|
|
||||||
The supplied \a device is initialized to the device identified by \a id.
|
|
||||||
|
|
||||||
\param id The ID of the device to be retrieved.
|
|
||||||
\param device Pointer to a pre-allocated BDiskDevice to be initialized
|
|
||||||
to the device identified by \a id.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_ENTRY_NOT_FOUND: A device with ID \a id could not be found.
|
|
||||||
- other error codes
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::GetDeviceWithID(int32 id, BDiskDevice *device) const
|
|
||||||
{
|
|
||||||
if (!device)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
return device->_SetTo(id, true, false, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPartitionWithID
|
|
||||||
/*! \brief Returns a BPartition for a given ID.
|
|
||||||
|
|
||||||
The supplied \a device is initialized to the device the partition
|
|
||||||
identified by \a id resides on, and \a partition is set to point to the
|
|
||||||
respective BPartition.
|
|
||||||
|
|
||||||
\param id The ID of the partition to be retrieved.
|
|
||||||
\param device Pointer to a pre-allocated BDiskDevice to be initialized
|
|
||||||
to the device the partition identified by \a id resides on.
|
|
||||||
\param partition Pointer to a pre-allocated BPartition pointer to be set
|
|
||||||
to the partition identified by \a id.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_ENTRY_NOT_FOUND: A partition with ID \a id could not be found.
|
|
||||||
- other error codes
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::GetPartitionWithID(int32 id, BDiskDevice *device,
|
|
||||||
BPartition **partition) const
|
|
||||||
{
|
|
||||||
if (!device || !partition)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
// download the device data
|
|
||||||
status_t error = device->_SetTo(id, false, false, 0);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
// find the partition object
|
|
||||||
*partition = device->FindDescendant(id);
|
|
||||||
if (!*partition) // should never happen!
|
|
||||||
return B_ENTRY_NOT_FOUND;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetDeviceForPath
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::GetDeviceForPath(const char *filename, BDiskDevice *device)
|
|
||||||
{
|
|
||||||
if (!filename || !device)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
// get the device ID
|
|
||||||
size_t neededSize = 0;
|
|
||||||
partition_id id = _kern_find_disk_device(filename, &neededSize);
|
|
||||||
if (id < 0)
|
|
||||||
return id;
|
|
||||||
// download the device data
|
|
||||||
return device->_SetTo(id, true, false, neededSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPartitionForPath
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::GetPartitionForPath(const char *filename,
|
|
||||||
BDiskDevice *device,
|
|
||||||
BPartition **partition)
|
|
||||||
{
|
|
||||||
if (!filename || !device || !partition)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
// get the partition ID
|
|
||||||
size_t neededSize = 0;
|
|
||||||
partition_id id = _kern_find_partition(filename, &neededSize);
|
|
||||||
if (id < 0)
|
|
||||||
return id;
|
|
||||||
// download the device data
|
|
||||||
status_t error = device->_SetTo(id, false, false, neededSize);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
// find the partition object
|
|
||||||
*partition = device->FindDescendant(id);
|
|
||||||
if (!*partition) // should never happen!
|
|
||||||
return B_ENTRY_NOT_FOUND;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// StartWatching
|
|
||||||
/*! \brief Adds a target to the list of targets to be notified on disk device
|
|
||||||
events.
|
|
||||||
|
|
||||||
\todo List the event mask flags, the events and describe the layout of the
|
|
||||||
notification message.
|
|
||||||
|
|
||||||
If \a target is already listening to events, this method replaces the
|
|
||||||
former event mask with \a eventMask.
|
|
||||||
|
|
||||||
\param target A BMessenger identifying the target to which the events
|
|
||||||
shall be sent.
|
|
||||||
\param eventMask A mask specifying on which events the target shall be
|
|
||||||
notified.
|
|
||||||
\return \c B_OK, if everything went fine, another error code otherwise.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::StartWatching(BMessenger target, uint32 eventMask)
|
|
||||||
{
|
|
||||||
/* status_t error = B_OK;
|
|
||||||
// compose request message
|
|
||||||
BMessage request(B_REG_DEVICE_START_WATCHING);
|
|
||||||
if (error == B_OK)
|
|
||||||
error = request.AddMessenger("target", target);
|
|
||||||
if (error == B_OK)
|
|
||||||
error = request.AddInt32("events", (int32)eventMask);
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
*/
|
|
||||||
// not implemented
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// StartWatchingJob
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::StartWatchingJob(BDiskDeviceJob *job, BMessenger target,
|
|
||||||
uint32 eventMask)
|
|
||||||
{
|
|
||||||
// not implemented
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// StopWatching
|
|
||||||
/*! \brief Remove a target from the list of targets to be notified on disk
|
|
||||||
device events.
|
|
||||||
\param target A BMessenger identifying the target to which notfication
|
|
||||||
message shall not longer be sent.
|
|
||||||
\return \c B_OK, if everything went fine, another error code otherwise.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::StopWatching(BMessenger target)
|
|
||||||
{
|
|
||||||
/* status_t error = B_OK;
|
|
||||||
// compose request message
|
|
||||||
BMessage request(B_REG_DEVICE_STOP_WATCHING);
|
|
||||||
if (error == B_OK)
|
|
||||||
error = request.AddMessenger("target", target);
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
*/
|
|
||||||
// not implemented
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
// GetNextPartitioningSystem
|
|
||||||
/*! \brief Returns the next partitioning system capable of partitioning.
|
|
||||||
|
|
||||||
The returned \a shortName can be passed to BSession::Partition().
|
|
||||||
|
|
||||||
\param shortName Pointer to a pre-allocation char buffer, of size
|
|
||||||
\c B_FILE_NAME_LENGTH or larger into which the short name of the
|
|
||||||
partitioning system shall be written.
|
|
||||||
\param longName Pointer to a pre-allocation char buffer, of size
|
|
||||||
\c B_FILE_NAME_LENGTH or larger into which the long name of the
|
|
||||||
partitioning system shall be written. May be \c NULL.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_BAD_VALUE: \c NULL \a shortName.
|
|
||||||
- \c B_ENTRY_NOT_FOUND: End of the list has been reached.
|
|
||||||
- other error codes
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::GetNextPartitioningSystem(char *shortName, char *longName)
|
|
||||||
{
|
|
||||||
status_t error = (shortName ? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK) {
|
|
||||||
// search until an add-on has been found or the end of all directories
|
|
||||||
// has been reached
|
|
||||||
bool found = false;
|
|
||||||
do {
|
|
||||||
// get the next add-on in the current dir
|
|
||||||
AddOnImage image;
|
|
||||||
error = _GetNextAddOn(fPartitionAddOnDir, &image);
|
|
||||||
if (error == B_OK) {
|
|
||||||
// add-on loaded: get the function that creates an add-on
|
|
||||||
// object
|
|
||||||
BDiskScannerPartitionAddOn *(*create_add_on)();
|
|
||||||
if (get_image_symbol(image.ID(), "create_ds_partition_add_on",
|
|
||||||
B_SYMBOL_TYPE_TEXT,
|
|
||||||
(void**)&create_add_on) == B_OK) {
|
|
||||||
// create the add-on object and copy the requested data
|
|
||||||
if (BDiskScannerPartitionAddOn *addOn
|
|
||||||
= (*create_add_on)()) {
|
|
||||||
const char *addOnShortName = addOn->ShortName();
|
|
||||||
const char *addOnLongName = addOn->LongName();
|
|
||||||
if (addOnShortName && addOnLongName) {
|
|
||||||
strcpy(shortName, addOnShortName);
|
|
||||||
if (longName)
|
|
||||||
strcpy(longName, addOnLongName);
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
delete addOn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (error == B_ENTRY_NOT_FOUND) {
|
|
||||||
// end of the current directory has been reached, try next dir
|
|
||||||
error = _GetNextAddOnDir(&fPartitionAddOnDir,
|
|
||||||
&fPartitionAddOnDirIndex,
|
|
||||||
"partition");
|
|
||||||
}
|
|
||||||
} while (error == B_OK && !found);
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNextFileSystem
|
|
||||||
/*! \brief Returns the next file system capable of initializing.
|
|
||||||
|
|
||||||
The returned \a shortName can be passed to BPartition::Initialize().
|
|
||||||
|
|
||||||
\param shortName Pointer to a pre-allocation char buffer, of size
|
|
||||||
\c B_FILE_NAME_LENGTH or larger into which the short name of the
|
|
||||||
file system shall be written.
|
|
||||||
\param longName Pointer to a pre-allocation char buffer, of size
|
|
||||||
\c B_FILE_NAME_LENGTH or larger into which the long name of the
|
|
||||||
file system shall be written. May be \c NULL.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_BAD_VALUE: \c NULL \a shortName.
|
|
||||||
- \c B_ENTRY_NOT_FOUND: End of the list has been reached.
|
|
||||||
- other error codes
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::GetNextFileSystem(char *shortName, char *longName)
|
|
||||||
{
|
|
||||||
status_t error = (shortName ? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK) {
|
|
||||||
// search until an add-on has been found or the end of all directories
|
|
||||||
// has been reached
|
|
||||||
bool found = false;
|
|
||||||
do {
|
|
||||||
// get the next add-on in the current dir
|
|
||||||
AddOnImage image;
|
|
||||||
error = _GetNextAddOn(fFSAddOnDir, &image);
|
|
||||||
if (error == B_OK) {
|
|
||||||
// add-on loaded: get the function that creates an add-on
|
|
||||||
// object
|
|
||||||
BDiskScannerFSAddOn *(*create_add_on)();
|
|
||||||
if (get_image_symbol(image.ID(), "create_ds_fs_add_on",
|
|
||||||
B_SYMBOL_TYPE_TEXT,
|
|
||||||
(void**)&create_add_on) == B_OK) {
|
|
||||||
// create the add-on object and copy the requested data
|
|
||||||
if (BDiskScannerFSAddOn *addOn = (*create_add_on)()) {
|
|
||||||
const char *addOnShortName = addOn->ShortName();
|
|
||||||
const char *addOnLongName = addOn->LongName();
|
|
||||||
if (addOnShortName && addOnLongName) {
|
|
||||||
strcpy(shortName, addOnShortName);
|
|
||||||
if (longName)
|
|
||||||
strcpy(longName, addOnLongName);
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
delete addOn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (error == B_ENTRY_NOT_FOUND) {
|
|
||||||
// end of the current directory has been reached, try next dir
|
|
||||||
error = _GetNextAddOnDir(&fFSAddOnDir, &fFSAddOnDirIndex,
|
|
||||||
"fs");
|
|
||||||
}
|
|
||||||
} while (error == B_OK && !found);
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// RewindPartitiningSystems
|
|
||||||
/*! \brief Rewinds the partitioning system list iterator.
|
|
||||||
\return \c B_OK, if everything went fine, another error code otherwise.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::RewindPartitiningSystems()
|
|
||||||
{
|
|
||||||
if (fPartitionAddOnDir) {
|
|
||||||
delete fPartitionAddOnDir;
|
|
||||||
fPartitionAddOnDir = NULL;
|
|
||||||
}
|
|
||||||
fPartitionAddOnDirIndex = 0;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// RewindFileSystems
|
|
||||||
/*! \brief Rewinds the file system list iterator.
|
|
||||||
\return \c B_OK, if everything went fine, another error code otherwise.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::RewindFileSystems()
|
|
||||||
{
|
|
||||||
if (fFSAddOnDir) {
|
|
||||||
delete fFSAddOnDir;
|
|
||||||
fFSAddOnDir = NULL;
|
|
||||||
}
|
|
||||||
fFSAddOnDirIndex = 0;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _GetObjectWithID
|
|
||||||
/*! \brief Returns a BDiskDevice for a given device, session or partition ID.
|
|
||||||
|
|
||||||
The supplied \a device is initialized to the device the object identified
|
|
||||||
by \a id belongs to.
|
|
||||||
|
|
||||||
\param fieldName "device_id", "sesison_id" or "partition_id" according to
|
|
||||||
the type of object the device shall be retrieved for.
|
|
||||||
\param id The ID of the device, session or partition to be retrieved.
|
|
||||||
\param device Pointer to a pre-allocated BDiskDevice to be initialized
|
|
||||||
to the device to be retrieved.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_ENTRY_NOT_FOUND: A device, session or partition respectively with
|
|
||||||
ID \a id could not be found.
|
|
||||||
- other error codes
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::_GetObjectWithID(const char *fieldName, int32 id,
|
|
||||||
BDiskDevice *device) const
|
|
||||||
{
|
|
||||||
status_t error = (device ? B_OK : B_BAD_VALUE);
|
|
||||||
// compose request message
|
|
||||||
BMessage request(B_REG_GET_DISK_DEVICE);
|
|
||||||
if (error == B_OK)
|
|
||||||
error = request.AddInt32(fieldName, id);
|
|
||||||
// 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;
|
|
||||||
// device
|
|
||||||
BMessage archive;
|
|
||||||
if (error == B_OK)
|
|
||||||
error = reply.FindMessage("device", &archive);
|
|
||||||
if (error == B_OK)
|
|
||||||
error = device->_Unarchive(&archive);
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// _GetNextAddOn
|
|
||||||
/*! \brief Finds and loads the next add-on of an add-on subdirectory.
|
|
||||||
\param directory The add-on directory.
|
|
||||||
\param image Pointer to an image_id into which the image ID of the loaded
|
|
||||||
add-on shall be written.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_ENTRY_NOT_FOUND: End of directory.
|
|
||||||
- other error codes
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::_GetNextAddOn(BDirectory **directory, int32 *index,
|
|
||||||
const char *subdir, AddOnImage *image)
|
|
||||||
{
|
|
||||||
status_t error = (directory && index && subdir && image
|
|
||||||
? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK) {
|
|
||||||
// search until an add-on has been found or the end of all directories
|
|
||||||
// has been reached
|
|
||||||
bool found = false;
|
|
||||||
do {
|
|
||||||
// get the next add-on in the current dir
|
|
||||||
error = _GetNextAddOn(*directory, image);
|
|
||||||
if (error == B_OK) {
|
|
||||||
found = true;
|
|
||||||
} else if (error == B_ENTRY_NOT_FOUND) {
|
|
||||||
// end of the current directory has been reached, try next dir
|
|
||||||
error = _GetNextAddOnDir(directory, index, subdir);
|
|
||||||
}
|
|
||||||
} while (error == B_OK && !found);
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _GetNextAddOn
|
|
||||||
/*! \brief Finds and loads the next add-on of an add-on subdirectory.
|
|
||||||
\param directory The add-on directory.
|
|
||||||
\param image Pointer to an image_id into which the image ID of the loaded
|
|
||||||
add-on shall be written.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_ENTRY_NOT_FOUND: End of directory.
|
|
||||||
- other error codes
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::_GetNextAddOn(BDirectory *directory, AddOnImage *image)
|
|
||||||
{
|
|
||||||
status_t error = (directory ? B_OK : B_ENTRY_NOT_FOUND);
|
|
||||||
if (error == B_OK) {
|
|
||||||
// iterate through the entry list and try to load the entries
|
|
||||||
bool found = false;
|
|
||||||
while (error == B_OK && !found) {
|
|
||||||
BEntry entry;
|
|
||||||
error = directory->GetNextEntry(&entry);
|
|
||||||
BPath path;
|
|
||||||
if (error == B_OK && entry.GetPath(&path) == B_OK)
|
|
||||||
found = (image->Load(path.Path()) == B_OK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _GetNextAddOnDir
|
|
||||||
/*! \brief Gets the next add-on directory path.
|
|
||||||
\param path Pointer to a BPath to be set to the found directory.
|
|
||||||
\param index Pointer to an index into the kAddOnDirs array indicating
|
|
||||||
which add-on dir shall be retrieved next.
|
|
||||||
\param subdir Name of the subdirectory (in the "disk_scanner" subdirectory
|
|
||||||
of the add-on directory) \a directory shall be set to.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_ENTRY_NOT_FOUND: End of directory list.
|
|
||||||
- other error codes
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::_GetNextAddOnDir(BPath *path, int32 *index,
|
|
||||||
const char *subdir)
|
|
||||||
{
|
|
||||||
status_t error = (*index < kAddOnDirCount ? B_OK : B_ENTRY_NOT_FOUND);
|
|
||||||
// get the add-on dir path
|
|
||||||
if (error == B_OK) {
|
|
||||||
error = find_directory(kAddOnDirs[*index], path);
|
|
||||||
(*index)++;
|
|
||||||
}
|
|
||||||
// construct the subdirectory path
|
|
||||||
if (error == B_OK) {
|
|
||||||
error = path->Append("disk_scanner");
|
|
||||||
if (error == B_OK)
|
|
||||||
error = path->Append(subdir);
|
|
||||||
}
|
|
||||||
if (error == B_OK)
|
|
||||||
printf(" next add-on dir: `%s'\n", path->Path());
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _GetNextAddOnDir
|
|
||||||
/*! \brief Gets the next add-on directory.
|
|
||||||
\param directory Pointer to a BDirectory* to be set to the found directory.
|
|
||||||
\param index Pointer to an index into the kAddOnDirs array indicating
|
|
||||||
which add-on dir shall be retrieved next.
|
|
||||||
\param subdir Name of the subdirectory (in the "disk_scanner" subdirectory
|
|
||||||
of the add-on directory) \a directory shall be set to.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_ENTRY_NOT_FOUND: End of directory list.
|
|
||||||
- other error codes
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::_GetNextAddOnDir(BDirectory **directory, int32 *index,
|
|
||||||
const char *subdir)
|
|
||||||
{
|
|
||||||
BPath path;
|
|
||||||
status_t error = _GetNextAddOnDir(&path, index, subdir);
|
|
||||||
// create a BDirectory object, if there is none yet.
|
|
||||||
if (error == B_OK && !*directory) {
|
|
||||||
*directory = new BDirectory;
|
|
||||||
if (!*directory)
|
|
||||||
error = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
// init the directory
|
|
||||||
if (error == B_OK)
|
|
||||||
error = (*directory)->SetTo(path.Path());
|
|
||||||
// cleanup on error
|
|
||||||
if (error != B_OK && *directory) {
|
|
||||||
delete *directory;
|
|
||||||
*directory = NULL;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _LoadPartitionAddOn
|
|
||||||
status_t
|
|
||||||
BDiskDeviceRoster::_LoadPartitionAddOn(const char *partitioningSystem,
|
|
||||||
AddOnImage *image,
|
|
||||||
BDiskScannerPartitionAddOn **_addOn)
|
|
||||||
{
|
|
||||||
status_t error = (partitioningSystem && image && _addOn
|
|
||||||
? B_OK : B_BAD_VALUE);
|
|
||||||
// load the image
|
|
||||||
bool found = false;
|
|
||||||
BPath path;
|
|
||||||
BDirectory *directory = NULL;
|
|
||||||
int32 index = 0;
|
|
||||||
while (error == B_OK && !found) {
|
|
||||||
error = _GetNextAddOn(&directory, &index, "partition", image);
|
|
||||||
if (error == B_OK) {
|
|
||||||
// add-on loaded: get the function that creates an add-on
|
|
||||||
// object
|
|
||||||
BDiskScannerPartitionAddOn *(*create_add_on)();
|
|
||||||
if (get_image_symbol(image->ID(), "create_ds_partition_add_on",
|
|
||||||
B_SYMBOL_TYPE_TEXT,
|
|
||||||
(void**)&create_add_on) == B_OK) {
|
|
||||||
// create the add-on object and copy the requested data
|
|
||||||
if (BDiskScannerPartitionAddOn *addOn = (*create_add_on)()) {
|
|
||||||
if (!strcmp(addOn->ShortName(), partitioningSystem)) {
|
|
||||||
*_addOn = addOn;
|
|
||||||
found = true;
|
|
||||||
} else
|
|
||||||
delete addOn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// cleanup
|
|
||||||
if (directory)
|
|
||||||
delete directory;
|
|
||||||
if (error != B_OK && image)
|
|
||||||
image->Unload();
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // 0
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the Haiku distribution and is covered
|
|
||||||
// by the MIT license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include <DiskDeviceTypes.h>
|
|
||||||
|
|
||||||
// Device Types
|
|
||||||
|
|
||||||
const char *kDeviceTypeFloppyDisk = "Floppy Disk Media";
|
|
||||||
const char *kDeviceTypeHardDisk = "Hard Disk Media";
|
|
||||||
const char *kDeviceTypeOptical = "Optical Media";
|
|
||||||
|
|
||||||
// Partition types
|
|
||||||
|
|
||||||
const char *kPartitionTypeUnrecognized = "Unrecognized";
|
|
||||||
|
|
||||||
const char *kPartitionTypeMultisession = "Multisession Storage Device";
|
|
||||||
|
|
||||||
const char *kPartitionTypeAudioSession = "Audio Session";
|
|
||||||
const char *kPartitionTypeDataSession = "Data Session";
|
|
||||||
|
|
||||||
const char *kPartitionTypeAmiga = "Amiga Partition Map";
|
|
||||||
const char *kPartitionTypeApple = "Apple Partition Map";
|
|
||||||
const char *kPartitionTypeIntel = "Intel Partition Map";
|
|
||||||
|
|
||||||
const char *kPartitionTypeIntelPrimary = "Intel Primary Partition";
|
|
||||||
const char *kPartitionTypeIntelExtended = "Intel Extended Partition";
|
|
||||||
const char *kPartitionTypeIntelLogical = "Intel Logical Partition";
|
|
||||||
|
|
||||||
const char *kPartitionTypeAmigaFFS = "AmigaFFS Filesystem";
|
|
||||||
const char *kPartitionTypeBFS = "BFS Filesystem";
|
|
||||||
const char *kPartitionTypeEXT2 = "EXT2 Filesystem";
|
|
||||||
const char *kPartitionTypeEXT3 = "EXT3 Filesystem";
|
|
||||||
const char *kPartitionTypeFAT12 = "FAT12 Filesystem";
|
|
||||||
const char *kPartitionTypeFAT32 = "FAT32 Filesystem";
|
|
||||||
const char *kPartitionTypeHFS = "HFS Filesystem";
|
|
||||||
const char *kPartitionTypeHFSPlus = "HFS+ Filesystem";
|
|
||||||
const char *kPartitionTypeISO9660 = "ISO9660 Filesystem";
|
|
||||||
const char *kPartitionTypeReiser = "Reiser Filesystem";
|
|
||||||
const char *kPartitionTypeUDF = "UDF Filesystem";
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
|
||||||
// by the OpenBeOS license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include <DiskDeviceVisitor.h>
|
|
||||||
|
|
||||||
/*! \class BDiskDeviceVisitor
|
|
||||||
\brief Base class of visitors used for BDiskDevice and
|
|
||||||
BPartition iteration.
|
|
||||||
|
|
||||||
BDiskDeviceRoster and BDiskDevice provide iteration methods,
|
|
||||||
that work together with an instance of a derived class of
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
/*! \brief Creates a new disk device visitor.
|
|
||||||
*/
|
|
||||||
BDiskDeviceVisitor::BDiskDeviceVisitor()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
/*! \brief Free all resources associated with this object.
|
|
||||||
|
|
||||||
Does nothing.
|
|
||||||
*/
|
|
||||||
BDiskDeviceVisitor::~BDiskDeviceVisitor()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Visit
|
|
||||||
/*! \brief Invoked when a BDiskDevice 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.
|
|
||||||
|
|
||||||
\param device The visited disk device.
|
|
||||||
\return \c true, if the iteration shall be terminated at this point,
|
|
||||||
\c false otherwise.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
BDiskDeviceVisitor::Visit(BDiskDevice *device)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Visit
|
|
||||||
/*! \brief Invoked when a BPartition 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.
|
|
||||||
|
|
||||||
\param partition The visited partition.
|
|
||||||
\param level The level of the partition in the partition tree.
|
|
||||||
\return \c true, if the iteration shall be terminated at this point,
|
|
||||||
\c false otherwise.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
BDiskDeviceVisitor::Visit(BPartition *partition, int32 level)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,212 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
|
||||||
// by the OpenBeOS license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include <DiskScannerAddOn.h>
|
|
||||||
#include <String.h>
|
|
||||||
|
|
||||||
// BDiskScannerPartitionAddOn
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
/*! \brief Creates a partition disk scanner add-on.
|
|
||||||
*/
|
|
||||||
BDiskScannerPartitionAddOn::BDiskScannerPartitionAddOn()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
/*! \brief Frees all resources associated with this object.
|
|
||||||
*/
|
|
||||||
BDiskScannerPartitionAddOn::~BDiskScannerPartitionAddOn()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \fn virtual const char *BDiskScannerPartitionAddOn::ShortName() = 0;
|
|
||||||
\brief Returns a short name for the add-on.
|
|
||||||
|
|
||||||
To be implemented by derived classes.
|
|
||||||
|
|
||||||
The returned string identifies the respective partition kernel module is
|
|
||||||
passed to partition_session().
|
|
||||||
|
|
||||||
\return A short name for the add-on.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! \fn virtual const char *BDiskScannerPartitionAddOn::LongName() = 0;
|
|
||||||
\brief Returns a user-readable long name for the add-on.
|
|
||||||
|
|
||||||
To be implemented by derived classes.
|
|
||||||
|
|
||||||
\return A long name for the add-on.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! \fn virtual BDiskScannerPartitionAddOn::BDiskScannerParameterEditor *
|
|
||||||
CreateEditor(const BSession *session, const char *parameters) = 0;
|
|
||||||
\brief Creates and returns an editor for editing partitioning parameters
|
|
||||||
for a specified session.
|
|
||||||
|
|
||||||
To be implemented by derived classes.
|
|
||||||
|
|
||||||
\param session The session to be partitioned.
|
|
||||||
\param parameters Parameters retrieved from the partition module. Should
|
|
||||||
initially be presented to the user.
|
|
||||||
\return The newly created editor. \c NULL, if an error occurred.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// FBC
|
|
||||||
void BDiskScannerPartitionAddOn::_ReservedDiskScannerPartitionAddOn1() {}
|
|
||||||
void BDiskScannerPartitionAddOn::_ReservedDiskScannerPartitionAddOn2() {}
|
|
||||||
void BDiskScannerPartitionAddOn::_ReservedDiskScannerPartitionAddOn3() {}
|
|
||||||
void BDiskScannerPartitionAddOn::_ReservedDiskScannerPartitionAddOn4() {}
|
|
||||||
void BDiskScannerPartitionAddOn::_ReservedDiskScannerPartitionAddOn5() {}
|
|
||||||
|
|
||||||
|
|
||||||
// BDiskScannerFSAddOn
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
/*! \brief Creates a FS disk scanner add-on.
|
|
||||||
*/
|
|
||||||
BDiskScannerFSAddOn::BDiskScannerFSAddOn()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
/*! \brief Frees all resources associated with this object.
|
|
||||||
*/
|
|
||||||
BDiskScannerFSAddOn::~BDiskScannerFSAddOn()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \fn virtual const char *BDiskScannerFSAddOn::ShortName() = 0;
|
|
||||||
\brief Returns a short name for the add-on.
|
|
||||||
|
|
||||||
To be implemented by derived classes.
|
|
||||||
|
|
||||||
The returned name identifies the file system (the kernel add-on) and is
|
|
||||||
passed to initialize_volume().
|
|
||||||
|
|
||||||
\return A short name for the add-on.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! \fn virtual const char *BDiskScannerFSAddOn::LongName() = 0;
|
|
||||||
\brief Returns a user-readable long name for the add-on.
|
|
||||||
|
|
||||||
To be implemented by derived classes.
|
|
||||||
|
|
||||||
\return A long name for the add-on.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! \fn virtual BDiskScannerFSAddOn::BDiskScannerParameterEditor *CreateEditor(
|
|
||||||
const BPartition *partition, const char *parameters) = 0;
|
|
||||||
\brief Creates and returns an editor for editing initialization parameters
|
|
||||||
for a specified partition.
|
|
||||||
|
|
||||||
To be implemented by derived classes.
|
|
||||||
|
|
||||||
\param partition The partition to be initialized.
|
|
||||||
\param parameters Parameters retrieved from the kernel FS add-on. Should
|
|
||||||
initially be presented to the user.
|
|
||||||
\return The newly created editor. \c NULL, if the FS doesn't need any
|
|
||||||
further parameters.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// FBC
|
|
||||||
void BDiskScannerFSAddOn::_ReservedDiskScannerFSAddOn1() {}
|
|
||||||
void BDiskScannerFSAddOn::_ReservedDiskScannerFSAddOn2() {}
|
|
||||||
void BDiskScannerFSAddOn::_ReservedDiskScannerFSAddOn3() {}
|
|
||||||
void BDiskScannerFSAddOn::_ReservedDiskScannerFSAddOn4() {}
|
|
||||||
void BDiskScannerFSAddOn::_ReservedDiskScannerFSAddOn5() {}
|
|
||||||
|
|
||||||
|
|
||||||
// BDiskScannerParameterEditor
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
/*! \brief Creates a disk scanner parameter editor.
|
|
||||||
*/
|
|
||||||
BDiskScannerParameterEditor::BDiskScannerParameterEditor()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
/*! \brief Frees all resources associated with this object.
|
|
||||||
*/
|
|
||||||
BDiskScannerParameterEditor::~BDiskScannerParameterEditor()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \brief Returns a view containing the controls needed for editing the
|
|
||||||
parameters.
|
|
||||||
|
|
||||||
To be overridden by derived classes.
|
|
||||||
The base class version returns \c NULL.
|
|
||||||
|
|
||||||
The returned BView is added to a window occasionally and removed, when
|
|
||||||
editing is done. The view belongs to the editor and needs to be deleted
|
|
||||||
by it. Subsequent calls to this method may return the same view, or each
|
|
||||||
time delete the old one and return a new one.
|
|
||||||
|
|
||||||
\return A view containing the controls needed for editing the parameters.
|
|
||||||
\c NULL can be returned, if no parameters are needed.
|
|
||||||
*/
|
|
||||||
BView *
|
|
||||||
BDiskScannerParameterEditor::View()
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// EditingDone
|
|
||||||
/*! \brief Called when the user finishes editing the parameters.
|
|
||||||
|
|
||||||
To be overridden by derived classes.
|
|
||||||
The base class version returns \c true.
|
|
||||||
|
|
||||||
The method is supposed to check whether the parameters the user set,
|
|
||||||
are valid, and, if so, return \c true. Otherwise an BAlert shall be
|
|
||||||
shown, explaining the problem to the user and \c false being returned
|
|
||||||
-- then the parameter dialog will not be closed.
|
|
||||||
|
|
||||||
\return \c true, if the current parameters are valid, \c false otherwise.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
BDiskScannerParameterEditor::EditingDone()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \brief Returns the edited parameters.
|
|
||||||
|
|
||||||
To be overridden by derived classes.
|
|
||||||
The base class version returns an empty string.
|
|
||||||
|
|
||||||
\param parameters A BString to be set to the edited parameters.
|
|
||||||
|
|
||||||
\return \c B_OK, if everything went fine, another error code otherwise.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BDiskScannerParameterEditor::GetParameters(BString *parameters)
|
|
||||||
{
|
|
||||||
status_t error = (parameters ? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK)
|
|
||||||
parameters->SetTo("");
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FBC
|
|
||||||
void BDiskScannerParameterEditor::_ReservedDiskScannerParameterEditor1() {}
|
|
||||||
void BDiskScannerParameterEditor::_ReservedDiskScannerParameterEditor2() {}
|
|
||||||
void BDiskScannerParameterEditor::_ReservedDiskScannerParameterEditor3() {}
|
|
||||||
void BDiskScannerParameterEditor::_ReservedDiskScannerParameterEditor4() {}
|
|
||||||
void BDiskScannerParameterEditor::_ReservedDiskScannerParameterEditor5() {}
|
|
||||||
|
|
||||||
|
|
||||||
/*! \fn BDiskScannerPartitionAddOn *create_ds_partition_add_on();
|
|
||||||
\brief To be provided by partition add-ons to create an add-on object.
|
|
||||||
\return A newly created BDiskScannerPartitionAddOn for this add-on.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! \fn BDiskScannerFSAddOn *create_ds_fs_add_on();
|
|
||||||
\brief To be provided by FS add-ons to create an add-on object.
|
|
||||||
\return A newly created BDiskScannerFSAddOn for this add-on.
|
|
||||||
*/
|
|
||||||
|
|
||||||
@@ -1,306 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
|
||||||
// by the OpenBeOS license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include <syscalls.h>
|
|
||||||
|
|
||||||
#include <DiskSystem.h>
|
|
||||||
#include <Partition.h>
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
BDiskSystem::BDiskSystem()
|
|
||||||
: fID(B_NO_INIT),
|
|
||||||
fName(),
|
|
||||||
fPrettyName(),
|
|
||||||
fFlags(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
BDiskSystem::~BDiskSystem()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitCheck
|
|
||||||
status_t
|
|
||||||
BDiskSystem::InitCheck() const
|
|
||||||
{
|
|
||||||
return (fID > 0 ? B_OK : fID);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name
|
|
||||||
const char *
|
|
||||||
BDiskSystem::Name() const
|
|
||||||
{
|
|
||||||
return fName.String();
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrettyName
|
|
||||||
const char *
|
|
||||||
BDiskSystem::PrettyName() const
|
|
||||||
{
|
|
||||||
return fPrettyName.String();
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportsDefragmenting
|
|
||||||
bool
|
|
||||||
BDiskSystem::SupportsDefragmenting(bool *whileMounted) const
|
|
||||||
{
|
|
||||||
if (InitCheck() != B_OK
|
|
||||||
|| !(fFlags & B_DISK_SYSTEM_SUPPORTS_DEFRAGMENTING)) {
|
|
||||||
if (whileMounted)
|
|
||||||
*whileMounted = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (whileMounted) {
|
|
||||||
*whileMounted = (IsFileSystem()
|
|
||||||
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_DEFRAGMENTING_WHILE_MOUNTED));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportsRepairing
|
|
||||||
bool
|
|
||||||
BDiskSystem::SupportsRepairing(bool checkOnly, bool *whileMounted) const
|
|
||||||
{
|
|
||||||
uint32 mainBit = B_DISK_SYSTEM_SUPPORTS_REPAIRING;
|
|
||||||
uint32 mountedBit = B_DISK_SYSTEM_SUPPORTS_REPAIRING_WHILE_MOUNTED;
|
|
||||||
if (checkOnly) {
|
|
||||||
mainBit = B_DISK_SYSTEM_SUPPORTS_CHECKING;
|
|
||||||
mountedBit = B_DISK_SYSTEM_SUPPORTS_CHECKING_WHILE_MOUNTED;
|
|
||||||
}
|
|
||||||
if (InitCheck() != B_OK || !(fFlags & mainBit)) {
|
|
||||||
if (whileMounted)
|
|
||||||
*whileMounted = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (whileMounted)
|
|
||||||
*whileMounted = (IsFileSystem() && (fFlags & mountedBit));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportsResizing
|
|
||||||
bool
|
|
||||||
BDiskSystem::SupportsResizing(bool *whileMounted) const
|
|
||||||
{
|
|
||||||
if (InitCheck() != B_OK
|
|
||||||
|| !(fFlags & B_DISK_SYSTEM_SUPPORTS_RESIZING)) {
|
|
||||||
if (whileMounted)
|
|
||||||
*whileMounted = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (whileMounted) {
|
|
||||||
*whileMounted = (IsFileSystem()
|
|
||||||
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_RESIZING_WHILE_MOUNTED));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportsResizingChild
|
|
||||||
bool
|
|
||||||
BDiskSystem::SupportsResizingChild() const
|
|
||||||
{
|
|
||||||
return (InitCheck() == B_OK && IsPartitioningSystem()
|
|
||||||
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD));
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportsMoving
|
|
||||||
bool
|
|
||||||
BDiskSystem::SupportsMoving(bool *whileMounted) const
|
|
||||||
{
|
|
||||||
if (InitCheck() != B_OK
|
|
||||||
|| !(fFlags & B_DISK_SYSTEM_SUPPORTS_MOVING)) {
|
|
||||||
if (whileMounted)
|
|
||||||
*whileMounted = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (whileMounted) {
|
|
||||||
*whileMounted = (IsFileSystem()
|
|
||||||
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_MOVING_WHILE_MOUNTED));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportsMovingChild
|
|
||||||
bool
|
|
||||||
BDiskSystem::SupportsMovingChild() const
|
|
||||||
{
|
|
||||||
return (InitCheck() == B_OK && IsPartitioningSystem()
|
|
||||||
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_MOVING_CHILD));
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportsSettingName
|
|
||||||
bool
|
|
||||||
BDiskSystem::SupportsSettingName() const
|
|
||||||
{
|
|
||||||
return (InitCheck() == B_OK && IsPartitioningSystem()
|
|
||||||
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_SETTING_NAME));
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportsSettingContentName
|
|
||||||
bool
|
|
||||||
BDiskSystem::SupportsSettingContentName(bool *whileMounted) const
|
|
||||||
{
|
|
||||||
if (InitCheck() != B_OK
|
|
||||||
|| !(fFlags & B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_NAME)) {
|
|
||||||
if (whileMounted)
|
|
||||||
*whileMounted = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (whileMounted) {
|
|
||||||
*whileMounted = (IsFileSystem()
|
|
||||||
&& (fFlags
|
|
||||||
& B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_NAME_WHILE_MOUNTED));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportsSettingType
|
|
||||||
bool
|
|
||||||
BDiskSystem::SupportsSettingType() const
|
|
||||||
{
|
|
||||||
return (InitCheck() == B_OK && IsPartitioningSystem()
|
|
||||||
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_SETTING_TYPE));
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportsSettingParameters
|
|
||||||
bool
|
|
||||||
BDiskSystem::SupportsSettingParameters() const
|
|
||||||
{
|
|
||||||
return (InitCheck() == B_OK && IsPartitioningSystem()
|
|
||||||
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_SETTING_PARAMETERS));
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportsSettingContentParameters
|
|
||||||
bool
|
|
||||||
BDiskSystem::SupportsSettingContentParameters(bool *whileMounted) const
|
|
||||||
{
|
|
||||||
if (InitCheck() != B_OK
|
|
||||||
|| !(fFlags & B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS)) {
|
|
||||||
if (whileMounted)
|
|
||||||
*whileMounted = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (whileMounted) {
|
|
||||||
*whileMounted = (IsFileSystem()
|
|
||||||
&& (fFlags
|
|
||||||
& B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS_WHILE_MOUNTED));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportsCreatingChild
|
|
||||||
bool
|
|
||||||
BDiskSystem::SupportsCreatingChild() const
|
|
||||||
{
|
|
||||||
return (InitCheck() == B_OK && IsPartitioningSystem()
|
|
||||||
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD));
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportsDeletingChild
|
|
||||||
bool
|
|
||||||
BDiskSystem::SupportsDeletingChild() const
|
|
||||||
{
|
|
||||||
return (InitCheck() == B_OK && IsPartitioningSystem()
|
|
||||||
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD));
|
|
||||||
}
|
|
||||||
|
|
||||||
// SupportsInitializing
|
|
||||||
bool
|
|
||||||
BDiskSystem::SupportsInitializing() const
|
|
||||||
{
|
|
||||||
return (InitCheck() == B_OK
|
|
||||||
&& (fFlags & B_DISK_SYSTEM_SUPPORTS_INITIALIZING));
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNextSupportedType
|
|
||||||
status_t
|
|
||||||
BDiskSystem::GetNextSupportedType(BPartition *partition, int32 *cookie,
|
|
||||||
char *type) const
|
|
||||||
{
|
|
||||||
if (InitCheck() != B_OK)
|
|
||||||
return InitCheck();
|
|
||||||
if (!cookie || !type || !partition || !partition->_IsShadow()
|
|
||||||
|| !partition->Parent() || partition->Parent()->_DiskSystem() != fID
|
|
||||||
|| !IsPartitioningSystem()) {
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
}
|
|
||||||
return _kern_get_next_supported_partition_type(partition->_ShadowID(),
|
|
||||||
partition->_ChangeCounter(),
|
|
||||||
cookie, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetTypeForContentType
|
|
||||||
status_t
|
|
||||||
BDiskSystem::GetTypeForContentType(const char *contentType, char *type) const
|
|
||||||
{
|
|
||||||
if (InitCheck() != B_OK)
|
|
||||||
return InitCheck();
|
|
||||||
if (!contentType || !type || !IsPartitioningSystem())
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
return _kern_get_partition_type_for_content_type(fID, contentType, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsPartitioningSystem
|
|
||||||
bool
|
|
||||||
BDiskSystem::IsPartitioningSystem() const
|
|
||||||
{
|
|
||||||
return (InitCheck() == B_OK && !(fFlags & B_DISK_SYSTEM_IS_FILE_SYSTEM));
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsFileSystem
|
|
||||||
bool
|
|
||||||
BDiskSystem::IsFileSystem() const
|
|
||||||
{
|
|
||||||
return (InitCheck() == B_OK && (fFlags & B_DISK_SYSTEM_IS_FILE_SYSTEM));
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsSubSystemFor
|
|
||||||
bool
|
|
||||||
BDiskSystem::IsSubSystemFor(BPartition *parent) const
|
|
||||||
{
|
|
||||||
return (InitCheck() == B_OK
|
|
||||||
&& parent && parent->_IsShadow()
|
|
||||||
&& _kern_is_sub_disk_system_for(fID, parent->_ShadowID(),
|
|
||||||
parent->_ChangeCounter()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// _SetTo
|
|
||||||
status_t
|
|
||||||
BDiskSystem::_SetTo(disk_system_id id)
|
|
||||||
{
|
|
||||||
_Unset();
|
|
||||||
if (id < 0)
|
|
||||||
return fID;
|
|
||||||
user_disk_system_info info;
|
|
||||||
status_t error = _kern_get_disk_system_info(id, &info);
|
|
||||||
if (error != B_OK)
|
|
||||||
return (fID = error);
|
|
||||||
return _SetTo(&info);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _SetTo
|
|
||||||
status_t
|
|
||||||
BDiskSystem::_SetTo(user_disk_system_info *info)
|
|
||||||
{
|
|
||||||
_Unset();
|
|
||||||
if (!info)
|
|
||||||
return (fID = B_BAD_VALUE);
|
|
||||||
fID = info->id;
|
|
||||||
fName = info->name;
|
|
||||||
fPrettyName = info->pretty_name;
|
|
||||||
fFlags = info->flags;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _Unset
|
|
||||||
void
|
|
||||||
BDiskSystem::_Unset()
|
|
||||||
{
|
|
||||||
fID = B_NO_INIT;
|
|
||||||
fName = (const char*)NULL;
|
|
||||||
fPrettyName = (const char*)NULL;
|
|
||||||
fFlags = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,722 +0,0 @@
|
|||||||
// LibBeAdapter.cpp
|
|
||||||
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <new>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include <Directory.h>
|
|
||||||
#include <Entry.h>
|
|
||||||
#include <fs_attr.h>
|
|
||||||
#include <fs_query.h>
|
|
||||||
#include <Path.h>
|
|
||||||
|
|
||||||
#include <syscalls.h>
|
|
||||||
|
|
||||||
|
|
||||||
mode_t __gUmask = 022;
|
|
||||||
// this is the standard umask and is used by BFile
|
|
||||||
|
|
||||||
enum {
|
|
||||||
FD_TYPE_UNKNOWN,
|
|
||||||
FD_TYPE_DIR,
|
|
||||||
FD_TYPE_ATTR_DIR,
|
|
||||||
FD_TYPE_QUERY,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int kFDTableSlotCount = 1024;
|
|
||||||
static uint8 sFDTable[kFDTableSlotCount];
|
|
||||||
|
|
||||||
static struct InitDirFDTable {
|
|
||||||
InitDirFDTable()
|
|
||||||
{
|
|
||||||
memset(sFDTable, FD_TYPE_UNKNOWN, sizeof(sFDTable));
|
|
||||||
}
|
|
||||||
} sInitDirFDTable;
|
|
||||||
|
|
||||||
// _kern_entry_ref_to_path
|
|
||||||
extern "C"
|
|
||||||
status_t
|
|
||||||
_kern_entry_ref_to_path(dev_t device, ino_t inode, const char *leaf,
|
|
||||||
char *userPath, size_t pathLength)
|
|
||||||
{
|
|
||||||
// check buffer
|
|
||||||
if (!userPath)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
// construct an entry_ref
|
|
||||||
if (!leaf)
|
|
||||||
leaf = ".";
|
|
||||||
entry_ref ref(device, inode, leaf);
|
|
||||||
// get the path
|
|
||||||
BPath path;
|
|
||||||
status_t error = path.SetTo(&ref);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
// copy the path into the buffer
|
|
||||||
if (strlcpy(userPath, path.Path(), pathLength) >= pathLength)
|
|
||||||
return B_BUFFER_OVERFLOW;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Syscall mapping between R5 and us
|
|
||||||
|
|
||||||
// private libroot.so functions
|
|
||||||
|
|
||||||
extern "C" status_t _kclosedir_(int fd);
|
|
||||||
|
|
||||||
extern "C" status_t _kclose_attr_dir_(int fd);
|
|
||||||
|
|
||||||
extern "C" status_t _kclose_query_(int fd);
|
|
||||||
|
|
||||||
extern "C" ssize_t _kreadlink_(int fd, const char *path, char *buffer,
|
|
||||||
size_t bufferSize);
|
|
||||||
|
|
||||||
extern "C" status_t _krstat_(int fd, const char *path, struct stat *st,
|
|
||||||
int16 unknown);
|
|
||||||
|
|
||||||
extern "C" status_t _kwstat_(int fd, const char *path, const struct stat *st,
|
|
||||||
uint32 mask, uint16 unknown);
|
|
||||||
|
|
||||||
extern "C" status_t _kwfsstat_(dev_t device, const struct fs_info *info,
|
|
||||||
long mask);
|
|
||||||
|
|
||||||
extern "C" status_t _klock_node_(int fd);
|
|
||||||
|
|
||||||
extern "C" status_t _kunlock_node_(int fd);
|
|
||||||
|
|
||||||
extern "C" status_t _kstart_watching_vnode_(dev_t device, ino_t node,
|
|
||||||
uint32 flags, port_id port,
|
|
||||||
int32 handlerToken);
|
|
||||||
|
|
||||||
extern "C" status_t _kstop_watching_vnode_(dev_t device, ino_t node,
|
|
||||||
port_id port, int32 handlerToken);
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" status_t _kstop_notifying_(port_id port, int32 handlerToken);
|
|
||||||
|
|
||||||
extern "C" status_t _kget_safemode_option_(const char *parameter, char *buffer, size_t *_bufferSize);
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
_kern_write_fs_info(dev_t device, const struct fs_info *info, int mask)
|
|
||||||
{
|
|
||||||
return _kwfsstat_(device, info, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
_kern_stop_notifying(port_id port, uint32 token)
|
|
||||||
{
|
|
||||||
return _kstop_notifying_(port, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
_kern_start_watching(dev_t device, ino_t node, uint32 flags,
|
|
||||||
port_id port, uint32 token)
|
|
||||||
{
|
|
||||||
return _kstart_watching_vnode_(device, node, flags, port, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
_kern_stop_watching(dev_t device, ino_t node, uint32 flags,
|
|
||||||
port_id port, uint32 token)
|
|
||||||
{
|
|
||||||
(void)flags;
|
|
||||||
return _kstop_watching_vnode_(device, node, port, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
// init_dir
|
|
||||||
static
|
|
||||||
status_t
|
|
||||||
init_dir(BDirectory &dir, int fd)
|
|
||||||
{
|
|
||||||
// get a node_ref for the dir
|
|
||||||
struct stat st;
|
|
||||||
if (fstat(fd, &st) < 0)
|
|
||||||
return errno;
|
|
||||||
node_ref ref;
|
|
||||||
ref.device = st.st_dev;
|
|
||||||
ref.node = st.st_ino;
|
|
||||||
// init the dir
|
|
||||||
return dir.SetTo(&ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
// open_dir_hack
|
|
||||||
static
|
|
||||||
int
|
|
||||||
open_dir_hack(const char *path)
|
|
||||||
{
|
|
||||||
DIR *dirHandle = opendir(path);
|
|
||||||
if (!dirHandle)
|
|
||||||
return errno;
|
|
||||||
int dirFD = dirHandle->fd;
|
|
||||||
if (dirFD < 0 || dirFD >= kFDTableSlotCount) {
|
|
||||||
closedir(dirHandle);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
free(dirHandle);
|
|
||||||
sFDTable[dirFD] = FD_TYPE_DIR;
|
|
||||||
return dirFD;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get_path
|
|
||||||
static
|
|
||||||
int
|
|
||||||
get_path(int fd, const char *relPath, BPath &path)
|
|
||||||
{
|
|
||||||
if (fd < 0 || relPath && relPath[0] == '/')
|
|
||||||
return path.SetTo(relPath);
|
|
||||||
BDirectory dir;
|
|
||||||
status_t error = init_dir(dir, fd);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
return path.SetTo(&dir, relPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_open
|
|
||||||
extern "C"
|
|
||||||
int
|
|
||||||
_kern_open(int fd, const char *path, int omode, int permissions)
|
|
||||||
{
|
|
||||||
status_t error;
|
|
||||||
BPath fullPath;
|
|
||||||
if (!path)
|
|
||||||
path = ".";
|
|
||||||
if (fd >= 0) {
|
|
||||||
// construct the full path
|
|
||||||
error = get_path(fd, path, fullPath);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
path = fullPath.Path();
|
|
||||||
}
|
|
||||||
// open the file
|
|
||||||
int result = open(path, omode, permissions);
|
|
||||||
if (result < 0)
|
|
||||||
return errno;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// _kern_open_entry_ref
|
|
||||||
extern "C"
|
|
||||||
int
|
|
||||||
_kern_open_entry_ref(dev_t device, ino_t inode, const char *name, int omode,
|
|
||||||
int permissions)
|
|
||||||
{
|
|
||||||
BPath fullPath;
|
|
||||||
node_ref ref;
|
|
||||||
ref.device = device;
|
|
||||||
ref.node = inode;
|
|
||||||
// init the dir and get the path
|
|
||||||
BDirectory dir;
|
|
||||||
status_t error = dir.SetTo(&ref);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
error = fullPath.SetTo(&dir, name);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
// open the file
|
|
||||||
int fd = open(fullPath.Path(), omode, permissions);
|
|
||||||
if (fd < 0)
|
|
||||||
return errno;
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_open_dir
|
|
||||||
extern "C"
|
|
||||||
int
|
|
||||||
_kern_open_dir(int fd, const char *path)
|
|
||||||
{
|
|
||||||
status_t error;
|
|
||||||
BPath fullPath;
|
|
||||||
if (fd >= 0) {
|
|
||||||
if (!path)
|
|
||||||
return _kern_dup(fd);
|
|
||||||
// construct the full path
|
|
||||||
error = get_path(fd, path, fullPath);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
path = fullPath.Path();
|
|
||||||
}
|
|
||||||
// open the dir
|
|
||||||
return open_dir_hack(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_open_dir_entry_ref
|
|
||||||
extern "C"
|
|
||||||
int
|
|
||||||
_kern_open_dir_entry_ref(dev_t device, ino_t inode, const char *path)
|
|
||||||
{
|
|
||||||
BPath fullPath;
|
|
||||||
node_ref ref;
|
|
||||||
ref.device = device;
|
|
||||||
ref.node = inode;
|
|
||||||
// init the dir and get the path
|
|
||||||
BDirectory dir;
|
|
||||||
status_t error = dir.SetTo(&ref);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
error = fullPath.SetTo(&dir, path);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
path = fullPath.Path();
|
|
||||||
// open the dir
|
|
||||||
return open_dir_hack(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_open_parent_dir
|
|
||||||
extern "C"
|
|
||||||
int
|
|
||||||
_kern_open_parent_dir(int fd, char *name, size_t pathLength)
|
|
||||||
{
|
|
||||||
if (fd < 0)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
// get the dir
|
|
||||||
BDirectory dir;
|
|
||||||
status_t error = init_dir(dir, fd);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
// get an entry
|
|
||||||
BEntry entry;
|
|
||||||
error = entry.SetTo(&dir, NULL);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
// copy back the path
|
|
||||||
if (name) {
|
|
||||||
char tmpName[B_FILE_NAME_LENGTH];
|
|
||||||
error = entry.GetName(tmpName);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
if (strlcpy(name, tmpName, pathLength) >= pathLength)
|
|
||||||
return B_BUFFER_OVERFLOW;
|
|
||||||
}
|
|
||||||
// get the parent dir path
|
|
||||||
BPath path;
|
|
||||||
error = path.SetTo(&dir, "..");
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
// open the dir
|
|
||||||
return open_dir_hack(path.Path());
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_open_query
|
|
||||||
extern "C"
|
|
||||||
int
|
|
||||||
_kern_open_query(dev_t device, const char *query, size_t queryLength, uint32 flags, port_id port,
|
|
||||||
int32 token)
|
|
||||||
{
|
|
||||||
// check params
|
|
||||||
if (!query || queryLength == 0 || device < 0)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
if (flags & B_LIVE_QUERY && port < 0)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
// open query
|
|
||||||
DIR *dirHandle;
|
|
||||||
if (flags & B_LIVE_QUERY)
|
|
||||||
dirHandle = fs_open_live_query(device, query, flags, port, token);
|
|
||||||
else
|
|
||||||
dirHandle = fs_open_query(device, query, flags);
|
|
||||||
if (!dirHandle)
|
|
||||||
return errno;
|
|
||||||
// get FD and return result
|
|
||||||
int dirFD = dirHandle->fd;
|
|
||||||
if (dirFD < 0 || dirFD >= kFDTableSlotCount) {
|
|
||||||
fs_close_query(dirHandle);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
free(dirHandle);
|
|
||||||
sFDTable[dirFD] = FD_TYPE_QUERY;
|
|
||||||
return dirFD;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_create_dir
|
|
||||||
extern "C"
|
|
||||||
status_t
|
|
||||||
_kern_create_dir(int fd, const char *path, int perms)
|
|
||||||
{
|
|
||||||
if (!path)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
status_t error;
|
|
||||||
BPath fullPath;
|
|
||||||
if (fd >= 0) {
|
|
||||||
// construct the full path
|
|
||||||
error = get_path(fd, path, fullPath);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
path = fullPath.Path();
|
|
||||||
}
|
|
||||||
// create the dir
|
|
||||||
return (mkdir(path, perms) < 0 ? errno : B_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_create_symlink
|
|
||||||
extern "C"
|
|
||||||
status_t
|
|
||||||
_kern_create_symlink(int fd, const char *path, const char *toPath, int mode)
|
|
||||||
{
|
|
||||||
(void)mode;
|
|
||||||
if (!path)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
status_t error;
|
|
||||||
BPath fullPath;
|
|
||||||
if (fd >= 0) {
|
|
||||||
// construct the full path
|
|
||||||
error = get_path(fd, path, fullPath);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
path = fullPath.Path();
|
|
||||||
}
|
|
||||||
// create the symlink
|
|
||||||
return (symlink(toPath, path) < 0 ? errno : B_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_close
|
|
||||||
extern "C"
|
|
||||||
status_t
|
|
||||||
_kern_close(int fd)
|
|
||||||
{
|
|
||||||
if (fd >= 0 && fd < kFDTableSlotCount && sFDTable[fd] != FD_TYPE_UNKNOWN) {
|
|
||||||
status_t error;
|
|
||||||
switch (sFDTable[fd]) {
|
|
||||||
case FD_TYPE_DIR:
|
|
||||||
error = _kclosedir_(fd);
|
|
||||||
break;
|
|
||||||
case FD_TYPE_ATTR_DIR:
|
|
||||||
error = _kclose_attr_dir_(fd);
|
|
||||||
break;
|
|
||||||
case FD_TYPE_QUERY:
|
|
||||||
error = _kclose_query_(fd);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error = B_BAD_VALUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
sFDTable[fd] = FD_TYPE_UNKNOWN;
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
} else if (close(fd) < 0)
|
|
||||||
return errno;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_dup
|
|
||||||
extern "C"
|
|
||||||
int
|
|
||||||
_kern_dup(int fd)
|
|
||||||
{
|
|
||||||
int clonedFD = dup(fd);
|
|
||||||
if (clonedFD < 0)
|
|
||||||
return errno;
|
|
||||||
if (fd >= 0 && fd < kFDTableSlotCount && sFDTable[fd] != FD_TYPE_UNKNOWN
|
|
||||||
&& clonedFD >= 0 && clonedFD < kFDTableSlotCount) {
|
|
||||||
sFDTable[clonedFD] = sFDTable[fd];
|
|
||||||
}
|
|
||||||
return clonedFD;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_read
|
|
||||||
extern "C"
|
|
||||||
ssize_t
|
|
||||||
_kern_read(int fd, off_t pos, void *buffer, size_t bufferSize)
|
|
||||||
{
|
|
||||||
if (!buffer)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
ssize_t result;
|
|
||||||
if (pos == -1)
|
|
||||||
result = read(fd, buffer, bufferSize);
|
|
||||||
else
|
|
||||||
result = read_pos(fd, pos, buffer, bufferSize);
|
|
||||||
return (result < 0 ? errno : result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_write
|
|
||||||
extern "C"
|
|
||||||
ssize_t
|
|
||||||
_kern_write(int fd, off_t pos, const void *buffer, size_t bufferSize)
|
|
||||||
{
|
|
||||||
if (!buffer)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
ssize_t result;
|
|
||||||
if (pos == -1)
|
|
||||||
result = write(fd, buffer, bufferSize);
|
|
||||||
else
|
|
||||||
result = write_pos(fd, pos, buffer, bufferSize);
|
|
||||||
return (result < 0 ? errno : result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_seek
|
|
||||||
extern "C"
|
|
||||||
off_t
|
|
||||||
_kern_seek(int fd, off_t pos, int seekType)
|
|
||||||
{
|
|
||||||
off_t result = lseek(fd, pos, seekType);
|
|
||||||
return (result < 0 ? errno : result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_read_dir
|
|
||||||
extern "C"
|
|
||||||
ssize_t
|
|
||||||
_kern_read_dir(int fd, struct dirent *buffer, size_t bufferSize,
|
|
||||||
uint32 maxCount)
|
|
||||||
{
|
|
||||||
if (fd < 0 || !buffer)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
if (fd >= kFDTableSlotCount || sFDTable[fd] == FD_TYPE_UNKNOWN)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
if (maxCount < 1)
|
|
||||||
return 0;
|
|
||||||
char tmpBuffer[sizeof(struct dirent) + B_FILE_NAME_LENGTH];
|
|
||||||
DIR *dirDir = (DIR*)tmpBuffer;
|
|
||||||
dirDir->fd = fd;
|
|
||||||
dirent *entry = NULL;
|
|
||||||
switch (sFDTable[fd]) {
|
|
||||||
case FD_TYPE_DIR:
|
|
||||||
entry = readdir(dirDir);
|
|
||||||
break;
|
|
||||||
case FD_TYPE_ATTR_DIR:
|
|
||||||
entry = fs_read_attr_dir(dirDir);
|
|
||||||
break;
|
|
||||||
case FD_TYPE_QUERY:
|
|
||||||
entry = fs_read_query(dirDir);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!entry)
|
|
||||||
return 0;
|
|
||||||
// Don't trust entry->d_reclen.
|
|
||||||
// Unlike stated in BeBook::BEntryList, the value is not the length
|
|
||||||
// of the whole structure, but only of the name. Some FSs count
|
|
||||||
// the terminating '\0', others don't.
|
|
||||||
// So we calculate the size ourselves (including the '\0'):
|
|
||||||
size_t entryLen = entry->d_name + strlen(entry->d_name) + 1
|
|
||||||
- (char*)entry;
|
|
||||||
if (bufferSize >= entryLen) {
|
|
||||||
memcpy(buffer, entry, entryLen);
|
|
||||||
return 1;
|
|
||||||
} else // buffer too small
|
|
||||||
return B_BUFFER_OVERFLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_rewind_dir
|
|
||||||
extern "C"
|
|
||||||
status_t
|
|
||||||
_kern_rewind_dir(int fd)
|
|
||||||
{
|
|
||||||
if (fd < 0 || fd >= kFDTableSlotCount || sFDTable[fd] == FD_TYPE_UNKNOWN)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
char tmpBuffer[sizeof(struct dirent) + B_FILE_NAME_LENGTH];
|
|
||||||
DIR *dirDir = (DIR*)tmpBuffer;
|
|
||||||
dirDir->fd = fd;
|
|
||||||
switch (sFDTable[fd]) {
|
|
||||||
case FD_TYPE_DIR:
|
|
||||||
rewinddir(dirDir);
|
|
||||||
break;
|
|
||||||
case FD_TYPE_ATTR_DIR:
|
|
||||||
fs_rewind_attr_dir(dirDir);
|
|
||||||
break;
|
|
||||||
case FD_TYPE_QUERY:
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_read_link
|
|
||||||
extern "C"
|
|
||||||
status_t
|
|
||||||
_kern_read_link(int fd, const char *path, char *buffer, size_t *_bufferSize)
|
|
||||||
{
|
|
||||||
ssize_t result = _kreadlink_(fd, path, buffer, *_bufferSize);
|
|
||||||
if (result < 0)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
buffer[result] = '\0';
|
|
||||||
*_bufferSize = result;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_unlink
|
|
||||||
extern "C"
|
|
||||||
status_t
|
|
||||||
_kern_unlink(int fd, const char *relPath)
|
|
||||||
{
|
|
||||||
BPath path;
|
|
||||||
status_t error = get_path(fd, relPath, path);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
if (unlink(path.Path()) < 0) {
|
|
||||||
error = errno;
|
|
||||||
if (error == B_IS_A_DIRECTORY) {
|
|
||||||
if (rmdir(path.Path()) < 0)
|
|
||||||
return errno;
|
|
||||||
} else
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_rename
|
|
||||||
extern "C"
|
|
||||||
status_t
|
|
||||||
_kern_rename(int oldDir, const char *oldRelPath, int newDir,
|
|
||||||
const char *newRelPath)
|
|
||||||
{
|
|
||||||
// get old path
|
|
||||||
BPath oldPath;
|
|
||||||
status_t error = get_path(oldDir, oldRelPath, oldPath);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
// get new path
|
|
||||||
BPath newPath;
|
|
||||||
error = get_path(newDir, newRelPath, newPath);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
// rename
|
|
||||||
if (rename(oldPath.Path(), newPath.Path()) < 0)
|
|
||||||
return errno;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// _kern_read_stat
|
|
||||||
extern "C"
|
|
||||||
status_t
|
|
||||||
_kern_read_stat(int fd, const char *path, bool traverseLink, struct stat *st,
|
|
||||||
size_t statSize)
|
|
||||||
{
|
|
||||||
if (traverseLink)
|
|
||||||
return B_ERROR; // unsupported
|
|
||||||
return _krstat_(fd, path, st, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_write_stat
|
|
||||||
extern "C"
|
|
||||||
status_t
|
|
||||||
_kern_write_stat(int fd, const char *path, bool traverseLink,
|
|
||||||
const struct stat *st, size_t statSize, int statMask)
|
|
||||||
{
|
|
||||||
if (traverseLink)
|
|
||||||
return B_ERROR; // unsupported
|
|
||||||
return _kwstat_(fd, path, st, statMask, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_lock_node
|
|
||||||
extern "C"
|
|
||||||
status_t
|
|
||||||
_kern_lock_node(int fd)
|
|
||||||
{
|
|
||||||
return _klock_node_(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_unlock_node
|
|
||||||
extern "C"
|
|
||||||
status_t
|
|
||||||
_kern_unlock_node(int fd)
|
|
||||||
{
|
|
||||||
return _kunlock_node_(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_fsync
|
|
||||||
extern "C"
|
|
||||||
status_t
|
|
||||||
_kern_fsync(int fd)
|
|
||||||
{
|
|
||||||
return (fsync(fd) < 0) ? errno : B_OK ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_open_attr_dir
|
|
||||||
extern "C"
|
|
||||||
int
|
|
||||||
_kern_open_attr_dir(int fd, const char *path)
|
|
||||||
{
|
|
||||||
if (fd < 0 && !path)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
if (fd >= 0 && path)
|
|
||||||
return B_ERROR; // unsupported
|
|
||||||
DIR *dirHandle = (fd >= 0 ? fs_fopen_attr_dir(fd) : fs_open_attr_dir(path));
|
|
||||||
if (!dirHandle)
|
|
||||||
return errno;
|
|
||||||
int dirFD = dirHandle->fd;
|
|
||||||
if (dirFD < 0 || dirFD >= kFDTableSlotCount) {
|
|
||||||
fs_close_attr_dir(dirHandle);
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
free(dirHandle);
|
|
||||||
sFDTable[dirFD] = FD_TYPE_ATTR_DIR;
|
|
||||||
return dirFD;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_remove_attr
|
|
||||||
extern "C"
|
|
||||||
status_t
|
|
||||||
_kern_remove_attr(int fd, const char *name)
|
|
||||||
{
|
|
||||||
return fs_remove_attr(fd, name) == -1 ? errno : B_OK ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _kern_rename_attr
|
|
||||||
extern "C"
|
|
||||||
status_t
|
|
||||||
_kern_rename_attr(int fromFile, const char *fromName, int toFile,
|
|
||||||
const char *toName)
|
|
||||||
{
|
|
||||||
status_t error = (fromName && toName ? B_OK : B_BAD_VALUE);
|
|
||||||
// Figure out how much data there is
|
|
||||||
attr_info info;
|
|
||||||
if (error == B_OK) {
|
|
||||||
if (fs_stat_attr(fromFile, fromName, &info) < 0)
|
|
||||||
error = B_BAD_VALUE; // This is what R5::BNode returns...
|
|
||||||
}
|
|
||||||
// Alloc a buffer
|
|
||||||
char *data = NULL;
|
|
||||||
if (error == B_OK) {
|
|
||||||
// alloc at least one byte
|
|
||||||
data = new(nothrow) char[info.size >= 1 ? info.size : 1];
|
|
||||||
if (data == NULL)
|
|
||||||
error = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
// Read in the data
|
|
||||||
if (error == B_OK) {
|
|
||||||
ssize_t size = fs_read_attr(fromFile, fromName, info.type, 0, data,
|
|
||||||
info.size);
|
|
||||||
if (size != info.size) {
|
|
||||||
if (size < 0)
|
|
||||||
error = errno;
|
|
||||||
else
|
|
||||||
error = B_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Write it to the new attribute
|
|
||||||
if (error == B_OK) {
|
|
||||||
ssize_t size = 0;
|
|
||||||
if (info.size > 0)
|
|
||||||
size = fs_write_attr(toFile, toName, info.type, 0, data, info.size);
|
|
||||||
if (size != info.size) {
|
|
||||||
if (size < 0)
|
|
||||||
error = errno;
|
|
||||||
else
|
|
||||||
error = B_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// free the buffer
|
|
||||||
if (data)
|
|
||||||
delete[] data;
|
|
||||||
// Remove the old attribute
|
|
||||||
if (error == B_OK)
|
|
||||||
error = _kern_remove_attr(fromFile, fromName);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" status_t
|
|
||||||
_kern_get_safemode_option(const char *parameter, char *buffer, size_t *_bufferSize)
|
|
||||||
{
|
|
||||||
return _kget_safemode_option_(parameter, buffer, _bufferSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
Notes concerning the OpenBeOS implementation of BNode:
|
|
||||||
1. GetNextAttrName returns B_BAD_VALUE when passed a NULL pointer instead of crashing
|
|
||||||
2. R5::BNode returns B_BAD_ADDRESS when RewindAttrs() fails (not B_FILE_ERROR as claimed in the BeBook). We currently follow suit.
|
|
||||||
3. RenameAttr() actually works, whereas the R5 version doesn't (apparently because BFS doesn't implement it directly...).
|
|
||||||
4. Write/ReadAttrString() functions need to be documented (they aren't in the R5 BeBook).
|
|
||||||
5. ReadAttrString() adds an extra NULL char to the end of the string it reads as a precaution before handing it back to the BString result, since it's possible to read a non-NULL-terminated string of characters from an attribute.
|
|
||||||
6. Write/ReadAttrString() can't be tested until we have an OpenBeOS implementation of BString.
|
|
||||||
7. Dup() should be declared const, but it isn't by R5, so our implementation follows suit.
|
|
||||||
8. Locking is not supported by the Posix implemention of OpenBeOS BNode, due to fcntl(fd, F_SETLK, ...) not being implemented in R5.
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,169 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
|
||||||
// by the OpenBeOS license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include <AppMisc.h>
|
|
||||||
#include <Looper.h>
|
|
||||||
#include <Messenger.h>
|
|
||||||
#include <NodeMonitor.h>
|
|
||||||
|
|
||||||
#include <syscalls.h>
|
|
||||||
|
|
||||||
// TODO: Tests!
|
|
||||||
|
|
||||||
|
|
||||||
// watch_node
|
|
||||||
/*! \brief Subscribes a target to node and/or mount watching, or unsubscribes
|
|
||||||
it from node watching.
|
|
||||||
|
|
||||||
Depending of \a flags the action performed by this function varies:
|
|
||||||
- \a flags is \c 0: The target is unsubscribed from watching the node.
|
|
||||||
\a node must not be \c NULL in this case.
|
|
||||||
- \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount
|
|
||||||
watching.
|
|
||||||
- \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT,
|
|
||||||
\c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to
|
|
||||||
watching the specified aspects of the node. \a node must not be \c NULL
|
|
||||||
in this case.
|
|
||||||
|
|
||||||
Note, that the latter two cases are not mutual exlusive, i.e. mount and
|
|
||||||
node watching can be requested with a single call.
|
|
||||||
|
|
||||||
\param node node_ref referring to the node to be watched. May be \c NULL,
|
|
||||||
if only mount watching is requested.
|
|
||||||
\param flags Flags indicating the actions to be performed.
|
|
||||||
\param target Messenger referring to the target. Must be valid.
|
|
||||||
\return \c B_OK, if everything went fine, another error code otherwise.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
watch_node(const node_ref *node, uint32 flags, BMessenger target)
|
|
||||||
{
|
|
||||||
status_t error = (target.IsValid() ? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK) {
|
|
||||||
BLooper *looper = NULL;
|
|
||||||
BHandler *handler = target.Target(&looper);
|
|
||||||
error = watch_node(node, flags, handler, looper);
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// watch_node
|
|
||||||
/*! \brief Subscribes a target to node and/or mount watching, or unsubscribes
|
|
||||||
it from node watching.
|
|
||||||
|
|
||||||
Depending of \a flags the action performed by this function varies:
|
|
||||||
- \a flags is \c 0: The target is unsubscribed from watching the node.
|
|
||||||
\a node must not be \c NULL in this case.
|
|
||||||
- \a flags contains \c B_WATCH_MOUNT: The target is subscribed to mount
|
|
||||||
watching.
|
|
||||||
- \a flags contains at least one of \c B_WATCH_NAME, \c B_WATCH_STAT,
|
|
||||||
\c B_WATCH_ATTR, or \c B_WATCH_DIRECTORY: The target is subscribed to
|
|
||||||
watching the specified aspects of the node. \a node must not be \c NULL
|
|
||||||
in this case.
|
|
||||||
|
|
||||||
Note, that the latter two cases are not mutual exlusive, i.e. mount and
|
|
||||||
node watching can be requested with a single call.
|
|
||||||
|
|
||||||
\param node node_ref referring to the node to be watched. May be \c NULL,
|
|
||||||
if only mount watching is requested.
|
|
||||||
\param flags Flags indicating the actions to be performed.
|
|
||||||
\param handler The target handler. May be \c NULL, if \a looper is not
|
|
||||||
\c NULL. Then the preferred handler of the looper is targeted.
|
|
||||||
\param looper The target looper. May be \c NULL, if \a handler is not
|
|
||||||
\c NULL. Then the handler's looper is the target looper.
|
|
||||||
\return \c B_OK, if everything went fine, another error code otherwise.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
watch_node(const node_ref *node, uint32 flags, const BHandler *handler,
|
|
||||||
const BLooper *looper)
|
|
||||||
{
|
|
||||||
status_t error = B_OK;
|
|
||||||
// check looper and handler and get the handler token
|
|
||||||
int32 handlerToken = -2;
|
|
||||||
if (handler) {
|
|
||||||
handlerToken = _get_object_token_(handler);
|
|
||||||
if (looper) {
|
|
||||||
if (looper != handler->Looper())
|
|
||||||
error = B_BAD_VALUE;
|
|
||||||
} else {
|
|
||||||
looper = handler->Looper();
|
|
||||||
if (!looper)
|
|
||||||
error = B_BAD_VALUE;
|
|
||||||
}
|
|
||||||
} else if (!looper)
|
|
||||||
error = B_BAD_VALUE;
|
|
||||||
if (error == B_OK) {
|
|
||||||
port_id port = _get_looper_port_(looper);
|
|
||||||
if (flags == B_STOP_WATCHING) {
|
|
||||||
// unsubscribe from node node watching
|
|
||||||
if (node)
|
|
||||||
error = _kern_stop_watching(node->device, node->node, flags, port, handlerToken);
|
|
||||||
else
|
|
||||||
error = B_BAD_VALUE;
|
|
||||||
} else {
|
|
||||||
// subscribe to...
|
|
||||||
// mount watching
|
|
||||||
if (flags & B_WATCH_MOUNT) {
|
|
||||||
error = _kern_start_watching((dev_t)-1, (ino_t)-1, 0, port, handlerToken);
|
|
||||||
flags &= ~B_WATCH_MOUNT;
|
|
||||||
}
|
|
||||||
// node watching
|
|
||||||
if (error == B_OK && flags)
|
|
||||||
error = _kern_start_watching(node->device, node->node, flags, port, handlerToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// stop_watching
|
|
||||||
/*! \brief Unsubscribes a target from node and mount monitoring.
|
|
||||||
\param target Messenger referring to the target. Must be valid.
|
|
||||||
\return \c B_OK, if everything went fine, another error code otherwise.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
stop_watching(BMessenger target)
|
|
||||||
{
|
|
||||||
status_t error = (target.IsValid() ? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK) {
|
|
||||||
BLooper *looper = NULL;
|
|
||||||
BHandler *handler = target.Target(&looper);
|
|
||||||
error = stop_watching(handler, looper);
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// stop_watching
|
|
||||||
/*! \brief Unsubscribes a target from node and mount monitoring.
|
|
||||||
\param handler The target handler. May be \c NULL, if \a looper is not
|
|
||||||
\c NULL. Then the preferred handler of the looper is targeted.
|
|
||||||
\param looper The target looper. May be \c NULL, if \a handler is not
|
|
||||||
\c NULL. Then the handler's looper is the target looper.
|
|
||||||
\return \c B_OK, if everything went fine, another error code otherwise.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
stop_watching(const BHandler *handler, const BLooper *looper)
|
|
||||||
{
|
|
||||||
status_t error = B_OK;
|
|
||||||
// check looper and handler and get the handler token
|
|
||||||
int32 handlerToken = -2;
|
|
||||||
if (handler) {
|
|
||||||
handlerToken = _get_object_token_(handler);
|
|
||||||
if (looper) {
|
|
||||||
if (looper != handler->Looper())
|
|
||||||
error = B_BAD_VALUE;
|
|
||||||
} else {
|
|
||||||
looper = handler->Looper();
|
|
||||||
if (!looper)
|
|
||||||
error = B_BAD_VALUE;
|
|
||||||
}
|
|
||||||
} else if (!looper)
|
|
||||||
error = B_BAD_VALUE;
|
|
||||||
// unsubscribe
|
|
||||||
if (error == B_OK) {
|
|
||||||
port_id port = _get_looper_port_(looper);
|
|
||||||
error = _kern_stop_notifying(port, handlerToken);
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,250 +0,0 @@
|
|||||||
#include "NodeMonitorHandler.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* static util functions for the super lazy
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/* static */ status_t
|
|
||||||
NodeMonitorHandler::make_entry_ref(dev_t device, ino_t directory,
|
|
||||||
const char * name,
|
|
||||||
entry_ref * ref)
|
|
||||||
{
|
|
||||||
ref->device = device;
|
|
||||||
ref->directory = directory;
|
|
||||||
return ref->set_name(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* static */ void
|
|
||||||
NodeMonitorHandler::make_node_ref(dev_t device, ino_t node, node_ref * ref)
|
|
||||||
{
|
|
||||||
ref->device = device;
|
|
||||||
ref->node = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* public functions: constructor, destructor, MessageReceived
|
|
||||||
*/
|
|
||||||
|
|
||||||
NodeMonitorHandler::NodeMonitorHandler(const char * name)
|
|
||||||
: BHandler(name)
|
|
||||||
{
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NodeMonitorHandler::~NodeMonitorHandler()
|
|
||||||
{
|
|
||||||
// nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ void
|
|
||||||
NodeMonitorHandler::MessageReceived(BMessage * msg)
|
|
||||||
{
|
|
||||||
status_t status = B_MESSAGE_NOT_UNDERSTOOD;
|
|
||||||
if (msg->what == B_NODE_MONITOR) {
|
|
||||||
int32 opcode;
|
|
||||||
if (msg->FindInt32("opcode", &opcode) == B_OK) {
|
|
||||||
switch (opcode) {
|
|
||||||
case B_ENTRY_CREATED:
|
|
||||||
status = HandleEntryCreated(msg);
|
|
||||||
break;
|
|
||||||
case B_ENTRY_REMOVED:
|
|
||||||
status = HandleEntryRemoved(msg);
|
|
||||||
break;
|
|
||||||
case B_ENTRY_MOVED:
|
|
||||||
status = HandleEntryMoved(msg);
|
|
||||||
break;
|
|
||||||
case B_STAT_CHANGED:
|
|
||||||
status = HandleStatChanged(msg);
|
|
||||||
break;
|
|
||||||
case B_ATTR_CHANGED:
|
|
||||||
status = HandleAttrChanged(msg);
|
|
||||||
break;
|
|
||||||
case B_DEVICE_MOUNTED:
|
|
||||||
status = HandleDeviceMounted(msg);
|
|
||||||
break;
|
|
||||||
case B_DEVICE_UNMOUNTED:
|
|
||||||
status = HandleDeviceUnmounted(msg);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (status == B_MESSAGE_NOT_UNDERSTOOD) {
|
|
||||||
inherited::MessageReceived(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* default virtual functions do nothing
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* virtual */ void
|
|
||||||
NodeMonitorHandler::EntryCreated(const char *name, ino_t directory,
|
|
||||||
dev_t device, ino_t node)
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ void
|
|
||||||
NodeMonitorHandler::EntryRemoved(ino_t directory, dev_t device, ino_t node)
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ void
|
|
||||||
NodeMonitorHandler::EntryMoved(const char *name, ino_t from_directory,
|
|
||||||
ino_t to_directory, dev_t device, ino_t node)
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ void
|
|
||||||
NodeMonitorHandler::StatChanged(ino_t node, dev_t device)
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ void
|
|
||||||
NodeMonitorHandler::AttrChanged(ino_t node, dev_t device)
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ void
|
|
||||||
NodeMonitorHandler::DeviceMounted(dev_t new_device, dev_t device,
|
|
||||||
ino_t directory)
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* virtual */ void
|
|
||||||
NodeMonitorHandler::DeviceUnmounted(dev_t new_device)
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* private functions to rip apart the corresponding BMessage
|
|
||||||
*/
|
|
||||||
|
|
||||||
status_t
|
|
||||||
NodeMonitorHandler::HandleEntryCreated(BMessage * msg)
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
ino_t directory;
|
|
||||||
dev_t device;
|
|
||||||
ino_t node;
|
|
||||||
if ((msg->FindString("name", &name) != B_OK) ||
|
|
||||||
(msg->FindInt64("directory", &directory) != B_OK) ||
|
|
||||||
(msg->FindInt32("device", &device) != B_OK) ||
|
|
||||||
(msg->FindInt64("node", &node) != B_OK)) {
|
|
||||||
return B_MESSAGE_NOT_UNDERSTOOD;
|
|
||||||
}
|
|
||||||
EntryCreated(name, directory, device, node);
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
NodeMonitorHandler::HandleEntryRemoved(BMessage * msg)
|
|
||||||
{
|
|
||||||
ino_t directory;
|
|
||||||
dev_t device;
|
|
||||||
ino_t node;
|
|
||||||
if ((msg->FindInt64("directory", &directory) != B_OK) ||
|
|
||||||
(msg->FindInt32("device", &device) != B_OK) ||
|
|
||||||
(msg->FindInt64("node", &node) != B_OK)) {
|
|
||||||
return B_MESSAGE_NOT_UNDERSTOOD;
|
|
||||||
}
|
|
||||||
EntryRemoved(directory, device, node);
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
NodeMonitorHandler::HandleEntryMoved(BMessage * msg)
|
|
||||||
{
|
|
||||||
const char *name;
|
|
||||||
ino_t from_directory;
|
|
||||||
ino_t to_directory;
|
|
||||||
dev_t device;
|
|
||||||
ino_t node;
|
|
||||||
if ((msg->FindString("name", &name) != B_OK) ||
|
|
||||||
(msg->FindInt64("from directory", &from_directory) != B_OK) ||
|
|
||||||
(msg->FindInt64("to directory", &to_directory) != B_OK) ||
|
|
||||||
(msg->FindInt32("device", &device) != B_OK) ||
|
|
||||||
(msg->FindInt64("node", &node) != B_OK)) {
|
|
||||||
return B_MESSAGE_NOT_UNDERSTOOD;
|
|
||||||
}
|
|
||||||
EntryMoved(name, from_directory, to_directory, device, node);
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
NodeMonitorHandler::HandleStatChanged(BMessage * msg)
|
|
||||||
{
|
|
||||||
ino_t node;
|
|
||||||
dev_t device;
|
|
||||||
if ((msg->FindInt64("node", &node) != B_OK) ||
|
|
||||||
(msg->FindInt32("device", &device) != B_OK)) {
|
|
||||||
return B_MESSAGE_NOT_UNDERSTOOD;
|
|
||||||
}
|
|
||||||
StatChanged(node, device);
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
NodeMonitorHandler::HandleAttrChanged(BMessage * msg)
|
|
||||||
{
|
|
||||||
ino_t node;
|
|
||||||
dev_t device;
|
|
||||||
if ((msg->FindInt64("node", &node) != B_OK) ||
|
|
||||||
(msg->FindInt32("device", &device) != B_OK)) {
|
|
||||||
return B_MESSAGE_NOT_UNDERSTOOD;
|
|
||||||
}
|
|
||||||
AttrChanged(node, device);
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
NodeMonitorHandler::HandleDeviceMounted(BMessage * msg)
|
|
||||||
{
|
|
||||||
dev_t new_device;
|
|
||||||
dev_t device;
|
|
||||||
ino_t directory;
|
|
||||||
if ((msg->FindInt32("new device", &new_device) != B_OK) ||
|
|
||||||
(msg->FindInt32("device", &device) != B_OK) ||
|
|
||||||
(msg->FindInt64("directory", &directory) != B_OK)) {
|
|
||||||
return B_MESSAGE_NOT_UNDERSTOOD;
|
|
||||||
}
|
|
||||||
DeviceMounted(new_device, device, directory);
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
|
||||||
NodeMonitorHandler::HandleDeviceUnmounted(BMessage * msg)
|
|
||||||
{
|
|
||||||
dev_t new_device;
|
|
||||||
if (msg->FindInt32("new device", &new_device) != B_OK) {
|
|
||||||
return B_MESSAGE_NOT_UNDERSTOOD;
|
|
||||||
}
|
|
||||||
DeviceUnmounted(new_device);
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,195 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
|
||||||
// by the OpenBeOS license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include <algobase.h>
|
|
||||||
#include <new.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <Button.h>
|
|
||||||
#include <DiskScannerAddOn.h>
|
|
||||||
#include <Screen.h>
|
|
||||||
#include <View.h>
|
|
||||||
|
|
||||||
#include "PartitioningDialog.h"
|
|
||||||
|
|
||||||
enum {
|
|
||||||
MSG_OK = 'okay',
|
|
||||||
MSG_CANCEL = 'cncl',
|
|
||||||
};
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
PartitioningDialog::PartitioningDialog(BRect dialogCenter)
|
|
||||||
: BWindow(BRect(100, 100, 100, 100), "Partitioning Parameters",
|
|
||||||
B_TITLED_WINDOW,
|
|
||||||
B_ASYNCHRONOUS_CONTROLS | B_QUIT_ON_WINDOW_CLOSE),
|
|
||||||
fEditor(NULL),
|
|
||||||
fEditorView(NULL),
|
|
||||||
fBlocker(-1),
|
|
||||||
fCancelled(NULL),
|
|
||||||
fCenter()
|
|
||||||
{
|
|
||||||
fBlocker = create_sem(0, "partitioning dialog blocker");
|
|
||||||
// calculate the dialog center point
|
|
||||||
if (!dialogCenter.IsValid())
|
|
||||||
dialogCenter = BScreen().Frame();
|
|
||||||
fCenter = dialogCenter.LeftTop() + dialogCenter.RightBottom();
|
|
||||||
fCenter.x /= 2;
|
|
||||||
fCenter.y /= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
PartitioningDialog::~PartitioningDialog()
|
|
||||||
{
|
|
||||||
if (fEditorView)
|
|
||||||
fEditorView->RemoveSelf();
|
|
||||||
if (fBlocker >= 0)
|
|
||||||
delete_sem(fBlocker);
|
|
||||||
}
|
|
||||||
|
|
||||||
// MessageReceived
|
|
||||||
void
|
|
||||||
PartitioningDialog::MessageReceived(BMessage *message)
|
|
||||||
{
|
|
||||||
switch (message->what) {
|
|
||||||
case MSG_OK:
|
|
||||||
{
|
|
||||||
if (fEditor->EditingDone()) {
|
|
||||||
if (fCancelled)
|
|
||||||
*fCancelled = false;
|
|
||||||
Quit();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MSG_CANCEL:
|
|
||||||
if (fCancelled)
|
|
||||||
*fCancelled = true;
|
|
||||||
Quit();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
BWindow::MessageReceived(message);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// QuitRequested
|
|
||||||
bool
|
|
||||||
PartitioningDialog::QuitRequested()
|
|
||||||
{
|
|
||||||
if (fCancelled)
|
|
||||||
*fCancelled = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go
|
|
||||||
status_t
|
|
||||||
PartitioningDialog::Go(BDiskScannerParameterEditor *editor, bool *_cancelled)
|
|
||||||
{
|
|
||||||
status_t error = _Init(editor);
|
|
||||||
bool wasRun = false;
|
|
||||||
// fire up the window
|
|
||||||
if (error == B_OK) {
|
|
||||||
if (fBlocker >= 0) {
|
|
||||||
sem_id blocker = fBlocker;
|
|
||||||
bool cancelled = true;
|
|
||||||
fCancelled = &cancelled;
|
|
||||||
Show();
|
|
||||||
wasRun = true;
|
|
||||||
acquire_sem(blocker);
|
|
||||||
if (cancelled)
|
|
||||||
error = B_ERROR;
|
|
||||||
if (_cancelled)
|
|
||||||
*_cancelled = cancelled;
|
|
||||||
} else
|
|
||||||
error = fBlocker;
|
|
||||||
}
|
|
||||||
// delete the window if not run
|
|
||||||
if (!wasRun)
|
|
||||||
delete this;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _Init
|
|
||||||
status_t
|
|
||||||
PartitioningDialog::_Init(BDiskScannerParameterEditor *editor)
|
|
||||||
{
|
|
||||||
status_t error = (editor ? B_OK : B_BAD_VALUE);
|
|
||||||
// set the parameter editor and view
|
|
||||||
if (error == B_OK) {
|
|
||||||
fEditor = editor;
|
|
||||||
fEditorView = editor->View();
|
|
||||||
if (!fEditorView)
|
|
||||||
error = B_ERROR;
|
|
||||||
}
|
|
||||||
// setup views
|
|
||||||
if (error == B_OK) {
|
|
||||||
BView *mainView = new(nothrow) BView(BRect(0, 0, 1, 1), "main",
|
|
||||||
B_FOLLOW_ALL, 0);
|
|
||||||
BMessage *okMessage = new BMessage(MSG_OK);
|
|
||||||
BMessage *cancelMessage = new BMessage(MSG_CANCEL);
|
|
||||||
BButton *okButton = new (nothrow) BButton(
|
|
||||||
BRect(0, 0, 1, 1), "ok", "OK", okMessage,
|
|
||||||
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
|
|
||||||
BButton *cancelButton = new (nothrow) BButton(
|
|
||||||
BRect(0, 0, 1, 1), "cancel", "Cancel", cancelMessage,
|
|
||||||
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
|
|
||||||
if (okMessage && cancelMessage && okButton && cancelButton) {
|
|
||||||
// add the views to the hierarchy
|
|
||||||
mainView->AddChild(fEditorView);
|
|
||||||
mainView->AddChild(okButton);
|
|
||||||
mainView->AddChild(cancelButton);
|
|
||||||
AddChild(mainView);
|
|
||||||
// set the buttons' preferred size
|
|
||||||
float buttonWidth = 0;
|
|
||||||
float buttonHeight = 0;
|
|
||||||
okButton->GetPreferredSize(&buttonWidth, &buttonHeight);
|
|
||||||
okButton->ResizeTo(buttonWidth, buttonHeight);
|
|
||||||
cancelButton->GetPreferredSize(&buttonWidth, &buttonHeight);
|
|
||||||
cancelButton->ResizeTo(buttonWidth, buttonHeight);
|
|
||||||
// setup their positions and sizes
|
|
||||||
int32 hSpacing = 10;
|
|
||||||
int32 vSpacing = 10;
|
|
||||||
BRect editorRect = fEditorView->Bounds();
|
|
||||||
BRect okRect = okButton->Bounds();
|
|
||||||
BRect cancelRect = cancelButton->Bounds();
|
|
||||||
// compute width and size of the main view
|
|
||||||
int32 width = max(editorRect.IntegerWidth() + 1,
|
|
||||||
okRect.IntegerWidth() + 1 + hSpacing
|
|
||||||
+ cancelRect.IntegerWidth() + 1)
|
|
||||||
+ 2 * hSpacing;
|
|
||||||
int32 height = editorRect.IntegerHeight() + 1
|
|
||||||
+ max(okRect.IntegerHeight(),
|
|
||||||
cancelRect.IntegerHeight()) + 1
|
|
||||||
+ 3 * vSpacing;
|
|
||||||
mainView->ResizeTo(width - 1, height -1);
|
|
||||||
ResizeTo(width - 1, height -1);
|
|
||||||
// set location of the editor view
|
|
||||||
fEditorView->MoveTo((width - editorRect.IntegerWidth() - 1) / 2,
|
|
||||||
vSpacing - 1);
|
|
||||||
fEditorView->ResizeTo(editorRect.Width(), editorRect.Height());
|
|
||||||
// set the location of the buttons
|
|
||||||
float buttonTop = 2 * vSpacing + editorRect.IntegerHeight();
|
|
||||||
float buttonLeft = width - hSpacing - okRect.IntegerWidth();
|
|
||||||
okButton->MoveTo(buttonLeft, buttonTop);
|
|
||||||
buttonLeft -= hSpacing + cancelRect.IntegerWidth();
|
|
||||||
cancelButton->MoveTo(buttonLeft, buttonTop);
|
|
||||||
} else {
|
|
||||||
// cleanup on error
|
|
||||||
error = B_NO_MEMORY;
|
|
||||||
if (!okButton && okMessage)
|
|
||||||
delete okMessage;
|
|
||||||
if (!cancelButton && cancelMessage)
|
|
||||||
delete cancelMessage;
|
|
||||||
if (okButton)
|
|
||||||
delete okButton;
|
|
||||||
if (cancelButton)
|
|
||||||
delete cancelButton;
|
|
||||||
if (mainView)
|
|
||||||
delete mainView;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
|
||||||
// by the OpenBeOS license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
#ifndef _PARTITIONING_DIALOG_H
|
|
||||||
#define _PARTITIONING_DIALOG_H
|
|
||||||
|
|
||||||
#include <OS.h>
|
|
||||||
#include <Window.h>
|
|
||||||
|
|
||||||
class BDiskScannerParameterEditor;
|
|
||||||
|
|
||||||
namespace BPrivate {
|
|
||||||
|
|
||||||
class PartitioningDialog : public BWindow {
|
|
||||||
public:
|
|
||||||
PartitioningDialog(BRect dialogCenter);
|
|
||||||
virtual ~PartitioningDialog();
|
|
||||||
|
|
||||||
virtual void MessageReceived(BMessage *message);
|
|
||||||
virtual bool QuitRequested();
|
|
||||||
|
|
||||||
status_t Go(BDiskScannerParameterEditor *editor, bool *cancelled);
|
|
||||||
|
|
||||||
private:
|
|
||||||
status_t _Init(BDiskScannerParameterEditor *editor);
|
|
||||||
|
|
||||||
private:
|
|
||||||
BDiskScannerParameterEditor *fEditor;
|
|
||||||
BView *fEditorView;
|
|
||||||
sem_id fBlocker;
|
|
||||||
bool *fCancelled;
|
|
||||||
BPoint fCenter;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace BPrivate
|
|
||||||
|
|
||||||
using BPrivate::PartitioningDialog;
|
|
||||||
|
|
||||||
#endif // _PARTITIONING_DIALOG_H
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
|
||||||
// by the OpenBeOS license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include <syscalls.h>
|
|
||||||
|
|
||||||
#include <PartitioningInfo.h>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
BPartitioningInfo::BPartitioningInfo()
|
|
||||||
: fPartitionID(-1),
|
|
||||||
fSpaces(NULL),
|
|
||||||
fCount(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
BPartitioningInfo::~BPartitioningInfo()
|
|
||||||
{
|
|
||||||
Unset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unset
|
|
||||||
void
|
|
||||||
BPartitioningInfo::Unset()
|
|
||||||
{
|
|
||||||
delete[] fSpaces;
|
|
||||||
fPartitionID = -1;
|
|
||||||
fSpaces = NULL;
|
|
||||||
fCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PartitionID
|
|
||||||
partition_id
|
|
||||||
BPartitioningInfo::PartitionID() const
|
|
||||||
{
|
|
||||||
return fPartitionID;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPartitionableSpaceAt
|
|
||||||
status_t
|
|
||||||
BPartitioningInfo::GetPartitionableSpaceAt(int32 index, off_t *offset,
|
|
||||||
off_t *size) const
|
|
||||||
{
|
|
||||||
if (!fSpaces || !offset || !size || index < 0 || index >= fCount)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
*offset = fSpaces[index].offset;
|
|
||||||
*size = fSpaces[index].size;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CountPartitionableSpaces
|
|
||||||
int32
|
|
||||||
BPartitioningInfo::CountPartitionableSpaces() const
|
|
||||||
{
|
|
||||||
return fCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _SetTo
|
|
||||||
status_t
|
|
||||||
BPartitioningInfo::_SetTo(partition_id partition, int32 changeCounter)
|
|
||||||
{
|
|
||||||
Unset();
|
|
||||||
status_t error = B_OK;
|
|
||||||
partitionable_space_data *buffer = NULL;
|
|
||||||
int32 count = 0;
|
|
||||||
int32 actualCount = 0;
|
|
||||||
do {
|
|
||||||
error = _kern_get_partitionable_spaces(partition, changeCounter,
|
|
||||||
buffer, count, &actualCount);
|
|
||||||
if (error == B_BUFFER_OVERFLOW) {
|
|
||||||
// buffer to small re-allocate it
|
|
||||||
if (buffer)
|
|
||||||
delete[] buffer;
|
|
||||||
buffer = new(nothrow) partitionable_space_data[actualCount];
|
|
||||||
if (buffer)
|
|
||||||
count = actualCount;
|
|
||||||
else
|
|
||||||
error = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
} while (error == B_BUFFER_OVERFLOW);
|
|
||||||
// set data / cleanup on failure
|
|
||||||
if (error == B_OK) {
|
|
||||||
fPartitionID = partition;
|
|
||||||
fSpaces = buffer;
|
|
||||||
fCount = actualCount;
|
|
||||||
} else if (buffer)
|
|
||||||
delete[] buffer;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,776 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the Haiku distribution and is covered
|
|
||||||
// by the MIT license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
/*!
|
|
||||||
\file Query.cpp
|
|
||||||
BQuery implementation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <new>
|
|
||||||
#include <parsedate.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include <Entry.h>
|
|
||||||
#include <fs_query.h>
|
|
||||||
#include <Query.h>
|
|
||||||
#include <Volume.h>
|
|
||||||
|
|
||||||
#include <MessengerPrivate.h>
|
|
||||||
#include <syscalls.h>
|
|
||||||
|
|
||||||
#include "QueryPredicate.h"
|
|
||||||
#include "storage_support.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace BPrivate::Storage;
|
|
||||||
|
|
||||||
// BQuery
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
/*! \brief Creates an uninitialized BQuery.
|
|
||||||
*/
|
|
||||||
BQuery::BQuery()
|
|
||||||
: BEntryList(),
|
|
||||||
fStack(NULL),
|
|
||||||
fPredicate(NULL),
|
|
||||||
fDevice((dev_t)B_ERROR),
|
|
||||||
fLive(false),
|
|
||||||
fPort(B_ERROR),
|
|
||||||
fToken(0),
|
|
||||||
fQueryFd(-1)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
/*! \brief Frees all resources associated with the object.
|
|
||||||
*/
|
|
||||||
BQuery::~BQuery()
|
|
||||||
{
|
|
||||||
Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear
|
|
||||||
/*! \brief Resets the object to a uninitialized state.
|
|
||||||
\return \c B_OK
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::Clear()
|
|
||||||
{
|
|
||||||
// close the currently open query
|
|
||||||
status_t error = B_OK;
|
|
||||||
if (fQueryFd >= 0) {
|
|
||||||
error = _kern_close(fQueryFd);
|
|
||||||
fQueryFd = -1;
|
|
||||||
}
|
|
||||||
// delete the predicate stack and the predicate
|
|
||||||
delete fStack;
|
|
||||||
fStack = NULL;
|
|
||||||
delete[] fPredicate;
|
|
||||||
fPredicate = NULL;
|
|
||||||
// reset the other parameters
|
|
||||||
fDevice = (dev_t)B_ERROR;
|
|
||||||
fLive = false;
|
|
||||||
fPort = B_ERROR;
|
|
||||||
fToken = 0;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushAttr
|
|
||||||
/*! \brief Pushes an attribute name onto the BQuery's predicate stack.
|
|
||||||
\param attrName the attribute name
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NO_MEMORY: Not enough memory.
|
|
||||||
- \c B_NOT_ALLOWED: PushAttribute() was called after Fetch().
|
|
||||||
\note In BeOS R5 this method returns \c void. That is checking the return
|
|
||||||
value will render your code source and binary incompatible!
|
|
||||||
Calling PushXYZ() after a Fetch() does change the predicate on R5,
|
|
||||||
but it doesn't affect the active query and the newly created
|
|
||||||
predicate can not even be used for the next query, since in order
|
|
||||||
to be able to reuse the BQuery object for another query, Clear() has
|
|
||||||
to be called and Clear() also deletes the predicate.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::PushAttr(const char *attrName)
|
|
||||||
{
|
|
||||||
return _PushNode(new(nothrow) AttributeNode(attrName), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushOp
|
|
||||||
/*! \brief Pushes an operator onto the BQuery's predicate stack.
|
|
||||||
\param op the code representing the operator
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NO_MEMORY: Not enough memory.
|
|
||||||
- \c B_NOT_ALLOWED: PushOp() was called after Fetch().
|
|
||||||
\note In BeOS R5 this method returns \c void. That is checking the return
|
|
||||||
value will render your code source and binary incompatible!
|
|
||||||
Calling PushXYZ() after a Fetch() does change the predicate on R5,
|
|
||||||
but it doesn't affect the active query and the newly created
|
|
||||||
predicate can not even be used for the next query, since in order
|
|
||||||
to be able to reuse the BQuery object for another query, Clear() has
|
|
||||||
to be called and Clear() also deletes the predicate.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::PushOp(query_op op)
|
|
||||||
{
|
|
||||||
status_t error = B_OK;
|
|
||||||
switch (op) {
|
|
||||||
case B_EQ:
|
|
||||||
case B_GT:
|
|
||||||
case B_GE:
|
|
||||||
case B_LT:
|
|
||||||
case B_LE:
|
|
||||||
case B_NE:
|
|
||||||
case B_CONTAINS:
|
|
||||||
case B_BEGINS_WITH:
|
|
||||||
case B_ENDS_WITH:
|
|
||||||
case B_AND:
|
|
||||||
case B_OR:
|
|
||||||
error = _PushNode(new(nothrow) BinaryOpNode(op), true);
|
|
||||||
break;
|
|
||||||
case B_NOT:
|
|
||||||
error = _PushNode(new(nothrow) UnaryOpNode(op), true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error = _PushNode(new(nothrow) SpecialOpNode(op), true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushUInt32
|
|
||||||
/*! \brief Pushes a uint32 value onto the BQuery's predicate stack.
|
|
||||||
\param value the value
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NO_MEMORY: Not enough memory.
|
|
||||||
- \c B_NOT_ALLOWED: PushUInt32() was called after Fetch().
|
|
||||||
\note In BeOS R5 this method returns \c void. That is checking the return
|
|
||||||
value will render your code source and binary incompatible!
|
|
||||||
Calling PushXYZ() after a Fetch() does change the predicate on R5,
|
|
||||||
but it doesn't affect the active query and the newly created
|
|
||||||
predicate can not even be used for the next query, since in order
|
|
||||||
to be able to reuse the BQuery object for another query, Clear() has
|
|
||||||
to be called and Clear() also deletes the predicate.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::PushUInt32(uint32 value)
|
|
||||||
{
|
|
||||||
return _PushNode(new(nothrow) UInt32ValueNode(value), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushInt32
|
|
||||||
/*! \brief Pushes an int32 value onto the BQuery's predicate stack.
|
|
||||||
\param value the value
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NO_MEMORY: Not enough memory.
|
|
||||||
- \c B_NOT_ALLOWED: PushInt32() was called after Fetch().
|
|
||||||
\note In BeOS R5 this method returns \c void. That is checking the return
|
|
||||||
value will render your code source and binary incompatible!
|
|
||||||
Calling PushXYZ() after a Fetch() does change the predicate on R5,
|
|
||||||
but it doesn't affect the active query and the newly created
|
|
||||||
predicate can not even be used for the next query, since in order
|
|
||||||
to be able to reuse the BQuery object for another query, Clear() has
|
|
||||||
to be called and Clear() also deletes the predicate.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::PushInt32(int32 value)
|
|
||||||
{
|
|
||||||
return _PushNode(new(nothrow) Int32ValueNode(value), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushUInt64
|
|
||||||
/*! \brief Pushes a uint64 value onto the BQuery's predicate stack.
|
|
||||||
\param value the value
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NO_MEMORY: Not enough memory.
|
|
||||||
- \c B_NOT_ALLOWED: PushUInt64() was called after Fetch().
|
|
||||||
\note In BeOS R5 this method returns \c void. That is checking the return
|
|
||||||
value will render your code source and binary incompatible!
|
|
||||||
Calling PushXYZ() after a Fetch() does change the predicate on R5,
|
|
||||||
but it doesn't affect the active query and the newly created
|
|
||||||
predicate can not even be used for the next query, since in order
|
|
||||||
to be able to reuse the BQuery object for another query, Clear() has
|
|
||||||
to be called and Clear() also deletes the predicate.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::PushUInt64(uint64 value)
|
|
||||||
{
|
|
||||||
return _PushNode(new(nothrow) UInt64ValueNode(value), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushInt64
|
|
||||||
/*! \brief Pushes an int64 value onto the BQuery's predicate stack.
|
|
||||||
\param value the value
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NO_MEMORY: Not enough memory.
|
|
||||||
- \c B_NOT_ALLOWED: PushInt64() was called after Fetch().
|
|
||||||
\note In BeOS R5 this method returns \c void. That is checking the return
|
|
||||||
value will render your code source and binary incompatible!
|
|
||||||
Calling PushXYZ() after a Fetch() does change the predicate on R5,
|
|
||||||
but it doesn't affect the active query and the newly created
|
|
||||||
predicate can not even be used for the next query, since in order
|
|
||||||
to be able to reuse the BQuery object for another query, Clear() has
|
|
||||||
to be called and Clear() also deletes the predicate.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::PushInt64(int64 value)
|
|
||||||
{
|
|
||||||
return _PushNode(new(nothrow) Int64ValueNode(value), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushFloat
|
|
||||||
/*! \brief Pushes a float value onto the BQuery's predicate stack.
|
|
||||||
\param value the value
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NO_MEMORY: Not enough memory.
|
|
||||||
- \c B_NOT_ALLOWED: PushFloat() was called after Fetch().
|
|
||||||
\note In BeOS R5 this method returns \c void. That is checking the return
|
|
||||||
value will render your code source and binary incompatible!
|
|
||||||
Calling PushXYZ() after a Fetch() does change the predicate on R5,
|
|
||||||
but it doesn't affect the active query and the newly created
|
|
||||||
predicate can not even be used for the next query, since in order
|
|
||||||
to be able to reuse the BQuery object for another query, Clear() has
|
|
||||||
to be called and Clear() also deletes the predicate.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::PushFloat(float value)
|
|
||||||
{
|
|
||||||
return _PushNode(new(nothrow) FloatValueNode(value), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushDouble
|
|
||||||
/*! \brief Pushes a double value onto the BQuery's predicate stack.
|
|
||||||
\param value the value
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NO_MEMORY: Not enough memory.
|
|
||||||
- \c B_NOT_ALLOWED: PushDouble() was called after Fetch().
|
|
||||||
\note In BeOS R5 this method returns \c void. That is checking the return
|
|
||||||
value will render your code source and binary incompatible!
|
|
||||||
Calling PushXYZ() after a Fetch() does change the predicate on R5,
|
|
||||||
but it doesn't affect the active query and the newly created
|
|
||||||
predicate can not even be used for the next query, since in order
|
|
||||||
to be able to reuse the BQuery object for another query, Clear() has
|
|
||||||
to be called and Clear() also deletes the predicate.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::PushDouble(double value)
|
|
||||||
{
|
|
||||||
return _PushNode(new(nothrow) DoubleValueNode(value), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushString
|
|
||||||
/*! \brief Pushes a string value onto the BQuery's predicate stack.
|
|
||||||
\param value the value
|
|
||||||
\param caseInsensitive \c true, if the case of the string should be
|
|
||||||
ignored, \c false otherwise
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NO_MEMORY: Not enough memory.
|
|
||||||
- \c B_NOT_ALLOWED: PushString() was called after Fetch().
|
|
||||||
\note In BeOS R5 this method returns \c void. That is checking the return
|
|
||||||
value will render your code source and binary incompatible!
|
|
||||||
Calling PushXYZ() after a Fetch() does change the predicate on R5,
|
|
||||||
but it doesn't affect the active query and the newly created
|
|
||||||
predicate can not even be used for the next query, since in order
|
|
||||||
to be able to reuse the BQuery object for another query, Clear() has
|
|
||||||
to be called and Clear() also deletes the predicate.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::PushString(const char *value, bool caseInsensitive)
|
|
||||||
{
|
|
||||||
return _PushNode(new(nothrow) StringNode(value, caseInsensitive), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushDate
|
|
||||||
/*! \brief Pushes a date value onto the BQuery's predicate stack.
|
|
||||||
The supplied date can be any string understood by the POSIX function
|
|
||||||
parsedate().
|
|
||||||
\param date the date string
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_ERROR: Error parsing the string.
|
|
||||||
- \c B_NOT_ALLOWED: PushDate() was called after Fetch().
|
|
||||||
\note Calling PushXYZ() after a Fetch() does change the predicate on R5,
|
|
||||||
but it doesn't affect the active query and the newly created
|
|
||||||
predicate can not even be used for the next query, since in order
|
|
||||||
to be able to reuse the BQuery object for another query, Clear() has
|
|
||||||
to be called and Clear() also deletes the predicate.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::PushDate(const char *date)
|
|
||||||
{
|
|
||||||
status_t error = (date ? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK) {
|
|
||||||
time_t t;
|
|
||||||
time(&t);
|
|
||||||
t = parsedate(date, t);
|
|
||||||
if (t < 0)
|
|
||||||
error = B_BAD_VALUE;
|
|
||||||
}
|
|
||||||
if (error == B_OK)
|
|
||||||
error = _PushNode(new(nothrow) DateNode(date), true);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetVolume
|
|
||||||
/*! \brief Sets the BQuery's volume.
|
|
||||||
A query is restricted to one volume. This method sets this volume. It
|
|
||||||
fails, if called after Fetch(). To reuse a BQuery object it has to be
|
|
||||||
reset via Clear().
|
|
||||||
\param volume the volume
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NOT_ALLOWED: SetVolume() was called after Fetch().
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::SetVolume(const BVolume *volume)
|
|
||||||
{
|
|
||||||
status_t error = (volume ? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK && _HasFetched())
|
|
||||||
error = B_NOT_ALLOWED;
|
|
||||||
if (error == B_OK) {
|
|
||||||
if (volume->InitCheck() == B_OK)
|
|
||||||
fDevice = volume->Device();
|
|
||||||
else
|
|
||||||
fDevice = (dev_t)B_ERROR;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetPredicate
|
|
||||||
/*! \brief Sets the BQuery's predicate.
|
|
||||||
A predicate can be set either using this method or constructing one on
|
|
||||||
the predicate stack. The two methods can not be mixed. The letter one
|
|
||||||
has precedence over this one.
|
|
||||||
The method fails, if called after Fetch(). To reuse a BQuery object it has
|
|
||||||
to be reset via Clear().
|
|
||||||
\param predicate the predicate string
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NOT_ALLOWED: SetPredicate() was called after Fetch().
|
|
||||||
- \c B_NO_MEMORY: Insufficient memory to store the predicate.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::SetPredicate(const char *expression)
|
|
||||||
{
|
|
||||||
status_t error = (expression ? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK && _HasFetched())
|
|
||||||
error = B_NOT_ALLOWED;
|
|
||||||
if (error == B_OK)
|
|
||||||
error = _SetPredicate(expression);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetTarget
|
|
||||||
/*! \brief Sets the BQuery's target and makes the query live.
|
|
||||||
The query update messages are sent to the specified target. They might
|
|
||||||
roll in immediately after calling Fetch().
|
|
||||||
This methods fails, if called after Fetch(). To reuse a BQuery object it
|
|
||||||
has to be reset via Clear().
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_BAD_VALUE: \a messenger was not properly initialized.
|
|
||||||
- \c B_NOT_ALLOWED: SetTarget() was called after Fetch().
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::SetTarget(BMessenger messenger)
|
|
||||||
{
|
|
||||||
status_t error = (messenger.IsValid() ? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK && _HasFetched())
|
|
||||||
error = B_NOT_ALLOWED;
|
|
||||||
if (error == B_OK) {
|
|
||||||
BMessenger::Private messengerPrivate(messenger);
|
|
||||||
fPort = messengerPrivate.Port();
|
|
||||||
fToken = (messengerPrivate.IsPreferredTarget()
|
|
||||||
? -1 : messengerPrivate.Token());
|
|
||||||
fLive = true;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsLive
|
|
||||||
/*! \brief Returns whether the query associated with this object is live.
|
|
||||||
\return \c true, if the query is live, \c false otherwise
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
BQuery::IsLive() const
|
|
||||||
{
|
|
||||||
return fLive;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPredicate
|
|
||||||
/*! \brief Returns the BQuery's predicate.
|
|
||||||
Regardless of whether the predicate has been constructed using the
|
|
||||||
predicate stack or set via SetPredicate(), this method returns a
|
|
||||||
string representation.
|
|
||||||
\param buffer a pointer to a buffer into which the predicate shall be
|
|
||||||
written
|
|
||||||
\param length the size of the provided buffer
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NO_INIT: The predicate isn't set.
|
|
||||||
- \c B_BAD_VALUE: \a buffer is \c NULL or too short.
|
|
||||||
\note This method causes the predicate stack to be evaluated and cleared.
|
|
||||||
You can't interleave Push*() and GetPredicate() calls.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::GetPredicate(char *buffer, size_t length)
|
|
||||||
{
|
|
||||||
status_t error = (buffer ? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK)
|
|
||||||
_EvaluateStack();
|
|
||||||
if (error == B_OK && !fPredicate)
|
|
||||||
error = B_NO_INIT;
|
|
||||||
if (error == B_OK && length <= strlen(fPredicate))
|
|
||||||
error = B_BAD_VALUE;
|
|
||||||
if (error == B_OK)
|
|
||||||
strcpy(buffer, fPredicate);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPredicate
|
|
||||||
/*! \brief Returns the BQuery's predicate.
|
|
||||||
Regardless of whether the predicate has been constructed using the
|
|
||||||
predicate stack or set via SetPredicate(), this method returns a
|
|
||||||
string representation.
|
|
||||||
\param predicate a pointer to a BString which shall be set to the
|
|
||||||
predicate string
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NO_INIT: The predicate isn't set.
|
|
||||||
- \c B_BAD_VALUE: \c NULL \a predicate.
|
|
||||||
\note This method causes the predicate stack to be evaluated and cleared.
|
|
||||||
You can't interleave Push*() and GetPredicate() calls.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::GetPredicate(BString *predicate)
|
|
||||||
{
|
|
||||||
status_t error = (predicate ? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK)
|
|
||||||
_EvaluateStack();
|
|
||||||
if (error == B_OK && !fPredicate)
|
|
||||||
error = B_NO_INIT;
|
|
||||||
if (error == B_OK)
|
|
||||||
predicate->SetTo(fPredicate);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PredicateLength
|
|
||||||
/*! \brief Returns the length of the BQuery's predicate string.
|
|
||||||
Regardless of whether the predicate has been constructed using the
|
|
||||||
predicate stack or set via SetPredicate(), this method returns the length
|
|
||||||
of its string representation (counting the terminating null).
|
|
||||||
\return
|
|
||||||
- the length of the predicate string (counting the terminating null) or
|
|
||||||
- 0, if an error occured
|
|
||||||
\note This method causes the predicate stack to be evaluated and cleared.
|
|
||||||
You can't interleave Push*() and PredicateLength() calls.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
BQuery::PredicateLength()
|
|
||||||
{
|
|
||||||
status_t error = _EvaluateStack();
|
|
||||||
if (error == B_OK && !fPredicate)
|
|
||||||
error = B_NO_INIT;
|
|
||||||
size_t size = 0;
|
|
||||||
if (error == B_OK)
|
|
||||||
size = strlen(fPredicate) + 1;
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TargetDevice
|
|
||||||
/*! \brief Returns the device ID identifying the BQuery's volume.
|
|
||||||
\return the device ID of the BQuery's volume or \c B_NO_INIT, if the
|
|
||||||
volume isn't set.
|
|
||||||
|
|
||||||
*/
|
|
||||||
dev_t
|
|
||||||
BQuery::TargetDevice() const
|
|
||||||
{
|
|
||||||
return fDevice;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch
|
|
||||||
/*! \brief Tells the BQuery to start fetching entries satisfying the predicate.
|
|
||||||
After Fetch() has been called GetNextEntry(), GetNextRef() and
|
|
||||||
GetNextDirents() can be used to retrieve the enties. Live query updates
|
|
||||||
may be sent immediately after this method has been called.
|
|
||||||
Fetch() fails, if it has already been called. To reuse a BQuery object it
|
|
||||||
has to be reset via Clear().
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NO_INIT: The predicate or the volume aren't set.
|
|
||||||
- \c B_BAD_VALUE: The predicate is invalid.
|
|
||||||
- \c B_NOT_ALLOWED: Fetch() has already been called.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::Fetch()
|
|
||||||
{
|
|
||||||
if (_HasFetched())
|
|
||||||
return B_NOT_ALLOWED;
|
|
||||||
|
|
||||||
_EvaluateStack();
|
|
||||||
|
|
||||||
if (!fPredicate || fDevice < 0)
|
|
||||||
return B_NO_INIT;
|
|
||||||
|
|
||||||
fQueryFd = _kern_open_query(fDevice, fPredicate, strlen(fPredicate),
|
|
||||||
fLive ? B_LIVE_QUERY : 0, fPort, fToken);
|
|
||||||
if (fQueryFd < 0)
|
|
||||||
return fQueryFd;
|
|
||||||
|
|
||||||
// set close on exec flag
|
|
||||||
fcntl(fQueryFd, F_SETFD, FD_CLOEXEC);
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// BEntryList interface
|
|
||||||
|
|
||||||
// GetNextEntry
|
|
||||||
/*! \brief Returns the BQuery's next entry as a BEntry.
|
|
||||||
Places the next entry in the list in \a entry, traversing symlinks if
|
|
||||||
\a traverse is \c true.
|
|
||||||
\param entry a pointer to a BEntry to be initialized with the found entry
|
|
||||||
\param traverse specifies whether to follow it, if the found entry
|
|
||||||
is a symbolic link.
|
|
||||||
\note The iterator used by this method is the same one used by
|
|
||||||
GetNextRef() and GetNextDirents().
|
|
||||||
\return
|
|
||||||
- \c B_OK if successful,
|
|
||||||
- \c B_ENTRY_NOT_FOUND when at the end of the list,
|
|
||||||
- \c B_BAD_VALUE: The queries predicate includes unindexed attributes.
|
|
||||||
- \c B_FILE_ERROR: Fetch() has not been called before.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::GetNextEntry(BEntry *entry, bool traverse)
|
|
||||||
{
|
|
||||||
status_t error = (entry ? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK) {
|
|
||||||
entry_ref ref;
|
|
||||||
error = GetNextRef(&ref);
|
|
||||||
if (error == B_OK)
|
|
||||||
error = entry->SetTo(&ref, traverse);
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNextRef
|
|
||||||
/*! \brief Returns the BQuery's next entry as an entry_ref.
|
|
||||||
Places an entry_ref to the next entry in the list into \a ref.
|
|
||||||
\param ref a pointer to an entry_ref to be filled in with the data of the
|
|
||||||
found entry
|
|
||||||
\note The iterator used by this method is the same one used by
|
|
||||||
GetNextEntry() and GetNextDirents().
|
|
||||||
\return
|
|
||||||
- \c B_OK if successful,
|
|
||||||
- \c B_ENTRY_NOT_FOUND when at the end of the list,
|
|
||||||
- \c B_BAD_VALUE: The queries predicate includes unindexed attributes.
|
|
||||||
- \c B_FILE_ERROR: Fetch() has not been called before.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::GetNextRef(entry_ref *ref)
|
|
||||||
{
|
|
||||||
status_t error = (ref ? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK && !_HasFetched())
|
|
||||||
error = B_FILE_ERROR;
|
|
||||||
if (error == B_OK) {
|
|
||||||
BPrivate::Storage::LongDirEntry entry;
|
|
||||||
bool next = true;
|
|
||||||
while (error == B_OK && next) {
|
|
||||||
if (GetNextDirents(&entry, sizeof(entry), 1) != 1) {
|
|
||||||
error = B_ENTRY_NOT_FOUND;
|
|
||||||
} else {
|
|
||||||
next = (!strcmp(entry.d_name, ".")
|
|
||||||
|| !strcmp(entry.d_name, ".."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (error == B_OK) {
|
|
||||||
ref->device = entry.d_pdev;
|
|
||||||
ref->directory = entry.d_pino;
|
|
||||||
error = ref->set_name(entry.d_name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNextDirents
|
|
||||||
/*! \brief Returns the BQuery's next entries as dirent structures.
|
|
||||||
Reads a number of entries into the array of dirent structures pointed to by
|
|
||||||
\a buf. Reads as many but no more than \a count entries, as many entries as
|
|
||||||
remain, or as many entries as will fit into the array at \a buf with given
|
|
||||||
length \a length (in bytes), whichever is smallest.
|
|
||||||
\param buf a pointer to a buffer to be filled with dirent structures of
|
|
||||||
the found entries
|
|
||||||
\param length the maximal number of entries to be read.
|
|
||||||
\note The iterator used by this method is the same one used by
|
|
||||||
GetNextEntry() and GetNextRef().
|
|
||||||
\return
|
|
||||||
- The number of dirent structures stored in the buffer, 0 when there are
|
|
||||||
no more entries to be read.
|
|
||||||
- \c B_BAD_VALUE: The queries predicate includes unindexed attributes.
|
|
||||||
- \c B_FILE_ERROR: Fetch() has not been called before.
|
|
||||||
*/
|
|
||||||
int32
|
|
||||||
BQuery::GetNextDirents(struct dirent *buf, size_t length, int32 count)
|
|
||||||
{
|
|
||||||
if (!buf)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
if (!_HasFetched())
|
|
||||||
return B_FILE_ERROR;
|
|
||||||
return _kern_read_dir(fQueryFd, buf, length, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rewind
|
|
||||||
/*! \brief Rewinds the entry list back to the first entry.
|
|
||||||
|
|
||||||
Unlike R5 Haiku implements this method for BQuery.
|
|
||||||
|
|
||||||
\return
|
|
||||||
- \c B_OK on success,
|
|
||||||
- \c B_FILE_ERROR, if Fetch() has not yet been called.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::Rewind()
|
|
||||||
{
|
|
||||||
if (!_HasFetched())
|
|
||||||
return B_FILE_ERROR;
|
|
||||||
return _kern_rewind_dir(fQueryFd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// CountEntries
|
|
||||||
/*! \brief Unimplemented method of the BEntryList interface.
|
|
||||||
\return 0.
|
|
||||||
*/
|
|
||||||
int32
|
|
||||||
BQuery::CountEntries()
|
|
||||||
{
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _HasFetched
|
|
||||||
/*! Returns whether Fetch() has already been called on this object.
|
|
||||||
\return \c true, if Fetch() has successfully been invoked, \c false
|
|
||||||
otherwise.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
BQuery::_HasFetched() const
|
|
||||||
{
|
|
||||||
return (fQueryFd >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// _PushNode
|
|
||||||
/*! \brief Pushs a node onto the predicate stack.
|
|
||||||
If the stack has not been allocate until this time, this method does
|
|
||||||
allocate it.
|
|
||||||
If the supplied node is \c NULL, it is assumed that there was not enough
|
|
||||||
memory to allocate the node and thus \c B_NO_MEMORY is returned.
|
|
||||||
In case the method fails, the caller retains the ownership of the supplied
|
|
||||||
node and thus is responsible for deleting it, if \a deleteOnError is
|
|
||||||
\c false. If it is \c true, the node is deleted, if an error occurs.
|
|
||||||
\param node the node to be pushed
|
|
||||||
\param deleteOnError
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NO_MEMORY: \c NULL \a node or insuffient memory to allocate the
|
|
||||||
predicate stack or push the node.
|
|
||||||
- \c B_NOT_ALLOWED: _PushNode() was called after Fetch().
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::_PushNode(QueryNode *node, bool deleteOnError)
|
|
||||||
{
|
|
||||||
status_t error = (node ? B_OK : B_NO_MEMORY);
|
|
||||||
if (error == B_OK && _HasFetched())
|
|
||||||
error = B_NOT_ALLOWED;
|
|
||||||
// allocate the stack, if necessary
|
|
||||||
if (error == B_OK && !fStack) {
|
|
||||||
fStack = new(nothrow) QueryStack;
|
|
||||||
if (!fStack)
|
|
||||||
error = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
if (error == B_OK)
|
|
||||||
error = fStack->PushNode(node);
|
|
||||||
if (error != B_OK && deleteOnError)
|
|
||||||
delete node;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _SetPredicate
|
|
||||||
/*! \brief Helper method to set the BQuery's predicate.
|
|
||||||
It is not checked whether Fetch() has already been invoked.
|
|
||||||
\param predicate the predicate string
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NO_MEMORY: Insufficient memory to store the predicate.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::_SetPredicate(const char *expression)
|
|
||||||
{
|
|
||||||
status_t error = B_OK;
|
|
||||||
// unset the old predicate
|
|
||||||
delete[] fPredicate;
|
|
||||||
fPredicate = NULL;
|
|
||||||
// set the new one
|
|
||||||
if (expression) {
|
|
||||||
fPredicate = new(nothrow) char[strlen(expression) + 1];
|
|
||||||
if (fPredicate)
|
|
||||||
strcpy(fPredicate, expression);
|
|
||||||
else
|
|
||||||
error = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _EvaluateStack
|
|
||||||
/*! Evaluates the query's predicate stack.
|
|
||||||
The method does nothing (and returns \c B_OK), if the stack is \c NULL.
|
|
||||||
If the stack is non-null and Fetch() has already been called, the method
|
|
||||||
fails.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_NO_MEMORY: Insufficient memory.
|
|
||||||
- \c B_NOT_ALLOWED: _EvaluateStack() was called after Fetch().
|
|
||||||
- another error code
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BQuery::_EvaluateStack()
|
|
||||||
{
|
|
||||||
status_t error = B_OK;
|
|
||||||
if (fStack) {
|
|
||||||
_SetPredicate(NULL);
|
|
||||||
if (_HasFetched())
|
|
||||||
error = B_NOT_ALLOWED;
|
|
||||||
// convert the stack to a tree and evaluate it
|
|
||||||
QueryNode *node = NULL;
|
|
||||||
if (error == B_OK)
|
|
||||||
error = fStack->ConvertToTree(node);
|
|
||||||
BString predicate;
|
|
||||||
if (error == B_OK)
|
|
||||||
error = node->GetString(predicate);
|
|
||||||
if (error == B_OK)
|
|
||||||
error = _SetPredicate(predicate.String());
|
|
||||||
delete fStack;
|
|
||||||
fStack = NULL;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// FBC
|
|
||||||
void BQuery::_QwertyQuery1() {}
|
|
||||||
void BQuery::_QwertyQuery2() {}
|
|
||||||
void BQuery::_QwertyQuery3() {}
|
|
||||||
void BQuery::_QwertyQuery4() {}
|
|
||||||
void BQuery::_QwertyQuery5() {}
|
|
||||||
void BQuery::_QwertyQuery6() {}
|
|
||||||
|
|
||||||
@@ -1,490 +0,0 @@
|
|||||||
//----------------------------------------------------------------------
|
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
|
||||||
// by the OpenBeOS license.
|
|
||||||
//---------------------------------------------------------------------
|
|
||||||
/*!
|
|
||||||
\file QueryPredicate.cpp
|
|
||||||
BQuery predicate helper classes implementation.
|
|
||||||
*/
|
|
||||||
#include "QueryPredicate.h"
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
namespace BPrivate {
|
|
||||||
namespace Storage {
|
|
||||||
|
|
||||||
// QueryNode
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
QueryNode::QueryNode()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
QueryNode::~QueryNode()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// LeafNode
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
LeafNode::LeafNode()
|
|
||||||
: QueryNode()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
LeafNode::~LeafNode()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Arity
|
|
||||||
uint32
|
|
||||||
LeafNode::Arity() const
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetChildAt
|
|
||||||
status_t
|
|
||||||
LeafNode::SetChildAt(QueryNode *child, int32 index)
|
|
||||||
{
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChildAt
|
|
||||||
QueryNode *
|
|
||||||
LeafNode::ChildAt(int32 index)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// UnaryNode
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
UnaryNode::UnaryNode()
|
|
||||||
: QueryNode(),
|
|
||||||
fChild(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
UnaryNode::~UnaryNode()
|
|
||||||
{
|
|
||||||
delete fChild;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Arity
|
|
||||||
uint32
|
|
||||||
UnaryNode::Arity() const
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetChildAt
|
|
||||||
status_t
|
|
||||||
UnaryNode::SetChildAt(QueryNode *child, int32 index)
|
|
||||||
{
|
|
||||||
status_t error = B_OK;
|
|
||||||
if (index == 0) {
|
|
||||||
delete fChild;
|
|
||||||
fChild = child;
|
|
||||||
} else
|
|
||||||
error = B_BAD_VALUE;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChildAt
|
|
||||||
QueryNode *
|
|
||||||
UnaryNode::ChildAt(int32 index)
|
|
||||||
{
|
|
||||||
QueryNode *result = NULL;
|
|
||||||
if (index == 0)
|
|
||||||
result = fChild;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// BinaryNode
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
BinaryNode::BinaryNode()
|
|
||||||
: QueryNode(),
|
|
||||||
fChild1(NULL),
|
|
||||||
fChild2(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
BinaryNode::~BinaryNode()
|
|
||||||
{
|
|
||||||
delete fChild1;
|
|
||||||
delete fChild2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Arity
|
|
||||||
uint32
|
|
||||||
BinaryNode::Arity() const
|
|
||||||
{
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetChildAt
|
|
||||||
status_t
|
|
||||||
BinaryNode::SetChildAt(QueryNode *child, int32 index)
|
|
||||||
{
|
|
||||||
status_t error = B_OK;
|
|
||||||
if (index == 0) {
|
|
||||||
delete fChild1;
|
|
||||||
fChild1 = child;
|
|
||||||
} else if (index == 1) {
|
|
||||||
delete fChild2;
|
|
||||||
fChild2 = child;
|
|
||||||
} else
|
|
||||||
error = B_BAD_VALUE;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChildAt
|
|
||||||
QueryNode *
|
|
||||||
BinaryNode::ChildAt(int32 index)
|
|
||||||
{
|
|
||||||
QueryNode *result = NULL;
|
|
||||||
if (index == 0)
|
|
||||||
result = fChild1;
|
|
||||||
else if (index == 1)
|
|
||||||
result = fChild2;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// AttributeNode
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
AttributeNode::AttributeNode(const char *attribute)
|
|
||||||
: LeafNode(),
|
|
||||||
fAttribute(attribute)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetString
|
|
||||||
status_t
|
|
||||||
AttributeNode::GetString(BString &predicate)
|
|
||||||
{
|
|
||||||
predicate.SetTo(fAttribute);
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// StringNode
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
StringNode::StringNode(const char *value, bool caseInsensitive)
|
|
||||||
: LeafNode(),
|
|
||||||
fValue()
|
|
||||||
{
|
|
||||||
if (value) {
|
|
||||||
if (caseInsensitive) {
|
|
||||||
int32 len = strlen(value);
|
|
||||||
for (int32 i = 0; i < len; i++) {
|
|
||||||
char c = value[i];
|
|
||||||
if (isalpha(c)) {
|
|
||||||
int lower = tolower(c);
|
|
||||||
int upper = toupper(c);
|
|
||||||
if (lower < 0 || upper < 0)
|
|
||||||
fValue << c;
|
|
||||||
else
|
|
||||||
fValue << "[" << (char)lower << (char)upper << "]";
|
|
||||||
} else
|
|
||||||
fValue << c;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
fValue = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetString
|
|
||||||
status_t
|
|
||||||
StringNode::GetString(BString &predicate)
|
|
||||||
{
|
|
||||||
BString escaped(fValue);
|
|
||||||
escaped.CharacterEscape("\"\\'", '\\');
|
|
||||||
predicate.SetTo("");
|
|
||||||
predicate << "\"" << escaped << "\"";
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// DateNode
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
DateNode::DateNode(const char *value)
|
|
||||||
: LeafNode(),
|
|
||||||
fValue(value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetString
|
|
||||||
status_t
|
|
||||||
DateNode::GetString(BString &predicate)
|
|
||||||
{
|
|
||||||
BString escaped(fValue);
|
|
||||||
escaped.CharacterEscape("%\"\\'", '\\');
|
|
||||||
predicate.SetTo("");
|
|
||||||
predicate << "%" << escaped << "%";
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ValueNode
|
|
||||||
|
|
||||||
// GetString
|
|
||||||
//
|
|
||||||
// float specialization
|
|
||||||
template<>
|
|
||||||
status_t
|
|
||||||
ValueNode<float>::GetString(BString &predicate)
|
|
||||||
{
|
|
||||||
char buffer[32];
|
|
||||||
sprintf(buffer, "0x%08lx", *(int32*)&fValue);
|
|
||||||
predicate.SetTo(buffer);
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetString
|
|
||||||
//
|
|
||||||
// double specialization
|
|
||||||
template<>
|
|
||||||
status_t
|
|
||||||
ValueNode<double>::GetString(BString &predicate)
|
|
||||||
{
|
|
||||||
char buffer[32];
|
|
||||||
sprintf(buffer, "0x%016Lx", *(int64*)&fValue);
|
|
||||||
predicate.SetTo(buffer);
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// SpecialOpNode
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
SpecialOpNode::SpecialOpNode(query_op op)
|
|
||||||
: LeafNode(),
|
|
||||||
fOp(op)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetString
|
|
||||||
status_t
|
|
||||||
SpecialOpNode::GetString(BString &predicate)
|
|
||||||
{
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// UnaryOpNode
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
UnaryOpNode::UnaryOpNode(query_op op)
|
|
||||||
: UnaryNode(),
|
|
||||||
fOp(op)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetString
|
|
||||||
status_t
|
|
||||||
UnaryOpNode::GetString(BString &predicate)
|
|
||||||
{
|
|
||||||
status_t error = (fChild ? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK) {
|
|
||||||
if (fOp == B_NOT) {
|
|
||||||
BString childString;
|
|
||||||
error = fChild->GetString(childString);
|
|
||||||
predicate.SetTo("(!");
|
|
||||||
predicate << childString << ")";
|
|
||||||
} else
|
|
||||||
error = B_BAD_VALUE;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// BinaryOpNode
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
BinaryOpNode::BinaryOpNode(query_op op)
|
|
||||||
: BinaryNode(),
|
|
||||||
fOp(op)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetString
|
|
||||||
status_t
|
|
||||||
BinaryOpNode::GetString(BString &predicate)
|
|
||||||
{
|
|
||||||
status_t error = (fChild1 && fChild2 ? B_OK : B_BAD_VALUE);
|
|
||||||
BString childString1;
|
|
||||||
BString childString2;
|
|
||||||
if (error == B_OK)
|
|
||||||
error = fChild1->GetString(childString1);
|
|
||||||
if (error == B_OK)
|
|
||||||
error = fChild2->GetString(childString2);
|
|
||||||
predicate.SetTo("");
|
|
||||||
if (error == B_OK) {
|
|
||||||
switch (fOp) {
|
|
||||||
case B_EQ:
|
|
||||||
predicate << "(" << childString1 << "=="
|
|
||||||
<< childString2 << ")";
|
|
||||||
break;
|
|
||||||
case B_GT:
|
|
||||||
predicate << "(" << childString1 << ">"
|
|
||||||
<< childString2 << ")";
|
|
||||||
break;
|
|
||||||
case B_GE:
|
|
||||||
predicate << "(" << childString1 << ">="
|
|
||||||
<< childString2 << ")";
|
|
||||||
break;
|
|
||||||
case B_LT:
|
|
||||||
predicate << "(" << childString1 << "<"
|
|
||||||
<< childString2 << ")";
|
|
||||||
break;
|
|
||||||
case B_LE:
|
|
||||||
predicate << "(" << childString1 << "<="
|
|
||||||
<< childString2 << ")";
|
|
||||||
break;
|
|
||||||
case B_NE:
|
|
||||||
predicate << "(" << childString1 << "!="
|
|
||||||
<< childString2 << ")";
|
|
||||||
break;
|
|
||||||
case B_CONTAINS:
|
|
||||||
if (StringNode *strNode = dynamic_cast<StringNode*>(fChild2)) {
|
|
||||||
BString value;
|
|
||||||
value << "*" << strNode->Value() << "*";
|
|
||||||
error = StringNode(value.String()).GetString(childString2);
|
|
||||||
}
|
|
||||||
if (error == B_OK) {
|
|
||||||
predicate << "(" << childString1 << "=="
|
|
||||||
<< childString2 << ")";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case B_BEGINS_WITH:
|
|
||||||
if (StringNode *strNode = dynamic_cast<StringNode*>(fChild2)) {
|
|
||||||
BString value;
|
|
||||||
value << strNode->Value() << "*";
|
|
||||||
error = StringNode(value.String()).GetString(childString2);
|
|
||||||
}
|
|
||||||
if (error == B_OK) {
|
|
||||||
predicate << "(" << childString1 << "=="
|
|
||||||
<< childString2 << ")";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case B_ENDS_WITH:
|
|
||||||
if (StringNode *strNode = dynamic_cast<StringNode*>(fChild2)) {
|
|
||||||
BString value;
|
|
||||||
value << "*" << strNode->Value();
|
|
||||||
error = StringNode(value.String()).GetString(childString2);
|
|
||||||
}
|
|
||||||
if (error == B_OK) {
|
|
||||||
predicate << "(" << childString1 << "=="
|
|
||||||
<< childString2 << ")";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case B_AND:
|
|
||||||
predicate << "(" << childString1 << "&&"
|
|
||||||
<< childString2 << ")";
|
|
||||||
break;
|
|
||||||
case B_OR:
|
|
||||||
predicate << "(" << childString1 << "||"
|
|
||||||
<< childString2 << ")";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error = B_BAD_VALUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// QueryStack
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
QueryStack::QueryStack()
|
|
||||||
: fNodes()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
QueryStack::~QueryStack()
|
|
||||||
{
|
|
||||||
for (int32 i = 0; QueryNode *node = (QueryNode*)fNodes.ItemAt(i); i++)
|
|
||||||
delete node;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushNode
|
|
||||||
status_t
|
|
||||||
QueryStack::PushNode(QueryNode *node)
|
|
||||||
{
|
|
||||||
status_t error = (node ? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK) {
|
|
||||||
if (!fNodes.AddItem(node))
|
|
||||||
error = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PopNode
|
|
||||||
QueryNode *
|
|
||||||
QueryStack::PopNode()
|
|
||||||
{
|
|
||||||
return (QueryNode*)fNodes.RemoveItem(fNodes.CountItems() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConvertToTree
|
|
||||||
status_t
|
|
||||||
QueryStack::ConvertToTree(QueryNode *&rootNode)
|
|
||||||
{
|
|
||||||
status_t error = _GetSubTree(rootNode);
|
|
||||||
if (error == B_OK && !fNodes.IsEmpty()) {
|
|
||||||
error = B_BAD_VALUE;
|
|
||||||
delete rootNode;
|
|
||||||
rootNode = NULL;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _GetSubTree
|
|
||||||
status_t
|
|
||||||
QueryStack::_GetSubTree(QueryNode *&rootNode)
|
|
||||||
{
|
|
||||||
QueryNode *node = PopNode();
|
|
||||||
status_t error = (node ? B_OK : B_BAD_VALUE);
|
|
||||||
if (error == B_OK) {
|
|
||||||
uint32 arity = node->Arity();
|
|
||||||
for (int32 i = (int32)arity - 1; error == B_OK && i >= 0; i--) {
|
|
||||||
QueryNode *child = NULL;
|
|
||||||
error = _GetSubTree(child);
|
|
||||||
if (error == B_OK) {
|
|
||||||
error = node->SetChildAt(child, i);
|
|
||||||
if (error != B_OK)
|
|
||||||
delete child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// clean up, if something went wrong
|
|
||||||
if (error != B_OK && node) {
|
|
||||||
delete node;
|
|
||||||
node = NULL;
|
|
||||||
}
|
|
||||||
rootNode = node;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}; // namespace Storage
|
|
||||||
}; // namespace BPrivate
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,222 +0,0 @@
|
|||||||
// ----------------------------------------------------------------------
|
|
||||||
// This software is part of the OpenBeOS distribution and is covered
|
|
||||||
// by the OpenBeOS license.
|
|
||||||
//
|
|
||||||
// File Name: VolumeRoster.cpp
|
|
||||||
//
|
|
||||||
// Description: BVolumeRoster class
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
/*!
|
|
||||||
\file VolumeRoster.cpp
|
|
||||||
BVolumeRoster implementation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <new>
|
|
||||||
|
|
||||||
#include <Bitmap.h>
|
|
||||||
#include <Directory.h>
|
|
||||||
#include <fs_info.h>
|
|
||||||
#include <Node.h>
|
|
||||||
#include <NodeMonitor.h>
|
|
||||||
#include <VolumeRoster.h>
|
|
||||||
|
|
||||||
static const char kBootVolumePath[] = "/boot";
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#ifdef USE_OPENBEOS_NAMESPACE
|
|
||||||
namespace OpenBeOS {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\class BVolumeRoster
|
|
||||||
\brief A roster of all volumes available in the system
|
|
||||||
|
|
||||||
Provides an interface for iterating through the volumes available in
|
|
||||||
the system and watching volume mounting/unmounting.
|
|
||||||
|
|
||||||
The class wraps the next_dev() function for iterating through the
|
|
||||||
volume list and the watch_node()/stop_watching() for the watching
|
|
||||||
features.
|
|
||||||
|
|
||||||
\author Vincent Dominguez
|
|
||||||
\author <a href='mailto:bonefish@users.sf.net'>Ingo Weinhold</a>
|
|
||||||
|
|
||||||
\version 0.0.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! \var dev_t BVolumeRoster::fCookie
|
|
||||||
\brief The iteration cookie for next_dev(). Initialized with 0.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! \var dev_t BVolumeRoster::fTarget
|
|
||||||
\brief BMessenger referring to the target to which the watching
|
|
||||||
notification messages are sent.
|
|
||||||
|
|
||||||
The object is allocated and owned by the roster. \c NULL, if not watching.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
/*! \brief Creates a new BVolumeRoster.
|
|
||||||
|
|
||||||
The object is ready to be used.
|
|
||||||
*/
|
|
||||||
BVolumeRoster::BVolumeRoster()
|
|
||||||
: fCookie(0),
|
|
||||||
fTarget(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
/*! \brief Frees all resources associated with this object.
|
|
||||||
|
|
||||||
If a watching was activated on (StartWatching()), it is deactived.
|
|
||||||
*/
|
|
||||||
BVolumeRoster::~BVolumeRoster()
|
|
||||||
{
|
|
||||||
StopWatching();
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetNextVolume
|
|
||||||
/*! \brief Returns the next volume in the list of available volumes.
|
|
||||||
\param volume A pointer to a pre-allocated BVolume to be initialized to
|
|
||||||
refer to the next volume in the list of available volumes.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_BAD_VALUE: The last volume in the list has already been returned.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BVolumeRoster::GetNextVolume(BVolume *volume)
|
|
||||||
{
|
|
||||||
// check parameter
|
|
||||||
status_t error = (volume ? B_OK : B_BAD_VALUE);
|
|
||||||
// get next device
|
|
||||||
dev_t device;
|
|
||||||
if (error == B_OK) {
|
|
||||||
device = next_dev(&fCookie);
|
|
||||||
if (device < 0)
|
|
||||||
error = device;
|
|
||||||
}
|
|
||||||
// init volume
|
|
||||||
if (error == B_OK)
|
|
||||||
error = volume->SetTo(device);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rewind
|
|
||||||
/*! \brief Rewinds the list of available volumes such that the next call to
|
|
||||||
GetNextVolume() will return the first element in the list.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BVolumeRoster::Rewind()
|
|
||||||
{
|
|
||||||
fCookie = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetBootVolume
|
|
||||||
/*! \brief Returns the boot volume.
|
|
||||||
|
|
||||||
Currently, this function looks for the volume that is mounted at "/boot".
|
|
||||||
The only way to fool the system into thinking that there is not a boot
|
|
||||||
volume is to rename "/boot" -- but, please refrain from doing so...(:o(
|
|
||||||
|
|
||||||
\param volume A pointer to a pre-allocated BVolume to be initialized to
|
|
||||||
refer to the boot volume.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- an error code otherwise
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BVolumeRoster::GetBootVolume(BVolume *volume)
|
|
||||||
{
|
|
||||||
// check parameter
|
|
||||||
status_t error = (volume ? B_OK : B_BAD_VALUE);
|
|
||||||
// get device
|
|
||||||
dev_t device;
|
|
||||||
if (error == B_OK) {
|
|
||||||
device = dev_for_path(kBootVolumePath);
|
|
||||||
if (device < 0)
|
|
||||||
error = device;
|
|
||||||
}
|
|
||||||
// init volume
|
|
||||||
if (error == B_OK)
|
|
||||||
error = volume->SetTo(device);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// StartWatching
|
|
||||||
/*! \brief Starts watching the list of volumes available in the system.
|
|
||||||
|
|
||||||
Notifications are sent to the specified target whenever a volume is
|
|
||||||
mounted or unmounted. The format of the notification messages is
|
|
||||||
described under watch_node(). Actually BVolumeRoster just provides a
|
|
||||||
more convenient interface for it.
|
|
||||||
|
|
||||||
If StartWatching() has been called before with another target and no
|
|
||||||
StopWatching() since, StopWatching() is called first, so that the former
|
|
||||||
target won't receive any notifications anymore.
|
|
||||||
|
|
||||||
When the object is destroyed all watching has an end as well.
|
|
||||||
|
|
||||||
\param messenger The target to which the notification messages shall be
|
|
||||||
sent.
|
|
||||||
\return
|
|
||||||
- \c B_OK: Everything went fine.
|
|
||||||
- \c B_BAD_VALUE: The supplied BMessenger is invalid.
|
|
||||||
- \c B_NO_MEMORY: Insufficient memory to carry out this operation.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
BVolumeRoster::StartWatching(BMessenger messenger)
|
|
||||||
{
|
|
||||||
StopWatching();
|
|
||||||
status_t error = (messenger.IsValid() ? B_OK : B_ERROR);
|
|
||||||
// clone messenger
|
|
||||||
if (error == B_OK) {
|
|
||||||
fTarget = new(nothrow) BMessenger(messenger);
|
|
||||||
if (!fTarget)
|
|
||||||
error = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
// start watching
|
|
||||||
if (error == B_OK)
|
|
||||||
error = watch_node(NULL, B_WATCH_MOUNT, messenger);
|
|
||||||
// cleanup on failure
|
|
||||||
if (error != B_OK && fTarget) {
|
|
||||||
delete fTarget;
|
|
||||||
fTarget = NULL;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// StopWatching
|
|
||||||
/*! \brief Stops volume watching initiated with StartWatching() before.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
BVolumeRoster::StopWatching()
|
|
||||||
{
|
|
||||||
if (fTarget) {
|
|
||||||
stop_watching(*fTarget);
|
|
||||||
delete fTarget;
|
|
||||||
fTarget = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Messenger
|
|
||||||
/*! \brief Returns a messenger to the target currently watching the volume
|
|
||||||
list.
|
|
||||||
\return A messenger to the target currently watching the volume list, or
|
|
||||||
an invalid messenger, if noone is currently watching.
|
|
||||||
*/
|
|
||||||
BMessenger
|
|
||||||
BVolumeRoster::Messenger() const
|
|
||||||
{
|
|
||||||
return (fTarget ? *fTarget : BMessenger());
|
|
||||||
}
|
|
||||||
|
|
||||||
// FBC
|
|
||||||
void BVolumeRoster::_SeveredVRoster1() {}
|
|
||||||
void BVolumeRoster::_SeveredVRoster2() {}
|
|
||||||
|
|
||||||
#ifdef USE_OPENBEOS_NAMESPACE
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
Reference in New Issue
Block a user