Esempio n. 1
0
static void Socket(Service::Interface* self) {
    u32* cmd_buffer = Kernel::GetCommandBuffer();
    u32 domain = cmd_buffer[1]; // Address family
    u32 type = cmd_buffer[2];
    u32 protocol = cmd_buffer[3];

    // Only 0 is allowed according to 3dbrew, using 0 will let the OS decide which protocol to use
    if (protocol != 0) {
        cmd_buffer[1] = UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code
        return;
    }

    if (domain != AF_INET) {
        cmd_buffer[1] = UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code
        return;
    }

    if (type != SOCK_DGRAM && type != SOCK_STREAM) {
        cmd_buffer[1] = UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code
        return;
    }

    u32 socket_handle = static_cast<u32>(::socket(domain, type, protocol));

    if ((s32)socket_handle != SOCKET_ERROR_VALUE)
        open_sockets[socket_handle] = { socket_handle, true };

    int result = 0;
    if ((s32)socket_handle == SOCKET_ERROR_VALUE)
        result = TranslateError(GET_ERRNO);

    cmd_buffer[1] = result;
    cmd_buffer[2] = socket_handle;
}
Esempio n. 2
0
/**
 * FS_User::OpenArchive service function
 *  Inputs:
 *      1 : Archive ID
 *      2 : Archive low path type
 *      3 : Archive low path size
 *      4 : (LowPathSize << 14) | 2
 *      5 : Archive low path
 *  Outputs:
 *      1 : Result of function, 0 on success, otherwise error code
 *      2 : Archive handle lower word (unused)
 *      3 : Archive handle upper word (same as file handle)
 */
static void OpenArchive(Service::Interface* self) {
    u32* cmd_buff = Service::GetCommandBuffer();

    auto archive_id       = static_cast<FileSys::Archive::IdCode>(cmd_buff[1]);
    auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[2]);
    u32 archivename_size  = cmd_buff[3];
    u32 archivename_ptr   = cmd_buff[5];
    FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr);

    DEBUG_LOG(KERNEL, "archive_path=%s", archive_path.DebugStr().c_str());

    if (archive_path.GetType() != FileSys::Empty) {
        ERROR_LOG(KERNEL, "archive LowPath type other than empty is currently unsupported");
        cmd_buff[1] = UnimplementedFunction(ErrorModule::FS).raw;
        return;
    }

    ResultVal<Handle> handle = Kernel::OpenArchive(archive_id);
    cmd_buff[1] = handle.Code().raw;
    if (handle.Succeeded()) {
        // cmd_buff[2] isn't used according to 3dmoo's implementation.
        cmd_buff[3] = *handle;
    } else {
        ERROR_LOG(KERNEL, "failed to get a handle for archive");
    }

    DEBUG_LOG(KERNEL, "called");
}
Esempio n. 3
0
ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::Path& path) {
    auto archive_itr = id_code_map.find(id_code);
    if (archive_itr == id_code_map.end()) {
        return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error
    }

    return archive_itr->second->Format(path);
}
Esempio n. 4
0
ResultVal<FileSys::ArchiveFormatInfo> ArchiveManager::GetArchiveFormatInfo(
    ArchiveIdCode id_code, FileSys::Path& archive_path, u64 program_id) {
    auto archive = id_code_map.find(id_code);
    if (archive == id_code_map.end()) {
        return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error
    }

    return archive->second->GetFormatInfo(archive_path, program_id);
}
Esempio n. 5
0
ResultCode ArchiveManager::FormatArchive(ArchiveIdCode id_code,
                                         const FileSys::ArchiveFormatInfo& format_info,
                                         const FileSys::Path& path, u64 program_id) {
    auto archive_itr = id_code_map.find(id_code);
    if (archive_itr == id_code_map.end()) {
        return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error
    }

    return archive_itr->second->Format(path, format_info, program_id);
}
Esempio n. 6
0
ResultCode FormatSaveData() {
    // Do not create the archive again if it already exists
    auto archive_itr = id_code_map.find(ArchiveIdCode::SaveData);
    if (archive_itr == id_code_map.end()) {
        return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error
    }

    // Use an empty path, we do not use it when formatting the savedata
    return archive_itr->second->backend->Format(FileSys::Path());
}
Esempio n. 7
0
ResultCode ArchiveManager::RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle,
                                                          const FileSys::Path& src_path,
                                                          ArchiveHandle dest_archive_handle,
                                                          const FileSys::Path& dest_path) {
    ArchiveBackend* src_archive = GetArchive(src_archive_handle);
    ArchiveBackend* dest_archive = GetArchive(dest_archive_handle);
    if (src_archive == nullptr || dest_archive == nullptr)
        return FileSys::ERR_INVALID_ARCHIVE_HANDLE;

    if (src_archive == dest_archive) {
        return src_archive->RenameDirectory(src_path, dest_path);
    } else {
        // TODO: Implement renaming across archives
        return UnimplementedFunction(ErrorModule::FS);
    }
}
Esempio n. 8
0
static void GetServiceHandle(Service::Interface* self) {
    ResultCode res = RESULT_SUCCESS;
    u32* cmd_buff = Service::GetCommandBuffer();

    std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize);
    Service::Interface* service = Service::g_manager->FetchFromPortName(port_name);

    if (nullptr != service) {
        cmd_buff[3] = service->GetHandle();
        LOG_TRACE(Service_SRV, "called port=%s, handle=0x%08X", port_name.c_str(), cmd_buff[3]);
    } else {
        LOG_ERROR(Service_SRV, "(UNIMPLEMENTED) called port=%s", port_name.c_str());
        res = UnimplementedFunction(ErrorModule::SRV);
    }
    cmd_buff[1] = res.raw;
}
Esempio n. 9
0
/**
 * FS_User::OpenFileDirectly service function
 *  Inputs:
 *      1 : Transaction
 *      2 : Archive ID
 *      3 : Archive low path type
 *      4 : Archive low path size
 *      5 : File low path type
 *      6 : File low path size
 *      7 : Flags
 *      8 : Attributes
 *      9 : (ArchiveLowPathSize << 14) | 0x802
 *      10 : Archive low path
 *      11 : (FileLowPathSize << 14) | 2
 *      12 : File low path
 *  Outputs:
 *      1 : Result of function, 0 on success, otherwise error code
 *      3 : File handle
 */
