// TODO: Add stream opening support /// <inheritdoc/> public ConcurrentDictionary <string, ConcurrentQueue <string> > Scan(Scanner scanner, Stream stream, string file) { // Get the name of the first cabinet file or header string directory = Path.GetDirectoryName(file); string noExtension = Path.GetFileNameWithoutExtension(file); string filenamePattern = Path.Combine(directory, noExtension); filenamePattern = new Regex(@"\d+$").Replace(filenamePattern, string.Empty); bool cabinetHeaderExists = File.Exists(Path.Combine(directory, filenamePattern + "1.hdr")); bool shouldScanCabinet = cabinetHeaderExists ? file.Equals(Path.Combine(directory, filenamePattern + "1.hdr"), StringComparison.OrdinalIgnoreCase) : file.Equals(Path.Combine(directory, filenamePattern + "1.cab"), StringComparison.OrdinalIgnoreCase); // If we have the first file if (shouldScanCabinet) { // If the cab file itself fails try { string tempPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); Directory.CreateDirectory(tempPath); InstallShieldCabinet cabfile = InstallShieldCabinet.Open(file); for (int i = 0; i < cabfile.FileCount; i++) { // If an individual entry fails try { string tempFile = Path.Combine(tempPath, cabfile.FileName(i)); cabfile.FileSave(i, tempFile); } catch { } } // Collect and format all found protections var protections = scanner.GetProtections(tempPath); // If temp directory cleanup fails try { Directory.Delete(tempPath, true); } catch { } // Remove temporary path references Utilities.StripFromKeys(protections, tempPath); return(protections); } catch { } } return(null); }
/// <summary> /// Process a single file path as a cabinet file /// </summary> /// <param name="file">Name of the file to process</param> /// <param name="outputInfo">True to display the cabinet information, false otherwise</param> /// <param name="extract">True to extract the cabinet, false otherwise</param> private static void ProcessCabinetPath(string file, bool outputInfo = true, bool extract = true) { if (!File.Exists(file)) { return; } var cab = InstallShieldCabinet.Open(file); if (outputInfo) { // Component Console.WriteLine($"Component Count: {cab.ComponentCount}"); for (int i = 0; i < cab.ComponentCount; i++) { Console.WriteLine($"\tComponent {i}: {cab.ComponentName(i)}"); } // Directory Console.WriteLine($"Directory Count: {cab.DirectoryCount}"); for (int i = 0; i < cab.DirectoryCount; i++) { Console.WriteLine($"\tDirectory {i}: {cab.DirectoryName(i)}"); } // File Console.WriteLine($"File Count: {cab.FileCount}"); for (int i = 0; i < cab.FileCount; i++) { Console.WriteLine($"\tFile {i}: {cab.FileName(i)}"); } // File Group Console.WriteLine($"File Group Count: {cab.FileGroupCount}"); for (int i = 0; i < cab.FileGroupCount; i++) { Console.WriteLine($"\tFile Group {i}: {cab.FileGroupName(i)}"); } } if (extract) { // Extract string baseDirectory = Path.Combine(Path.GetDirectoryName(Path.GetFullPath(file)), Path.GetFileNameWithoutExtension(file)); if (!Directory.Exists(baseDirectory)) { Directory.CreateDirectory(baseDirectory); } for (int i = 0; i < cab.FileCount; i++) { string filename = new string(cab.FileName(i).Select(c => Path.GetInvalidFileNameChars().Contains(c) ? '_' : c).ToArray()); string directory = cab.DirectoryName(cab.FileDirectory(i)); string newfile = Path.Combine(baseDirectory, directory, filename); if (!Directory.Exists(Path.GetDirectoryName(newfile))) { Directory.CreateDirectory(Path.GetDirectoryName(newfile)); } Console.WriteLine($"Outputting file at index {i} to {newfile}..."); cab.FileSave(i, newfile); } } }