xref: /haiku/src/kits/storage/Volume.cpp (revision 81f5654c124bf46fba0fd251f208e2d88d81e1ce)
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