1 /* 2 * Copyright 2003 Tyler Akidau, haiku@akidau.net 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 /*! \file session.cpp 8 \brief Disk device manager partition module for CD/DVD sessions. 9 */ 10 11 12 #include <unistd.h> 13 14 #include <disk_device_manager/ddm_modules.h> 15 #include <disk_device_types.h> 16 #include <DiskDeviceTypes.h> 17 #include <KernelExport.h> 18 19 #include "Debug.h" 20 #include "Disc.h" 21 22 23 #define SESSION_PARTITION_MODULE_NAME "partitioning_systems/session/v1" 24 25 26 static status_t 27 standard_operations(int32 op, ...) 28 { 29 switch (op) { 30 case B_MODULE_INIT: 31 case B_MODULE_UNINIT: 32 return B_OK; 33 } 34 35 return B_ERROR; 36 } 37 38 39 static float 40 identify_partition(int fd, partition_data *partition, void **cookie) 41 { 42 DEBUG_INIT_ETC(NULL, ("fd: %d, id: %ld, offset: %Ld, " 43 "size: %Ld, block_size: %ld, flags: 0x%lx", fd, 44 partition->id, partition->offset, partition->size, 45 partition->block_size, partition->flags)); 46 47 device_geometry geometry; 48 float result = -1; 49 if ((partition->flags & B_PARTITION_IS_DEVICE) != 0 50 && partition->block_size == 2048 51 && ioctl(fd, B_GET_GEOMETRY, &geometry) == 0 52 && geometry.device_type == B_CD) { 53 Disc *disc = new(std::nothrow) Disc(fd); 54 if (disc != NULL && disc->InitCheck() == B_OK) { 55 *cookie = static_cast<void*>(disc); 56 result = 0.7; 57 } else 58 delete disc; 59 } 60 PRINT(("returning %ld\n", int32(result * 10000))); 61 return result; 62 } 63 64 65 static status_t 66 scan_partition(int fd, partition_data *partition, void *cookie) 67 { 68 DEBUG_INIT_ETC(NULL, ("fd: %d, id: %ld, offset: %Ld, size: %Ld, " 69 "block_size: %ld, cookie: %p", fd, partition->id, partition->offset, 70 partition->size, partition->block_size, cookie)); 71 72 Disc *disc = static_cast<Disc*>(cookie); 73 partition->status = B_PARTITION_VALID; 74 partition->flags |= B_PARTITION_PARTITIONING_SYSTEM 75 | B_PARTITION_READ_ONLY; 76 partition->content_size = partition->size; 77 78 Session *session = NULL; 79 status_t error = B_OK; 80 for (int i = 0; (session = disc->GetSession(i)); i++) { 81 partition_data *child = create_child_partition(partition->id, 82 i, partition->offset + session->Offset(), session->Size(), -1); 83 if (!child) { 84 PRINT(("Unable to create child at index %d.\n", i)); 85 // something went wrong 86 error = B_ERROR; 87 break; 88 } 89 child->block_size = session->BlockSize(); 90 child->flags |= session->Flags(); 91 child->type = strdup(session->Type()); 92 delete session; 93 if (!child->type) { 94 error = B_NO_MEMORY; 95 break; 96 } 97 child->parameters = NULL; 98 } 99 PRINT(("error: 0x%lx, `%s'\n", error, strerror(error))); 100 RETURN(error); 101 } 102 103 104 static void 105 free_identify_partition_cookie(partition_data */*partition*/, void *cookie) 106 { 107 DEBUG_INIT_ETC(NULL, ("cookie: %p", cookie)); 108 delete static_cast<Disc*>(cookie); 109 } 110 111 112 static partition_module_info sSessionModule = { 113 { 114 SESSION_PARTITION_MODULE_NAME, 115 0, 116 standard_operations 117 }, 118 "session", // short_name 119 MULTISESSION_PARTITION_NAME, // pretty_name 120 0, // flags 121 122 // scanning 123 identify_partition, // identify_partition 124 scan_partition, // scan_partition 125 free_identify_partition_cookie, // free_identify_partition_cookie 126 NULL, // free_partition_cookie 127 NULL, // free_partition_content_cookie 128 }; 129 130 partition_module_info *modules[] = { 131 &sSessionModule, 132 NULL 133 }; 134