aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Services/Ncm
diff options
context:
space:
mode:
authorAc_K <Acoustik666@gmail.com>2019-09-19 02:45:11 +0200
committerjduncanator <1518948+jduncanator@users.noreply.github.com>2019-09-19 10:45:11 +1000
commita0720b5681852f3d786d77bd3793b0359dea321c (patch)
tree9d8f61e540d1d1d827999902dad95e5c0c1e076e /Ryujinx.HLE/HOS/Services/Ncm
parent4af3101b22e6957d6aa48a2768566d658699f4ed (diff)
Refactoring HOS folder structure (#771)
* Refactoring HOS folder structure Refactoring HOS folder structure: - Added some subfolders when needed (Following structure decided in private). - Added some `Types` folders when needed. - Little cleanup here and there. - Add services placeholders for every HOS services (close #766 and #753). * Remove Types namespaces
Diffstat (limited to 'Ryujinx.HLE/HOS/Services/Ncm')
-rw-r--r--Ryujinx.HLE/HOS/Services/Ncm/IContentStorage.cs7
-rw-r--r--Ryujinx.HLE/HOS/Services/Ncm/Lr/ILocationResolverManager.cs22
-rw-r--r--Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs254
-rw-r--r--Ryujinx.HLE/HOS/Services/Ncm/Lr/ResultCode.cs13
4 files changed, 289 insertions, 7 deletions
diff --git a/Ryujinx.HLE/HOS/Services/Ncm/IContentStorage.cs b/Ryujinx.HLE/HOS/Services/Ncm/IContentStorage.cs
deleted file mode 100644
index 5bfbe4db..00000000
--- a/Ryujinx.HLE/HOS/Services/Ncm/IContentStorage.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Ncm
-{
- class IContentStorage : IpcService
- {
- public IContentStorage() { }
- }
-} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Ncm/Lr/ILocationResolverManager.cs b/Ryujinx.HLE/HOS/Services/Ncm/Lr/ILocationResolverManager.cs
new file mode 100644
index 00000000..44b8272b
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Ncm/Lr/ILocationResolverManager.cs
@@ -0,0 +1,22 @@
+using Ryujinx.HLE.FileSystem;
+using Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager;
+
+namespace Ryujinx.HLE.HOS.Services.Ncm.Lr
+{
+ [Service("lr")]
+ class ILocationResolverManager : IpcService
+ {
+ public ILocationResolverManager(ServiceCtx context) { }
+
+ [Command(0)]
+ // OpenLocationResolver()
+ public ResultCode OpenLocationResolver(ServiceCtx context)
+ {
+ StorageId storageId = (StorageId)context.RequestData.ReadByte();
+
+ MakeObject(context, new ILocationResolver(storageId));
+
+ return ResultCode.Success;
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs b/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs
new file mode 100644
index 00000000..d77bac73
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Ncm/Lr/LocationResolverManager/ILocationResolver.cs
@@ -0,0 +1,254 @@
+using LibHac.Fs.NcaUtils;
+using Ryujinx.HLE.FileSystem;
+using Ryujinx.HLE.FileSystem.Content;
+using System.Text;
+
+using static Ryujinx.HLE.Utilities.StringUtils;
+
+namespace Ryujinx.HLE.HOS.Services.Ncm.Lr.LocationResolverManager
+{
+ class ILocationResolver : IpcService
+ {
+ private StorageId _storageId;
+
+ public ILocationResolver(StorageId storageId)
+ {
+ _storageId = storageId;
+ }
+
+ [Command(0)]
+ // ResolveProgramPath()
+ public ResultCode ResolveProgramPath(ServiceCtx context)
+ {
+ long titleId = context.RequestData.ReadInt64();
+
+ if (ResolvePath(context, titleId, ContentType.Program))
+ {
+ return ResultCode.Success;
+ }
+ else
+ {
+ return ResultCode.ProgramLocationEntryNotFound;
+ }
+ }
+
+ [Command(1)]
+ // RedirectProgramPath()
+ public ResultCode RedirectProgramPath(ServiceCtx context)
+ {
+ long titleId = context.RequestData.ReadInt64();
+
+ RedirectPath(context, titleId, 0, ContentType.Program);
+
+ return ResultCode.Success;
+ }
+
+ [Command(2)]
+ // ResolveApplicationControlPath()
+ public ResultCode ResolveApplicationControlPath(ServiceCtx context)
+ {
+ long titleId = context.RequestData.ReadInt64();
+
+ if (ResolvePath(context, titleId, ContentType.Control))
+ {
+ return ResultCode.Success;
+ }
+ else
+ {
+ return ResultCode.AccessDenied;
+ }
+ }
+
+ [Command(3)]
+ // ResolveApplicationHtmlDocumentPath()
+ public ResultCode ResolveApplicationHtmlDocumentPath(ServiceCtx context)
+ {
+ long titleId = context.RequestData.ReadInt64();
+
+ if (ResolvePath(context, titleId, ContentType.Manual))
+ {
+ return ResultCode.Success;
+ }
+ else
+ {
+ return ResultCode.AccessDenied;
+ }
+ }
+
+ [Command(4)]
+ // ResolveDataPath()
+ public ResultCode ResolveDataPath(ServiceCtx context)
+ {
+ long titleId = context.RequestData.ReadInt64();
+
+ if (ResolvePath(context, titleId, ContentType.Data) || ResolvePath(context, titleId, ContentType.PublicData))
+ {
+ return ResultCode.Success;
+ }
+ else
+ {
+ return ResultCode.AccessDenied;
+ }
+ }
+
+ [Command(5)]
+ // RedirectApplicationControlPath()
+ public ResultCode RedirectApplicationControlPath(ServiceCtx context)
+ {
+ long titleId = context.RequestData.ReadInt64();
+
+ RedirectPath(context, titleId, 1, ContentType.Control);
+
+ return ResultCode.Success;
+ }
+
+ [Command(6)]
+ // RedirectApplicationHtmlDocumentPath()
+ public ResultCode RedirectApplicationHtmlDocumentPath(ServiceCtx context)
+ {
+ long titleId = context.RequestData.ReadInt64();
+
+ RedirectPath(context, titleId, 1, ContentType.Manual);
+
+ return ResultCode.Success;
+ }
+
+ [Command(7)]
+ // ResolveApplicationLegalInformationPath()
+ public ResultCode ResolveApplicationLegalInformationPath(ServiceCtx context)
+ {
+ long titleId = context.RequestData.ReadInt64();
+
+ if (ResolvePath(context, titleId, ContentType.Manual))
+ {
+ return ResultCode.Success;
+ }
+ else
+ {
+ return ResultCode.AccessDenied;
+ }
+ }
+
+ [Command(8)]
+ // RedirectApplicationLegalInformationPath()
+ public ResultCode RedirectApplicationLegalInformationPath(ServiceCtx context)
+ {
+ long titleId = context.RequestData.ReadInt64();
+
+ RedirectPath(context, titleId, 1, ContentType.Manual);
+
+ return ResultCode.Success;
+ }
+
+ [Command(9)]
+ // Refresh()
+ public ResultCode Refresh(ServiceCtx context)
+ {
+ context.Device.System.ContentManager.RefreshEntries(_storageId, 1);
+
+ return ResultCode.Success;
+ }
+
+ [Command(10)]
+ // SetProgramNcaPath2()
+ public ResultCode SetProgramNcaPath2(ServiceCtx context)
+ {
+ long titleId = context.RequestData.ReadInt64();
+
+ RedirectPath(context, titleId, 1, ContentType.Program);
+
+ return ResultCode.Success;
+ }
+
+ [Command(11)]
+ // ClearLocationResolver2()
+ public ResultCode ClearLocationResolver2(ServiceCtx context)
+ {
+ context.Device.System.ContentManager.RefreshEntries(_storageId, 1);
+
+ return ResultCode.Success;
+ }
+
+ [Command(12)]
+ // DeleteProgramNcaPath()
+ public ResultCode DeleteProgramNcaPath(ServiceCtx context)
+ {
+ long titleId = context.RequestData.ReadInt64();
+
+ DeleteContentPath(context, titleId, ContentType.Program);
+
+ return ResultCode.Success;
+ }
+
+ [Command(13)]
+ // DeleteControlNcaPath()
+ public ResultCode DeleteControlNcaPath(ServiceCtx context)
+ {
+ long titleId = context.RequestData.ReadInt64();
+
+ DeleteContentPath(context, titleId, ContentType.Control);
+
+ return ResultCode.Success;
+ }
+
+ [Command(14)]
+ // DeleteDocHtmlNcaPath()
+ public ResultCode DeleteDocHtmlNcaPath(ServiceCtx context)
+ {
+ long titleId = context.RequestData.ReadInt64();
+
+ DeleteContentPath(context, titleId, ContentType.Manual);
+
+ return ResultCode.Success;
+ }
+
+ [Command(15)]
+ // DeleteInfoHtmlNcaPath()
+ public ResultCode DeleteInfoHtmlNcaPath(ServiceCtx context)
+ {
+ long titleId = context.RequestData.ReadInt64();
+
+ DeleteContentPath(context, titleId, ContentType.Manual);
+
+ return ResultCode.Success;
+ }
+
+ private void RedirectPath(ServiceCtx context, long titleId, int flag, ContentType contentType)
+ {
+ string contentPath = ReadUtf8String(context);
+ LocationEntry newLocation = new LocationEntry(contentPath, flag, titleId, contentType);
+
+ context.Device.System.ContentManager.RedirectLocation(newLocation, _storageId);
+ }
+
+ private bool ResolvePath(ServiceCtx context, long titleId,ContentType contentType)
+ {
+ ContentManager contentManager = context.Device.System.ContentManager;
+ string contentPath = contentManager.GetInstalledContentPath(titleId, _storageId, ContentType.Program);
+
+ if (!string.IsNullOrWhiteSpace(contentPath))
+ {
+ long position = context.Request.RecvListBuff[0].Position;
+ long size = context.Request.RecvListBuff[0].Size;
+
+ byte[] contentPathBuffer = Encoding.UTF8.GetBytes(contentPath);
+
+ context.Memory.WriteBytes(position, contentPathBuffer);
+ }
+ else
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ private void DeleteContentPath(ServiceCtx context, long titleId, ContentType contentType)
+ {
+ ContentManager contentManager = context.Device.System.ContentManager;
+ string contentPath = contentManager.GetInstalledContentPath(titleId, _storageId, ContentType.Manual);
+
+ contentManager.ClearEntry(titleId, ContentType.Manual, _storageId);
+ }
+ }
+}
diff --git a/Ryujinx.HLE/HOS/Services/Ncm/Lr/ResultCode.cs b/Ryujinx.HLE/HOS/Services/Ncm/Lr/ResultCode.cs
new file mode 100644
index 00000000..5ff7e466
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Ncm/Lr/ResultCode.cs
@@ -0,0 +1,13 @@
+namespace Ryujinx.HLE.HOS.Services.Ncm.Lr
+{
+ enum ResultCode
+ {
+ ModuleId = 8,
+ ErrorCodeShift = 9,
+
+ Success = 0,
+
+ ProgramLocationEntryNotFound = (2 << ErrorCodeShift) | ModuleId,
+ AccessDenied = (5 << ErrorCodeShift) | ModuleId
+ }
+} \ No newline at end of file