Quellcode durchsuchen

glue: Correct missing bytes in ApplicationLaunchParameter

Zach Hilman vor 7 Jahren
Ursprung
Commit
d10fc2d727

+ 0 - 2
src/core/core.cpp

@@ -61,8 +61,6 @@ FileSys::StorageId GetStorageIdForFrontendSlot(
     default:
     default:
         return FileSys::StorageId::None;
         return FileSys::StorageId::None;
     }
     }
-
-    UNREACHABLE();
 }
 }
 
 
 } // Anonymous namespace
 } // Anonymous namespace

+ 3 - 0
src/core/file_sys/patch_manager.h

@@ -66,6 +66,9 @@ public:
     std::map<std::string, std::string, std::less<>> GetPatchVersionNames(
     std::map<std::string, std::string, std::less<>> GetPatchVersionNames(
         VirtualFile update_raw = nullptr) const;
         VirtualFile update_raw = nullptr) const;
 
 
+    // If the game update exists, returns the u32 version field in its Meta-type NCA. If that fails,
+    // it will fallback to the Meta-type NCA of the base game. If that fails, the result will be
+    // std::nullopt
     std::optional<u32> GetGameVersion() const;
     std::optional<u32> GetGameVersion() const;
 
 
     // Given title_id of the program, attempts to get the control data of the update and parse
     // Given title_id of the program, attempts to get the control data of the update and parse

+ 7 - 7
src/core/file_sys/registered_cache.cpp

@@ -647,16 +647,16 @@ ContentProviderUnion::ListEntriesFilterOrigin(std::optional<ContentProviderUnion
 
 
 std::optional<ContentProviderUnionSlot> ContentProviderUnion::GetSlotForEntry(
 std::optional<ContentProviderUnionSlot> ContentProviderUnion::GetSlotForEntry(
     u64 title_id, ContentRecordType type) const {
     u64 title_id, ContentRecordType type) const {
-    for (const auto& [slot, provider] : providers) {
-        if (provider == nullptr)
-            continue;
+    const auto iter =
+        std::find_if(providers.begin(), providers.end(), [title_id, type](const auto& provider) {
+            return provider.second != nullptr && provider.second->HasEntry(title_id, type);
+        });
 
 
-        if (provider->HasEntry(title_id, type)) {
-            return slot;
-        }
+    if (iter == providers.end()) {
+        return std::nullopt;
     }
     }
 
 
-    return std::nullopt;
+    return iter->first;
 }
 }
 
 
 ManualContentProvider::~ManualContentProvider() = default;
 ManualContentProvider::~ManualContentProvider() = default;

+ 21 - 9
src/core/hle/service/glue/arp.cpp

@@ -58,7 +58,8 @@ void ARP_R::GetApplicationLaunchProperty(Kernel::HLERequestContext& ctx) {
     if (!title_id.has_value()) {
     if (!title_id.has_value()) {
         LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!");
         LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!");
         IPC::ResponseBuilder rb{ctx, 2};
         IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(ERR_NONEXISTENT);
+        rb.Push(ERR_NOT_REGISTERED);
+        return;
     }
     }
 
 
     const auto res = manager.GetLaunchProperty(*title_id);
     const auto res = manager.GetLaunchProperty(*title_id);
@@ -67,6 +68,7 @@ void ARP_R::GetApplicationLaunchProperty(Kernel::HLERequestContext& ctx) {
         LOG_ERROR(Service_ARP, "Failed to get launch property!");
         LOG_ERROR(Service_ARP, "Failed to get launch property!");
         IPC::ResponseBuilder rb{ctx, 2};
         IPC::ResponseBuilder rb{ctx, 2};
         rb.Push(res.Code());
         rb.Push(res.Code());
+        return;
     }
     }
 
 
     IPC::ResponseBuilder rb{ctx, 6};
     IPC::ResponseBuilder rb{ctx, 6};
@@ -86,6 +88,7 @@ void ARP_R::GetApplicationLaunchPropertyWithApplicationId(Kernel::HLERequestCont
         LOG_ERROR(Service_ARP, "Failed to get launch property!");
         LOG_ERROR(Service_ARP, "Failed to get launch property!");
         IPC::ResponseBuilder rb{ctx, 2};
         IPC::ResponseBuilder rb{ctx, 2};
         rb.Push(res.Code());
         rb.Push(res.Code());
+        return;
     }
     }
 
 
     IPC::ResponseBuilder rb{ctx, 6};
     IPC::ResponseBuilder rb{ctx, 6};
