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 } 57 } 58 PRINT(("returning %ld\n", int32(result * 10000))); 59 return result; 60 } 61 62 63 static status_t 64 scan_partition(int fd, partition_data *partition, void *cookie) 65 { 66 DEBUG_INIT_ETC(NULL, ("fd: %d, id: %ld, offset: %Ld, size: %Ld, " 67 "block_size: %ld, cookie: %p", fd, partition->id, partition->offset, 68 partition->size, partition->block_size, cookie)); 69 70 Disc *disc = static_cast<Disc*>(cookie); 71 partition->status = B_PARTITION_VALID; 72 partition->flags |= B_PARTITION_PARTITIONING_SYSTEM 73 | B_PARTITION_READ_ONLY; 74 partition->content_size = partition->size; 75 76 Session *session = NULL; 77 status_t error = B_OK; 78 for (int i = 0; (session = disc->GetSession(i)); i++) { 79 partition_data *child = create_child_partition(partition->id, 80 i, -1); 81 if (!child) { 82 PRINT(("Unable to create child at index %d.\n", i)); 83 // something went wrong 84 error = B_ERROR; 85 break; 86 } 87 child->offset = partition->offset + session->Offset(); 88 child->size = session->Size(); 89 child->block_size = session->BlockSize(); 90 child->flags |= session->Flags(); 91 child->type = strdup(session->Type()); 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_PARTITION_NAME, // pretty_name 118 0, // flags 119 120 // scanning 121 identify_partition, // identify_partition 122 scan_partition, // scan_partition 123 free_identify_partition_cookie, // free_identify_partition_cookie 124 NULL, // free_partition_cookie 125 NULL, // free_partition_content_cookie 126 }; 127 128 partition_module_info *modules[] = { 129 &sSessionModule, 130 NULL 131 }; 132 133