1 /*
2 * Copyright 2003-2006, Haiku Inc.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Ingo Weinhold, bonefish@users.sf.net
7 */
8
9 #include <DiskDeviceList.h>
10
11 #include <AutoLocker.h>
12 #include <DiskDevice.h>
13 #include <DiskDevicePrivate.h>
14 #include <DiskDeviceRoster.h>
15 #include <Locker.h>
16 #include <Looper.h>
17 #include <Partition.h>
18
19 #include <new>
20 using namespace std;
21
22 // constructor
23 /*! \brief Creates an empty BDiskDeviceList object.
24 */
BDiskDeviceList(bool useOwnLocker)25 BDiskDeviceList::BDiskDeviceList(bool useOwnLocker)
26 : fLocker(NULL),
27 fDevices(20, true),
28 fSubscribed(false)
29 {
30 if (useOwnLocker)
31 fLocker = new(nothrow) BLocker("BDiskDeviceList_fLocker");
32 }
33
34 // destructor
35 /*! \brief Frees all resources associated with the object.
36 */
~BDiskDeviceList()37 BDiskDeviceList::~BDiskDeviceList()
38 {
39 delete fLocker;
40 }
41
42 // MessageReceived
43 /*! \brief Implemented to handle notification messages.
44 */
45 void
MessageReceived(BMessage * message)46 BDiskDeviceList::MessageReceived(BMessage *message)
47 {
48 AutoLocker<BDiskDeviceList> _(this);
49 switch (message->what) {
50 case B_DEVICE_UPDATE:
51 {
52 uint32 event;
53 if (message->FindInt32("event", (int32*)&event) == B_OK) {
54 switch (event) {
55 case B_DEVICE_MOUNT_POINT_MOVED:
56 _MountPointMoved(message);
57 break;
58 case B_DEVICE_PARTITION_MOUNTED:
59 _PartitionMounted(message);
60 break;
61 case B_DEVICE_PARTITION_UNMOUNTED:
62 _PartitionUnmounted(message);
63 break;
64 case B_DEVICE_PARTITION_INITIALIZED:
65 _PartitionInitialized(message);
66 break;
67 case B_DEVICE_PARTITION_RESIZED:
68 _PartitionResized(message);
69 break;
70 case B_DEVICE_PARTITION_MOVED:
71 _PartitionMoved(message);
72 break;
73 case B_DEVICE_PARTITION_CREATED:
74 _PartitionCreated(message);
75 break;
76 case B_DEVICE_PARTITION_DELETED:
77 _PartitionDeleted(message);
78 break;
79 case B_DEVICE_PARTITION_DEFRAGMENTED:
80 _PartitionDefragmented(message);
81 break;
82 case B_DEVICE_PARTITION_REPAIRED:
83 _PartitionRepaired(message);
84 break;
85 case B_DEVICE_MEDIA_CHANGED:
86 _MediaChanged(message);
87 break;
88 case B_DEVICE_ADDED:
89 _DeviceAdded(message);
90 break;
91 case B_DEVICE_REMOVED:
92 _DeviceRemoved(message);
93 break;
94 }
95 }
96 }
97 default:
98 BHandler::MessageReceived(message);
99 }
100 }
101
102 // SetNextHandler
103 /*! \brief Implemented to unsubscribe from notification services when going
104 to be detached from looper.
105 */
106 void
SetNextHandler(BHandler * handler)107 BDiskDeviceList::SetNextHandler(BHandler *handler)
108 {
109 if (!handler) {
110 AutoLocker<BDiskDeviceList> _(this);
111 if (fSubscribed)
112 _StopWatching();
113 }
114 BHandler::SetNextHandler(handler);
115 }
116
117 // Fetch
118 /*! \brief Empties the list and refills it according to the current state.
119
120 Furthermore, if added to a looper, the list subscribes to notification
121 services needed to keep the list up-to-date.
122
123 If an error occurs, the list Unset()s itself.
124
125 The object doesn't need to be locked, when this method is invoked. The
126 method does itself try to lock the list, but doesn't fail, if that
127 doesn't succeed. That way an object can be used without locking in a
128 single threaded environment.
129
130 \return \c B_OK, if everything went fine, another error code otherwise.
131 */
132 status_t
Fetch()133 BDiskDeviceList::Fetch()
134 {
135 Unset();
136 AutoLocker<BDiskDeviceList> _(this);
137 // register for notifications
138 status_t error = B_OK;
139 if (Looper())
140 error = _StartWatching();
141 // get the devices
142 BDiskDeviceRoster roster;
143 while (error == B_OK) {
144 if (BDiskDevice *device = new(nothrow) BDiskDevice) {
145 status_t status = roster.GetNextDevice(device);
146 if (status == B_OK)
147 fDevices.AddItem(device);
148 else if (status == B_ENTRY_NOT_FOUND)
149 break;
150 else
151 error = status;
152 } else
153 error = B_NO_MEMORY;
154 }
155 // cleanup on error
156 if (error != B_OK)
157 Unset();
158 return error;
159 }
160
161 // Unset
162 /*! \brief Empties the list and unsubscribes from all notification services.
163
164 The object doesn't need to be locked, when this method is invoked. The
165 method does itself try to lock the list, but doesn't fail, if that
166 doesn't succeed. That way an object can be used without locking in a
167 single threaded environment.
168 */
169 void
Unset()170 BDiskDeviceList::Unset()
171 {
172 AutoLocker<BDiskDeviceList> _(this);
173 // unsubscribe from notification services
174 _StopWatching();
175 // empty the list
176 fDevices.MakeEmpty();
177 }
178
179 // Lock
180 /*! \brief Locks the list.
181
182 If on construction it had been specified, that the list shall use an
183 own BLocker, then this locker is locked, otherwise LockLooper() is
184 invoked.
185
186 \return \c true, if the list could be locked successfully, \c false
187 otherwise.
188 */
189 bool
Lock()190 BDiskDeviceList::Lock()
191 {
192 if (fLocker)
193 return fLocker->Lock();
194 return LockLooper();
195 }
196
197 // Unlock
198 /*! \brief Unlocks the list.
199
200 If on construction it had been specified, that the list shall use an
201 own BLocker, then this locker is unlocked, otherwise UnlockLooper() is
202 invoked.
203 */
204 void
Unlock()205 BDiskDeviceList::Unlock()
206 {
207 if (fLocker)
208 return fLocker->Unlock();
209 return UnlockLooper();
210 }
211
212 // CountDevices
213 /*! \brief Returns the number of devices in the list.
214
215 The list must be locked.
216
217 \return The number of devices in the list.
218 */
219 int32
CountDevices() const220 BDiskDeviceList::CountDevices() const
221 {
222 return fDevices.CountItems();
223 }
224
225 // DeviceAt
226 /*! \brief Retrieves a device by index.
227
228 The list must be locked.
229
230 \param index The list index of the device to be returned.
231 \return The device with index \a index, or \c NULL, if the list is not
232 locked or \a index is out of range.
233 */
234 BDiskDevice *
DeviceAt(int32 index) const235 BDiskDeviceList::DeviceAt(int32 index) const
236 {
237 return fDevices.ItemAt(index);
238 }
239
240 // VisitEachDevice
241 /*! \brief Iterates through the all devices in the list.
242
243 The supplied visitor's Visit(BDiskDevice*) is invoked for each device.
244 If Visit() returns \c true, the iteration is terminated and this method
245 returns the respective device.
246
247 The list must be locked.
248
249 \param visitor The visitor.
250 \return The respective device, if the iteration was terminated early,
251 \c NULL otherwise.
252 */
253 BDiskDevice *
VisitEachDevice(BDiskDeviceVisitor * visitor)254 BDiskDeviceList::VisitEachDevice(BDiskDeviceVisitor *visitor)
255 {
256 if (visitor) {
257 for (int32 i = 0; BDiskDevice *device = DeviceAt(i); i++) {
258 if (visitor->Visit(device))
259 return device;
260 }
261 }
262 return NULL;
263 }
264
265 // VisitEachPartition
266 /*! \brief Iterates through the all devices' partitions.
267
268 The supplied visitor's Visit(BPartition*) is invoked for each partition.
269 If Visit() returns \c true, the iteration is terminated and this method
270 returns the respective partition.
271
272 The list must be locked.
273
274 \param visitor The visitor.
275 \return The respective partition, if the iteration was terminated early,
276 \c NULL otherwise.
277 */
278 BPartition *
VisitEachPartition(BDiskDeviceVisitor * visitor)279 BDiskDeviceList::VisitEachPartition(BDiskDeviceVisitor *visitor)
280 {
281 if (visitor) {
282 for (int32 i = 0; BDiskDevice *device = DeviceAt(i); i++) {
283 if (BPartition *partition = device->VisitEachDescendant(visitor))
284 return partition;
285 }
286 }
287 return NULL;
288 }
289
290 // VisitEachMountedPartition
291 /*! \brief Iterates through the all devices' partitions that are mounted.
292
293 The supplied visitor's Visit(BPartition*) is invoked for each mounted
294 partition.
295 If Visit() returns \c true, the iteration is terminated and this method
296 returns the respective partition.
297
298 The list must be locked.
299
300 \param visitor The visitor.
301 \return The respective partition, if the iteration was terminated early,
302 \c NULL otherwise.
303 */
304 BPartition *
VisitEachMountedPartition(BDiskDeviceVisitor * visitor)305 BDiskDeviceList::VisitEachMountedPartition(BDiskDeviceVisitor *visitor)
306 {
307 BPartition *partition = NULL;
308 if (visitor) {
309 struct MountedPartitionFilter : public PartitionFilter {
310 virtual ~MountedPartitionFilter() {};
311 virtual bool Filter(BPartition *partition, int32 level)
312 { return partition->IsMounted(); }
313 } filter;
314 PartitionFilterVisitor filterVisitor(visitor, &filter);
315 partition = VisitEachPartition(&filterVisitor);
316 }
317 return partition;
318 }
319
320 // VisitEachMountablePartition
321 /*! \brief Iterates through the all devices' partitions that are mountable.
322
323 The supplied visitor's Visit(BPartition*) is invoked for each mountable
324 partition.
325 If Visit() returns \c true, the iteration is terminated and this method
326 returns the respective partition.
327
328 The list must be locked.
329
330 \param visitor The visitor.
331 \return The respective partition, if the iteration was terminated early,
332 \c NULL otherwise.
333 */
334 BPartition *
VisitEachMountablePartition(BDiskDeviceVisitor * visitor)335 BDiskDeviceList::VisitEachMountablePartition(BDiskDeviceVisitor *visitor)
336 {
337 BPartition *partition = NULL;
338 if (visitor) {
339 struct MountablePartitionFilter : public PartitionFilter {
340 virtual ~MountablePartitionFilter() {};
341 virtual bool Filter(BPartition *partition, int32 level)
342 { return partition->ContainsFileSystem(); }
343 } filter;
344 PartitionFilterVisitor filterVisitor(visitor, &filter);
345 partition = VisitEachPartition(&filterVisitor);
346 }
347 return partition;
348 }
349
350 // DeviceWithID
351 /*! \brief Retrieves a device by ID.
352
353 The list must be locked.
354
355 \param id The ID of the device to be returned.
356 \return The device with ID \a id, or \c NULL, if the list is not
357 locked or no device with ID \a id is in the list.
358 */
359 BDiskDevice *
DeviceWithID(int32 id) const360 BDiskDeviceList::DeviceWithID(int32 id) const
361 {
362 IDFinderVisitor visitor(id);
363 return const_cast<BDiskDeviceList*>(this)->VisitEachDevice(&visitor);
364 }
365
366 // PartitionWithID
367 /*! \brief Retrieves a partition by ID.
368
369 The list must be locked.
370
371 \param id The ID of the partition to be returned.
372 \return The partition with ID \a id, or \c NULL, if the list is not
373 locked or no partition with ID \a id is in the list.
374 */
375 BPartition *
PartitionWithID(int32 id) const376 BDiskDeviceList::PartitionWithID(int32 id) const
377 {
378 IDFinderVisitor visitor(id);
379 return const_cast<BDiskDeviceList*>(this)->VisitEachPartition(&visitor);
380 }
381
382 // MountPointMoved
383 /*! \brief Invoked, when the mount point of a partition has been moved.
384
385 The list is locked, when this method is invoked.
386
387 \param partition The concerned partition.
388 */
389 void
MountPointMoved(BPartition * partition)390 BDiskDeviceList::MountPointMoved(BPartition *partition)
391 {
392 PartitionChanged(partition, B_DEVICE_MOUNT_POINT_MOVED);
393 }
394
395 // PartitionMounted
396 /*! \brief Invoked, when a partition has been mounted.
397
398 The list is locked, when this method is invoked.
399
400 \param partition The concerned partition.
401 */
402 void
PartitionMounted(BPartition * partition)403 BDiskDeviceList::PartitionMounted(BPartition *partition)
404 {
405 PartitionChanged(partition, B_DEVICE_PARTITION_MOUNTED);
406 }
407
408 // PartitionUnmounted
409 /*! \brief Invoked, when a partition has been unmounted.
410
411 The list is locked, when this method is invoked.
412
413 \param partition The concerned partition.
414 */
415 void
PartitionUnmounted(BPartition * partition)416 BDiskDeviceList::PartitionUnmounted(BPartition *partition)
417 {
418 PartitionChanged(partition, B_DEVICE_PARTITION_UNMOUNTED);
419 }
420
421 // PartitionInitialized
422 /*! \brief Invoked, when a partition has been initialized.
423
424 The list is locked, when this method is invoked.
425
426 \param partition The concerned partition.
427 */
428 void
PartitionInitialized(BPartition * partition)429 BDiskDeviceList::PartitionInitialized(BPartition *partition)
430 {
431 PartitionChanged(partition, B_DEVICE_PARTITION_INITIALIZED);
432 }
433
434 // PartitionResized
435 /*! \brief Invoked, when a partition has been resized.
436
437 The list is locked, when this method is invoked.
438
439 \param partition The concerned partition.
440 */
441 void
PartitionResized(BPartition * partition)442 BDiskDeviceList::PartitionResized(BPartition *partition)
443 {
444 PartitionChanged(partition, B_DEVICE_PARTITION_RESIZED);
445 }
446
447 // PartitionMoved
448 /*! \brief Invoked, when a partition has been moved.
449
450 The list is locked, when this method is invoked.
451
452 \param partition The concerned partition.
453 */
454 void
PartitionMoved(BPartition * partition)455 BDiskDeviceList::PartitionMoved(BPartition *partition)
456 {
457 PartitionChanged(partition, B_DEVICE_PARTITION_MOVED);
458 }
459
460 // PartitionCreated
461 /*! \brief Invoked, when a partition has been created.
462
463 The list is locked, when this method is invoked.
464
465 \param partition The concerned partition.
466 */
467 void
PartitionCreated(BPartition * partition)468 BDiskDeviceList::PartitionCreated(BPartition *partition)
469 {
470 }
471
472 // PartitionDeleted
473 /*! \brief Invoked, when a partition has been deleted.
474
475 The method is called twice for a deleted partition. The first time
476 before the BDiskDevice the partition belongs to has been updated. The
477 \a partition parameter will point to a still valid BPartition object.
478 On the second invocation the device object will have been updated and
479 the partition object will have been deleted -- \a partition will be
480 \c NULL then.
481
482 The list is locked, when this method is invoked.
483
484 \param partition The concerned partition. Only non- \c NULL on the first
485 invocation.
486 \param partitionID The ID of the concerned partition.
487 */
488 void
PartitionDeleted(BPartition * partition,partition_id partitionID)489 BDiskDeviceList::PartitionDeleted(BPartition *partition,
490 partition_id partitionID)
491 {
492 }
493
494 // PartitionDefragmented
495 /*! \brief Invoked, when a partition has been defragmented.
496
497 The list is locked, when this method is invoked.
498
499 \param partition The concerned partition.
500 */
501 void
PartitionDefragmented(BPartition * partition)502 BDiskDeviceList::PartitionDefragmented(BPartition *partition)
503 {
504 PartitionChanged(partition, B_DEVICE_PARTITION_DEFRAGMENTED);
505 }
506
507 // PartitionRepaired
508 /*! \brief Invoked, when a partition has been repaired.
509
510 The list is locked, when this method is invoked.
511
512 \param partition The concerned partition.
513 */
514 void
PartitionRepaired(BPartition * partition)515 BDiskDeviceList::PartitionRepaired(BPartition *partition)
516 {
517 PartitionChanged(partition, B_DEVICE_PARTITION_REPAIRED);
518 }
519
520 // PartitionChanged
521 /*! \brief Catch-all method invoked by the \c Partition*() hooks, save by
522 PartitionCreated() and PartitionDeleted().
523
524 If you're interested only in the fact, that something about the partition
525 changed, you can just override this hook instead of the ones telling you
526 exactly what happened.
527
528 \param partition The concerned partition.
529 \param event The event that occurred, if you are interested in it after all.
530 */
531 void
PartitionChanged(BPartition * partition,uint32 event)532 BDiskDeviceList::PartitionChanged(BPartition *partition, uint32 event)
533 {
534 }
535
536 // MediaChanged
537 /*! \brief Invoked, when the media of a device has been changed.
538
539 The list is locked, when this method is invoked.
540
541 \param device The concerned device.
542 */
543 void
MediaChanged(BDiskDevice * device)544 BDiskDeviceList::MediaChanged(BDiskDevice *device)
545 {
546 }
547
548 // DeviceAdded
549 /*! \brief Invoked, when a device has been added.
550
551 The list is locked, when this method is invoked.
552
553 \param device The concerned device.
554 */
555 void
DeviceAdded(BDiskDevice * device)556 BDiskDeviceList::DeviceAdded(BDiskDevice *device)
557 {
558 }
559
560 // DeviceRemoved
561 /*! \brief Invoked, when a device has been removed.
562
563 The supplied object is already removed from the list and is going to be
564 deleted after the hook returns.
565
566 The list is locked, when this method is invoked.
567
568 \param device The concerned device.
569 */
570 void
DeviceRemoved(BDiskDevice * device)571 BDiskDeviceList::DeviceRemoved(BDiskDevice *device)
572 {
573 }
574
575 // _StartWatching
576 /*! \brief Starts watching for disk device notifications.
577
578 The object must be locked (if possible at all), when this method is
579 invoked.
580
581 \return \c B_OK, if everything went fine, another error code otherwise.
582 */
583 status_t
_StartWatching()584 BDiskDeviceList::_StartWatching()
585 {
586 if (!Looper() || fSubscribed)
587 return B_BAD_VALUE;
588
589 status_t error = BDiskDeviceRoster().StartWatching(BMessenger(this));
590 fSubscribed = (error == B_OK);
591 return error;
592 }
593
594 // _StopWatching
595 /*! \brief Stop watching for disk device notifications.
596
597 The object must be locked (if possible at all), when this method is
598 invoked.
599 */
600 void
_StopWatching()601 BDiskDeviceList::_StopWatching()
602 {
603 if (fSubscribed) {
604 BDiskDeviceRoster().StopWatching(BMessenger(this));
605 fSubscribed = false;
606 }
607 }
608
609 // _MountPointMoved
610 /*! \brief Handles a "mount point moved" message.
611 \param message The respective notification message.
612 */
613 void
_MountPointMoved(BMessage * message)614 BDiskDeviceList::_MountPointMoved(BMessage *message)
615 {
616 if (_UpdateDevice(message) != NULL) {
617 if (BPartition *partition = _FindPartition(message))
618 MountPointMoved(partition);
619 }
620 }
621
622 // _PartitionMounted
623 /*! \brief Handles a "partition mounted" message.
624 \param message The respective notification message.
625 */
626 void
_PartitionMounted(BMessage * message)627 BDiskDeviceList::_PartitionMounted(BMessage *message)
628 {
629 if (_UpdateDevice(message) != NULL) {
630 if (BPartition *partition = _FindPartition(message))
631 PartitionMounted(partition);
632 }
633 }
634
635 // _PartitionUnmounted
636 /*! \brief Handles a "partition unmounted" message.
637 \param message The respective notification message.
638 */
639 void
_PartitionUnmounted(BMessage * message)640 BDiskDeviceList::_PartitionUnmounted(BMessage *message)
641 {
642 if (_UpdateDevice(message) != NULL) {
643 if (BPartition *partition = _FindPartition(message))
644 PartitionUnmounted(partition);
645 }
646 }
647
648 // _PartitionInitialized
649 /*! \brief Handles a "partition initialized" message.
650 \param message The respective notification message.
651 */
652 void
_PartitionInitialized(BMessage * message)653 BDiskDeviceList::_PartitionInitialized(BMessage *message)
654 {
655 if (_UpdateDevice(message) != NULL) {
656 if (BPartition *partition = _FindPartition(message))
657 PartitionInitialized(partition);
658 }
659 }
660
661 // _PartitionResized
662 /*! \brief Handles a "partition resized" message.
663 \param message The respective notification message.
664 */
665 void
_PartitionResized(BMessage * message)666 BDiskDeviceList::_PartitionResized(BMessage *message)
667 {
668 if (_UpdateDevice(message) != NULL) {
669 if (BPartition *partition = _FindPartition(message))
670 PartitionResized(partition);
671 }
672 }
673
674 // _PartitionMoved
675 /*! \brief Handles a "partition moved" message.
676 \param message The respective notification message.
677 */
678 void
_PartitionMoved(BMessage * message)679 BDiskDeviceList::_PartitionMoved(BMessage *message)
680 {
681 if (_UpdateDevice(message) != NULL) {
682 if (BPartition *partition = _FindPartition(message))
683 PartitionMoved(partition);
684 }
685 }
686
687 // _PartitionCreated
688 /*! \brief Handles a "partition created" message.
689 \param message The respective notification message.
690 */
691 void
_PartitionCreated(BMessage * message)692 BDiskDeviceList::_PartitionCreated(BMessage *message)
693 {
694 if (_UpdateDevice(message) != NULL) {
695 if (BPartition *partition = _FindPartition(message))
696 PartitionCreated(partition);
697 }
698 }
699
700 // _PartitionDeleted
701 /*! \brief Handles a "partition deleted" message.
702 \param message The respective notification message.
703 */
704 void
_PartitionDeleted(BMessage * message)705 BDiskDeviceList::_PartitionDeleted(BMessage *message)
706 {
707 if (BPartition *partition = _FindPartition(message)) {
708 partition_id id = partition->ID();
709 PartitionDeleted(partition, id);
710 if (_UpdateDevice(message))
711 PartitionDeleted(NULL, id);
712 }
713 }
714
715 // _PartitionDefragmented
716 /*! \brief Handles a "partition defragmented" message.
717 \param message The respective notification message.
718 */
719 void
_PartitionDefragmented(BMessage * message)720 BDiskDeviceList::_PartitionDefragmented(BMessage *message)
721 {
722 if (_UpdateDevice(message) != NULL) {
723 if (BPartition *partition = _FindPartition(message))
724 PartitionDefragmented(partition);
725 }
726 }
727
728 // _PartitionRepaired
729 /*! \brief Handles a "partition repaired" message.
730 \param message The respective notification message.
731 */
732 void
_PartitionRepaired(BMessage * message)733 BDiskDeviceList::_PartitionRepaired(BMessage *message)
734 {
735 if (_UpdateDevice(message) != NULL) {
736 if (BPartition *partition = _FindPartition(message))
737 PartitionRepaired(partition);
738 }
739 }
740
741 // _MediaChanged
742 /*! \brief Handles a "media changed" message.
743 \param message The respective notification message.
744 */
745 void
_MediaChanged(BMessage * message)746 BDiskDeviceList::_MediaChanged(BMessage *message)
747 {
748 if (BDiskDevice *device = _UpdateDevice(message))
749 MediaChanged(device);
750 }
751
752 // _DeviceAdded
753 /*! \brief Handles a "device added" message.
754 \param message The respective notification message.
755 */
756 void
_DeviceAdded(BMessage * message)757 BDiskDeviceList::_DeviceAdded(BMessage *message)
758 {
759 int32 id;
760 if (message->FindInt32("device_id", &id) == B_OK && !DeviceWithID(id)) {
761 BDiskDevice *device = new(nothrow) BDiskDevice;
762 if (BDiskDeviceRoster().GetDeviceWithID(id, device) == B_OK) {
763 fDevices.AddItem(device);
764 DeviceAdded(device);
765 } else
766 delete device;
767 }
768 }
769
770 // _DeviceRemoved
771 /*! \brief Handles a "device removed" message.
772 \param message The respective notification message.
773 */
774 void
_DeviceRemoved(BMessage * message)775 BDiskDeviceList::_DeviceRemoved(BMessage *message)
776 {
777 if (BDiskDevice *device = _FindDevice(message)) {
778 fDevices.RemoveItem(device, false);
779 DeviceRemoved(device);
780 delete device;
781 }
782 }
783
784 // _FindDevice
785 /*! \brief Returns the device for the ID contained in a motification message.
786 \param message The notification message.
787 \return The device with the ID, or \c NULL, if the ID or the device could
788 not be found.
789 */
790 BDiskDevice *
_FindDevice(BMessage * message)791 BDiskDeviceList::_FindDevice(BMessage *message)
792 {
793 BDiskDevice *device = NULL;
794 int32 id;
795 if (message->FindInt32("device_id", &id) == B_OK)
796 device = DeviceWithID(id);
797 return device;
798 }
799
800 // _FindPartition
801 /*! \brief Returns the partition for the ID contained in a motification
802 message.
803 \param message The notification message.
804 \return The partition with the ID, or \c NULL, if the ID or the partition
805 could not be found.*/
806 BPartition *
_FindPartition(BMessage * message)807 BDiskDeviceList::_FindPartition(BMessage *message)
808 {
809 BPartition *partition = NULL;
810 int32 id;
811 if (message->FindInt32("partition_id", &id) == B_OK)
812 partition = PartitionWithID(id);
813 return partition;
814 }
815
816 // _UpdateDevice
817 /*! \brief Finds the device for the ID contained in a motification message
818 and updates it.
819 \param message The notification message.
820 \return The device with the ID, or \c NULL, if the ID or the device could
821 not be found.
822 */
823 BDiskDevice *
_UpdateDevice(BMessage * message)824 BDiskDeviceList::_UpdateDevice(BMessage *message)
825 {
826 BDiskDevice *device = _FindDevice(message);
827 if (device) {
828 if (device->Update() != B_OK) {
829 fDevices.RemoveItem(device);
830 device = NULL;
831 }
832 }
833 return device;
834 }
835
836