diff options
| author | Alex Barney <thealexbarney@gmail.com> | 2020-01-05 04:49:44 -0700 |
|---|---|---|
| committer | Thog <me@thog.eu> | 2020-01-05 12:49:44 +0100 |
| commit | 63b24b4af2804f173764c98586a19c39db04ad4d (patch) | |
| tree | 7994f00e4bc06edc430004a7caa1bdf0231b2668 /Ryujinx.HLE/HOS/Services | |
| parent | e0e12b1672e49ab5810bf88bf8274990605ed67a (diff) | |
Rename "RyuFs" directory to "Ryujinx" and use the same savedata system the Switch uses (#801)
* Use savedata FS commands from LibHac
* Add EnsureSaveData. Use ApplicationControlProperty struct
* Add a function to migrate to the new directory layout
* LibHac update
* Change backup structure
* Don't create UI files in the save path
* Update RyuFs paths
* Add GetProgramIndexForAccessLog
Ryujinx only runs one program at a time, so always return values reflecting that
* Load control NCA when loading from an NSP
* Skip over UI stats when exiting
* Set TitleName and TitleId in more cases. Fix TitleID naming style
* Completely comment out GUI play stats code
* rebase
* Update LibHac
* Update LibHac
* Revert UI changes
* Do migration automatically at startup
* Rename RyuFs directory to Ryujinx
* Update RyuFs text
* Store savedata paths in the GUI
* Make "Open Save Directory" work
* Use a dummy NACP in EnsureSaveData if one is not loaded
* Remove manual migration button
* Respond to feedback
* Don't read the installer config to get a version string
* Delete nuget.config
* Exclude 'sdcard' and 'bis' during migration
Co-authored-by: Thog <thog@protonmail.com>
Diffstat (limited to 'Ryujinx.HLE/HOS/Services')
7 files changed, 268 insertions, 285 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs index f8e6b22a..ec26d11f 100644 --- a/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs +++ b/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs @@ -287,7 +287,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc // Account actually calls nn::arp::detail::IReader::GetApplicationControlProperty() with the current PID and store the result (NACP File) internally. // But since we use LibHac and we load one Application at a time, it's not necessary. - context.ResponseData.Write(context.Device.System.ControlData.UserAccountSwitchLock); + context.ResponseData.Write(context.Device.System.ControlData.Value.UserAccountSwitchLock); Logger.PrintStub(LogClass.ServiceAcc); diff --git a/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs b/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs index 464d0b47..904264aa 100644 --- a/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs +++ b/Ryujinx.HLE/HOS/Services/Am/AppletOE/ApplicationProxyService/ApplicationProxy/IApplicationFunctions.cs @@ -1,13 +1,19 @@ +using LibHac; +using LibHac.Account; +using LibHac.Common; +using LibHac.Ncm; +using LibHac.Ns; +using Ryujinx.Common; using Ryujinx.Common.Logging; using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Threading; -using Ryujinx.HLE.HOS.Services.Am.AppletAE; using Ryujinx.HLE.HOS.Services.Am.AppletAE.Storage; using Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService; -using Ryujinx.HLE.Utilities; using System; +using static LibHac.Fs.ApplicationSaveDataManagement; + namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy { class IApplicationFunctions : IpcService @@ -24,7 +30,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati public ResultCode PopLaunchParameter(ServiceCtx context) { // Only the first 0x18 bytes of the Data seems to be actually used. - MakeObject(context, new IStorage(StorageHelper.MakeLaunchParams())); + MakeObject(context, new AppletAE.IStorage(StorageHelper.MakeLaunchParams())); return ResultCode.Success; } @@ -33,13 +39,33 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati // EnsureSaveData(nn::account::Uid) -> u64 public ResultCode EnsureSaveData(ServiceCtx context) { - UInt128 userId = new UInt128(context.RequestData.ReadBytes(0x10)); + Uid userId = context.RequestData.ReadStruct<Uid>(); + TitleId titleId = new TitleId(context.Process.TitleId); - context.ResponseData.Write(0L); + BlitStruct<ApplicationControlProperty> controlHolder = context.Device.System.ControlData; - Logger.PrintStub(LogClass.ServiceAm, new { userId }); + ref ApplicationControlProperty control = ref controlHolder.Value; - return ResultCode.Success; + if (Util.IsEmpty(controlHolder.ByteSpan)) + { + // If the current application doesn't have a loaded control property, create a dummy one + // and set the savedata sizes so a user savedata will be created. + control = ref new BlitStruct<ApplicationControlProperty>(1).Value; + + // The set sizes don't actually matter as long as they're non-zero because we use directory savedata. + control.UserAccountSaveDataSize = 0x4000; + control.UserAccountSaveDataJournalSize = 0x4000; + + Logger.PrintWarning(LogClass.ServiceAm, + "No control file was found for this game. Using a dummy one instead. This may cause inaccuracies in some games."); + } + + Result result = EnsureApplicationSaveData(context.Device.System.FsClient, out long requiredSize, titleId, + ref context.Device.System.ControlData.Value, ref userId); + + context.ResponseData.Write(requiredSize); + + return (ResultCode)result.Value; } [Command(21)] diff --git a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs index 2b0f06dd..1dd5fb86 100644 --- a/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs +++ b/Ryujinx.HLE/HOS/Services/Fs/FileSystemProxy/FileSystemProxyHelper.cs @@ -3,54 +3,12 @@ using LibHac.Fs; using LibHac.FsSystem; using LibHac.FsSystem.NcaUtils; using LibHac.Spl; -using Ryujinx.Common; -using Ryujinx.HLE.FileSystem; -using Ryujinx.HLE.Utilities; using System.IO; namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy { static class FileSystemProxyHelper { - public static ResultCode LoadSaveDataFileSystem(ServiceCtx context, bool readOnly, out IFileSystem loadedFileSystem) - { - loadedFileSystem = null; - - SaveSpaceId saveSpaceId = (SaveSpaceId)context.RequestData.ReadInt64(); - ulong titleId = context.RequestData.ReadUInt64(); - UInt128 userId = context.RequestData.ReadStruct<UInt128>(); - long saveId = context.RequestData.ReadInt64(); - SaveDataType saveDataType = (SaveDataType)context.RequestData.ReadByte(); - SaveInfo saveInfo = new SaveInfo(titleId, saveId, saveDataType, saveSpaceId, userId); - string savePath = context.Device.FileSystem.GetSavePath(context, saveInfo); - - try - { - LocalFileSystem fileSystem = new LocalFileSystem(savePath); - - Result result = DirectorySaveDataFileSystem.CreateNew(out DirectorySaveDataFileSystem dirFileSystem, fileSystem); - if (result.IsFailure()) - { - return (ResultCode)result.Value; - } - - LibHac.Fs.IFileSystem saveFileSystem = dirFileSystem; - - if (readOnly) - { - saveFileSystem = new ReadOnlyFileSystem(saveFileSystem); - } - - loadedFileSystem = new IFileSystem(saveFileSystem); - } - catch (HorizonResultException ex) - { - return (ResultCode)ex.ResultValue.Value; - } - - return ResultCode.Success; - } - public static ResultCode OpenNsp(ServiceCtx context, string pfsPath, out IFileSystem openedFileSystem) { openedFileSystem = null; @@ -154,5 +112,15 @@ namespace Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy } } } + + public static Result ReadFsPath(out FsPath path, ServiceCtx context, int index = 0) + { + long position = context.Request.SendBuff[index].Position; + long size = context.Request.SendBuff[index].Size; + + byte[] pathBytes = context.Memory.ReadBytes(position, size); + + return FsPath.FromSpan(out path, pathBytes); + } } } diff --git a/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs b/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs index 38111019..60f4a3f4 100644 --- a/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs +++ b/Ryujinx.HLE/HOS/Services/Fs/IFileSystemProxy.cs @@ -3,13 +3,14 @@ using LibHac.Fs; using LibHac.FsService; using LibHac.FsSystem; using LibHac.FsSystem.NcaUtils; +using LibHac.Ncm; +using Ryujinx.Common; using Ryujinx.Common.Logging; -using Ryujinx.HLE.FileSystem; using Ryujinx.HLE.HOS.Services.Fs.FileSystemProxy; using System.IO; -using static Ryujinx.HLE.FileSystem.VirtualFileSystem; using static Ryujinx.HLE.Utilities.StringUtils; +using StorageId = Ryujinx.HLE.FileSystem.StorageId; namespace Ryujinx.HLE.HOS.Services.Fs { @@ -90,29 +91,13 @@ namespace Ryujinx.HLE.HOS.Services.Fs // OpenBisFileSystem(nn::fssrv::sf::Partition partitionID, buffer<bytes<0x301>, 0x19, 0x301>) -> object<nn::fssrv::sf::IFileSystem> Bis public ResultCode OpenBisFileSystem(ServiceCtx context) { - int bisPartitionId = context.RequestData.ReadInt32(); - string partitionString = ReadUtf8String(context); - string bisPartitionPath = string.Empty; + BisPartitionId bisPartitionId = (BisPartitionId)context.RequestData.ReadInt32(); - switch (bisPartitionId) - { - case 29: - bisPartitionPath = SafeNandPath; - break; - case 30: - case 31: - bisPartitionPath = SystemNandPath; - break; - case 32: - bisPartitionPath = UserNandPath; - break; - default: - return ResultCode.InvalidInput; - } + Result rc = FileSystemProxyHelper.ReadFsPath(out FsPath path, context); + if (rc.IsFailure()) return (ResultCode)rc.Value; - string fullPath = context.Device.FileSystem.GetFullPartitionPath(bisPartitionPath); - - LocalFileSystem fileSystem = new LocalFileSystem(fullPath); + rc = _baseFileSystemProxy.OpenBisFileSystem(out LibHac.Fs.IFileSystem fileSystem, ref path, bisPartitionId); + if (rc.IsFailure()) return (ResultCode)rc.Value; MakeObject(context, new FileSystemProxy.IFileSystem(fileSystem)); @@ -123,15 +108,69 @@ namespace Ryujinx.HLE.HOS.Services.Fs // OpenSdCardFileSystem() -> object<nn::fssrv::sf::IFileSystem> public ResultCode OpenSdCardFileSystem(ServiceCtx context) { - string sdCardPath = context.Device.FileSystem.GetSdCardPath(); - - LocalFileSystem fileSystem = new LocalFileSystem(sdCardPath); + Result rc = _baseFileSystemProxy.OpenSdCardFileSystem(out LibHac.Fs.IFileSystem fileSystem); + if (rc.IsFailure()) return (ResultCode)rc.Value; MakeObject(context, new FileSystemProxy.IFileSystem(fileSystem)); return ResultCode.Success; } + [Command(21)] + public ResultCode DeleteSaveDataFileSystem(ServiceCtx context) + { + ulong saveDataId = context.RequestData.ReadUInt64(); + + Result result = _baseFileSystemProxy.DeleteSaveDataFileSystem(saveDataId); + + return (ResultCode)result.Value; + } + + [Command(22)] + public ResultCode CreateSaveDataFileSystem(ServiceCtx context) + { + SaveDataAttribute attribute = context.RequestData.ReadStruct<SaveDataAttribute>(); + SaveDataCreateInfo createInfo = context.RequestData.ReadStruct<SaveDataCreateInfo>(); + SaveMetaCreateInfo metaCreateInfo = context.RequestData.ReadStruct<SaveMetaCreateInfo>(); + + Result result = _baseFileSystemProxy.CreateSaveDataFileSystem(ref attribute, ref createInfo, ref metaCreateInfo); + + return (ResultCode)result.Value; + } + + [Command(23)] + public ResultCode CreateSaveDataFileSystemBySystemSaveDataId(ServiceCtx context) + { + SaveDataAttribute attribute = context.RequestData.ReadStruct<SaveDataAttribute>(); + SaveDataCreateInfo createInfo = context.RequestData.ReadStruct<SaveDataCreateInfo>(); + + Result result = _baseFileSystemProxy.CreateSaveDataFileSystemBySystemSaveDataId(ref attribute, ref createInfo); + + return (ResultCode)result.Value; + } + + [Command(25)] + public ResultCode DeleteSaveDataFileSystemBySaveDataSpaceId(ServiceCtx context) + { + SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); + ulong saveDataId = context.RequestData.ReadUInt64(); + + Result result = _baseFileSystemProxy.DeleteSaveDataFileSystemBySaveDataSpaceId(spaceId, saveDataId); + + return (ResultCode)result.Value; + } + + [Command(28)] + public ResultCode DeleteSaveDataFileSystemBySaveDataAttribute(ServiceCtx context) + { + SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); + SaveDataAttribute attribute = context.RequestData.ReadStruct<SaveDataAttribute>(); + + Result result = _baseFileSystemProxy.DeleteSaveDataFileSystemBySaveDataAttribute(spaceId, ref attribute); + + return (ResultCode)result.Value; + } + [Command(30)] // OpenGameCardStorage(u32, u32) -> object<nn::fssrv::sf::IStorage> public ResultCode OpenGameCardStorage(ServiceCtx context) @@ -149,46 +188,141 @@ namespace Ryujinx.HLE.HOS.Services.Fs return (ResultCode)result.Value; } + [Command(35)] + public ResultCode CreateSaveDataFileSystemWithHashSalt(ServiceCtx context) + { + SaveDataAttribute attribute = context.RequestData.ReadStruct<SaveDataAttribute>(); + SaveDataCreateInfo createInfo = context.RequestData.ReadStruct<SaveDataCreateInfo>(); + SaveMetaCreateInfo metaCreateInfo = context.RequestData.ReadStruct<SaveMetaCreateInfo>(); + HashSalt hashSalt = context.RequestData.ReadStruct<HashSalt>(); + + Result result = _baseFileSystemProxy.CreateSaveDataFileSystemWithHashSalt(ref attribute, ref createInfo, ref metaCreateInfo, ref hashSalt); + + return (ResultCode)result.Value; + } + [Command(51)] // OpenSaveDataFileSystem(u8 save_data_space_id, nn::fssrv::sf::SaveStruct saveStruct) -> object<nn::fssrv::sf::IFileSystem> saveDataFs public ResultCode OpenSaveDataFileSystem(ServiceCtx context) { - ResultCode result = FileSystemProxyHelper.LoadSaveDataFileSystem(context, false, out FileSystemProxy.IFileSystem fileSystem); + SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); + SaveDataAttribute attribute = context.RequestData.ReadStruct<SaveDataAttribute>(); + + if (attribute.TitleId == TitleId.Zero) + { + attribute.TitleId = new TitleId(context.Process.TitleId); + } - if (result == ResultCode.Success) + Result result = _baseFileSystemProxy.OpenSaveDataFileSystem(out LibHac.Fs.IFileSystem fileSystem, spaceId, ref attribute); + + if (result.IsSuccess()) { - MakeObject(context, fileSystem); + MakeObject(context, new FileSystemProxy.IFileSystem(fileSystem)); } - return result; + return (ResultCode)result.Value; } [Command(52)] // OpenSaveDataFileSystemBySystemSaveDataId(u8 save_data_space_id, nn::fssrv::sf::SaveStruct saveStruct) -> object<nn::fssrv::sf::IFileSystem> systemSaveDataFs public ResultCode OpenSaveDataFileSystemBySystemSaveDataId(ServiceCtx context) { - ResultCode result = FileSystemProxyHelper.LoadSaveDataFileSystem(context, false, out FileSystemProxy.IFileSystem fileSystem); + SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); + SaveDataAttribute attribute = context.RequestData.ReadStruct<SaveDataAttribute>(); + + Result result = _baseFileSystemProxy.OpenSaveDataFileSystemBySystemSaveDataId(out LibHac.Fs.IFileSystem fileSystem, spaceId, ref attribute); - if (result == ResultCode.Success) + if (result.IsSuccess()) { - MakeObject(context, fileSystem); + MakeObject(context, new FileSystemProxy.IFileSystem(fileSystem)); } - return result; + return (ResultCode)result.Value; } [Command(53)] // OpenReadOnlySaveDataFileSystem(u8 save_data_space_id, nn::fssrv::sf::SaveStruct save_struct) -> object<nn::fssrv::sf::IFileSystem> public ResultCode OpenReadOnlySaveDataFileSystem(ServiceCtx context) { - ResultCode result = FileSystemProxyHelper.LoadSaveDataFileSystem(context, true, out FileSystemProxy.IFileSystem fileSystem); + SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); + SaveDataAttribute attribute = context.RequestData.ReadStruct<SaveDataAttribute>(); + + if (attribute.TitleId == TitleId.Zero) + { + attribute.TitleId = new TitleId(context.Process.TitleId); + } + + Result result = _baseFileSystemProxy.OpenReadOnlySaveDataFileSystem(out LibHac.Fs.IFileSystem fileSystem, spaceId, ref attribute); + + if (result.IsSuccess()) + { + MakeObject(context, new FileSystemProxy.IFileSystem(fileSystem)); + } + + return (ResultCode)result.Value; + } + + [Command(60)] + public ResultCode OpenSaveDataInfoReader(ServiceCtx context) + { + Result result = _baseFileSystemProxy.OpenSaveDataInfoReader(out LibHac.FsService.ISaveDataInfoReader infoReader); - if (result == ResultCode.Success) + if (result.IsSuccess()) { - MakeObject(context, fileSystem); + MakeObject(context, new ISaveDataInfoReader(infoReader)); } - return result; + return (ResultCode)result.Value; + } + + [Command(61)] + public ResultCode OpenSaveDataInfoReaderBySaveDataSpaceId(ServiceCtx context) + { + SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadByte(); + + Result result = _baseFileSystemProxy.OpenSaveDataInfoReaderBySaveDataSpaceId(out LibHac.FsService.ISaveDataInfoReader infoReader, spaceId); + + if (result.IsSuccess()) + { + MakeObject(context, new ISaveDataInfoReader(infoReader)); + } + + return (ResultCode)result.Value; + } + + [Command(67)] + public ResultCode FindSaveDataWithFilter(ServiceCtx context) + { + SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); + SaveDataFilter filter = context.RequestData.ReadStruct<SaveDataFilter>(); + + long bufferPosition = context.Request.ReceiveBuff[0].Position; + long bufferLen = context.Request.ReceiveBuff[0].Size; + + byte[] infoBuffer = new byte[bufferLen]; + + Result result = _baseFileSystemProxy.FindSaveDataWithFilter(out long count, infoBuffer, spaceId, ref filter); + + context.Memory.WriteBytes(bufferPosition, infoBuffer); + context.ResponseData.Write(count); + + return (ResultCode)result.Value; + } + + [Command(68)] + public ResultCode OpenSaveDataInfoReaderWithFilter(ServiceCtx context) + { + SaveDataSpaceId spaceId = (SaveDataSpaceId)context.RequestData.ReadInt64(); + SaveDataFilter filter = context.RequestData.ReadStruct<SaveDataFilter>(); + + Result result = _baseFileSystemProxy.OpenSaveDataInfoReaderWithFilter(out LibHac.FsService.ISaveDataInfoReader infoReader, spaceId, ref filter); + + if (result.IsSuccess()) + { + MakeObject(context, new ISaveDataInfoReader(infoReader)); + } + + return (ResultCode)result.Value; } [Command(200)] @@ -306,5 +440,17 @@ namespace Ryujinx.HLE.HOS.Services.Fs return ResultCode.Success; } + + [Command(1011)] + public ResultCode GetProgramIndexForAccessLog(ServiceCtx context) + { + int programIndex = 0; + int programCount = 1; + + context.ResponseData.Write(programIndex); + context.ResponseData.Write(programCount); + + return ResultCode.Success; + } } }
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Fs/ISaveDataInfoReader.cs b/Ryujinx.HLE/HOS/Services/Fs/ISaveDataInfoReader.cs new file mode 100644 index 00000000..3d5ae8e2 --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Fs/ISaveDataInfoReader.cs @@ -0,0 +1,31 @@ +using LibHac; + +namespace Ryujinx.HLE.HOS.Services.Fs +{ + class ISaveDataInfoReader : IpcService + { + private LibHac.FsService.ISaveDataInfoReader _baseReader; + + public ISaveDataInfoReader(LibHac.FsService.ISaveDataInfoReader baseReader) + { + _baseReader = baseReader; + } + + [Command(0)] + // ReadSaveDataInfo() -> (u64, buffer<unknown, 6>) + public ResultCode ReadSaveDataInfo(ServiceCtx context) + { + long bufferPosition = context.Request.ReceiveBuff[0].Position; + long bufferLen = context.Request.ReceiveBuff[0].Size; + + byte[] infoBuffer = new byte[bufferLen]; + + Result result = _baseReader.ReadSaveDataInfo(out long readCount, infoBuffer); + + context.Memory.WriteBytes(bufferPosition, infoBuffer); + context.ResponseData.Write(readCount); + + return (ResultCode)result.Value; + } + } +} diff --git a/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs b/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs index d09403f9..e185233b 100644 --- a/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs +++ b/Ryujinx.HLE/HOS/Services/Ns/IApplicationManagerInterface.cs @@ -1,8 +1,4 @@ -using LibHac; -using System; -using System.Text; - -namespace Ryujinx.HLE.HOS.Services.Ns +namespace Ryujinx.HLE.HOS.Services.Ns { [Service("ns:am")] class IApplicationManagerInterface : IpcService @@ -10,201 +6,17 @@ namespace Ryujinx.HLE.HOS.Services.Ns public IApplicationManagerInterface(ServiceCtx context) { } [Command(400)] - // GetApplicationControlData(unknown<0x10>) -> (unknown<4>, buffer<unknown, 6>) + // GetApplicationControlData(u8, u64) -> (unknown<4>, buffer<unknown, 6>) public ResultCode GetApplicationControlData(ServiceCtx context) { - long position = context.Request.ReceiveBuff[0].Position; - - Nacp nacp = context.Device.System.ControlData; - - for (int i = 0; i < 0x10; i++) - { - NacpDescription description = nacp.Descriptions[i]; - - byte[] titleData = new byte[0x200]; - byte[] developerData = new byte[0x100]; - - if (description !=null && description.Title != null) - { - byte[] titleDescriptionData = Encoding.ASCII.GetBytes(description.Title); - Buffer.BlockCopy(titleDescriptionData, 0, titleData, 0, titleDescriptionData.Length); - - } - - if (description != null && description.Developer != null) - { - byte[] developerDescriptionData = Encoding.ASCII.GetBytes(description.Developer); - Buffer.BlockCopy(developerDescriptionData, 0, developerData, 0, developerDescriptionData.Length); - } - - context.Memory.WriteBytes(position, titleData); - context.Memory.WriteBytes(position + 0x200, developerData); - - position += i * 0x300; - } - - byte[] isbn = new byte[0x25]; - - if (nacp.Isbn != null) - { - byte[] isbnData = Encoding.ASCII.GetBytes(nacp.Isbn); - Buffer.BlockCopy(isbnData, 0, isbn, 0, isbnData.Length); - } - - context.Memory.WriteBytes(position, isbn); - position += isbn.Length; - - context.Memory.WriteByte(position++, nacp.StartupUserAccount); - context.Memory.WriteByte(position++, nacp.UserAccountSwitchLock); - context.Memory.WriteByte(position++, nacp.AocRegistrationType); - - context.Memory.WriteInt32(position, nacp.AttributeFlag); - position += 4; - - context.Memory.WriteUInt32(position, nacp.SupportedLanguageFlag); - position += 4; - - context.Memory.WriteUInt32(position, nacp.ParentalControlFlag); - position += 4; - - context.Memory.WriteByte(position++, nacp.Screenshot); - context.Memory.WriteByte(position++, nacp.VideoCapture); - context.Memory.WriteByte(position++, nacp.DataLossConfirmation); - context.Memory.WriteByte(position++, nacp.PlayLogPolicy); - - context.Memory.WriteUInt64(position, nacp.PresenceGroupId); - position += 8; - - for (int i = 0; i < nacp.RatingAge.Length; i++) - { - context.Memory.WriteSByte(position++, nacp.RatingAge[i]); - } - - byte[] displayVersion = new byte[0x10]; - - if (nacp.DisplayVersion != null) - { - byte[] displayVersionData = Encoding.ASCII.GetBytes(nacp.DisplayVersion); - Buffer.BlockCopy(displayVersionData, 0, displayVersion, 0, displayVersionData.Length); - } - - context.Memory.WriteBytes(position, displayVersion); - position += displayVersion.Length; - - context.Memory.WriteUInt64(position, nacp.AddOnContentBaseId); - position += 8; - - context.Memory.WriteUInt64(position, nacp.SaveDataOwnerId); - position += 8; - - context.Memory.WriteInt64(position, nacp.UserAccountSaveDataSize); - position += 8; - - context.Memory.WriteInt64(position, nacp.UserAccountSaveDataJournalSize); - position += 8; + byte source = (byte)context.RequestData.ReadInt64(); + ulong titleId = (byte)context.RequestData.ReadUInt64(); - context.Memory.WriteInt64(position, nacp.DeviceSaveDataSize); - position += 8; - - context.Memory.WriteInt64(position, nacp.DeviceSaveDataJournalSize); - position += 8; - - context.Memory.WriteInt64(position, nacp.BcatDeliveryCacheStorageSize); - position += 8; - - byte[] applicationErrorCodeCategory = new byte[0x8]; - - if (nacp.ApplicationErrorCodeCategory != null) - { - byte[] applicationErrorCodeCategoryData = Encoding.ASCII.GetBytes(nacp.ApplicationErrorCodeCategory); - Buffer.BlockCopy(applicationErrorCodeCategoryData, 0, applicationErrorCodeCategoryData, 0, applicationErrorCodeCategoryData.Length); - } - - context.Memory.WriteBytes(position, applicationErrorCodeCategory); - position += applicationErrorCodeCategory.Length; - - for (int i = 0; i < nacp.LocalCommunicationId.Length; i++) - { - context.Memory.WriteUInt64(position, nacp.LocalCommunicationId[i]); - position += 8; - } - - context.Memory.WriteByte(position++, nacp.LogoType); - context.Memory.WriteByte(position++, nacp.LogoHandling); - context.Memory.WriteByte(position++, nacp.RuntimeAddOnContentInstall); - - byte[] reserved000 = new byte[0x3]; - context.Memory.WriteBytes(position, reserved000); - position += reserved000.Length; - - context.Memory.WriteByte(position++, nacp.CrashReport); - context.Memory.WriteByte(position++, nacp.Hdcp); - context.Memory.WriteUInt64(position, nacp.SeedForPseudoDeviceId); - position += 8; - - byte[] bcatPassphrase = new byte[65]; - if (nacp.BcatPassphrase != null) - { - byte[] bcatPassphraseData = Encoding.ASCII.GetBytes(nacp.BcatPassphrase); - Buffer.BlockCopy(bcatPassphraseData, 0, bcatPassphrase, 0, bcatPassphraseData.Length); - } - - context.Memory.WriteBytes(position, bcatPassphrase); - position += bcatPassphrase.Length; - - context.Memory.WriteByte(position++, nacp.Reserved01); - - byte[] reserved02 = new byte[0x6]; - context.Memory.WriteBytes(position, reserved02); - position += reserved02.Length; - - context.Memory.WriteInt64(position, nacp.UserAccountSaveDataSizeMax); - position += 8; - - context.Memory.WriteInt64(position, nacp.UserAccountSaveDataJournalSizeMax); - position += 8; - - context.Memory.WriteInt64(position, nacp.DeviceSaveDataSizeMax); - position += 8; - - context.Memory.WriteInt64(position, nacp.DeviceSaveDataJournalSizeMax); - position += 8; - - context.Memory.WriteInt64(position, nacp.TemporaryStorageSize); - position += 8; - - context.Memory.WriteInt64(position, nacp.CacheStorageSize); - position += 8; - - context.Memory.WriteInt64(position, nacp.CacheStorageJournalSize); - position += 8; - - context.Memory.WriteInt64(position, nacp.CacheStorageDataAndJournalSizeMax); - position += 8; - - context.Memory.WriteInt16(position, nacp.CacheStorageIndex); - position += 2; - - byte[] reserved03 = new byte[0x6]; - context.Memory.WriteBytes(position, reserved03); - position += reserved03.Length; - - for (int i = 0; i < 16; i++) - { - ulong value = 0; - - if (nacp.PlayLogQueryableApplicationId.Count > i) - { - value = nacp.PlayLogQueryableApplicationId[i]; - } + long position = context.Request.ReceiveBuff[0].Position; - context.Memory.WriteUInt64(position, value); - position += 8; - } + byte[] nacpData = context.Device.System.ControlData.ByteSpan.ToArray(); - context.Memory.WriteByte(position++, nacp.PlayLogQueryCapability); - context.Memory.WriteByte(position++, nacp.RepairFlag); - context.Memory.WriteByte(position++, nacp.ProgramIndex); + context.Memory.WriteBytes(position, nacpData); return ResultCode.Success; } diff --git a/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs b/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs index b3646925..925a2593 100644 --- a/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs +++ b/Ryujinx.HLE/HOS/Services/Sdb/Pdm/QueryService/QueryPlayStatisticsManager.cs @@ -30,7 +30,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService } } - PlayLogQueryCapability queryCapability = (PlayLogQueryCapability)context.Device.System.ControlData.PlayLogQueryCapability; + PlayLogQueryCapability queryCapability = (PlayLogQueryCapability)context.Device.System.ControlData.Value.PlayLogQueryCapability; List<ulong> titleIds = new List<ulong>(); @@ -44,7 +44,7 @@ namespace Ryujinx.HLE.HOS.Services.Sdb.Pdm.QueryService // Check if input title ids are in the whitelist. foreach (ulong titleId in titleIds) { - if (!context.Device.System.ControlData.PlayLogQueryableApplicationId.Contains(titleId)) + if (!context.Device.System.ControlData.Value.PlayLogQueryableApplicationId.Contains(titleId)) { return (ResultCode)Am.ResultCode.ObjectInvalid; } |
