public static void Stop() { SDService.Stop(); NANDService.Stop(); Started = false; }
private static bool FindEmuMMC(DriveInfo drive) { DirectoryInfo root = drive.RootDirectory; FileInfo emummcIni = root.GetFile("emuMMC/emummc.ini"); if (emummcIni.Exists) { // find the DiskDrive associated with this drive letter VolumeInfo volume = AllVolumes .Where(x => x.Caption == drive.Name).FirstOrDefault(); LogicalDiskInfo logicalDisk = AllLogicalDisks .Where(x => x.DeviceID == volume.DriveLetter).FirstOrDefault(); IEnumerable <PartitionInfo> partitionsFromLogicalDisk = ToDiskPartitions(logicalDisk); if (!partitionsFromLogicalDisk.Any()) { return(false); } DiskInfo disk = AllDisks.Where(x => x.Index == partitionsFromLogicalDisk.First().DiskIndex).FirstOrDefault(); IEnumerable <PartitionInfo> partitions = AllPartitions.Where(x => x.DiskIndex == disk.Index); // parse ini FileIniDataParser parser = new FileIniDataParser(); IniData ini = parser.ReadFile(emummcIni.FullName); ini.SectionKeySeparator = '/'; if (!ini.TryGetKey("emummc/sector", out string sectorStr)) { return(false); } ulong sector = ulong.Parse(sectorStr.Replace("0x", ""), System.Globalization.NumberStyles.HexNumber); PartitionInfo partition = partitions.Where(x => (sector * x.BlockSize) - 0x1000000 /* hekate's 16MB padding to protect the emuMMC */ == x.StartingOffset).FirstOrDefault(); bool usingEmummc = partition != null; if (usingEmummc) { MessageBoxResult r = MessageBox.Show("emuMMC was detected on this SD card. Do you want to open that instead of sysMMC content?", "emuMMC", MessageBoxButton.YesNo); if (r == MessageBoxResult.No) { usingEmummc = false; } } if (usingEmummc) { DeviceStream stream = new DeviceStream(disk.PhysicalName, disk.Length); IStorage diskStorage = new CachedStorage(stream.AsStorage().AsReadOnly(), disk.SectorSize * 100, 4, true); long offset = (long)partition.StartingOffset; offset += 0x1000000; // account for hekate's padding offset += 0x400000; // BOOT0 offset += 0x400000; // BOOT1 NANDService.InsertNAND(diskStorage.Slice(offset, (long)partition.Size), false); } return(usingEmummc); } return(false); }
public static void Start() { if (!Started) { Started = true; FsView = new FSView(); int count = 0; FsView.Ready += (source) => { if (source == TitleSource.SD) { StatusService.SDStatus = StatusService.Status.OK; } else if (source == TitleSource.NAND) { count++; if (count == 2) { StatusService.NANDStatus = StatusService.Status.OK; Update(); count = 0; } return; } Update(); }; SDService.OnSDPluggedIn += (_) => { FsView.LoadFileSystemAsync("Opening SD filesystem...", () => SwitchFs.OpenSdCard(HACGUIKeyset.Keyset, new LocalFileSystem(SDService.SDEffectiveRoot.FullName)), TitleSource.SD, true); StatusService.SDStatus = StatusService.Status.Progress; }; SDService.OnSDRemoved += (drive) => { StatusService.SDStatus = StatusService.Status.Incorrect; FsView.IndexedFilesystems[TitleSource.SD].Clear(); Update(); }; NANDService.OnNANDPluggedIn += () => { FsView.LoadFileSystemAsync("Opening NAND user filesystem...", () => SwitchFs.OpenNandPartition(HACGUIKeyset.Keyset, NANDService.NAND.OpenUserPartition()), TitleSource.NAND, false); FsView.LoadFileSystemAsync("Opening NAND system filesystem...", () => SwitchFs.OpenNandPartition(HACGUIKeyset.Keyset, NANDService.NAND.OpenSystemPartition()), TitleSource.NAND, true); TaskManagerPage.Current.Queue.Submit(new DecryptTicketsTask(Preferences.Current.DefaultConsoleName)); TaskManagerPage.Current.Queue.Submit(new SaveKeysetTask(Preferences.Current.DefaultConsoleName)); // TODO TaskManagerPage.Current.Queue.Submit(new CopyAccountDataTask()); StatusService.NANDStatus = StatusService.Status.Progress; }; NANDService.OnNANDRemoved += () => { StatusService.NANDStatus = StatusService.Status.Incorrect; FsView.IndexedFilesystems[TitleSource.NAND].Clear(); Update(); }; SDService.Start(); NANDService.Start(); } }
public static void Start() { if (!Started) { Started = true; NANDSystemTitleView = new FSView(TitleSource.NAND); NANDUserTitleView = new FSView(TitleSource.NAND); SDTitleView = new FSView(TitleSource.SD); Applications = new Dictionary <ulong, Application>(); Titles = new Dictionary <ulong, Title>(); Saves = new Dictionary <string, SaveDataFileSystem>(); SDService.OnSDPluggedIn += (drive) => { SDTitleView.Ready += (_, __) => { StatusService.SDStatus = StatusService.Status.OK; }; SDTitleView.LoadFileSystemAsync("Opening SD filesystem...", () => SwitchFs.OpenSdCard(HACGUIKeyset.Keyset, new LocalFileSystem(drive.RootDirectory.FullName)), true); Update(); StatusService.SDStatus = StatusService.Status.Progress; }; SDService.OnSDRemoved += (drive) => { StatusService.SDStatus = StatusService.Status.Incorrect; SDTitleView.FS = null; Update(); }; NANDService.OnNANDPluggedIn += () => { void onComplete() { StatusService.NANDStatus = StatusService.Status.OK; Update(); }; int count = 0; NANDSystemTitleView.Ready += (_, __) => { count++; if (count >= 2) { onComplete(); } }; NANDUserTitleView.Ready += (_, __) => { count++; if (count >= 2) { onComplete(); } }; NANDUserTitleView.LoadFileSystemAsync("Opening NAND user filesystem...", () => SwitchFs.OpenNandPartition(HACGUIKeyset.Keyset, NANDService.NAND.OpenUserPartition()), false); NANDSystemTitleView.LoadFileSystemAsync("Opening NAND system filesystem...", () => SwitchFs.OpenNandPartition(HACGUIKeyset.Keyset, NANDService.NAND.OpenSystemPartition()), true); TaskManagerPage.Current.Queue.Submit(new DecryptTicketsTask()); StatusService.NANDStatus = StatusService.Status.Progress; }; NANDService.OnNANDRemoved += () => { StatusService.NANDStatus = StatusService.Status.Incorrect; NANDSystemTitleView.FS = null; NANDUserTitleView.FS = null; Update(); }; SDService.Start(); NANDService.Start(); Update(); } }