[gnome-games] retro: Check presence of mandatory firmwares



commit 56156e57a4d8b105c3193dfd4d56f4405debcd62
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Thu Feb 16 15:09:10 2017 +0100

    retro: Check presence of mandatory firmwares
    
    Checks whether the mandatory firmwares for a given platform are present
    and check if they match the expected chcksums and doesn't run the game
    otherwise.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=778744

 src/retro/retro-core-source.vala |   52 +++++++++++++++++++++++++++++++++----
 src/retro/retro-error.vala       |    1 +
 src/retro/retro-runner.vala      |    6 ++++
 3 files changed, 53 insertions(+), 6 deletions(-)
---
diff --git a/src/retro/retro-core-source.vala b/src/retro/retro-core-source.vala
index c9a6e48..7db5080 100644
--- a/src/retro/retro-core-source.vala
+++ b/src/retro/retro-core-source.vala
@@ -4,13 +4,12 @@ public class Games.RetroCoreSource : Object {
        private string platform;
        private string[] mime_types;
 
-       private string module_path;
+       private Retro.CoreDescriptor core_descriptor;
        private bool searched;
 
        public RetroCoreSource (string platform, string[] mime_types) {
                this.platform = platform;
                this.mime_types = mime_types;
-               module_path = null;
                searched = false;
        }
 
@@ -21,7 +20,9 @@ public class Games.RetroCoreSource : Object {
        public string get_module_path () throws Error {
                ensure_module_is_found ();
 
-               return module_path;
+               var module_file = core_descriptor.get_module_file ();
+
+               return module_file.get_path ();
        }
 
        private void ensure_module_is_found () throws Error {
@@ -30,8 +31,12 @@ public class Games.RetroCoreSource : Object {
                        search_module ();
                }
 
-               if (module_path == null)
+               if (core_descriptor == null)
                        throw new RetroError.MODULE_NOT_FOUND (_("No module found for platform '%s' and MIME 
types [ '%s' ]."), platform, string.joinv ("', '", mime_types));
+
+               if (core_descriptor.has_firmwares (platform))
+                       foreach (var firmware in core_descriptor.get_firmwares (platform))
+                               check_firmware_is_valid (firmware);
        }
 
        private void search_module () throws Error {
@@ -51,8 +56,7 @@ public class Games.RetroCoreSource : Object {
                                if (!(mime_type in supported_mime_types))
                                        return false;
 
-                       var module_file = core_descriptor.get_module_file ();
-                       module_path = module_file.get_path ();
+                       this.core_descriptor = core_descriptor;
 
                        return true;
                }
@@ -62,4 +66,40 @@ public class Games.RetroCoreSource : Object {
                        return false;
                }
        }
+
+       private void check_firmware_is_valid (string firmware) throws Error {
+               if (!core_descriptor.get_is_firmware_mandatory (firmware))
+                       return;
+
+               var platforms_dir = Application.get_platforms_dir ();
+               var firmware_dir = File.new_for_path (@"$platforms_dir/$platform/system");
+               var firmware_path = core_descriptor.get_firmware_path (firmware);
+               var firmware_file = firmware_dir.get_child (firmware_path);
+               if (!firmware_file.query_exists ())
+                       throw new RetroError.FIRMWARE_NOT_FOUND (_("This games requires the %s firmware file 
to run."), firmware_file.get_path ());
+
+               var has_md5 = core_descriptor.has_firmware_md5 (firmware);
+               var has_sha512 = core_descriptor.has_firmware_sha512 (firmware);
+               if (!has_md5 || !has_sha512)
+                       return;
+
+               var stream = firmware_file.read ();
+
+               stream.seek (0, SeekType.END);
+               var size = (size_t) stream.tell ();
+               stream.seek (0, SeekType.SET);
+               var bytes = stream.read_bytes (size);
+
+               if (has_md5) {
+                       var md5 = core_descriptor.get_firmware_md5 (firmware);
+                       if (Checksum.compute_for_bytes (ChecksumType.MD5, bytes) != md5)
+                               throw new RetroError.FIRMWARE_NOT_FOUND (_("This games requires the %s 
firmware file with a MD5 fingerprint of %s to run."), firmware_file.get_path (), md5);
+               }
+
+               if (has_sha512) {
+                       var sha512 = core_descriptor.get_firmware_sha512 (firmware);
+                       if (Checksum.compute_for_bytes (ChecksumType.SHA512, bytes) != sha512)
+                               throw new RetroError.FIRMWARE_NOT_FOUND (_("This games requires the %s 
firmware file with a SHA-512 fingerprint of %s to run."), firmware_file.get_path (), sha512);
+               }
+       }
 }
diff --git a/src/retro/retro-error.vala b/src/retro/retro-error.vala
index cbd5b79..db4665d 100644
--- a/src/retro/retro-error.vala
+++ b/src/retro/retro-error.vala
@@ -5,4 +5,5 @@ private errordomain Games.RetroError {
        INVALID_GAME_FILE,
        COULDNT_WRITE_SNAPSHOT,
        COULDNT_LOAD_SNAPSHOT,
+       FIRMWARE_NOT_FOUND,
 }
diff --git a/src/retro/retro-runner.vala b/src/retro/retro-runner.vala
index b3bf472..a63ae30 100644
--- a/src/retro/retro-runner.vala
+++ b/src/retro/retro-runner.vala
@@ -119,6 +119,12 @@ public class Games.RetroRunner : Object, Runner {
 
                        return false;
                }
+               catch (RetroError.FIRMWARE_NOT_FOUND e) {
+                       debug (e.message);
+                       error_message = get_unsupported_system_message ();
+
+                       return false;
+               }
 
                return true;
        }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]