From 7d038b9bd8b80f6002e69e0b036767dfdbfdb0bd Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 7 Dec 2017 13:52:08 -0500 Subject: [PATCH] HLE/FS: Implemented FS::GetProgramLaunchInfo. This function is used by the DLP system module during the DLPSRVR initialization. --- src/core/hle/kernel/process.cpp | 22 ++++++++++++- src/core/hle/kernel/process.h | 8 ++++- src/core/hle/kernel/thread.cpp | 1 + src/core/hle/service/fs/fs_user.cpp | 50 ++++++++++++++++++++++++++++- 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index cf3163e0f..478680550 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include #include "common/assert.h" #include "common/common_funcs.h" @@ -16,6 +17,9 @@ namespace Kernel { +// Lists all processes that exist in the current session. +static std::vector> process_list; + SharedPtr CodeSet::Create(std::string name, u64 program_id) { SharedPtr codeset(new CodeSet); @@ -37,6 +41,7 @@ SharedPtr Process::Create(SharedPtr code_set) { process->flags.raw = 0; process->flags.memory_region.Assign(MemoryRegion::APPLICATION); + process_list.push_back(process); return process; } @@ -299,5 +304,20 @@ ResultCode Process::LinearFree(VAddr target, u32 size) { Kernel::Process::Process() {} Kernel::Process::~Process() {} -SharedPtr g_current_process; +void ClearProcessList() { + process_list.clear(); } + +SharedPtr GetProcessById(u32 process_id) { + auto itr = std::find_if( + process_list.begin(), process_list.end(), + [&](const SharedPtr& process) { return process->process_id == process_id; }); + + if (itr == process_list.end()) + return nullptr; + + return *itr; +} + +SharedPtr g_current_process; +} // namespace Kernel diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index b52211d2a..461391fd3 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "common/bit_field.h" #include "common/common_types.h" @@ -175,5 +176,10 @@ private: ~Process() override; }; +void ClearProcessList(); + +/// Retrieves a process from the current list of processes. +SharedPtr GetProcessById(u32 process_id); + extern SharedPtr g_current_process; -} +} // namespace Kernel diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 736007401..92eceb98f 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -516,6 +516,7 @@ void ThreadingShutdown() { } thread_list.clear(); ready_queue.clear(); + ClearProcessList(); } const std::vector>& GetThreadList() { diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index d80d4665a..452ab5506 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -15,8 +15,10 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" +#include "core/hle/kernel/process.h" #include "core/hle/kernel/server_session.h" #include "core/hle/result.h" +#include "core/hle/service/am/am.h" #include "core/hle/service/fs/archive.h" #include "core/hle/service/fs/fs_user.h" #include "core/settings.h" @@ -920,6 +922,52 @@ static void GetFormatInfo(Service::Interface* self) { cmd_buff[5] = format_info->duplicate_data; } +/** + * FS_User::GetProgramLaunchInfo service function. + * Inputs: + * 0 : 0x082F0040 + * 1 : Process ID + * Outputs: + * 0 : 0x082F0140 + * 1 : Result of function, 0 on success, otherwise error code + * 2-3 : Program ID + * 4 : Media type + * 5 : Unknown + */ +static void GetProgramLaunchInfo(Service::Interface* self) { + IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x82F, 1, 0); + + u32 process_id = rp.Pop(); + + LOG_DEBUG(Service_FS, "process_id=%u", process_id); + + // TODO(Subv): The real FS service manages its own process list and only checks the processes + // that were registered with the 'fs:REG' service. + auto process = Kernel::GetProcessById(process_id); + + IPC::RequestBuilder rb = rp.MakeBuilder(5, 0); + + if (process == nullptr) { + // Note: In this case, the rest of the parameters are not changed but the command header + // remains the same. + rb.Push(ResultCode(FileSys::ErrCodes::ArchiveNotMounted, ErrorModule::FS, + ErrorSummary::NotFound, ErrorLevel::Status)); + rb.Skip(4, false); + return; + } + + u64 program_id = process->codeset->program_id; + + auto media_type = Service::AM::GetTitleMediaType(program_id); + + rb.Push(RESULT_SUCCESS); + rb.Push(program_id); + rb.Push(static_cast(media_type)); + + // TODO(Subv): Find out what this value means. + rb.Push(0); +} + const Interface::FunctionInfo FunctionTable[] = { {0x000100C6, nullptr, "Dummy1"}, {0x040100C4, nullptr, "Control"}, @@ -969,7 +1017,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x082C0082, nullptr, "CardNorDirectCpuWriteWithoutVerify"}, {0x082D0040, nullptr, "CardNorDirectSectorEraseWithoutVerify"}, {0x082E0040, nullptr, "GetProductInfo"}, - {0x082F0040, nullptr, "GetProgramLaunchInfo"}, + {0x082F0040, GetProgramLaunchInfo, "GetProgramLaunchInfo"}, {0x08300182, nullptr, "CreateExtSaveData"}, {0x08310180, nullptr, "CreateSharedExtSaveData"}, {0x08320102, nullptr, "ReadExtSaveDataIcon"},