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