mirror of
https://github.com/PabloMK7/citra.git
synced 2024-12-01 19:59:38 +00:00
HLE/FS: Implemented FS::GetProgramLaunchInfo.
This function is used by the DLP system module during the DLPSRVR initialization.
This commit is contained in:
parent
81fbe06915
commit
7d038b9bd8
4 changed files with 78 additions and 3 deletions
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
|
@ -16,6 +17,9 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
// Lists all processes that exist in the current session.
|
||||||
|
static std::vector<SharedPtr<Process>> process_list;
|
||||||
|
|
||||||
SharedPtr<CodeSet> CodeSet::Create(std::string name, u64 program_id) {
|
SharedPtr<CodeSet> CodeSet::Create(std::string name, u64 program_id) {
|
||||||
SharedPtr<CodeSet> codeset(new CodeSet);
|
SharedPtr<CodeSet> codeset(new CodeSet);
|
||||||
|
|
||||||
|
@ -37,6 +41,7 @@ SharedPtr<Process> Process::Create(SharedPtr<CodeSet> code_set) {
|
||||||
process->flags.raw = 0;
|
process->flags.raw = 0;
|
||||||
process->flags.memory_region.Assign(MemoryRegion::APPLICATION);
|
process->flags.memory_region.Assign(MemoryRegion::APPLICATION);
|
||||||
|
|
||||||
|
process_list.push_back(process);
|
||||||
return process;
|
return process;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,5 +304,20 @@ ResultCode Process::LinearFree(VAddr target, u32 size) {
|
||||||
Kernel::Process::Process() {}
|
Kernel::Process::Process() {}
|
||||||
Kernel::Process::~Process() {}
|
Kernel::Process::~Process() {}
|
||||||
|
|
||||||
SharedPtr<Process> g_current_process;
|
void ClearProcessList() {
|
||||||
|
process_list.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SharedPtr<Process> GetProcessById(u32 process_id) {
|
||||||
|
auto itr = std::find_if(
|
||||||
|
process_list.begin(), process_list.end(),
|
||||||
|
[&](const SharedPtr<Process>& process) { return process->process_id == process_id; });
|
||||||
|
|
||||||
|
if (itr == process_list.end())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return *itr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedPtr<Process> g_current_process;
|
||||||
|
} // namespace Kernel
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include <boost/container/static_vector.hpp>
|
#include <boost/container/static_vector.hpp>
|
||||||
#include "common/bit_field.h"
|
#include "common/bit_field.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
@ -175,5 +176,10 @@ private:
|
||||||
~Process() override;
|
~Process() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void ClearProcessList();
|
||||||
|
|
||||||
|
/// Retrieves a process from the current list of processes.
|
||||||
|
SharedPtr<Process> GetProcessById(u32 process_id);
|
||||||
|
|
||||||
extern SharedPtr<Process> g_current_process;
|
extern SharedPtr<Process> g_current_process;
|
||||||
}
|
} // namespace Kernel
|
||||||
|
|
|
@ -516,6 +516,7 @@ void ThreadingShutdown() {
|
||||||
}
|
}
|
||||||
thread_list.clear();
|
thread_list.clear();
|
||||||
ready_queue.clear();
|
ready_queue.clear();
|
||||||
|
ClearProcessList();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<SharedPtr<Thread>>& GetThreadList() {
|
const std::vector<SharedPtr<Thread>>& GetThreadList() {
|
||||||
|
|
|
@ -15,8 +15,10 @@
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
#include "core/hle/kernel/client_port.h"
|
#include "core/hle/kernel/client_port.h"
|
||||||
#include "core/hle/kernel/client_session.h"
|
#include "core/hle/kernel/client_session.h"
|
||||||
|
#include "core/hle/kernel/process.h"
|
||||||
#include "core/hle/kernel/server_session.h"
|
#include "core/hle/kernel/server_session.h"
|
||||||
#include "core/hle/result.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/archive.h"
|
||||||
#include "core/hle/service/fs/fs_user.h"
|
#include "core/hle/service/fs/fs_user.h"
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
|
@ -920,6 +922,52 @@ static void GetFormatInfo(Service::Interface* self) {
|
||||||
cmd_buff[5] = format_info->duplicate_data;
|
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<u32>();
|
||||||
|
|
||||||
|
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<u8>(media_type));
|
||||||
|
|
||||||
|
// TODO(Subv): Find out what this value means.
|
||||||
|
rb.Push<u32>(0);
|
||||||
|
}
|
||||||
|
|
||||||
const Interface::FunctionInfo FunctionTable[] = {
|
const Interface::FunctionInfo FunctionTable[] = {
|
||||||
{0x000100C6, nullptr, "Dummy1"},
|
{0x000100C6, nullptr, "Dummy1"},
|
||||||
{0x040100C4, nullptr, "Control"},
|
{0x040100C4, nullptr, "Control"},
|
||||||
|
@ -969,7 +1017,7 @@ const Interface::FunctionInfo FunctionTable[] = {
|
||||||
{0x082C0082, nullptr, "CardNorDirectCpuWriteWithoutVerify"},
|
{0x082C0082, nullptr, "CardNorDirectCpuWriteWithoutVerify"},
|
||||||
{0x082D0040, nullptr, "CardNorDirectSectorEraseWithoutVerify"},
|
{0x082D0040, nullptr, "CardNorDirectSectorEraseWithoutVerify"},
|
||||||
{0x082E0040, nullptr, "GetProductInfo"},
|
{0x082E0040, nullptr, "GetProductInfo"},
|
||||||
{0x082F0040, nullptr, "GetProgramLaunchInfo"},
|
{0x082F0040, GetProgramLaunchInfo, "GetProgramLaunchInfo"},
|
||||||
{0x08300182, nullptr, "CreateExtSaveData"},
|
{0x08300182, nullptr, "CreateExtSaveData"},
|
||||||
{0x08310180, nullptr, "CreateSharedExtSaveData"},
|
{0x08310180, nullptr, "CreateSharedExtSaveData"},
|
||||||
{0x08320102, nullptr, "ReadExtSaveDataIcon"},
|
{0x08320102, nullptr, "ReadExtSaveDataIcon"},
|
||||||
|
|
Loading…
Reference in a new issue