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