diff --git a/build/jam/BuildSetup b/build/jam/BuildSetup index ce2ed4090c..5864f70723 100644 --- a/build/jam/BuildSetup +++ b/build/jam/BuildSetup @@ -1355,7 +1355,7 @@ if $(HAIKU_NO_WERROR) != 1 { EnableWerror src add-ons translators bmp ; # EnableWerror src add-ons translators exr ; EnableWerror src add-ons translators gif ; - EnableWerror src add-ons translators hpgs ; +# EnableWerror src add-ons translators hpgs ; EnableWerror src add-ons translators hvif ; EnableWerror src add-ons translators ico ; # EnableWerror src add-ons translators jpeg ; # gcc2 diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index 6c2037cd7b..2734ce0165 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -87,18 +87,18 @@ SYSTEM_LIBS = libbe.so libbsd.so libbnetapi.so libdebug.so libdevice.so libgame.so $(X86_ONLY)libGL.so libgnu.so - $(HAIKU_JPEG_CURRENT_LIB) libmail.so libmedia.so libmidi.so libmidi2.so libnetwork.so - $(HAIKU_LIBPNG_CURRENT_LIB) libroot.so libroot-addon-icu.so libscreensaver.so libtextencoding.so libtiff.so libtracker.so libtranslation.so - libz.so $(HAIKU_SHARED_LIBSTDC++) $(HAIKU_SHARED_LIBSUPC++) - $(HAIKU_FREETYPE_CURRENT_LIB) ; PRIVATE_SYSTEM_LIBS = + $(HAIKU_JPEG_CURRENT_LIB) + $(HAIKU_LIBPNG_CURRENT_LIB) + $(HAIKU_ZLIB_CURRENT_LIB) + $(HAIKU_FREETYPE_CURRENT_LIB) libalm.so libfluidsynth.so libilmimf.so @@ -334,6 +334,13 @@ SYSTEM_LIBS_ALIASES = $(SYSTEM_LIBS_LIBBE_ALIASES) ; +OPTIONAL_LIBS_ALIASES = + $(HAIKU_FREETYPE_CURRENT_LINK) + $(HAIKU_JPEG_CURRENT_LINK) + $(HAIKU_LIBPNG_CURRENT_LINK) + $(HAIKU_ZLIB_CURRENT_LINK) +; + # libfreetype.so links to the current freetype lib AddSymlinkToHaikuHybridImage system lib : $(HAIKU_FREETYPE_CURRENT_LIB:BS) : $(HAIKU_FREETYPE_CURRENT_LINK) : : true ; @@ -352,6 +359,12 @@ AddSymlinkToHaikuHybridImage system lib : $(HAIKU_JPEG_CURRENT_LIB:BS) AddSymlinkToHaikuHybridImage system lib : $(HAIKU_JPEG_CURRENT_LINK) : libjpeg.so : : true ; +# zlib.so links to the current zlib +AddSymlinkToHaikuHybridImage system lib : $(HAIKU_ZLIB_CURRENT_LIB:BS) + : $(HAIKU_ZLIB_CURRENT_LINK) : : true ; +AddSymlinkToHaikuHybridImage system lib : $(HAIKU_ZLIB_CURRENT_LINK) + : libzlib.so : : true ; + # servers AddFilesToHaikuImage system servers : $(SYSTEM_SERVERS) ; @@ -724,42 +737,42 @@ AddDirectoryToHaikuImage home config settings printers "Save as PDF" # PDF Writer enconding files CopyDirectoryToHaikuImage system data : [ FDirName $(HAIKU_TOP) src add-ons print drivers pdf encoding ] - : "PDF Writer" : -x .svn -x Jamfile ; + : "PDF Writer" : -x Jamfile ; # Gutenprint data files CopyDirectoryToHaikuImage system data : [ FDirName $(HAIKU_TOP) src libs print libgutenprint src xml ] - : gutenprint : -x .svn -x *.c -x Makefile.am -x Makefile.in ; + : gutenprint : -x *.c -x Makefile.am -x Makefile.in ; # dvb channel settings CopyDirectoryToHaikuImage home config settings Media : [ FDirName $(HAIKU_TOP) data settings media dvb ] - : dvb : -x .svn -x Jamfile ; + : dvb : -x Jamfile ; # licenses CopyDirectoryToHaikuImage system data : [ FDirName $(HAIKU_TOP) data system data licenses ] - : licenses : -x .svn ; + : licenses ; # Copy documentation as per DiskUsage's license requirement. CopyDirectoryToHaikuImage system documentation : [ FDirName $(HAIKU_TOP) docs apps diskusage ] - : diskusage : -x .svn ; + : diskusage ; # Copy documentation as per PDFlib Lite's license requirement. CopyDirectoryToHaikuImage system documentation : [ FDirName $(HAIKU_TOP) src libs pdflib doc ] - : pdflib : -x .svn ; + : pdflib ; # Copy sample programs as per PDFlib Lite's license requirement. CopyDirectoryToHaikuImage develop sample-code : [ FDirName $(HAIKU_TOP) src libs pdflib bind pdflib ] - : pdflib : -x .svn ; + : pdflib ; # Copy Mesa3D GL headers into image if $(TARGET_ARCH) = x86 { CopyDirectoryToHaikuImage develop headers os opengl - : [ FDirName $(HAIKU_MESA_HEADERS) GL ] : : -x .svn ; + : [ FDirName $(HAIKU_MESA_HEADERS) GL ] ; } #pragma mark - Optional Packages diff --git a/build/jam/ImageRules b/build/jam/ImageRules index c2275408d3..34f90ae832 100644 --- a/build/jam/ImageRules +++ b/build/jam/ImageRules @@ -705,7 +705,7 @@ rule AddSourceDirectoryToHaikuImage dirTokens : alwaysUpdate CopyDirectoryToHaikuImage home HaikuSources : [ FDirName $(HAIKU_TOP) $(dirTokens) ] - : : -x .svn : $(alwaysUpdate) ; + : : : $(alwaysUpdate) ; } rule AddHeaderDirectoryToHaikuImage dirTokens : dirName : alwaysUpdate @@ -715,7 +715,7 @@ rule AddHeaderDirectoryToHaikuImage dirTokens : dirName : alwaysUpdate CopyDirectoryToHaikuImage develop headers : [ FDirName $(HAIKU_TOP) headers $(dirTokens) ] - : $(dirName) : -x .svn : $(alwaysUpdate) ; + : $(dirName) : : $(alwaysUpdate) ; } rule AddWifiFirmwareToHaikuImage driver : package : archive : extract diff --git a/build/jam/OptionalBuildFeatures b/build/jam/OptionalBuildFeatures index 6028a25479..31227844e4 100644 --- a/build/jam/OptionalBuildFeatures +++ b/build/jam/OptionalBuildFeatures @@ -581,3 +581,43 @@ if $(TARGET_ARCH) = ppc || $(TARGET_ARCH) = x86 { } else { Echo "jpeg support not available on $(TARGET_ARCH)" ; } + +# zlib +local zlibBaseURL = $(baseURL)/lib ; +if $(TARGET_ARCH) = ppc || $(TARGET_ARCH) = x86 { + if $(TARGET_ARCH) = ppc { + HAIKU_ZLIB_FILE = zlib-1.2.7-ppc-gcc4-2012-10-30.zip ; + } else if $(HAIKU_GCC_VERSION[1]) >= 4 { + HAIKU_ZLIB_FILE = zlib-1.2.7-x86-gcc4-2012-10-30.zip ; + } else { + HAIKU_ZLIB_FILE = zlib-1.2.7-x86-gcc2-2012-10-30.zip ; + } + + local zlibZipFile = [ DownloadFile $(HAIKU_ZLIB_FILE) + : $(zlibBaseURL)/$(HAIKU_ZLIB_FILE) ] ; + + HAIKU_ZLIB_DIR = [ FDirName $(HAIKU_OPTIONAL_BUILD_PACKAGES_DIR) + $(HAIKU_ZLIB_FILE:B) ] ; + + HAIKU_ZLIB_HEADERS_DEPENDENCY = [ ExtractArchive $(HAIKU_ZLIB_DIR) + : common/include : $(zlibZipFile) + : extracted-zlib ] ; + + HAIKU_ZLIB_LIB = [ ExtractArchive $(HAIKU_ZLIB_DIR) + : + common/lib/libz.so + : $(zlibZipFile) + : extracted-zlib ] ; + HAIKU_ZLIB_CURRENT_LIB = [ ExtractArchive $(HAIKU_ZLIB_DIR) + : + common/lib/libz.so.1.2.7 + : $(zlibZipFile) + : extracted-zlib ] ; + Depends $(HAIKU_ZLIB_LIB) $(HAIKU_ZLIB_CURRENT_LIB) : $(HAIKU_ZLIB_HEADERS_DEPENDENCY) ; + + HAIKU_ZLIB_CURRENT_LINK = libz.so.1 ; + + HAIKU_ZLIB_HEADERS = [ FDirName $(HAIKU_ZLIB_DIR) common include ] ; +} else { + Echo "zlib support not available on $(TARGET_ARCH)" ; +} diff --git a/build/jam/OptionalPackages b/build/jam/OptionalPackages index 31f5e76a6f..52e822a9f0 100644 --- a/build/jam/OptionalPackages +++ b/build/jam/OptionalPackages @@ -782,7 +782,8 @@ if [ IsOptionalHaikuImagePackageAdded DevelopmentMin ] && $(TARGET_ARCH) = x86 { # library symlinks local lib ; - for lib in $(SYSTEM_LIBS) $(SYSTEM_LIBS_LIBGL_ALIASES) $(developmentLibs) { + for lib in $(SYSTEM_LIBS) $(SYSTEM_LIBS_LIBGL_ALIASES) $(developmentLibs) + $(OPTIONAL_LIBS_ALIASES) { AddSymlinkToHaikuHybridImage $(abiDirTokens) lib : /system/lib $(lib:BS) : : true ; local abiVersion = [ on $(lib) return $(HAIKU_LIB_ABI_VERSION) ] ; @@ -846,7 +847,6 @@ if [ IsOptionalHaikuImagePackageAdded DevelopmentMin ] && $(TARGET_ARCH) = x86 { AddHeaderDirectoryToHaikuImage libs ncurses : 3rdparty ; AddHeaderDirectoryToHaikuImage libs termcap : 3rdparty ; AddHeaderDirectoryToHaikuImage libs tiff : 3rdparty ; - AddHeaderDirectoryToHaikuImage libs zlib : 3rdparty ; CopyDirectoryToHaikuImage develop headers : [ FDirName $(HAIKU_FREETYPE_DIR) develop headers 3rdparty ] ; @@ -854,14 +854,16 @@ if [ IsOptionalHaikuImagePackageAdded DevelopmentMin ] && $(TARGET_ARCH) = x86 { : 3rdparty ; CopyDirectoryToHaikuImage develop headers : $(HAIKU_LIBPNG_HEADERS) : 3rdparty ; + CopyDirectoryToHaikuImage develop headers : $(HAIKU_ZLIB_HEADERS) + : 3rdparty ; # cpp headers if $(HAIKU_GCC_VERSION[1]) = 2 { # GCC 2 only -- for GCC 4 they come with the DevelopmentBase package CopyDirectoryToHaikuImage $(abiDirTokens) headers - : [ FDirName $(HAIKU_TOP) headers cpp ] : : -x .svn ; + : [ FDirName $(HAIKU_TOP) headers cpp ] ; CopyDirectoryToAlternativeGCCArchive $(abiDirTokens) headers - : [ FDirName $(HAIKU_TOP) headers cpp ] : : -x .svn ; + : [ FDirName $(HAIKU_TOP) headers cpp ] ; } } @@ -1978,10 +1980,10 @@ if [ IsOptionalHaikuImagePackageAdded WebPositiveBookmarks ] { if [ IsOptionalHaikuImagePackageAdded Welcome ] { CopyDirectoryToHaikuImage system documentation : [ FDirName $(HAIKU_TOP) docs welcome ] - : welcome : -x .svn ; + : welcome ; CopyDirectoryToHaikuImage system documentation : [ FDirName $(HAIKU_TOP) docs userguide ] - : userguide : -x .svn ; + : userguide ; } diff --git a/build/scripts/build_cross_tools b/build/scripts/build_cross_tools index ea442b5557..37382620d3 100755 --- a/build/scripts/build_cross_tools +++ b/build/scripts/build_cross_tools @@ -109,7 +109,7 @@ copy_headers() sourceDir=$1 targetDir=$2 - headers="`find $sourceDir -name \*\.h | grep -v /.svn`" + headers="`find $sourceDir -name \*\.h`" headers="`echo $headers | sed -e s@$sourceDir/@@g`" for f in $headers; do headerTargetDir=$targetDir/`dirname $f` diff --git a/build/scripts/build_cross_tools_gcc4 b/build/scripts/build_cross_tools_gcc4 index d8960f37eb..976ff9d3f5 100755 --- a/build/scripts/build_cross_tools_gcc4 +++ b/build/scripts/build_cross_tools_gcc4 @@ -130,7 +130,7 @@ copy_headers() sourceDir=$1 targetDir=$2 - headers="$(find $sourceDir -name \*\.h | grep -v /.svn)" + headers="$(find $sourceDir -name \*\.h)" headers="$(echo $headers | sed -e s@$sourceDir/@@g)" for f in $headers; do headerTargetDir=$targetDir/$(dirname $f) diff --git a/configure b/configure index 8250c28c46..fb2b95e921 100755 --- a/configure +++ b/configure @@ -327,7 +327,7 @@ HOST_GCC_OBJCOPY=`gcc -print-prog-name=objcopy` SFDISK_BINARY=sfdisk HOST_SFDISK=$SFDISK_BINARY -haikuRequiredLegacyGCCVersion="2.95.3-haiku-121012" +haikuRequiredLegacyGCCVersion="2.95.3-haiku-121101" export haikuRequiredLegacyGCCVersion # version of legacy gcc required to build haiku diff --git a/headers/cpp/std/bastring.h b/headers/cpp/std/bastring.h index b07761e961..774f7be3e9 100644 --- a/headers/cpp/std/bastring.h +++ b/headers/cpp/std/bastring.h @@ -350,7 +350,10 @@ private: public: const charT* c_str () const - { if (length () == 0) return ""; terminate (); return data (); } + { + static const charT null_str[1] = {0}; + if (length () == 0) return null_str; terminate (); return data (); + } void resize (size_type n, charT c); void resize (size_type n) { resize (n, eos ()); } diff --git a/headers/cpp/std/complext.h b/headers/cpp/std/complext.h index d3eb98a2f9..0e70194780 100644 --- a/headers/cpp/std/complext.h +++ b/headers/cpp/std/complext.h @@ -387,6 +387,22 @@ template complex<_FLT> template complex<_FLT> sqrt (const complex<_FLT>&) __attribute__ ((const)); +template inline complex<_FLT> +tan (const complex<_FLT>& x) +{ + return sin (x) / cos (x); +} +template inline complex<_FLT> +tanh (const complex<_FLT>& x) +{ + return sinh (x) / cosh (x); +} +template inline complex<_FLT> +log10 (const complex<_FLT>& x) +{ + return log (x) / log (10.0); +} + template istream& operator >> (istream&, complex<_FLT>&); template ostream& operator << (ostream&, const complex<_FLT>&); } // extern "C++" diff --git a/headers/posix/unistd.h b/headers/posix/unistd.h index 8380ae65a6..4cc5e3f967 100644 --- a/headers/posix/unistd.h +++ b/headers/posix/unistd.h @@ -220,7 +220,7 @@ extern int execle(const char *path, const char *arg , ... /*, char **envp */); extern int exect(const char *path, char *const *argv); extern int execvp(const char *file, char *const *argv); -extern void _exit(int status); +extern void _exit(int status) __attribute__ ((noreturn)); extern pid_t tcgetpgrp(int fd); extern int tcsetpgrp(int fd, pid_t pgrpid); diff --git a/src/add-ons/kernel/busses/ata/Jamfile b/src/add-ons/kernel/busses/ata/Jamfile index 1eb6dfdc00..2159c1b5d0 100644 --- a/src/add-ons/kernel/busses/ata/Jamfile +++ b/src/add-ons/kernel/busses/ata/Jamfile @@ -3,6 +3,6 @@ SubDir HAIKU_TOP src add-ons kernel busses ata ; SubInclude HAIKU_TOP src add-ons kernel busses ata generic_ide_pci ; SubInclude HAIKU_TOP src add-ons kernel busses ata ide_isa ; SubInclude HAIKU_TOP src add-ons kernel busses ata it8211 ; -#SubInclude HAIKU_TOP src add-ons kernel busses ata promise_tx2 ; +SubInclude HAIKU_TOP src add-ons kernel busses ata promise_tx2 ; SubInclude HAIKU_TOP src add-ons kernel busses ata silicon_image_3112 ; SubInclude HAIKU_TOP src add-ons kernel busses ata legacy_sata ; diff --git a/src/add-ons/kernel/busses/ata/promise_tx2/promise_tx2.c b/src/add-ons/kernel/busses/ata/promise_tx2/promise_tx2.c index d90ffff55e..c97cb323e3 100644 --- a/src/add-ons/kernel/busses/ata/promise_tx2/promise_tx2.c +++ b/src/add-ons/kernel/busses/ata/promise_tx2/promise_tx2.c @@ -21,65 +21,70 @@ #include "wrapper.h" -#define PROMISE_TX2_CONTROLLER_MODULE_NAME "busses/ata/promise_tx2/device_v1" +#define PROMISE_TX2_CONTROLLER_MODULE_NAME "busses/ata/promise_tx2/driver_v1" #define PROMISE_TX2_CHANNEL_MODULE_NAME "busses/ata/promise_tx2/channel/v1" -static ata_for_controller_interface *ide; -static ata_adapter_interface *ata_adapter; -static device_manager_info *pnp; +static ata_for_controller_interface *sATA; +static ata_adapter_interface *sATAAdapter; +static device_manager_info *sDeviceManager; + + +static void +set_channel(void *cookie, ata_channel channel) +{ + sATAAdapter->set_channel((ata_adapter_channel_info *)cookie, channel); +} static status_t write_command_block_regs(void *channel_cookie, ata_task_file *tf, ata_reg_mask mask) { - return ata_adapter->write_command_block_regs((ata_adapter_channel_info *)channel_cookie, tf, mask); + return sATAAdapter->write_command_block_regs((ata_adapter_channel_info *)channel_cookie, tf, mask); } static status_t read_command_block_regs(void *channel_cookie, ata_task_file *tf, ata_reg_mask mask) { - return ata_adapter->read_command_block_regs((ata_adapter_channel_info *)channel_cookie, tf, mask); + return sATAAdapter->read_command_block_regs((ata_adapter_channel_info *)channel_cookie, tf, mask); } static uint8 get_altstatus(void *channel_cookie) { - return ata_adapter->get_altstatus((ata_adapter_channel_info *)channel_cookie); + return sATAAdapter->get_altstatus((ata_adapter_channel_info *)channel_cookie); } static status_t write_device_control(void *channel_cookie, uint8 val) { - return ata_adapter->write_device_control((ata_adapter_channel_info *)channel_cookie, val); + return sATAAdapter->write_device_control((ata_adapter_channel_info *)channel_cookie, val); } static status_t write_pio(void *channel_cookie, uint16 *data, int count, bool force_16bit) { - return ata_adapter->write_pio((ata_adapter_channel_info *)channel_cookie, data, count, force_16bit); + return sATAAdapter->write_pio((ata_adapter_channel_info *)channel_cookie, data, count, force_16bit); } static status_t read_pio(void *channel_cookie, uint16 *data, int count, bool force_16bit) { - return ata_adapter->read_pio((ata_adapter_channel_info *)channel_cookie, data, count, force_16bit); + return sATAAdapter->read_pio((ata_adapter_channel_info *)channel_cookie, data, count, force_16bit); } static int32 -inthand(void *arg) +handle_interrupt(void *arg) { ata_adapter_channel_info *channel = (ata_adapter_channel_info *)arg; pci_device_module_info *pci = channel->pci; - pci_device device = channel->device; - ide_bm_status bm_status; - uint8 status; + pci_device *device = channel->device; SHOW_FLOW0( 3, "" ); @@ -91,7 +96,7 @@ inthand(void *arg) if ((pci->read_io_8(device, channel->bus_master_base + 3) & 0x20) == 0) return B_UNHANDLED_INTERRUPT; - return ata_adapter->inthand(arg); + return sATAAdapter->inthand(arg); } @@ -99,88 +104,86 @@ static status_t prepare_dma(void *channel_cookie, const physical_entry *sg_list, size_t sg_list_count, bool to_device) { - return ata_adapter->prepare_dma((ata_adapter_channel_info *)channel_cookie, sg_list, sg_list_count, to_device); + return sATAAdapter->prepare_dma((ata_adapter_channel_info *)channel_cookie, sg_list, sg_list_count, to_device); } static status_t start_dma(void *channel_cookie) { - return ata_adapter->start_dma((ata_adapter_channel_info *)channel_cookie); + return sATAAdapter->start_dma((ata_adapter_channel_info *)channel_cookie); } static status_t finish_dma(void *channel_cookie) { - return ata_adapter->finish_dma((ata_adapter_channel_info *)channel_cookie); + return sATAAdapter->finish_dma((ata_adapter_channel_info *)channel_cookie); } static status_t -init_channel(device_node_handle node, ata_channel ata_channel, - void **channel_cookie) +init_channel(device_node *node, void **channel_cookie) { - return ata_adapter->init_channel(node, ata_channel, (ata_adapter_channel_info **)channel_cookie, - sizeof(ata_adapter_channel_info), inthand); -} - - -static status_t -uninit_channel(void *channel_cookie) -{ - return ata_adapter->uninit_channel((ata_adapter_channel_info *)channel_cookie); -} - - -static void channel_removed(device_node_handle node, void *channel_cookie) -{ - return ata_adapter->channel_removed(node, (ata_adapter_channel_info *)channel_cookie); -} - - -static status_t -init_controller(device_node_handle node, void *user_cookie, - ata_adapter_controller_info **cookie) -{ - return ata_adapter->init_controller(node, user_cookie, cookie, - sizeof(ata_adapter_controller_info)); -} - - -static status_t -uninit_controller(ata_adapter_controller_info *controller) -{ - return ata_adapter->uninit_controller(controller); + return sATAAdapter->init_channel(node, + (ata_adapter_channel_info **)channel_cookie, + sizeof(ata_adapter_channel_info), handle_interrupt); } static void -controller_removed(device_node_handle node, ata_adapter_controller_info *controller) +uninit_channel(void *channel_cookie) { - return ata_adapter->controller_removed(node, controller); + sATAAdapter->uninit_channel((ata_adapter_channel_info *)channel_cookie); +} + + +static void channel_removed(void *channel_cookie) +{ + return sATAAdapter->channel_removed( + (ata_adapter_channel_info *)channel_cookie); +} + + +static status_t +init_controller(device_node *node, void **cookie) +{ + return sATAAdapter->init_controller(node, + (ata_adapter_controller_info **)cookie, + sizeof(ata_adapter_controller_info)); +} + + +static void +uninit_controller(void *controller) +{ + sATAAdapter->uninit_controller( + (ata_adapter_controller_info *)controller); +} + + +static void +controller_removed(void *controller) +{ + return sATAAdapter->controller_removed( + (ata_adapter_controller_info *)controller); } // publish node of ide controller static status_t -publish_controller(device_node_handle parent, uint16 bus_master_base, uint8 intnum, - io_resource_handle *resources, device_node_handle *node) +publish_controller(device_node *parent, uint16 bus_master_base, uint8 intnum, + io_resource *resources, device_node **node) { device_attr attrs[] = { - // info about ourself and our consumer - { B_DRIVER_MODULE, B_STRING_TYPE, { string: PROMISE_TX2_CONTROLLER_MODULE_NAME }}, - // properties of this controller for ide bus manager // there are always max. 2 devices - { IDE_CONTROLLER_MAX_DEVICES_ITEM, B_UINT8_TYPE, { ui8: 2 }}, + { ATA_CONTROLLER_MAX_DEVICES_ITEM, B_UINT8_TYPE, { ui8: 2 }}, // of course we can DMA - { IDE_CONTROLLER_CAN_DMA_ITEM, B_UINT8_TYPE, { ui8: 1 }}, - // command queuing always works - { IDE_CONTROLLER_CAN_CQ_ITEM, B_UINT8_TYPE, { ui8: 1 }}, + { ATA_CONTROLLER_CAN_DMA_ITEM, B_UINT8_TYPE, { ui8: 1 }}, // choose any name here - { IDE_CONTROLLER_CONTROLLER_NAME_ITEM, B_STRING_TYPE, { string: "Promise TX2" }}, + { ATA_CONTROLLER_CONTROLLER_NAME_ITEM, B_STRING_TYPE, { string: "Promise TX2" }}, // DMA properties // some say it must be dword-aligned, others that it can be byte-aligned; @@ -203,19 +206,18 @@ publish_controller(device_node_handle parent, uint16 bus_master_base, uint8 intn SHOW_FLOW0(2, ""); - return pnp->register_device(parent, attrs, resources, node); + return sDeviceManager->register_node(parent, + PROMISE_TX2_CONTROLLER_MODULE_NAME, attrs, resources, node); } // detect pure IDE controller, i.e. without channels static status_t -detect_controller(pci_device_module_info *pci, pci_device pci_device, - device_node_handle parent, uint16 bus_master_base, int8 intnum, - device_node_handle *node) +detect_controller(pci_device_module_info *pci, pci_device *pci_device, + device_node *parent, uint16 bus_master_base, int8 intnum, + device_node **node) { - io_resource_handle resource_handles[2]; - SHOW_FLOW0(3, ""); if ((bus_master_base & PCI_address_space) != 1) @@ -225,33 +227,33 @@ detect_controller(pci_device_module_info *pci, pci_device pci_device, { io_resource resources[2] = { - { IO_PORT, bus_master_base, 16 }, + { B_IO_PORT, bus_master_base, 16 }, {} }; - if (pnp->acquire_io_resources(resources, resource_handles) != B_OK) - return B_ERROR; + return publish_controller(parent, bus_master_base, intnum, resources, + node); } - - return publish_controller(parent, bus_master_base, intnum, resource_handles, node); } static status_t -probe_controller(device_node_handle parent) +probe_controller(device_node *parent) { pci_device_module_info *pci; - pci_device device; + pci_device *device; uint16 command_block_base[2]; uint16 control_block_base[2]; uint16 bus_master_base; - device_node_handle controller_node, channels[2]; + device_node *controller_node; + device_node *channels[2]; uint8 intnum; - status_t res; + status_t status; SHOW_FLOW0(3, ""); - if (pnp->init_driver(parent, NULL, (driver_module_info **)&pci, (void **)&device) != B_OK) + if (sDeviceManager->get_driver(parent, (driver_module_info **)&pci, + (void **)&device) != B_OK) return B_ERROR; command_block_base[0] = pci->read_pci_config(device, PCI_base_registers, 4); @@ -267,99 +269,86 @@ probe_controller(device_node_handle parent) control_block_base[1] &= PCI_address_io_mask; bus_master_base &= PCI_address_io_mask; - res = detect_controller(pci, device, parent, bus_master_base, intnum, &controller_node); - if (res != B_OK || controller_node == NULL) - goto err; + status = detect_controller(pci, device, parent, bus_master_base, intnum, + &controller_node); + if (status != B_OK || controller_node == NULL) + return status; - ata_adapter->detect_channel(pci, device, controller_node, + sATAAdapter->detect_channel(pci, device, controller_node, PROMISE_TX2_CHANNEL_MODULE_NAME, true, command_block_base[0], control_block_base[0], bus_master_base, intnum, 0, "Primary Channel", &channels[0], false); - ata_adapter->detect_channel(pci, device, controller_node, + sATAAdapter->detect_channel(pci, device, controller_node, PROMISE_TX2_CHANNEL_MODULE_NAME, true, command_block_base[1], control_block_base[1], bus_master_base, intnum, 1, "Secondary Channel", &channels[1], false); - pnp->uninit_driver(parent); - return B_OK; - -err: - pnp->uninit_driver(parent); - return res; -} - - -static status_t -std_ops(int32 op, ...) -{ - switch (op) { - case B_MODULE_INIT: - case B_MODULE_UNINIT: - return B_OK; - - default: - return B_ERROR; - } } module_dependency module_dependencies[] = { - { IDE_FOR_CONTROLLER_MODULE_NAME, (module_info **)&ide }, - { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&pnp }, - { ATA_ADAPTER_MODULE_NAME, (module_info **)&ata_adapter }, + { ATA_FOR_CONTROLLER_MODULE_NAME, (module_info **)&sATA }, + { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&sDeviceManager }, + { ATA_ADAPTER_MODULE_NAME, (module_info **)&sATAAdapter }, {} }; // exported interface -static ide_controller_interface channel_interface = { +static ata_controller_interface sChannelInterface = { { { PROMISE_TX2_CHANNEL_MODULE_NAME, 0, - std_ops + NULL }, - NULL, // supported devices - NULL, - (status_t (*)( device_node_handle , void *, void ** )) init_channel, + NULL, // supports_device() + NULL, // register_device() + init_channel, uninit_channel, + NULL, // register_child_devices() + NULL, // rescan_child_devices() channel_removed }, - &write_command_block_regs, - &read_command_block_regs, + set_channel, - &get_altstatus, - &write_device_control, + write_command_block_regs, + read_command_block_regs, - &write_pio, - &read_pio, + get_altstatus, + write_device_control, - &prepare_dma, - &start_dma, - &finish_dma, + write_pio, + read_pio, + + prepare_dma, + start_dma, + finish_dma, }; -static driver_module_info controller_interface = { +static driver_module_info sControllerInterface = { { PROMISE_TX2_CONTROLLER_MODULE_NAME, 0, - std_ops + NULL }, NULL, probe_controller, - (status_t (*)(device_node_handle, void *, void **)) init_controller, - (status_t (*)(void *)) uninit_controller, - (void (*)(device_node_handle, void *)) controller_removed + init_controller, + uninit_controller, + NULL, + NULL, + controller_removed }; module_info *modules[] = { - (module_info *)&controller_interface, - (module_info *)&channel_interface, + (module_info *)&sControllerInterface, + (module_info *)&sChannelInterface, NULL }; diff --git a/src/add-ons/kernel/file_systems/ntfs/attributes.c b/src/add-ons/kernel/file_systems/ntfs/attributes.c index bef6dcd11c..0e10eba511 100644 --- a/src/add-ons/kernel/file_systems/ntfs/attributes.c +++ b/src/add-ons/kernel/file_systems/ntfs/attributes.c @@ -8,8 +8,6 @@ */ -#define MIME_STRING_TYPE 'MIMS' - #include #include #include @@ -23,7 +21,9 @@ #include "mime_table.h" #include "ntfs.h" -//TODO: notify*() + +const char* kHaikuAttrPrefix={"HAIKU-XATTR:"}; + status_t fs_open_attrib_dir(fs_volume *_vol, fs_vnode *_node, void **_cookie) @@ -66,9 +66,9 @@ fs_open_attrib_dir(fs_volume *_vol, fs_vnode *_node, void **_cookie) exit: - if (ctx) + if (ctx != NULL) ntfs_attr_put_search_ctx(ctx); - if (ni) + if (ni != NULL) ntfs_inode_close(ni); TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result)); @@ -153,23 +153,31 @@ fs_read_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie, TRACE("%s - ENTER\n", __FUNCTION__); - while (!(result = ntfs_attrs_walk(cookie->ctx))) { ATTR_RECORD *attr = cookie->ctx->attr; if (attr->type == AT_DATA) { + const char *real_name; // it's the actual file body if (attr->name_length == 0) continue; name = ntfs_attr_name_get((const ntfschar *)(((char *)attr) + attr->name_offset), attr->name_length); - dprintf("found AT_DATA '%s'\n", name); - bufsize = MIN(bufsize, sizeof(struct dirent) + strlen(name) + 1); + + if(strncmp(name, kHaikuAttrPrefix, strlen(kHaikuAttrPrefix)) !=0 ) { + TRACE("found AT_DATA '%s' - Skip\n", name); + continue; + } + TRACE("found AT_DATA '%s' - Found\n", name); + + real_name = name + strlen(kHaikuAttrPrefix); + + bufsize = MIN(bufsize, sizeof(struct dirent) + strlen(real_name) + 1); entry->d_ino = node->vnid; entry->d_dev = ns->id; - entry->d_reclen = sizeof(struct dirent) + strlen(name); + entry->d_reclen = sizeof(struct dirent) + strlen(real_name); //XXX size - strcpy(entry->d_name, name); + strcpy(entry->d_name, real_name); ntfs_attr_name_free(&name); numEntries++; if (numEntries >= *num) @@ -210,9 +218,13 @@ fs_create_attrib(fs_volume *_vol, fs_vnode *_node, const char* name, int ulen; ntfs_inode *ni = NULL; ntfs_attr *na = NULL; - status_t result = B_NO_ERROR; + status_t result = B_NO_ERROR; - TRACE("%s - ENTER\n", __FUNCTION__); + if (ns->flags & B_FS_IS_READONLY) { + return B_READ_ONLY_DEVICE; + } + + TRACE("%s - ENTER - name: [%s] vnid: %d\n", __FUNCTION__, name, node->vnid); LOCK_VOL(ns); @@ -224,7 +236,7 @@ fs_create_attrib(fs_volume *_vol, fs_vnode *_node, const char* name, ni = ntfs_inode_open(ns->ntvol, node->vnid); if (ni == NULL) { result = errno; - ERROR("%s - inode_open: %s\n", __FUNCTION__, strerror(result)); + TRACE("%s - inode_open: %s\n", __FUNCTION__, strerror(result)); goto exit; } @@ -235,59 +247,66 @@ fs_create_attrib(fs_volume *_vol, fs_vnode *_node, const char* name, // check for a named stream if (true) { + char ntfs_attr_name[MAX_PATH] = {0}; + strcat(ntfs_attr_name, kHaikuAttrPrefix); + strcat(ntfs_attr_name,name); + uname = ntfs_calloc(MAX_PATH); - ulen = ntfs_mbstoucs(name, &uname); + ulen = ntfs_mbstoucs(ntfs_attr_name, &uname); if (ulen < 0) { result = EILSEQ; - ERROR("%s - mb alloc: %s\n", __FUNCTION__, strerror(result)); + TRACE("%s - mb alloc: %s\n", __FUNCTION__, strerror(result)); goto exit; } na = ntfs_attr_open(ni, AT_DATA, uname, ulen); - if (na) { - result = EEXIST; - ERROR("%s - ntfs_attr_open: %s\n", __FUNCTION__, - strerror(result)); - goto exit; + if (na != NULL) { + if (ntfs_attr_truncate(na, 0)) { + result = errno; + goto exit; + } + } else { + if (ntfs_attr_add(ni, AT_DATA, uname, ulen, NULL, 0) < 0) { + result = errno; + TRACE("%s - ntfs_attr_add: %s\n", __FUNCTION__, + strerror(result)); + goto exit; + } + na = ntfs_attr_open(ni, AT_DATA, uname, ulen); + if (na == NULL) { + result = errno; + TRACE("%s - ntfs_attr_open: %s\n", __FUNCTION__, + strerror(result)); + goto exit; + } } - //if (ntfs_non_resident_attr_record_add(ni, AT_DATA, uname, ulen, 0, 32, - // 0) < 0) { - if (ntfs_attr_add(ni, AT_DATA, uname, ulen, NULL, 0) < 0) { + if(ntfs_attr_pwrite(na, 0, sizeof(uint32), &type) < 0 ) { result = errno; - //ERROR("%s - ntfs_non_resident_attr_record_add: %s\n", - ERROR("%s - ntfs_attr_add: %s\n", __FUNCTION__, strerror(result)); - goto exit; - } - na = ntfs_attr_open(ni, AT_DATA, uname, ulen); - if (!na) { - result = errno; - ERROR("%s - ntfs_attr_open: %s\n", __FUNCTION__, - strerror(result)); goto exit; } } - cookie = (attrcookie*)ntfs_calloc(sizeof(attrcookie)); if (cookie != NULL) { cookie->omode = openMode; *_cookie = (void*)cookie; - cookie->inode = ni; - cookie->stream = na; - ni = NULL; - na = NULL; + cookie->vnid = node->vnid; + cookie->uname = uname; + cookie->uname_len = ulen; + cookie->type = type; + uname = NULL; } else result = ENOMEM; exit: - if (uname) + if (uname != NULL) free(uname); - if (na) + if (na != NULL) ntfs_attr_close(na); - if (ni) + if (ni != NULL) ntfs_inode_close(ni); TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result)); @@ -310,8 +329,9 @@ fs_open_attrib(fs_volume *_vol, fs_vnode *_node, const char *name, ntfs_inode *ni = NULL; ntfs_attr *na = NULL; status_t result = B_NO_ERROR; + uint32 type = B_XATTR_TYPE; - TRACE("%s - ENTER\n", __FUNCTION__); + TRACE("%s - ENTER - name: [%s] vnid: %d\n", __FUNCTION__, name, node->vnid); LOCK_VOL(ns); @@ -333,18 +353,33 @@ fs_open_attrib(fs_volume *_vol, fs_vnode *_node, const char *name, // check for a named stream if (true) { + char ntfs_attr_name[MAX_PATH] = {0}; + strcat(ntfs_attr_name, kHaikuAttrPrefix); + strcat(ntfs_attr_name, name); + uname = ntfs_calloc(MAX_PATH); - ulen = ntfs_mbstoucs(name, &uname); + ulen = ntfs_mbstoucs(ntfs_attr_name, &uname); if (ulen < 0) { result = EILSEQ; goto exit; } na = ntfs_attr_open(ni, AT_DATA, uname, ulen); - if (na) { + if (na != NULL) { if (openMode & O_TRUNC) { - if (ntfs_attr_truncate(na, 0)) - result = errno; + if (ns->flags & B_FS_IS_READONLY) { + result = B_READ_ONLY_DEVICE; + goto exit; + } else { + if (ntfs_attr_truncate(na, sizeof(uint32))) { + result = errno; + goto exit; + } + } + } + if (ntfs_attr_pread(na, 0, sizeof(uint32), &type) != sizeof(uint32)) { + result = errno; + goto exit; } } else { result = ENOENT; @@ -357,22 +392,23 @@ fs_open_attrib(fs_volume *_vol, fs_vnode *_node, const char *name, if (cookie != NULL) { cookie->omode = openMode; + cookie->vnid = node->vnid; + cookie->uname = uname; + cookie->uname_len = ulen; + cookie->type = type; *_cookie = (void*)cookie; - cookie->inode = ni; - cookie->stream = na; - ni = NULL; - na = NULL; + uname = NULL; } else result = ENOMEM; exit: - if (uname) + if (uname != NULL) free(uname); - if (na) + if (na != NULL) ntfs_attr_close(na); - if (ni) + if (ni != NULL) ntfs_inode_close(ni); TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result)); @@ -386,6 +422,7 @@ exit: status_t fs_close_attrib(fs_volume *_vol, fs_vnode *_node, void *cookie) { + TRACE("%s vnid: %d\n", __FUNCTION__, ((vnode*)_node->private_node)->vnid); return B_NO_ERROR; } @@ -398,10 +435,8 @@ fs_free_attrib_cookie(fs_volume *_vol, fs_vnode *_node, void *_cookie) LOCK_VOL(ns); - if (cookie->stream) - ntfs_attr_close(cookie->stream); - if (cookie->inode) - ntfs_inode_close(cookie->inode); + if (cookie->uname != NULL) + free(cookie->uname); UNLOCK_VOL(ns); @@ -415,21 +450,33 @@ fs_read_attrib_stat(fs_volume *_vol, fs_vnode *_node, void *_cookie, struct stat *stat) { nspace *ns = (nspace *)_vol->private_volume; - //vnode *node = (vnode *)_node->private_node; + vnode *node = (vnode *)_node->private_node; attrcookie *cookie = (attrcookie *)_cookie; - //ntfs_inode *ni = cookie->inode; - ntfs_attr *na = cookie->stream; - - //status_t result = B_NO_ERROR; + ntfs_inode *ni = NULL; + ntfs_attr *na = NULL; + status_t result = B_NO_ERROR; LOCK_VOL(ns); - //ERRPRINT("%s - ENTER\n", __FUNCTION__); + ni = ntfs_inode_open(ns->ntvol, node->vnid); + if (ni == NULL) { + result = errno; + goto exit; + } + na = ntfs_attr_open(ni, AT_DATA, cookie->uname, cookie->uname_len); + if (na == NULL) { + result = errno; + goto exit; + } - stat->st_type = B_XATTR_TYPE; - stat->st_size = na ? na->data_size : 0; + stat->st_type = cookie->type; + stat->st_size = na ? na->data_size - sizeof(uint32) : 0; -//exit: +exit: + if (na != NULL) + ntfs_attr_close(na); + if (ni != NULL) + ntfs_inode_close(ni); UNLOCK_VOL(ns); @@ -442,10 +489,10 @@ fs_read_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos, void *buffer, size_t *len) { nspace *ns = (nspace *)_vol->private_volume; - //vnode *node = (vnode *)_node->private_node; + vnode *node = (vnode *)_node->private_node; attrcookie *cookie = (attrcookie *)_cookie; - ntfs_inode *ni = cookie->inode; - ntfs_attr *na = cookie->stream; + ntfs_inode *ni = NULL; + ntfs_attr *na = NULL; size_t size = *len; int total = 0; status_t result = B_NO_ERROR; @@ -455,20 +502,32 @@ fs_read_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos, return EINVAL; } - LOCK_VOL(ns); - TRACE("%s - ENTER\n", __FUNCTION__); + TRACE("%s - ENTER vnid: %d\n", __FUNCTION__, node->vnid); + + ni = ntfs_inode_open(ns->ntvol, node->vnid); + if (ni == NULL) { + result = errno; + goto exit; + } + na = ntfs_attr_open(ni, AT_DATA, cookie->uname, cookie->uname_len); + if (na == NULL) { + result = errno; + goto exit; + } + + pos += sizeof(uint32); // it is a named stream - if (na) { + if (na != NULL) { if (pos + size > na->data_size) size = na->data_size - pos; while (size) { off_t bytesRead = ntfs_attr_pread(na, pos, size, buffer); if (bytesRead < (s64)size) { - ntfs_log_error("ntfs_attr_pread returned less bytes than " + ERROR("ntfs_attr_pread returned less bytes than " "requested.\n"); } if (bytesRead <= 0) { @@ -487,10 +546,12 @@ fs_read_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos, result = ENOENT; // TODO } - fs_ntfs_update_times(_vol, ni, NTFS_UPDATE_ATIME); // XXX needed ? - exit: - + if (na != NULL) + ntfs_attr_close(na); + if (ni != NULL) + ntfs_inode_close(ni); + TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result)); UNLOCK_VOL(ns); @@ -500,22 +561,24 @@ exit: status_t -fs_write_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie,off_t pos, +fs_write_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos, const void *buffer, size_t *_length) { nspace *ns = (nspace *)_vol->private_volume; - //vnode *node = (vnode *)_node->private_node; + vnode *node = (vnode *)_node->private_node; attrcookie *cookie = (attrcookie *)_cookie; - ntfs_inode *ni = cookie->inode; - ntfs_attr *na = cookie->stream; + ntfs_inode *ni = NULL; + ntfs_attr *na = NULL; size_t size = *_length; + char *attr_name = NULL; + char *real_name = NULL; int total = 0; status_t result = B_NO_ERROR; - TRACE("%s - ENTER!!\n", __FUNCTION__); - if (ns->flags & B_FS_IS_READONLY) { - ERROR("ntfs is read-only\n"); - return EROFS; + TRACE("%s - ENTER vnode: %d\n", __FUNCTION__, node->vnid); + + if (ns->flags & B_FS_IS_READONLY) { + return B_READ_ONLY_DEVICE; } if (pos < 0) { @@ -523,13 +586,23 @@ fs_write_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie,off_t pos, return EINVAL; } - LOCK_VOL(ns); - TRACE("%s - ENTER\n", __FUNCTION__); + ni = ntfs_inode_open(ns->ntvol, node->vnid); + if (ni == NULL) { + result = errno; + goto exit; + } + na = ntfs_attr_open(ni, AT_DATA, cookie->uname, cookie->uname_len); + if (na == NULL) { + result = errno; + goto exit; + } + + pos += sizeof(uint32); // it is a named stream - if (na) { + if (na != NULL) { if (cookie->omode & O_APPEND) pos = na->data_size; @@ -560,15 +633,27 @@ fs_write_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie,off_t pos, *_length = total; } else { *_length = 0; - return EINVAL; + result = EINVAL; + goto exit; } - - - if (total > 0) - fs_ntfs_update_times(_vol, ni, NTFS_UPDATE_ATIME); // XXX needed ? - -exit: + if (ntfs_ucstombs(na->name, na->name_len, &attr_name, 0) >= 0) { + if (attr_name != NULL) { + if(strncmp(attr_name, kHaikuAttrPrefix, strlen(kHaikuAttrPrefix)) !=0 ) + goto exit; + real_name = attr_name + strlen(kHaikuAttrPrefix); + notify_attribute_changed(ns->id, MREF(ni->mft_no), + real_name, B_ATTR_CHANGED); + free(attr_name); + } + } + +exit: + if (na != NULL) + ntfs_attr_close(na); + if (ni != NULL) + ntfs_inode_close(ni); + TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result)); UNLOCK_VOL(ns); @@ -576,3 +661,68 @@ exit: return result; } + +status_t +fs_remove_attrib(fs_volume *_vol, fs_vnode *_node, const char* name) +{ + nspace *ns = (nspace *)_vol->private_volume; + vnode *node = (vnode *)_node->private_node; + char ntfs_attr_name[MAX_PATH]={0}; + ntfschar *uname = NULL; + int ulen; + ntfs_inode *ni = NULL; + status_t result = B_NO_ERROR; + + TRACE("%s - ENTER - name: [%s]\n", __FUNCTION__, name); + + if (ns->flags & B_FS_IS_READONLY) { + ERROR("ntfs is read-only\n"); + return B_READ_ONLY_DEVICE; + } + + LOCK_VOL(ns); + + if (node == NULL) { + result = EINVAL; + goto exit; + } + + ni = ntfs_inode_open(ns->ntvol, node->vnid); + if (ni == NULL) { + result = errno; + goto exit; + } + + strcat(ntfs_attr_name, kHaikuAttrPrefix); + strcat(ntfs_attr_name, name); + + uname = ntfs_calloc(MAX_PATH); + ulen = ntfs_mbstoucs(ntfs_attr_name, &uname); + if (ulen < 0) { + result = EILSEQ; + goto exit; + } + + if (ntfs_attr_remove(ni, AT_DATA, uname, ulen)) { + result = ENOENT; + goto exit; + } + + if (!(ni->flags & FILE_ATTR_ARCHIVE)) { + ni->flags |= FILE_ATTR_ARCHIVE; + NInoFileNameSetDirty(ni); + } + notify_attribute_changed(ns->id, MREF(ni->mft_no), name, B_ATTR_REMOVED); +exit: + if (uname != NULL) + free(uname); + + if (ni != NULL) + ntfs_inode_close(ni); + + TRACE("%s - EXIT, result is %s\n", __FUNCTION__, strerror(result)); + + UNLOCK_VOL(ns); + + return result; +} diff --git a/src/add-ons/kernel/file_systems/ntfs/attributes.h b/src/add-ons/kernel/file_systems/ntfs/attributes.h index a7d924ef81..4e29b4d574 100644 --- a/src/add-ons/kernel/file_systems/ntfs/attributes.h +++ b/src/add-ons/kernel/file_systems/ntfs/attributes.h @@ -33,6 +33,7 @@ status_t fs_read_attrib(fs_volume *_vol, fs_vnode *_node, void *cookie, off_t pos, void *buffer, size_t *_length); status_t fs_write_attrib(fs_volume *_vol, fs_vnode *_node, void *cookie, off_t pos, const void *buffer, size_t *_length); +status_t fs_remove_attrib(fs_volume *_vol, fs_vnode *_node, const char* name); #endif // NTFS_ATTRIBUTES_H diff --git a/src/add-ons/kernel/file_systems/ntfs/fake_attributes.c b/src/add-ons/kernel/file_systems/ntfs/fake_attributes.c index 517add5d57..be029521f6 100644 --- a/src/add-ons/kernel/file_systems/ntfs/fake_attributes.c +++ b/src/add-ons/kernel/file_systems/ntfs/fake_attributes.c @@ -21,13 +21,27 @@ #include "fake_attributes.h" #include "mime_table.h" -int32 kBeOSTypeCookie = 0x1234; +int32 kOpenTypeCookie = 0; +int32 kCloseTypeCookie = 1; +int32 kSetTypeCookie = 0x1234; +int32 kFreeTypeCookie = 0x87654321; + +char *kFailBackMime = {"application/octet-stream"}; +char *kDirectoryMime = {"application/x-vnd.Be-directory"}; + status_t set_mime(vnode *node, const char *filename) { struct ext_mime *p; - int32 namelen, ext_len; - node->mime = NULL; + int32 namelen; + int32 ext_len; + node->mime = kFailBackMime; + + if (filename == NULL) + { + node->mime = kDirectoryMime; + return B_NO_ERROR; + } namelen = strlen(filename); for (p=mimes; p->extension; p++) { @@ -63,17 +77,18 @@ fake_open_attrib_dir(fs_volume *_vol, fs_vnode *_node, void **_cookie) goto exit; } - *(int32 *)(*_cookie) = 0; + *(int32 *)(*_cookie) = kOpenTypeCookie; exit: - TRACE("fs_open_attrdir - EXIT, result is %s\n", strerror(result)); + TRACE("fake_open_attrdir - EXIT, result is %s\n", strerror(result)); UNLOCK_VOL(ns); return result; } + status_t fake_close_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie) { @@ -83,7 +98,7 @@ fake_close_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie) LOCK_VOL(ns); - *(int32 *)_cookie = 1; + *(int32 *)_cookie = kCloseTypeCookie; TRACE("fake_close_attrdir - EXIT\n"); @@ -92,6 +107,7 @@ fake_close_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie) return B_NO_ERROR; } + status_t fake_free_attrib_dir_cookie(fs_volume *_vol, fs_vnode *_node, void *_cookie) { @@ -109,7 +125,7 @@ fake_free_attrib_dir_cookie(fs_volume *_vol, fs_vnode *_node, void *_cookie) goto exit; } - *(int32 *)_cookie = 0x87654321; + *(int32 *)_cookie = kFreeTypeCookie; free(_cookie); exit: @@ -122,6 +138,7 @@ exit: return result; } + status_t fake_rewind_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie) { @@ -134,13 +151,13 @@ fake_rewind_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie) TRACE("fake_rewind_attrcookie - ENTER\n"); if (_cookie == NULL) { - TRACE("fake_rewind_attrcookie - error: fs_rewind_attrcookie" + TRACE("fake_rewind_attrcookie - error: fake_rewind_attrcookie" "called with null cookie\n"); result = EINVAL; goto exit; } - *(uint32 *)_cookie = 0; + *(uint32 *)_cookie = kOpenTypeCookie; exit: @@ -167,16 +184,16 @@ fake_read_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie, *num = 0; - if ((*cookie == 0) && (node->mime)) { + if ((*cookie == kOpenTypeCookie) && (node->mime)) { *num = 1; entry->d_ino = node->vnid; entry->d_dev = ns->id; - entry->d_reclen = 10; + entry->d_reclen = sizeof(struct dirent) + 10; strcpy(entry->d_name, "BEOS:TYPE"); } - *cookie = 1; + *cookie = kCloseTypeCookie; TRACE("fake_read_attrdir - EXIT\n"); @@ -186,28 +203,45 @@ fake_read_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie, } status_t -fake_open_attrib(fs_volume *_vol, fs_vnode *_node, const char *name, - int openMode, void **_cookie) +fake_create_attrib(fs_volume *_vol, fs_vnode *_node, const char* name, + uint32 type, int openMode, void** _cookie) { nspace *ns = (nspace *)_vol->private_volume; - vnode *node = (vnode *)_node->private_node; int result = B_NO_ERROR; LOCK_VOL(ns); - TRACE("fake_open_attrib - ENTER\n"); + TRACE("fake_create_attrib - ENTER (name = [%s])\n",name); - if (strcmp(name, "BEOS:TYPE")) { - result = ENOENT; + if (strcmp(name, "BEOS:TYPE") != 0) goto exit; - } + + *_cookie = &kSetTypeCookie; - if (node->mime == NULL) { - result = ENOENT; - goto exit; - } +exit: - *_cookie = &kBeOSTypeCookie; + TRACE("fake_create_attrib - EXIT, result is %s\n", strerror(result)); + + UNLOCK_VOL(ns); + + return result; +} + +status_t +fake_open_attrib(fs_volume *_vol, fs_vnode *_node, const char *name, + int openMode, void **_cookie) +{ + nspace *ns = (nspace *)_vol->private_volume; + int result = B_NO_ERROR; + + LOCK_VOL(ns); + + TRACE("fake_open_attrib - ENTER (name = [%s])\n",name); + + if (strcmp(name, "BEOS:TYPE") != 0) + goto exit; + + *_cookie = &kSetTypeCookie; exit: @@ -238,25 +272,23 @@ fake_read_attrib_stat(fs_volume *_vol, fs_vnode *_node, void *_cookie, struct stat *stat) { nspace *ns = (nspace *)_vol->private_volume; - vnode *node = (vnode *)_node->private_node; + vnode *node = (vnode *)_node->private_node; int result = B_NO_ERROR; LOCK_VOL(ns); TRACE("fake_read_attr_stat - ENTER\n"); - if (_cookie != &kBeOSTypeCookie) { - result = ENOENT; - goto exit; - } - - if (node->mime == NULL) { + if (_cookie != &kSetTypeCookie) { result = ENOENT; goto exit; } stat->st_type = MIME_STRING_TYPE; - stat->st_size = strlen(node->mime) + 1; + if (node->mime == NULL) + stat->st_size = 0; + else + stat->st_size = strlen(node->mime) + 1; exit: @@ -274,7 +306,7 @@ fake_read_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,void *buffer, size_t *_length) { nspace *ns = (nspace *)_vol->private_volume; - vnode *node = (vnode *)_node->private_node; + vnode *node = (vnode *)_node->private_node; int result = B_NO_ERROR; @@ -282,7 +314,7 @@ fake_read_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, TRACE("fake_read_attr - ENTER\n"); - if (_cookie != &kBeOSTypeCookie) { + if (_cookie != &kSetTypeCookie) { result = ENOENT; goto exit; } @@ -315,23 +347,5 @@ status_t fake_write_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos, const void *buffer, size_t *_length) { - nspace *ns = (nspace *)_vol->private_volume; - - int result = B_NO_ERROR; - - LOCK_VOL(ns); - - TRACE("fake_write_attr - ENTER\n"); - - *_length = 0; - - if (_cookie != &kBeOSTypeCookie) { - result = ENOSYS; - } - - TRACE("fake_write_attrib - EXIT, result is %s\n", strerror(result)); - - UNLOCK_VOL(ns); - - return result; + return B_NO_ERROR; } diff --git a/src/add-ons/kernel/file_systems/ntfs/fake_attributes.h b/src/add-ons/kernel/file_systems/ntfs/fake_attributes.h index c12749418a..f121f0fdb6 100644 --- a/src/add-ons/kernel/file_systems/ntfs/fake_attributes.h +++ b/src/add-ons/kernel/file_systems/ntfs/fake_attributes.h @@ -24,6 +24,8 @@ status_t fake_rewind_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie); status_t fake_read_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie, struct dirent *buf, size_t bufsize, uint32 *num); +status_t fake_create_attrib(fs_volume *_vol, fs_vnode *_node, const char *name, + uint32 type, int openMode, void** _cookie); status_t fake_open_attrib(fs_volume *_vol, fs_vnode *_node, const char *name, int openMode, void **_cookie); status_t fake_close_attrib(fs_volume *_vol, fs_vnode *_node, void *cookie); diff --git a/src/add-ons/kernel/file_systems/ntfs/fs_func.c b/src/add-ons/kernel/file_systems/ntfs/fs_func.c index 3427e4b314..82188287ad 100644 --- a/src/add-ons/kernel/file_systems/ntfs/fs_func.c +++ b/src/add-ons/kernel/file_systems/ntfs/fs_func.c @@ -43,6 +43,7 @@ #include "ntfs.h" #include "volume_util.h" +static const char* kNTFSUntitled = {"NTFS Untitled"}; typedef struct identify_cookie { NTFS_BOOT_SECTOR boot; @@ -118,16 +119,22 @@ static u64 ntfs_inode_lookup(fs_volume *_vol, ino_t parent, const char *name) { nspace *ns = (nspace*)_vol->private_volume; - + ntfschar *uname = NULL; + int uname_len; u64 ino = (u64)-1; u64 inum; - ntfs_inode *dir_ni; + ntfs_inode *dir_ni; /* Open target directory. */ dir_ni = ntfs_inode_open(ns->ntvol, parent); if (dir_ni) { + uname_len = ntfs_mbstoucs(name, &uname); + if (uname_len < 0) { + errno = EINVAL; + return (ino); + } /* Lookup file */ - inum = ntfs_inode_lookup_by_mbsname(dir_ni, name); + inum = ntfs_inode_lookup_by_name(dir_ni, uname, uname_len); /* never return inodes 0 and 1 */ if (MREF(inum) <= 1) { inum = (u64)-1; @@ -139,6 +146,8 @@ ntfs_inode_lookup(fs_volume *_vol, ino_t parent, const char *name) else ino = MREF(inum); } + if (uname != NULL) + free(uname); return (ino); } @@ -149,137 +158,53 @@ ntfs_remove(fs_volume *_vol, ino_t parent, const char *name) nspace *ns = (nspace*)_vol->private_volume; ntfschar *uname = NULL; - ntfs_inode *dir_ni = NULL, *ni = NULL; - int res = B_OK, uname_len; + ntfs_inode *ni = NULL; + ntfs_inode *dir_ni = NULL; + int result = B_OK; + int uname_len; u64 iref; /* Open parent directory. */ dir_ni = ntfs_inode_open(ns->ntvol, parent); if (!dir_ni) { - res = EINVAL; + result = EINVAL; goto exit; } /* Generate unicode filename. */ uname_len = ntfs_mbstoucs(name, &uname); if (uname_len < 0) { - res = EINVAL; + result = EINVAL; goto exit; } /* Open object for delete. */ - iref = ntfs_inode_lookup_by_mbsname(dir_ni, name); + iref = ntfs_inode_lookup_by_name(dir_ni, uname, uname_len); if (iref == (u64)-1) { - res = EINVAL; + result = EINVAL; goto exit; } /* deny unlinking metadata files */ if (MREF(iref) < FILE_first_user) { - res = EINVAL; + result = EINVAL; goto exit; } ni = ntfs_inode_open(ns->ntvol, MREF(iref)); if (!ni) { - res = EINVAL; + result = EINVAL; goto exit; } if (ntfs_delete(ns->ntvol, (char*)NULL, ni, dir_ni, uname, uname_len)) - res = EINVAL; + result = EINVAL; /* ntfs_delete() always closes ni and dir_ni */ ni = dir_ni = NULL; exit: - if (ni) + if (ni != NULL) ntfs_inode_close(ni); - if (dir_ni) + if (dir_ni != NULL) ntfs_inode_close(dir_ni); free(uname); - return res; -} - - -static status_t -do_unlink(fs_volume *_vol, vnode *dir, const char *name, bool isdir) -{ - nspace *ns = (nspace*)_vol->private_volume; - ino_t vnid; - vnode *node = NULL; - ntfs_inode *ni = NULL; - ntfs_inode *bi = NULL; - ntfschar *uname = NULL; - int unameLength; - - status_t result = B_NO_ERROR; - - unameLength = ntfs_mbstoucs(name, &uname); - if (unameLength < 0) { - result = EINVAL; - goto exit1; - } - - bi = ntfs_inode_open(ns->ntvol, dir->vnid); - if (bi == NULL) { - result = ENOENT; - goto exit1; - } - - vnid = MREF(ntfs_inode_lookup_by_name(bi, uname, unameLength)); - - if ( vnid == (u64)-1 || vnid == FILE_root) { - result = EINVAL; - goto exit1; - } - - result = get_vnode(_vol, vnid, (void**)&node); - - if (result != B_NO_ERROR || node==NULL) { - result = ENOENT; - goto exit1; - } - - ni = ntfs_inode_open(ns->ntvol, node->vnid); - if (ni == NULL) { - result = ENOENT; - goto exit2; - } - - if (isdir) { - if (!(ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) { - result = ENOTDIR; - goto exit2; - } - if (ntfs_check_empty_dir(ni)<0) { - result = ENOTEMPTY; - goto exit2; - } - } else if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) { - result = EISDIR; - goto exit2; - } - - // TODO: the file must not be deleted here, only unlinked! - if (ntfs_delete(ns->ntvol, (char*)NULL, ni, bi, uname, unameLength)) - result = errno; - - ni = bi = NULL; - - node->parent_vnid = dir->vnid; - - notify_entry_removed(ns->id, dir->vnid, name, vnid); - - remove_vnode(_vol, vnid); - - result = 0; -exit2: - put_vnode(_vol, vnid); -exit1: - free(uname); - - if (ni) - ntfs_inode_close(ni); - if (bi) - ntfs_inode_close(bi); - return result; } @@ -301,10 +226,10 @@ float fs_identify_partition(int fd, partition_data *partition, void **_cookie) { NTFS_BOOT_SECTOR boot; - identify_cookie *cookie; + char devpath[MAX_PATH]; + identify_cookie *cookie = NULL; ntfs_volume *ntVolume; uint8 *buf = (uint8*)&boot; - char devpath[256]; // read in the boot sector TRACE("fs_identify_partition: read in the boot sector\n"); @@ -325,19 +250,6 @@ fs_identify_partition(int fd, partition_data *partition, void **_cookie) return -1; } - // get path for device - if (!ioctl(fd, B_GET_PATH_FOR_DEVICE, devpath)) { - ERROR("fs_identify_partition: couldn't get path for device\n"); - return -1; - } - - // try mount - ntVolume = utils_mount_volume(devpath, MS_RDONLY | MS_RECOVER); - if (!ntVolume) { - ERROR("fs_identify_partition: mount failed\n"); - return -1; - } - // allocate identify_cookie cookie = (identify_cookie *)malloc(sizeof(identify_cookie)); if (!cookie) { @@ -345,15 +257,21 @@ fs_identify_partition(int fd, partition_data *partition, void **_cookie) return -1; } + strcpy(cookie->label, kNTFSUntitled); + + // try get path for device + if (ioctl(fd, B_GET_PATH_FOR_DEVICE, devpath)) { + // try mount + ntVolume = utils_mount_volume(devpath, MS_RDONLY | MS_RECOVER); + if (ntVolume != NULL) { + if (ntVolume->vol_name && ntVolume->vol_name[0] != '\0') + strcpy(cookie->label, ntVolume->vol_name); + ntfs_umount(ntVolume, true); + } + } + memcpy(&cookie->boot, &boot, 512); - strcpy(cookie->label, "NTFS Volume"); - - if (ntVolume->vol_name && ntVolume->vol_name[0] != '\0') - strcpy(cookie->label, ntVolume->vol_name); - - ntfs_umount(ntVolume, true); - *_cookie = cookie; return 0.8f; @@ -422,7 +340,7 @@ fs_mount(fs_volume *_vol, const char *device, ulong flags, const char *args, ns->noatime = strcasecmp(get_driver_parameter(handle, "no_atime", "true", "true"), "true") == 0; ns->fake_attrib = strcasecmp(get_driver_parameter(handle, "fake_attributes", - "false", "false"), "false") != 0; + "true", "true"), "true") == 0; unload_driver_settings(handle); if (ns->ro || (flags & B_MOUNT_READ_ONLY) != 0 @@ -437,13 +355,28 @@ fs_mount(fs_volume *_vol, const char *device, ulong flags, const char *args, gNTFSVnodeOps.free_attr_dir_cookie = fake_free_attrib_dir_cookie; gNTFSVnodeOps.read_attr_dir = fake_read_attrib_dir; gNTFSVnodeOps.rewind_attr_dir = fake_rewind_attrib_dir; - gNTFSVnodeOps.create_attr = NULL; + gNTFSVnodeOps.create_attr = fake_create_attrib; gNTFSVnodeOps.open_attr = fake_open_attrib; gNTFSVnodeOps.close_attr = fake_close_attrib; gNTFSVnodeOps.free_attr_cookie = fake_free_attrib_cookie; gNTFSVnodeOps.read_attr = fake_read_attrib; gNTFSVnodeOps.read_attr_stat = fake_read_attrib_stat; gNTFSVnodeOps.write_attr = fake_write_attrib; + gNTFSVnodeOps.remove_attr = NULL; + } else { + gNTFSVnodeOps.open_attr_dir = fs_open_attrib_dir; + gNTFSVnodeOps.close_attr_dir = fs_close_attrib_dir; + gNTFSVnodeOps.free_attr_dir_cookie = fs_free_attrib_dir_cookie; + gNTFSVnodeOps.read_attr_dir = fs_read_attrib_dir; + gNTFSVnodeOps.rewind_attr_dir = fs_rewind_attrib_dir; + gNTFSVnodeOps.create_attr = fs_create_attrib; + gNTFSVnodeOps.open_attr = fs_open_attrib; + gNTFSVnodeOps.close_attr = fs_close_attrib; + gNTFSVnodeOps.free_attr_cookie = fs_free_attrib_cookie; + gNTFSVnodeOps.read_attr = fs_read_attrib; + gNTFSVnodeOps.read_attr_stat = fs_read_attrib_stat; + gNTFSVnodeOps.write_attr = fs_write_attrib; + gNTFSVnodeOps.remove_attr = fs_remove_attrib; } ns->ntvol = utils_mount_volume(device, mountFlags | MS_RECOVER); @@ -535,7 +468,7 @@ fs_rfsstat(fs_volume *_vol, struct fs_info *fss) break; } if (i < 0) - strcpy(fss->volume_name, "NTFS Untitled"); + strcpy(fss->volume_name, kNTFSUntitled); else fss->volume_name[i + 1] = 0; @@ -557,7 +490,7 @@ fs_wfsstat(fs_volume *_vol, const struct fs_info *fss, uint32 mask) if (ns->flags & B_FS_IS_READONLY) { ERROR("ntfs is read-only\n"); - return EROFS; + return B_READ_ONLY_DEVICE; } LOCK_VOL(ns); @@ -575,70 +508,50 @@ exit: status_t -fs_walk(fs_volume *_vol, fs_vnode *_dir, const char *file, ino_t *vnid) +fs_walk(fs_volume *_vol, fs_vnode *_dir, const char *file, ino_t *_vnid) { nspace *ns = (nspace*)_vol->private_volume; vnode *baseNode = (vnode*)_dir->private_node; vnode *newNode = NULL; - ntfschar *unicode = NULL; - ntfs_inode *bi = NULL; status_t result = B_NO_ERROR; - int len; LOCK_VOL(ns); TRACE("fs_walk - ENTER : find for \"%s\"\n",file); - if (ns == NULL || _dir == NULL || file == NULL || vnid == NULL) { + if (ns == NULL || _dir == NULL || file == NULL || _vnid == NULL) { result = EINVAL; goto exit; } if (!strcmp(file, ".")) { - *vnid = baseNode->vnid; - if (get_vnode(_vol, *vnid, (void**)&newNode) != 0) + *_vnid = baseNode->vnid; + if (get_vnode(_vol, *_vnid, (void**)&newNode) != 0) result = ENOENT; } else if (!strcmp(file, "..") && baseNode->vnid != FILE_root) { - *vnid = baseNode->parent_vnid; - if (get_vnode(_vol, *vnid, (void**)&newNode) != 0) + *_vnid = baseNode->parent_vnid; + if (get_vnode(_vol, *_vnid, (void**)&newNode) != 0) result = ENOENT; } else { - unicode = ntfs_calloc(MAX_PATH); - len = ntfs_mbstoucs(file, &unicode); - if (len < 0) { - result = EILSEQ; + ino_t vnid = ntfs_inode_lookup(_vol, baseNode->vnid, file); + + if (vnid == (u64)-1) { + result = errno; goto exit; } - bi = ntfs_inode_open(ns->ntvol, baseNode->vnid); - if (!bi) { - result = ENOENT; - goto exit; - } - - *vnid = MREF(ntfs_inode_lookup_by_name(bi, unicode, len)); - TRACE("fs_walk - VNID = %d\n",*vnid); - - ntfs_inode_close(bi); - - if (*vnid == (u64)-1) { - result = EINVAL; - goto exit; - } - - if (get_vnode(_vol, *vnid, (void**)&newNode) != 0) + if (get_vnode(_vol, vnid, (void**)&newNode) != 0) result = ENOENT; if (newNode!=NULL) newNode->parent_vnid = baseNode->vnid; + + *_vnid = vnid; } exit: TRACE("fs_walk - EXIT, result is %s\n", strerror(result)); - if (unicode) - free(unicode); - UNLOCK_VOL(ns); return result; @@ -676,7 +589,7 @@ fs_get_vnode_name(fs_volume *_vol, fs_vnode *_vnode, char *buffer, strlcpy(buffer, name, bufferSize); exit: - if (ni) + if (ni != NULL) ntfs_inode_close(ni); UNLOCK_VOL(ns); @@ -723,7 +636,7 @@ fs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type, if (ns->fake_attrib) { if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) - set_mime(newNode, ".***"); + set_mime(newNode, NULL); else { name = (char*)malloc(MAX_PATH); if (name != NULL) { @@ -893,7 +806,7 @@ fs_rstat(fs_volume *_vol, fs_vnode *_node, struct stat *stbuf) stbuf->st_mtim = ntfs2timespec(ni->last_data_change_time); exit: - if (ni) + if (ni != NULL) ntfs_inode_close(ni); TRACE("fs_rstat - EXIT, result is %s\n", strerror(result)); @@ -954,7 +867,7 @@ fs_wstat(fs_volume *_vol, fs_vnode *_node, const struct stat *st, uint32 mask) } exit: - if (ni) + if (ni != NULL) ntfs_inode_close(ni); TRACE("fs_wstat: EXIT with (%s)\n", strerror(result)); @@ -1008,7 +921,7 @@ fs_fsync(fs_volume *_vol, fs_vnode *_node) ntfs_inode_sync(ni); exit: - if (ni) + if (ni != NULL) ntfs_inode_close(ni); TRACE("fs_fsync: EXIT\n"); @@ -1062,10 +975,10 @@ fs_open(fs_volume *_vol, fs_vnode *_node, int omode, void **_cookie) result = ENOMEM; exit: - if (na) + if (na != NULL) ntfs_attr_close(na); - if (ni) + if (ni != NULL) ntfs_inode_close(ni); TRACE("fs_open - EXIT\n"); @@ -1086,15 +999,14 @@ fs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode, vnode *newNode = NULL; ntfs_attr *na = NULL; ntfs_inode *ni = NULL; - ntfs_inode *bi = NULL; + ntfs_inode *dir_ni = NULL; ntfschar *uname = NULL; status_t result = B_NO_ERROR; int unameLength; - if (ns->flags & B_FS_IS_READONLY) { - ERROR("ntfs is read-only\n"); - return EROFS; - } + if (ns->flags & B_FS_IS_READONLY) { + return B_READ_ONLY_DEVICE; + } LOCK_VOL(ns); @@ -1111,13 +1023,13 @@ fs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode, goto exit; } - bi = ntfs_inode_open(ns->ntvol, dir->vnid); - if (bi == NULL) { + dir_ni = ntfs_inode_open(ns->ntvol, dir->vnid); + if (dir_ni == NULL) { result = ENOENT; goto exit; } - if (!(bi->mrec->flags & MFT_RECORD_IS_DIRECTORY)) { + if (!(dir_ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) { result = EINVAL; goto exit; } @@ -1137,53 +1049,58 @@ fs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode, goto exit; } - ni = ntfs_pathname_to_inode(ns->ntvol, bi, name); - if (ni) { + ni = ntfs_pathname_to_inode(ns->ntvol, dir_ni, name); + if (ni != NULL) { // file exists *_vnid = MREF(ni->mft_no); if (omode & O_TRUNC) { na = ntfs_attr_open(ni, AT_DATA, NULL, 0); - if (na) { + if (na != NULL) { if (ntfs_attr_truncate(na, 0)) result = errno; + ntfs_attr_close(na); } else result = errno; } ntfs_inode_close(ni); } else { le32 securid = const_cpu_to_le32(0); - ni = ntfs_create(bi, securid, uname, unameLength, S_IFREG); - if (ni) { - *_vnid = MREF(ni->mft_no); - + ni = ntfs_create(dir_ni, securid, uname, unameLength, S_IFREG); + if (ni != NULL) { + ino_t vnid = MREF(ni->mft_no); + newNode = (vnode*)ntfs_calloc(sizeof(vnode)); if (newNode == NULL) { result = ENOMEM; goto exit; } - if (ntfs_inode_close_in_dir(ni, bi)) { - result = EINVAL; - goto exit; - } - - newNode->vnid = *_vnid; - newNode->parent_vnid = MREF(bi->mft_no); + newNode->vnid = vnid; + newNode->parent_vnid = dir->vnid; - if (ns->fake_attrib) - set_mime(newNode, name); - ni->flags |= FILE_ATTR_ARCHIVE; - ntfs_inode_update_mbsname(bi, name, ni->mft_no); NInoSetDirty(ni); - result = B_NO_ERROR; - result = publish_vnode(_vol, *_vnid, (void*)newNode, &gNTFSVnodeOps, + result = publish_vnode(_vol, vnid, (void*)newNode, &gNTFSVnodeOps, S_IFREG, 0); - - ntfs_mark_free_space_outdated(ns); - fs_ntfs_update_times(_vol, bi, NTFS_UPDATE_MCTIME); - notify_entry_created(ns->id, MREF(bi->mft_no), name, *_vnid); + + if (ntfs_inode_close_in_dir(ni, dir_ni)) { + result = EINVAL; + goto exit; + } + + *_vnid = vnid; + + if (ns->fake_attrib) { + if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) + set_mime(newNode, NULL); + else + set_mime(newNode, name); + } + + ntfs_mark_free_space_outdated(ns); + fs_ntfs_update_times(_vol, dir_ni, NTFS_UPDATE_MCTIME); + notify_entry_created(ns->id, dir->vnid, name, vnid); } else result = errno; } @@ -1193,12 +1110,12 @@ exit: *_cookie = cookie; else free(cookie); - - if (na) - ntfs_attr_close(na); - if (bi) - ntfs_inode_close(bi); - free(uname); + + if (dir_ni != NULL) + ntfs_inode_close(dir_ni); + + if (uname != NULL) + free(uname); TRACE("fs_create - EXIT, result is %s\n", strerror(result)); @@ -1209,11 +1126,11 @@ exit: status_t -fs_read(fs_volume *_vol, fs_vnode *_dir, void *_cookie, off_t offset, void *buf, +fs_read(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t offset, void *buf, size_t *len) { nspace *ns = (nspace*)_vol->private_volume; - vnode *node = (vnode*)_dir->private_node; + vnode *node = (vnode*)_node->private_node; ntfs_inode *ni = NULL; ntfs_attr *na = NULL; size_t size = *len; @@ -1245,7 +1162,7 @@ fs_read(fs_volume *_vol, fs_vnode *_dir, void *_cookie, off_t offset, void *buf, } na = ntfs_attr_open(ni, AT_DATA, NULL, 0); - if (!na) { + if (na == NULL) { *len = 0; result = EINVAL; goto exit2; @@ -1273,11 +1190,11 @@ fs_read(fs_volume *_vol, fs_vnode *_dir, void *_cookie, off_t offset, void *buf, fs_ntfs_update_times(_vol, ni, NTFS_UPDATE_ATIME); exit: - if (na) + if (na != NULL) ntfs_attr_close(na); exit2: - if (ni) + if (ni != NULL) ntfs_inode_close(ni); UNLOCK_VOL(ns); @@ -1289,11 +1206,11 @@ exit2: status_t -fs_write(fs_volume *_vol, fs_vnode *_dir, void *_cookie, off_t offset, +fs_write(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t offset, const void *buf, size_t *len) { nspace *ns = (nspace*)_vol->private_volume; - vnode *node = (vnode*)_dir->private_node; + vnode *node = (vnode*)_node->private_node; filecookie *cookie = (filecookie*)_cookie; ntfs_inode *ni = NULL; ntfs_attr *na = NULL; @@ -1303,7 +1220,7 @@ fs_write(fs_volume *_vol, fs_vnode *_dir, void *_cookie, off_t offset, if (ns->flags & B_FS_IS_READONLY) { ERROR("ntfs is read-only\n"); - return EROFS; + return B_READ_ONLY_DEVICE; } LOCK_VOL(ns); @@ -1332,7 +1249,7 @@ fs_write(fs_volume *_vol, fs_vnode *_dir, void *_cookie, off_t offset, } na = ntfs_attr_open(ni, AT_DATA, NULL, 0); - if (!na) { + if (na == NULL) { ERROR("fs_write - ntfs_attr_open()==NULL\n"); *len = 0; result = EINVAL; @@ -1347,7 +1264,7 @@ fs_write(fs_volume *_vol, fs_vnode *_dir, void *_cookie, off_t offset, if (ntfs_attr_truncate(na, offset + size)) size = na->data_size - offset; else - notify_stat_changed(ns->id, MREF(ni->mft_no), B_STAT_SIZE); + notify_stat_changed(ns->id, node->vnid, B_STAT_SIZE); } while (size) { @@ -1374,10 +1291,10 @@ fs_write(fs_volume *_vol, fs_vnode *_dir, void *_cookie, off_t offset, TRACE("fs_write - OK\n"); exit: - if (na) + if (na != NULL) ntfs_attr_close(na); exit2: - if (ni) + if (ni != NULL) ntfs_inode_close(ni); TRACE("fs_write - EXIT, result is %s, writed %d bytes\n", @@ -1506,9 +1423,9 @@ fs_readlink(fs_volume *_vol, fs_vnode *_node, char *buffer, size_t *bufferSize) exit: free(intxFile); - if (na) + if (na != NULL) ntfs_attr_close(na); - if (ni) + if (ni != NULL) ntfs_inode_close(ni); TRACE("fs_readlink - EXIT, result is %s\n", strerror(result)); @@ -1525,16 +1442,19 @@ fs_create_symlink(fs_volume *_vol, fs_vnode *_dir, const char *name, { nspace *ns = (nspace*)_vol->private_volume; vnode *dir = (vnode*)_dir->private_node; - ntfs_inode *sym = NULL; - ntfs_inode *bi = NULL; - vnode *symnode = NULL; + ntfs_inode *ni = NULL; + ntfs_inode *dir_ni = NULL; + vnode *newNode = NULL; ntfschar *uname = NULL; ntfschar *utarget = NULL; int unameLength; int utargetLength; status_t result = B_NO_ERROR; - int fmode = FS_FILE_MODE; - le32 securid = 0; + le32 securid = const_cpu_to_le32(0); + + if (ns->flags & B_FS_IS_READONLY) { + return B_READ_ONLY_DEVICE; + } LOCK_VOL(ns); @@ -1544,10 +1464,10 @@ fs_create_symlink(fs_volume *_vol, fs_vnode *_dir, const char *name, result = EINVAL; goto exit; } - - bi = ntfs_inode_open(ns->ntvol, dir->vnid); - if (bi == NULL) { - result = ENOENT; + + dir_ni = ntfs_inode_open(ns->ntvol, dir->vnid); + if (dir_ni == NULL) { + result = ENOENT; goto exit; } @@ -1563,51 +1483,45 @@ fs_create_symlink(fs_volume *_vol, fs_vnode *_dir, const char *name, goto exit; } - sym = ntfs_create_symlink(bi, securid, uname, unameLength, utarget, + ni = ntfs_create_symlink(dir_ni, securid, uname, unameLength, utarget, utargetLength); - if (sym == NULL) { - result = EINVAL; - goto exit; - } - - symnode = (vnode*)ntfs_calloc(sizeof(vnode)); - if (symnode == NULL) { - result = ENOMEM; - goto exit; - } - - symnode->vnid = MREF(sym->mft_no); - symnode->parent_vnid = MREF(bi->mft_no); - - if (ns->fake_attrib) { - if (sym->mrec->flags & MFT_RECORD_IS_DIRECTORY) { - set_mime(symnode, ".***"); - fmode = FS_DIR_MODE; - } else { - set_mime(symnode, name); + if (ni) { + ino_t vnid = MREF(ni->mft_no); + newNode = (vnode*)ntfs_calloc(sizeof(vnode)); + if (newNode == NULL) { + result = ENOMEM; + goto exit; } - } - result = publish_vnode(_vol, MREF(sym->mft_no), symnode, &gNTFSVnodeOps, - S_IFLNK | fmode, 0); - if (result != 0) { - ERROR("fs_symlink - new_vnode failed for vnid %Ld: %s\n", - MREF(sym->mft_no), strerror(result)); - } + newNode->vnid = vnid; + newNode->parent_vnid = MREF(dir_ni->mft_no); + + ni->flags |= FILE_ATTR_ARCHIVE; + NInoSetDirty(ni); - put_vnode(_vol, MREF(sym->mft_no)); - fs_ntfs_update_times(_vol, sym, NTFS_UPDATE_CTIME); - fs_ntfs_update_times(_vol, bi, NTFS_UPDATE_MCTIME); + result = B_NO_ERROR; + result = publish_vnode(_vol, vnid, (void*)newNode, &gNTFSVnodeOps, + S_IFREG, 0); + put_vnode(_vol, vnid); + + if (ntfs_inode_close_in_dir(ni, dir_ni)) { + result = EINVAL; + goto exit; + } - notify_entry_created(ns->id, MREF( bi->mft_no ), name, MREF(sym->mft_no)); + ntfs_mark_free_space_outdated(ns); + fs_ntfs_update_times(_vol, dir_ni, NTFS_UPDATE_MCTIME); + notify_entry_created(ns->id, MREF(dir_ni->mft_no), name, vnid); + } else + result = errno; exit: - if (sym) - ntfs_inode_close(sym); - if (bi) - ntfs_inode_close(bi); - free(utarget); - free(uname); + if (dir_ni != NULL) + ntfs_inode_close(dir_ni); + if (utarget != NULL) + free(utarget); + if (uname != NULL) + free(uname); TRACE("fs_symlink - EXIT, result is %s\n", strerror(result)); @@ -1626,13 +1540,13 @@ fs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms) ntfschar *uname = NULL; int unameLength; ntfs_inode *ni = NULL; - ntfs_inode *bi = NULL; + ntfs_inode *dir_ni = NULL; status_t result = B_NO_ERROR; le32 securid = const_cpu_to_le32(0); if (ns->flags & B_FS_IS_READONLY) { ERROR("ntfs is read-only\n"); - return EROFS; + return B_READ_ONLY_DEVICE; } LOCK_VOL(ns); @@ -1644,13 +1558,13 @@ fs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms) goto exit; } - bi = ntfs_inode_open(ns->ntvol, dir->vnid); - if (bi == NULL) { + dir_ni = ntfs_inode_open(ns->ntvol, dir->vnid); + if (dir_ni == NULL) { result = ENOENT; goto exit; } - if (!(bi->mrec->flags & MFT_RECORD_IS_DIRECTORY)) { + if (!(dir_ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) { result = EINVAL; goto exit; } @@ -1661,8 +1575,8 @@ fs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms) goto exit; } - ni = ntfs_create(bi, securid, uname, unameLength, S_IFDIR); - if (ni) { + ni = ntfs_create(dir_ni, securid, uname, unameLength, S_IFDIR); + if (ni != NULL) { ino_t vnid = MREF(ni->mft_no); newNode = (vnode*)ntfs_calloc(sizeof(vnode)); @@ -1671,19 +1585,10 @@ fs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms) goto exit; } - if (ntfs_inode_close_in_dir(ni, bi)) { - result = EINVAL; - goto exit; - } - newNode->vnid = vnid; - newNode->parent_vnid = MREF(bi->mft_no); - - if (ns->fake_attrib) - set_mime(newNode, ".***"); + newNode->parent_vnid = MREF(dir_ni->mft_no); ni->flags |= FILE_ATTR_ARCHIVE; - ntfs_inode_update_mbsname(bi, name, ni->mft_no); NInoSetDirty(ni); result = publish_vnode(_vol, vnid, (void*)newNode, &gNTFSVnodeOps, @@ -1691,16 +1596,22 @@ fs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms) put_vnode(_vol, vnid); + if (ntfs_inode_close_in_dir(ni, dir_ni)) { + result = EINVAL; + goto exit; + } + ntfs_mark_free_space_outdated(ns); - fs_ntfs_update_times(_vol, bi, NTFS_UPDATE_MCTIME); - notify_entry_created(ns->id, MREF(bi->mft_no), name, vnid); + fs_ntfs_update_times(_vol, dir_ni, NTFS_UPDATE_MCTIME); + notify_entry_created(ns->id, MREF(dir_ni->mft_no), name, vnid); } else result = errno; exit: - if (bi) - ntfs_inode_close(bi); - free(uname); + if (dir_ni != NULL) + ntfs_inode_close(dir_ni); + if (uname != NULL) + free(uname); TRACE("fs_mkdir - EXIT, result is %s\n", strerror(result)); @@ -1715,49 +1626,49 @@ fs_rename(fs_volume *_vol, fs_vnode *_odir, const char *name, fs_vnode *_ndir, const char *newname) { nspace *ns = (nspace*)_vol->private_volume; - vnode *odir = (vnode*)_odir->private_node; - vnode *ndir = (vnode*)_ndir->private_node; + vnode *parent_vnode = (vnode*)_odir->private_node; + vnode *newparent_vnode = (vnode*)_ndir->private_node; vnode *file = NULL; - - ino_t parent = odir->vnid; - ino_t newparent = ndir->vnid; - ino_t ino, xino; + ino_t parent_vnid = parent_vnode->vnid; + ino_t newparent_vnid = newparent_vnode->vnid; + + ino_t inode; + ino_t target_inode; ntfs_inode *ni = NULL; ntfs_inode *dir_ni = NULL; status_t result = B_NO_ERROR; - if (ns->flags & B_FS_IS_READONLY) { ERROR("ntfs is read-only\n"); - return EROFS; + return B_READ_ONLY_DEVICE; } LOCK_VOL(ns); TRACE("NTFS:fs_rename - oldname:%s newname:%s\n", name, newname); - ino = ntfs_inode_lookup(_vol, parent, name); - if (ino == (u64)-1) { + inode = ntfs_inode_lookup(_vol, parent_vnid, name); + if (inode == (u64)-1) { result = EINVAL; goto exit; } /* Check whether target is present */ - xino = ntfs_inode_lookup(_vol, newparent, newname); + target_inode = ntfs_inode_lookup(_vol, newparent_vnid, newname); - if (xino == (u64)-1) { + if (target_inode == (u64)-1) { ntfschar *uname = NULL; int uname_len; - result = get_vnode(_vol, ino, (void**)&file); + result = get_vnode(_vol, inode, (void**)&file); if (result != B_NO_ERROR) goto exit; - ni = ntfs_inode_open(ns->ntvol, ino); + ni = ntfs_inode_open(ns->ntvol, inode); if (!ni) { result = EINVAL; goto exit; @@ -1769,7 +1680,7 @@ fs_rename(fs_volume *_vol, fs_vnode *_odir, const char *name, goto exit; } - dir_ni = ntfs_inode_open(ns->ntvol, newparent); + dir_ni = ntfs_inode_open(ns->ntvol, newparent_vnid); if (!dir_ni) { result = EINVAL; goto exit; @@ -1780,8 +1691,6 @@ fs_rename(fs_volume *_vol, fs_vnode *_odir, const char *name, goto exit; } - ntfs_inode_update_mbsname(dir_ni, newname, ni->mft_no); - ni->flags |= FILE_ATTR_ARCHIVE; fs_ntfs_update_times(_vol, ni, NTFS_UPDATE_CTIME); @@ -1789,23 +1698,26 @@ fs_rename(fs_volume *_vol, fs_vnode *_odir, const char *name, if (ns->fake_attrib) { if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) - set_mime(file, ".***"); + set_mime(file, NULL); else set_mime(file, newname); + notify_attribute_changed(ns->id, file->vnid, "BEOS:TYPE", + B_ATTR_CHANGED); } - + ntfs_inode_close(dir_ni); ntfs_inode_close(ni); free(uname); - ntfs_remove(_vol, parent, name); + ntfs_remove(_vol, parent_vnid, name); + + file->parent_vnid = newparent_vnid; - file->parent_vnid = newparent; - put_vnode(_vol, file->vnid); - notify_entry_moved(ns->id, parent, name, newparent, newname, ino); + notify_entry_moved(ns->id, parent_vnid, name, newparent_vnid, + newname, inode); } else result = EINVAL; exit: @@ -1822,11 +1734,15 @@ fs_rmdir(fs_volume *_vol, fs_vnode *_dir, const char *name) { nspace *ns = (nspace*)_vol->private_volume; vnode *dir = (vnode*)_dir->private_node; + vnode *file = NULL; + ntfs_inode *ni = NULL; + ntfs_inode *dir_ni = NULL; status_t result = B_NO_ERROR; + ino_t ino; if (ns->flags & B_FS_IS_READONLY) { ERROR("ntfs is read-only\n"); - return EROFS; + return B_READ_ONLY_DEVICE; } LOCK_VOL(ns); @@ -1835,20 +1751,64 @@ fs_rmdir(fs_volume *_vol, fs_vnode *_dir, const char *name) if (ns == NULL || dir == NULL || name == NULL) { result = EINVAL; - goto exit1; + goto exit; } if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { result = EPERM; - goto exit1; + goto exit; } - result = do_unlink(_vol, dir, name, true); + ino = ntfs_inode_lookup(_vol, dir->vnid, name); + if (ino == (u64)-1) { + result = EINVAL; + goto exit; + } - // TODO: space must not be freed here, but in fs_remove_vnode()!!! + result = get_vnode(_vol, ino, (void**)&file); + if (result != B_NO_ERROR) + goto exit; + + ni = ntfs_inode_open(ns->ntvol, file->vnid); + if (ni != NULL) { + if (!(ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) { + result = ENOTDIR; + goto exit; + } + if (ntfs_check_empty_dir(ni)<0) { + result = ENOTEMPTY; + goto exit; + } + ntfs_inode_close(ni); + } else { + result = EINVAL; + goto exit; + } + + + result = ntfs_remove(_vol, dir->vnid, name); + if(result != B_NO_ERROR) { + goto exit; + } + + notify_entry_removed(ns->id, dir->vnid, name, file->vnid); + + remove_vnode(_vol, file->vnid); + + put_vnode(_vol, ino); + + dir_ni = ntfs_inode_open(ns->ntvol, dir->vnid); + if (dir_ni != NULL) { + fs_ntfs_update_times(_vol, dir_ni, NTFS_UPDATE_MCTIME); + ntfs_inode_close(dir_ni); + } + ntfs_mark_free_space_outdated(ns); -exit1: +exit: + if (ni != NULL) + ntfs_inode_close(ni); + TRACE("fs_rmdir - EXIT, result is %s\n", strerror(result)); UNLOCK_VOL(ns); @@ -1862,11 +1822,14 @@ fs_unlink(fs_volume *_vol, fs_vnode *_dir, const char *name) { nspace *ns = (nspace*)_vol->private_volume; vnode *dir = (vnode*)_dir->private_node; + vnode *file = NULL; + ntfs_inode *dir_ni = NULL; status_t result = B_NO_ERROR; + ino_t inode; if (ns->flags & B_FS_IS_READONLY) { ERROR("ntfs is read-only\n"); - return EROFS; + return B_READ_ONLY_DEVICE; } LOCK_VOL(ns); @@ -1883,11 +1846,35 @@ fs_unlink(fs_volume *_vol, fs_vnode *_dir, const char *name) goto exit; } - result = do_unlink(_vol, dir, name, false); + inode = ntfs_inode_lookup(_vol, dir->vnid, name); + if (inode == (u64)-1) { + result = EINVAL; + goto exit; + } + + result = get_vnode(_vol, inode, (void**)&file); + if (result != B_NO_ERROR) + goto exit; + + result = ntfs_remove(_vol, dir->vnid, name); + if(result != B_NO_ERROR) { + goto exit; + } + + notify_entry_removed(ns->id, dir->vnid, name, file->vnid); + + remove_vnode(_vol, file->vnid); + + put_vnode(_vol, inode); + + dir_ni = ntfs_inode_open(ns->ntvol, dir->vnid); + if (dir_ni != NULL) { + fs_ntfs_update_times(_vol, dir_ni, NTFS_UPDATE_MCTIME); + ntfs_inode_close(dir_ni); + } - // TODO: space must not be freed here, but in fs_remove_vnode()!!! ntfs_mark_free_space_outdated(ns); - + exit: TRACE("fs_unlink - EXIT, result is %s\n", strerror(result)); diff --git a/src/add-ons/kernel/file_systems/ntfs/kernel_interface.c b/src/add-ons/kernel/file_systems/ntfs/kernel_interface.c index b9e7930fe8..9e12359598 100644 --- a/src/add-ons/kernel/file_systems/ntfs/kernel_interface.c +++ b/src/add-ons/kernel/file_systems/ntfs/kernel_interface.c @@ -156,7 +156,7 @@ fs_vnode_ops gNTFSVnodeOps = { &fs_read_attrib_stat, NULL, //&fs_write_attr_stat, NULL, //&fs_rename_attr, - NULL, //&fs_remove_attr, + &fs_remove_attrib, }; diff --git a/src/add-ons/kernel/file_systems/ntfs/mime_table.c b/src/add-ons/kernel/file_systems/ntfs/mime_table.c index 5a92158088..649dbf6e4f 100644 --- a/src/add-ons/kernel/file_systems/ntfs/mime_table.c +++ b/src/add-ons/kernel/file_systems/ntfs/mime_table.c @@ -3,14 +3,14 @@ This file may be used under the terms of the Be Sample Code License. */ +#include + struct ext_mime { char *extension; char *mime; }; struct ext_mime mimes[] = { - { "***", "application/x-vnd.Be-directory"}, - { "gz", "application/x-gzip" }, { "hqx", "application/x-binhex40" }, { "lha", "application/x-lharc" }, @@ -24,8 +24,13 @@ struct ext_mime mimes[] = { { "z", "application/x-compress" }, { "zip", "application/zip" }, { "zoo", "application/x-zoo" }, - { "rar", "application/x-rar-compressed" }, + { "rar", "application/x-rar" }, { "pkg", "application/x-scode-UPkg" }, + { "7z", "application/x-7z-compressed" }, + { "bz2", "application/x-bzip2" }, + { "xz", "application/x-xz" }, + + { "jar", "application/x-jar" }, { "aif", "audio/x-aiff" }, { "aiff", "audio/x-aiff" }, @@ -37,13 +42,20 @@ struct ext_mime mimes[] = { { "wav", "audio/x-wav" }, { "mp3", "audio/x-mpeg" }, { "ogg", "audio/x-vorbis" }, + { "flac", "audio/x-flac" }, + { "wma", "audio/x-ms-wma" }, { "avi", "video/x-msvideo" }, { "mov", "video/quicktime" }, + { "qt", "video/quicktime" }, { "mpg", "video/mpeg" }, { "mpeg", "video/mpeg" }, + { "flv", "video/x-flv" }, + { "mp4", "video/mp4" }, + { "mkv", "video/x-matroska" }, { "asf", "application/x-asf" }, { "rm", "video/vnd.rn-realvideo" }, + { "wmv", "video/x-ms-wmv" }, { "bmp", "image/x-bmp" }, { "fax", "image/g3fax" }, @@ -61,11 +73,21 @@ struct ext_mime mimes[] = { { "tif", "image/tiff" }, { "tiff", "image/tiff" }, { "xbm", "image/x-xbitmap" }, - { "djvu", "image/x-djvu" }, + { "djvu", "image/x-djvu" }, + { "svg", "image/svg+xml" }, + { "ico", "image/vnd.microsoft.icon" }, + { "doc", "application/msword" }, + { "xls", "application/vnd.ms-excel" }, + { "xls", "application/vnd.ms-excel" }, + { "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }, + { "docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }, + { "ppt", "application/vnd.ms-powerpoint" }, + { "pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation" }, + { "chm", "application/x-chm" }, + { "txt", "text/plain" }, { "xml", "text/plain" }, - { "doc", "text/plain" }, { "htm", "text/html" }, { "html", "text/html" }, { "rtf", "text/rtf" }, @@ -74,15 +96,15 @@ struct ext_mime mimes[] = { { "c++", "text/x-source-code" }, { "h", "text/x-source-code" }, { "hh", "text/x-source-code" }, + { "hpp", "text/x-source-code" }, { "cxx", "text/x-source-code" }, { "cpp", "text/x-source-code" }, { "S", "text/x-source-code" }, { "java", "text/x-source-code" }, - - { "exe", "application/x-vnd.Be-elfexecutable" }, - { "dll", "application/x-vnd.Be.ELF-object" }, - + { "ini", "text/plain" }, + { "inf", "text/plain" }, + { "ttf", "application/x-truetype" }, - { 0, 0 } + { NULL, NULL } }; diff --git a/src/add-ons/kernel/file_systems/ntfs/ntfs.h b/src/add-ons/kernel/file_systems/ntfs/ntfs.h index e26147d1e7..16bbcf8ae5 100644 --- a/src/add-ons/kernel/file_systems/ntfs/ntfs.h +++ b/src/add-ons/kernel/file_systems/ntfs/ntfs.h @@ -87,19 +87,20 @@ typedef struct vnode { } vnode; typedef struct filecookie { - int omode; - off_t last_size; + int omode; + off_t last_size; } filecookie; typedef struct attrcookie { - int omode; - ntfs_inode *inode; - ntfs_attr *stream; - // MFT ref for EA ? + int omode; + ino_t vnid; + ntfschar* uname; + int uname_len; + uint32 type; } attrcookie; typedef struct attrdircookie { - ntfs_inode *inode; + ntfs_inode* inode; ntfs_attr_search_ctx *ctx; } attrdircookie; diff --git a/src/add-ons/kernel/file_systems/ntfs/ntfsdir.c b/src/add-ons/kernel/file_systems/ntfs/ntfsdir.c index bc3bb5e92f..36a1aacea5 100644 --- a/src/add-ons/kernel/file_systems/ntfs/ntfsdir.c +++ b/src/add-ons/kernel/file_systems/ntfs/ntfsdir.c @@ -33,8 +33,8 @@ #include -//callback function for readdir() -static int _ntfs_dirent_filler(void *_dirent, const ntfschar *name, +static int +_ntfs_dirent_filler(void *_dirent, const ntfschar *name, const int name_len, const int name_type, const s64 pos, const MFT_REF mref, const unsigned dt_type) { @@ -45,42 +45,64 @@ static int _ntfs_dirent_filler(void *_dirent, const ntfschar *name, return 0; if (MREF(mref) == FILE_root || MREF(mref) >= FILE_first_user - || cookie->show_sys_files) { - if (cookie->readed == 1) { - cookie->pos=pos; - cookie->readed = 0; - return -1; - } else { - if (ntfs_ucstombs(name, name_len, &filename, 0) >= 0) { - if (filename) { - strcpy(cookie->name,filename); - cookie->ino=MREF(mref); - cookie->readed = 1; - free(filename); - return 0; - } + || cookie->show_sys_files) { + int len = ntfs_ucstombs(name, name_len, &filename, 0); + if (len >= 0 && filename != NULL) { + cache_entry* new_entry = + (cache_entry*)ntfs_calloc(sizeof(cache_entry)); + if (new_entry == NULL) { + free(filename); + return -1; + } + + new_entry->ent = + (struct dirent*)ntfs_calloc(sizeof(struct dirent) + len); + new_entry->ent->d_dev = cookie->dev_id; + new_entry->ent->d_ino = MREF(mref); + memcpy(new_entry->ent->d_name,filename, len + 1); + new_entry->ent->d_reclen = sizeof(struct dirent) + len; + + if(cookie->cache_root == NULL || cookie->entry == NULL) { + cookie->cache_root = new_entry; + cookie->entry = cookie->cache_root; + cookie->entry->next = NULL; + } else { + cookie->entry->next = (void*)new_entry; + cookie->entry = cookie->entry->next; + cookie->entry->next = NULL; } - return -1; + free(filename); + return 0; } + return -1; } - return 0; } status_t -fs_free_dircookie(fs_volume *_vol, fs_vnode *vnode, void *cookie) +fs_free_dircookie(fs_volume *_vol, fs_vnode *vnode, void *_cookie) { nspace *ns = (nspace*)_vol->private_volume; - - LOCK_VOL(ns); + dircookie *cookie = (dircookie*)_cookie; + + LOCK_VOL(ns); TRACE("fs_free_dircookie - ENTER\n"); - if (cookie != NULL) + + if (cookie != NULL) { + cache_entry *entry = cookie->cache_root; + while (entry != NULL) { + cache_entry *next = entry->next; + if (entry->ent != NULL) + free(entry->ent); + free(entry); + entry = next; + } free(cookie); + } TRACE("fs_free_dircookie - EXIT\n"); - UNLOCK_VOL(ns); return B_NO_ERROR; @@ -93,11 +115,10 @@ fs_opendir(fs_volume *_vol, fs_vnode *_node, void** _cookie) nspace *ns = (nspace*)_vol->private_volume; vnode *node = (vnode*)_node->private_node; dircookie *cookie = NULL; - int result = B_NO_ERROR; ntfs_inode *ni = NULL; + int result = B_NO_ERROR; LOCK_VOL(ns); - TRACE("fs_opendir - ENTER\n"); ni = ntfs_inode_open(ns->ntvol, node->vnid); @@ -114,21 +135,19 @@ fs_opendir(fs_volume *_vol, fs_vnode *_node, void** _cookie) cookie = (dircookie*)ntfs_calloc(sizeof(dircookie)); if (cookie != NULL) { cookie->pos = 0; - cookie->ino = 0; - cookie->readed = 0; - cookie->last = 0; - cookie->name[0] = 0; + cookie->dev_id = ns->id; cookie->show_sys_files = ns->show_sys_files; + cookie->cache_root = NULL; + cookie->entry = cookie->cache_root; *_cookie = (void*)cookie; } else result = ENOMEM; exit: - if (ni) + if (ni != NULL) ntfs_inode_close(ni); TRACE("fs_opendir - EXIT\n"); - UNLOCK_VOL(ns); return result; @@ -138,32 +157,7 @@ exit: status_t fs_closedir(fs_volume *_vol, fs_vnode *_node, void *cookie) { - nspace *ns = (nspace*)_vol->private_volume; - vnode *node = (vnode*)_node->private_node; - int result = B_NO_ERROR; - ntfs_inode *ni = NULL; - - LOCK_VOL(ns); - - TRACE("fs_closedir - ENTER\n"); - - ni = ntfs_inode_open(ns->ntvol, node->vnid); - if (ni == NULL) { - result = ENOENT; - goto exit; - } - - fs_ntfs_update_times(_vol, ni, NTFS_UPDATE_ATIME); - -exit: - if (ni) - ntfs_inode_close(ni); - - TRACE("fs_closedir - EXIT\n"); - - UNLOCK_VOL(ns); - - return result; + return B_NO_ERROR; } @@ -174,50 +168,61 @@ fs_readdir(fs_volume *_vol, fs_vnode *_node, void *_cookie, struct dirent *buf, nspace *ns = (nspace*)_vol->private_volume; vnode *node = (vnode*)_node->private_node; dircookie *cookie = (dircookie*)_cookie; - uint32 nameLength = bufsize - sizeof(struct dirent), realLen; - int result = B_NO_ERROR; ntfs_inode *ni = NULL; - LOCK_VOL(ns); + uint32 nameLength = bufsize - sizeof(struct dirent), realLen; + int result = B_NO_ERROR; + LOCK_VOL(ns); TRACE("fs_readdir - ENTER (sizeof(buf)=%d, bufsize=%d, num=%d\n", sizeof(buf), bufsize, *num); - + if (!ns || !node || !cookie || !num || bufsize < sizeof(*buf)) { result = EINVAL; goto exit; } - if (cookie->readed == 1 || cookie->last == 1) { - result = ENOENT; - goto exit; - } - ni = ntfs_inode_open(ns->ntvol, node->vnid); if (ni == NULL) { - ERROR("fs_readdir - dir not opened\n"); + TRACE("fs_readdir - dir not opened\n"); result = ENOENT; goto exit; } - result = ntfs_readdir(ni, &cookie->pos, cookie, - (ntfs_filldir_t)_ntfs_dirent_filler); + if(cookie->cache_root == NULL) { + cookie->entry = NULL; + result = ntfs_readdir(ni, &cookie->pos, cookie, + (ntfs_filldir_t)_ntfs_dirent_filler); + cookie->entry = cookie->cache_root; + if(result) { + result = ENOENT; + goto exit; + } + } + if(cookie->entry == NULL) { + result = ENOENT; + goto exit; + } + + if(cookie->entry->ent == NULL) { + result = ENOENT; + goto exit; + } + realLen = nameLength > 255 ? 255 : nameLength; + buf->d_dev = ns->id; - buf->d_ino = cookie->ino; - strlcpy(buf->d_name, cookie->name, realLen + 1); + buf->d_ino = cookie->entry->ent->d_ino; + strlcpy(buf->d_name, cookie->entry->ent->d_name, realLen + 1); buf->d_reclen = sizeof(struct dirent) + realLen; - - if (result == 0) - cookie->last = 1; - - result = B_NO_ERROR; + + cookie->entry = (cache_entry*)cookie->entry->next; TRACE("fs_readdir - FILE: [%s]\n",buf->d_name); exit: - if (ni) + if (ni != NULL) ntfs_inode_close(ni); if (result == B_NO_ERROR) @@ -228,8 +233,7 @@ exit: if (result == ENOENT) result = B_NO_ERROR; - TRACE("fs_readdir - EXIT result (%s)\n", strerror(result)); - + TRACE("fs_readdir - EXIT num=%d result (%s)\n",*num, strerror(result)); UNLOCK_VOL(ns); return result; @@ -237,26 +241,33 @@ exit: status_t -fs_rewinddir(fs_volume *_vol, fs_vnode *vnode, void *_cookie) +fs_rewinddir(fs_volume *_vol, fs_vnode *_node, void *_cookie) { nspace *ns = (nspace*)_vol->private_volume; dircookie *cookie = (dircookie*)_cookie; int result = EINVAL; LOCK_VOL(ns); - TRACE("fs_rewinddir - ENTER\n"); + if (cookie != NULL) { + cache_entry *entry = cookie->cache_root; + while (entry != NULL) { + cache_entry *next = entry->next; + if (entry->ent != NULL) + free(entry->ent); + free(entry); + entry = next; + } cookie->pos = 0; - cookie->ino = 0; - cookie->readed = 0; - cookie->last = 0; - cookie->name[0] = 0; + cookie->dev_id = ns->id; + cookie->show_sys_files = ns->show_sys_files; + cookie->cache_root = NULL; + cookie->entry = cookie->cache_root; result = B_NO_ERROR; } TRACE("fs_rewinddir - EXIT, result is %s\n", strerror(result)); - UNLOCK_VOL(ns); return result; diff --git a/src/add-ons/kernel/file_systems/ntfs/ntfsdir.h b/src/add-ons/kernel/file_systems/ntfs/ntfsdir.h index a84df3d131..2fa305cc40 100644 --- a/src/add-ons/kernel/file_systems/ntfs/ntfsdir.h +++ b/src/add-ons/kernel/file_systems/ntfs/ntfsdir.h @@ -24,15 +24,21 @@ #include "ntfs.h" +typedef struct cache_entry { + struct dirent *ent; + struct cache_entry *next; +} cache_entry; + + typedef struct dircookie { u64 pos; - int readed; - int last; - ino_t ino; - BOOL show_sys_files; - char name[MAX_PATH]; + dev_t dev_id; + BOOL show_sys_files; + cache_entry *cache_root; + cache_entry *entry; } dircookie; + status_t fs_closedir(fs_volume *volume, fs_vnode *vnode, void *cookie); status_t fs_free_dircookie(fs_volume *volume, fs_vnode *vnode, void *cookie); status_t fs_opendir(fs_volume *volume, fs_vnode *vnode, void** cookie); diff --git a/src/add-ons/media/plugins/ffmpeg/Jamfile b/src/add-ons/media/plugins/ffmpeg/Jamfile index 0ac75227b0..0d88d5bb32 100644 --- a/src/add-ons/media/plugins/ffmpeg/Jamfile +++ b/src/add-ons/media/plugins/ffmpeg/Jamfile @@ -56,7 +56,7 @@ Addon ffmpeg : be media - libz.a + $(HAIKU_ZLIB_LIB) $(TARGET_LIBSUPC++) $(TARGET_NETWORK_LIBS) ; diff --git a/src/add-ons/translators/exr/openexr/ilmimf/Jamfile b/src/add-ons/translators/exr/openexr/ilmimf/Jamfile index 3bbe147182..7351941281 100644 --- a/src/add-ons/translators/exr/openexr/ilmimf/Jamfile +++ b/src/add-ons/translators/exr/openexr/ilmimf/Jamfile @@ -11,7 +11,10 @@ if $(HAIKU_LIBSTDC++) = libstdc++.r4.so { SubDirC++Flags -Dios_base=ios -ftemplate-depth-24 ; } -UseLibraryHeaders zlib ; +UseHeaders $(HAIKU_ZLIB_HEADERS) : true ; + +Includes [ FGristFiles ImfPxr24Compressor.cpp ImfZipCompressor.cpp ] + : $(HAIKU_ZLIB_HEADERS_DEPENDENCY) ; #StaticLibrary libilmimf.a : SharedLibrary libilmimf.so : @@ -73,6 +76,7 @@ ImfVecAttribute.cpp ImfVersion.cpp ImfWav.cpp ImfZipCompressor.cpp -: libhalf.a libiex.a libimath.a libilmthread.a $(TARGET_LIBSTDC++) z +: libhalf.a libiex.a libimath.a libilmthread.a $(TARGET_LIBSTDC++) + $(HAIKU_ZLIB_LIB) ; diff --git a/src/add-ons/translators/hpgs/Jamfile b/src/add-ons/translators/hpgs/Jamfile index d485776c97..d42549c35e 100644 --- a/src/add-ons/translators/hpgs/Jamfile +++ b/src/add-ons/translators/hpgs/Jamfile @@ -2,7 +2,8 @@ SubDir HAIKU_TOP src add-ons translators hpgs ; SubDirSysHdrs [ FDirName $(SUBDIR) lib ] ; SubDirCcFlags -DHPGS_SHARED -std=c99 ; -UseLibraryHeaders zlib ; +UseLibraryHeaders iconv ; +UseHeaders $(HAIKU_ZLIB_HEADERS) : true ; UseHeaders $(HAIKU_LIBPNG_HEADERS) : true ; SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) shared ] ; @@ -42,13 +43,15 @@ hpgszostream.c Includes [ FGristFiles hpgsimage.c ] : $(HAIKU_LIBPNG_HEADERS_DEPENDENCY) ; +Includes [ FGristFiles hpgszostream.c ] + : $(HAIKU_ZLIB_HEADERS_DEPENDENCY) ; Translator HPGSTranslator : # HPGSTranslator classes ConfigView.cpp HPGSTranslator.cpp $(sources) - : be translation $(HAIKU_LIBPNG_LIB) libtextencoding.so libz.so + : be translation $(HAIKU_LIBPNG_LIB) libtextencoding.so $(HAIKU_ZLIB_LIB) libtranslatorsutils.a $(TARGET_LIBSUPC++) $(HAIKU_LOCALE_LIBS) : true ; diff --git a/src/add-ons/translators/hpgs/lib/hpgsimage.c b/src/add-ons/translators/hpgs/lib/hpgsimage.c index 813408d938..da2d4aaf1e 100644 --- a/src/add-ons/translators/hpgs/lib/hpgsimage.c +++ b/src/add-ons/translators/hpgs/lib/hpgsimage.c @@ -36,6 +36,7 @@ #include #if (defined(__BEOS__) || defined(__HAIKU__)) #include +#define png_infopp_NULL (png_infopp)NULL #else #include #endif diff --git a/src/add-ons/translators/png/Jamfile b/src/add-ons/translators/png/Jamfile index ebaa98b26c..f1b7df60ed 100644 --- a/src/add-ons/translators/png/Jamfile +++ b/src/add-ons/translators/png/Jamfile @@ -2,7 +2,7 @@ SubDir HAIKU_TOP src add-ons translators png ; SetSubDirSupportedPlatformsBeOSCompatible ; -UseLibraryHeaders zlib ; +UseHeaders $(HAIKU_ZLIB_HEADERS) : true ; UseHeaders $(HAIKU_LIBPNG_HEADERS) : true ; SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) shared ] ; @@ -20,7 +20,8 @@ Translator PNGTranslator : PNGTranslator.cpp PNGView.cpp - : be translation $(HAIKU_LIBPNG_LIB) z libtranslatorsutils.a $(TARGET_LIBSUPC++) + : be translation $(HAIKU_LIBPNG_LIB) $(HAIKU_ZLIB_LIB) + $(TARGET_LIBSUPC++) libtranslatorsutils.a $(HAIKU_LOCALE_LIBS) : true ; diff --git a/src/add-ons/translators/wonderbrush/Jamfile b/src/add-ons/translators/wonderbrush/Jamfile index 1396e4e0ab..7d0e80a929 100644 --- a/src/add-ons/translators/wonderbrush/Jamfile +++ b/src/add-ons/translators/wonderbrush/Jamfile @@ -5,11 +5,14 @@ SetSubDirSupportedPlatformsBeOSCompatible ; # Include support sub folder SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons translators wonderbrush support ] ; -UseLibraryHeaders zlib ; +UseHeaders $(HAIKU_ZLIB_HEADERS) : true ; SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) shared ] ; AddResources WonderBrushTranslator : WonderBrushTranslator.rdef ; +Includes [ FGristFiles bitmap_compression.cpp ] + : $(HAIKU_ZLIB_HEADERS_DEPENDENCY) ; + Translator WonderBrushTranslator : Canvas.cpp Layer.cpp @@ -23,8 +26,8 @@ Translator WonderBrushTranslator : blending.cpp lab_convert.cpp - : be translation z libtranslatorsutils.a $(TARGET_LIBSUPC++) - $(HAIKU_LOCALE_LIBS) + : be translation $(HAIKU_ZLIB_LIB) libtranslatorsutils.a + $(TARGET_LIBSUPC++) $(HAIKU_LOCALE_LIBS) : true ; diff --git a/src/apps/installedpackages/Jamfile b/src/apps/installedpackages/Jamfile index 415d23a904..ba753e9e03 100644 --- a/src/apps/installedpackages/Jamfile +++ b/src/apps/installedpackages/Jamfile @@ -11,7 +11,7 @@ Application InstalledPackages : main.cpp UninstallWindow.cpp UninstallView.cpp - : be tracker translation z $(TARGET_LIBSUPC++) $(HAIKU_LOCALE_LIBS) + : be tracker translation $(TARGET_LIBSUPC++) $(HAIKU_LOCALE_LIBS) ; DoCatalogs InstalledPackages : diff --git a/src/apps/packageinstaller/Jamfile b/src/apps/packageinstaller/Jamfile index 41370706b7..6753cf1bbd 100644 --- a/src/apps/packageinstaller/Jamfile +++ b/src/apps/packageinstaller/Jamfile @@ -1,10 +1,13 @@ SubDir HAIKU_TOP src apps packageinstaller ; UsePrivateHeaders shared interface ; -SubDirHdrs $(HAIKU_TOP) headers libs zlib ; +UseHeaders $(HAIKU_ZLIB_HEADERS) : true ; #SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits interface ] ; +Includes [ FGristFiles PackageItem.cpp ] + : $(HAIKU_ZLIB_HEADERS_DEPENDENCY) ; + Application PackageInstaller : main.cpp PackageWindow.cpp @@ -16,7 +19,8 @@ Application PackageInstaller : PackageTextViewer.cpp PackageImageViewer.cpp InstalledPackageInfo.cpp - : be $(HAIKU_LOCALE_LIBS) tracker translation z $(TARGET_LIBSUPC++) + : be $(HAIKU_LOCALE_LIBS) tracker translation $(HAIKU_ZLIB_LIB) + $(TARGET_LIBSUPC++) : PackageInstaller.rdef ; diff --git a/src/kits/package/Jamfile b/src/kits/package/Jamfile index a73037b36f..f62c2755ff 100644 --- a/src/kits/package/Jamfile +++ b/src/kits/package/Jamfile @@ -1,6 +1,6 @@ SubDir HAIKU_TOP src kits package ; -UseLibraryHeaders zlib ; +UseHeaders $(HAIKU_ZLIB_HEADERS) : true ; UsePrivateHeaders kernel @@ -8,6 +8,9 @@ UsePrivateHeaders SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package hpkg ] ; +Includes [ FGristFiles ZlibCompressionBase.cpp ] + : $(HAIKU_ZLIB_HEADERS_DEPENDENCY) ; + HPKG_SOURCES = AttributeDataReader.cpp BlockBufferCache.cpp @@ -72,5 +75,5 @@ SharedLibrary libpackage.so $(HPKG_SOURCES) : - libshared.a be z $(TARGET_LIBSTDC++) + libshared.a be $(HAIKU_ZLIB_LIB) $(TARGET_LIBSTDC++) ; diff --git a/src/libs/Jamfile b/src/libs/Jamfile index 19c7a38276..b8c745a33c 100644 --- a/src/libs/Jamfile +++ b/src/libs/Jamfile @@ -24,4 +24,4 @@ SubInclude HAIKU_TOP src libs termcap ; SubInclude HAIKU_TOP src libs tiff ; SubInclude HAIKU_TOP src libs udis86 ; SubInclude HAIKU_TOP src libs util ; -SubInclude HAIKU_TOP src libs zlib ; + diff --git a/src/libs/tiff/Jamfile b/src/libs/tiff/Jamfile index 64d5482a4a..9402c316ba 100644 --- a/src/libs/tiff/Jamfile +++ b/src/libs/tiff/Jamfile @@ -1,7 +1,8 @@ SubDir HAIKU_TOP src libs tiff ; -UseLibraryHeaders tiff zlib ; +UseLibraryHeaders tiff ; UseHeaders $(HAIKU_JPEG_HEADERS) : true ; +UseHeaders $(HAIKU_ZLIB_HEADERS) : true ; SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) shared ] ; @@ -47,10 +48,12 @@ local shared_files = Includes [ FGristFiles tif_jpeg.c tif_ojpeg.c ] : $(HAIKU_JPEG_HEADERS_DEPENDENCY) ; +Includes [ FGristFiles tif_pixarlog.c tif_zip.c ] + : $(HAIKU_ZLIB_HEADERS_DEPENDENCY) ; Objects $(shared_files) ; SharedLibrary libtiff.so : [ FGristFiles $(shared_files:S=.o) ] - : $(HAIKU_JPEG_LIB) z : 3.8 ; + : $(HAIKU_JPEG_LIB) $(HAIKU_ZLIB_LIB) : 3.8 ; StaticLibrary libtiff.a : [ FGristFiles $(shared_files:S=.o) ] ;