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((dev_t)-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((dev_t)-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 = (dev_t)-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 279 // ToDo: change the name of the mount point, too 280 // (or the link to the boot volume, if that name has been changed) 281 282 return error; 283 } 284 285 // GetIcon 286 /*! \brief Returns the icon of the volume. 287 \param icon A pointer to a pre-allocated BBitmap of the correct dimension 288 to store the requested icon (16x16 for the mini and 32x32 for the 289 large icon). 290 \param which Specifies the size of the icon to be retrieved: 291 \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon. 292 */ 293 status_t 294 BVolume::GetIcon(BBitmap *icon, icon_size which) const 295 { 296 // check initialization 297 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 298 // get FS stat 299 fs_info info; 300 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 301 error = errno; 302 // get the icon 303 if (error == B_OK) 304 error = get_device_icon(info.device_name, icon, which); 305 return error; 306 } 307 308 // IsRemovable 309 /*! \brief Returns whether the volume is removable. 310 \return \c true, when the object is properly initialized and the 311 referred to volume is removable, \c false otherwise. 312 */ 313 bool 314 BVolume::IsRemovable() const 315 { 316 // check initialization 317 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 318 // get FS stat 319 fs_info info; 320 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 321 error = errno; 322 return (error == B_OK && (info.flags & B_FS_IS_REMOVABLE)); 323 } 324 325 // IsReadOnly 326 /*! \brief Returns whether the volume is read only. 327 \return \c true, when the object is properly initialized and the 328 referred to volume is read only, \c false otherwise. 329 */ 330 bool 331 BVolume::IsReadOnly(void) const 332 { 333 // check initialization 334 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 335 // get FS stat 336 fs_info info; 337 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 338 error = errno; 339 return (error == B_OK && (info.flags & B_FS_IS_READONLY)); 340 } 341 342 // IsPersistent 343 /*! \brief Returns whether the volume is persistent. 344 \return \c true, when the object is properly initialized and the 345 referred to volume is persistent, \c false otherwise. 346 */ 347 bool 348 BVolume::IsPersistent(void) const 349 { 350 // check initialization 351 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 352 // get FS stat 353 fs_info info; 354 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 355 error = errno; 356 return (error == B_OK && (info.flags & B_FS_IS_PERSISTENT)); 357 } 358 359 // IsShared 360 /*! \brief Returns whether the volume is shared. 361 \return \c true, when the object is properly initialized and the 362 referred to volume is shared, \c false otherwise. 363 */ 364 bool 365 BVolume::IsShared(void) const 366 { 367 // check initialization 368 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 369 // get FS stat 370 fs_info info; 371 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 372 error = errno; 373 return (error == B_OK && (info.flags & B_FS_IS_SHARED)); 374 } 375 376 // KnowsMime 377 /*! \brief Returns whether the volume supports MIME types. 378 \return \c true, when the object is properly initialized and the 379 referred to volume supports MIME types, \c false otherwise. 380 */ 381 bool 382 BVolume::KnowsMime(void) const 383 { 384 // check initialization 385 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 386 // get FS stat 387 fs_info info; 388 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 389 error = errno; 390 return (error == B_OK && (info.flags & B_FS_HAS_MIME)); 391 } 392 393 // KnowsAttr 394 /*! \brief Returns whether the volume supports attributes. 395 \return \c true, when the object is properly initialized and the 396 referred to volume supports attributes, \c false otherwise. 397 */ 398 bool 399 BVolume::KnowsAttr(void) const 400 { 401 // check initialization 402 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 403 // get FS stat 404 fs_info info; 405 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 406 error = errno; 407 return (error == B_OK && (info.flags & B_FS_HAS_ATTR)); 408 } 409 410 // KnowsQuery 411 /*! \brief Returns whether the volume supports queries. 412 \return \c true, when the object is properly initialized and the 413 referred to volume supports queries, \c false otherwise. 414 */ 415 bool 416 BVolume::KnowsQuery(void) const 417 { 418 // check initialization 419 status_t error = (InitCheck() == B_OK ? B_OK : B_BAD_VALUE); 420 // get FS stat 421 fs_info info; 422 if (error == B_OK && fs_stat_dev(fDevice, &info) != 0) 423 error = errno; 424 return (error == B_OK && (info.flags & B_FS_HAS_QUERY)); 425 } 426 427 // == 428 /*! \brief Returns whether two BVolume objects are equal. 429 430 Two volume objects are said to be equal, if they either are both 431 uninitialized, or both are initialized and refer to the same volume. 432 433 \param volume The object to be compared with. 434 \result \c true, if this object and the supplied one are equal, \c false 435 otherwise. 436 */ 437 bool 438 BVolume::operator==(const BVolume &volume) const 439 { 440 return (InitCheck() != B_OK && volume.InitCheck() != B_OK 441 || fDevice == volume.fDevice); 442 } 443 444 // != 445 /*! \brief Returns whether two BVolume objects are unequal. 446 447 Two volume objects are said to be equal, if they either are both 448 uninitialized, or both are initialized and refer to the same volume. 449 450 \param volume The object to be compared with. 451 \result \c true, if this object and the supplied one are unequal, \c false 452 otherwise. 453 */ 454 bool 455 BVolume::operator!=(const BVolume &volume) const 456 { 457 return !(*this == volume); 458 } 459 460 // = 461 /*! \brief Assigns another BVolume object to this one. 462 463 This object is made an exact clone of the supplied one. 464 465 \param volume The volume from which shall be assigned. 466 \return A reference to this object. 467 */ 468 BVolume& 469 BVolume::operator=(const BVolume &volume) 470 { 471 if (&volume != this) { 472 this->fDevice = volume.fDevice; 473 this->fCStatus = volume.fCStatus; 474 } 475 return *this; 476 } 477 478 479 // FBC 480 void BVolume::_TurnUpTheVolume1() {} 481 void BVolume::_TurnUpTheVolume2() {} 482 void BVolume::_TurnUpTheVolume3() {} 483 void BVolume::_TurnUpTheVolume4() {} 484 void BVolume::_TurnUpTheVolume5() {} 485 void BVolume::_TurnUpTheVolume6() {} 486 void BVolume::_TurnUpTheVolume7() {} 487 void BVolume::_TurnUpTheVolume8() {} 488 489 #ifdef USE_OPENBEOS_NAMESPACE 490 } 491 #endif 492