diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-01-18 16:54:34 -0300 | 
|---|---|---|
| committer | bunnei <bunneidev@gmail.com> | 2018-01-18 14:54:34 -0500 | 
| commit | 59575d5cae573b57eb9e1e611e2c25ceb935ec0a (patch) | |
| tree | ec98ab8ec825b0001face3a4e7c9b821bd67e0b2 /src/core/hle/service | |
| parent | 463356f0a74d103ff1d4e6ef5cbd73b8a8b53135 (diff) | |
Stub PopLaunchParameter and implement Buffer C Descriptors reading on hle_ipc (#96)
* Stub PopLaunchParameter and implement Buffer C Descriptors reading
* Address PR feedback
* Ensure we push a u64 not a size_t
* Fix formatting
Diffstat (limited to 'src/core/hle/service')
| -rw-r--r-- | src/core/hle/service/am/applet_oe.cpp | 86 | 
1 files changed, 86 insertions, 0 deletions
diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp index b360e7e5f..0d7f9c03d 100644 --- a/src/core/hle/service/am/applet_oe.cpp +++ b/src/core/hle/service/am/applet_oe.cpp @@ -201,10 +201,76 @@ private:      Kernel::SharedPtr<Kernel::Event> event;  }; +class IStorageAccessor final : public ServiceFramework<IStorageAccessor> { +public: +    explicit IStorageAccessor(std::vector<u8> buffer) +        : ServiceFramework("IStorageAccessor"), buffer(std::move(buffer)) { +        static const FunctionInfo functions[] = { +            {0, &IStorageAccessor::GetSize, "GetSize"}, +            {11, &IStorageAccessor::Read, "Read"}, +        }; +        RegisterHandlers(functions); +    } + +private: +    std::vector<u8> buffer; + +    void GetSize(Kernel::HLERequestContext& ctx) { +        IPC::RequestBuilder rb{ctx, 4}; + +        rb.Push(RESULT_SUCCESS); +        rb.Push(static_cast<u64>(buffer.size())); + +        LOG_DEBUG(Service, "called"); +    } + +    void Read(Kernel::HLERequestContext& ctx) { +        IPC::RequestParser rp{ctx}; + +        u64 offset = rp.Pop<u64>(); + +        const auto& output_buffer = ctx.BufferDescriptorC()[0]; + +        ASSERT(offset + output_buffer.Size() <= buffer.size()); + +        Memory::WriteBlock(output_buffer.Address(), buffer.data() + offset, output_buffer.Size()); + +        IPC::RequestBuilder rb{ctx, 2}; + +        rb.Push(RESULT_SUCCESS); + +        LOG_DEBUG(Service, "called"); +    } +}; + +class IStorage final : public ServiceFramework<IStorage> { +public: +    explicit IStorage(std::vector<u8> buffer) +        : ServiceFramework("IStorage"), buffer(std::move(buffer)) { +        static const FunctionInfo functions[] = { +            {0, &IStorage::Open, "Open"}, +        }; +        RegisterHandlers(functions); +    } + +private: +    std::vector<u8> buffer; + +    void Open(Kernel::HLERequestContext& ctx) { +        IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; + +        rb.Push(RESULT_SUCCESS); +        rb.PushIpcInterface<AM::IStorageAccessor>(buffer); + +        LOG_DEBUG(Service, "called"); +    } +}; +  class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {  public:      IApplicationFunctions() : ServiceFramework("IApplicationFunctions") {          static const FunctionInfo functions[] = { +            {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},              {22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},              {66, &IApplicationFunctions::InitializeGamePlayRecording,               "InitializeGamePlayRecording"}, @@ -215,6 +281,26 @@ public:      }  private: +    void PopLaunchParameter(Kernel::HLERequestContext& ctx) { +        constexpr u8 data[0x88] = { +            0xca, 0x97, 0x94, 0xc7, // Magic +            1,    0,    0,    0,    // IsAccountSelected (bool) +            1,    0,    0,    0,    // User Id (word 0) +            0,    0,    0,    0,    // User Id (word 1) +            0,    0,    0,    0,    // User Id (word 2) +            0,    0,    0,    0     // User Id (word 3) +        }; + +        std::vector<u8> buffer(data, data + sizeof(data)); + +        IPC::RequestBuilder rb{ctx, 2, 0, 0, 1}; + +        rb.Push(RESULT_SUCCESS); +        rb.PushIpcInterface<AM::IStorage>(buffer); + +        LOG_DEBUG(Service, "called"); +    } +      void SetTerminateResult(Kernel::HLERequestContext& ctx) {          // Takes an input u32 Result, no output.          // For example, in some cases official apps use this with error 0x2A2 then uses svcBreak.  | 