static void OpenFileDirectly(Service::Interface* self) {
    u32* cmd_buff = Service::GetCommandBuffer();

    auto archive_id       = static_cast<FileSys::Archive::IdCode>(cmd_buff[2]);
    auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[3]);
    u32 archivename_size  = cmd_buff[4];
    auto filename_type    = static_cast<FileSys::LowPathType>(cmd_buff[5]);
    u32 filename_size     = cmd_buff[6];
    FileSys::Mode mode; mode.hex = cmd_buff[7];
    u32 attributes        = cmd_buff[8]; // TODO(Link Mauve): do something with those attributes.
    u32 archivename_ptr   = cmd_buff[10];
    u32 filename_ptr      = cmd_buff[12];
    FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr);
    FileSys::Path file_path(filename_type, filename_size, filename_ptr);

    DEBUG_LOG(KERNEL, "archive_path=%s file_path=%s, mode=%u attributes=%d",
              archive_path.DebugStr().c_str(), file_path.DebugStr().c_str(), mode.hex, attributes);

    if (archive_path.GetType() != FileSys::Empty) {
        ERROR_LOG(KERNEL, "archive LowPath type other than empty is currently unsupported");
        cmd_buff[1] = UnimplementedFunction(ErrorModule::FS).raw;
        return;
    }

    // TODO(Link Mauve): Check if we should even get a handle for the archive, and don't leak it
    // TODO(yuriks): Why is there all this duplicate (and seemingly useless) code up here?
    ResultVal<Handle> archive_handle = Kernel::OpenArchive(archive_id);
    cmd_buff[1] = archive_handle.Code().raw;
    if (archive_handle.Failed()) {
        ERROR_LOG(KERNEL, "failed to get a handle for archive");
        return;
    }
    // cmd_buff[2] isn't used according to 3dmoo's implementation.
    cmd_buff[3] = *archive_handle;

    ResultVal<Handle> handle = Kernel::OpenFileFromArchive(*archive_handle, file_path, mode);
    cmd_buff[1] = handle.Code().raw;
    if (handle.Succeeded()) {
        cmd_buff[3] = *handle;
    } else {
        ERROR_LOG(KERNEL, "failed to get a handle for file %s", file_path.DebugStr().c_str());
    }

    DEBUG_LOG(KERNEL, "called");
}
Esempio n. 10
0
ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path,
                                          ArchiveHandle dest_archive_handle, const FileSys::Path& dest_path) {
    ArchiveBackend* src_archive = GetArchive(src_archive_handle);
    ArchiveBackend* dest_archive = GetArchive(dest_archive_handle);
    if (src_archive == nullptr || dest_archive == nullptr)
        return ERR_INVALID_HANDLE;

    if (src_archive == dest_archive) {
        if (src_archive->RenameDirectory(src_path, dest_path))
            return RESULT_SUCCESS;
    } else {
        // TODO: Implement renaming across archives
        return UnimplementedFunction(ErrorModule::FS);
    }

    // TODO(yuriks): This code probably isn't right, it'll return a Status even if the file didn't
    // exist or similar. Verify.
    return ResultCode(ErrorDescription::NoData, ErrorModule::FS, // TODO: verify description
                      ErrorSummary::NothingHappened, ErrorLevel::Status);
}
Esempio n. 11
0
ResultCode ArchiveManager::CreateExtSaveData(MediaType media_type, u32 high, u32 low,
                                             const std::vector<u8>& smdh_icon,
                                             const FileSys::ArchiveFormatInfo& format_info,
                                             u64 program_id) {
    // Construct the binary path to the archive first
    FileSys::Path path =
        FileSys::ConstructExtDataBinaryPath(static_cast<u32>(media_type), high, low);

    auto archive = id_code_map.find(media_type == MediaType::NAND ? ArchiveIdCode::SharedExtSaveData
                                                                  : ArchiveIdCode::ExtSaveData);

    if (archive == id_code_map.end()) {
        return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error
    }

    auto ext_savedata = static_cast<FileSys::ArchiveFactory_ExtSaveData*>(archive->second.get());

    ResultCode result = ext_savedata->Format(path, format_info, program_id);
    if (result.IsError())
        return result;

    ext_savedata->WriteIcon(path, smdh_icon.data(), smdh_icon.size());
    return RESULT_SUCCESS;
}