@@ -103,7 +106,8 @@ void ARP_R::GetApplicationControlProperty(Kernel::HLERequestContext& ctx) {
     if (!title_id.has_value()) {
     if (!title_id.has_value()) {
         LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!");
         LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!");
         IPC::ResponseBuilder rb{ctx, 2};
         IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(ERR_NONEXISTENT);
+        rb.Push(ERR_NOT_REGISTERED);
+        return;
     }
     }
 
 
     const auto res = manager.GetControlProperty(*title_id);
     const auto res = manager.GetControlProperty(*title_id);
@@ -112,6 +116,7 @@ void ARP_R::GetApplicationControlProperty(Kernel::HLERequestContext& ctx) {
         LOG_ERROR(Service_ARP, "Failed to get control property!");
         LOG_ERROR(Service_ARP, "Failed to get control property!");
         IPC::ResponseBuilder rb{ctx, 2};
         IPC::ResponseBuilder rb{ctx, 2};
         rb.Push(res.Code());
         rb.Push(res.Code());
+        return;
     }
     }
 
 
     ctx.WriteBuffer(*res);
     ctx.WriteBuffer(*res);
@@ -132,6 +137,7 @@ void ARP_R::GetApplicationControlPropertyWithApplicationId(Kernel::HLERequestCon
         LOG_ERROR(Service_ARP, "Failed to get control property!");
         LOG_ERROR(Service_ARP, "Failed to get control property!");
         IPC::ResponseBuilder rb{ctx, 2};
         IPC::ResponseBuilder rb{ctx, 2};
         rb.Push(res.Code());
         rb.Push(res.Code());
+        return;
     }
     }
 
 
     ctx.WriteBuffer(*res);
     ctx.WriteBuffer(*res);
@@ -168,14 +174,16 @@ private:
         if (process_id == 0) {
         if (process_id == 0) {
             LOG_ERROR(Service_ARP, "Must have non-zero process ID!");
             LOG_ERROR(Service_ARP, "Must have non-zero process ID!");
             IPC::ResponseBuilder rb{ctx, 2};
             IPC::ResponseBuilder rb{ctx, 2};
-            rb.Push(ERR_PROCESS_ID_ZERO);
+            rb.Push(ERR_INVALID_PROCESS_ID);
+            return;
         }
         }
 
 
         if (issued) {
         if (issued) {
             LOG_ERROR(Service_ARP,
             LOG_ERROR(Service_ARP,
                       "Attempted to issue registrar, but registrar is already issued!");
                       "Attempted to issue registrar, but registrar is already issued!");
             IPC::ResponseBuilder rb{ctx, 2};
             IPC::ResponseBuilder rb{ctx, 2};
-            rb.Push(ERR_ALREADY_ISSUED);
+            rb.Push(ERR_INVALID_ACCESS);
+            return;
         }
         }
 
 
         issue_process_id(process_id, launch, std::move(control));
         issue_process_id(process_id, launch, std::move(control));
@@ -193,7 +201,8 @@ private:
                 Service_ARP,
                 Service_ARP,
                 "Attempted to set application launch property, but registrar is already issued!");
                 "Attempted to set application launch property, but registrar is already issued!");
             IPC::ResponseBuilder rb{ctx, 2};
             IPC::ResponseBuilder rb{ctx, 2};
