xref: /haiku/src/kits/storage/disk_device/MutablePartition.cpp (revision b30304acc8c37e678a1bf66976d15bdab103f931)
1 /*
2  * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 #include <MutablePartition.h>
7 
8 #include <stdlib.h>
9 #include <string.h>
10 
11 #include <new>
12 
13 #include <Partition.h>
14 
15 #include <ddm_userland_interface_defs.h>
16 
17 #include "DiskDeviceUtils.h"
18 #include "PartitionDelegate.h"
19 
20 
21 using std::nothrow;
22 
23 
24 // UninitializeContents
25 void
26 BMutablePartition::UninitializeContents()
27 {
28 	DeleteAllChildren();
29 	SetVolumeID(-1);
30 	SetContentName(NULL);
31 	SetContentParameters(NULL);
32 	SetContentSize(0);
33 	SetBlockSize(Parent()->BlockSize());
34 	SetContentType(NULL);
35 	SetStatus(B_PARTITION_UNINITIALIZED);
36 	ClearFlags(B_PARTITION_FILE_SYSTEM | B_PARTITION_PARTITIONING_SYSTEM);
37 //	if (!Device()->IsReadOnlyMedia())
38 //		ClearFlags(B_PARTITION_READ_ONLY);
39 }
40 
41 
42 // Offset
43 off_t
44 BMutablePartition::Offset() const
45 {
46 	return fData->offset;
47 }
48 
49 
50 // SetOffset
51 void
52 BMutablePartition::SetOffset(off_t offset)
53 {
54 	if (fData->offset != offset) {
55 		fData->offset = offset;
56 		Changed(B_PARTITION_CHANGED_OFFSET);
57 	}
58 }
59 
60 
61 // Size
62 off_t
63 BMutablePartition::Size() const
64 {
65 	return fData->size;
66 }
67 
68 
69 // SetSize
70 void
71 BMutablePartition::SetSize(off_t size)
72 {
73 	if (fData->size != size) {
74 		fData->size = size;
75 		Changed(B_PARTITION_CHANGED_SIZE);
76 	}
77 }
78 
79 
80 // ContentSize
81 off_t
82 BMutablePartition::ContentSize() const
83 {
84 	return fData->content_size;
85 }
86 
87 
88 // SetContentSize
89 void
90 BMutablePartition::SetContentSize(off_t size)
91 {
92 	if (fData->content_size != size) {
93 		fData->content_size = size;
94 		Changed(B_PARTITION_CHANGED_CONTENT_SIZE);
95 	}
96 }
97 
98 
99 // BlockSize
100 off_t
101 BMutablePartition::BlockSize() const
102 {
103 	return fData->block_size;
104 }
105 
106 
107 // SetBlockSize
108 void
109 BMutablePartition::SetBlockSize(off_t blockSize)
110 {
111 	if (fData->block_size != blockSize) {
112 		fData->block_size = blockSize;
113 		Changed(B_PARTITION_CHANGED_BLOCK_SIZE);
114 	}
115 }
116 
117 
118 // Status
119 uint32
120 BMutablePartition::Status() const
121 {
122 	return fData->status;
123 }
124 
125 
126 // SetStatus
127 void
128 BMutablePartition::SetStatus(uint32 status)
129 {
130 	if (fData->status != status) {
131 		fData->status = status;
132 		Changed(B_PARTITION_CHANGED_STATUS);
133 	}
134 }
135 
136 
137 // Flags
138 uint32
139 BMutablePartition::Flags() const
140 {
141 	return fData->flags;
142 }
143 
144 
145 // SetFlags
146 void
147 BMutablePartition::SetFlags(uint32 flags)
148 {
149 	if (fData->flags != flags) {
150 		fData->flags = flags;
151 		Changed(B_PARTITION_CHANGED_FLAGS);
152 	}
153 }
154 
155 
156 // ClearFlags
157 void
158 BMutablePartition::ClearFlags(uint32 flags)
159 {
160 	if (flags & fData->flags) {
161 		fData->flags &= ~flags;
162 		Changed(B_PARTITION_CHANGED_FLAGS);
163 	}
164 }
165 
166 
167 // VolumeID
168 dev_t
169 BMutablePartition::VolumeID() const
170 {
171 	return fData->volume;
172 }
173 
174 
175 // SetVolumeID
176 void
177 BMutablePartition::SetVolumeID(dev_t volumeID)
178 {
179 	if (fData->volume != volumeID) {
180 		fData->volume = volumeID;
181 		Changed(B_PARTITION_CHANGED_VOLUME);
182 	}
183 }
184 
185 
186 // Index
187 int32
188 BMutablePartition::Index() const
189 {
190 	return fData->index;
191 }
192 
193 
194 // Name
195 const char*
196 BMutablePartition::Name() const
197 {
198 	return fData->name;
199 }
200 
201 
202 // SetName
203 status_t
204 BMutablePartition::SetName(const char* name)
205 {
206 	if (compare_string(name, fData->name) == 0)
207 		return B_OK;
208 
209 	if (set_string(fData->name, name) != B_OK)
210 		return B_NO_MEMORY;
211 
212 	Changed(B_PARTITION_CHANGED_NAME);
213 	return B_OK;
214 }
215 
216 
217 // ContentName
218 const char*
219 BMutablePartition::ContentName() const
220 {
221 	return fData->content_name;
222 }
223 
224 
225 // SetContentName
226 status_t
227 BMutablePartition::SetContentName(const char* name)
228 {
229 	if (compare_string(name, fData->content_name) == 0)
230 		return B_OK;
231 
232 	if (set_string(fData->content_name, name) != B_OK)
233 		return B_NO_MEMORY;
234 
235 	Changed(B_PARTITION_CHANGED_CONTENT_NAME);
236 	return B_OK;
237 }
238 
239 
240 // Type
241 const char*
242 BMutablePartition::Type() const
243 {
244 	return fData->type;
245 }
246 
247 
248 // SetType
249 status_t
250 BMutablePartition::SetType(const char* type)
251 {
252 	if (compare_string(type, fData->type) == 0)
253 		return B_OK;
254 
255 	if (set_string(fData->type, type) != B_OK)
256 		return B_NO_MEMORY;
257 
258 	Changed(B_PARTITION_CHANGED_TYPE);
259 	return B_OK;
260 }
261 
262 
263 // ContentType
264 const char*
265 BMutablePartition::ContentType() const
266 {
267 	return fData->content_type;
268 }
269 
270 
271 // SetContentType
272 status_t
273 BMutablePartition::SetContentType(const char* type)
274 {
275 	if (compare_string(type, fData->content_type) == 0)
276 		return B_OK;
277 
278 	if (set_string(fData->content_type, type) != B_OK)
279 		return B_NO_MEMORY;
280 
281 	Changed(B_PARTITION_CHANGED_CONTENT_TYPE
282 		| B_PARTITION_CHANGED_INITIALIZATION);
283 	return B_OK;
284 }
285 
286 
287 // Parameters
288 const char*
289 BMutablePartition::Parameters() const
290 {
291 	return fData->parameters;
292 }
293 
294 
295 // SetParameters
296 status_t
297 BMutablePartition::SetParameters(const char* parameters)
298 {
299 	if (compare_string(parameters, fData->parameters) == 0)
300 		return B_OK;
301 
302 	if (set_string(fData->parameters, parameters) != B_OK)
303 		return B_NO_MEMORY;
304 
305 	Changed(B_PARTITION_CHANGED_PARAMETERS);
306 	return B_OK;
307 }
308 
309 
310 // ContentParameters
311 const char*
312 BMutablePartition::ContentParameters() const
313 {
314 	return fData->content_parameters;
315 }
316 
317 
318 // SetContentParameters
319 status_t
320 BMutablePartition::SetContentParameters(const char* parameters)
321 {
322 	if (compare_string(parameters, fData->content_parameters) == 0)
323 		return B_OK;
324 
325 	if (set_string(fData->content_parameters, parameters) != B_OK)
326 		return B_NO_MEMORY;
327 
328 	Changed(B_PARTITION_CHANGED_CONTENT_PARAMETERS);
329 	return B_OK;
330 }
331 
332 
333 // CreateChild
334 status_t
335 BMutablePartition::CreateChild(int32 index, BMutablePartition** _child)
336 {
337 	if (index < 0)
338 		index = fChildren.CountItems();
339 	else if (index > fChildren.CountItems())
340 		return B_BAD_VALUE;
341 
342 	// create the BPartition
343 	BPartition* partition = new(nothrow) BPartition;
344 	if (!partition)
345 		return B_NO_MEMORY;
346 
347 	// create the delegate
348 	BPartition::Delegate* delegate
349 		= new(nothrow) BPartition::Delegate(partition);
350 	if (!delegate) {
351 		delete partition;
352 		return B_NO_MEMORY;
353 	}
354 	partition->fDelegate = delegate;
355 // TODO: Any further initialization required?
356 
357 	// add the child
358 	BMutablePartition* child = delegate->MutablePartition();
359 	if (!fChildren.AddItem(child, index)) {
360 		delete partition;
361 		return B_NO_MEMORY;
362 	}
363 	child->fParent = this;
364 
365 	*_child = child;
366 
367 	Changed(B_PARTITION_CHANGED_CHILDREN);
368 	return B_OK;
369 }
370 
371 
372 // CreateChild
373 status_t
374 BMutablePartition::CreateChild(int32 index, const char* type, const char* name,
375 	const char* parameters, BMutablePartition** _child)
376 {
377 	// create the child
378 	BMutablePartition* child;
379 	status_t error = CreateChild(index, &child);
380 	if (error != B_OK)
381 		return error;
382 
383 	// set the name, type, and parameters
384 	error = SetType(type);
385 	if (error == B_OK)
386 		error = SetName(name);
387 	if (error == B_OK)
388 		error = SetParameters(parameters);
389 
390 	// cleanup on error
391 	if (error != B_OK) {
392 		DeleteChild(child);
393 		return error;
394 	}
395 
396 	*_child = child;
397 
398 	Changed(B_PARTITION_CHANGED_CHILDREN);
399 	return B_OK;
400 }
401 
402 
403 // DeleteChild
404 status_t
405 BMutablePartition::DeleteChild(int32 index)
406 {
407 	BMutablePartition* child = (BMutablePartition*)fChildren.RemoveItem(index);
408 	if (!child)
409 		return B_BAD_VALUE;
410 
411 	// This will delete not only all delegates in the child's hierarchy, but
412 	// also the respective partitions themselves, if they are no longer
413 	// referenced.
414 	child->fDelegate->Partition()->_DeleteDelegates();
415 
416 	Changed(B_PARTITION_CHANGED_CHILDREN);
417 	return B_OK;
418 }
419 
420 
421 // DeleteChild
422 status_t
423 BMutablePartition::DeleteChild(BMutablePartition* child)
424 {
425 	return DeleteChild(IndexOfChild(child));
426 }
427 
428 
429 // DeleteAllChildren
430 void
431 BMutablePartition::DeleteAllChildren()
432 {
433 	int32 count = CountChildren();
434 	for (int32 i = count - 1; i >= 0; i--)
435 		DeleteChild(i);
436 }
437 
438 
439 // Parent
440 BMutablePartition*
441 BMutablePartition::Parent() const
442 {
443 	return fParent;
444 }
445 
446 
447 // ChildAt
448 BMutablePartition*
449 BMutablePartition::ChildAt(int32 index) const
450 {
451 	return (BMutablePartition*)fChildren.ItemAt(index);
452 }
453 
454 
455 // CountChildren
456 int32
457 BMutablePartition::CountChildren() const
458 {
459 	return fChildren.CountItems();
460 }
461 
462 
463 // IndexOfChild
464 int32
465 BMutablePartition::IndexOfChild(BMutablePartition* child) const
466 {
467 	if (!child)
468 		return -1;
469 	return fChildren.IndexOf(child);
470 }
471 
472 
473 // SetChangeFlags
474 void
475 BMutablePartition::SetChangeFlags(uint32 flags)
476 {
477 	fChangeFlags = flags;
478 }
479 
480 
481 // ChangeFlags
482 uint32
483 BMutablePartition::ChangeFlags() const
484 {
485 	return fChangeFlags;
486 }
487 
488 
489 // Changed
490 void
491 BMutablePartition::Changed(uint32 flags, uint32 clearFlags)
492 {
493 	fChangeFlags &= ~clearFlags;
494 	fChangeFlags |= flags;
495 
496 	if (Parent())
497 		Parent()->Changed(B_PARTITION_CHANGED_DESCENDANTS);
498 }
499 
500 
501 // ChildCookie
502 void*
503 BMutablePartition::ChildCookie() const
504 {
505 	return fChildCookie;
506 }
507 
508 
509 // SetChildCookie
510 void
511 BMutablePartition::SetChildCookie(void* cookie)
512 {
513 	fChildCookie = cookie;
514 }
515 
516 
517 // constructor
518 BMutablePartition::BMutablePartition(BPartition::Delegate* delegate)
519 	: fDelegate(delegate),
520 	  fData(NULL),
521 	  fParent(NULL),
522 	  fChangeFlags(0),
523 	  fChildCookie(NULL)
524 {
525 }
526 
527 
528 // Init
529 status_t
530 BMutablePartition::Init(const user_partition_data* partitionData,
531 	BMutablePartition* parent)
532 {
533 	fParent = parent;
534 
535 	// add to the parent's child list
536 	if (fParent) {
537 		if (!fParent->fChildren.AddItem(this))
538 			return B_NO_MEMORY;
539 	}
540 
541 	// allocate data structure
542 	fData = new(nothrow) user_partition_data;
543 	if (!fData)
544 		return B_NO_MEMORY;
545 
546 	memset(fData, 0, sizeof(user_partition_data));
547 
548 	// copy the flat data
549 	fData->id = partitionData->id;
550 	fData->offset = partitionData->offset;
551 	fData->size = partitionData->size;
552 	fData->content_size = partitionData->content_size;
553 	fData->block_size = partitionData->block_size;
554 	fData->status = partitionData->status;
555 	fData->flags = partitionData->flags;
556 	fData->volume = partitionData->volume;
557 	fData->index = partitionData->index;
558 	fData->change_counter = partitionData->change_counter;
559 	fData->disk_system = partitionData->disk_system;
560 
561 	// copy the strings
562 	SET_STRING_RETURN_ON_ERROR(fData->name, partitionData->name);
563 	SET_STRING_RETURN_ON_ERROR(fData->content_name,
564 		partitionData->content_name);
565 	SET_STRING_RETURN_ON_ERROR(fData->type, partitionData->type);
566 	SET_STRING_RETURN_ON_ERROR(fData->content_type,
567 		partitionData->content_type);
568 	SET_STRING_RETURN_ON_ERROR(fData->parameters, partitionData->parameters);
569 	SET_STRING_RETURN_ON_ERROR(fData->content_parameters,
570 		partitionData->content_parameters);
571 
572 	return B_OK;
573 }
574 
575 
576 // destructor
577 BMutablePartition::~BMutablePartition()
578 {
579 	if (fData) {
580 		free(fData->name);
581 		free(fData->content_name);
582 		free(fData->type);
583 		free(fData->content_type);
584 		free(fData->parameters);
585 		free(fData->content_parameters);
586 		delete fData;
587 	}
588 }
589 
590 
591 // PartitionData
592 const user_partition_data*
593 BMutablePartition::PartitionData() const
594 {
595 	return fData;
596 }
597 
598 
599 // GetDelegate
600 BPartition::Delegate*
601 BMutablePartition::GetDelegate() const
602 {
603 	return fDelegate;
604 }
605 
606