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