status_t _user_get_file_disk_device_path(partition_id id, char* buffer, size_t bufferSize) { if (id < 0 || buffer == NULL || bufferSize == 0) return B_BAD_VALUE; if (!IS_USER_ADDRESS(buffer)) return B_BAD_ADDRESS; KDiskDeviceManager *manager = KDiskDeviceManager::Default(); KDiskDevice *device = manager->RegisterDevice(id, true); if (device != NULL) { PartitionRegistrar _(device, true); if (DeviceReadLocker locker = device) { KFileDiskDevice* fileDevice = dynamic_cast<KFileDiskDevice*>(device); if (fileDevice == NULL) return B_BAD_VALUE; ssize_t copied = user_strlcpy(buffer, fileDevice->FilePath(), bufferSize); if (copied < 0) return copied; return (size_t)copied < bufferSize ? B_OK : B_BUFFER_OVERFLOW; } } return B_ERROR; }
partition_id _user_find_partition(const char *_filename, size_t *neededSize) { UserStringParameter<false> filename; status_t error = filename.Init(_filename, B_PATH_NAME_LENGTH); if (error != B_OK) return error; KDiskDeviceManager *manager = KDiskDeviceManager::Default(); // find the partition KPartition *partition = manager->RegisterPartition(filename); if (partition == NULL) return B_ENTRY_NOT_FOUND; PartitionRegistrar _(partition, true); partition_id id = partition->ID(); if (neededSize != NULL) { // get and lock the partition's device KDiskDevice *device = manager->RegisterDevice(partition->ID(), false); if (device == NULL) return B_ENTRY_NOT_FOUND; PartitionRegistrar _2(device, true); if (DeviceReadLocker locker = device) { // get the needed size UserDataWriter writer; device->WriteUserData(writer); error = copy_to_user_value(neededSize, writer.AllocatedSize()); if (error != B_OK) return error; } else return B_ERROR; } return id; }
partition_id _user_find_disk_device(const char *_filename, size_t *neededSize) { UserStringParameter<false> filename; status_t error = filename.Init(_filename, B_PATH_NAME_LENGTH); if (error != B_OK) return error; partition_id id = B_ENTRY_NOT_FOUND; KDiskDeviceManager *manager = KDiskDeviceManager::Default(); // find the device if (KDiskDevice *device = manager->RegisterDevice(filename)) { PartitionRegistrar _(device, true); id = device->ID(); if (neededSize) { if (DeviceReadLocker locker = device) { // get the needed size UserDataWriter writer; device->WriteUserData(writer); error = copy_to_user_value(neededSize, writer.AllocatedSize()); if (error != B_OK) return error; } else return B_ERROR; } } return id; }
/*! \brief Writes data describing the disk device identified by ID and all its partitions into the supplied buffer. The function passes the buffer size required to hold the data back through the \a _neededSize parameter, if the device could be found at least and no serious error occured. If fails with \c B_BUFFER_OVERFLOW, if the supplied buffer is too small or a \c NULL buffer is supplied (and \c bufferSize is 0). The device is identified by \a id. If \a deviceOnly is \c true, then it must be the ID of a disk device, otherwise the disk device is chosen, on which the partition \a id refers to resides. \param id The ID of an arbitrary partition on the disk device (including the disk device itself), whose data shall be returned (if \a deviceOnly is \c false), or the ID of the disk device itself (if \a deviceOnly is true). \param deviceOnly Specifies whether only IDs of disk devices (\c true), or also IDs of partitions (\c false) are accepted for \a id. \param buffer The buffer into which the disk device data shall be written. May be \c NULL. \param bufferSize The size of \a buffer. \param _neededSize Pointer to a variable into which the actually needed buffer size is written. May be \c NULL. \return - \c B_OK: Everything went fine. The device was found and, if not \c NULL, in \a _neededSize the actually needed buffer size is returned. And \a buffer will contain the disk device data. - \c B_BAD_VALUE: \c NULL \a buffer, but not 0 \a bufferSize. - \c B_BUFFER_OVERFLOW: The supplied buffer was too small. \a _neededSize, if not \c NULL, will contain the required buffer size. - \c B_NO_MEMORY: Insufficient memory to complete the operation. - \c B_ENTRY_NOT_FOUND: \a id is no valid disk device ID (if \a deviceOnly is \c true) or not even a valid partition ID (if \a deviceOnly is \c false). - \c B_ERROR: An unexpected error occured. - another error code... */ status_t _user_get_disk_device_data(partition_id id, bool deviceOnly, user_disk_device_data *buffer, size_t bufferSize, size_t *_neededSize) { if (buffer == NULL && bufferSize > 0) return B_BAD_VALUE; KDiskDeviceManager *manager = KDiskDeviceManager::Default(); // get the device KDiskDevice *device = manager->RegisterDevice(id, deviceOnly); if (device == NULL) return B_ENTRY_NOT_FOUND; PartitionRegistrar _(device, true); if (DeviceReadLocker locker = device) { // do a dry run first to get the needed size UserDataWriter writer; device->WriteUserData(writer); size_t neededSize = writer.AllocatedSize(); if (_neededSize != NULL) { status_t error = copy_ref_var_to_user(neededSize, _neededSize); if (error != B_OK) return error; } // if no buffer has been supplied or the buffer is too small, // then we're done if (buffer == NULL || bufferSize < neededSize) return B_BUFFER_OVERFLOW; if (!IS_USER_ADDRESS(buffer)) return B_BAD_ADDRESS; // otherwise allocate a kernel buffer user_disk_device_data *kernelBuffer = static_cast<user_disk_device_data*>(malloc(neededSize)); if (kernelBuffer == NULL) return B_NO_MEMORY; MemoryDeleter deleter(kernelBuffer); // write the device data into the buffer writer.SetTo(kernelBuffer, bufferSize); device->WriteUserData(writer); // sanity check if (writer.AllocatedSize() != neededSize) { ERROR(("Size of written disk device user data changed from " "%lu to %lu while device was locked!\n")); return B_ERROR; } // relocate status_t error = writer.Relocate(buffer); if (error != B_OK) return error; // copy out return user_memcpy(buffer, kernelBuffer, neededSize); } else return B_ERROR; }