diff --git a/headers/os/kernel/disk_scanner.h b/headers/os/kernel/disk_scanner.h deleted file mode 100644 index cf68432099..0000000000 --- a/headers/os/kernel/disk_scanner.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Disk device iteration and information -** -** Distributed under the terms of the OpenBeOS License. -*/ -#ifndef _FS_DEVICE_H -#define _FS_DEVICE_H - - -#include -#include -#include - - -// session flags -enum { - B_DATA_SESSION = 0x01, /* data session */ - B_VIRTUAL_SESSION = 0x02, /* e.g. hard disk */ -}; - -typedef struct session_info { - off_t offset; /* offset from start of device (in bytes) */ - off_t size; /* size (in bytes) */ - int32 logical_block_size; /* logical block size (in bytes) */ - int32 index; /* session index */ - uint32 flags; /* session flags */ -} session_info; - -// partition flags -enum { - B_HIDDEN_PARTITION = 0x01, /* non-file system partition */ - B_VIRTUAL_PARTITION = 0x02, /* e.g. floppy */ - B_EMPTY_PARTITION = 0x04, /* empty partition, implies - B_HIDDEN_PARTITION */ -}; - -typedef struct extended_partition_info { - partition_info info; - uint32 flags; /* partition flags */ - char partition_name[B_FILE_NAME_LENGTH]; - char partition_type[B_FILE_NAME_LENGTH]; - char file_system_short_name[B_FILE_NAME_LENGTH]; /* "", if hidden */ - char file_system_long_name[B_FILE_NAME_LENGTH]; /* or unknown FS */ - char volume_name[B_FILE_NAME_LENGTH]; /* "", if hidden */ - uint32 file_system_flags; /* same as fs_info::flags */ -} extended_partition_info; - - -#ifdef __cplusplus -extern "C" { -#endif - -// getting infos -status_t get_nth_session_info(int deviceFD, int32 index, - session_info *sessionInfo); -status_t get_nth_partition_info(int deviceFD, int32 sessionIndex, - int32 partitionIndex, - extended_partition_info *partitionInfo, - char *partitionMapName); - -// partitioning -status_t get_partitioning_parameters(int deviceFD, int32 sessionIndex, - const char *identifier, char *buffer, - size_t bufferSize, size_t *actualSize); -status_t partition_session(int deviceFD, int32 sessionIndex, - const char *identifier, const char *parameters); - -// initialization -status_t get_fs_initialization_parameters(int deviceFD, int32 sessionIndex, - int32 partitionIndex, - const char *fileSystem, char *buffer, - size_t bufferSize, - size_t *actualSize); -// TODO: Move to . It fits better there. -status_t initialize_volume(const char *where, const char *fileSystem, - const char *volumeName, const char *parameters); - -#ifdef __cplusplus -} -#endif - -#endif /* _FS_DEVICE_H */ diff --git a/src/add-ons/kernel/disk_scanner/Jamfile b/src/add-ons/kernel/disk_scanner/Jamfile deleted file mode 100644 index c19831fe95..0000000000 --- a/src/add-ons/kernel/disk_scanner/Jamfile +++ /dev/null @@ -1,11 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel disk_scanner ; - -UsePrivateHeaders $(DOT) ; - -KernelAddon disk_scanner : - disk_scanner.c -; - -#SubInclude HAIKU_TOP src add-ons kernel disk_scanner fs ; -SubInclude HAIKU_TOP src add-ons kernel disk_scanner partition ; -SubInclude HAIKU_TOP src add-ons kernel disk_scanner session ; diff --git a/src/add-ons/kernel/disk_scanner/disk_scanner.c b/src/add-ons/kernel/disk_scanner/disk_scanner.c deleted file mode 100644 index afc768aa79..0000000000 --- a/src/add-ons/kernel/disk_scanner/disk_scanner.c +++ /dev/null @@ -1,665 +0,0 @@ -//---------------------------------------------------------------------- -// This software is part of the OpenBeOS distribution and is covered -// by the OpenBeOS license. -//--------------------------------------------------------------------- -/*! - \file disk_scanner.c - disk_scanner kernel module -*/ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -static const char *kSessionModulePrefix = "disk_scanner/session"; -static const char *kPartitionModulePrefix = "disk_scanner/partition"; -static const char *kFSModulePrefix = "disk_scanner/fs"; - -#define TRACE(x) ; -//#define TRACE(x) dprintf x - -// fs_block -typedef struct fs_block { - off_t offset; - void *data; - struct fs_block *previous; - struct fs_block *next; -} fs_block; - -// fs_buffer_cache -typedef struct fs_buffer_cache { - int fd; - off_t offset; - off_t size; - size_t block_size; - struct fs_block *first_block; - struct fs_block *last_block; -} fs_buffer_cache; - -// prototypes -static status_t read_block(int fd, off_t offset, size_t size, uchar **block); -static status_t get_partition_module_block(int deviceFD, - const session_info *sessionOffset, const uchar *block, - partition_module_info **partitionModule); -static status_t init_fs_buffer_cache(struct fs_buffer_cache *cache, int fd, - off_t offset, off_t size, size_t blockSize); -static status_t cleanup_fs_buffer_cache(struct fs_buffer_cache *cache); -static status_t get_buffer(struct fs_buffer_cache *cache, off_t offset, - size_t size, void **_buffer, size_t *actualSize); - - -// std_ops -static -status_t -std_ops(int32 op, ...) -{ - TRACE(("disk_scanner: std_ops(0x%lx)\n", op)); - switch(op) { - case B_MODULE_INIT: - case B_MODULE_UNINIT: - return B_OK; - } - return B_ERROR; -} - -// get_session_module -static -status_t -disk_scanner_get_session_module(int deviceFD, off_t deviceSize, int32 blockSize, - session_module_info **sessionModule) -{ - // Iterate through the list of session modules and return the first one - // that thinks, it is the right one. - status_t error = (sessionModule ? B_OK : B_BAD_VALUE); - void *list = NULL; - TRACE(("disk_scanner: get_session_module(%d, %lld, %ld)\n", deviceFD, - deviceSize, blockSize)); - if (error == B_OK) - *sessionModule = NULL; - if (error == B_OK && ((list = open_module_list(kSessionModulePrefix)))) { - char moduleName[B_PATH_NAME_LENGTH]; - size_t bufferSize = sizeof(moduleName); - for (; read_next_module_name(list, moduleName, &bufferSize) == B_OK; - bufferSize = sizeof(moduleName)) { - session_module_info *module = NULL; - if (get_module(moduleName, (module_info**)&module) == B_OK) { - if (module->identify(deviceFD, deviceSize, blockSize)) { - // found module - *sessionModule = module; - break; - } - put_module(moduleName); - } - } - close_module_list(list); - } - // set result - if (error == B_OK && !*sessionModule) - error = B_ENTRY_NOT_FOUND; - return error; -} - -// read_block -static -status_t -read_block(int fd, off_t offset, size_t size, uchar **block) -{ - status_t error = (block && size > 0 ? B_OK : B_BAD_VALUE); - if (error == B_OK) { - *block = malloc(size); - if (*block) { - if (read_pos(fd, offset, *block, size) != (ssize_t)size) { - error = errno; - if (error == B_OK) - error = B_IO_ERROR; - free(*block); - *block = NULL; - } - } else - error = B_NO_MEMORY; - } - return error; -} - -// get_partition_module_block -static -status_t -get_partition_module_block(int deviceFD, const session_info *sessionInfo, - const uchar *block, - partition_module_info **partitionModule) -{ - // Iterate through the list of partition modules and return the first one - // that thinks, it is the right one. - status_t error = (partitionModule && block ? B_OK : B_BAD_VALUE); - void *list = NULL; - if (error == B_OK) - *partitionModule = NULL; - if (error == B_OK && ((list = open_module_list(kPartitionModulePrefix)))) { - char moduleName[B_PATH_NAME_LENGTH]; - size_t bufferSize = sizeof(moduleName); - for (; read_next_module_name(list, moduleName, &bufferSize) == B_OK; - bufferSize = sizeof(moduleName)) { - partition_module_info *module = NULL; - TRACE(("disk_scanner: trying partition module: `%s'\n", moduleName)); - if (get_module(moduleName, (module_info**)&module) == B_OK) { - if (module->identify(deviceFD, sessionInfo, block)) { - // found module - *partitionModule = module; - break; - } - put_module(moduleName); - } - } - close_module_list(list); - } - // set result - if (error == B_OK && !*partitionModule) - error = B_ENTRY_NOT_FOUND; - return error; -} - -// get_partition_module_for_identifier -static -status_t -get_partition_module_for_identifier(const char *identifier, - partition_module_info **partitionModule) -{ - // find the partition module that knows the supplied identifier - status_t error = (identifier ? B_OK : B_BAD_VALUE); - void *list = NULL; - if (error == B_OK) - *partitionModule = NULL; - if (error == B_OK && ((list = open_module_list(kPartitionModulePrefix)))) { - char moduleName[B_PATH_NAME_LENGTH]; - size_t bufferSize = sizeof(moduleName); - for (; read_next_module_name(list, moduleName, &bufferSize) == B_OK; - bufferSize = sizeof(moduleName)) { - partition_module_info *module = NULL; - if (get_module(moduleName, (module_info**)&module) == B_OK) { - if (!strcmp(module->short_name, identifier)) { - // found module - *partitionModule = module; - break; - } - put_module(moduleName); - } - } - close_module_list(list); - } - if (error == B_OK && !*partitionModule) - error = B_ENTRY_NOT_FOUND; - return error; -} - - -// get_partition_module -static -status_t -disk_scanner_get_partition_module(int deviceFD, - const session_info *sessionInfo, - partition_module_info **partitionModule) -{ - status_t error = (partitionModule && sessionInfo ? B_OK : B_BAD_VALUE); - TRACE(("disk_scanner: get_partition_module(%d, %lld, %lld, %ld)\n", - deviceFD, sessionInfo->offset, sessionInfo->size, - sessionInfo->logical_block_size)); - if (error == B_OK) { - off_t sessionOffset = sessionInfo->offset; - int32 blockSize = sessionInfo->logical_block_size; - // read the first block of the session and let the helper function - // do the job - uchar *block = NULL; - error = read_block(deviceFD, sessionOffset, blockSize, &block); - if (error == B_OK) { - error = get_partition_module_block(deviceFD, sessionInfo, - block, partitionModule); - free(block); - } - } - return error; -} - -// get_nth_session_info -static -status_t -disk_scanner_get_nth_session_info(int deviceFD, int32 index, - session_info *sessionInfo, - session_module_info **_sessionModule) -{ - status_t error = B_OK; - session_module_info *sessionModule - = (_sessionModule ? *_sessionModule : NULL); - int32 blockSize = 0; - off_t deviceSize = 0; - device_geometry geometry; - // get the media status - if (ioctl(deviceFD, B_GET_MEDIA_STATUS, &error) != 0) - error = errno; - // get the device geometry - TRACE(("disk_scanner: get_nth_session_info(%d, %ld)\n", deviceFD, index)); - if (error == B_OK) { - if (ioctl(deviceFD, B_GET_GEOMETRY, &geometry) == 0) { - blockSize = geometry.bytes_per_sector; - deviceSize = (off_t)blockSize * geometry.sectors_per_track - * geometry.cylinder_count * geometry.head_count; - } else - error = errno; - } - // get a session module, if the device is a CD, otherwise return a - // virtual session - if (error == B_OK) { - // get the session module - if (!sessionModule) { - error = disk_scanner_get_session_module(deviceFD, deviceSize, - blockSize, - &sessionModule); - if (error == B_OK) { - error = sessionModule->get_nth_info(deviceFD, index, - deviceSize, blockSize, - sessionInfo); - } else if (error == B_ENTRY_NOT_FOUND) { - // no session add-on found -- return a virtual session for - // index 0 - error = B_OK; - if (index == 0) { - sessionInfo->offset = 0; - sessionInfo->size = deviceSize; - sessionInfo->logical_block_size = blockSize; - sessionInfo->index = 0; - sessionInfo->flags = B_VIRTUAL_SESSION | B_DATA_SESSION; - } else - error = B_ENTRY_NOT_FOUND; - } - } - } - // cleanup / set results - if (_sessionModule) - *_sessionModule = sessionModule; - else if (sessionModule) - put_module(sessionModule->module.name); - TRACE(("disk_scanner: get_nth_session_info() done: %s\n", - strerror(error))); - return error; -} - -// get_nth_partition_info -static -status_t -disk_scanner_get_nth_partition_info(int deviceFD, - const session_info *sessionInfo, - int32 partitionIndex, - extended_partition_info *partitionInfo, - char *partitionMapName, - partition_module_info **_partitionModule) -{ - partition_module_info *partitionModule - = (_partitionModule ? *_partitionModule : NULL); - status_t error = (partitionInfo ? B_OK : B_BAD_VALUE); - TRACE(("disk_scanner: get_nth_partition_info(%d, %lld, %lld, %ld, %ld, %ld)\n", - deviceFD, sessionInfo->offset, sessionInfo->size, - partitionInfo->info.logical_block_size, partitionInfo->info.session, - partitionInfo->info.partition)); - if (error == B_OK) { - off_t sessionOffset = sessionInfo->offset; - off_t sessionSize = sessionInfo->size; - int32 blockSize = sessionInfo->logical_block_size; - uchar *block = NULL; - // fill in the fields we do already know - partitionInfo->info.logical_block_size = blockSize; - partitionInfo->info.session = sessionInfo->index; - partitionInfo->info.partition = partitionIndex; - // Read the first block of the session and get the partition module. - if (!(sessionInfo->flags & B_DATA_SESSION)) { - // Don't that, if the session is an audio session. - // Fall through and return a virtual partition, if partition 0 - // is requested. - if (partitionInfo->info.partition != 0) - error = B_ENTRY_NOT_FOUND; - } else if (!partitionModule) { - error = read_block(deviceFD, sessionOffset, blockSize, &block); -TRACE((" check: %s\n", strerror(error))); - if (error == B_OK) { - error = get_partition_module_block(deviceFD, sessionInfo, - block, &partitionModule); -TRACE((" check: %s\n", strerror(error))); - if (error == B_ENTRY_NOT_FOUND - && partitionInfo->info.partition == 0) { - // No matching partition module found, and first partition - // requested: Just set the error to B_OK: below a virtual - // partition info will be returned. - error = B_OK; - } - } - } - // get the info - if (error == B_OK) { - if (partitionModule) { - error = partitionModule->get_nth_info(deviceFD, sessionInfo, - block, partitionIndex, partitionInfo); - } else { - // no partition module: return a virtual partition info - partitionInfo->info.offset = sessionOffset; - partitionInfo->info.size = sessionSize; - partitionInfo->flags = B_VIRTUAL_PARTITION; - partitionInfo->partition_name[0] = '\0'; - partitionInfo->partition_type[0] = '\0'; - } - } -TRACE((" check: %s\n", strerror(error))); - // set results / cleanup - if (error == B_OK && partitionMapName) { - // return partition module identifier - if (partitionModule) - strcpy(partitionMapName, partitionModule->short_name); - else - partitionMapName[0] = '\0'; - } - if (_partitionModule) - *_partitionModule = partitionModule; - else if (partitionModule) - put_module(partitionModule->module.name); - if (block) - free(block); - } - return error; -} - -// get_partition_fs_info -static -status_t -disk_scanner_get_partition_fs_info(int deviceFD, - extended_partition_info *partitionInfo) -{ - status_t error = (partitionInfo ? B_OK : B_BAD_VALUE); - void *list = NULL; - fs_buffer_cache cache; - bool cacheInitialized = false; - TRACE(("disk_scanner: get_partition_fs_info(%d, %lld, %lld, %ld)\n", deviceFD, - partitionInfo->info.offset, partitionInfo->info.size, - partitionInfo->info.logical_block_size)); - // init the cache - if (error == B_OK) { - error = init_fs_buffer_cache(&cache, deviceFD, - partitionInfo->info.offset, partitionInfo->info.size, - partitionInfo->info.logical_block_size); - cacheInitialized = (error == B_OK); - } - // Iterate through the list of FS modules and return the result of the - // one with the highest priority that thinks, it is the right one. - if (error == B_OK && ((list = open_module_list(kFSModulePrefix)))) { - extended_partition_info bestInfo; - float bestPriority = -2; - char moduleName[B_PATH_NAME_LENGTH]; - size_t bufferSize = sizeof(moduleName); - error = B_ENTRY_NOT_FOUND; - for (; read_next_module_name(list, moduleName, &bufferSize) == B_OK; - bufferSize = sizeof(moduleName)) { - fs_module_info *module = NULL; - TRACE(("disk_scanner: trying fs module: `%s'\n", moduleName)); - // get the module - if (get_module(moduleName, (module_info**)&module) == B_OK) { - // get the info - extended_partition_info info = *partitionInfo; - float priority = 0; - if (module->identify(deviceFD, &info, &priority, get_buffer, - &cache)) { - // copy the info, if it is the first or the has a higher - // priority than the one found before - if (error == B_ENTRY_NOT_FOUND - || priority > bestPriority) { - bestInfo = info; - bestPriority = priority; - } - error = B_OK; - } - put_module(moduleName); - } - // set the return value - if (error == B_OK) - *partitionInfo = bestInfo; - } - close_module_list(list); - } - // cleanup the cache - if (cacheInitialized) - cleanup_fs_buffer_cache(&cache); - return error; -} - -// get_partitioning_params -static -status_t -disk_scanner_get_partitioning_params(int deviceFD, - const struct session_info *sessionInfo, - const char *identifier, char *buffer, - size_t bufferSize, size_t *actualSize) -{ - // find the partition module that knows the supplied identifier - status_t error = (sessionInfo && identifier && buffer && actualSize - ? B_OK : B_BAD_VALUE); - partition_module_info *partitionModule = NULL; - if (error == B_OK) - get_partition_module_for_identifier(identifier, &partitionModule); - // get the parameters from the module - if (error == B_OK) { - error = partitionModule->get_partitioning_params(deviceFD, sessionInfo, - buffer, bufferSize, actualSize); - } - // cleanup - if (partitionModule) - put_module(partitionModule->module.name); - return error; -} - -// partition -static -status_t -disk_scanner_partition(int deviceFD, const struct session_info *sessionInfo, - const char *identifier, const char *parameters) -{ - // find the partition module that knows the supplied identifier - status_t error = (sessionInfo && identifier ? B_OK : B_BAD_VALUE); - partition_module_info *partitionModule = NULL; - if (error == B_OK) - get_partition_module_for_identifier(identifier, &partitionModule); - // let the module do the actual partitioning - if (error == B_OK) - error = partitionModule->partition(deviceFD, sessionInfo, parameters); - // cleanup - if (partitionModule) - put_module(partitionModule->module.name); - return error; -} - - -// new_fs_block -static -status_t -new_fs_block(int fd, off_t offset, size_t size, fs_block **_block) -{ - status_t error = (_block ? B_OK : B_BAD_VALUE); - fs_block *block = NULL; - // alloc the block - if (error == B_OK) { - block = (fs_block*)malloc(sizeof(fs_block)); - if (!block) - error = B_NO_MEMORY; - } - // read the block - if (error == B_OK) - error = read_block(fd, offset, size, (uchar**)&block->data); - // set the fields / cleanup on error - if (error == B_OK) { - block->offset = offset; - block->previous = NULL; - block->next = NULL; - *_block = block; - } else { - if (block) - free(block); - } - return error; -} - -// delete_fs_block -static -void -delete_fs_block(fs_block *block) -{ - if (block) { - if (block->data) - free(block->data); - free(block); - } -} - -// init_fs_buffer_cache -static -status_t -init_fs_buffer_cache(struct fs_buffer_cache *cache, int fd, off_t offset, - off_t size, size_t blockSize) -{ - cache->fd = fd; - cache->offset = offset; - cache->size = size; - cache->block_size = blockSize; - cache->first_block = NULL; - cache->last_block = NULL; - return B_OK; -} - -// cleanup_fs_buffer_cache -static -status_t -cleanup_fs_buffer_cache(struct fs_buffer_cache *cache) -{ - if (cache) { - while (cache->first_block) { - fs_block *block = cache->first_block; - cache->first_block = block->next; - delete_fs_block(block); - } - } - return B_OK; -} - -// get_buffer -static -status_t -get_buffer(struct fs_buffer_cache *cache, off_t offset, size_t size, - void **_buffer, size_t *actualSize) -{ - status_t error = (cache && _buffer && actualSize - && offset >= 0 && size > 0 - ? B_OK : B_BAD_VALUE); - uint8 *buffer = NULL; - // check the bounds - if (error == B_OK) { - offset += cache->offset; // make relative to beginning of device - if (offset >= cache->offset + cache->size) - size = 0; - else if (offset + size > cache->offset + cache->size) - size = cache->offset + cache->size - offset; - } - // allocate the buffer - if (error == B_OK && size > 0) { - buffer = (uint8*)malloc(size); - if (buffer) { - // iterate through the list of cached blocks - off_t blockOffset = offset - offset % cache->block_size; - size_t remainingBytes = size; - fs_block *block = NULL; - for (block = cache->first_block; - remainingBytes > 0; - block = block->next) { - if (!block || block->offset >= blockOffset) { - if (!block || block->offset > blockOffset) { - // the block is not in cache, read it - fs_block *newBlock = NULL; - error = new_fs_block(cache->fd, blockOffset, - cache->block_size, &newBlock); - if (error == B_OK) { - // insert the new block - if (block) - newBlock->previous = block->previous; - else - newBlock->previous = cache->last_block; - newBlock->next = block; - if (newBlock->previous) - newBlock->previous->next = newBlock; - else - cache->first_block = newBlock; - if (newBlock->next) - newBlock->next->previous = newBlock; - else - cache->last_block = newBlock; - block = newBlock; - } - } - if (error == B_OK) { - // block is (now) in cache, copy the data - off_t inBlockOffset = 0; - size_t toCopy = cache->block_size; - if (blockOffset < offset) { - inBlockOffset = offset - blockOffset; - toCopy -= inBlockOffset; - } - if (toCopy > remainingBytes) - toCopy = remainingBytes; - memcpy(buffer + blockOffset + inBlockOffset - offset, - (uint8*)block->data + inBlockOffset, toCopy); - blockOffset += cache->block_size; - remainingBytes -= toCopy; - } - } - // bail out on failure - if (error != B_OK) - break; - } - } else - error = B_NO_MEMORY; - } - // set results / cleanup on error - if (error == B_OK) { - *_buffer = buffer; - *actualSize = size; - } else { - if (buffer) - free(buffer); - } - return error; -} - - -static disk_scanner_module_info disk_scanner_module = -{ - // module_info - { - DISK_SCANNER_MODULE_NAME, - 0, // better B_KEEP_LOADED? - std_ops - }, - disk_scanner_get_session_module, - disk_scanner_get_partition_module, - disk_scanner_get_nth_session_info, - disk_scanner_get_nth_partition_info, - disk_scanner_get_partition_fs_info, - disk_scanner_get_partitioning_params, - disk_scanner_partition -}; - -_EXPORT disk_scanner_module_info *modules[] = -{ - &disk_scanner_module, - NULL -}; - - diff --git a/src/add-ons/kernel/disk_scanner/fs/Jamfile b/src/add-ons/kernel/disk_scanner/fs/Jamfile deleted file mode 100644 index 877cd99f46..0000000000 --- a/src/add-ons/kernel/disk_scanner/fs/Jamfile +++ /dev/null @@ -1,25 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel disk_scanner fs ; - -UsePrivateHeaders $(DOT) ; -UsePrivateHeaders [ FDirName kernel disk_device_manager ] ; -UsePrivateHeaders [ FDirName storage ] ; - -# For now build a userland version only. -Addon bfs : - bfs.c -; - -LinkAgainst bfs : - libkernelland_emu.so - libdisk_device_manager.so -; - - -#KernelAddon bfs : kernel disk_scanner fs : -# bfs.c -#; - -#KernelAddon iso9660 : kernel disk_scanner fs : -# iso9660.cpp -#; - diff --git a/src/add-ons/kernel/disk_scanner/fs/bfs.c b/src/add-ons/kernel/disk_scanner/fs/bfs.c deleted file mode 100644 index ea41de5487..0000000000 --- a/src/add-ons/kernel/disk_scanner/fs/bfs.c +++ /dev/null @@ -1,435 +0,0 @@ -//---------------------------------------------------------------------- -// This software is part of the OpenBeOS distribution and is covered -// by the OpenBeOS license. -//--------------------------------------------------------------------- -/*! - \file bfs.c - disk_scanner filesystem module for BFS filesystems -*/ - -#include -#include -#include -#include - -#include -#include -#include - -// B_PLAIN_C_ERROR: -//static const char *kBFSModuleName = "file_systems/bfs/v1"; -#define kBFSModuleName "file_systems/bfs/v1" - -const char *kModuleDebugName = "fs/bfs"; - -#define TRACE(x) ; -//#define TRACE(x) dprintf x - -// prototypes -//static bool bfs_fs_identify(int deviceFD, -// struct extended_partition_info *partitionInfo, float *priority, -// fs_get_buffer get_buffer, struct fs_buffer_cache *cache); - -//---------------------------------------------------------------------- -// Stolen from src/add-ons/kernel/file_systems/bfs/bfs.h -//---------------------------------------------------------------------- - -typedef struct block_run -{ - int32 allocation_group; - uint16 start; - uint16 length; -} block_run; - -typedef block_run inode_addr; - -#define BFS_DISK_NAME_LENGTH 32 - -typedef struct disk_super_block -{ - char name[BFS_DISK_NAME_LENGTH]; - int32 magic1; - int32 fs_byte_order; - uint32 block_size; - uint32 block_shift; - off_t num_blocks; - off_t used_blocks; - int32 inode_size; - int32 magic2; - int32 blocks_per_ag; - int32 ag_shift; - int32 num_ags; - int32 flags; - block_run log_blocks; - off_t log_start; - off_t log_end; - int32 magic3; - inode_addr root_dir; - inode_addr indices; - int32 pad[8]; -} disk_super_block; - -#define SUPER_BLOCK_FS_LENDIAN 'BIGE' /* BIGE */ - -#define SUPER_BLOCK_MAGIC1 'BFS1' /* BFS1 */ -#define SUPER_BLOCK_MAGIC2 0xdd121031 -#define SUPER_BLOCK_MAGIC3 0x15b6830e - -#define SUPER_BLOCK_DISK_CLEAN 'CLEN' /* CLEN */ -#define SUPER_BLOCK_DISK_DIRTY 'DIRT' /* DIRT */ - -static -char * -get_tupel(uint32 id) -{ - static unsigned char tupel[5]; - int16 i; - - tupel[0] = 0xff & (id >> 24); - tupel[1] = 0xff & (id >> 16); - tupel[2] = 0xff & (id >> 8); - tupel[3] = 0xff & (id); - tupel[4] = 0; - for (i = 0;i < 4;i++) - if (tupel[i] < ' ' || tupel[i] > 128) - tupel[i] = '.'; - - return (char *)tupel; -} - -static -void -dump_super_block(disk_super_block *superBlock) -{ - dprintf("disk_super_block:\n"); - dprintf(" name = %s\n",superBlock->name); - dprintf(" magic1 = %#08lx (%s) %s\n",superBlock->magic1, get_tupel(superBlock->magic1), (superBlock->magic1 == SUPER_BLOCK_MAGIC1 ? "valid" : "INVALID")); - dprintf(" fs_byte_order = %#08lx (%s)\n",superBlock->fs_byte_order, get_tupel(superBlock->fs_byte_order)); - dprintf(" block_size = %lu\n",superBlock->block_size); - dprintf(" block_shift = %lu\n",superBlock->block_shift); - dprintf(" num_blocks = %Lu\n",superBlock->num_blocks); - dprintf(" used_blocks = %Lu\n",superBlock->used_blocks); - dprintf(" inode_size = %lu\n",superBlock->inode_size); - dprintf(" magic2 = %#08lx (%s) %s\n",superBlock->magic2, get_tupel(superBlock->magic2), (superBlock->magic2 == (int)SUPER_BLOCK_MAGIC2 ? "valid" : "INVALID")); - dprintf(" blocks_per_ag = %lu\n",superBlock->blocks_per_ag); - dprintf(" ag_shift = %lu (%lld bytes)\n",superBlock->ag_shift, 1LL << superBlock->ag_shift); - dprintf(" num_ags = %lu\n",superBlock->num_ags); - dprintf(" flags = %#08lx (%s)\n",superBlock->flags, get_tupel(superBlock->flags)); -// dump_block_run(" log_blocks = ",superBlock->log_blocks); - dprintf(" log_start = %Lu\n",superBlock->log_start); - dprintf(" log_end = %Lu\n",superBlock->log_end); - dprintf(" magic3 = %#08lx (%s) %s\n",superBlock->magic3, get_tupel(superBlock->magic3), (superBlock->magic3 == SUPER_BLOCK_MAGIC3 ? "valid" : "INVALID")); -// dump_block_run(" root_dir = ",superBlock->root_dir); -// dump_block_run(" indices = ",superBlock->indices); -} - -static -inline int64 -divide_roundup(int64 num,int32 divisor) -{ - return (num + divisor - 1) / divisor; -} -//---------------------------------------------------------------------- -// End stolen BFS code -//---------------------------------------------------------------------- - -#if 0 - -// std_ops -static -status_t -std_ops(int32 op, ...) -{ - TRACE(("%s: std_ops(0x%lx)\n", kModuleDebugName, op)); - switch(op) { - case B_MODULE_INIT: - case B_MODULE_UNINIT: - return B_OK; - } - return B_ERROR; -} - -// read_block -static -status_t -read_block(fs_get_buffer get_buffer, struct fs_buffer_cache *cache, - off_t offset, size_t size, uchar **block) -{ - size_t actualSize = 0; - status_t error = get_buffer(cache, offset, size, (void**)block, - &actualSize); - if (error == B_OK && actualSize != size) { - error = B_ERROR; - free(*block); - } - return error; -} - -// bfs_fs_identify -/*! \brief Returns true if the given partition is a valid BFS partition. - - See fs_identify_hook() for more information. - - \todo Fill in partitionInfo->mounted_at with something useful. -*/ -static -bool -bfs_fs_identify(int deviceFD, struct extended_partition_info *partitionInfo, - float *priority, fs_get_buffer get_buffer, - struct fs_buffer_cache *cache) -{ - bool result = false; - TRACE(("%s: identify(%d, %p, offset: %lld)\n", kModuleDebugName, deviceFD, - partitionInfo, partitionInfo ? partitionInfo->info.offset : -1)); - - if (partitionInfo) { - uchar *buffer = NULL; - disk_super_block *superBlock = NULL; - status_t error = read_block(get_buffer, cache, 0, 1024, &buffer); - if (!error && buffer) { - superBlock = (disk_super_block*)(buffer+512); -// dump_super_block(superBlock); - - if (superBlock->magic1 != (int32)SUPER_BLOCK_MAGIC1 - || superBlock->magic2 != (int32)SUPER_BLOCK_MAGIC2 - || superBlock->magic3 != (int32)SUPER_BLOCK_MAGIC3 - || (int32)superBlock->block_size != superBlock->inode_size - || superBlock->fs_byte_order != SUPER_BLOCK_FS_LENDIAN - || (1UL << superBlock->block_shift) != superBlock->block_size - || superBlock->num_ags < 1 - || superBlock->ag_shift < 1 - || superBlock->blocks_per_ag < 1 - || superBlock->num_blocks < 10 - || superBlock->num_ags != divide_roundup(superBlock->num_blocks,1L << superBlock->ag_shift)) - { - result = false; - } else { - if (partitionInfo->file_system_short_name) - strcpy(partitionInfo->file_system_short_name, "bfs"); - if (partitionInfo->file_system_long_name) - strcpy(partitionInfo->file_system_long_name, "Be File System"); - if (partitionInfo->volume_name) - strcpy(partitionInfo->volume_name, superBlock->name); - if (priority) - *priority = 0; - partitionInfo->file_system_flags = B_FS_IS_PERSISTENT - | B_FS_HAS_ATTR | B_FS_HAS_MIME | B_FS_HAS_QUERY; - result = true; - } - free(buffer); - } - } - return result; -} - -static fs_module_info bfs_fs_module = -{ - // module_info - { - BFS_FS_MODULE_NAME, - 0, // better B_KEEP_LOADED? - std_ops - }, - bfs_fs_identify -}; - -_EXPORT fs_module_info *modules[] = -{ - &bfs_fs_module, - NULL -}; - -#endif // 0 - - -// module -static status_t bfs_std_ops(int32 op, ...); - -// scanning -static float bfs_identify_partition(int fd, partition_data *partition, - void **cookie); -static status_t bfs_scan_partition(int fd, partition_data *partition, - void *cookie); -static void bfs_free_identify_partition_cookie(partition_data *partition, - void *cookie); -static void bfs_free_partition_content_cookie(partition_data *partition); - -static fs_module_info bfs_module = { - { - kBFSModuleName, - 0, - bfs_std_ops - }, -// B_PLAIN_C_ERROR: -// kPartitionTypeBFS, // pretty_name - "BFS Filesystem", // pretty_name - B_DISK_SYSTEM_IS_FILE_SYSTEM, // flags - - // scanning - bfs_identify_partition, // identify_partition - bfs_scan_partition, // scan_partition - bfs_free_identify_partition_cookie, // free_identify_partition_cookie - bfs_free_partition_content_cookie, // free_partition_content_cookie - - // querying - NULL, // supports_defragmenting - NULL, // supports_repairing - NULL, // supports_resizing - NULL, // supports_moving - NULL, // supports_setting_content_name - NULL, // supports_setting_content_parameters - NULL, // supports_initializing - - NULL, // validate_resize - NULL, // validate_move - NULL, // validate_set_content_name - NULL, // validate_set_content_parameters - NULL, // validate_initialize - - // shadow partition modification - NULL, // shadow_changed - - // writing - NULL, // defragment - NULL, // repair - NULL, // resize - NULL, // move - NULL, // set_content_name - NULL, // set_content_parameters - NULL, // initialize -}; - - -#ifdef __cplusplus -extern "C" -#endif -fs_module_info *modules[]; -_EXPORT fs_module_info *modules[] = -{ - &bfs_module, - NULL -}; - - -// read_super_block -static -status_t -read_super_block(int fd, disk_super_block **_superBlock) -{ - status_t error = B_OK; - ssize_t bytesRead; - // allocate space for the super block - disk_super_block *superBlock - = (disk_super_block*)malloc(sizeof(disk_super_block)); - if (!superBlock) - return B_NO_MEMORY; - // read and check the super block - bytesRead = read_pos(fd, 512, superBlock, sizeof(disk_super_block)); - if (bytesRead < 0) { - error = bytesRead; - } else if (bytesRead != sizeof(disk_super_block) - || superBlock->magic1 != (int32)SUPER_BLOCK_MAGIC1 - || superBlock->magic2 != (int32)SUPER_BLOCK_MAGIC2 - || superBlock->magic3 != (int32)SUPER_BLOCK_MAGIC3 - || (int32)superBlock->block_size != superBlock->inode_size - || superBlock->fs_byte_order != SUPER_BLOCK_FS_LENDIAN - || (1UL << superBlock->block_shift) != superBlock->block_size - || superBlock->num_ags < 1 - || superBlock->ag_shift < 1 - || superBlock->blocks_per_ag < 1 - || superBlock->num_blocks < 10 - || superBlock->num_ags != divide_roundup(superBlock->num_blocks, - 1L << superBlock->ag_shift)) { - error = B_ERROR; - } - // set result / cleanup on failure - if (error == B_OK) - *_superBlock = superBlock; - else if (superBlock) - free(superBlock); - return error; -} - -// bfs_std_ops -static -status_t -bfs_std_ops(int32 op, ...) -{ - TRACE(("bfs: bfs_std_ops(0x%lx)\n", op)); - switch(op) { - case B_MODULE_INIT: - case B_MODULE_UNINIT: - return B_OK; - } - return B_ERROR; -} - -// bfs_identify_partition -static -float -bfs_identify_partition(int fd, partition_data *partition, void **cookie) -{ - disk_super_block *superBlock = NULL; - // check parameters - if (fd < 0 || !partition || !cookie) - return -1; - TRACE(("bfs: bfs_identify_partition(%d, %ld: %lld, %lld, %ld)\n", fd, - partition->id, partition->offset, partition->size, - partition->block_size)); - // read super block - if (read_super_block(fd, &superBlock) != B_OK) - return -1; - *cookie = superBlock; - return 0.5; -} - -// bfs_scan_partition -static -status_t -bfs_scan_partition(int fd, partition_data *partition, void *cookie) -{ - disk_super_block *superBlock = NULL; - // check parameters - if (fd < 0 || !partition || !cookie) - return B_ERROR; - TRACE(("bfs: bfs_scan_partition(%d, %ld: %lld, %lld, %ld)\n", fd, - partition->id, partition->offset, partition->size, - partition->block_size)); - superBlock = (disk_super_block*)cookie; - // fill in the partition_data structure - partition->content_size - = (off_t)superBlock->num_blocks * superBlock->block_size; - if (partition->content_size <= partition->size) - partition->status = B_PARTITION_VALID; - else - partition->status = B_PARTITION_CORRUPT; - partition->flags |= B_PARTITION_FILE_SYSTEM; - partition->block_size = superBlock->block_size; - partition->content_name = strdup(superBlock->name); - // (content_type is set by the system) - // (no content_parameters, content_cookie ?) - // free the super block - free(superBlock); - if (!partition->content_name) - return B_NO_MEMORY; - return B_OK; -} - -// bfs_free_identify_partition_cookie -static -void -bfs_free_identify_partition_cookie(partition_data *partition, void *cookie) -{ - if (cookie) - free(cookie); -} - -// bfs_free_partition_content_cookie -static -void -bfs_free_partition_content_cookie(partition_data *partition) -{ - if (partition) - partition->content_cookie = NULL; -} - diff --git a/src/add-ons/kernel/disk_scanner/fs/iso9660.cpp b/src/add-ons/kernel/disk_scanner/fs/iso9660.cpp deleted file mode 100644 index 64d938a8db..0000000000 --- a/src/add-ons/kernel/disk_scanner/fs/iso9660.cpp +++ /dev/null @@ -1,635 +0,0 @@ -//---------------------------------------------------------------------- -// This software is part of the OpenBeOS distribution and is covered -// by the OpenBeOS license. -//--------------------------------------------------------------------- -/*! - \file iso9660.cpp - \brief disk_scanner filesystem module for iso9660 CD-ROM filesystems - -
iso9660
- The standard to which this module is written is ECMA-119 second - edition, a freely available iso9660 equivalent. - -
Joliet
- Joliet support comes courtesy of the following document: - - http://www-plateau.cs.berkeley.edu/people/chaffee/jolspec.htm - - As specified there, the existence of any of the following escape - sequences in a supplementary volume descriptor's "escape sequences" - field denotes a Joliet volume descriptor using unicode ucs-2 - character encoding (2-byte characters, big-endian): - - - UCS-2 Level 1: 0x252F40 == "%/@" - - UCS-2 Level 2: 0x252F43 == "%/C" - - UCS-2 Level 3: 0x252F45 == "%/E" - - The following UCS-2 characters are considered illegal (we allow them, - printing out a warning if encountered): - - - All values between 0x0000 and 0x001f inclusive == control chars - - 0x002A == '*' - - 0x002F == '/' - - 0x003A == ':' - - 0x003B == ';' - - 0x003F == '?' - - 0x005C == '\' -*/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define TRACE(x) ; -//#define TRACE(x) dprintf x - -// misc constants -#define ISO9660_FS_MODULE_NAME "disk_scanner/fs/iso9660/v1" -static const char *kModuleDebugName = "fs/iso9660"; -static const char *kISO9660Signature = "CD001"; -static const uint32 kVolumeDescriptorLength = 2048; -#define ISO9660_VOLUME_IDENTIFIER_LENGTH 32 -#define ISO9660_ESCAPE_SEQUENCE_LENGTH 32 - -//! Volume descriptor types -typedef enum { - ISO9660VD_BOOT, - ISO9660VD_PRIMARY, - ISO9660VD_SUPPLEMENTARY, - ISO9660VD_PARTITION, - ISO9660VD_TERMINATOR = 255 -} iso9660_volume_descriptor_type; - -/*! \brief The portion of the volume descriptor common to all - descriptor types. -*/ -typedef struct iso9660_common_volume_descriptor { - uchar volume_descriptor_type; - char standard_identifier[5]; // should be 'CD001' - uchar volume_descriptor_version; - // Remaining bytes are unused -} __attribute__((packed)) iso9660_common_volume_descriptor; - -/*! \brief Primary volume descriptor -*/ -typedef struct iso9660_primary_volume_descriptor { - iso9660_common_volume_descriptor info; - uchar volume_flags; - char system_identifier[32]; - char volume_identifier[ISO9660_VOLUME_IDENTIFIER_LENGTH]; - uchar unused01[8]; - uint32 volume_space_size_little_endian; - uint32 volume_space_size_big_endian; - uchar unused02[ISO9660_ESCAPE_SEQUENCE_LENGTH]; - uint16 volume_set_size_little_endian; - uint16 volume_set_size_big_endian; - uint16 volume_sequence_number_little_endian; - uint16 volume_sequence_number_big_endian; - uint16 logical_block_size_little_endian; - uint16 logical_block_size_big_endian; - uint32 path_table_size_little_endian; - uint32 path_table_size_big_endian; - uint32 ignored02[4]; - uchar root_directory_record[34]; - char volume_set_identifier[28]; - // Remaining bytes are disinteresting to us -} __attribute__((packed)) iso9660_primary_volume_descriptor; - -typedef struct iso9660_supplementary_volume_descriptor { - iso9660_common_volume_descriptor info; - uchar volume_flags; - char system_identifier[32]; - char volume_identifier[ISO9660_VOLUME_IDENTIFIER_LENGTH]; - uchar unused01[8]; - uint32 volume_space_size_little_endian; - uint32 volume_space_size_big_endian; - char escape_sequences[ISO9660_ESCAPE_SEQUENCE_LENGTH]; - uint16 volume_set_size_little_endian; - uint16 volume_set_size_big_endian; - uint16 volume_sequence_number_little_endian; - uint16 volume_sequence_number_big_endian; - uint16 logical_block_size_little_endian; - uint16 logical_block_size_big_endian; - uint32 path_table_size_little_endian; - uint32 path_table_size_big_endian; - uint32 ignored02[4]; - uchar root_directory_record[34]; - char volume_set_identifier[28]; - // Remaining bytes are disinteresting to us -} __attribute__((packed)) iso9660_supplementary_volume_descriptor; - -typedef struct iso9660_directory_record { - uint8 length; - uint8 extended_attribute_record_length; - uint32 location_le; - uint32 location_be; - uint32 data_length; - uchar ignored[14]; - uint16 volume_space_le; -} __attribute__((packed)) iso9660_directory_record; - -/*! \brief Contains all the info of interest pertaining to an - iso9660 volume. - - Currently supported character set encoding styles (in decreasing - order of precedence): - - Joliet (UCS-12 (16-bit unicode), which is converted to UTF-8) - - iso9660 (some absurdly tiny character set, but we actually allow UTF-8) -*/ -struct iso9660_info { - iso9660_info(); - ~iso9660_info(); - - bool is_valid(); - - void set_iso9660_volume_name(const char *name, uint32 length); - void set_joliet_volume_name(const char *name, uint32 length); - - const char* get_preferred_volume_name(); - - char *iso9660_volume_name; - char *joliet_volume_name; - - void set_string(char **string, const char *new_string, uint32 new_length); -}; - -//---------------------------------------------------------------------------- -// iso9660_info -//---------------------------------------------------------------------------- - -/*! \brief Creates a new iso9660_info struct with empty volume names. - - \note Use the applicable set_XYZ_volume_name() functions rather than - messing with the volume name data members directly. -*/ -iso9660_info::iso9660_info() - : iso9660_volume_name(NULL) - , joliet_volume_name(NULL) -{ -} - -/*! \brief Destroys the struct, freeing the volume name strings. -*/ -iso9660_info::~iso9660_info() -{ - if (iso9660_volume_name) { - free(iso9660_volume_name); - iso9660_volume_name = NULL; - } - if (joliet_volume_name) { - free(joliet_volume_name); - joliet_volume_name = NULL; - } -} - -/*! \brief Returns true if a valid volume name exists. -*/ -bool -iso9660_info::is_valid() -{ - return iso9660_volume_name || joliet_volume_name; -} - -/*! \brief Sets the iso9660 volume name. - - \param name UTF-8 string containing the name. - \param length The length (in bytes) of the string. -*/ -void -iso9660_info::set_iso9660_volume_name(const char *name, uint32 length) -{ - set_string(&iso9660_volume_name, name, length); -} - -/*! \brief Sets the Joliet volume name. - - \param name UTF-8 string containing the name. - \param length The length (in bytes) of the string. -*/ -void -iso9660_info::set_joliet_volume_name(const char *name, uint32 length) -{ - set_string(&joliet_volume_name, name, length); -} - -/*! \brief Returns the volume name of highest precedence. - - Currently, the ordering is (decreasingly): - - Joliet - - iso9660 -*/ -const char* -iso9660_info::get_preferred_volume_name() -{ - if (joliet_volume_name) - return joliet_volume_name; - else - return iso9660_volume_name; -} - -/*! \brief Copies the given string into the old string, managing memory - deallocation and allocation as necessary. -*/ -void -iso9660_info::set_string(char **string, const char *new_string, uint32 new_length) -{ - TRACE(("%s: iso9660_info::set_string(%p (`%s'), `%s', %ld)\n", kModuleDebugName, - string, *string, new_string, new_length)); - if (string) { - char *&old_string = *string; - if (old_string) - free(old_string); - if (new_string) { - old_string = (char*)malloc(new_length+1); - if (old_string) { - strncpy(old_string, new_string, new_length); - old_string[new_length] = 0; - } - } else { - old_string = NULL; - } - } -} - -//---------------------------------------------------------------------------- -// C functions -//---------------------------------------------------------------------------- - -/*! \brief Converts the given unicode character to utf8. - - Courtesy Mr. Axel Dörfler. - - \todo Once OpenTracker's locale kit is done, perhaps that functionality - should be used rather than outright stealing the code. -*/ -static -void -unicode_to_utf8(uint32 c, char **out) -{ - char *s = *out; - - if (c < 0x80) - *(s++) = c; - else if (c < 0x800) { - *(s++) = 0xc0 | (c>>6); - *(s++) = 0x80 | (c & 0x3f); - } else if (c < 0x10000) { - *(s++) = 0xe0 | (c>>12); - *(s++) = 0x80 | ((c>>6) & 0x3f); - *(s++) = 0x80 | (c & 0x3f); - } else if (c <= 0x10ffff) { - *(s++) = 0xf0 | (c>>18); - *(s++) = 0x80 | ((c>>12) & 0x3f); - *(s++) = 0x80 | ((c>>6) & 0x3f); - *(s++) = 0x80 | (c & 0x3f); - } - *out = s; -} - -static -const char* -volume_descriptor_type_to_string(iso9660_volume_descriptor_type type) -{ - switch (type) { - case ISO9660VD_BOOT: return "boot"; - case ISO9660VD_PRIMARY: return "primary"; - case ISO9660VD_SUPPLEMENTARY: return "supplementary"; - case ISO9660VD_PARTITION: return "partiton"; - case ISO9660VD_TERMINATOR: return "terminator"; - default: return "invalid"; - } -} - -static -void -dump_common_volume_descriptor(iso9660_common_volume_descriptor *common, const char *indent, - bool print_header) -{ - if (print_header) - TRACE(("%siso9660_common_volume_descriptor:\n", indent)); - - TRACE(("%s volume descriptor type == %d (%s)\n", indent, - common->volume_descriptor_type, - volume_descriptor_type_to_string((iso9660_volume_descriptor_type)common->volume_descriptor_type))); - TRACE(("%s standard identifier == %.5s (%s)\n", indent, common->standard_identifier, - strncmp(common->standard_identifier, kISO9660Signature, 5) == 0 ? "valid" : "INVALID")); - TRACE(("%s volume descriptor version == %d\n", indent, common->volume_descriptor_version)); -} - -static -void -dump_directory_record(iso9660_directory_record *record, const char *indent); - -static -void -dump_primary_volume_descriptor(iso9660_primary_volume_descriptor *primary, const char *indent, - bool print_header) -{ - if (print_header) - TRACE(("%siso9660_primary_volume_descriptor:\n", indent)); - - dump_common_volume_descriptor(&(primary->info), indent, false); - TRACE(("%s volume identifier == `%.32s'\n", indent, - primary->volume_identifier)); - TRACE(("%s volume space size == %ld\n", indent, - primary->volume_space_size_little_endian)); - TRACE(("%s volume set size == %d\n", indent, - primary->volume_set_size_little_endian)); - TRACE(("%s volume sequence number == %d\n", indent, - primary->volume_sequence_number_little_endian)); - TRACE(("%s logical block size == %d\n", indent, - primary->logical_block_size_little_endian)); - TRACE(("%s path table size == %ld\n", indent, - primary->path_table_size_little_endian)); - TRACE(("%s volume set identifier == %.28s\n", indent, - primary->volume_set_identifier)); - dump_directory_record((iso9660_directory_record*)primary->root_directory_record, indent); -} - -static -void -dump_supplementary_volume_descriptor(iso9660_supplementary_volume_descriptor *supplementary, const char *indent, - bool print_header) -{ - if (print_header) - TRACE(("%siso9660_supplementary_volume_descriptor:\n", indent)); - - dump_primary_volume_descriptor((iso9660_primary_volume_descriptor*)supplementary, indent, false); - TRACE(("%s escape sequences ==", indent)); - for (int i = 0; i < ISO9660_ESCAPE_SEQUENCE_LENGTH; i++) { - TRACE((" %2x", supplementary->escape_sequences[i])); - if (i == ISO9660_ESCAPE_SEQUENCE_LENGTH/2-1) - TRACE(("\n ")); - } - TRACE(("\n")); -} - -static -void -dump_directory_record(iso9660_directory_record *record, const char *indent) -{ - TRACE(("%s root directory record:\n", indent)); - TRACE(("%s length == %d\n", indent, record->length)); - TRACE(("%s location == %ld\n", indent, record->location_le)); - TRACE(("%s data length == %ld\n", indent, record->data_length)); - TRACE(("%s volume sequence number == %d\n", indent, record->volume_space_le)); -} - -static -status_t -check_common_volume_descriptor(iso9660_common_volume_descriptor *common) -{ - status_t error = common ? B_OK : B_BAD_VALUE; - if (!error) { - error = strncmp(common->standard_identifier, kISO9660Signature, - 5) == 0 ? B_OK : B_BAD_DATA; - } - return error; -} - -// std_ops -static -status_t -std_ops(int32 op, ...) -{ - TRACE(("%s: std_ops(0x%lx)\n", kModuleDebugName, op)); - switch(op) { - case B_MODULE_INIT: - case B_MODULE_UNINIT: - return B_OK; - } - return B_ERROR; -} - -// read_block -static -status_t -read_block(fs_get_buffer get_buffer, struct fs_buffer_cache *cache, - off_t offset, size_t size, uchar **block) -{ - size_t actualSize = 0; - status_t error = get_buffer(cache, offset, size, (void**)block, - &actualSize); - if (error == B_OK && actualSize != size) { - error = B_ERROR; - free(*block); - } - return error; -} - -// iso9660_fs_identify -/*! \brief Returns true if the given partition is a valid iso9660 partition. - - See fs_identify_hook() for more information. - - \todo Fill in partitionInfo->mounted_at with something useful. -*/ -static -bool -iso9660_fs_identify(int deviceFD, struct extended_partition_info *partitionInfo, - float *priority, fs_get_buffer get_buffer, - struct fs_buffer_cache *cache) -{ - bool result = false; - uchar *buffer = NULL; - uint32 blockSize = partitionInfo->info.logical_block_size; - bool exit = false; - // The first 16 blocks are for "system use" only, and thus are - // irrelevant to us and generally just zeros - off_t offset = 16 * blockSize; - status_t error = B_OK; - - TRACE(("%s: identify(%d, %p)\n", kModuleDebugName, deviceFD, - partitionInfo)); - - iso9660_info info; - - // Read through the volume descriptors looking for a primary descriptor. - // If for some reason there are more than one primary descriptor, the - // volume name from the last encountered descriptor will be used. - while (!error && !exit) {// && count++ < 10) { - iso9660_common_volume_descriptor *common = NULL; - - // Read the block containing the current descriptor - error = read_block(get_buffer, cache, offset, blockSize, &buffer); - offset += blockSize; - if (!error) { - common = (iso9660_common_volume_descriptor*)buffer; - error = check_common_volume_descriptor(common); -// dump_common_volume_descriptor(common, "", true); - } - - // Handle each type of descriptor appropriately - if (!error) { - TRACE(("%s: found %s descriptor\n", kModuleDebugName, - volume_descriptor_type_to_string((iso9660_volume_descriptor_type)common->volume_descriptor_type))); - - switch (common->volume_descriptor_type) { - case ISO9660VD_BOOT: - break; - - case ISO9660VD_PRIMARY: - { - int i; - iso9660_primary_volume_descriptor *primary = (iso9660_primary_volume_descriptor*)buffer; - - dump_primary_volume_descriptor(primary, " ", true); - - // Cut off any trailing spaces from the volume id. Note - // that this allows for spaces INSIDE the volume id, even - // though that's not technically allowed by the standard; - // this was necessary to support certain RedHat 6.2 CD-ROMs - // from a certain Linux company who shall remain unnamed. ;-) - for (i = ISO9660_VOLUME_IDENTIFIER_LENGTH-1; i >= 0; i--) { - if (primary->volume_identifier[i] != 0x20) - break; - } - - // Give a holler if the iso9660 name is already set - if (info.iso9660_volume_name) { - char str[ISO9660_VOLUME_IDENTIFIER_LENGTH+1]; - strncpy(str, primary->volume_identifier, i+1); - str[i+1] = 0; - TRACE(("%s: duplicate iso9660 volume name found, using latter (`%s') " - "instead of former (`%s')\n", kModuleDebugName, str, - info.iso9660_volume_name)); - } - - info.set_iso9660_volume_name(primary->volume_identifier, i+1); - break; - } - - case ISO9660VD_SUPPLEMENTARY: - { - iso9660_supplementary_volume_descriptor *supplementary = (iso9660_supplementary_volume_descriptor*)buffer; - dump_supplementary_volume_descriptor((iso9660_supplementary_volume_descriptor*)supplementary, " ", true); - - // Copy and null terminate the escape sequences - char escapes[ISO9660_ESCAPE_SEQUENCE_LENGTH+1]; - strncpy(escapes, supplementary->escape_sequences, ISO9660_ESCAPE_SEQUENCE_LENGTH); - escapes[ISO9660_ESCAPE_SEQUENCE_LENGTH] = 0; - - // Check for a Joliet VD - if (strstr(escapes, "%/@") || strstr(escapes, "%/C") || strstr(escapes, "%/E")) { - char str[(ISO9660_VOLUME_IDENTIFIER_LENGTH*3/2)+1]; - // Since we're dealing with 16-bit Unicode, each UTF-8 sequence - // will be at most 3 bytes long. So we need 3/2 as many chars as - // we start out with. - char *str_iterator = str; - uint16 ch; - - // Walk thru the unicode volume name, converting to utf8 as we go. - for (int i = 0; - (ch = B_BENDIAN_TO_HOST_INT16(((uint16*)supplementary->volume_identifier)[i])) - && i < ISO9660_VOLUME_IDENTIFIER_LENGTH; - i++) { - // Give a warning if the character is technically illegal - if ( ch <= 0x001F - || ch == 0x002A - || ch == 0x002F - || ch == 0x003A - || ch == 0x003B - || ch == 0x003F - || ch == 0x005C) - { - TRACE(("%s: warning: illegal Joliet character found: 0%4x\n", - kModuleDebugName, ch)); - } - - // Convert to utf-8 - unicode_to_utf8(ch, &str_iterator); - } - *str_iterator = 0; - - // Give a holler if the joliet name is already set - if (info.joliet_volume_name) { - TRACE(("%s: duplicate joliet volume name found, using latter (`%s') " - "instead of former (`%s')\n", kModuleDebugName, str, - info.joliet_volume_name)); - } - - info.set_joliet_volume_name(str, strlen(str)); - } // end "if Joliet VD" - break; - } - - case ISO9660VD_PARTITION: - break; - - case ISO9660VD_TERMINATOR: - exit = true; - break; - - default: - break; - } - } - if (buffer) { - free(buffer); - buffer = NULL; - } - } - - switch (error) { - case B_OK: - if (info.is_valid()) { - result = true; - if (partitionInfo->file_system_short_name) - strcpy(partitionInfo->file_system_short_name, "iso9660"); - if (partitionInfo->file_system_long_name) - strcpy(partitionInfo->file_system_long_name, "iso9660 CD-ROM File System"); - partitionInfo->file_system_flags = B_FS_IS_PERSISTENT; - if (priority) - *priority = 0; - // Copy the volume name of highest precedence - if (partitionInfo->volume_name) { - TRACE(("%s: iso9660 name: `%s'\n", kModuleDebugName, info.iso9660_volume_name)); - TRACE(("%s: joliet name: `%s'\n", kModuleDebugName, info.joliet_volume_name)); - const char *name = info.get_preferred_volume_name(); - int length = strlen(name); - if (length > B_FILE_NAME_LENGTH-1) - length = B_FILE_NAME_LENGTH-1; - strncpy(partitionInfo->volume_name, name, length); - partitionInfo->volume_name[length] = 0; - } - } - break; - - case B_BAD_DATA: - TRACE(("%s: identify: bad signature\n", kModuleDebugName)); - break; - - default: - TRACE(("%s: identify error: 0x%lx\n", kModuleDebugName, - error)); - break; - } - - return result; -} - -static fs_module_info iso9660_fs_module = -{ - // module_info - { - ISO9660_FS_MODULE_NAME, - 0, // better B_KEEP_LOADED? - std_ops - }, - iso9660_fs_identify, -}; - -_EXPORT fs_module_info *modules[] = -{ - &iso9660_fs_module, - NULL -}; - diff --git a/src/add-ons/kernel/disk_scanner/partition/Jamfile b/src/add-ons/kernel/disk_scanner/partition/Jamfile deleted file mode 100644 index 5ef356b5b7..0000000000 --- a/src/add-ons/kernel/disk_scanner/partition/Jamfile +++ /dev/null @@ -1,8 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel disk_scanner partition ; - -UsePrivateHeaders $(DOT) ; - -#KernelAddon intel : kernel disk_scanner partition : -# intel.cpp -#; - diff --git a/src/add-ons/kernel/disk_scanner/partition/intel.cpp b/src/add-ons/kernel/disk_scanner/partition/intel.cpp deleted file mode 100644 index 4953388300..0000000000 --- a/src/add-ons/kernel/disk_scanner/partition/intel.cpp +++ /dev/null @@ -1,425 +0,0 @@ -//---------------------------------------------------------------------- -// This software is part of the OpenBeOS distribution and is covered -// by the OpenBeOS license. -//--------------------------------------------------------------------- -/*! - \file intel.cpp - \brief disk_scanner partition module for "intel" style partitions. -*/ - -// TODO: The implementation is very strict right now. It rejects a partition -// completely, if it finds an error in its partition tables. We should see, -// what error can be handled gracefully, e.g. by ignoring the partition -// descriptor or the whole partition table sector. - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "intel_parameters.h" -#include "intel_partition_map.h" - -#define TRACE(x) ; -//#define TRACE(x) dprintf x - -#define INTEL_PARTITION_MODULE_NAME "disk_scanner/partition/intel/v1" - -// partition module identifier -static const char *const kShortModuleName = "intel"; - -// Maximal number of logical partitions per extended partition we allow. -static const int32 kMaxLogicalPartitionCount = 128; - - -// PartitionMapParser - -class PartitionMapParser { -public: - PartitionMapParser(int deviceFD, off_t sessionOffset, off_t sessionSize, - int32 blockSize); - ~PartitionMapParser(); - - status_t Parse(const uint8 *block, PartitionMap *map); - - int32 CountPartitions() const; - const Partition *PartitionAt(int32 index) const; - -private: - status_t _ParsePrimary(const partition_table_sector *pts); - status_t _ParseExtended(PrimaryPartition *primary, off_t offset); - status_t _ReadPTS(off_t offset, partition_table_sector *pts = NULL); - -private: - int fDeviceFD; - off_t fSessionOffset; - off_t fSessionSize; - int32 fBlockSize; - partition_table_sector *fPTS; // while parsing - PartitionMap *fMap; // -}; - -// constructor -PartitionMapParser::PartitionMapParser(int deviceFD, off_t sessionOffset, - off_t sessionSize, int32 blockSize) - : fDeviceFD(deviceFD), - fSessionOffset(sessionOffset), - fSessionSize(sessionSize), - fBlockSize(blockSize), - fPTS(NULL), - fMap(NULL) -{ -} - -// destructor -PartitionMapParser::~PartitionMapParser() -{ -} - -// Parse -status_t -PartitionMapParser::Parse(const uint8 *block, PartitionMap *map) -{ - status_t error = (map ? B_OK : B_BAD_VALUE); - if (error == B_OK) { - fMap = map; - fMap->Unset(); - if (block) { - const partition_table_sector *pts - = (const partition_table_sector*)block; - error = _ParsePrimary(pts); - } else { - partition_table_sector pts; - error = _ReadPTS(0, &pts); - if (error == B_OK) - error = _ParsePrimary(&pts); - } - if (error == B_OK && !fMap->Check(fSessionSize, fBlockSize)) - error = B_BAD_DATA; - fMap = NULL; - } - return error; -} - -// _ParsePrimary -status_t -PartitionMapParser::_ParsePrimary(const partition_table_sector *pts) -{ - status_t error = (pts ? B_OK : B_BAD_VALUE); - // check the signature - if (error == B_OK && pts->signature != kPartitionTableSectorSignature) { - TRACE(("intel: _ParsePrimary(): invalid PTS signature\n")); - error = B_BAD_DATA; - } - // examine the table - if (error == B_OK) { - for (int32 i = 0; i < 4; i++) { - const partition_descriptor *descriptor = &pts->table[i]; - PrimaryPartition *partition = fMap->PrimaryPartitionAt(i); - partition->SetTo(descriptor, 0, fBlockSize); - // fail, if location is bad - if (!partition->CheckLocation(fSessionSize, fBlockSize)) { - error = B_BAD_DATA; - break; - } - } - } - // allocate a PTS buffer - if (error == B_OK) { - fPTS = new(nothrow) partition_table_sector; - if (!fPTS) - error = B_NO_MEMORY; - } - // parse extended partitions - if (error == B_OK) { - for (int32 i = 0; error == B_OK && i < 4; i++) { - PrimaryPartition *primary = fMap->PrimaryPartitionAt(i); - if (primary->IsExtended()) - error = _ParseExtended(primary, primary->Offset()); - } - } - // cleanup - if (fPTS) { - delete fPTS; - fPTS = NULL; - } - return error; -} - -// _ParseExtended -status_t -PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset) -{ - status_t error = B_OK; - int32 partitionCount = 0; - while (error == B_OK) { - // check for cycles - if (++partitionCount > kMaxLogicalPartitionCount) { - TRACE(("intel: _ParseExtended(): Maximal number of logical " - "partitions for extended partition reached. Cycle?\n")); - error = B_BAD_DATA; - } - // read the PTS - if (error == B_OK) - error = _ReadPTS(offset); - // check the signature - if (error == B_OK - && fPTS->signature != kPartitionTableSectorSignature) { - TRACE(("intel: _ParseExtended(): invalid PTS signature\n")); - error = B_BAD_DATA; - } - // ignore the PTS, if any error occured till now - if (error != B_OK) { - TRACE(("intel: _ParseExtended(): ignoring this PTS\n")); - error = B_OK; - break; - } - // examine the table - LogicalPartition extended; - LogicalPartition nonExtended; - if (error == B_OK) { - for (int32 i = 0; error == B_OK && i < 4; i++) { - const partition_descriptor *descriptor = &fPTS->table[i]; - LogicalPartition *partition = NULL; - if (!descriptor->is_empty()) { - if (descriptor->is_extended()) { - if (extended.IsEmpty()) { - extended.SetTo(descriptor, offset, fBlockSize, - primary); - partition = &extended; - } else { - // only one extended partition allowed - error = B_BAD_DATA; - TRACE(("intel: _ParseExtended(): " - "only one extended partition allowed\n")); - } - } else { - if (nonExtended.IsEmpty()) { - nonExtended.SetTo(descriptor, offset, fBlockSize, - primary); - partition = &nonExtended; - } else { - // only one non-extended partition allowed - error = B_BAD_DATA; - TRACE(("intel: _ParseExtended(): only one " - "non-extended partition allowed\n")); - } - } - // check the partition's location - if (partition && !partition->CheckLocation(fSessionSize, - fBlockSize)) { - error = B_BAD_DATA; - } - } - } - } - // add non-extended partition to list - if (error == B_OK && !nonExtended.IsEmpty()) { - LogicalPartition *partition - = new(nothrow) LogicalPartition(nonExtended); - if (partition) - primary->AddLogicalPartition(partition); - else - error = B_NO_MEMORY; - } - // prepare to parse next extended partition - if (error == B_OK && !extended.IsEmpty()) - offset = extended.Offset(); - else - break; - } - return error; -} - -// _ReadPTS -status_t -PartitionMapParser::_ReadPTS(off_t offset, partition_table_sector *pts) -{ - status_t error = B_OK; - if (!pts) - pts = fPTS; - int32 toRead = sizeof(partition_table_sector); - // check the offset - if (offset < 0 || offset + toRead > fSessionSize) { - error = B_BAD_VALUE; - TRACE(("intel: _ReadPTS(): bad offset: %Ld\n", offset)); - // read - } else if (read_pos(fDeviceFD, fSessionOffset + offset, pts, toRead) - != toRead) { - error = errno; - if (error == B_OK) - error = B_IO_ERROR; - TRACE(("intel: _ReadPTS(): reading the PTS failed: %s\n", - strerror(error))); - } - return error; -} - - -// std_ops -static -status_t -std_ops(int32 op, ...) -{ - TRACE(("intel: std_ops(0x%lx)\n", op)); - switch(op) { - case B_MODULE_INIT: - case B_MODULE_UNINIT: - return B_OK; - } - return B_ERROR; -} - -// read_partition_map -static -bool -read_partition_map(int deviceFD, const session_info *sessionInfo, - const uchar *block, PartitionMap *map) -{ - bool result = true; - off_t sessionOffset = sessionInfo->offset; - off_t sessionSize = sessionInfo->size; - int32 blockSize = sessionInfo->logical_block_size; - TRACE(("intel: read_partition_map(%d, %lld, %lld, %p, %ld)\n", deviceFD, - sessionOffset, sessionSize, block, blockSize)); - // check block size - if (result) { - result = ((uint32)blockSize >= sizeof(partition_table_sector)); - if (!result) { - TRACE(("intel: read_partition_map: bad block size: %ld, should be " - ">= %ld\n", blockSize, sizeof(partition_table_sector))); - } - } - // read the partition structure - if (result) { - PartitionMapParser parser(deviceFD, sessionOffset, sessionSize, - blockSize); - result = (parser.Parse(block, map) == B_OK); - } - return result; -} - -// intel_identify -static -bool -intel_identify(int deviceFD, const session_info *sessionInfo, - const uchar *block) -{ - TRACE(("intel: identify(%d, %lld, %lld, %p, %ld)\n", deviceFD, - sessionInfo->offset, sessionInfo->size, block, - sessionInfo->logical_block_size)); - PartitionMap map; - return read_partition_map(deviceFD, sessionInfo, block, &map); -} - -// intel_get_nth_info -static -status_t -intel_get_nth_info(int deviceFD, const session_info *sessionInfo, - const uchar *block, int32 index, - extended_partition_info *partitionInfo) -{ - status_t error = B_OK; - off_t sessionOffset = sessionInfo->offset; - TRACE(("intel: get_nth_info(%d, %lld, %lld, %p, %ld, %ld)\n", deviceFD, - sessionOffset, sessionInfo->size, block, - sessionInfo->logical_block_size, index)); - PartitionMap map; - if (read_partition_map(deviceFD, sessionInfo, block, &map)) { - if (Partition *partition = map.PartitionAt(index)) { - if (partition->IsEmpty()) { - // empty partition - partitionInfo->info.offset = sessionOffset; - partitionInfo->info.size = 0; - partitionInfo->flags - = B_HIDDEN_PARTITION | B_EMPTY_PARTITION; - } else { - // non-empty partition - partitionInfo->info.offset - = partition->Offset() + sessionOffset; - partitionInfo->info.size = partition->Size(); - if (partition->IsExtended()) - partitionInfo->flags = B_HIDDEN_PARTITION; - else - partitionInfo->flags = 0; - } - partitionInfo->partition_name[0] = '\0'; - partition->GetTypeString(partitionInfo->partition_type); - } else - error = B_ENTRY_NOT_FOUND; - } else // couldn't read partition map -- we shouldn't be in get_nth_info() - error = B_BAD_DATA; - return error; -} - -// intel_get_partitioning_params -static -status_t -intel_get_partitioning_params(int deviceFD, - const struct session_info *sessionInfo, - char *buffer, size_t bufferSize, - size_t *actualSize) -{ - status_t error = B_OK; - PartitionMap map; - if (!read_partition_map(deviceFD, sessionInfo, NULL, &map)) { - // couldn't read partition map, set up a default one: - // four empty primary partitions - map.Unset(); - } - // get the parameter length - size_t length = 0; - if (error == B_OK) { - ParameterUnparser unparser; - error = unparser.GetParameterLength(&map, &length); - } - // write the parameters - if (error == B_OK && length <= bufferSize) { - ParameterUnparser unparser; - error = unparser.Unparse(&map, buffer, bufferSize); - } - // set the results - if (error == B_OK) - *actualSize = length; - return error; -} - -// intel_partition -static -status_t -intel_partition(int deviceFD, const struct session_info *sessionInfo, - const char *parameters) -{ - // not yet supported - return B_UNSUPPORTED; -} - - -static partition_module_info intel_partition_module = -{ - // module_info - { - INTEL_PARTITION_MODULE_NAME, - 0, // better B_KEEP_LOADED? - std_ops - }, - kShortModuleName, - - intel_identify, - intel_get_nth_info, - intel_get_partitioning_params, - intel_partition, -}; - -extern "C" partition_module_info *modules[]; -_EXPORT partition_module_info *modules[] = -{ - &intel_partition_module, - NULL -}; - diff --git a/src/add-ons/kernel/disk_scanner/partition/intel_parameters.cpp b/src/add-ons/kernel/disk_scanner/partition/intel_parameters.cpp deleted file mode 100644 index 8347126ccc..0000000000 --- a/src/add-ons/kernel/disk_scanner/partition/intel_parameters.cpp +++ /dev/null @@ -1,390 +0,0 @@ -//---------------------------------------------------------------------- -// This software is part of the OpenBeOS distribution and is covered -// by the OpenBeOS license. -//--------------------------------------------------------------------- -/*! - \file intel_parameters.cpp - \brief Class implementations for "intel" style partitioning - parameter support. -*/ - -#include -#include -#include -#include -#include - -#include "intel_parameters.h" -#include "intel_partition_map.h" - -// Grammar for parameters: -// -// partition ::= "{" ptsoffset "," offset "," size "," type "," -// active "}" -// primary ::= "{" partition+ "}" -// partition_map ::= primary primary primary primary - -// longest token (including terminating null) -const int32 kMaxTokenLen = 256; - - -// Tokenizer - -// constructor -Tokenizer::Tokenizer() - : fInput(NULL), - fPosition(0), - fLastPosition(0) -{ -} - -// constructor -Tokenizer::Tokenizer(const char *input) - : fInput(input), - fPosition(0), - fLastPosition(0) -{ -} - -// SetTo -void -Tokenizer::SetTo(const char *input) -{ - fInput = input; - fPosition = 0; - fLastPosition = 0; -} - -// GetNextToken -int32 -Tokenizer::GetNextToken(char *buffer) -{ - int32 kind = TOKEN_ERROR; - fLastPosition = fPosition; - // skip WS - _SkipWhiteSpace(); - switch (fInput[fPosition]) { - case '{': - case '}': - case ',': - kind = fInput[fPosition]; - fPosition++; - break; - case '\0': - kind = TOKEN_EOF; - break; - default: - { - if (isdigit(fInput[fPosition])) { - int32 startPos = fPosition; - while (isdigit(fInput[fPosition])) - fPosition++; - int32 len = fPosition - startPos; - if (len < kMaxTokenLen) { - if (buffer) { - memcpy(buffer, fInput + startPos, len); - buffer[len] = '\0'; - } - kind = TOKEN_NUMBER; - } else { - printf("token too long at: %ld\n", startPos); - kind = TOKEN_ERROR; - } - } - break; - } - } - return kind; -} - -// ExpectToken -bool -Tokenizer::ExpectToken(int32 kind, char *buffer) -{ - bool result = (GetNextToken(buffer) == kind); - if (!result) - PutLastToken(); - return result; -} - -// ReadNumber -bool -Tokenizer::ReadNumber(int64 &number) -{ - char buffer[kMaxTokenLen]; - bool result = ExpectToken(TOKEN_NUMBER, buffer); - if (result) - number = atoll(buffer); - return result; -} - -// _SkipWhiteSpace -void -Tokenizer::_SkipWhiteSpace() -{ - while (fInput[fPosition] != '\0' && isspace(fInput[fPosition])) - fPosition++; -} - - -// ParameterParser - -// constructor -ParameterParser::ParameterParser() - : fTokenizer(), - fParseError(B_OK), - fMap(NULL) -{ -} - -// Parse -status_t -ParameterParser::Parse(const char *parameters, PartitionMap *map) -{ - status_t error = (parameters && map ? B_OK : B_BAD_VALUE); - if (error == B_OK) { - // init parser - fParseError = B_OK; - fTokenizer.SetTo(parameters); - fMap = map; - // partition_map ::= primary primary primary primary - if (_ParsePrimaryPartition(fMap->PrimaryPartitionAt(0)) - && _ParsePrimaryPartition(fMap->PrimaryPartitionAt(1)) - && _ParsePrimaryPartition(fMap->PrimaryPartitionAt(2)) - && _ParsePrimaryPartition(fMap->PrimaryPartitionAt(3)) - && fTokenizer.ReadEOF()) { - // successfully parsed - } else - _ErrorOccurred(); - // cleanup / set results - fMap = NULL; - error = fParseError; - } - return error; -} - -// _ParsePrimaryPartition -bool -ParameterParser::_ParsePrimaryPartition(PrimaryPartition *primary) -{ - // primary ::= "{" partition+ "}" - if (fTokenizer.ReadOpen() - && _ParsePartition(primary)) { - while (_NoError() && !fTokenizer.ReadClose()) { - LogicalPartition *partition = new(nothrow) LogicalPartition; - if (partition) { - if (_ParsePartition(partition)) - primary->AddLogicalPartition(partition); - else - delete partition; - } else - _ErrorOccurred(B_NO_MEMORY); - } - } else - _ErrorOccurred(); - return _NoError(); -} - -// _ParsePartition -bool -ParameterParser::_ParsePartition(Partition *partition) -{ - // partition ::= "{" ptsoffset "," offset "," size "," type "," - // active "}" - int64 ptsOffset, offset, size, type, active; - if (fTokenizer.ReadOpen() - && fTokenizer.ReadNumber(ptsOffset) - && fTokenizer.ReadComma() - && fTokenizer.ReadNumber(offset) - && fTokenizer.ReadComma() - && fTokenizer.ReadNumber(size) - && fTokenizer.ReadComma() - && fTokenizer.ReadNumber(type) - && fTokenizer.ReadComma() - && fTokenizer.ReadNumber(active) - && fTokenizer.ReadClose()) { - if (ptsOffset >= 0 && offset >= 0 && size >= 0 - && type >= 0 && type < 256) { - partition->SetPTSOffset(ptsOffset); - partition->SetOffset(offset); - partition->SetSize(size); - partition->SetType((uint8)type); - partition->SetActive(active); - } else - _ErrorOccurred(B_BAD_VALUE); - } else - _ErrorOccurred(); - return _NoError(); -} - -// _ErrorOccurred -void -ParameterParser::_ErrorOccurred(status_t error) -{ - if (fParseError == B_OK) - fParseError = error; -} - - -// ParameterUnparser - -// constructor -ParameterUnparser::ParameterUnparser() - : fMap(NULL), - fParameters(NULL), - fPosition(0), - fSize(0), - fDryRun(false), - fUnparseError(B_OK) -{ -} - -// GetParameterLength -status_t -ParameterUnparser::GetParameterLength(const PartitionMap *map, size_t *length) -{ - status_t error = (map && length ? B_OK : B_BAD_VALUE); - if (error == B_OK) { - // init unparser for a dry run - fUnparseError = B_OK; - fMap = map; - char buffer[kMaxTokenLen]; - fParameters = buffer; - fPosition = 0; - fSize = 0; - fDryRun = true; - // dry run -- get the parameter size - if (_UnparsePartitionMap()) - *length = fPosition + 1; - // cleanup / set results - fMap = NULL; - error = fUnparseError; - } - return error; -} - -// Unparse -status_t -ParameterUnparser::Unparse(const PartitionMap *map, char *parameters, - size_t size) -{ - status_t error = (map && parameters ? B_OK : B_BAD_VALUE); - if (error == B_OK) { - // init unparser - fUnparseError = B_OK; - fMap = map; - fParameters = parameters; - fPosition = 0; - fSize = size; - fDryRun = false; - // unparse the partition map - _UnparsePartitionMap(); - // cleanup / set results - fMap = NULL; - error = fUnparseError; - } - return error; -} - -// _UnparsePartitionMap -bool -ParameterUnparser::_UnparsePartitionMap() -{ - if (_UnparsePrimaryPartition(fMap->PrimaryPartitionAt(0)) - && _UnparsePrimaryPartition(fMap->PrimaryPartitionAt(1)) - && _UnparsePrimaryPartition(fMap->PrimaryPartitionAt(2)) - && _UnparsePrimaryPartition(fMap->PrimaryPartitionAt(3))) { - // successfully unparsed - } - return _NoError(); -} - -// _UnparsePrimaryPartition -bool -ParameterUnparser::_UnparsePrimaryPartition(const PrimaryPartition *primary) -{ - // primary ::= "{" partition+ "}" - if (_WriteOpen() && _UnparsePartition(primary)) { - for (int32 i = 0; i < primary->CountLogicalPartitions(); i++) { - const LogicalPartition *partition = primary->LogicalPartitionAt(i); - if (!_UnparsePartition(partition)) - break; - } - if (_NoError()) - _WriteClose(); - } - return _NoError(); -} - -// _UnparsePartition -bool -ParameterUnparser::_UnparsePartition(const Partition *partition) -{ - // partition ::= "{" ptsoffset "," offset "," size "," type "," - // active "}" - if (_WriteOpen() - && _WriteNumber(partition->PTSOffset()) - && _WriteComma() - && _WriteNumber(partition->Offset()) - && _WriteComma() - && _WriteNumber(partition->Size()) - && _WriteComma() - && _WriteNumber(partition->Type()) - && _WriteComma() - && _WriteNumber(partition->Active() ? 1 : 0) - && _WriteClose()) { - // success - } - return _NoError(); -} - -// _Write -bool -ParameterUnparser::_Write(const char *str) -{ - size_t len = strlen(str); - if (!fDryRun) { - if (fSize > fPosition + len) - strcpy(fParameters + fPosition, str); - else - _ErrorOccurred(B_BAD_VALUE); - } - fPosition += len; - return _NoError(); -} - -// _WriteNumber -bool -ParameterUnparser::_WriteNumber(int64 number) -{ - char buffer[kMaxTokenLen]; - sprintf(buffer, "%lld", number); - return _Write(buffer); -} - -// _ErrorOccurred -void -ParameterUnparser::_ErrorOccurred(status_t error) -{ - if (fUnparseError == B_OK) - fUnparseError = error; -} - - - -/* -// main -int -main() -{ - const char *parameters = "{{ 0, 10, 1, 0}{ 0, 3, 1, 0}}" - "{{10, 13, 1, 1}}" - "{{23, 7, 1, 0}}" - "{{30, 9, 1, 0}}"; - ParameterParser parser; - status_t error = parser.Parse(parameters); - if (error != B_OK) - printf("error while parsing: %s\n", strerror(error)); - return 0; -} -*/ diff --git a/src/add-ons/kernel/disk_scanner/partition/intel_parameters.h b/src/add-ons/kernel/disk_scanner/partition/intel_parameters.h deleted file mode 100644 index 04128ecbfd..0000000000 --- a/src/add-ons/kernel/disk_scanner/partition/intel_parameters.h +++ /dev/null @@ -1,110 +0,0 @@ -//---------------------------------------------------------------------- -// This software is part of the OpenBeOS distribution and is covered -// by the OpenBeOS license. -//--------------------------------------------------------------------- -/*! - \file intel_parameters.h - \brief Class interface definitions for "intel" style partitioning - parameter support. -*/ - -#ifndef _INTEL_PARAMETERS_H -#define _INTEL_PARAMETERS_H - -#include - -class Partition; -class PartitionMap; -class PrimaryPartition; - -// tokens -enum { - TOKEN_ERROR = -1, - TOKEN_EOF = '\0', - TOKEN_OPEN = '{', - TOKEN_CLOSE = '}', - TOKEN_COMMA = ',', - TOKEN_NUMBER = '0', -}; - -// Tokenizer -class Tokenizer { -public: - Tokenizer(); - Tokenizer(const char *input); - - void SetTo(const char *input); - - int32 GetNextToken(char *buffer = NULL); - void PutLastToken() { fPosition = fLastPosition; } - - bool ExpectToken(int32 kind, char *buffer = NULL); - - bool ReadOpen() { return (ExpectToken(TOKEN_OPEN)); } - bool ReadClose() { return (ExpectToken(TOKEN_CLOSE)); } - bool ReadComma() { return (ExpectToken(TOKEN_COMMA)); } - bool ReadEOF() { return (ExpectToken(TOKEN_EOF)); } - bool ReadNumber(int64 &number); - -private: - void _SkipWhiteSpace(); - -private: - const char *fInput; - int32 fPosition; - int32 fLastPosition; -}; - -// ParameterParser -class ParameterParser { -public: - ParameterParser(); - ~ParameterParser() {} - - status_t Parse(const char *parameters, PartitionMap *map); - -private: - bool _ParsePrimaryPartition(PrimaryPartition *primary); - bool _ParsePartition(Partition *partition); - void _ErrorOccurred(status_t error = B_ERROR); - bool _NoError() const { return (fParseError == B_OK); } - -private: - Tokenizer fTokenizer; - status_t fParseError; - PartitionMap *fMap; -}; - -// ParameterUnparser -class ParameterUnparser { -public: - ParameterUnparser(); - ~ParameterUnparser() {} - - status_t GetParameterLength(const PartitionMap *map, size_t *length); - status_t Unparse(const PartitionMap *map, char *parameters, size_t length); - -private: - bool _UnparsePartitionMap(); - bool _UnparsePrimaryPartition(const PrimaryPartition *primary); - bool _UnparsePartition(const Partition *partition); - - bool _Write(const char *str); - bool _WriteOpen() { return _Write("{"); } - bool _WriteClose() { return _Write("}"); } - bool _WriteComma() { return _Write(","); } - bool _WriteNumber(int64 number); - - void _ErrorOccurred(status_t error = B_ERROR); - bool _NoError() const { return (fUnparseError == B_OK); } - -private: - const PartitionMap *fMap; - char *fParameters; - size_t fPosition; - size_t fSize; - bool fDryRun; - status_t fUnparseError; -}; - -#endif // _INTEL_PARAMETERS_H diff --git a/src/add-ons/kernel/disk_scanner/partition/intel_partition_map.cpp b/src/add-ons/kernel/disk_scanner/partition/intel_partition_map.cpp deleted file mode 100644 index 7a09c131ad..0000000000 --- a/src/add-ons/kernel/disk_scanner/partition/intel_partition_map.cpp +++ /dev/null @@ -1,476 +0,0 @@ -//---------------------------------------------------------------------- -// This software is part of the OpenBeOS distribution and is covered -// by the OpenBeOS license. -//--------------------------------------------------------------------- -/*! - \file intel_partition_map.cpp - \brief Definitions for "intel" style partitions and implementation - of related classes. -*/ - -#include -#include -#include -#include - -#include - -#include "intel_partition_map.h" - -#define TRACE(x) ; -//#define TRACE(x) dprintf x - - -// partition_type -struct partition_type { - uint8 type; - char *name; -}; - -static const struct partition_type kPartitionTypes[] = { - // these entries must be sorted by type (currently not) - { 0x00, "empty" }, - { 0x01, "FAT 12-bit" }, - { 0x02, "Xenix root" }, - { 0x03, "Xenix user" }, - { 0x04, "FAT 16-bit (dos 3.0)" }, - { 0x05, "Extended Partition" }, - { 0x06, "FAT 16-bit (dos 3.31)" }, - { 0x07, "OS/2 IFS, Windows NT, Advanced Unix" }, - { 0x0b, "FAT 32-bit" }, - { 0x0c, "FAT 32-bit, LBA-mapped" }, - { 0x0d, "FAT 16-bit, LBA-mapped" }, - { 0x0f, "Extended Partition, LBA-mapped" }, - { 0x42, "Windows 2000 marker (switches to a proprietary partition table)" }, - { 0x4d, "QNX 4" }, - { 0x4e, "QNX 4 2nd part" }, - { 0x4f, "QNX 4 3rd part" }, - { 0x78, "XOSL boot loader" }, - { 0x82, "Linux swapfile" }, - { 0x83, "Linux native" }, - { 0x85, "Linux extendend partition" }, - { 0xa5, "FreeBSD" }, - { 0xa6, "OpenBSD" }, - { 0xa7, "NextSTEP" }, - { 0xa8, "MacOS X" }, - { 0xa9, "NetBSD" }, - { 0xab, "MacOS X boot" }, - { 0xbe, "Solaris 8 boot" }, - { 0xeb, "BeOS" }, - { 0, NULL } -}; - -// partition_type_string -static -const char * -partition_type_string(uint8 type) -{ - int32 i; - for (i = 0; kPartitionTypes[i].name ; i++) - { - if (type == kPartitionTypes[i].type) - return kPartitionTypes[i].name; - } - return NULL; -} - -// get_partition_type_string -void -get_partition_type_string(uint8 type, char *buffer) -{ - if (buffer) { - if (const char *str = partition_type_string(type)) - strcpy(buffer, str); - else - sprintf(buffer, "Unrecognized Type 0x%x", type); - } -} - - -// Partition - -// constructor -Partition::Partition() - : fPTSOffset(0), - fOffset(0), - fSize(0), - fType(0), - fActive(false) -{ -} - -// constructor -Partition::Partition(const partition_descriptor *descriptor,off_t ptsOffset, - off_t baseOffset, int32 blockSize) - : fPTSOffset(0), - fOffset(0), - fSize(0), - fType(0), - fActive(false) -{ - SetTo(descriptor, ptsOffset, baseOffset, blockSize); -} - -// SetTo -void -Partition::SetTo(const partition_descriptor *descriptor, off_t ptsOffset, - off_t baseOffset, int32 blockSize) -{ -TRACE(("Partition::SetTo(): active: %x\n", descriptor->active)); - fPTSOffset = ptsOffset; - fOffset = baseOffset + (off_t)descriptor->start * blockSize; - fSize = (off_t)descriptor->size * blockSize; - fType = descriptor->type; - fActive = descriptor->active; - if (fSize == 0) - Unset(); -} - -// Unset -void -Partition::Unset() -{ - fPTSOffset = 0; - fOffset = 0; - fSize = 0; - fType = 0; - fActive = false; -} - -// CheckLocation -bool -Partition::CheckLocation(off_t sessionSize, int32 blockSize) const -{ - // offsets and size must be block aligned, PTS and partition must lie - // within the session - return (fPTSOffset % blockSize == 0 - && fOffset % blockSize == 0 - && fSize % blockSize == 0 - && fPTSOffset >= 0 && fPTSOffset < sessionSize - && fOffset >= 0 && fOffset + fSize <= sessionSize); -} - - -// PrimaryPartition - -// constructor -PrimaryPartition::PrimaryPartition() - : Partition(), - fHead(NULL), - fTail(NULL), - fLogicalPartitionCount(0) -{ -} - -// constructor -PrimaryPartition::PrimaryPartition(const partition_descriptor *descriptor, - off_t ptsOffset, int32 blockSize) - : Partition(), - fHead(NULL), - fTail(NULL), - fLogicalPartitionCount(0) -{ - SetTo(descriptor, ptsOffset, blockSize); -} - -// SetTo -void -PrimaryPartition::SetTo(const partition_descriptor *descriptor, - off_t ptsOffset, int32 blockSize) -{ - Unset(); - Partition::SetTo(descriptor, ptsOffset, 0, blockSize); -} - -// Unset -void -PrimaryPartition::Unset() -{ - while (LogicalPartition *partition = fHead) { - fHead = partition->Next(); - delete partition; - } - fHead = NULL; - fTail = NULL; - fLogicalPartitionCount = 0; - Partition::Unset(); -} - -// LogicalPartitionAt -LogicalPartition * -PrimaryPartition::LogicalPartitionAt(int32 index) const -{ - LogicalPartition *partition = NULL; - if (index >= 0 && index < fLogicalPartitionCount) { - for (partition = fHead; index > 0; index--) - partition = partition->Next(); - } - return partition; -} - -// AddLogicalPartition -void -PrimaryPartition::AddLogicalPartition(LogicalPartition *partition) -{ - if (partition) { - partition->SetPrimaryPartition(this); - if (fTail) { - fTail->SetNext(partition); - fTail = partition; - } else - fHead = fTail = partition; - partition->SetNext(NULL); - fLogicalPartitionCount++; - } -} - - -// LogicalPartition - -// constructor -LogicalPartition::LogicalPartition() - : Partition(), - fPrimary(NULL), - fNext(NULL) -{ -} - -// constructor -LogicalPartition::LogicalPartition(const partition_descriptor *descriptor, - off_t ptsOffset, int32 blockSize, - PrimaryPartition *primary) - : Partition(), - fPrimary(NULL), - fNext(NULL) -{ - SetTo(descriptor, ptsOffset, blockSize, primary); -} - -// SetTo -void -LogicalPartition::SetTo(const partition_descriptor *descriptor, - off_t ptsOffset, int32 blockSize, - PrimaryPartition *primary) -{ - Unset(); - if (descriptor && primary) { - off_t baseOffset = (descriptor->is_extended() ? primary->Offset() - : ptsOffset); - Partition::SetTo(descriptor, ptsOffset, baseOffset, blockSize); - fPrimary = primary; - } -} - -// Unset -void -LogicalPartition::Unset() -{ - fPrimary = NULL; - fNext = NULL; - Partition::Unset(); -} - - -// PartitionMap - -// constructor -PartitionMap::PartitionMap() -{ -} - -// destructor -PartitionMap::~PartitionMap() -{ -} - -// Unset -void -PartitionMap::Unset() -{ - for (int32 i = 0; i < 4; i++) - fPrimaries[i].Unset(); -} - -// PrimaryPartitionAt -PrimaryPartition * -PartitionMap::PrimaryPartitionAt(int32 index) -{ - PrimaryPartition *partition = NULL; - if (index >= 0 && index < 4) - partition = fPrimaries + index; - return partition; -} - -// PrimaryPartitionAt -const PrimaryPartition * -PartitionMap::PrimaryPartitionAt(int32 index) const -{ - const PrimaryPartition *partition = NULL; - if (index >= 0 && index < 4) - partition = fPrimaries + index; - return partition; -} - -// CountPartitions -int32 -PartitionMap::CountPartitions() const -{ - int32 count = 4; - for (int32 i = 0; i < 4; i++) - count += fPrimaries[i].CountLogicalPartitions(); - return count; -} - -// PartitionAt -Partition * -PartitionMap::PartitionAt(int32 index) -{ - Partition *partition = NULL; - int32 count = CountPartitions(); - if (index >= 0 && index < count) { - if (index < 4) - partition = fPrimaries + index; - else { - index -= 4; - int32 primary = 0; - while (index >= fPrimaries[primary].CountLogicalPartitions()) { - index -= fPrimaries[primary].CountLogicalPartitions(); - primary++; - } - partition = fPrimaries[primary].LogicalPartitionAt(index); - } - } - return partition; -} - -// PartitionAt -const Partition * -PartitionMap::PartitionAt(int32 index) const -{ - return const_cast(this)->PartitionAt(index); -} - -// cmp_partition_offset -static -int -cmp_partition_offset(const void *p1, const void *p2) -{ - const Partition *partition1 = *(const Partition**)p1; - const Partition *partition2 = *(const Partition**)p2; - if (partition1->Offset() < partition2->Offset()) - return -1; - else if (partition1->Offset() > partition2->Offset()) - return 1; - return 0; -} - -// cmp_offset -static -int -cmp_offset(const void *o1, const void *o2) -{ - off_t offset1 = *static_cast(o1); - off_t offset2 = *static_cast(o2); - if (offset1 < offset2) - return -1; - else if (offset1 > offset2) - return 1; - return 0; -} - -// is_inside_partitions -static -bool -is_inside_partitions(off_t location, const Partition **partitions, int32 count) -{ - bool result = false; - if (count > 0) { - // binary search - int32 lower = 0; - int32 upper = count - 1; - while (lower < upper) { - int32 mid = (lower + upper) / 2; - const Partition *midPartition = partitions[mid]; - if (location >= midPartition->Offset() + midPartition->Size()) - lower = mid + 1; - else - upper = mid; - } - const Partition *partition = partitions[lower]; - result = (location >= partition->Offset() && - location < partition->Offset() + partition->Size()); - } - return result; -} - -// Check -bool -PartitionMap::Check(off_t sessionSize, int32 blockSize) const -{ - int32 partitionCount = CountPartitions(); - // 1. check partition locations - for (int32 i = 0; i < partitionCount; i++) { - if (!PartitionAt(i)->CheckLocation(sessionSize, blockSize)) - return false; - } - // 2. check overlapping of partitions and location of PTSs - bool result = true; - const Partition **byOffset = new(nothrow) const Partition*[partitionCount]; - off_t *ptsOffsets = new(nothrow) off_t[partitionCount - 3]; - if (byOffset && ptsOffsets) { - // fill the arrays - int32 byOffsetCount = 0; - int32 ptsOffsetCount = 1; // primary PTS - ptsOffsets[0] = 0; // - for (int32 i = 0; i < partitionCount; i++) { - const Partition *partition = PartitionAt(i); - if (!partition->IsExtended()) - byOffset[byOffsetCount++] = partition; - // add only logical partition PTS locations - if (i >= 4) - ptsOffsets[ptsOffsetCount++] = partition->PTSOffset(); - } - // sort the arrays - qsort(byOffset, byOffsetCount, sizeof(const Partition*), - cmp_partition_offset); - qsort(ptsOffsets, ptsOffsetCount, sizeof(off_t), cmp_offset); - // check for overlappings - off_t nextOffset = 0; - for (int32 i = 0; i < byOffsetCount; i++) { - const Partition *partition = byOffset[i]; - if (partition->Offset() < nextOffset) { - TRACE(("intel: PartitionMap::Check(): overlapping partitions!" - "\n")); - result = false; - break; - } - nextOffset = partition->Offset() + partition->Size(); - } - // check uniqueness of PTS offsets and whether they lie outside of the - // non-extended partitions - if (result) { - for (int32 i = 0; i < ptsOffsetCount; i++) { - if (i > 0 && ptsOffsets[i] == ptsOffsets[i - 1]) { - TRACE(("intel: PartitionMap::Check(): same PTS for " - "different extended partitions!\n")); - result = false; - break; - } else if (is_inside_partitions(ptsOffsets[i], byOffset, - byOffsetCount)) { - TRACE(("intel: PartitionMap::Check(): a PTS lies " - "inside a non-extended partition!\n")); - result = false; - break; - } - } - } - } else - result = false; // no memory: assume failure - // cleanup - if (byOffset) - delete[] byOffset; - if (ptsOffsets) - delete[] ptsOffsets; - return result; -} - diff --git a/src/add-ons/kernel/disk_scanner/partition/intel_partition_map.h b/src/add-ons/kernel/disk_scanner/partition/intel_partition_map.h deleted file mode 100644 index 220e873ce9..0000000000 --- a/src/add-ons/kernel/disk_scanner/partition/intel_partition_map.h +++ /dev/null @@ -1,169 +0,0 @@ -//---------------------------------------------------------------------- -// This software is part of the OpenBeOS distribution and is covered -// by the OpenBeOS license. -//--------------------------------------------------------------------- -/*! - \file intel_partition_map.h - \brief Definitions for "intel" style partitions and interface definitions - for related classes. -*/ - -#ifndef _INTEL_PARTITION_MAP_H -#define _INTEL_PARTITION_MAP_H - -#include - -// is_empty_type -static inline -bool -is_empty_type(uint8 type) -{ - return (type == 0x00); -} - -// is_extended_type -static inline -bool -is_extended_type(uint8 type) -{ - return (type == 0x05 || type == 0x0f || type == 0x85); -} - -void get_partition_type_string(uint8 type, char *buffer); - -// chs -struct chs { - uint8 cylinder; - uint16 head_sector; // head[15:10], sector[9:0] -} _PACKED; - -// partition_descriptor -struct partition_descriptor { - uint8 active; - chs begin; - uint8 type; - chs end; - uint32 start; - uint32 size; - - bool is_empty() const { return is_empty_type(type); } - bool is_extended() const { return is_extended_type(type); } -} _PACKED; - -// partition_table_sector -struct partition_table_sector { - char pad1[446]; - partition_descriptor table[4]; - uint16 signature; -} _PACKED; - -static const uint16 kPartitionTableSectorSignature = 0xaa55; - -class Partition; -class PrimaryPartition; -class LogicalPartition; - -// Partition -class Partition { -public: - Partition(); - Partition(const partition_descriptor *descriptor, off_t ptsOffset, - off_t baseOffset, int32 blockSize); - - void SetTo(const partition_descriptor *descriptor, off_t ptsOffset, - off_t baseOffset, int32 blockSize); - void Unset(); - - bool IsEmpty() const { return is_empty_type(fType); } - bool IsExtended() const { return is_extended_type(fType); } - - off_t PTSOffset() const { return fPTSOffset; } - off_t Offset() const { return fOffset; } - off_t Size() const { return fSize; } - uint8 Type() const { return fType; } - bool Active() const { return fActive; } - void GetTypeString(char *buffer) const - { get_partition_type_string(fType, buffer); } - - void SetPTSOffset(off_t offset) { fPTSOffset = offset; } - void SetOffset(off_t offset) { fOffset = offset; } - void SetSize(off_t size) { fSize = size; } - void SetType(uint8 type) { fType = type; } - void SetActive(bool active) { fActive = active; } - - bool CheckLocation(off_t sessionSize, int32 blockSize) const; - -private: - off_t fPTSOffset; - off_t fOffset; // relative to the start of the session - off_t fSize; - uint8 fType; - bool fActive; -}; - -// PrimaryPartition -class PrimaryPartition : public Partition { -public: - PrimaryPartition(); - PrimaryPartition(const partition_descriptor *descriptor, off_t ptsOffset, - int32 blockSize); - - void SetTo(const partition_descriptor *descriptor, off_t ptsOffset, - int32 blockSize); - void Unset(); - - // only if extended - int32 CountLogicalPartitions() const { return fLogicalPartitionCount; } - LogicalPartition *LogicalPartitionAt(int32 index) const; - void AddLogicalPartition(LogicalPartition *partition); - -private: - LogicalPartition *fHead; - LogicalPartition *fTail; - int32 fLogicalPartitionCount; -}; - -// LogicalPartition -class LogicalPartition : public Partition { -public: - LogicalPartition(); - LogicalPartition(const partition_descriptor *descriptor, off_t ptsOffset, - int32 blockSize, PrimaryPartition *primary); - - void SetTo(const partition_descriptor *descriptor, off_t ptsOffset, - int32 blockSize, PrimaryPartition *primary); - void Unset(); - - void SetPrimaryPartition(PrimaryPartition *primary) { fPrimary = primary; } - PrimaryPartition *GetPrimaryPartition() const { return fPrimary; } - - void SetNext(LogicalPartition *next) { fNext = next; } - LogicalPartition *Next() const { return fNext; } - -private: - PrimaryPartition *fPrimary; - LogicalPartition *fNext; -}; - -// PartitionMap -class PartitionMap { -public: - PartitionMap(); - ~PartitionMap(); - - void Unset(); - - PrimaryPartition *PrimaryPartitionAt(int32 index); - const PrimaryPartition *PrimaryPartitionAt(int32 index) const; - - int32 CountPartitions() const; - Partition *PartitionAt(int32 index); - const Partition *PartitionAt(int32 index) const; - - bool Check(off_t sessionSize, int32 blockSize) const; - -private: - PrimaryPartition fPrimaries[4]; -}; - -#endif // _INTEL_PARTITION_MAP_H diff --git a/src/add-ons/kernel/disk_scanner/session/Jamfile b/src/add-ons/kernel/disk_scanner/session/Jamfile deleted file mode 100644 index f362cf5b45..0000000000 --- a/src/add-ons/kernel/disk_scanner/session/Jamfile +++ /dev/null @@ -1,8 +0,0 @@ -SubDir HAIKU_TOP src add-ons kernel disk_scanner session ; - -UsePrivateHeaders $(DOT) ; - -#KernelAddon intel : kernel disk_scanner session : -# cdrom.cpp -#; - diff --git a/src/add-ons/kernel/disk_scanner/session/cdrom.cpp b/src/add-ons/kernel/disk_scanner/session/cdrom.cpp deleted file mode 100644 index 6015eeb75e..0000000000 --- a/src/add-ons/kernel/disk_scanner/session/cdrom.cpp +++ /dev/null @@ -1,1127 +0,0 @@ -//---------------------------------------------------------------------- -// This software is part of the OpenBeOS distribution and is covered -// by the OpenBeOS license. -//--------------------------------------------------------------------- -/*! - \file cdrom.cpp - disk_scanner session module for SCSI/ATAPI cdrom drives - - The protocols followed in this module are based on information - taken from the "SCSI-3 Multimedia Commands" draft, revision 10A. - - The SCSI command of interest is "READ TOC/PMA/ATIP", command - number \c 0x43. - - The format of interest for said command is "Full TOC", format - number \c 0x2. -*/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -extern "C" { - #include -} - -//#define DBG(y) (y) -#define DBG(y) - -#define TRACE(x) DBG(dprintf x) - -// These macros turn on or off extensive and generally unnecessary -// debugging output regarding table of contents parsing -#define WARN(x) (dprintf x) -//#define WARN(x) - -#define CDROM_SESSION_MODULE_NAME "disk_scanner/session/cdrom/v1" -static const char *kModuleDebugName = "session/cdrom"; - -/*! \brief raw_device_command flags - - This is the only combination of flags that works on my system. :-) -*/ -const uint8 kScsiFlags = B_RAW_DEVICE_DATA_IN - | B_RAW_DEVICE_REPORT_RESIDUAL - | B_RAW_DEVICE_SHORT_READ_VALID; - -/*! \brief Timeout value used when making scsi commands - - I'm honestly not sure what value to use here. It's currently - 1 second because I got sick of waiting for the timeout while - figuring out how to get the commands to work. -*/ -const uint32 kScsiTimeout = 1000000; - -//! SCSI "READ TOC/PMA/ATIP" command struct -typedef struct { - uint8 command; //!< 0x43 == READ TOC/PMA/ATIP - uint8 reserved2:1, - msf:1, //!< addressing format: 0 == LBA, 1 == MSF; try lba first, then msf if that fails - reserved1:3, - reserved0:3; - uint8 format:4, //!< sub-command: 0x0 == "TOC", 0x1 == "Session Info", 0x2 == "Full TOC", ... - reserved3:4; - uint8 reserved4; - uint8 reserved5; - uint8 reserved6; - uint8 number; //!< track/session number - uint16 length; //!< length of data buffer passed in raw_device_command.data; BIG-ENDIAN!!! - uint8 control; //!< control codes; 0x0 should be fine -} __attribute__((packed)) scsi_table_of_contents_command; - -// Some of the possible "READ TOC/PMA/ATIP" formats -const uint8 kTableOfContentsFormat = 0x00; -const uint8 kSessionFormat = 0x01; -const uint8 kFullTableOfContentsFormat = 0x10; //!< "READ TOC/PMA/ATIP" format of interest - -/*! \brief Minutes:Seconds:Frames format address - - - Each msf frame corresponds to one logical block. - - Each msf second corresponds to 75 msf frames - - Each msf minute corresponds to 60 msf seconds - - Logical block 0 is at msf address 00:02:00 -*/ -typedef struct { - uint8 reserved; - uint8 minutes; - uint8 seconds; - uint8 frames; -} msf_address; - -#define CDROM_FRAMES_PER_SECOND (75) -#define CDROM_FRAMES_PER_MINUTE (CDROM_FRAMES_PER_SECOND*60) - -/*! \brief Returns an initialized \c msf_address struct -*/ -static -inline -msf_address -make_msf_address(uint8 minutes, uint8 seconds, uint8 frames) -{ - msf_address result; - result.reserved = 0; - result.minutes = minutes; - result.seconds = seconds; - result.frames = frames; - return result; -} - -/*! \brief Converts the given msf address to lba format -*/ -static -inline -uint32 -msf_to_lba(msf_address msf) -{ - return (CDROM_FRAMES_PER_MINUTE * msf.minutes) - + (CDROM_FRAMES_PER_SECOND * msf.seconds) - + msf.frames - 150; -} - -/*! \brief Header for data returned by all formats of SCSI - "READ TOC/PMA/ATIP" command. -*/ -typedef struct { - uint16 length; //!< Length of data in reply (not including these 2 bytes); BIG ENDIAN!!! - uint8 first; //!< First track/session in reply - uint8 last; //!< Last track/session in reply -} cdrom_table_of_contents_header; - -/*! \brief Type of entries returned by "READ TOC/PMA/ATIP" when called with format - \c kTableOfContentsFormat == 0x00 -*/ -typedef struct { - uint8 reserved0; - uint8 control:4, - adr:4; - uint8 track_number; - uint8 reserved1; - uint32 address; -} cdrom_table_of_contents_entry; - -/*! \brief Type of entries returned by "READ TOC/PMA/ATIP" when called with format - \c kFullTableOfContentsFormat == 0x10 -*/ -typedef struct { - uint8 session; - uint8 control:4, - adr:4; - uint8 tno; - uint8 point; - uint8 minutes; - uint8 seconds; - uint8 frames; - uint8 zero; - uint8 pminutes; - uint8 pseconds; - uint8 pframes; -} cdrom_full_table_of_contents_entry; - -/*! \brief Bitflags for control entries -*/ -enum { - kControlDataTrack = 0x4, - kControlCopyPermitted = 0x2, -}; - -extern "C" { - static status_t std_ops(int32 op, ...); - static bool cdrom_session_identify(int deviceFD, off_t deviceSize, int32 blockSize); - static status_t cdrom_session_get_nth_info(int deviceFD, int32 index, off_t deviceSize, - int32 blockSize, struct session_info *sessionInfo); -} - -/*! \brief An item that can be stored in a List object. -*/ -struct list_item { -public: - list_item(uint32 index, list_item *next = NULL) - : index(index) - , next(next) - { - }; - - int32 index; - list_item *next; -}; - -/*! \brief A simple, singly linked list. -*/ -class List { -public: - List(); - ~List(); - - list_item* Find(int32 index) const; - void Add(list_item *item); - void Clear(); - void SortAndRemoveDuplicates(); - - list_item* First() const; - list_item* Last() const; - -private: - list_item *fFirst; - list_item *fLast; -}; - -/*! \brief Keeps track of track information. - - Can be stored in a List object. -*/ -struct track : public list_item { -public: - track(uint32 index, off_t startLBA, uint8 control, uint8 adr, track *next = NULL) - : list_item(index, next) - , start_lba(startLBA) - , control(control) - , adr(adr) - { - } - - off_t start_lba; - uint8 control; //!< only used to give what are probably useless warnings - uint8 adr; //!< only used to give what are probably useless warnings -}; - -/*! \brief Keeps track of session information. - - Can be stored in a List object. -*/ -struct session : public list_item { -public: - session(uint32 index, session *next = NULL); - - bool first_track_hint_is_set(); - bool last_track_hint_is_set(); - bool end_lba_is_set(); // also implies control and adr are set - - bool is_audio(); - - int8 first_track_hint; - int8 last_track_hint; - int8 control; - int8 adr; - off_t end_lba; - - List track_list; -}; - -/*! \brief A class that encapsulates a complete, parsed, and error - checked table of contents for a CD-ROM. -*/ -class Disc { -public: - Disc(cdrom_full_table_of_contents_entry entries[], uint32 count); - - status_t InitCheck(); - status_t GetSessionInfo(int32 index, int32 blockSize, session_info *sessionInfo); - - void Dump(); - -private: - status_t ParseTableOfContents(cdrom_full_table_of_contents_entry entries[], - uint32 count); - void SortAndRemoveDuplicates(); - status_t CheckForErrorsAndWarnings(); - - status_t fInitStatus; - List fSessionList; -}; - -//------------------------------------------------------------------------------ -// List -//------------------------------------------------------------------------------ - -/*! \brief Creates an empty list. -*/ -List::List() - : fFirst(NULL) - , fLast(NULL) -{ -} - -List::~List() -{ - Clear(); -} - -/*! \brief Returns the ListItem with the given index, or NULL if not found. -*/ -list_item* -List::Find(int32 index) const -{ -// TRACE(("%s: List::Find(%ld)\n", kModuleDebugName, index)); - list_item *item = fFirst; - while (item && item->index != index) { - item = item->next; - } - return item; -} - -/*! \brief Adds the given item to the end of the list. - - \param item The item to add (may not be NULL) -*/ -void -List::Add(list_item *item) -{ -// TRACE(("%s: List::Add(%p)\n", kModuleDebugName, item)); - if (item) { - item->next = NULL; - if (fLast) { - fLast->next = item; - fLast = item; - } else { - fFirst = fLast = item; - } - } else { - TRACE(("%s: List::Add(): NULL item parameter\n", kModuleDebugName)); - } -} - -/*! \brief Clears the list. -*/ -void -List::Clear() -{ - list_item *item = fFirst; - while (item) { - list_item *next = item->next; - delete item; - item = next; - } - fFirst = fLast = NULL; -} - -/*! \brief Bubble sorts the list by index, removing any duplicates - (the first instance is kept). - - \todo I believe duplicate removal is actually unnecessary, but I need to verify that. -*/ -void -List::SortAndRemoveDuplicates() -{ - bool sorted = false; - while (!sorted) { - sorted = true; - - list_item *prev = NULL; - list_item *item = fFirst; - list_item *next = NULL; - while (item && item->next) { - next = item->next; -// dprintf("List::Sort: %ld -> %ld\n", item->index, next->index); - if (item->index > next->index) { - sorted = false; - - // Keep fLast up to date - if (next == fLast) - fLast = item; - - // Swap - if (prev) { - // item is not fFirst - prev->next = next; - item->next = next->next; - next->next = item; - } else { - // item must be fFirst - fFirst = next; - item->next = next->next; - next->next = item; - } - } else if (item->index == next->index) { - // Duplicate indicies - TRACE(("%s: List::SortAndRemoveDuplicates: duplicate indicies found (#%ld); " - "keeping first instance\n", kModuleDebugName, item->index)); - item->next = next->next; - delete next; - next = item->next; - continue; - } - prev = item; - item = next; - } - } -} - -/*! \brief Returns the first item in the list, or NULL if empty -*/ -list_item* -List::First() const { - return fFirst; -} - -/*! \brief Returns the last item in the list, or NULL if empty -*/ -list_item* -List::Last() const { - return fLast; -} - -//------------------------------------------------------------------------------ -// session -//------------------------------------------------------------------------------ - -/*! \brief Creates an unitialized session object -*/ -session::session(uint32 index, session *next = NULL) - : list_item(index, next) - , first_track_hint(-1) - , last_track_hint(-1) - , control(-1) - , adr(-1) - , end_lba(0) -{ -} - -/*! \brief Returns true if the \a first_track_hint member has not been - set to a legal value yet. -*/ -bool -session::first_track_hint_is_set() -{ - return 1 <= first_track_hint && first_track_hint <= 99; -} - -/*! \brief Returns true if the \a last_track_hint member has not been - set to a legal value yet. -*/ -bool -session::last_track_hint_is_set() -{ - return 1 <= last_track_hint && last_track_hint <= 99; -} - -/*! \brief Returns true if the \a end_lba member has not been - set to a legal value yet. - - The result of this function also signals that the \a control - and \a adr members have or have not been set, since they are - set at the same time as \a end_lba. -*/ -bool -session::end_lba_is_set() -{ - return end_lba > 0; -} - -/*! \brief Returns true if the session is flagged as being audio. - - If the \c control value for the session has not been set, returns - false. -*/ -bool -session::is_audio() -{ - return end_lba_is_set() && !(control & kControlDataTrack); -} - -//------------------------------------------------------------------------------ -// Disc -//------------------------------------------------------------------------------ - -/*! \brief Creates a new Disc object by parsing the given table of contents - entries and checking the resultant data structure for errors and - warnings. - - If successful, subsequent calls to InitCheck() will return \c B_OK, - elsewise they will return an error code. -*/ -Disc::Disc(cdrom_full_table_of_contents_entry entries[], uint32 count) - : fInitStatus(B_NO_INIT) -{ - TRACE(("%s: Disc::Disc(%p, %ld)\n", kModuleDebugName, entries, count)); - status_t error = ParseTableOfContents(entries, count); - Dump(); - if (!error) { - SortAndRemoveDuplicates(); - error = CheckForErrorsAndWarnings(); - } - fInitStatus = error; - - - fInitStatus = B_OK; -} - -/*! \brief Returns \c B_OK if the object was successfully initialized, or - an error code if not. -*/ -status_t -Disc::InitCheck() -{ - return fInitStatus; -} - -/*! \brief Stores the info for the given session (using 0 based indicies) in the - struct pointed to by \a sessionInfo. - - Returns \c B_ENTRY_NOT_FOUND if no such session exists. -*/ -status_t -Disc::GetSessionInfo(int32 index, int32 blockSize, session_info *sessionInfo) -{ - TRACE(("%s: Disc::GetSessionInfo(%ld, %ld, %p)\n", kModuleDebugName, - index, blockSize, sessionInfo)); - int32 counter = -1; - for (session *session = (struct session*)fSessionList.First(); - session; - session = (struct session*)session->next) - { - if (session->is_audio()) { - counter++; // only one session per audio session - if (counter == index) { - // Found an audio session. Take the start of the first - // track with the end of session. - track *track = (struct track*)session->track_list.First(); - if (track) { - TRACE(("%s: found session #%ld info (audio session)\n", kModuleDebugName, index)); - - off_t start_lba = track->start_lba; - off_t end_lba = session->end_lba; - - sessionInfo->logical_block_size = blockSize; - sessionInfo->offset = start_lba * blockSize; - sessionInfo->size = (end_lba - start_lba) * blockSize; - sessionInfo->index = index; - sessionInfo->flags = 0; - - return B_OK; - } else { - TRACE(("%s: Disc::GetSessionInfo: session #%ld is an audio " - "session with no tracks\n", kModuleDebugName, index)); - return B_ENTRY_NOT_FOUND; - } - } - } else { - for (track *track = (struct track*)session->track_list.First(); - track; - track = (struct track*)track->next) - { - counter++; - if (counter == index) { - TRACE(("%s: found session #%ld info (data session)\n", kModuleDebugName, index)); - - off_t start_lba = track->start_lba; - off_t end_lba = track->next - ? ((struct track*)track->next)->start_lba - : session->end_lba; - - sessionInfo->logical_block_size = blockSize; - sessionInfo->offset = start_lba * blockSize; - sessionInfo->size = (end_lba - start_lba) * blockSize; - sessionInfo->index = index; - sessionInfo->flags = B_DATA_SESSION; - - return B_OK; - } - } - } - } - - return B_ENTRY_NOT_FOUND; -} - -/*! \brief Dumps a printout of the disc using TRACE. -*/ -void -Disc::Dump() -{ - TRACE(("%s: Disc dump:\n", kModuleDebugName)); - session *session = (struct session*)fSessionList.First(); - while (session) { - TRACE(("session %ld:\n", session->index)); - TRACE((" first track hint: %d\n", session->first_track_hint)); - TRACE((" last track hint: %d\n", session->last_track_hint)); - TRACE((" end_lba: %lld\n", session->end_lba)); - TRACE((" control: %d (%s session, copy %s)\n", session->control, - (session->control & kControlDataTrack ? "data" : "audio"), - (session->control & kControlCopyPermitted ? "permitted" : "prohibited"))); - TRACE((" adr: %d\n", session->adr)); - track *track = (struct track*)session->track_list.First(); - while (track) { - TRACE((" track %ld:\n", track->index)); - TRACE((" start_lba: %lld\n", track->start_lba)); - track = (struct track*)track->next; - } - session = (struct session*)session->next; - } -} - -/*! \brief Reads through the given table of contents data and creates an unsorted, - unverified (i.e. non-error-checked) list of sessions and tracks. -*/ -status_t -Disc::ParseTableOfContents(cdrom_full_table_of_contents_entry entries[], uint32 count) -{ - TRACE(("%s: Disc::ParseTableOfContents(%p, %ld)\n", kModuleDebugName, entries, count)); - for (uint32 i = 0; i < count; i++) { - // Find or create the appropriate session - uint8 session_index = entries[i].session; - session *session = (struct session*)fSessionList.Find(session_index); - if (!session) { - session = new struct session(session_index); - if (!session) { - return B_NO_MEMORY; - } else { - fSessionList.Add(session); - } - } - - uint8 point = entries[i].point; - - switch (point) { - - // first track hint - case 0xA0: - if (!session->first_track_hint_is_set()) { - int8 first_track_hint = entries[i].pminutes; - if (1 <= first_track_hint && first_track_hint <= 99) { - session->first_track_hint = first_track_hint; - } else { - WARN(("%s: warning: illegal first track hint %d found " - "for session %d\n", kModuleDebugName, first_track_hint, - session_index)); - } - } else { - WARN(("%s: warning: duplicated first track hint values found for" - "session %d; using first value encountered: %d", kModuleDebugName, - session_index, session->first_track_hint)); - } - break; - - // last track hint - case 0xA1: - if (!session->last_track_hint_is_set()) { - int8 last_track_hint = entries[i].pminutes; - if (1 <= last_track_hint && last_track_hint <= 99) { - session->last_track_hint = last_track_hint; - } else { - WARN(("%s: warning: illegal last track hint %d found " - "for session %d\n", kModuleDebugName, last_track_hint, - session_index)); - } - } else { - WARN(("%s: warning: duplicate last track hint values found for" - "session %d; using first value encountered: %d", kModuleDebugName, - session_index, session->last_track_hint)); - } - break; - - // end of session address - case 0xA2: - if (!session->end_lba_is_set()) { - off_t end_lba = msf_to_lba(make_msf_address( - entries[i].pminutes, - entries[i].pseconds, - entries[i].pframes)); - if (end_lba > 0) { - session->end_lba = end_lba; - // We also grab the session's control and adr values - // from this entry - session->control = entries[i].control; - session->adr = entries[i].adr; - } else { - WARN(("%s: warning: illegal end lba %lld found " - "for session %d\n", kModuleDebugName, end_lba, - session_index)); - } - } else { - WARN(("%s: warning: duplicate end lba values found for" - "session %d; using first value encountered: %lld", - kModuleDebugName, session_index, session->end_lba)); - } - break; - - // Valid, but uninteresting, points - case 0xB0: - case 0xB1: - case 0xB2: - case 0xB3: - case 0xB4: - case 0xC0: - case 0xC1: - break; - - default: - // Anything else had better be a valid track number, - // or it's an invalid point - if (1 <= point && point <= 99) { - // Create and add the track. We'll weed out any duplicates later. - uint8 track_index = point; - off_t start_lba = msf_to_lba(make_msf_address( - entries[i].pminutes, - entries[i].pseconds, - entries[i].pframes)); - // The control and adr values grabbed here are only used later on - // to signal a warning if they don't match the corresponding values - // of the parent session. - track *track = new(nothrow) struct track(track_index, start_lba, - entries[i].control, entries[i].adr); - if (!track) { - return B_NO_MEMORY; - } else { - session->track_list.Add(track); - } - } else { - WARN(("%s: warning: illegal point 0x%2x found in table of contents\n", - kModuleDebugName, entries[i].point)); - } - break; - } - } - return B_OK; -} - -/*! \brief Bubble sorts the session list and each session's track lists, - removing all but the first of any duplicates (by index) found along - the way. -*/ -void -Disc::SortAndRemoveDuplicates() -{ - fSessionList.SortAndRemoveDuplicates(); - session *session = (struct session*)fSessionList.First(); - while (session) { - session->track_list.SortAndRemoveDuplicates(); - session = (struct session*)session->next; - } -} - -/* \brief Checks the sessions and tracks for any anomalies. - - Errors will return an error code, warnings will return B_OK. - Both will print a notification using TRACE. - - Anomalies that result in errors: - - Sessions with no end_lba set - - Sessions with no tracks - - Anomalies that result in warnings: - - Inaccurate first_track_hint and/or last_track_hint values - - Sequences of sessions or tracks that do not start at 1, - do not end at or before 99, or are not strictly ascending. - (all tracks are checked as a single sequence, since track - numbering does not restart with each session). - - Tracks with different control and/or adr values than their - parent session - - Anomalies that are currently *not* checked: - - First Track Hint or Last Track Hint control and adr values - that do not match the values for their session; Ingo's copy - of the BeOS R5 CD is like this, but I don't believe it's - a matter we need to worry about. This could certainly be - changed in the future if needed. -*/ -status_t -Disc::CheckForErrorsAndWarnings() { - int32 lastSessionIndex = 0; - int32 lastTrackIndex = 0; - - for (session *session = (struct session*)fSessionList.First(); - session; - session = (struct session*)session->next) - { - // Check for errors - //----------------- - - // missing end lba - if (!session->end_lba_is_set()) { - TRACE(("%s: Disc::CheckForErrorsAndWarnings: error: no end of session " - "address for session #%ld\n", kModuleDebugName, session->index)); - return B_ERROR; - } - - // empty track list - track *track = (struct track*)session->track_list.First(); - if (!track) { - TRACE(("%s: Disc::CheckForErrorsAndWarnings: error: session #%ld has no" - "tracks\n", kModuleDebugName, session->index)); - return B_ERROR; - } - - // Check for warnings - //------------------- - - // incorrect first track hint - if (session->first_track_hint_is_set() - && session->first_track_hint != track->index) - { - TRACE(("%s: Disc::CheckForErrorsAndWarnings: warning: session #%ld: first " - "track hint (%d) doesn't match actual first track (%ld)\n", kModuleDebugName, - session->index, session->first_track_hint, track->index)); - } - - // incorrect last track hint - struct track *last = (struct track*)session->track_list.Last(); - if (session->last_track_hint_is_set() && last - && session->last_track_hint != last->index) - { - TRACE(("%s: Disc::CheckForErrorsAndWarnings: warning: session #%ld: last " - "track hint (%d) doesn't match actual last track (%ld)\n", kModuleDebugName, - session->index, session->last_track_hint, last->index)); - } - - // invalid session sequence - if (lastSessionIndex+1 != session->index) { - TRACE(("%s: Disc::CheckForErrorsAndWarnings: warning: index for session #%ld " - "is out of sequence (should have been #%ld)\n", kModuleDebugName, - session->index, lastSessionIndex)); - } - lastSessionIndex = session->index; - - for ( ; track; track = (struct track*)track->next) { - // invalid track sequence - if (lastTrackIndex+1 != track->index) { - TRACE(("%s: Disc::CheckForErrorsAndWarnings: warning: index for track #%ld " - "is out of sequence (should have been #%ld)\n", kModuleDebugName, - track->index, lastTrackIndex)); - } - lastTrackIndex = track->index; - - // mismatched control - if (track->control != session->control) { - TRACE(("%s: Disc::CheckForErrorsAndWarnings: warning: control for track #%ld " - "(%d, %s track, copy %s) does not match control for parent session #%ld " - "(%d, %s session, copy %s)\n", kModuleDebugName, track->index, track->control, - (track->control & kControlDataTrack ? "data" : "audio"), - (track->control & kControlCopyPermitted ? "permitted" : "prohibited"), - session->index, session->control, - (session->control & kControlDataTrack ? "data" : "audio"), - (session->control & kControlCopyPermitted ? "permitted" : "prohibited"))); - } - - // mismatched adr - if (track->adr != session->adr) { - TRACE(("%s: Disc::CheckForErrorsAndWarnings: warning: adr for track #%ld " - "(adr = %d) does not match adr for parent session #%ld (adr = %d)\n", kModuleDebugName, - track->index, track->adr, session->index, session->adr)); - } - } - } - - return B_OK; -} - -//------------------------------------------------------------------------------ -// C functions -//------------------------------------------------------------------------------ - -// std_ops -static -status_t -std_ops(int32 op, ...) -{ - TRACE(("%s: std_ops(0x%lx)\n", kModuleDebugName, op)); - switch(op) { - case B_MODULE_INIT: - case B_MODULE_UNINIT: - return B_OK; - } - return B_ERROR; -} - -/* -static -void -dump_scsi_command(raw_device_command *cmd) { - int i; - uint j; - scsi_table_of_contents_command *scsi_command = (scsi_table_of_contents_command*)(&(cmd->command)); - - for (i = 0; i < cmd->command_length; i++) - TRACE(("%.2x,", cmd->command[i])); - TRACE(("\n")); - - TRACE(("raw_device_command:\n")); - TRACE((" command:\n")); - TRACE((" command = %d (0x%.2x)\n", scsi_command->command, scsi_command->command)); - TRACE((" msf = %d\n", scsi_command->msf)); - TRACE((" format = %d (0x%.2x)\n", scsi_command->format, scsi_command->format)); - TRACE((" number = %d\n", scsi_command->number)); - TRACE((" length = %d\n", B_BENDIAN_TO_HOST_INT16(scsi_command->length))); - TRACE((" control = %d\n", scsi_command->control)); - TRACE((" command_length = %d\n", cmd->command_length)); - TRACE((" flags = %d\n", cmd->flags)); - TRACE((" scsi_status = 0x%x\n", cmd->scsi_status)); - TRACE((" cam_status = 0x%x\n", cmd->cam_status)); - TRACE((" data = %p\n", cmd->data)); - TRACE((" data_length = %ld\n", cmd->data_length)); - TRACE((" sense_data = %p\n", cmd->sense_data)); - TRACE((" sense_data_length = %ld\n", cmd->sense_data_length)); - TRACE((" timeout = %lld\n", cmd->timeout)); - TRACE(("data dump:\n")); - for (j = 0; j < 2048; j++) {//cmd->data_length; j++) { - uchar c = ((uchar*)cmd->data)[j]; - - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9')) - TRACE(("\\%c,", c)); - else - TRACE(("%.2x,", c)); - } - TRACE(("\n")); - TRACE(("sense_data dump:\n")); - for (j = 0; j < cmd->sense_data_length; j++) { - uchar c = ((uchar*)cmd->sense_data)[j]; - if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9')) - TRACE(("%c", c)); - else if (c == 0) - TRACE(("_")); - else - TRACE(("-")); - } - TRACE(("\n")); -} -*/ - -static -void -dump_full_table_of_contents(uchar *data, uint16 data_length) -{ - cdrom_table_of_contents_header *header; - cdrom_full_table_of_contents_entry *entries; - int i, count; - int header_length; - - header = (cdrom_table_of_contents_header*)data; - entries = (cdrom_full_table_of_contents_entry*)(data+4); - header_length = B_BENDIAN_TO_HOST_INT16(header->length); - if (data_length < header_length) { - TRACE(("dump_full_table_of_contents: warning, data buffer not large enough (%d < %d)\n", - data_length, header_length)); - header_length = data_length; - } - - TRACE(("%s: table of contents dump:\n", kModuleDebugName)); - TRACE(("--------------------------------------------------\n")); - TRACE(("header:\n")); - TRACE((" length = %d\n", header_length)); - TRACE((" first = %d\n", header->first)); - TRACE((" last = %d\n", header->last)); - - count = (header_length-2) / sizeof(cdrom_full_table_of_contents_entry); - TRACE(("\n")); - TRACE(("entry count = %d\n", count)); - - for (i = 0; i < count; i++) { - TRACE(("\n")); - TRACE(("entry #%d:\n", i)); - TRACE((" session = %d\n", entries[i].session)); - TRACE((" adr = %d\n", entries[i].adr)); - TRACE((" control = %d (%s track, copy %s)\n", entries[i].control, - (entries[i].control & kControlDataTrack ? "data" : "audio"), - (entries[i].control & kControlCopyPermitted ? "permitted" : "prohibited"))); - TRACE((" tno = %d\n", entries[i].tno)); - TRACE((" point = %d (0x%.2x)\n", entries[i].point, entries[i].point)); - TRACE((" minutes = %d\n", entries[i].minutes)); - TRACE((" frames = %d\n", entries[i].seconds)); - TRACE((" seconds = %d\n", entries[i].frames)); - TRACE((" zero = %d\n", entries[i].zero)); - TRACE((" pminutes = %d\n", entries[i].pminutes)); - TRACE((" pseconds = %d\n", entries[i].pseconds)); - TRACE((" pframes = %d\n", entries[i].pframes)); - TRACE((" lba = %ld\n", msf_to_lba(make_msf_address(entries[i].pminutes, - entries[i].pseconds, entries[i].pframes)))); - } - TRACE(("--------------------------------------------------\n")); -} - -// read_table_of_contents -static -status_t -read_table_of_contents(int deviceFD, uint32 first_session, uchar *buffer, - uint16 buffer_length, bool msf) -{ - scsi_table_of_contents_command scsi_command; - raw_device_command raw_command; - const uint32 sense_data_length = 1024; - uchar sense_data[sense_data_length]; - status_t error = buffer ? B_OK : B_BAD_VALUE; - - TRACE(("%s: read_table_of_contents: (%d, %p, %d)\n", kModuleDebugName, - deviceFD, buffer, buffer_length)); - - if (error) - return error; - - // Init the scsi command and copy it into the BeOS "raw scsi command" ioctl struct - memset(raw_command.command, 0, 16); - scsi_command.command = 0x43; - scsi_command.msf = 0; - scsi_command.format = 2; - scsi_command.number = first_session; - scsi_command.length = B_HOST_TO_BENDIAN_INT16(buffer_length); - scsi_command.control = 0; - scsi_command.reserved0 = scsi_command.reserved1 = scsi_command.reserved2 - = scsi_command.reserved3 = scsi_command.reserved4 - = scsi_command.reserved5 = scsi_command.reserved6 = 0; - memcpy(raw_command.command, &scsi_command, sizeof(scsi_command)); - - // Init the rest of the raw command - raw_command.command_length = 10; - raw_command.flags = kScsiFlags; - raw_command.scsi_status = 0; - raw_command.cam_status = 0; - raw_command.data = buffer; - raw_command.data_length = buffer_length; - memset(raw_command.data, 0, raw_command.data_length); - raw_command.sense_data = sense_data; - raw_command.sense_data_length = sense_data_length; - memset(raw_command.sense_data, 0, raw_command.sense_data_length); - raw_command.timeout = kScsiTimeout; - - if (ioctl(deviceFD, B_RAW_DEVICE_COMMAND, &raw_command) == 0) { - if (raw_command.scsi_status == 0 && raw_command.cam_status == 1) { - // SUCCESS!!! - DBG(dump_full_table_of_contents(buffer, buffer_length)); - } else { - error = B_FILE_ERROR; - TRACE(("%s: scsi ioctl succeeded, but scsi command failed\n", - kModuleDebugName)); - } - } else { - error = errno; - TRACE(("%s: scsi command failed with error 0x%lx\n", kModuleDebugName, - error)); - } - - return error; - -} - -// cdrom_session_identify -static -bool -cdrom_session_identify(int deviceFD, off_t deviceSize, int32 blockSize) -{ - device_geometry geometry; - bool result = false; - if (ioctl(deviceFD, B_GET_GEOMETRY, &geometry) == 0) - result = (geometry.device_type == B_CD); - else - TRACE(("%s: Unable to get device geometry\n", kModuleDebugName)); - return result; -} - -// cdrom_session_get_nth_info -/*! \todo Check that read_toc buffer was large enough on success -*/ -static -status_t -cdrom_session_get_nth_info(int deviceFD, int32 index, off_t deviceSize, - int32 blockSize, struct session_info *sessionInfo) -{ - status_t error = sessionInfo && index >= 0 ? B_OK : B_BAD_VALUE; - uchar data[2048]; - int32 session = index+1; - - TRACE(("%s: get_nth_info(%d, %ld, %lld, %ld, %p)\n", kModuleDebugName, - deviceFD, index, deviceSize, blockSize, sessionInfo)); - - // Attempt to read the table of contents, first in lba mode, then in msf mode - if (!error) { - error = read_table_of_contents(deviceFD, 1, data, 2048, false); - } - if (error) { - TRACE(("%s: lba read_toc failed, trying msf instead\n", kModuleDebugName)); - error = read_table_of_contents(deviceFD, 1, data, 2048, true); - } - - // Interpret the data returned, if successful - if (!error) { - cdrom_table_of_contents_header *header; - cdrom_full_table_of_contents_entry *entries; - int count; - - header = (cdrom_table_of_contents_header*)data; - entries = (cdrom_full_table_of_contents_entry*)(data+4); - header->length = B_BENDIAN_TO_HOST_INT16(header->length); - - count = (header->length-2) / sizeof(cdrom_full_table_of_contents_entry); - - // Check for a valid session index - if (session < 1 || session > 99) - error = B_ENTRY_NOT_FOUND; - - // Extract the data of interest - if (!error) { - Disc disc(entries, count); - error = disc.InitCheck(); - if (!error) - error = disc.GetSessionInfo(index, blockSize, sessionInfo); - } - } - - if (error) - TRACE(("%s: get_nth error 0x%lx\n", kModuleDebugName, error)); - - return error; -} - -static session_module_info cdrom_session_module = -{ - // module_info - { - CDROM_SESSION_MODULE_NAME, - 0, // better B_KEEP_LOADED? - std_ops - }, - cdrom_session_identify, - cdrom_session_get_nth_info -}; - -_EXPORT session_module_info *modules[] = -{ - &cdrom_session_module, - NULL -}; - diff --git a/src/add-ons/kernel/partitioning_systems/session/Disc.cpp b/src/add-ons/kernel/partitioning_systems/session/Disc.cpp index 282474c678..9ce2e06c4c 100644 --- a/src/add-ons/kernel/partitioning_systems/session/Disc.cpp +++ b/src/add-ons/kernel/partitioning_systems/session/Disc.cpp @@ -1,5 +1,5 @@ //---------------------------------------------------------------------- -// This software is part of the OpenBeOS distribution and is covered +// This software is part of the OpenBeOS distribution and is covered // by the OpenBeOS license. // // Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net @@ -7,14 +7,14 @@ /*! \file Disc.cpp - Disc class implementation, used to enumerate the CD/DVD sessions. - + Disc class implementation, used to enumerate the CD/DVD sessions. + The protocols followed in this module are based on information taken from the "SCSI-3 Multimedia Commands" draft, revision 10A. - + The SCSI command of interest is "READ TOC/PMA/ATIP", command number \c 0x43. - + The format of interest for said command is "Full TOC", format number \c 0x2. */ @@ -26,7 +26,7 @@ #include "Debug.h" -static const char *kModuleDebugName = "session"; +DBG(static const char *kModuleDebugName = "session"); //------------------------------------------------------------------------------ // Helper function declarations @@ -62,15 +62,15 @@ class List { public: List(); ~List(); - + list_item* Find(int32 index) const; void Add(list_item *item); void Clear(); void SortAndRemoveDuplicates(); - + list_item* First() const; list_item* Last() const; - + private: list_item *fFirst; list_item *fLast; @@ -89,7 +89,7 @@ public: , adr(adr) { } - + off_t start_lba; uint8 control; //!< only used to give what are probably useless warnings uint8 adr; //!< only used to give what are probably useless warnings @@ -102,11 +102,11 @@ public: struct session : public list_item { public: session(uint32 index, session *next = NULL); - + bool first_track_hint_is_set(); bool last_track_hint_is_set(); bool end_lba_is_set(); // also implies control and adr are set - + bool is_audio(); int8 first_track_hint; @@ -114,7 +114,7 @@ public: int8 control; int8 adr; off_t end_lba; - + List track_list; }; @@ -142,7 +142,7 @@ List::Find(int32 index) const { // TRACE(("%s: List::Find(%ld)\n", kModuleDebugName, index)); list_item *item = fFirst; - while (item && item->index != index) { + while (item && item->index != index) { item = item->next; } return item; @@ -185,7 +185,7 @@ List::Clear() /*! \brief Bubble sorts the list by index, removing any duplicates (the first instance is kept). - + \todo I believe duplicate removal is actually unnecessary, but I need to verify that. */ void @@ -203,23 +203,23 @@ List::SortAndRemoveDuplicates() // dprintf("List::Sort: %ld -> %ld\n", item->index, next->index); if (item->index > next->index) { sorted = false; - + // Keep fLast up to date if (next == fLast) fLast = item; - // Swap + // Swap if (prev) { // item is not fFirst prev->next = next; item->next = next->next; - next->next = item; + next->next = item; } else { // item must be fFirst fFirst = next; item->next = next->next; next->next = item; - } + } } else if (item->index == next->index) { // Duplicate indicies TRACE(("%s: List::SortAndRemoveDuplicates: duplicate indicies found (#%ld); " @@ -227,7 +227,7 @@ List::SortAndRemoveDuplicates() item->next = next->next; delete next; next = item->next; - continue; + continue; } prev = item; item = next; @@ -285,7 +285,7 @@ session::last_track_hint_is_set() /*! \brief Returns true if the \a end_lba member has not been set to a legal value yet. - + The result of this function also signals that the \a control and \a adr members have or have not been set, since they are set at the same time as \a end_lba. @@ -314,7 +314,7 @@ session::is_audio() /*! \brief Creates a new Disc object by parsing the given table of contents entries and checking the resultant data structure for errors and warnings. - + If successful, subsequent calls to InitCheck() will return \c B_OK, elsewise they will return an error code. */ @@ -326,25 +326,25 @@ Disc::Disc(int fd) uchar data[kBlockSize]; /* - if (!error) + if (!error) error = sessionInfo && index >= 0 ? B_OK : B_BAD_VALUE; int32 session = index+1; // Check for a valid session index if (session < 1 || session > 99) error = B_ENTRY_NOT_FOUND; -*/ +*/ status_t error = fSessionList ? B_OK : B_NO_MEMORY; // Attempt to read the table of contents, first in lba mode, then in msf mode if (!error) { error = read_table_of_contents(fd, 1, data, kBlockSize, false); - } + } if (error) { TRACE(("%s: lba read_toc failed, trying msf instead\n", kModuleDebugName)); error = read_table_of_contents(fd, 1, data, kBlockSize, true); } - + // Interpret the data returned, if successful if (!error) { cdrom_table_of_contents_header *header; @@ -354,17 +354,17 @@ Disc::Disc(int fd) header = (cdrom_table_of_contents_header*)data; entries = (cdrom_full_table_of_contents_entry*)(data+4); header->length = B_BENDIAN_TO_HOST_INT16(header->length); - + count = (header->length-2) / sizeof(cdrom_full_table_of_contents_entry); - + error = _ParseTableOfContents(entries, count); // Dump(); if (!error) { _SortAndRemoveDuplicates(); error = _CheckForErrorsAndWarnings(); - } + } } - + PRINT(("Setting init status to 0x%lx, `%s'\n", error, strerror(error))); fInitStatus = error; } @@ -386,7 +386,7 @@ Disc::InitCheck() /*! \brief Stores the info for the given session (using 0 based indicies) in the struct pointed to by \a sessionInfo. - + Returns \c B_ENTRY_NOT_FOUND if no such session exists. */ Session* @@ -399,7 +399,7 @@ Disc::GetSession(int32 index) session = (struct session*)session->next) { if (session->is_audio()) { - counter++; // only one session per audio session + counter++; // only one session per audio session if (counter == index) { // Found an audio session. Take the start of the first // track with the end of session. @@ -409,22 +409,22 @@ Disc::GetSession(int32 index) off_t start_lba = track->start_lba; off_t end_lba = session->end_lba; - + off_t offset = start_lba * kBlockSize; off_t size = (end_lba - start_lba) * kBlockSize; - + Session *result = new Session(offset, size, kBlockSize, index, B_PARTITION_READ_ONLY, kPartitionTypeAudioSession); - if (!result) + if (!result) PRINT(("Error allocating new Session object; out of memory!\n")); return result; } else { PRINT(("Error: session #%ld is an audio " "session with no tracks!\n", index)); return NULL; - } - } + } + } } else { for (track *track = (struct track*)session->track_list.First(); track; @@ -438,21 +438,21 @@ Disc::GetSession(int32 index) off_t end_lba = track->next ? ((struct track*)track->next)->start_lba : session->end_lba; - + off_t offset = start_lba * kBlockSize; off_t size = (end_lba - start_lba) * kBlockSize; - + Session *result = new Session(offset, size, kBlockSize, index, B_PARTITION_READ_ONLY, kPartitionTypeDataSession); - if (!result) + if (!result) PRINT(("Error allocating new Session object; out of memory!\n")); return result; - } - } - } + } + } + } } - + PRINT(("no session #%ld found!\n", index)); return NULL; } @@ -502,11 +502,11 @@ Disc::_ParseTableOfContents(cdrom_full_table_of_contents_entry entries[], uint32 fSessionList->Add(session); } } - + uint8 point = entries[i].point; - + switch (point) { - + // first track hint case 0xA0: if (!session->first_track_hint_is_set()) { @@ -521,10 +521,10 @@ Disc::_ParseTableOfContents(cdrom_full_table_of_contents_entry entries[], uint32 } else { WARN(("%s: warning: duplicated first track hint values found for" "session %d; using first value encountered: %d", kModuleDebugName, - session_index, session->first_track_hint)); - } + session_index, session->first_track_hint)); + } break; - + // last track hint case 0xA1: if (!session->last_track_hint_is_set()) { @@ -539,10 +539,10 @@ Disc::_ParseTableOfContents(cdrom_full_table_of_contents_entry entries[], uint32 } else { WARN(("%s: warning: duplicate last track hint values found for" "session %d; using first value encountered: %d", kModuleDebugName, - session_index, session->last_track_hint)); - } + session_index, session->last_track_hint)); + } break; - + // end of session address case 0xA2: if (!session->end_lba_is_set()) { @@ -564,10 +564,10 @@ Disc::_ParseTableOfContents(cdrom_full_table_of_contents_entry entries[], uint32 } else { WARN(("%s: warning: duplicate end lba values found for" "session %d; using first value encountered: %lld", - kModuleDebugName, session_index, session->end_lba)); - } + kModuleDebugName, session_index, session->end_lba)); + } break; - + // Valid, but uninteresting, points case 0xB0: case 0xB1: @@ -577,7 +577,7 @@ Disc::_ParseTableOfContents(cdrom_full_table_of_contents_entry entries[], uint32 case 0xC0: case 0xC1: break; - + default: // Anything else had better be a valid track number, // or it's an invalid point @@ -590,7 +590,7 @@ Disc::_ParseTableOfContents(cdrom_full_table_of_contents_entry entries[], uint32 entries[i].pframes)); // The control and adr values grabbed here are only used later on // to signal a warning if they don't match the corresponding values - // of the parent session. + // of the parent session. track *track = new(nothrow) struct track(track_index, start_lba, entries[i].control, entries[i].adr); if (!track) { @@ -602,7 +602,7 @@ Disc::_ParseTableOfContents(cdrom_full_table_of_contents_entry entries[], uint32 WARN(("%s: warning: illegal point 0x%2x found in table of contents\n", kModuleDebugName, entries[i].point)); } - break; + break; } } return B_OK; @@ -631,7 +631,7 @@ Disc::_SortAndRemoveDuplicates() Anomalies that result in errors: - Sessions with no end_lba set - Sessions with no tracks - + Anomalies that result in warnings: - Inaccurate first_track_hint and/or last_track_hint values - Sequences of sessions or tracks that do not start at 1, @@ -640,33 +640,33 @@ Disc::_SortAndRemoveDuplicates() numbering does not restart with each session). - Tracks with different control and/or adr values than their parent session - + Anomalies that are currently *not* checked: - First Track Hint or Last Track Hint control and adr values that do not match the values for their session; Ingo's copy of the BeOS R5 CD is like this, but I don't believe it's a matter we need to worry about. This could certainly be changed in the future if needed. -*/ +*/ status_t Disc::_CheckForErrorsAndWarnings() { int32 lastSessionIndex = 0; int32 lastTrackIndex = 0; - + for (session *session = (struct session*)fSessionList->First(); session; session = (struct session*)session->next) { // Check for errors //----------------- - + // missing end lba if (!session->end_lba_is_set()) { TRACE(("%s: Disc::_CheckForErrorsAndWarnings: error: no end of session " "address for session #%ld\n", kModuleDebugName, session->index)); return B_ERROR; } - + // empty track list track *track = (struct track*)session->track_list.First(); if (!track) { @@ -674,10 +674,10 @@ Disc::_CheckForErrorsAndWarnings() { "tracks\n", kModuleDebugName, session->index)); return B_ERROR; } - + // Check for warnings //------------------- - + // incorrect first track hint if (session->first_track_hint_is_set() && session->first_track_hint != track->index) @@ -696,7 +696,7 @@ Disc::_CheckForErrorsAndWarnings() { "track hint (%d) doesn't match actual last track (%ld)\n", kModuleDebugName, session->index, session->last_track_hint, last->index)); } - + // invalid session sequence if (lastSessionIndex+1 != session->index) { TRACE(("%s: Disc::_CheckForErrorsAndWarnings: warning: index for session #%ld " @@ -704,7 +704,7 @@ Disc::_CheckForErrorsAndWarnings() { session->index, lastSessionIndex)); } lastSessionIndex = session->index; - + for ( ; track; track = (struct track*)track->next) { // invalid track sequence if (lastTrackIndex+1 != track->index) { @@ -732,7 +732,7 @@ Disc::_CheckForErrorsAndWarnings() { "(adr = %d) does not match adr for parent session #%ld (adr = %d)\n", kModuleDebugName, track->index, track->adr, session->index, session->adr)); } - } + } } return B_OK; @@ -750,7 +750,7 @@ Session::Session(off_t offset, off_t size, uint32 blockSize, int32 index, , fIndex(index) , fFlags(flags) , fType(strdup(type)) -{ +{ } Session::~Session() { @@ -814,15 +814,16 @@ dump_scsi_command(raw_device_command *cmd) { } */ -static -void + +#ifdef DEBUG +static void dump_full_table_of_contents(uchar *data, uint16 data_length) { cdrom_table_of_contents_header *header; cdrom_full_table_of_contents_entry *entries; int i, count; int header_length; - + header = (cdrom_table_of_contents_header*)data; entries = (cdrom_full_table_of_contents_entry*)(data+4); header_length = B_BENDIAN_TO_HOST_INT16(header->length); @@ -831,18 +832,18 @@ dump_full_table_of_contents(uchar *data, uint16 data_length) data_length, header_length)); header_length = data_length; } - + TRACE(("%s: table of contents dump:\n", kModuleDebugName)); TRACE(("--------------------------------------------------\n")); TRACE(("header:\n")); TRACE((" length = %d\n", header_length)); TRACE((" first = %d\n", header->first)); TRACE((" last = %d\n", header->last)); - + count = (header_length-2) / sizeof(cdrom_full_table_of_contents_entry); TRACE(("\n")); TRACE(("entry count = %d\n", count)); - + for (i = 0; i < count; i++) { TRACE(("\n")); TRACE(("entry #%d:\n", i)); @@ -865,25 +866,25 @@ dump_full_table_of_contents(uchar *data, uint16 data_length) } TRACE(("--------------------------------------------------\n")); } +#endif // DEBUG -// read_table_of_contents -static -status_t + +static status_t read_table_of_contents(int deviceFD, uint32 first_session, uchar *buffer, - uint16 buffer_length, bool msf) + uint16 buffer_length, bool msf) { scsi_table_of_contents_command scsi_command; raw_device_command raw_command; const uint32 sense_data_length = 1024; uchar sense_data[sense_data_length]; status_t error = buffer ? B_OK : B_BAD_VALUE; - - DEBUG_INIT_ETC(NULL, ("fd: %d, buffer: %p, buffer_length: %d", + + DEBUG_INIT_ETC(NULL, ("fd: %d, buffer: %p, buffer_length: %d", deviceFD, buffer, buffer_length)); if (error) return error; - + // Init the scsi command and copy it into the BeOS "raw scsi command" ioctl struct memset(raw_command.command, 0, 16); scsi_command.command = 0x43; @@ -891,7 +892,7 @@ read_table_of_contents(int deviceFD, uint32 first_session, uchar *buffer, scsi_command.format = kFullTableOfContentsFormat; scsi_command.number = first_session; scsi_command.length = B_HOST_TO_BENDIAN_INT16(buffer_length); - scsi_command.control = 0; + scsi_command.control = 0; scsi_command.reserved0 = scsi_command.reserved1 = scsi_command.reserved2 = scsi_command.reserved3 = scsi_command.reserved4 = scsi_command.reserved5 = scsi_command.reserved6 = 0; @@ -900,7 +901,7 @@ read_table_of_contents(int deviceFD, uint32 first_session, uchar *buffer, // Init the rest of the raw command raw_command.command_length = 10; raw_command.flags = kScsiFlags; - raw_command.scsi_status = 0; + raw_command.scsi_status = 0; raw_command.cam_status = 0; raw_command.data = buffer; raw_command.data_length = buffer_length; @@ -908,8 +909,8 @@ read_table_of_contents(int deviceFD, uint32 first_session, uchar *buffer, raw_command.sense_data = sense_data; raw_command.sense_data_length = sense_data_length; memset(raw_command.sense_data, 0, raw_command.sense_data_length); - raw_command.timeout = kScsiTimeout; - + raw_command.timeout = kScsiTimeout; + if (ioctl(deviceFD, B_RAW_DEVICE_COMMAND, &raw_command) == 0) { if (raw_command.scsi_status == 0 && raw_command.cam_status == 1) { // SUCCESS!!! @@ -926,7 +927,7 @@ read_table_of_contents(int deviceFD, uint32 first_session, uchar *buffer, } return error; - + } // cdrom_session_get_nth_info @@ -941,19 +942,19 @@ cdrom_session_get_nth_info(int deviceFD, int32 index, off_t deviceSize, status_t error = sessionInfo && index >= 0 ? B_OK : B_BAD_VALUE; uchar data[2048]; int32 session = index+1; - + TRACE(("%s: get_nth_info(%d, %ld, %lld, %ld, %p)\n", kModuleDebugName, deviceFD, index, deviceSize, blockSize, sessionInfo)); // Attempt to read the table of contents, first in lba mode, then in msf mode if (!error) { error = read_table_of_contents(deviceFD, 1, data, 2048, false); - } + } if (error) { TRACE(("%s: lba read_toc failed, trying msf instead\n", kModuleDebugName)); error = read_table_of_contents(deviceFD, 1, data, 2048, true); } - + // Interpret the data returned, if successful if (!error) { cdrom_table_of_contents_header *header; @@ -963,25 +964,25 @@ cdrom_session_get_nth_info(int deviceFD, int32 index, off_t deviceSize, header = (cdrom_table_of_contents_header*)data; entries = (cdrom_full_table_of_contents_entry*)(data+4); header->length = B_BENDIAN_TO_HOST_INT16(header->length); - + count = (header->length-2) / sizeof(cdrom_full_table_of_contents_entry); - + // Check for a valid session index if (session < 1 || session > 99) error = B_ENTRY_NOT_FOUND; - + // Extract the data of interest if (!error) { Disc disc(entries, count); error = disc.InitCheck(); - if (!error) + if (!error) error = disc.GetSessionInfo(index, blockSize, sessionInfo); } } - - if (error) + + if (error) TRACE(("%s: get_nth error 0x%lx\n", kModuleDebugName, error)); - + return error; } */ diff --git a/src/add-ons/kernel/partitioning_systems/session/Disc.h b/src/add-ons/kernel/partitioning_systems/session/Disc.h index 871d9a53d0..4103ae1757 100644 --- a/src/add-ons/kernel/partitioning_systems/session/Disc.h +++ b/src/add-ons/kernel/partitioning_systems/session/Disc.h @@ -1,5 +1,5 @@ //---------------------------------------------------------------------- -// This software is part of the OpenBeOS distribution and is covered +// This software is part of the OpenBeOS distribution and is covered // by the OpenBeOS license. // // Copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net @@ -9,7 +9,7 @@ Disc class, used to enumerate the CD/DVD sessions. */ - + #ifndef _DISC_H #define _DISC_H @@ -20,7 +20,6 @@ #include #include -#include #include #include @@ -37,16 +36,16 @@ class Disc { public: Disc(int fd); ~Disc(); - + status_t InitCheck(); Session* GetSession(int32 index); - + void Dump(); - + // CDs and DVDs are required to have a block size of 2K by // the SCSI-3 standard static const int kBlockSize = 2048; - + private: status_t _ParseTableOfContents(cdrom_full_table_of_contents_entry entries[], uint32 count); @@ -63,11 +62,11 @@ private: class Session { public: ~Session(); - + off_t Offset() { return fOffset; } off_t Size() { return fSize; } uint32 BlockSize() { return fBlockSize; } - int32 Index() { return fIndex; } + int32 Index() { return fIndex; } uint32 Flags() { return fFlags; } const char* Type() { return fType; } private: @@ -76,13 +75,13 @@ private: uint32 flags, const char *type); Session(const Session &ref); // not implemented Session& operator=(const Session &ref); // not implemented - + off_t fOffset; off_t fSize; uint32 fBlockSize; - int32 fIndex; + int32 fIndex; uint32 fFlags; - char *fType; + char *fType; }; #endif // _DISC_H