110919Slancea/* 210919Slancea * Copyright 2003 Tyler Akidau, haiku@akidau.net 310919Slancea * Distributed under the terms of the MIT License. 410919Slancea */ 510919Slancea 610919Slancea 710919Slancea/*! \file session.cpp 810919Slancea \brief Disk device manager partition module for CD/DVD sessions. 910919Slancea*/ 1010919Slancea 1110919Slancea 1210919Slancea#include <unistd.h> 1310919Slancea 1410919Slancea#include <disk_device_manager/ddm_modules.h> 1510919Slancea#include <disk_device_types.h> 1610919Slancea#include <DiskDeviceTypes.h> 1710919Slancea#include <KernelExport.h> 1810919Slancea 1910919Slancea#include "Debug.h" 2010919Slancea#include "Disc.h" 2110919Slancea 2210919Slancea 2310919Slancea#define SESSION_PARTITION_MODULE_NAME "partitioning_systems/session/v1" 2410919Slancea 2510919Slancea 2610919Slanceastatic status_t 2710919Slanceastandard_operations(int32 op, ...) 2810919Slancea{ 2910919Slancea switch (op) { 3010919Slancea case B_MODULE_INIT: 3110919Slancea case B_MODULE_UNINIT: 3210919Slancea return B_OK; 3310919Slancea } 3410919Slancea 3510919Slancea return B_ERROR; 3610919Slancea} 3710919Slancea 3810919Slancea 3910919Slanceastatic float 4010919Slanceaidentify_partition(int fd, partition_data *partition, void **cookie) 4110919Slancea{ 4210919Slancea DEBUG_INIT_ETC(NULL, ("fd: %d, id: %ld, offset: %Ld, " 4310919Slancea "size: %Ld, block_size: %ld, flags: 0x%lx", fd, 4410919Slancea partition->id, partition->offset, partition->size, 4510919Slancea partition->block_size, partition->flags)); 4610919Slancea 4710919Slancea device_geometry geometry; 4810919Slancea float result = -1; 4910919Slancea if ((partition->flags & B_PARTITION_IS_DEVICE) != 0 5010919Slancea && partition->block_size == 2048 5110919Slancea && ioctl(fd, B_GET_GEOMETRY, &geometry) == 0 5210919Slancea && geometry.device_type == B_CD) { 5310919Slancea Disc *disc = new(std::nothrow) Disc(fd); 5410919Slancea if (disc != NULL && disc->InitCheck() == B_OK) { 5510919Slancea // If we have only a single session then we can let the file system 5610919Slancea // drivers play directly with the device. 5710919Slancea Session *session = disc->GetSession(1); 5810919Slancea if (session != NULL) { 5910919Slancea result = 0.9f; 6010919Slancea delete session; 6110919Slancea } else 6210919Slancea result = 0.1f; 6310919Slancea 6410919Slancea *cookie = static_cast<void*>(disc); 6510919Slancea } else 6610919Slancea delete disc; 6710919Slancea } 6810919Slancea PRINT(("returning %g\n", result)); 6910919Slancea return result; 7010919Slancea} 7110919Slancea 7210919Slancea 7310919Slanceastatic status_t 7410919Slanceascan_partition(int fd, partition_data *partition, void *cookie) 7510919Slancea{ 7610919Slancea DEBUG_INIT_ETC(NULL, ("fd: %d, id: %ld, offset: %Ld, size: %Ld, " 7710919Slancea "block_size: %ld, cookie: %p", fd, partition->id, partition->offset, 7810919Slancea partition->size, partition->block_size, cookie)); 7910919Slancea 8010919Slancea Disc *disc = static_cast<Disc*>(cookie); 8110919Slancea partition->status = B_PARTITION_VALID; 8210919Slancea partition->flags |= B_PARTITION_PARTITIONING_SYSTEM 8310919Slancea | B_PARTITION_READ_ONLY; 8410919Slancea partition->content_size = partition->size; 8510919Slancea 8610919Slancea Session *session = NULL; 8710919Slancea status_t error = B_OK; 8810919Slancea for (int i = 0; (session = disc->GetSession(i)); i++) { 8910919Slancea partition_data *child = create_child_partition(partition->id, 9010919Slancea i, partition->offset + session->Offset(), session->Size(), -1); 9110919Slancea if (!child) { 9210919Slancea PRINT(("Unable to create child at index %d.\n", i)); 9310919Slancea // something went wrong 9410919Slancea error = B_ERROR; 9510919Slancea break; 9610919Slancea } 9710919Slancea child->block_size = session->BlockSize(); 9810919Slancea child->flags |= session->Flags(); 9910919Slancea child->type = strdup(session->Type()); 10010919Slancea delete session; 10110919Slancea if (!child->type) { 10210919Slancea error = B_NO_MEMORY; 10310919Slancea break; 10410919Slancea } 10510919Slancea child->parameters = NULL; 10610919Slancea } 10710919Slancea PRINT(("error: 0x%lx, `%s'\n", error, strerror(error))); 10810919Slancea RETURN(error); 10910919Slancea} 11010919Slancea 11110919Slancea 11210919Slanceastatic void 11310919Slanceafree_identify_partition_cookie(partition_data */*partition*/, void *cookie) 114{ 115 DEBUG_INIT_ETC(NULL, ("cookie: %p", cookie)); 116 delete static_cast<Disc*>(cookie); 117} 118 119 120static partition_module_info sSessionModule = { 121 { 122 SESSION_PARTITION_MODULE_NAME, 123 0, 124 standard_operations 125 }, 126 "session", // short_name 127 MULTISESSION_PARTITION_NAME, // pretty_name 128 0, // flags 129 130 // scanning 131 identify_partition, // identify_partition 132 scan_partition, // scan_partition 133 free_identify_partition_cookie, // free_identify_partition_cookie 134 NULL, // free_partition_cookie 135 NULL, // free_partition_content_cookie 136}; 137 138partition_module_info *modules[] = { 139 &sSessionModule, 140 NULL 141}; 142