using System.IO; namespace FirmwareFlasher; public static class FirmwareCatalog { // 모델 무관하게 보조 파일명은 공통 — 앱 후보 = 이 4개를 뺀 .bin static readonly HashSet Support = new(StringComparer.OrdinalIgnoreCase) { "bootloader.bin", "partition-table.bin", "ota_data_initial.bin", "www_fs.bin" }; static string? KnownNote(string fileName) => fileName switch { "DIBD720Te_08C_04R020C.bin" => "320×64 (4단20열, 8색) · 부팅 검증됨", "DIBD720Ue_08B_08R040C.bin" => "640×128 (8단40열, 256색) · 미검증", _ => null, }; /// 폴더의 앱 후보(.bin 중 보조 4종 제외)를 나열. public static List LoadApps(string folder) { var apps = new List(); if (!Directory.Exists(folder)) return apps; foreach (var path in Directory.EnumerateFiles(folder, "*.bin")) { var name = Path.GetFileName(path); if (Support.Contains(name)) continue; apps.Add(new FirmwareItem { FileName = name, FullPath = path, Size = SafeLen(path), Note = KnownNote(name), }); } apps.Sort((a, b) => string.Compare(a.FileName, b.FileName, StringComparison.OrdinalIgnoreCase)); return apps; } /// 선택한 모드+프로파일에 필요한 보조 파일이 폴더에 다 있는지. 없으면 빠진 목록. public static string? MissingFor(string folder, FlashProfile p, FlashMode mode) { if (mode == FlashMode.AppOnly) return null; bool includeBoot = mode == FlashMode.Full; var miss = new List(); foreach (var rg in p.SupportRegions) { if (rg.Kind == "bootloader" && !includeBoot) continue; if (!File.Exists(Path.Combine(folder, rg.File!))) miss.Add(rg.File!); } return miss.Count == 0 ? null : string.Join(", ", miss); } /// exe 위치에서 위로 올라가며 firmware\ (bin 포함) 폴더를 찾는다. public static string? AutoLocate(string startDir) { var dir = new DirectoryInfo(startDir); for (int i = 0; i < 6 && dir is not null; i++) { var candidate = Path.Combine(dir.FullName, "firmware"); if (Directory.Exists(candidate) && Directory.EnumerateFiles(candidate, "*.bin").Any()) return candidate; dir = dir.Parent; } return null; } static long SafeLen(string p) { try { return new FileInfo(p).Length; } catch { return 0; } } }