private static void IterateDisks() { ManagementObjectCollection disks = GetDisks(); foreach (ManagementObject disk in disks) { if (disk["Model"].ToString() == "Linux UMS disk 0 USB Device") // probably a bad way of filtering? { try { DiskInfo info = CreateDiskInfo(disk); //DiskStream diskStream = new DiskStream(DiskStream.CreateDiskInfo(disk)); impl is shit i guess Stream diskStream = new RandomAccessSectorStream(new SectorStream(new DeviceStream(info.PhysicalName, info.Length), info.SectorSize * 100)); if (InsertNAND(diskStream, true)) { CurrentDisk = info; } } catch (UnauthorizedAccessException) { Console.WriteLine("Cannot direct access drive due to lack of permissions."); } } } }
private static void Refresh() { ManagementObjectCollection disks = GetDisks(); foreach (ManagementObject disk in disks) { if (disk["Model"].ToString() == "Linux UMS disk 0 USB Device") // probably a bad way of filtering? { try { DiskInfo info = CreateDiskInfo(disk); IEnumerable <PartitionInfo> partitions = CreatePartitionInfos(GetPartitions()).Where((p) => info.Index == p.DiskIndex).OrderBy((p) => p.Index); PartitionInfo lastPartition = partitions.Last(); long length = (long)(lastPartition.Size + lastPartition.StartingOffset); long missingLength = (0x747BFFE00 - 0x727800000) + 0x200; // (start of GPT backup - end of USER) + length of GPT backup length += missingLength; IStorage diskStorage = new CachedStorage(new DeviceStream(info.PhysicalName, length).AsStorage().AsReadOnly(), info.SectorSize * 100, 4, true); if (InsertNAND(diskStorage, true)) { CurrentDisk = info; } } catch (UnauthorizedAccessException) { Console.WriteLine("Cannot direct access drive due to lack of permissions."); } } } }
private static DiskInfo CreateDiskInfo(ManagementObject disk) { var info = new DiskInfo { PhysicalName = (string)disk.GetPropertyValue("Name"), Name = (string)disk.GetPropertyValue("Caption"), Model = (string)disk.GetPropertyValue("Model"), //todo Why is Windows returning small sizes? https://stackoverflow.com/questions/15051660 Length = (long)((ulong)disk.GetPropertyValue("Size")), SectorSize = (int)((uint)disk.GetPropertyValue("BytesPerSector")), DisplaySize = Util.GetBytesReadable((long)((ulong)disk.GetPropertyValue("Size"))) }; return(info); }
static NANDService() { Validator = DefaultValidator; // Create event handlers to detect when a device is added or removed CreateWatcher = new ManagementEventWatcher(); WqlEventQuery createQuery = new WqlEventQuery("SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'"); CreateWatcher.EventArrived += new EventArrivedEventHandler((s, e) => { if (NAND == null) // ignore if we already found the Switch { Refresh(); } }); CreateWatcher.Query = createQuery; DeleteWatcher = new ManagementEventWatcher(); WqlEventQuery deleteQuery = new WqlEventQuery("SELECT * FROM __InstanceDeletionEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_USBHub'"); DeleteWatcher.EventArrived += new EventArrivedEventHandler((s, e) => { if (NAND != null) // ignore if we haven't found a Switch yet { if (CurrentDisk != null) { // means the NAND is access over USB, so we need to determine if it ManagementObjectCollection disks = GetDisks(); bool found = false; foreach (ManagementObject disk in disks) // search to see if we can match the DiskInfo with an existing device { DiskInfo info = CreateDiskInfo(disk); if (info.PhysicalName.Equals(CurrentDisk.PhysicalName)) { found = true; break; } } if (!found) { OnNANDRemoved(); } } } }); DeleteWatcher.Query = deleteQuery; }
private static void Refresh() { ManagementObjectCollection disks = GetDisks(); foreach (ManagementObject disk in disks) { if (disk["Model"].ToString() == "Linux UMS disk 0 USB Device") // probably a bad way of filtering? { try { DiskInfo info = CreateDiskInfo(disk); IStorage diskStorage = new CachedStorage(new DeviceStream(info.PhysicalName, info.Length).AsStorage().AsReadOnly(), info.SectorSize * 100, 4, true); if (InsertNAND(diskStorage, true)) { CurrentDisk = info; } } catch (UnauthorizedAccessException) { Console.WriteLine("Cannot direct access drive due to lack of permissions."); } } } }
private static void Refresh() { foreach (DiskInfo info in CreateDiskInfos(GetDisks())) { if (info.Model == "Linux UMS disk 0 USB Device" && info.Partitions > 1) // probably a bad way of filtering? { try { IEnumerable <PartitionInfo> partitions = CreatePartitionInfos(GetPartitions()) .Where((p) => info.Index == p.DiskIndex) .OrderBy((p) => p.Index); if (!partitions.Any()) { continue; // obv the NAND should have *some* partitions } PartitionInfo lastPartition = partitions.Last(); long length = (long)(lastPartition.Size + lastPartition.StartingOffset); // thx windows for ignoring the GPT backup AND reporting the size of the disk incorrectly... long missingLength = (0x747BFFE00 - 0x727800000) + 0x200; // (start of GPT backup - end of USER) + length of GPT backup length += missingLength; DeviceStream stream = new DeviceStream(info.PhysicalName, length); IStorage diskStorage = new CachedStorage(stream.AsStorage().AsReadOnly(), info.SectorSize * 100, 4, true); if (InsertNAND(diskStorage, true)) { CurrentDisk = info; break; } } catch (UnauthorizedAccessException) { MessageBox.Show("Cannot get direct access drive due to lack of permissions.\nReopen HACGUI as administrator to use the plugged in NAND."); } } } }
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); }