xref: /haiku/src/add-ons/kernel/partitioning_systems/session/session.cpp (revision 24159a0c7d6d6dcba9f2a0c1a7c08d2c8167f21b)
1 //----------------------------------------------------------------------
2 //  This software is part of the Haiku distribution and is covered
3 //  by the MIT license.
4 //
5 //  Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net
6 //---------------------------------------------------------------------
7 /*!
8 	\file session.cpp
9 	\brief Disk device manager partition module for CD/DVD sessions.
10 */
11 
12 #include <ddm_modules.h>
13 #include <DiskDeviceTypes.h>
14 #include <KernelExport.h>
15 #include <unistd.h>
16 
17 #include "Debug.h"
18 #include "Disc.h"
19 
20 #define SESSION_PARTITION_MODULE_NAME "partitioning_systems/session/v1"
21 #define SESSION_PARTITION_NAME "Multisession Storage Device"
22 
23 static status_t standard_operations(int32 op, ...);
24 static float identify_partition(int fd, partition_data *partition,
25                                 void **cookie);
26 static status_t scan_partition(int fd, partition_data *partition,
27                                void *cookie);
28 static void free_identify_partition_cookie(partition_data *partition,
29                                            void *cookie);
30 static void free_partition_cookie(partition_data *partition);
31 static void free_partition_content_cookie(partition_data *partition);
32 
33 
34 static status_t
35 standard_operations(int32 op, ...)
36 {
37 	switch (op) {
38 		case B_MODULE_INIT:
39 		case B_MODULE_UNINIT:
40 			return B_OK;
41 	}
42 
43 	return B_ERROR;
44 }
45 
46 
47 static float
48 identify_partition(int fd, partition_data *partition, void **cookie)
49 {
50 	DEBUG_INIT_ETC(NULL, ("fd: %d, id: %ld, offset: %Ld, "
51 	       "size: %Ld, block_size: %ld, flags: 0x%lx", fd,
52 	       partition->id, partition->offset, partition->size,
53 	       partition->block_size, partition->flags));
54 	device_geometry geometry;
55 	float result = -1;
56 	if (partition->flags & B_PARTITION_IS_DEVICE
57 	    && partition->block_size == 2048
58 	    && ioctl(fd, B_GET_GEOMETRY, &geometry) == 0
59 	    && geometry.device_type == B_CD)
60 	{
61 		Disc *disc = new Disc(fd);
62 		if (disc && disc->InitCheck() == B_OK) {
63 			*cookie = static_cast<void*>(disc);
64 			result = 0.5;
65 		}
66 	}
67 	PRINT(("returning %ld\n", int32(result * 10000)));
68 	return result;
69 }
70 
71 
72 static status_t
73 scan_partition(int fd, partition_data *partition, void *cookie)
74 {
75 	DEBUG_INIT_ETC(NULL, ("fd: %d, id: %ld, offset: %Ld, size: %Ld, "
76 	               "block_size: %ld, cookie: %p", fd, partition->id, partition->offset,
77 	               partition->size, partition->block_size, cookie));
78 
79 	status_t error = fd >= 0 && partition && cookie ? B_OK : B_BAD_VALUE;
80 	if (!error) {
81 		Disc *disc = static_cast<Disc*>(cookie);
82 		partition->status = B_PARTITION_VALID;
83 		partition->flags |= B_PARTITION_PARTITIONING_SYSTEM
84 							| B_PARTITION_READ_ONLY;
85 		partition->content_size = partition->size;
86 		partition->content_cookie = disc;
87 
88 		Session *session = NULL;
89 		for (int i = 0; (session = disc->GetSession(i)); i++) {
90 			partition_data *child = create_child_partition(partition->id,
91 														   i, -1);
92 			if (!child) {
93 				PRINT(("Unable to create child at index %d.\n", i));
94 				// something went wrong
95 				error = B_ERROR;
96 				break;
97 			}
98 			child->offset = partition->offset + session->Offset();
99 			child->size = session->Size();
100 			child->block_size = session->BlockSize();
101 			child->flags |= session->Flags();
102 			child->type = strdup(session->Type());
103 			if (!child->type) {
104 				error = B_NO_MEMORY;
105 				break;
106 			}
107 			child->parameters = NULL;
108 			child->cookie = session;
109 		}
110 	}
111 	// cleanup on error
112 	if (error) {
113 		delete static_cast<Disc*>(cookie);
114 		partition->content_cookie = NULL;
115 		for (int32 i = 0; i < partition->child_count; i++) {
116 			if (partition_data *child = get_child_partition(partition->id, i)) {
117 				delete static_cast<Session *>(child->cookie);
118 				child->cookie = NULL;
119 			}
120 		}
121 	}
122 	PRINT(("error: 0x%lx, `%s'\n", error, strerror(error)));
123 	RETURN(error);
124 }
125 
126 
127 static void
128 free_identify_partition_cookie(partition_data */*partition*/, void *cookie)
129 {
130 	if (cookie) {
131 		DEBUG_INIT_ETC(NULL, ("cookie: %p", cookie));
132 		delete static_cast<Disc*>(cookie);
133 	}
134 }
135 
136 
137 static void
138 free_partition_cookie(partition_data *partition)
139 {
140 	if (partition && partition->cookie) {
141 		DEBUG_INIT_ETC(NULL, ("partition->cookie: %p", partition->cookie));
142 		delete static_cast<Session *>(partition->cookie);
143 		partition->cookie = NULL;
144 	}
145 }
146 
147 
148 static void
149 free_partition_content_cookie(partition_data *partition)
150 {
151 	if (partition && partition->content_cookie) {
152 		DEBUG_INIT_ETC(NULL, ("partition->content_cookie: %p", partition->content_cookie));
153 		delete static_cast<Disc*>(partition->content_cookie);
154 		partition->content_cookie = NULL;
155 	}
156 }
157 
158 
159 static partition_module_info sSessionModule = {
160 	{
161 		SESSION_PARTITION_MODULE_NAME,
162 		0,
163 		standard_operations
164 	},
165 	SESSION_PARTITION_NAME,				// pretty_name
166 	0,									// flags
167 
168 	// scanning
169 	identify_partition,					// identify_partition
170 	scan_partition,						// scan_partition
171 	free_identify_partition_cookie,		// free_identify_partition_cookie
172 	free_partition_cookie,				// free_partition_cookie
173 	free_partition_content_cookie,		// free_partition_content_cookie
174 
175 	// querying
176 	NULL,								// supports_repairing
177 	NULL,								// supports_resizing
178 	NULL,								// supports_resizing_child
179 	NULL,								// supports_moving
180 	NULL,								// supports_moving_child
181 	NULL,								// supports_setting_name
182 	NULL,								// supports_setting_content_name
183 	NULL,								// supports_setting_type
184 	NULL,								// supports_setting_parameters
185 	NULL,								// supports_setting_content_parameters
186 	NULL,								// supports_initializing
187 	NULL,								// supports_initializing_child
188 	NULL,								// supports_creating_child
189 	NULL,								// supports_deleting_child
190 	NULL,								// is_sub_system_for
191 
192 	NULL,								// validate_resize
193 	NULL,								// validate_resize_child
194 	NULL,								// validate_move
195 	NULL,								// validate_move_child
196 	NULL,								// validate_set_name
197 	NULL,								// validate_set_content_name
198 	NULL,								// validate_set_type
199 	NULL,								// validate_set_parameters
200 	NULL,								// validate_set_content_parameters
201 	NULL,								// validate_initialize
202 	NULL,								// validate_create_child
203 	NULL,								// get_partitionable_spaces
204 	NULL,								// get_next_supported_type
205 	NULL,								// get_type_for_content_type
206 
207 	// shadow partition modification
208 	NULL,								// shadow_changed
209 
210 	// writing
211 	NULL,								// repair
212 	NULL,								// resize
213 	NULL,								// resize_child
214 	NULL,								// move
215 	NULL,								// move_child
216 	NULL,								// set_name
217 	NULL,								// set_content_name
218 	NULL,								// set_type
219 	NULL,								// set_parameters
220 	NULL,								// set_content_parameters
221 	NULL,								// initialize
222 	NULL,								// create_child
223 	NULL,								// delete_child
224 };
225 
226 partition_module_info *modules[] = {
227 	&sSessionModule,
228 	NULL
229 };
230 
231