diff --git a/Ryujinx.HLE/HOS/Services/Acc/IAccountService.cs b/Ryujinx.HLE/HOS/Services/Acc/IAccountService.cs index 4bda472ebd..23f3eec79c 100644 --- a/Ryujinx.HLE/HOS/Services/Acc/IAccountService.cs +++ b/Ryujinx.HLE/HOS/Services/Acc/IAccountService.cs @@ -1,6 +1,6 @@ using Ryujinx.Common.Logging; using Ryujinx.HLE.FileSystem; -using Ryujinx.HLE.HOS.Services.Arp; +using Ryujinx.HLE.HOS.Services.Glue; using Ryujinx.HLE.HOS.SystemState; using Ryujinx.HLE.Utilities; using System; @@ -173,26 +173,14 @@ namespace Ryujinx.HLE.HOS.Services.Acc /* if (nn::arp::detail::IReader::GetApplicationLaunchProperty() == 0xCC9D) // InvalidProcessId { - _applicationLaunchProperty = new ApplicationLaunchProperty - { - TitleId = 0x00; - Version = 0x00; - BaseGameStorageId = 0x03; - UpdateGameStorageId = 0x00; - } + _applicationLaunchProperty = ApplicationLaunchProperty.Default; return ResultCode.InvalidArgument; } else */ { - _applicationLaunchProperty = new ApplicationLaunchProperty - { - TitleId = BitConverter.ToInt64(StringUtils.HexToBytes(context.Device.System.TitleID), 0), - Version = 0x00, - BaseGameStorageId = (byte)StorageId.NandSystem, - UpdateGameStorageId = (byte)StorageId.None - }; + _applicationLaunchProperty = ApplicationLaunchProperty.GetByPid(context); } Logger.PrintStub(LogClass.ServiceAcc, new { unknown }); diff --git a/Ryujinx.HLE/HOS/Services/Acc/IManagerForApplication.cs b/Ryujinx.HLE/HOS/Services/Acc/IManagerForApplication.cs index 02cafd2500..8fb901c5b7 100644 --- a/Ryujinx.HLE/HOS/Services/Acc/IManagerForApplication.cs +++ b/Ryujinx.HLE/HOS/Services/Acc/IManagerForApplication.cs @@ -1,5 +1,5 @@ using Ryujinx.Common.Logging; -using Ryujinx.HLE.HOS.Services.Arp; +using Ryujinx.HLE.HOS.Services.Glue; using Ryujinx.HLE.Utilities; namespace Ryujinx.HLE.HOS.Services.Acc diff --git a/Ryujinx.HLE/HOS/Services/Arp/ApplicationLaunchProperty.cs b/Ryujinx.HLE/HOS/Services/Arp/ApplicationLaunchProperty.cs deleted file mode 100644 index 16ffea0b84..0000000000 --- a/Ryujinx.HLE/HOS/Services/Arp/ApplicationLaunchProperty.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Ryujinx.HLE.HOS.Services.Arp -{ - class ApplicationLaunchProperty - { - public long TitleId; - public int Version; - public byte BaseGameStorageId; - public byte UpdateGameStorageId; - public short Padding; - } -} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Bcat/IBcatService.cs b/Ryujinx.HLE/HOS/Services/Bcat/IBcatService.cs index 6fdcba46c8..030f9110b0 100644 --- a/Ryujinx.HLE/HOS/Services/Bcat/IBcatService.cs +++ b/Ryujinx.HLE/HOS/Services/Bcat/IBcatService.cs @@ -1,7 +1,9 @@ +using Ryujinx.HLE.HOS.Services.Glue; + namespace Ryujinx.HLE.HOS.Services.Bcat { class IBcatService : IpcService { - public IBcatService() { } + public IBcatService(ApplicationLaunchProperty applicationLaunchProperty) { } } } \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Bcat/IDeliveryCacheStorageService.cs b/Ryujinx.HLE/HOS/Services/Bcat/IDeliveryCacheStorageService.cs index 5e3db998b7..1c9aed1183 100644 --- a/Ryujinx.HLE/HOS/Services/Bcat/IDeliveryCacheStorageService.cs +++ b/Ryujinx.HLE/HOS/Services/Bcat/IDeliveryCacheStorageService.cs @@ -1,7 +1,47 @@ +using Ryujinx.HLE.HOS.Services.Glue; +using System; +using System.Text; + namespace Ryujinx.HLE.HOS.Services.Bcat { class IDeliveryCacheStorageService : IpcService { - public IDeliveryCacheStorageService() { } + private const int DeliveryCacheDirectoriesLimit = 100; + private const int DeliveryCacheDirectoryNameLength = 32; + + private string[] _deliveryCacheDirectories = new string[0]; + + public IDeliveryCacheStorageService(ServiceCtx context, ApplicationLaunchProperty applicationLaunchProperty) + { + // TODO: Read directories.meta file from the save data (loaded in IServiceCreator) in _deliveryCacheDirectories. + } + + [Command(10)] + // EnumerateDeliveryCacheDirectory() -> (u32, buffer) + public ResultCode EnumerateDeliveryCacheDirectory(ServiceCtx context) + { + long outputPosition = context.Request.ReceiveBuff[0].Position; + long outputSize = context.Request.ReceiveBuff[0].Size; + + for (int index = 0; index < _deliveryCacheDirectories.Length; index++) + { + if (index == DeliveryCacheDirectoriesLimit - 1) + { + break; + } + + byte[] directoryNameBuffer = Encoding.ASCII.GetBytes(_deliveryCacheDirectories[index]); + + Array.Resize(ref directoryNameBuffer, DeliveryCacheDirectoryNameLength); + + directoryNameBuffer[DeliveryCacheDirectoryNameLength - 1] = 0x00; + + context.Memory.WriteBytes(outputPosition + index * DeliveryCacheDirectoryNameLength, directoryNameBuffer); + } + + context.ResponseData.Write(_deliveryCacheDirectories.Length); + + return ResultCode.Success; + } } } \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Bcat/IServiceCreator.cs b/Ryujinx.HLE/HOS/Services/Bcat/IServiceCreator.cs index e2a3b35224..4e9d36563d 100644 --- a/Ryujinx.HLE/HOS/Services/Bcat/IServiceCreator.cs +++ b/Ryujinx.HLE/HOS/Services/Bcat/IServiceCreator.cs @@ -1,3 +1,5 @@ +using Ryujinx.HLE.HOS.Services.Glue; + namespace Ryujinx.HLE.HOS.Services.Bcat { [Service("bcat:a")] @@ -12,9 +14,16 @@ namespace Ryujinx.HLE.HOS.Services.Bcat // CreateBcatService(u64, pid) -> object public ResultCode CreateBcatService(ServiceCtx context) { - long id = context.RequestData.ReadInt64(); + // TODO: Call arp:r GetApplicationLaunchProperty with the pid to get the TitleId. + // Add an instance of nn::bcat::detail::service::core::PassphraseManager. + // Add an instance of nn::bcat::detail::service::ServiceMemoryManager. + // Add an instance of nn::bcat::detail::service::core::TaskManager who load "bcat-sys:/" system save data and open "dc/task.bin". + // If the file don't exist, create a new one (size of 0x800) and write 2 empty struct with a size of 0x400. - MakeObject(context, new IBcatService()); + MakeObject(context, new IBcatService(ApplicationLaunchProperty.GetByPid(context))); + + // NOTE: If the IBcatService is null this error is returned, Doesn't occur in our case. + // return ResultCode.NullObject; return ResultCode.Success; } @@ -23,9 +32,16 @@ namespace Ryujinx.HLE.HOS.Services.Bcat // CreateDeliveryCacheStorageService(u64, pid) -> object public ResultCode CreateDeliveryCacheStorageService(ServiceCtx context) { - long id = context.RequestData.ReadInt64(); + // TODO: Call arp:r GetApplicationLaunchProperty with the pid to get the TitleId. + // Add an instance of nn::bcat::detail::service::core::ApplicationStorageManager who load "bcat-dc-X:/" system save data, + // return ResultCode.NullSaveData if failed. + // Where X depend of the ApplicationLaunchProperty stored in an array (range 0-3). + // Add an instance of nn::bcat::detail::service::ServiceMemoryManager. - MakeObject(context, new IDeliveryCacheStorageService()); + MakeObject(context, new IDeliveryCacheStorageService(context, ApplicationLaunchProperty.GetByPid(context))); + + // NOTE: If the IDeliveryCacheStorageService is null this error is returned, Doesn't occur in our case. + // return ResultCode.NullObject; return ResultCode.Success; } diff --git a/Ryujinx.HLE/HOS/Services/Bcat/ResultCode.cs b/Ryujinx.HLE/HOS/Services/Bcat/ResultCode.cs new file mode 100644 index 0000000000..bc13d9dd4a --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Bcat/ResultCode.cs @@ -0,0 +1,14 @@ +namespace Ryujinx.HLE.HOS.Services.Bcat +{ + enum ResultCode + { + ModuleId = 122, + ErrorCodeShift = 9, + + Success = 0, + + NullArgument = (2 << ErrorCodeShift) | ModuleId, + NullSaveData = (31 << ErrorCodeShift) | ModuleId, + NullObject = (91 << ErrorCodeShift) | ModuleId + } +} \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Glue/ApplicationLaunchProperty.cs b/Ryujinx.HLE/HOS/Services/Glue/ApplicationLaunchProperty.cs new file mode 100644 index 0000000000..b96f0d0549 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Glue/ApplicationLaunchProperty.cs @@ -0,0 +1,43 @@ +using Ryujinx.HLE.FileSystem; +using Ryujinx.HLE.Utilities; +using System; + +namespace Ryujinx.HLE.HOS.Services.Glue +{ + class ApplicationLaunchProperty + { + public long TitleId; + public int Version; + public byte BaseGameStorageId; + public byte UpdateGameStorageId; + public short Padding; + + public static ApplicationLaunchProperty Default + { + get + { + return new ApplicationLaunchProperty + { + TitleId = 0x00, + Version = 0x00, + BaseGameStorageId = (byte)StorageId.NandSystem, + UpdateGameStorageId = (byte)StorageId.None + }; + } + } + + public static ApplicationLaunchProperty GetByPid(ServiceCtx context) + { + // TODO: Handle ApplicationLaunchProperty as array when pid will be supported and return the right item. + // For now we can hardcode values, and fix it after GetApplicationLaunchProperty is implemented. + + return new ApplicationLaunchProperty + { + TitleId = BitConverter.ToInt64(StringUtils.HexToBytes(context.Device.System.TitleID), 0), + Version = 0x00, + BaseGameStorageId = (byte)StorageId.NandSystem, + UpdateGameStorageId = (byte)StorageId.None + }; + } + } +} \ No newline at end of file