-            rb.Push(ERR_ALREADY_ISSUED);
+            rb.Push(ERR_INVALID_ACCESS);
+            return;
         }
         }
 
 
         IPC::RequestParser rp{ctx};
         IPC::RequestParser rp{ctx};
@@ -211,7 +220,8 @@ private:
                 Service_ARP,
                 Service_ARP,
                 "Attempted to set application control property, but registrar is already issued!");
                 "Attempted to set application control property, but registrar is already issued!");
             IPC::ResponseBuilder rb{ctx, 2};
             IPC::ResponseBuilder rb{ctx, 2};
-            rb.Push(ERR_ALREADY_ISSUED);
+            rb.Push(ERR_INVALID_ACCESS);
+            return;
         }
         }
 
 
         control = ctx.ReadBuffer();
         control = ctx.ReadBuffer();
@@ -247,7 +257,7 @@ void ARP_W::AcquireRegistrar(Kernel::HLERequestContext& ctx) {
         [this](u64 process_id, ApplicationLaunchProperty launch, std::vector<u8> control) {
         [this](u64 process_id, ApplicationLaunchProperty launch, std::vector<u8> control) {
             const auto res = GetTitleIDForProcessID(system, process_id);
             const auto res = GetTitleIDForProcessID(system, process_id);
             if (!res.has_value()) {
             if (!res.has_value()) {
-                return ERR_NONEXISTENT;
+                return ERR_NOT_REGISTERED;
             }
             }
 
 
             return manager.Register(*res, launch, std::move(control));
             return manager.Register(*res, launch, std::move(control));
@@ -267,7 +277,8 @@ void ARP_W::DeleteProperties(Kernel::HLERequestContext& ctx) {
     if (process_id == 0) {
     if (process_id == 0) {
         LOG_ERROR(Service_ARP, "Must have non-zero process ID!");
         LOG_ERROR(Service_ARP, "Must have non-zero process ID!");
         IPC::ResponseBuilder rb{ctx, 2};
         IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(ERR_PROCESS_ID_ZERO);
+        rb.Push(ERR_INVALID_PROCESS_ID);
+        return;
     }
     }
 
 
     const auto title_id = GetTitleIDForProcessID(system, process_id);
     const auto title_id = GetTitleIDForProcessID(system, process_id);
@@ -275,7 +286,8 @@ void ARP_W::DeleteProperties(Kernel::HLERequestContext& ctx) {
     if (!title_id.has_value()) {
     if (!title_id.has_value()) {
         LOG_ERROR(Service_ARP, "No title ID for process ID!");
         LOG_ERROR(Service_ARP, "No title ID for process ID!");
         IPC::ResponseBuilder rb{ctx, 2};
         IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(ERR_NONEXISTENT);
+        rb.Push(ERR_NOT_REGISTERED);
+        return;
     }
     }
 
 
     IPC::ResponseBuilder rb{ctx, 2};
     IPC::ResponseBuilder rb{ctx, 2};

+ 4 - 5
src/core/hle/service/glue/errors.h

@@ -8,10 +8,9 @@
 
 
 namespace Service::Glue {
 namespace Service::Glue {
 
 
-constexpr ResultCode ERR_OUTPUT_TOO_SMALL{0x3C9D};
-constexpr ResultCode ERR_PROCESS_ID_ZERO{0x3E9D};
-constexpr ResultCode ERR_TITLE_ID_ZERO{0x3E9D};
-constexpr ResultCode ERR_ALREADY_ISSUED{0x549D};
-constexpr ResultCode ERR_NONEXISTENT{0xCC9D};
+constexpr ResultCode ERR_INVALID_RESOURCE{ErrorModule::ARP, 0x1E};
+constexpr ResultCode ERR_INVALID_PROCESS_ID{ErrorModule::ARP, 0x1F};
+constexpr ResultCode ERR_INVALID_ACCESS{ErrorModule::ARP, 0x2A};
+constexpr ResultCode ERR_NOT_REGISTERED{ErrorModule::ARP, 0x66};
 
 
 } // namespace Service::Glue
 } // namespace Service::Glue

+ 13 - 8
src/core/hle/service/glue/manager.cpp

@@ -7,18 +7,23 @@
 
 
 namespace Service::Glue {
 namespace Service::Glue {
 
 
+struct ARPManager::MapEntry {
+    ApplicationLaunchProperty launch;
+    std::vector<u8> control;
+};
+
 ARPManager::ARPManager() = default;
 ARPManager::ARPManager() = default;
 
 
 ARPManager::~ARPManager() = default;
 ARPManager::~ARPManager() = default;
 
 
 ResultVal<ApplicationLaunchProperty> ARPManager::GetLaunchProperty(u64 title_id) const {
 ResultVal<ApplicationLaunchProperty> ARPManager::GetLaunchProperty(u64 title_id) const {
     if (title_id == 0) {
     if (title_id == 0) {
-        return ERR_TITLE_ID_ZERO;
+        return ERR_INVALID_PROCESS_ID;
     }
     }
 
 
     const auto iter = entries.find(title_id);
     const auto iter = entries.find(title_id);
     if (iter == entries.end()) {
     if (iter == entries.end()) {
-        return ERR_NONEXISTENT;
+        return ERR_NOT_REGISTERED;
     }
     }
 
 
     return MakeResult<ApplicationLaunchProperty>(iter->second.launch);
     return MakeResult<ApplicationLaunchProperty>(iter->second.launch);
@@ -26,12 +31,12 @@ ResultVal<ApplicationLaunchProperty> ARPManager::GetLaunchProperty(u64 title_id)
 
 
 ResultVal<std::vector<u8>> ARPManager::GetControlProperty(u64 title_id) const {
 ResultVal<std::vector<u8>> ARPManager::GetControlProperty(u64 title_id) const {
     if (title_id == 0) {
     if (title_id == 0) {
-        return ERR_TITLE_ID_ZERO;
+        return ERR_INVALID_PROCESS_ID;
     }
     }
 
 
     const auto iter = entries.find(title_id);
     const auto iter = entries.find(title_id);
     if (iter == entries.end()) {
     if (iter == entries.end()) {
-        return ERR_NONEXISTENT;
+        return ERR_NOT_REGISTERED;
     }
     }
 
 
     return MakeResult<std::vector<u8>>(iter->second.control);
     return MakeResult<std::vector<u8>>(iter->second.control);
@@ -40,12 +45,12 @@ ResultVal<std::vector<u8>> ARPManager::GetControlProperty(u64 title_id) const {
 ResultCode ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch,
 ResultCode ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch,
                                 std::vector<u8> control) {
                                 std::vector<u8> control) {
     if (title_id == 0) {
     if (title_id == 0) {
-        return ERR_TITLE_ID_ZERO;
+        return ERR_INVALID_PROCESS_ID;
     }
     }
 
 
     const auto iter = entries.find(title_id);
     const auto iter = entries.find(title_id);
     if (iter != entries.end()) {
     if (iter != entries.end()) {
-        return ERR_ALREADY_ISSUED;
+        return ERR_INVALID_ACCESS;
     }
     }
 
 
     entries.insert_or_assign(title_id, MapEntry{launch, std::move(control)});
     entries.insert_or_assign(title_id, MapEntry{launch, std::move(control)});
@@ -54,12 +59,12 @@ ResultCode ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch,
 
 
 ResultCode ARPManager::Unregister(u64 title_id) {
 ResultCode ARPManager::Unregister(u64 title_id) {
     if (title_id == 0) {
     if (title_id == 0) {
-        return ERR_TITLE_ID_ZERO;
+        return ERR_INVALID_PROCESS_ID;
     }
     }
 
 
     const auto iter = entries.find(title_id);
     const auto iter = entries.find(title_id);
     if (iter == entries.end()) {
     if (iter == entries.end()) {
-        return ERR_NONEXISTENT;
+        return ERR_NOT_REGISTERED;
     }
     }
 
 
     entries.erase(iter);
     entries.erase(iter);

+ 23 - 6
src/core/hle/service/glue/manager.h

@@ -4,6 +4,9 @@
 
 
 #pragma once
 #pragma once
 
 
+#include <map>
+#include <vector>
+#include "common/common_types.h"
 #include "core/file_sys/control_metadata.h"
 #include "core/file_sys/control_metadata.h"
 #include "core/file_sys/romfs_factory.h"
 #include "core/file_sys/romfs_factory.h"
 #include "core/hle/result.h"
 #include "core/hle/result.h"
@@ -15,31 +18,45 @@ struct ApplicationLaunchProperty {
     u32 version;
     u32 version;
     FileSys::StorageId base_game_storage_id;
     FileSys::StorageId base_game_storage_id;
     FileSys::StorageId update_storage_id;
     FileSys::StorageId update_storage_id;
-    INSERT_PADDING_BYTES(0x2);
+    u8 program_index;
+    u8 reserved;
 };
 };
 static_assert(sizeof(ApplicationLaunchProperty) == 0x10,
 static_assert(sizeof(ApplicationLaunchProperty) == 0x10,
               "ApplicationLaunchProperty has incorrect size.");
               "ApplicationLaunchProperty has incorrect size.");
 
 
+// A class to manage state related to the arp:w and arp:r services, specifically the registration
+// and unregistration of launch and control properties.
 class ARPManager {
 class ARPManager {
 public:
 public:
     ARPManager();
     ARPManager();
     ~ARPManager();
     ~ARPManager();
 
 
+    // Returns the ApplicationLaunchProperty corresponding to the provided title ID if it was
+    // previously registered, otherwise ERR_NOT_REGISTERED if it was never registered or
+    // ERR_INVALID_PROCESS_ID if the title ID is 0.
     ResultVal<ApplicationLaunchProperty> GetLaunchProperty(u64 title_id) const;
     ResultVal<ApplicationLaunchProperty> GetLaunchProperty(u64 title_id) const;
+
+    // Returns a vector of the raw bytes of NACP data (necessarily 0x4000 in size) corresponding to
+    // the provided title ID if it was previously registered, otherwise ERR_NOT_REGISTERED if it was
+    // never registered or ERR_INVALID_PROCESS_ID if the title ID is 0.
     ResultVal<std::vector<u8>> GetControlProperty(u64 title_id) const;
     ResultVal<std::vector<u8>> GetControlProperty(u64 title_id) const;
 
 
+    // Adds a new entry to the internal database with the provided parameters, returning
+    // ERR_INVALID_ACCESS if attempting to re-register a title ID without an intermediate Unregister
+    // step, and ERR_INVALID_PROCESS_ID if the title ID is 0.
     ResultCode Register(u64 title_id, ApplicationLaunchProperty launch, std::vector<u8> control);
     ResultCode Register(u64 title_id, ApplicationLaunchProperty launch, std::vector<u8> control);
 
 
+    // Removes the registration for the provided title ID from the database, returning
+    // ERR_NOT_REGISTERED if it doesn't exist in the database and ERR_INVALID_PROCESS_ID if the
+    // title ID is 0.
     ResultCode Unregister(u64 title_id);
     ResultCode Unregister(u64 title_id);
 
 
+    // Removes all entries from the database, always succeeds. Should only be used when resetting
+    // system state.
     void ResetAll();
     void ResetAll();
 
 
 private:
 private:
-    struct MapEntry {
-        ApplicationLaunchProperty launch;
-        std::vector<u8> control;
-    };
-
+    struct MapEntry;
     std::map<u64, MapEntry> entries;
     std::map<u64, MapEntry> entries;
 };
 };