1 // ---------------------------------------------------------------------- 2 // This software is part of the OpenBeOS distribution and is covered 3 // by the OpenBeOS license. 4 // 5 // File Name: Volume.cpp 6 // 7 // Description: BVolume class 8 // ---------------------------------------------------------------------- 9 /*! 10 \file Volume.h 11 BVolume implementation. 12 */ 13 14 #include <errno.h> 15 16 #include <Bitmap.h> 17 #include <Directory.h> 18 #include <fs_info.h> 19 #include <kernel_interface.h> 20 #include <Node.h> 21 #include <Volume.h> 22 23 24 #ifdef USE_OPENBEOS_NAMESPACE 25 namespace OpenBeOS { 26 #endif 27 28 /*! 29 \class BVolume 30 \brief Represents a disk volume 31 32 Provides an interface for querying information about a volume. 33 34 The class is a simple wrapper for a \c dev_t and the function 35 fs_stat_dev. The only exception is the method is SetName(), which 36 sets the name of the volume. 37 38 \author Vincent Dominguez 39 \author <a href='mailto:bonefish@users.sf.net'>Ingo Weinhold</a> 40 41 \version 0.0.0 42 */ 43 44 /*! \var dev_t BVolume::fDevice 45 \brief The volume's device ID. 46 */ 47 48 /*! \var dev_t BVolume::fCStatus 49 \brief The object's initialization status. 50 */ 51 52 // constructor 53 /*! \brief Creates an uninitialized BVolume. 54 55 InitCheck() will return \c B_NO_INIT. 56 */ 57 BVolume::BVolume() 58 : fDevice(-1), 59 fCStatus(B_NO_INIT) 60 { 61 } 62 63 // constructor 64 /*! \brief Creates a BVolume and initializes it to the volume specified 65 by the supplied device ID. 66 67 InitCheck() should be called to check whether the initialization was 68 successful. 69 70 \param device The device ID of the volume. 71 */ 72 BVolume::BVolume(dev_t device) 73 : fDevice(-1), 74 fCStatus(B_NO_INIT) 75 { 76 SetTo(device); 77 } 78 79 // copy constructor 80 /*! \brief Creates a BVolume and makes it a clone of the supplied one. 81 82 Afterwards the object refers to the same device the supplied object 83 does. If the latter is not properly initialized, this object isn't 84 either. 85 86 \param volume The volume object to be cloned. 87 */ 88 BVolume::BVolume(const BVolume &volume) 89 : fDevice(volume.fDevice), 90 fCStatus(volume.fCStatus) 91 { 92 } 93 94 // destructor 95 /*! \brief Frees all resources associated with the object. 96 97 Does nothing. 98 */ 99 BVolume::~BVolume() 100 { 101 } 102 103 // InitCheck 104 /*! \brief Returns the result of the last initialization. 105 \return 106 - \c B_OK: The object is properly initialized. 107 - an error code otherwise 108 */ 109 status_t 110 BVolume::InitCheck(void) const 111 { 112 return fCStatus; 113 } 114 115 // SetTo 116 /*! \brief Re-initializes the object to refer to the volume specified by 117 the supplied device ID. 118 \param device The device ID of the volume. 119 \param 120 - \c B_OK: Everything went fine. 121 - an error code otherwise 122 */ 123 status_t 124 BVolume::SetTo(dev_t device) 125 { 126 // uninitialize 127 Unset(); 128 // check the parameter 129 status_t error = (device >= 0 ? B_OK : B_BAD_VALUE); 130 if (error == B_OK) { 131 fs_info info; 132 if (fs_stat_dev(device, &info) != 0) 133 error = errno; 134 } 135 // set the new value 136 if (error == B_OK) 137 fDevice = device; 138 // set the init status variable 139 fCStatus = error; 140 return fCStatus; 141 } 142 143 // Unset 144 /*! \brief Uninitialized the BVolume. 145 */ 146 void 147 BVolume::Unset() 148 { 149 fDevice = -1; 150 fCStatus = B_NO_INIT; 151 } 152 153 // Device 154 /*! \brief Returns the device ID of the volume the object refers to. 155 \return Returns the device ID of the volume the object refers to 156 or -1, if the object is not properly initialized. 157 */ 158 dev_t 159 BVolume::Device() const 160 { 161 return fDevice; 162 } 163 164 // GetRootDirectory 165 /*! \brief Returns the root directory of the volume referred to by the object. 166 \param directory A pointer to a pre-allocated BDirectory to be initialized 167 to the volume's root directory. 168 \return 169 - \c B_OK: Everything went fine. 170 - \c B_BAD_VALUE: \c NULL \a directory or the object is not properly 171 initialized. 172 - another error code 173 */ 174 status_t 175 BVolume::GetRootDirectory(BDirectory *directory) const 176 { 177 // check parameter and initialization 178 status_t error = (directory && InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 179 // get FS stat 180 fs_info info; 181 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 182 error = errno; 183 // init the directory 184 if (error == B_OK) { 185 node_ref ref; 186 ref.device = info.dev; 187 ref.node = info.root; 188 error = directory->SetTo(&ref); 189 } 190 return error; 191 } 192 193 // Capacity 194 /*! \brief Returns the volume's total storage capacity. 195 \return 196 - The volume's total storage capacity (in bytes), when the object is 197 properly initialized. 198 - \c B_BAD_VALUE otherwise. 199 */ 200 off_t 201 BVolume::Capacity() const 202 { 203 // check initialization 204 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 205 // get FS stat 206 fs_info info; 207 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 208 error = errno; 209 return (error == B_OK ? info.total_blocks * info.block_size : error); 210 } 211 212 // FreeBytes 213 /*! \brief Returns the amount of storage that's currently unused on the 214 volume (in bytes). 215 \return 216 - The amount of storage that's currently unused on the volume (in bytes), 217 when the object is properly initialized. 218 - \c B_BAD_VALUE otherwise. 219 */ 220 off_t 221 BVolume::FreeBytes() const 222 { 223 // check initialization 224 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 225 // get FS stat 226 fs_info info; 227 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 228 error = errno; 229 return (error == B_OK ? info.free_blocks * info.block_size : error); 230 } 231 232 // GetName 233 /*! \brief Returns the name of the volume. 234 235 The name of the volume is copied into the provided buffer. 236 237 \param name A pointer to a pre-allocated character buffer of size 238 \c B_FILE_NAME_LENGTH or larger into which the name of the 239 volume shall be written. 240 \return 241 - \c B_OK: Everything went fine. 242 - \c B_BAD_VALUE: \c NULL \a name or the object is not properly 243 initialized. 244 - another error code 245 */ 246 status_t 247 BVolume::GetName(char *name) const 248 { 249 // check parameter and initialization 250 status_t error = (name && InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 251 // get FS stat 252 fs_info info; 253 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 254 error = errno; 255 // copy the name 256 if (error == B_OK) 257 strncpy(name, info.volume_name, B_FILE_NAME_LENGTH); 258 return error; 259 } 260 261 // SetName 262 /*! \brief Sets the name of the volume referred to by this object. 263 \param name The volume's new name. Must not be longer than 264 \c B_FILE_NAME_LENGTH (including the terminating null). 265 \return 266 - \c B_OK: Everything went fine. 267 - \c B_BAD_VALUE: \c NULL \a name or the object is not properly 268 initialized. 269 - another error code 270 */ 271 status_t 272 BVolume::SetName(const char *name) 273 { 274 // check initialization 275 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 276 if (error == B_OK) 277 error = BPrivate::Storage::set_volume_name(fDevice, name); 278 return error; 279 } 280 281 // GetIcon 282 /*! \brief Returns the icon of the volume. 283 \param icon A pointer to a pre-allocated BBitmap of the correct dimension 284 to store the requested icon (16x16 for the mini and 32x32 for the 285 large icon). 286 \param which Specifies the size of the icon to be retrieved: 287 \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon. 288 */ 289 status_t 290 BVolume::GetIcon(BBitmap *icon, icon_size which) const 291 { 292 // check parameter and initialization 293 status_t error = (icon && InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 294 BRect rect; 295 if (error == B_OK) { 296 if (which == B_MINI_ICON) 297 rect.Set(0, 0, 15, 15); 298 else if (which == B_LARGE_ICON) 299 rect.Set(0, 0, 31, 31); 300 else 301 error = B_BAD_VALUE; 302 } 303 // check whether icon size and bitmap dimensions do match 304 if (error == B_OK 305 && (icon->Bounds() != rect || icon->ColorSpace() != B_CMAP8)) { 306 error = B_BAD_VALUE; 307 } 308 // get FS stat 309 fs_info info; 310 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 311 error = errno; 312 // get the icon 313 if (error == B_OK) 314 error = get_device_icon(info.device_name, icon->Bits(), which); 315 return error; 316 } 317 318 // IsRemovable 319 /*! \brief Returns whether the volume is removable. 320 \return \c true, when the object is properly initialized and the 321 referred to volume is removable, \c false otherwise. 322 */ 323 bool 324 BVolume::IsRemovable() const 325 { 326 // check initialization 327 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 328 // get FS stat 329 fs_info info; 330 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 331 error = errno; 332 return (error == B_OK && (info.flags & B_FS_IS_REMOVABLE)); 333 } 334 335 // IsReadOnly 336 /*! \brief Returns whether the volume is read only. 337 \return \c true, when the object is properly initialized and the 338 referred to volume is read only, \c false otherwise. 339 */ 340 bool 341 BVolume::IsReadOnly(void) const 342 { 343 // check initialization 344 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 345 // get FS stat 346 fs_info info; 347 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 348 error = errno; 349 return (error == B_OK && (info.flags & B_FS_IS_READONLY)); 350 } 351 352 // IsPersistent 353 /*! \brief Returns whether the volume is persistent. 354 \return \c true, when the object is properly initialized and the 355 referred to volume is persistent, \c false otherwise. 356 */ 357 bool 358 BVolume::IsPersistent(void) const 359 { 360 // check initialization 361 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 362 // get FS stat 363 fs_info info; 364 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 365 error = errno; 366 return (error == B_OK && (info.flags & B_FS_IS_PERSISTENT)); 367 } 368 369 // IsShared 370 /*! \brief Returns whether the volume is shared. 371 \return \c true, when the object is properly initialized and the 372 referred to volume is shared, \c false otherwise. 373 */ 374 bool 375 BVolume::IsShared(void) const 376 { 377 // check initialization 378 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 379 // get FS stat 380 fs_info info; 381 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 382 error = errno; 383 return (error == B_OK && (info.flags & B_FS_IS_SHARED)); 384 } 385 386 // KnowsMime 387 /*! \brief Returns whether the volume supports MIME types. 388 \return \c true, when the object is properly initialized and the 389 referred to volume supports MIME types, \c false otherwise. 390 */ 391 bool 392 BVolume::KnowsMime(void) const 393 { 394 // check initialization 395 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 396 // get FS stat 397 fs_info info; 398 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 399 error = errno; 400 return (error == B_OK && (info.flags & B_FS_HAS_MIME)); 401 } 402 403 // KnowsAttr 404 /*! \brief Returns whether the volume supports attributes. 405 \return \c true, when the object is properly initialized and the 406 referred to volume supports attributes, \c false otherwise. 407 */ 408 bool 409 BVolume::KnowsAttr(void) const 410 { 411 // check initialization 412 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 413 // get FS stat 414 fs_info info; 415 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 416 error = errno; 417 return (error == B_OK && (info.flags & B_FS_HAS_ATTR)); 418 } 419 420 // KnowsQuery 421 /*! \brief Returns whether the volume supports queries. 422 \return \c true, when the object is properly initialized and the 423 referred to volume supports queries, \c false otherwise. 424 */ 425 bool 426 BVolume::KnowsQuery(void) const 427 { 428 // check initialization 429 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 430 // get FS stat 431 fs_info info; 432 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 433 error = errno; 434 return (error == B_OK && (info.flags & B_FS_HAS_QUERY)); 435 } 436 437 // == 438 /*! \brief Returns whether two BVolume objects are equal. 439 440 Two volume objects are said to be equal, if they either are both 441 uninitialized, or both are initialized and refer to the same volume. 442 443 \param volume The object to be compared with. 444 \result \c true, if this object and the supplied one are equal, \c false 445 otherwise. 446 */ 447 bool 448 BVolume::operator==(const BVolume &volume) const 449 { 450 return (InitCheck() != B_OK && volume.InitCheck() != B_OK 451 || fDevice == volume.fDevice); 452 } 453 454 // != 455 /*! \brief Returns whether two BVolume objects are unequal. 456 457 Two volume objects are said to be equal, if they either are both 458 uninitialized, or both are initialized and refer to the same volume. 459 460 \param volume The object to be compared with. 461 \result \c true, if this object and the supplied one are unequal, \c false 462 otherwise. 463 */ 464 bool 465 BVolume::operator!=(const BVolume &volume) const 466 { 467 return !(*this == volume); 468 } 469 470 // = 471 /*! \brief Assigns another BVolume object to this one. 472 473 This object is made an exact clone of the supplied one. 474 475 \param volume The volume from which shall be assigned. 476 \return A reference to this object. 477 */ 478 BVolume& 479 BVolume::operator=(const BVolume &volume) 480 { 481 if (&volume != this) { 482 this->fDevice = volume.fDevice; 483 this->fCStatus = volume.fCStatus; 484 } 485 return *this; 486 } 487 488 489 // FBC 490 void BVolume::_ReservedVolume1() {} 491 void BVolume::_ReservedVolume2() {} 492 void BVolume::_ReservedVolume3() {} 493 void BVolume::_ReservedVolume4() {} 494 void BVolume::_ReservedVolume5() {} 495 void BVolume::_ReservedVolume6() {} 496 void BVolume::_ReservedVolume7() {} 497 void BVolume::_ReservedVolume8() {} 498 499 #ifdef USE_OPENBEOS_NAMESPACE 500 } 501 #endif 502