Compare commits

..

15 Commits
1.06 ... 1.07

Author SHA1 Message Date
Matt Nadareski
1e16e952cf Update for 1.07 2018-06-27 10:35:40 -07:00
Matt Nadareski
9f493ae27a One last fix for drive speed finding
DIC can sometimes report that a drive has a 0x speed, causing this automatic finder to fail in those cases
2018-06-27 10:35:29 -07:00
Matt Nadareski
2021230836 Quick fix to account for possibly odd speeds 2018-06-27 00:21:53 -07:00
Matt Nadareski
12ba5702fd Minor updates
This mostly takes care of adding a ton of comments and descriptions. Other minor changes include:
- Removing last remnants of psxt001z
- Capitalizing public variables
- Fixing the build that I stupidly broke
- Ensuring whitespace-named discs are handled
- Simplified DumpEnvironment init
2018-06-26 21:08:26 -07:00
Jacopo Santoni
2cf083eb89 Refactor of dump procedure into smaller components (#76)
* Split type combobox into system combobox and disc type combobox

* corrected indentation for xaml file

* fixed merge with head

* fixed format

* fixed issues for PR, added KnownSystem.CUSTOM

* removed Updater.cs which ended by error in commit

* fixed GetOuptutName() for new drive/system combobox

* created Tasks file\nmoved some methods there, created DumpEnvironment to manage are arguments

* moved additional methods to Tasks to make it more modular

* changed StartDumping flow to avoid returning if extra tools are not found

* moved main dump workflow into Tasks class

* created specific DumpResult class for better error reporting/management

* fixes

* continued refactor
- split EnsureDiscInformation into an additional EnsureCorrectInformationForSystemAndMediaType
- proof of concept of using custom extensions to enum types to give better functionality (and encapsulation)
- changed cmb_MediaType to keep a List<MediaType?> and got rid of Tuple<string, MediaType?>

* restored GetDiscType functionality

* fixed btn_StartStop enabled on EnsureCorrect... error

* fixed whitespace

* fixed indentation

* fixes for PR
2018-06-26 20:18:37 -07:00
Matt Nadareski
c1f22d47dc Remove Redundant Calls and PSX Automation (#75)
* Work with callbacks to increase perf

* Make EDC field for PSX automatic

* Make AntiMod field for PSX automatic

* Make LibCrypt field for PSX automatic

* Remove psxt001z

Now that we have confirmed that DIC outputs the required information for libcrypt, we no longer need the external call to psxt001z to confirm (output was unused anyway)

* We need the subIntention data for LibCrypt

* Let's avoid null for now

* Set default speed in case of error

* Check the layerbreak better

* Remove extraneous header checking

* Add SubIntention field if it exists, always

* Add LibCrypt flag by default for PSX

* SubIntention needs a newline
2018-06-26 10:35:58 -07:00
Matt Nadareski
11287d081d Add system requirements (fixes #72) 2018-06-25 10:18:06 -07:00
Matt Nadareski
8652af5697 Usability Updates (#73)
* Checkpoint

* Add notes

* Rename Validation -> Validators

* Move data to Data folder

* Get current disk type

* Automatically detect disc type

* Comment out WIP code

* Add more prototype

The hope is that having this unhooked prototype code will get either myself or another contributor the right inspiration to get it going properly
2018-06-25 10:00:06 -07:00
Matt Nadareski
69561cb1a0 Bits and Pieces (#70)
* DiscType -> MediaType

* Fix bulk find/replace

* Add OrderedDictionary

* Stage 1 of moving off of Tuples

* Add CHANGELIST.md

* Stage 2 of Tuple removal

* String replacement for output paths

* Stage 3 of Tuple removal

* Slight reordering
2018-06-21 11:46:14 -07:00
Matt Nadareski
d587d2b4b3 Add system and media type to output submission info (#65)
* Add new constants to the template

* Slight reordering

* Add new fields to the output

* Whitespace!

* Minor formatting cleanup

* Add TODO

* Whitepace, 2.0
2018-06-20 22:00:26 -07:00
Matt Nadareski
a19418e46f Remove sg-raw (#64)
* Remove sg-raw from OptionsWindow.xaml.cs

* Remove sg-raw from OptionsWindow.xaml

* Remove sg-raw from Options.cs

* Remove sg-raw from MainWindow.xaml.cs

* Missed the other rows

* Remove sg-raw from App.config
2018-06-20 12:44:39 -07:00
Jacopo Santoni
de22ead07c Enhancement of options management (#63)
* Split type combobox into system combobox and disc type combobox

* corrected indentation for xaml file

* fixed merge with head

* fixed format

* fixed issues for PR, added KnownSystem.CUSTOM

* removed Updater.cs which ended by error in commit

* fixed GetOuptutName() for new drive/system combobox

* added OptionsFrame that will manage all applicaton settings and implemented path browse buttons

* removed old properties code, added Options to manage all the program options, implemented interactions with OptionsWindow

* fixed margins automatically inserted by MSVS

* fixed margins automatically inserted by MSVS

* removed empty method placed by XAML designer

* added closed callback for OptionsWindows, tweaks

* fixed button in toolbar
2018-06-20 12:30:31 -07:00
Matt Nadareski
f777869103 Formats and Types (#58)
* Combine single/dual-layer disc types

* Add silly formats

* Minor tweaks to disc type population

* Make codepath slightly less complex

* Fix null error on dump

* Update strings that looked wrong in output
2018-06-20 11:38:12 -07:00
reignstumble
aec1131271 Update README.md 2018-06-20 12:23:01 -04:00
Jacopo Santoni
308fad3ed2 Separated of System and Disc Type (#56)
* Split type combobox into system combobox and disc type combobox

* corrected indentation for xaml file

* fixed merge with head

* fixed format

* fixed issues for PR, added KnownSystem.CUSTOM

* removed Updater.cs which ended by error in commit

* fixed GetOuptutName() for new drive/system combobox
2018-06-18 12:43:07 -07:00
18 changed files with 2106 additions and 1141 deletions

View File

@@ -2,9 +2,7 @@
<configuration>
<appSettings>
<add key="dicPath" value="Programs\DiscImageCreator.exe"/>
<add key="psxt001zPath" value="psxt001z.exe"/>
<add key="sgRawPath" value="sg_raw.exe"/>
<add key="subdumpPath" value="subdump.exe"/>
<add key="defaultOutputPath" value="ISO"/>
</appSettings>
</configuration>
</configuration>

72
CHANGELIST.md Normal file
View File

@@ -0,0 +1,72 @@
### 1.07 (2018-06-27)
- Separated system and media type for easier navigation
- Combined instances of single- and dual-layer discs
- Removed reliance on **sg-raw** and **psxt001z**
- Added system and disc type to the submission info
- First attempt at getting current disc type
- Made the three PSX-specific fields (**EDC**, **Anti-modchip**, and **LibCrypt**) automatically filled in, when possible
- Many, many, many behind the scenes updates for speed, future features, and stability
### 1.06 (2018-06-15)
- Fixed not being able to use the `/c2` flag properly
- Fixed times when the ability to start dumping was improperly allowed
- Added full support for XBOX and XBOX360 (XDG1, XDG2) dumping through DIC (using a Kreon, or presumably a 0800)
### 1.05a (2018-06-14)
- Fixed some ordering and nullability issues
- Added automatic fields for PS1, PS2, Saturn
### 1.05 (2018-06-14)
- Miscellaneous fixes around custom parameter validation, dump information accuracy, settings window, and TODO cleanup
- Add many more supported platforms, mostly arcade (based on publicly available information)
- Add floppy disk dumping support
- Add optional disc eject on completion
- Add subdump for Sega Saturn
- Fully support newest version of DIC including all new flags and commands
- PlayStation and Saturn discs still don't have all internal information automatically generated
### 1.04b (2018-06-13)
- Added subIntention reading
- Fixed extra extensions being appended
- Fixed internationalization error (number formatting)
- Fixed "Custom Input" not working
### 1.04a (2018-06-13)
- Fixed issue with empty trays
- Added settings dialog
### 1.04 (2018-06-13)
- Behind-the-scenes fixes and formatting
- Better checks for external programs
- Automatically changing disc information
- Custom parameters (and parameter validation)
- Automatic drive speed selection
- Automatic submission information creation
- Add ability to stop a dump from the UI
### 1.03 (2018-06-08)
- edccchk now run on all CD-Roms
- Discs unsupported by Windows are now regonized
- Extra \ when accepting default save has been removed.
### 1.02b (2018-05-18)
- Added missing DLL
### 1.02 (2018-05-18)
- Fixed XBOX One and PS4 Drive Speed issue.
- Started implementing DiscImageCreator Path selection.
- Conforming my naming for objects and variable
### 1.01d (2018-05-18)
-Combine IBM PC-CD options, misc fixes.

View File

@@ -39,6 +39,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -90,10 +91,17 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Constants.cs" />
<Compile Include="Data\Constants.cs" />
<Compile Include="External\OrderedDictionary.cs" />
<Compile Include="External\IOrderedDictionary.cs" />
<Compile Include="Options.cs" />
<Compile Include="Tasks.cs" />
<Compile Include="Utilities\DumpInformation.cs" />
<Compile Include="Utilities\Validation.cs" />
<Compile Include="Utilities\Validators.cs" />
<Compile Include="Utilities\Converters.cs" />
<Compile Include="OptionsWindow.xaml.cs">
<DependentUpon>OptionsWindow.xaml</DependentUpon>
</Compile>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@@ -102,11 +110,15 @@
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Enumerations.cs" />
<Compile Include="Data\Enumerations.cs" />
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Page Include="OptionsWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
@@ -131,5 +143,25 @@
<ItemGroup>
<Resource Include="Icon.ico" />
</ItemGroup>
<ItemGroup>
<COMReference Include="IMAPI2">
<Guid>{2735412F-7F64-5B0F-8F00-5D77AFBE261E}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
<COMReference Include="IMAPI2FS">
<Guid>{2C941FD0-975B-59BE-A960-9A2A262853A5}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -1,4 +1,4 @@
namespace DICUI
namespace DICUI.Data
{
/// <summary>
/// Text for UI elements
@@ -7,6 +7,7 @@
{
public const string StartDumping = "Start Dumping";
public const string StopDumping = "Stop Dumping";
public const string FloppyDriveString = "<<FLOPPY>>";
}
/// <summary>
@@ -72,6 +73,8 @@
public const string TitleField = "Title";
public const string DiscNumberField = "Disc Number / Letter";
public const string DiscTitleField = "Disc Title";
public const string SystemField = "System";
public const string MediaTypeField = "Media Type";
public const string CategoryField = "Category";
public const string RegionField = "Region";
public const string LanguagesField = "Languages";
@@ -95,13 +98,13 @@
public const string DATField = "DAT";
public const string ErrorCountField = "Error Count";
public const string CuesheetField = "Cuesheet";
public const string SubIntentionField = "SubIntention (SecuROM)";
public const string WriteOffsetField = "WriteOffset";
public const string SubIntentionField = "SubIntention Data (SecuROM/LibCrypt)";
public const string WriteOffsetField = "Write Offset";
public const string LayerbreakField = "Layerbreak";
public const string PlaystationEXEDateField = "EXE Date";
public const string PlayStationEDCField = "EDC"; // TODO: Not automatic yet
public const string PlayStationAntiModchipField = "Anti-modchip"; // TODO: Not automatic yet
public const string PlayStationLibCryptField = "LibCrypt"; // TODO: Not automatic yet
public const string PlayStationEDCField = "EDC";
public const string PlayStationAntiModchipField = "Anti-modchip";
public const string PlayStationLibCryptField = "LibCrypt";
public const string SaturnHeaderField = "Header";
public const string SaturnBuildDateField = "Build Date";
public const string XBOXDMIHash = "DMI.bin Hashes";

View File

@@ -1,29 +1,5 @@
namespace DICUI
namespace DICUI.Data
{
/// <summary>
/// Known disc types
/// </summary>
public enum DiscType
{
NONE = 0,
CD,
DVD5,
DVD9,
GDROM,
HDDVD,
BD25,
BD50,
// Special Formats
GameCubeGameDisc,
WiiOpticalDisc,
WiiUOpticalDisc,
UMD,
// Keeping this separate since it's currently unsupported in the UI
Floppy = 99,
}
/// <summary>
/// Known systems
/// </summary>
@@ -142,6 +118,7 @@
BDVideo,
DVDVideo,
EnhancedCD,
HDDVDVideo,
PalmOS,
PhilipsCDiDigitalVideo,
PhotoCD,
@@ -151,5 +128,34 @@
VideoCD,
#endregion
Custom = -1
}
/// <summary>
/// Known media types
/// </summary>
public enum MediaType
{
// Generic Optical Formats
NONE = 0,
CD,
DVD,
GDROM,
HDDVD,
BluRay,
LaserDisc,
// Special Optical Formats
GameCubeGameDisc,
WiiOpticalDisc,
WiiUOpticalDisc,
UMD,
// Non-Optical Formats
Floppy,
Cartridge,
Cassette,
CED,
}
}

10
External/IOrderedDictionary.cs vendored Normal file
View File

@@ -0,0 +1,10 @@
using System.Collections.Generic;
using System.Collections.Specialized;
namespace DICUI.External
{
// Adapted from https://www.codeproject.com/Articles/18615/OrderedDictionary-T-A-generic-implementation-of-IO
public interface IOrderedDictionary<TKey, TValue> : IOrderedDictionary, IDictionary<TKey, TValue>
{
}
}

326
External/OrderedDictionary.cs vendored Normal file
View File

@@ -0,0 +1,326 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
namespace DICUI.External
{
// Adapted from https://www.codeproject.com/Articles/18615/OrderedDictionary-T-A-generic-implementation-of-IO
public class OrderedDictionary<TKey, TValue> : IOrderedDictionary<TKey, TValue>
{
private List<KeyValuePair<TKey, TValue>> _list;
private Dictionary<TKey, TValue> _dictionary;
#region Interface properties
public int Count { get; }
int ICollection.Count => Count;
int ICollection<KeyValuePair<TKey, TValue>>.Count => Count;
ICollection IDictionary.Keys => _dictionary.Keys;
ICollection<TKey> IDictionary<TKey, TValue>.Keys => _dictionary.Keys;
ICollection IDictionary.Values => _dictionary.Values;
ICollection<TValue> IDictionary<TKey, TValue>.Values => _dictionary.Values;
bool IDictionary.IsReadOnly => false;
bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly => false;
bool IDictionary.IsFixedSize => false;
object ICollection.SyncRoot => new object();
bool ICollection.IsSynchronized => true;
public TValue this[int index]
{
get
{
return _list[index].Value;
}
set
{
if (index >= Count || index < 0)
throw new ArgumentOutOfRangeException("index",
"'index' must be non-negative and less than" +
" the size of the collection");
TKey key = _list[index].Key;
_list[index] = new KeyValuePair<TKey, TValue>(key, value);
_dictionary[key] = value;
}
}
object IOrderedDictionary.this[int index]
{
get
{
return _list[index].Value;
}
set
{
if (index >= Count || index < 0)
throw new ArgumentOutOfRangeException("index",
"'index' must be non-negative and less than" +
" the size of the collection");
var valueObj = (TValue)value;
if (valueObj == null)
throw new ArgumentException($"Value must be of type {typeof(TValue)}");
TKey key = _list[index].Key;
_list[index] = new KeyValuePair<TKey, TValue>(key, valueObj);
_dictionary[key] = valueObj;
}
}
object IDictionary.this[object key]
{
get
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
return _dictionary[keyObj];
}
set
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
var valueObj = (TValue)value;
if (valueObj == null)
throw new ArgumentException($"Value must be of type {typeof(TValue)}");
if (_dictionary.ContainsKey(keyObj))
{
_dictionary[keyObj] = valueObj;
_list[IndexOfKey(keyObj)] = new KeyValuePair<TKey, TValue>(keyObj, valueObj);
}
else
{
Add(keyObj, valueObj);
}
}
}
TValue IDictionary<TKey, TValue>.this[TKey key]
{
get
{
return _dictionary[key];
}
set
{
if (_dictionary.ContainsKey(key))
{
_dictionary[key] = value;
_list[IndexOfKey(key)] = new KeyValuePair<TKey, TValue>(key, value);
}
else
{
Add(key, value);
}
}
}
#endregion
public OrderedDictionary()
{
_list = new List<KeyValuePair<TKey, TValue>>();
_dictionary = new Dictionary<TKey, TValue>();
Count = 0;
}
public int Add(TKey key, TValue value)
{
_dictionary.Add(key, value);
_list.Add(new KeyValuePair<TKey, TValue>(key, value));
return Count - 1;
}
public void Insert(int index, TKey key, TValue value)
{
if (index > Count || index < 0)
throw new ArgumentOutOfRangeException("index");
_dictionary.Add(key, value);
_list.Insert(index, new KeyValuePair<TKey, TValue>(key, value));
}
void IOrderedDictionary.RemoveAt(int index)
{
if (index >= Count || index < 0)
throw new ArgumentOutOfRangeException("index",
"'index' must be non-negative and less than " +
"the size of the collection");
TKey key = _list[index].Key;
_list.RemoveAt(index);
_dictionary.Remove(key);
}
public bool Remove(TKey key)
{
if (null == key)
throw new ArgumentNullException("key");
int index = IndexOfKey(key);
if (index >= 0)
{
if (_dictionary.Remove(key))
{
_list.RemoveAt(index);
return true;
}
}
return false;
}
public bool ContainsKey(TKey key)
{
return _dictionary.ContainsKey(key);
}
private int IndexOfKey(TKey key)
{
return _list.FindIndex(kvp => kvp.Key.Equals(key));
}
#region Interface methods
IDictionaryEnumerator IOrderedDictionary.GetEnumerator()
{
return _dictionary.GetEnumerator();
}
void IOrderedDictionary.Insert(int index, object key, object value)
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
var valueObj = (TValue)value;
if (valueObj == null)
throw new ArgumentException($"Value must be of type {typeof(TValue)}");
Insert(index, keyObj, valueObj);
}
bool IDictionary.Contains(object key)
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
return _dictionary.ContainsKey(keyObj);
}
void IDictionary.Add(object key, object value)
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
var valueObj = (TValue)value;
if (valueObj == null)
throw new ArgumentException($"Value must be of type {typeof(TValue)}");
Add(keyObj, valueObj);
}
void IDictionary.Clear()
{
_dictionary.Clear();
_list.Clear();
}
IDictionaryEnumerator IDictionary.GetEnumerator()
{
return _dictionary.GetEnumerator();
}
void IDictionary.Remove(object key)
{
var keyObj = (TKey)key;
if (keyObj == null)
throw new ArgumentException($"Key must be of type {typeof(TKey)}");
Remove(keyObj);
}
void ICollection.CopyTo(Array array, int index)
{
var arrayObj = array as KeyValuePair<TKey, TValue>[];
if (arrayObj == null)
throw new ArgumentException($"Key must be of type {typeof(KeyValuePair<TKey, TValue>[])}");
_list.CopyTo(arrayObj, index);
}
bool IDictionary<TKey, TValue>.ContainsKey(TKey key)
{
return ContainsKey(key);
}
void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
{
Add(key, value);
}
bool IDictionary<TKey, TValue>.Remove(TKey key)
{
return Remove(key);
}
bool IDictionary<TKey, TValue>.TryGetValue(TKey key, out TValue value)
{
return _dictionary.TryGetValue(key, out value);
}
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
{
Add(item.Key, item.Value);
}
void ICollection<KeyValuePair<TKey, TValue>>.Clear()
{
_dictionary.Clear();
_list.Clear();
}
bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
{
return _list.Contains(item);
}
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
_list.CopyTo(array, arrayIndex);
}
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
{
return Remove(item.Key);
}
IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
{
return _list.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _list.GetEnumerator();
}
#endregion
}
}

View File

@@ -4,9 +4,14 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DICUI"
xmlns:utilities="clr-namespace:DICUI.Utilities"
mc:Ignorable="d"
Title="Disc Image Creator GUI" Height="450" Width="600">
<Window.Resources>
<utilities:EnumDescriptionConverter x:Key="enumConverter" />
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*"/>
@@ -21,7 +26,7 @@
<ToolBarTray Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Height="30" HorizontalAlignment="Stretch" IsLocked="True">
<ToolBar>
<Button x:Name="tbr_Properties" Content="Properties" Command="Properties" Click="tbr_Properties_Click" CommandManager.CanExecute="tbr_Properties_CanExecute"/>
<Button x:Name="tbr_Options" Content="Options" Click="tbr_Options_Click" />
</ToolBar>
</ToolBarTray>
<GroupBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,5,5.2,5.4" HorizontalAlignment="Stretch" Header="Settings"/>
@@ -42,24 +47,31 @@
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center">Disc Type</Label>
<ComboBox x:Name="cmb_DiscType" Grid.Row="0" Grid.Column="1" Height="22" SelectionChanged="cmb_DiscType_SelectionChanged" />
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Content="System/Media Type" />
<ComboBox x:Name="cmb_SystemType" Grid.Row="0" Grid.Column="1" Height="22" Width="250" HorizontalAlignment="left" SelectionChanged="cmb_SystemType_SelectionChanged" />
<ComboBox x:Name="cmb_MediaType" Grid.Row="0" Grid.Column="1" Height="22" Width="140" HorizontalAlignment="right" SelectionChanged="cmb_MediaType_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource enumConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center">Output Filename</Label>
<TextBox x:Name="txt_OutputFilename" Grid.Row="1" Grid.Column="1" Height="22" TextChanged="txt_OutputFilename_TextChanged"/>
<TextBox x:Name="txt_OutputFilename" Grid.Row="1" Grid.Column="1" Height="22" TextChanged="txt_OutputFilename_TextChanged" />
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center">Output Directory</Label>
<TextBox x:Name="txt_OutputDirectory" Grid.Row="2" Grid.Column="1" Height="22" Width="345" HorizontalAlignment="left" TextChanged="txt_OutputDirectory_TextChanged"/>
<TextBox x:Name="txt_OutputDirectory" Grid.Row="2" Grid.Column="1" Height="22" Width="345" HorizontalAlignment="left" TextChanged="txt_OutputDirectory_TextChanged" />
<Button x:Name="btn_OutputDirectoryBrowse" Grid.Row="2" Grid.Column="1" Height="22" Width="50" HorizontalAlignment="Right" Content="Browse" Click="btn_OutputDirectoryBrowse_Click"/>
<Label Grid.Row="3" Grid.Column="0" VerticalAlignment="Center">Drive Letter</Label>
<ComboBox x:Name="cmb_DriveLetter" Grid.Row="3" Grid.Column="1" Height="22" Width="397" HorizontalAlignment="left" SelectionChanged="cmb_DriveLetter_SelectionChanged"/>
<ComboBox x:Name="cmb_DriveLetter" Grid.Row="3" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="left" SelectionChanged="cmb_DriveLetter_SelectionChanged" />
<Label Grid.Row="4" Grid.Column="0" VerticalAlignment="Center">Drive Speed</Label>
<ComboBox x:Name="cmb_DriveSpeed" Grid.Row="4" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="left" SelectionChanged="cmb_DriveSpeed_SelectionChanged"/>
<ComboBox x:Name="cmb_DriveSpeed" Grid.Row="4" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="left" SelectionChanged="cmb_DriveSpeed_SelectionChanged" />
<Label Grid.Row="5" Grid.Column="0" VerticalAlignment="Center">Parameters</Label>
<TextBox x:Name="txt_Parameters" Grid.Row="5" Grid.Column="1" Height="22" Width="397" HorizontalAlignment="left" IsEnabled="False" />
<TextBox x:Name="txt_Parameters" Grid.Row="5" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" IsEnabled="False" />
</Grid>
<Grid Grid.Row="2" Grid.Column="0" Margin="15,19.6,15.2,9.8" Grid.ColumnSpan="2">

File diff suppressed because it is too large Load Diff

50
Options.cs Normal file
View File

@@ -0,0 +1,50 @@
using System;
using System.Configuration;
using System.Reflection;
namespace DICUI
{
public class Options
{
public string defaultOutputPath { get; private set; }
public string dicPath { get; private set; }
public string subdumpPath { get; private set; }
public void Save()
{
Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
//TODO: reflection is used
Array.ForEach(
GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance),
p => {
configFile.AppSettings.Settings.Remove(p.Name);
configFile.AppSettings.Settings.Add(p.Name, p.GetValue(this) as string);
}
);
configFile.Save(ConfigurationSaveMode.Modified);
}
public void Load()
{
//TODO: hardcoded, we should find a better way
dicPath = ConfigurationManager.AppSettings["dicPath"] ?? @"Programs\DiscImageCreator.exe";
subdumpPath = ConfigurationManager.AppSettings["subdumpPath"] ?? "subdump.exe";
defaultOutputPath = ConfigurationManager.AppSettings["defaultOutputPath"] ?? "ISO";
}
//TODO: probably should be generic for non-string options
//TODO: using reflection for Set and Get is orthodox but it works, should be changed to a key,value map probably
public void Set(string key, string value)
{
GetType().GetProperty(key, BindingFlags.Public | BindingFlags.Instance).SetValue(this, value);
}
public string Get(string key)
{
return GetType().GetProperty(key, BindingFlags.Public | BindingFlags.Instance).GetValue(this) as string;
}
}
}

59
OptionsWindow.xaml Normal file
View File

@@ -0,0 +1,59 @@
<Window x:Class="DICUI.OptionsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DICUI"
mc:Ignorable="d"
Title="Options" Height="260" Width="515.132">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<GroupBox Grid.Column="0" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Paths">
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2.0*" />
<ColumnDefinition Width="0.2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="DicImageCreator Path:" FontWeight="Bold"/>
<TextBox x:Name="txt_dicPath" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="btn_dicPath" Grid.Row="0" Grid.Column="2" Height="22" Width="22" Content="..." Click="btn_BrowseForPath_Click" />
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="subdump Path:" FontWeight="Bold"/>
<TextBox x:Name="txt_subdumpPath" Grid.Row="1" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="btn_subdumpPath" Grid.Row="1" Grid.Column="2" Height="22" Width="22" Content="..." Click="btn_BrowseForPath_Click"/>
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Default Output Path:" FontWeight="Bold"/>
<TextBox x:Name="txt_defaultOutputPath" Grid.Row="2" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="btn_defaultOutputPath" Grid.Row="2" Grid.Column="2" Height="22" Width="22" Content="..." Click="btn_BrowseForPath_Click" />
</Grid>
</GroupBox>
<Grid Height="22" Grid.Row="1" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Button x:Name="btn_Accept" Grid.Row="0" Grid.Column="1" Height="22" Width="80" Content="Accept" Click="btn_Accept_Click" />
<Button x:Name="btn_Cancel" Grid.Row="0" Grid.Column="2" Height="22" Width="80" Content="Cancel" Click="btn_Cancel_Click" />
</Grid>
</Grid>
</Window>

115
OptionsWindow.xaml.cs Normal file
View File

@@ -0,0 +1,115 @@
using System;
using System.IO;
using System.Windows;
using System.Windows.Forms;
using Button = System.Windows.Controls.Button;
using TextBox = System.Windows.Controls.TextBox;
namespace DICUI
{
/// <summary>
/// Interaction logic for OptionsWindow.xaml
/// </summary>
public partial class OptionsWindow : Window
{
private readonly Options _options;
public OptionsWindow(Options options)
{
InitializeComponent();
_options = options;
}
private OpenFileDialog CreateOpenFileDialog()
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.InitialDirectory = System.AppDomain.CurrentDomain.BaseDirectory;
dialog.Filter = "Executables (*.exe)|*.exe";
dialog.FilterIndex = 0;
dialog.RestoreDirectory = true;
return dialog;
}
private FolderBrowserDialog CreateFolderBrowserDialog()
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
return dialog;
}
private string[] PathSettings()
{
string[] pathSettings = { "defaultOutputPath", "dicPath", "subdumpPath" };
return pathSettings;
}
private TextBox TextBoxForPathSetting(string name)
{
return FindName("txt_" + name) as TextBox;
}
private void btn_BrowseForPath_Click(object sender, EventArgs e)
{
Button button = sender as Button;
// strips button prefix to obtain the setting name
string pathSettingName = button.Name.Substring("btn_".Length);
// TODO: hack for now, then we'll see
bool shouldBrowseForPath = pathSettingName == "defaultOutputPath";
CommonDialog dialog = shouldBrowseForPath ? (CommonDialog)CreateFolderBrowserDialog() : CreateOpenFileDialog();
using (dialog)
{
DialogResult result = dialog.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
string path;
bool exists;
if (shouldBrowseForPath)
{
path = (dialog as FolderBrowserDialog).SelectedPath;
exists = Directory.Exists(path);
}
else
{
path = (dialog as OpenFileDialog).FileName;
exists = File.Exists(path);
}
if (exists)
TextBoxForPathSetting(pathSettingName).Text = path;
else
{
System.Windows.MessageBox.Show(
"Specified path doesn't exists!",
"Error",
MessageBoxButton.OK,
MessageBoxImage.Error
);
}
}
}
}
private void btn_Accept_Click(object sender, EventArgs e)
{
Array.ForEach(PathSettings(), setting => _options.Set(setting, TextBoxForPathSetting(setting).Text));
_options.Save();
Hide();
}
private void btn_Cancel_Click(object sender, EventArgs e)
{
// just hide the window and don't care
Hide();
}
public void Refresh()
{
Array.ForEach(PathSettings(), setting => TextBoxForPathSetting(setting).Text = _options.Get(setting));
}
}
}

111
README.md
View File

@@ -1,112 +1,41 @@
# DICUI
This is my current progress on my C# Disc Image Creator UI.
I am using Disc Image Creator, created by Sarami, and would like to thanks him for this great software.
DiscImageCreator UI in C#
You can get the latest code and released on his github right here:
https://github.com/saramibreak/DiscImageCreator
This is a community project, so if you have some time and knowledge to give, we'll be glad to add you to the contributor of this project :)
I'm a hobbyist programmer, so this code might not be optimal, feel free to make your recommendation / Pull request.
We are using DiscImageCreator (DIC), created by Sarami, and we would like to thanks him for his great software. The latest release of DIC can be found on [the GitHub page](https://github.com/saramibreak/DiscImageCreator)
I would like this project to be a community project, so if you have some time and knowledge to give, I'll be glad to add you to the contributor of this project :)
## System Requirements
--------------------------------------------------------------------------
Currently working on the project:
ReignStumble - Co-Lead Programmer
Even though this is written in C#, this program can only be used on Windows systems due to the base program, DiscImageCreator, being Windows-only.
darksabre76 - Co-Lead Programmer
- Windows 7 (newest version of Windows recommended)
- .NET Framework 4.6.1 Runtimes
- 128 MB of free RAM
- As much hard drive space as amount of discs you will be dumping (20+ GB recommended)
NHellFire - Contributer
Ensure that your operating system is as up-to-date as possible, since some features may rely on those updates.
Dizzzy - Concept/Ideas/Beta tester
## Changelist
## Releases
Download the latest release here:
[https://github.com/reignstumble/DICUI/releases](https://github.com/reignstumble/DICUI/releases)
--------------------------------------------------------------------------
2018-06-15
--------------------------------------------------------------------------
## Changelist
Version 1.06 released:
A list of all changes can now be found [here](https://github.com/reignstumble/DICUI/blob/master/CHANGELIST.md).
- Fixed not being able to use the `/c2` flag properly
- Fixed times when the ability to start dumping was improperly allowed
- Added full support for XBOX and XBOX360 (XDG1, XDG2) dumping through DIC (using a Kreon, or presumably a 0800)
## Contributors
--------------------------------------------------------------------------
2018-06-14
--------------------------------------------------------------------------
Here are the talented people who have contributed to the project so far:
Version 1.05a released:
**ReignStumble** - Project Lead / UI Design
- Fixed some ordering and nullability issues
- Added automatic fields for PS1, PS2, Saturn
**darksabre76** - Project Co-Lead / Backend Design
Version 1.05 released:
**Jakz** - Feature Contributor
- Miscellaneous fixes around custom parameter validation, dump information accuracy, settings window, and TODO cleanup
- Add many more supported platforms, mostly arcade (based on publicly available information)
- Add floppy disk dumping support
- Add optional disc eject on completion
- Add subdump for Sega Saturn
- Fully support newest version of DIC including all new flags and commands
**NHellFire** - Feature Contributor
**Known Issues:**
- PlayStation and Saturn discs still don't have all internal information automatically generated
--------------------------------------------------------------------------
2018-06-13
--------------------------------------------------------------------------
Version 1.04b released:
- Added subIntention reading
- Fixed extra extensions being appended
- Fixed internationalization error (number formatting)
- Fixed "Custom Input" not working
Version 1.04a released:
- Fixed issue with empty trays
- Added settings dialog
Version 1.04 released:
- Behind-the-scenes fixes and formatting
- Better checks for external programs
- Automatically changing disc information
- Custom parameters (and parameter validation)
- Automatic drive speed selection
- Automatic submission information creation
- Add ability to stop a dump from the UI
--------------------------------------------------------------------------
2018-06-08
--------------------------------------------------------------------------
Version 1.03 released:
- edccchk now run on all CD-Roms
- Discs unsupported by Windows are now regonized
- Extra \ when accepting default save has been removed.
--------------------------------------------------------------------------
2018-05-18
--------------------------------------------------------------------------
Version 1.02b released:
- Fixed XBOX One and PS4 Drive Speed issue. (1.02)
- Started implementing DiscImageCreator Path selection. (1.02)
- Conforming my naming for objects and variable. (1.02)
- Added missing DLL (1.02b)
--------------------------------------------------------------------------
2018-05-14
--------------------------------------------------------------------------
Version 1.01d released
**Dizzzy** - Concept/Ideas/Beta tester

291
Tasks.cs Normal file
View File

@@ -0,0 +1,291 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI
{
/// <summary>
/// Generic success/failure result object, with optional message
/// </summary>
public class Result
{
private bool success;
public string message { get; private set; }
private Result(bool success, string message)
{
this.success = success;
this.message = message;
}
public static Result Success() => new Result(true, "");
public static Result Success(string message) => new Result(true, message);
public static Result Success(string message, params object[] args) => new Result(true, string.Format(message, args));
public static Result Failure(string message) => new Result(false, message);
public static Result Failure(string message, params object[] args) => new Result(false, string.Format(message, args));
public static implicit operator bool(Result result) => result.success;
}
/// <summary>
/// Represents the state of all settings to be used during dumping
/// </summary>
public class DumpEnvironment
{
// Tool paths
public string DICPath;
public string SubdumpPath;
// Output paths
public string OutputDirectory;
public string OutputFilename;
// UI information
public char DriveLetter;
public KnownSystem? System;
public MediaType? Type;
public bool IsFloppy;
public string DICParameters;
// External process information
public Process dicProcess;
/// <summary>
/// Checks if the configuration is valid
/// </summary>
/// <returns>True if the configuration is valid, false otherwise</returns>
public bool IsConfigurationValid()
{
return !((string.IsNullOrWhiteSpace(DICParameters)
|| !Validators.ValidateParameters(DICParameters)
|| (IsFloppy ^ Type == Data.MediaType.Floppy)));
}
/// <summary>
/// Adjust the current environment if we are given custom parameters
/// </summary>
public void AdjustForCustomConfiguration()
{
// If we have a custom configuration, we need to extract the best possible information from it
if (System == KnownSystem.Custom)
{
Validators.DetermineFlags(DICParameters, out Type, out System, out string letter, out string path);
DriveLetter = letter[0];
OutputDirectory = Path.GetDirectoryName(path);
OutputFilename = Path.GetFileName(path);
}
}
/// <summary>
/// Fix the output paths to remove characters that DiscImageCreator can't handle
/// </summary>
/// <remarks>
/// TODO: Investigate why the `&` replacement is needed
/// </remarks>
public void FixOutputPaths()
{
OutputDirectory = OutputDirectory.Replace('.', '_').Replace('&', '_');
OutputFilename = new StringBuilder(OutputFilename.Replace('&', '_')).Replace('.', '_', 0, OutputFilename.LastIndexOf('.')).ToString();
}
}
/// <summary>
/// Class containing dumping tasks
/// </summary>
public class Tasks
{
/// <summary>
/// Validate the current DumpEnvironment
/// </summary>
/// <param name="env">DumpEnvirionment containing all required information</param>
/// <returns>Result instance with the outcome</returns>
public static Result ValidateEnvironment(DumpEnvironment env)
{
// Validate that everything is good
if (!env.IsConfigurationValid())
return Result.Failure("Error! Current configuration is not supported!");
env.AdjustForCustomConfiguration();
env.FixOutputPaths();
// Validate that the required program exists
if (!File.Exists(env.DICPath))
return Result.Failure("Error! Could not find DiscImageCreator!");
// If a complete dump already exists
if (DumpInformation.FoundAllFiles(env.OutputDirectory, env.OutputFilename, env.Type))
{
MessageBoxResult result = MessageBox.Show("A complete dump already exists! Are you sure you want to overwrite?", "Overwrite?", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
if (result == MessageBoxResult.No || result == MessageBoxResult.Cancel || result == MessageBoxResult.None)
{
return Result.Failure("Dumping aborted!");
}
}
return Result.Success();
}
/// <summary>
/// Run DiscImageCreator with the given DumpEnvironment
/// </summary>
/// <param name="env">DumpEnvirionment containing all required information</param>
public static void ExecuteDiskImageCreator(DumpEnvironment env)
{
env.dicProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = env.DICPath,
Arguments = env.DICParameters,
},
};
env.dicProcess.Start();
env.dicProcess.WaitForExit();
}
/// <summary>
/// Execute subdump for a (potential) Sega Saturn dump
/// </summary>
/// <param name="env">DumpEnvirionment containing all required information</param>
public static async void ExecuteSubdump(DumpEnvironment env)
{
await Task.Run(() =>
{
Process childProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = env.SubdumpPath,
Arguments = "-i " + env.DriveLetter + ": -f " + Path.Combine(env.OutputDirectory, Path.GetFileNameWithoutExtension(env.OutputFilename) + "_subdump.sub") + "-mode 6 -rereadnum 25 -fix 2",
},
};
childProcess.Start();
childProcess.WaitForExit();
});
}
/// <summary>
/// Run any additional tools given a DumpEnvironment
/// </summary>
/// <param name="env">DumpEnvirionment containing all required information</param>
/// <returns>Result instance with the outcome</returns>
public static Result ExecuteAdditionalToolsAfterDIC(DumpEnvironment env)
{
// Special cases
switch (env.System)
{
case KnownSystem.SegaSaturn:
if (!File.Exists(env.SubdumpPath))
return Result.Failure("Error! Could not find subdump!");
ExecuteSubdump(env);
break;
}
return Result.Success();
}
/// <summary>
/// Verify that the current environment has a complete dump and create submission info is possible
/// </summary>
/// <param name="env">DumpEnvirionment containing all required information</param>
/// <returns>Result instance with the outcome</returns>
public static Result VerifyAndSaveDumpOutput(DumpEnvironment env)
{
// Check to make sure that the output had all the correct files
if (!DumpInformation.FoundAllFiles(env.OutputDirectory, env.OutputFilename, env.Type))
return Result.Failure("Error! Please check output directory as dump may be incomplete!");
Dictionary<string, string> templateValues = DumpInformation.ExtractOutputInformation(env.OutputDirectory, env.OutputFilename, env.System, env.Type, env.DriveLetter);
List<string> formattedValues = DumpInformation.FormatOutputData(templateValues, env.System, env.Type);
bool success = DumpInformation.WriteOutputData(env.OutputDirectory, env.OutputFilename, formattedValues);
return Result.Success();
}
/// <summary>
/// Eject the disc using DIC
/// </summary>
public static async void EjectDisc(DumpEnvironment env)
{
// Validate that the required program exists
if (!File.Exists(env.DICPath))
return;
CancelDumping(env);
if (env.IsFloppy)
return;
Process childProcess;
await Task.Run(() =>
{
childProcess = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = env.DICPath,
Arguments = DICCommands.Eject + " " + env.DriveLetter,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true,
},
};
childProcess.Start();
childProcess.WaitForExit();
});
}
/// <summary>
/// Cancel an in-progress dumping process
/// </summary>
public static void CancelDumping(DumpEnvironment env)
{
try
{
if (env.dicProcess != null && !env.dicProcess.HasExited)
env.dicProcess.Kill();
}
catch
{ }
}
/// <summary>
/// This executes the complete dump workflow on a DumpEnvironment
/// </summary>
public static async Task<Result> StartDumping(DumpEnvironment env)
{
Result result = Tasks.ValidateEnvironment(env);
// is something is wrong in environment return
if (!result)
return result;
// execute DIC
await Task.Run(() => Tasks.ExecuteDiskImageCreator(env));
// execute additional tools
result = Tasks.ExecuteAdditionalToolsAfterDIC(env);
// is something is wrong with additional tools report and return
// TODO: don't return, just keep generating output from DIC
/*if (!result.Item1)
{
lbl_Status.Content = result.Item2;
btn_StartStop.Content = UIElements.StartDumping;
return;
}*/
// verify dump output and save it
result = Tasks.VerifyAndSaveDumpOutput(env);
return result;
}
}
}

View File

@@ -1,41 +1,98 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Data;
using IMAPI2;
using DICUI.Data;
namespace DICUI.Utilities
{
/// <summary>
/// Extensions for MediaType? for easier calling
/// </summary>
public static class MediaTypeExtensions
{
public static string Name(this MediaType? type)
{
return Converters.MediaTypeToString(type);
}
public static string Extension(this MediaType? type)
{
return Converters.MediaTypeToExtension(type);
}
public static bool DoesSupportDriveSpeed(this MediaType? type)
{
return type != MediaType.BluRay && type != MediaType.Floppy;
}
}
/// <summary>
/// Extensions for KnownSystem? for easier calling
/// </summary>
public static class KnownSystemExtensions
{
public static bool DoesSupportDriveSpeed(this KnownSystem? system)
{
return system != KnownSystem.MicrosoftXBOX
&& system != KnownSystem.MicrosoftXBOX360XDG2
&& system != KnownSystem.MicrosoftXBOX360XDG3;
}
}
/// <summary>
/// Used to provide a converter to XAML files to render comboboxes with enum values
/// </summary>
public class EnumDescriptionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is MediaType?)
return ((MediaType?)value).Name();
else
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return string.Empty;
}
}
public static class Converters
{
/// <summary>
/// Get the DiscType associated with a given base command
/// Get the MediaType associated with a given base command
/// </summary>
/// <param name="baseCommand">String value to check</param>
/// <returns>DiscType if possible, null on error</returns>
/// <returns>MediaType if possible, null on error</returns>
/// <remarks>This takes the "safe" route by assuming the larger of any given format</remarks>
public static DiscType? BaseCommmandToDiscType(string baseCommand)
public static MediaType? BaseCommmandToMediaType(string baseCommand)
{
switch (baseCommand)
{
case DICCommands.CompactDisc:
return DiscType.CD;
return MediaType.CD;
case DICCommands.GDROM:
case DICCommands.Swap:
return DiscType.GDROM;
return MediaType.GDROM;
case DICCommands.DigitalVideoDisc:
return DiscType.DVD9;
case DICCommands.BluRay:
return DiscType.BD50;
case DICCommands.XBOX:
return DiscType.DVD5;
return MediaType.DVD;
case DICCommands.BluRay:
return MediaType.BluRay;
// Non-optical
case DICCommands.Floppy:
return DiscType.Floppy;
return MediaType.Floppy;
default:
return null;
}
}
/// <summary>
/// Get the most common known system for a given DiscType
/// Get the most common known system for a given MediaType
/// </summary>
/// <param name="baseCommand">String value to check</param>
/// <returns>KnownSystem if possible, null on error</returns>
@@ -59,96 +116,142 @@ namespace DICUI.Utilities
}
}
/// <summary>
/// Convert IMAPI physical media type to a MediaType
/// </summary>
/// <param name="type">IMAPI_MEDIA_PHYSICAL_TYPE value to check</param>
/// <returns>MediaType if possible, null on error</returns>
public static MediaType? IMAPIDiskTypeToMediaType(IMAPI_MEDIA_PHYSICAL_TYPE type)
{
switch (type)
{
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_UNKNOWN:
return MediaType.NONE;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDRW:
return MediaType.CD;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDRAM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSRW:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSR_DUALLAYER:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHRW:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DISK:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSRW_DUALLAYER:
return MediaType.DVD;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDRAM:
return MediaType.HDDVD;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDRE:
return MediaType.BluRay;
default:
return null;
}
}
/// <summary>
/// Get the default extension for a given disc type
/// </summary>
/// <param name="type">DiscType value to check</param>
/// <param name="type">MediaType value to check</param>
/// <returns>Valid extension (with leading '.'), null on error</returns>
public static string DiscTypeToExtension(DiscType? type)
public static string MediaTypeToExtension(MediaType? type)
{
switch (type)
{
case DiscType.CD:
case DiscType.GDROM:
case MediaType.CD:
case MediaType.GDROM:
case MediaType.Cartridge:
return ".bin";
case DiscType.DVD5:
case DiscType.DVD9:
case DiscType.HDDVD:
case DiscType.BD25:
case DiscType.BD50:
case DiscType.WiiOpticalDisc:
case DiscType.UMD:
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.BluRay:
case MediaType.WiiOpticalDisc:
case MediaType.UMD:
return ".iso";
case DiscType.GameCubeGameDisc:
case MediaType.LaserDisc:
case MediaType.GameCubeGameDisc:
return ".raw";
case DiscType.WiiUOpticalDisc:
case MediaType.WiiUOpticalDisc:
return ".wud";
case DiscType.Floppy:
case MediaType.Floppy:
return ".img";
case DiscType.NONE:
case MediaType.Cassette:
return ".wav";
case MediaType.NONE:
case MediaType.CED:
default:
return null;
}
}
/// <summary>
/// Get the string representation of the DiscType enum values
/// Get the string representation of the MediaType enum values
/// </summary>
/// <param name="type">DiscType value to convert</param>
/// <param name="type">MediaType value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string DiscTypeToString(DiscType? type)
public static string MediaTypeToString(MediaType? type)
{
switch (type)
{
case DiscType.CD:
case MediaType.CD:
return "CD-ROM";
case DiscType.DVD5:
return "DVD-5 [Single-Layer]";
case DiscType.DVD9:
return "DVD-9 [Dual-Layer]";
case DiscType.GDROM:
case MediaType.DVD:
return "DVD";
case MediaType.GDROM:
return "GD-ROM";
case DiscType.HDDVD:
case MediaType.HDDVD:
return "HD-DVD";
case DiscType.BD25:
return "BluRay-25 [Single-Layer]";
case DiscType.BD50:
return "BluRay-50 [Dual-Layer]";
case MediaType.BluRay:
return "BluRay";
case MediaType.LaserDisc:
return "LaserDisc";
case DiscType.GameCubeGameDisc:
case MediaType.CED:
return "CED";
case MediaType.GameCubeGameDisc:
return "GameCube Game";
case DiscType.WiiOpticalDisc:
case MediaType.WiiOpticalDisc:
return "Wii Optical";
case DiscType.WiiUOpticalDisc:
case MediaType.WiiUOpticalDisc:
return "Wii U Optical";
case DiscType.UMD:
case MediaType.UMD:
return "UMD";
case DiscType.Floppy:
case MediaType.Cartridge:
return "Cartridge";
case MediaType.Cassette:
return "Cassette Tape";
case MediaType.Floppy:
return "Floppy Disk";
case DiscType.NONE:
case MediaType.NONE:
default:
return "Unknown";
}
}
/// <summary>
/// Get the DIC command to be used for a given DiscType
/// Get the DIC command to be used for a given MediaType
/// </summary>
/// <param name="type">DiscType value to check</param>
/// <param name="type">MediaType value to check</param>
/// <returns>String containing the command, null on error</returns>
public static string KnownSystemAndDiscTypeToBaseCommand(KnownSystem? sys, DiscType? type)
public static string KnownSystemAndMediaTypeToBaseCommand(KnownSystem? sys, MediaType? type)
{
switch (type)
{
case DiscType.CD:
case MediaType.CD:
if (sys == KnownSystem.MicrosoftXBOX)
{
return DICCommands.XBOX;
}
return DICCommands.CompactDisc;
case DiscType.DVD5:
case MediaType.DVD:
if (sys == KnownSystem.MicrosoftXBOX
|| sys == KnownSystem.MicrosoftXBOX360XDG2
|| sys == KnownSystem.MicrosoftXBOX360XDG3)
@@ -156,34 +259,25 @@ namespace DICUI.Utilities
return DICCommands.XBOX;
}
return DICCommands.DigitalVideoDisc;
case DiscType.DVD9:
if (sys == KnownSystem.MicrosoftXBOX
|| sys == KnownSystem.MicrosoftXBOX360XDG2
|| sys == KnownSystem.MicrosoftXBOX360XDG3)
{
return DICCommands.XBOX;
}
return DICCommands.DigitalVideoDisc;
case DiscType.GDROM:
case MediaType.GDROM:
return DICCommands.GDROM;
case DiscType.HDDVD:
case MediaType.HDDVD:
return null;
case DiscType.BD25:
case DiscType.BD50:
case MediaType.BluRay:
return DICCommands.BluRay;
// Special Formats
case DiscType.GameCubeGameDisc:
case MediaType.GameCubeGameDisc:
return DICCommands.DigitalVideoDisc;
case DiscType.WiiOpticalDisc:
case MediaType.WiiOpticalDisc:
return null;
case DiscType.WiiUOpticalDisc:
case MediaType.WiiUOpticalDisc:
return null;
case DiscType.UMD:
case MediaType.UMD:
return null;
// Non-optical
case DiscType.Floppy:
case MediaType.Floppy:
return DICCommands.Floppy;
default:
@@ -195,12 +289,12 @@ namespace DICUI.Utilities
/// Get list of default parameters for a given system and disc type
/// </summary>
/// <param name="sys">KnownSystem value to check</param>
/// <param name="type">DiscType value to check</param>
/// <param name="type">MediaType value to check</param>
/// <returns>List of strings representing the parameters</returns>
public static List<string> KnownSystemAndDiscTypeToParameters(KnownSystem? sys, DiscType? type)
public static List<string> KnownSystemAndMediaTypeToParameters(KnownSystem? sys, MediaType? type)
{
// First check to see if the combination of system and disctype is valid
List<DiscType?> validTypes = Validation.GetValidDiscTypes(sys);
// First check to see if the combination of system and MediaType is valid
var validTypes = Validators.GetValidMediaTypes(sys);
if (!validTypes.Contains(type))
{
return null;
@@ -210,7 +304,7 @@ namespace DICUI.Utilities
List<string> parameters = new List<string>();
switch (type)
{
case DiscType.CD:
case MediaType.CD:
parameters.Add(DICFlags.C2Opcode); parameters.Add("20");
switch (sys)
@@ -226,42 +320,37 @@ namespace DICUI.Utilities
break;
case KnownSystem.SonyPlayStation:
parameters.Add(DICFlags.ScanAntiMod);
parameters.Add(DICFlags.NoFixSubQLibCrypt);
break;
}
break;
case DiscType.DVD5:
case MediaType.DVD:
// Currently no defaults set
break;
case DiscType.DVD9:
// Currently no defaults set
break;
case DiscType.GDROM:
case MediaType.GDROM:
parameters.Add(DICFlags.C2Opcode); parameters.Add("20");
break;
case DiscType.HDDVD:
case MediaType.HDDVD:
break;
case DiscType.BD25:
// Currently no defaults set
break;
case DiscType.BD50:
case MediaType.BluRay:
// Currently no defaults set
break;
// Special Formats
case DiscType.GameCubeGameDisc:
case MediaType.GameCubeGameDisc:
parameters.Add(DICFlags.Raw);
break;
case DiscType.WiiOpticalDisc:
case MediaType.WiiOpticalDisc:
// Currently no defaults set
break;
case DiscType.WiiUOpticalDisc:
case MediaType.WiiUOpticalDisc:
// Currently no defaults set
break;
case DiscType.UMD:
case MediaType.UMD:
break;
// Non-optical
case DiscType.Floppy:
case MediaType.Floppy:
// Currently no defaults set
break;
}
@@ -481,6 +570,8 @@ namespace DICUI.Utilities
return "DVD-Video";
case KnownSystem.EnhancedCD:
return "Enhanced CD";
case KnownSystem.HDDVDVideo:
return "HD-DVD-Video";
case KnownSystem.PalmOS:
return "PalmOS";
case KnownSystem.PhilipsCDiDigitalVideo:
@@ -498,10 +589,13 @@ namespace DICUI.Utilities
#endregion
case KnownSystem.Custom:
return "Custom Input";
case KnownSystem.NONE:
default:
return "Unknown";
}
}
}
}
}

View File

@@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using DICUI.Data;
namespace DICUI.Utilities
{
@@ -52,9 +53,9 @@ namespace DICUI.Utilities
/// </summary>
/// <param name="outputDirectory">Base directory to use</param>
/// <param name="outputFilename">Base filename to use</param>
/// <param name="type">DiscType value to check</param>
/// <param name="type">MediaType value to check</param>
/// <returns></returns>
public static bool FoundAllFiles(string outputDirectory, string outputFilename, DiscType? type)
public static bool FoundAllFiles(string outputDirectory, string outputFilename, MediaType? type)
{
// First, sanitized the output filename to strip off any potential extension
outputFilename = Path.GetFileNameWithoutExtension(outputFilename);
@@ -63,8 +64,8 @@ namespace DICUI.Utilities
string combinedBase = Path.Combine(outputDirectory, outputFilename);
switch (type)
{
case DiscType.CD:
case DiscType.GDROM: // TODO: Verify GD-ROM outputs this
case MediaType.CD:
case MediaType.GDROM: // TODO: Verify GD-ROM outputs this
return File.Exists(combinedBase + ".c2")
&& File.Exists(combinedBase + ".ccd")
&& File.Exists(combinedBase + ".cue")
@@ -85,15 +86,13 @@ namespace DICUI.Utilities
&& File.Exists(combinedBase + "_subIntention.txt")
&& File.Exists(combinedBase + "_subReadable.txt")
&& File.Exists(combinedBase + "_volDesc.txt");
case DiscType.DVD5:
case DiscType.DVD9:
case DiscType.HDDVD:
case DiscType.BD25:
case DiscType.BD50:
case DiscType.GameCubeGameDisc:
case DiscType.WiiOpticalDisc:
case DiscType.WiiUOpticalDisc:
case DiscType.UMD:
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.BluRay:
case MediaType.GameCubeGameDisc:
case MediaType.WiiOpticalDisc:
case MediaType.WiiUOpticalDisc:
case MediaType.UMD:
return File.Exists(combinedBase + ".dat")
&& File.Exists(combinedBase + "_cmd.txt")
&& File.Exists(combinedBase + "_disc.txt")
@@ -101,7 +100,7 @@ namespace DICUI.Utilities
&& File.Exists(combinedBase + "_mainError.txt")
&& File.Exists(combinedBase + "_mainInfo.txt")
&& File.Exists(combinedBase + "_volDesc.txt");
case DiscType.Floppy:
case MediaType.Floppy:
return File.Exists(combinedBase + ".dat")
&& File.Exists(combinedBase + "_cmd.txt")
&& File.Exists(combinedBase + "_disc.txt");
@@ -117,11 +116,11 @@ namespace DICUI.Utilities
/// <param name="outputDirectory">Base directory to use</param>
/// <param name="outputFilename">Base filename to use</param>
/// <param name="sys">KnownSystem value to check</param>
/// <param name="type">DiscType value to check</param>
/// <param name="type">MediaType value to check</param>
/// <param name="driveLetter">Drive letter to check</param>
/// <returns>Dictionary containing mapped output values, null on error</returns>
/// <remarks>TODO: Make sure that all special formats are accounted for</remarks>
public static Dictionary<string, string> ExtractOutputInformation(string outputDirectory, string outputFilename, KnownSystem? sys, DiscType? type, char driveLetter)
public static Dictionary<string, string> ExtractOutputInformation(string outputDirectory, string outputFilename, KnownSystem? sys, MediaType? type, char driveLetter)
{
// First, sanitized the output filename to strip off any potential extension
outputFilename = Path.GetFileNameWithoutExtension(outputFilename);
@@ -139,6 +138,8 @@ namespace DICUI.Utilities
{ Template.TitleField, Template.RequiredValue },
{ Template.DiscNumberField, Template.OptionalValue },
{ Template.DiscTitleField, Template.OptionalValue },
{ Template.SystemField, Converters.KnownSystemToString(sys) },
{ Template.MediaTypeField, Converters.MediaTypeToString(type) },
{ Template.CategoryField, "Games" },
{ Template.RegionField, "World (CHANGE THIS)" },
{ Template.LanguagesField, "Klingon (CHANGE THIS)" },
@@ -151,22 +152,22 @@ namespace DICUI.Utilities
{ Template.DATField, GetDatfile(combinedBase + ".dat") },
};
// Now we want to do a check by DiscType and extract all required info
// Now we want to do a check by MediaType and extract all required info
switch (type)
{
case DiscType.CD:
case DiscType.GDROM: // TODO: Verify GD-ROM outputs this
case MediaType.CD:
case MediaType.GDROM: // TODO: Verify GD-ROM outputs this
mappings[Template.MasteringRingField] = Template.RequiredIfExistsValue;
mappings[Template.MasteringSIDField] = Template.RequiredIfExistsValue;
mappings[Template.MouldSIDField] = Template.RequiredIfExistsValue;
mappings[Template.AdditionalMouldField] = Template.RequiredIfExistsValue;
mappings[Template.ToolstampField] = Template.RequiredIfExistsValue;
mappings[Template.PVDField] = GetPVD(combinedBase + "_mainInfo.txt");
mappings[Template.PVDField] = GetPVD(combinedBase + "_mainInfo.txt") ?? "";
mappings[Template.ErrorCountField] = GetErrorCount(combinedBase + ".img_EdcEcc.txt",
combinedBase + "_c2Error.txt",
combinedBase + "_mainError.txt").ToString();
mappings[Template.CuesheetField] = GetFullFile(combinedBase + ".cue");
mappings[Template.WriteOffsetField] = GetWriteOffset(combinedBase + "_disc.txt");
mappings[Template.CuesheetField] = GetFullFile(combinedBase + ".cue") ?? "";
mappings[Template.WriteOffsetField] = GetWriteOffset(combinedBase + "_disc.txt") ?? "";
// System-specific options
switch (sys)
@@ -180,77 +181,89 @@ namespace DICUI.Utilities
FileInfo fi = new FileInfo(combinedBase + "_subIntention.txt");
if (fi.Length > 0)
{
mappings[Template.SubIntentionField] = GetFullFile(combinedBase + "_subIntention.txt");
mappings[Template.SubIntentionField] = GetFullFile(combinedBase + "_subIntention.txt") ?? "";
}
}
break;
case KnownSystem.SegaSaturn:
mappings[Template.SaturnHeaderField] = GetSaturnHeader(GetFirstTrack(outputDirectory, outputFilename)).ToString();
mappings[Template.SaturnHeaderField] = GetSaturnHeader(GetFirstTrack(outputDirectory, outputFilename)) ?? "";
if (GetSaturnBuildInfo(mappings[Template.SaturnHeaderField], out string serial, out string version, out string buildDate))
{
mappings[Template.DiscSerialField] = serial;
mappings[Template.VersionField] = version;
mappings[Template.SaturnBuildDateField] = buildDate;
mappings[Template.DiscSerialField] = serial ?? "";
mappings[Template.VersionField] = version ?? "";
mappings[Template.SaturnBuildDateField] = buildDate ?? "";
}
break;
case KnownSystem.SonyPlayStation:
mappings[Template.PlaystationEXEDateField] = GetPlayStationEXEDate(driveLetter);
mappings[Template.PlayStationEDCField] = Template.YesNoValue;
mappings[Template.PlayStationAntiModchipField] = Template.YesNoValue;
mappings[Template.PlayStationLibCryptField] = Template.YesNoValue;
break;
case KnownSystem.SonyPlayStation2:
mappings[Template.PlaystationEXEDateField] = GetPlayStationEXEDate(driveLetter);
mappings[Template.VersionField] = GetPlayStation2Version(driveLetter);
break;
}
break;
case DiscType.DVD5:
case DiscType.HDDVD:
case DiscType.BD25:
mappings[Template.MasteringRingField] = Template.RequiredIfExistsValue;
mappings[Template.MasteringSIDField] = Template.RequiredIfExistsValue;
mappings[Template.MouldSIDField] = Template.RequiredIfExistsValue;
mappings[Template.AdditionalMouldField] = Template.RequiredIfExistsValue;
mappings[Template.ToolstampField] = Template.RequiredIfExistsValue;
mappings[Template.PVDField] = GetPVD(combinedBase + "_mainInfo.txt");
// System-specific options
switch (sys)
{
case KnownSystem.AppleMacintosh:
case KnownSystem.IBMPCCompatible:
mappings[Template.ISBNField] = Template.OptionalValue;
mappings[Template.CopyProtectionField] = Template.RequiredIfExistsValue;
mappings[Template.PlaystationEXEDateField] = GetPlayStationEXEDate(driveLetter) ?? "";
mappings[Template.PlayStationEDCField] = GetMissingEDCCount(combinedBase + ".img_eccEdc.txt") > 0 ? "No" : "Yes";
mappings[Template.PlayStationAntiModchipField] = GetAntiModchipDetected(combinedBase + "_disc.txt") ? "Yes" : "No";
mappings[Template.PlayStationLibCryptField] = "No";
if (File.Exists(combinedBase + "_subIntention.txt"))
{
FileInfo fi = new FileInfo(combinedBase + "_subIntention.txt");
if (fi.Length > 0)
{
mappings[Template.SubIntentionField] = GetFullFile(combinedBase + "_subIntention.txt");
mappings[Template.PlayStationLibCryptField] = "Yes";
mappings[Template.SubIntentionField] = GetFullFile(combinedBase + "_subIntention.txt") ?? "";
}
}
break;
case KnownSystem.SonyPlayStation2:
mappings[Template.PlaystationEXEDateField] = GetPlayStationEXEDate(driveLetter);
mappings[Template.VersionField] = GetPlayStation2Version(driveLetter);
mappings[Template.PlaystationEXEDateField] = GetPlayStationEXEDate(driveLetter) ?? "";
mappings[Template.VersionField] = GetPlayStation2Version(driveLetter) ?? "";
break;
}
break;
case DiscType.DVD9:
case DiscType.BD50:
mappings["Outer " + Template.MasteringRingField] = Template.RequiredIfExistsValue;
mappings["Inner " + Template.MasteringRingField] = Template.RequiredIfExistsValue;
mappings["Outer " + Template.MasteringSIDField] = Template.RequiredIfExistsValue;
mappings["Inner " + Template.MasteringSIDField] = Template.RequiredIfExistsValue;
mappings[Template.MouldSIDField] = Template.RequiredIfExistsValue;
mappings[Template.AdditionalMouldField] = Template.RequiredIfExistsValue;
mappings["Outer " + Template.ToolstampField] = Template.RequiredIfExistsValue;
mappings["Inner " + Template.ToolstampField] = Template.RequiredIfExistsValue;
mappings[Template.PVDField] = GetPVD(combinedBase + "_mainInfo.txt");
mappings[Template.LayerbreakField] = GetLayerbreak(combinedBase + "_disc.txt");
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.BluRay:
string layerbreak = GetLayerbreak(combinedBase + "_disc.txt") ?? "";
// If we have a single-layer disc
if (String.IsNullOrWhiteSpace(layerbreak))
{
switch (type)
{
case MediaType.DVD:
mappings[Template.MediaTypeField] += "-5";
break;
case MediaType.BluRay:
mappings[Template.MediaTypeField] += "-25";
break;
}
mappings[Template.MasteringRingField] = Template.RequiredIfExistsValue;
mappings[Template.MasteringSIDField] = Template.RequiredIfExistsValue;
mappings[Template.MouldSIDField] = Template.RequiredIfExistsValue;
mappings[Template.AdditionalMouldField] = Template.RequiredIfExistsValue;
mappings[Template.ToolstampField] = Template.RequiredIfExistsValue;
mappings[Template.PVDField] = GetPVD(combinedBase + "_mainInfo.txt") ?? "";
}
// If we have a dual-layer disc
else
{
switch (type)
{
case MediaType.DVD:
mappings[Template.MediaTypeField] += "-9";
break;
case MediaType.BluRay:
mappings[Template.MediaTypeField] += "-50";
break;
}
mappings["Outer " + Template.MasteringRingField] = Template.RequiredIfExistsValue;
mappings["Inner " + Template.MasteringRingField] = Template.RequiredIfExistsValue;
mappings["Outer " + Template.MasteringSIDField] = Template.RequiredIfExistsValue;
mappings["Inner " + Template.MasteringSIDField] = Template.RequiredIfExistsValue;
mappings[Template.MouldSIDField] = Template.RequiredIfExistsValue;
mappings[Template.AdditionalMouldField] = Template.RequiredIfExistsValue;
mappings["Outer " + Template.ToolstampField] = Template.RequiredIfExistsValue;
mappings["Inner " + Template.ToolstampField] = Template.RequiredIfExistsValue;
mappings[Template.PVDField] = GetPVD(combinedBase + "_mainInfo.txt") ?? "";
mappings[Template.LayerbreakField] = layerbreak;
}
// System-specific options
switch (sys)
@@ -264,7 +277,7 @@ namespace DICUI.Utilities
FileInfo fi = new FileInfo(combinedBase + "_subIntention.txt");
if (fi.Length > 0)
{
mappings[Template.SubIntentionField] = GetFullFile(combinedBase + "_subIntention.txt");
mappings[Template.SubIntentionField] = GetFullFile(combinedBase + "_subIntention.txt") ?? "";
}
}
break;
@@ -273,18 +286,17 @@ namespace DICUI.Utilities
case KnownSystem.MicrosoftXBOX360XDG3:
if (GetXBOXAuxInfo(combinedBase + "_disc.txt", out string dmihash, out string pfihash, out string sshash, out string ss))
{
mappings[Template.XBOXDMIHash] = dmihash;
mappings[Template.XBOXPFIHash] = pfihash;
mappings[Template.XBOXSSHash] = sshash;
mappings[Template.XBOXSSRanges] = ss;
mappings[Template.XBOXDMIHash] = dmihash ?? "";
mappings[Template.XBOXPFIHash] = pfihash ?? "";
mappings[Template.XBOXSSHash] = sshash ?? "";
mappings[Template.XBOXSSRanges] = ss ?? "";
}
break;
case KnownSystem.SonyPlayStation2:
mappings[Template.PlaystationEXEDateField] = GetPlayStationEXEDate(driveLetter);
mappings[Template.VersionField] = GetPlayStation2Version(driveLetter);
mappings[Template.PlaystationEXEDateField] = GetPlayStationEXEDate(driveLetter) ?? "";
mappings[Template.VersionField] = GetPlayStation2Version(driveLetter) ?? "";
break;
}
break;
}
@@ -398,7 +410,7 @@ namespace DICUI.Utilities
}
else if (line.StartsWith("Total errors:"))
{
return Int64.Parse(line.Remove(0, 14));
return Int64.Parse(line.Remove(0, "Total errors:".Length).Trim());
}
return -1;
@@ -411,6 +423,49 @@ namespace DICUI.Utilities
}
}
/// <summary>
/// Get the existance of an anti-modchip string from the input file, if possible
/// </summary>
/// <param name="disc">_disc.txt file location</param>
/// <returns>Antimodchip existance if possible, false on error</returns>
private static bool GetAntiModchipDetected(string disc)
{
// If the file doesn't exist, we can't get info from it
if (!File.Exists(disc))
{
return false;
}
using (StreamReader sr = File.OpenText(disc))
{
try
{
// Check for either antimod string
string line = sr.ReadLine().Trim();
while (!sr.EndOfStream)
{
if (line.StartsWith("Detected anti-mod string"))
{
return true;
}
else if (line.StartsWith("No anti-mod string"))
{
return false;
}
line = sr.ReadLine().Trim();
}
return false;
}
catch
{
// We don't care what the exception is right now
return false;
}
}
}
/// <summary>
/// Get the layerbreak from the input file, if possible
/// </summary>
@@ -428,12 +483,6 @@ namespace DICUI.Utilities
{
try
{
// Make sure this file is a _disc.txt
if (sr.ReadLine() != "========== DiscStructure ==========")
{
return null;
}
// Fast forward to the layerbreak
while (!sr.ReadLine().Trim().StartsWith("EndDataSector")) ;
@@ -448,6 +497,41 @@ namespace DICUI.Utilities
}
}
/// <summary>
/// Get the detected missing EDC count from the input files, if possible
/// </summary>
/// <param name="edcecc">.img_EdcEcc.txt file location</param>
/// <returns>Missing EDC count if possible, -1 on error</returns>
private static long GetMissingEDCCount(string edcecc)
{
// If one of the files doesn't exist, we can't get info from them
if (!File.Exists(edcecc))
{
return -1;
}
// First line of defense is the EdcEcc error file
using (StreamReader sr = File.OpenText(edcecc))
{
try
{
// Fast forward to the PVD
string line = sr.ReadLine();
while (!line.StartsWith("[INFO]"))
{
line = sr.ReadLine();
}
return Int64.Parse(line.Remove(0, "[INFO] Number of sector(s) where EDC doesn't exist: ".Length).Trim());
}
catch
{
// We don't care what the exception is right now
return -1;
}
}
}
/// <summary>
/// Get the PVD from the input file, if possible
/// </summary>
@@ -465,22 +549,15 @@ namespace DICUI.Utilities
{
try
{
// Make sure this file is a _mainInfo.txt
if (sr.ReadLine() != "========== LBA[000016, 0x00010]: Main Channel ==========")
{
return null;
}
// Fast forward to the PVD
while (!sr.ReadLine().StartsWith("0310")) ;
// Now that we're at the PVD, read each line in and concatenate
string pvd = sr.ReadLine() + "\n"; // 0320
pvd += sr.ReadLine() + "\n"; // 0330
pvd += sr.ReadLine() + "\n"; // 0340
pvd += sr.ReadLine() + "\n"; // 0350
pvd += sr.ReadLine() + "\n"; // 0360
pvd += sr.ReadLine() + "\n"; // 0370
string pvd = "";
for (int i = 0; i < 6; i++)
{
pvd += sr.ReadLine() + "\n"; // 320-370
}
return pvd;
}
@@ -619,7 +696,7 @@ namespace DICUI.Utilities
{
byte[] sub = new byte[16];
Array.Copy(headerBytes, ptr, sub, 0, 16);
headerString += ptr.ToString("X").PadLeft(4, '0') + " : "
headerString += ptr.ToString("X").PadLeft(4, '0') + " : "
+ BitConverter.ToString(sub).Replace("-", " ") + " "
+ Encoding.ASCII.GetString(sub) + "\n";
ptr += 16;
@@ -687,12 +764,6 @@ namespace DICUI.Utilities
{
try
{
// Make sure this file is a _disc.txt for XBOX
if (sr.ReadLine() != "========== Lock state ==========")
{
return false;
}
// Fast forward to the Security Sector Ranges
while (!sr.ReadLine().Trim().StartsWith("Number of security sector ranges:")) ;
@@ -743,12 +814,6 @@ namespace DICUI.Utilities
{
try
{
// Make sure this file is a _disc.txt
if (sr.ReadLine() != "========== TOC ==========")
{
return null;
}
// Fast forward to the offsets
while (!sr.ReadLine().Trim().StartsWith("========== Offset")) ;
sr.ReadLine(); // Combined Offset
@@ -771,10 +836,10 @@ namespace DICUI.Utilities
/// </summary>
/// <param name="info">Information dictionary that should contain normalized values</param>
/// <param name="sys">KnownSystem value to check</param>
/// <param name="type">DiscType value to check</param>
/// <param name="type">MediaType value to check</param>
/// <returns>List of strings representing each line of an output file, null on error</returns>
/// <remarks>TODO: Get full list of customizable stuff for other systems</remarks>
public static List<string> FormatOutputData(Dictionary<string, string> info, KnownSystem? sys, DiscType? type)
public static List<string> FormatOutputData(Dictionary<string, string> info, KnownSystem? sys, MediaType? type)
{
// Check to see if the inputs are valid
if (info == null)
@@ -789,6 +854,8 @@ namespace DICUI.Utilities
output.Add(Template.TitleField + ": " + info[Template.TitleField]);
output.Add(Template.DiscNumberField + ": " + info[Template.DiscNumberField]);
output.Add(Template.DiscTitleField + ": " + info[Template.DiscTitleField]);
output.Add(Template.SystemField + ": " + info[Template.SystemField]);
output.Add(Template.MediaTypeField + ": " + info[Template.MediaTypeField]);
output.Add(Template.CategoryField + ": " + info[Template.CategoryField]);
output.Add(Template.RegionField + ": " + info[Template.RegionField]);
output.Add(Template.LanguagesField + ": " + info[Template.LanguagesField]);
@@ -806,31 +873,36 @@ namespace DICUI.Utilities
output.Add("Ringcode Information:");
switch (type)
{
case DiscType.CD:
case DiscType.GDROM:
case DiscType.DVD5:
case DiscType.HDDVD:
case DiscType.BD25:
output.Add("\t" + Template.MasteringRingField + ": " + info[Template.MasteringRingField]);
output.Add("\t" + Template.MasteringSIDField + ": " + info[Template.MasteringSIDField]);
output.Add("\t" + Template.MouldSIDField + ": " + info[Template.MouldSIDField]);
output.Add("\t" + Template.AdditionalMouldField + ": " + info[Template.AdditionalMouldField]);
output.Add("\t" + Template.ToolstampField + ": " + info[Template.ToolstampField]);
break;
case DiscType.DVD9:
case DiscType.BD50:
output.Add("\tOuter " + Template.MasteringRingField + ": " + info["Outer " + Template.MasteringRingField]);
output.Add("\tInner " + Template.MasteringRingField + ": " + info["Inner " + Template.MasteringRingField]);
output.Add("\tOuter " + Template.MasteringSIDField + ": " + info["Outer " + Template.MasteringSIDField]);
output.Add("\tInner " + Template.MasteringSIDField + ": " + info["Inner " + Template.MasteringSIDField]);
output.Add("\t" + Template.MouldSIDField + ": " + info[Template.MouldSIDField]);
output.Add("\t" + Template.AdditionalMouldField + ": " + info[Template.AdditionalMouldField]);
output.Add("\tOuter " + Template.ToolstampField + ": " + info["Outer " + Template.ToolstampField]);
output.Add("\tInner " + Template.ToolstampField + ": " + info["Inner " + Template.ToolstampField]);
case MediaType.CD:
case MediaType.GDROM:
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.BluRay:
// If we have a dual-layer disc
if (info.ContainsKey(Template.LayerbreakField))
{
output.Add("\tOuter " + Template.MasteringRingField + ": " + info["Outer " + Template.MasteringRingField]);
output.Add("\tInner " + Template.MasteringRingField + ": " + info["Inner " + Template.MasteringRingField]);
output.Add("\tOuter " + Template.MasteringSIDField + ": " + info["Outer " + Template.MasteringSIDField]);
output.Add("\tInner " + Template.MasteringSIDField + ": " + info["Inner " + Template.MasteringSIDField]);
output.Add("\t" + Template.MouldSIDField + ": " + info[Template.MouldSIDField]);
output.Add("\t" + Template.AdditionalMouldField + ": " + info[Template.AdditionalMouldField]);
output.Add("\tOuter " + Template.ToolstampField + ": " + info["Outer " + Template.ToolstampField]);
output.Add("\tInner " + Template.ToolstampField + ": " + info["Inner " + Template.ToolstampField]);
}
// If we have a single-layer disc
else
{
output.Add("\t" + Template.MasteringRingField + ": " + info[Template.MasteringRingField]);
output.Add("\t" + Template.MasteringSIDField + ": " + info[Template.MasteringSIDField]);
output.Add("\t" + Template.MouldSIDField + ": " + info[Template.MouldSIDField]);
output.Add("\t" + Template.AdditionalMouldField + ": " + info[Template.AdditionalMouldField]);
output.Add("\t" + Template.ToolstampField + ": " + info[Template.ToolstampField]);
}
break;
}
output.Add(Template.BarcodeField + ": " + info[Template.BarcodeField]);
switch(sys)
switch (sys)
{
case KnownSystem.AppleMacintosh:
case KnownSystem.IBMPCCompatible:
@@ -839,8 +911,8 @@ namespace DICUI.Utilities
}
switch (type)
{
case DiscType.CD:
case DiscType.GDROM:
case MediaType.CD:
case MediaType.GDROM:
output.Add(Template.ErrorCountField + ": " + info[Template.ErrorCountField]);
break;
}
@@ -862,9 +934,13 @@ namespace DICUI.Utilities
}
switch (type)
{
case DiscType.DVD9:
case DiscType.BD50:
output.Add(Template.LayerbreakField + ": " + info[Template.LayerbreakField]);
case MediaType.DVD:
case MediaType.BluRay:
// If we have a dual-layer disc
if (info.ContainsKey(Template.LayerbreakField))
{
output.Add(Template.LayerbreakField + ": " + info[Template.LayerbreakField]);
}
break;
}
output.Add(Template.PVDField + ":"); output.Add("");
@@ -874,12 +950,6 @@ namespace DICUI.Utilities
case KnownSystem.AppleMacintosh:
case KnownSystem.IBMPCCompatible:
output.Add(Template.CopyProtectionField + ": " + info[Template.CopyProtectionField]); output.Add("");
if (info.ContainsKey(Template.SubIntentionField))
{
output.Add(Template.SubIntentionField + ":"); output.Add("");
output.AddRange(info[Template.SubIntentionField].Split('\n'));
}
break;
case KnownSystem.MicrosoftXBOX:
case KnownSystem.MicrosoftXBOX360XDG2:
@@ -891,10 +961,15 @@ namespace DICUI.Utilities
output.AddRange(info[Template.XBOXSSRanges].Split('\n'));
break;
}
if (info.ContainsKey(Template.SubIntentionField))
{
output.Add(Template.SubIntentionField + ":"); output.Add("");
output.AddRange(info[Template.SubIntentionField].Split('\n')); output.Add("");
}
switch (type)
{
case DiscType.CD:
case DiscType.GDROM:
case MediaType.CD:
case MediaType.GDROM:
output.Add(Template.CuesheetField + ":"); output.Add("");
output.AddRange(info[Template.CuesheetField].Split('\n')); output.Add("");
output.Add(Template.WriteOffsetField + ": " + info[Template.WriteOffsetField]); output.Add("");

View File

@@ -3,119 +3,117 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using IMAPI2;
using DICUI.Data;
using DICUI.External;
namespace DICUI.Utilities
{
public static class Validation
public static class Validators
{
/// <summary>
/// Get a list of valid DiscTypes for a given system
/// Get a list of valid MediaTypes for a given KnownSystem
/// </summary>
/// <param name="sys">KnownSystem value to check</param>
/// <returns>List of DiscTypes</returns>
public static List<DiscType?> GetValidDiscTypes(KnownSystem? sys)
/// <returns>MediaTypes, if possible</returns>
public static List<MediaType?> GetValidMediaTypes(KnownSystem? sys)
{
List<DiscType?> types = new List<DiscType?>();
var types = new List<MediaType?>();
switch (sys)
{
#region Consoles
case KnownSystem.BandaiPlaydiaQuickInteractiveSystem:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.BandaiApplePippin:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.CommodoreAmigaCD32:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.CommodoreAmigaCDTV:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.MattelHyperscan:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.MicrosoftXBOX:
types.Add(DiscType.CD);
types.Add(DiscType.DVD9);
types.Add(MediaType.CD);
types.Add(MediaType.DVD);
break;
case KnownSystem.MicrosoftXBOX360XDG2:
types.Add(DiscType.CD);
types.Add(DiscType.DVD9);
types.Add(DiscType.HDDVD);
types.Add(MediaType.CD);
types.Add(MediaType.DVD);
break;
case KnownSystem.MicrosoftXBOX360XDG3:
types.Add(DiscType.CD);
types.Add(DiscType.DVD9);
types.Add(DiscType.HDDVD);
types.Add(MediaType.CD);
types.Add(MediaType.DVD);
types.Add(MediaType.HDDVD);
break;
case KnownSystem.MicrosoftXBOXOne:
types.Add(DiscType.BD25);
types.Add(DiscType.BD50);
types.Add(MediaType.BluRay);
break;
case KnownSystem.NECPCEngineTurboGrafxCD:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.NECPCFX:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.NintendoGameCube:
types.Add(DiscType.GameCubeGameDisc);
types.Add(MediaType.GameCubeGameDisc);
break;
case KnownSystem.NintendoWii:
types.Add(DiscType.WiiOpticalDisc);
types.Add(MediaType.WiiOpticalDisc);
break;
case KnownSystem.NintendoWiiU:
types.Add(DiscType.WiiUOpticalDisc);
types.Add(MediaType.WiiUOpticalDisc);
break;
case KnownSystem.Panasonic3DOInteractiveMultiplayer:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.PhilipsCDi:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.SegaCDMegaCD:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.SegaDreamcast:
types.Add(DiscType.GDROM);
types.Add(MediaType.GDROM);
break;
case KnownSystem.SegaSaturn:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.SNKNeoGeoCD:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.SonyPlayStation:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.SonyPlayStation2:
types.Add(DiscType.CD);
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.CD);
types.Add(MediaType.DVD);
break;
case KnownSystem.SonyPlayStation3:
types.Add(DiscType.BD25);
types.Add(DiscType.BD50);
types.Add(MediaType.BluRay);
break;
case KnownSystem.SonyPlayStation4:
types.Add(DiscType.BD25);
types.Add(DiscType.BD50);
types.Add(MediaType.BluRay);
break;
case KnownSystem.SonyPlayStationPortable:
types.Add(DiscType.UMD);
types.Add(MediaType.UMD);
break;
case KnownSystem.VMLabsNuon:
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.DVD);
break;
case KnownSystem.VTechVFlashVSmilePro:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.ZAPiTGamesGameWaveFamilyEntertainmentSystem:
types.Add(DiscType.DVD5);
types.Add(MediaType.DVD);
break;
#endregion
@@ -123,34 +121,32 @@ namespace DICUI.Utilities
#region Computers
case KnownSystem.AcornArchimedes:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.AppleMacintosh:
types.Add(DiscType.CD);
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(DiscType.Floppy);
types.Add(MediaType.CD);
types.Add(MediaType.DVD);
types.Add(MediaType.Floppy);
break;
case KnownSystem.CommodoreAmigaCD:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.FujitsuFMTowns:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.IBMPCCompatible:
types.Add(DiscType.CD);
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(DiscType.Floppy);
types.Add(MediaType.CD);
types.Add(MediaType.DVD);
types.Add(MediaType.Floppy);
break;
case KnownSystem.NECPC88:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.NECPC98:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.SharpX68000:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
#endregion
@@ -158,192 +154,169 @@ namespace DICUI.Utilities
#region Arcade
case KnownSystem.AmigaCUBOCD32:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.AmericanLaserGames3DO:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.Atari3DO:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.Atronic:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.AUSCOMSystem1:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.BallyGameMagic:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.CapcomCPSystemIII:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.GlobalVRVarious:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.GlobalVRVortek:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.GlobalVRVortekV3:
types.Add(DiscType.DVD5); // TODO: Confirm
types.Add(DiscType.DVD9); // TODO: Confirm
types.Add(MediaType.DVD); // TODO: Confirm
break;
case KnownSystem.ICEPCHardware:
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.DVD);
break;
case KnownSystem.IncredibleTechnologiesEagle:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.IncredibleTechnologiesVarious:
types.Add(DiscType.CD);
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.CD);
types.Add(MediaType.DVD);
break;
case KnownSystem.KonamiFirebeat:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.KonamiGVSystem:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.KonamiM2:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.KonamiPython:
types.Add(DiscType.DVD5); // TODO: Confirm
types.Add(DiscType.DVD9); // TODO: Confirm
types.Add(MediaType.DVD); // TODO: Confirm
break;
case KnownSystem.KonamiPython2:
types.Add(DiscType.DVD5); // TODO: Confirm
types.Add(DiscType.DVD9); // TODO: Confirm
types.Add(MediaType.DVD); // TODO: Confirm
break;
case KnownSystem.KonamiSystem573:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.KonamiTwinkle:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.KonamiVarious:
types.Add(DiscType.CD);
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.CD);
types.Add(MediaType.DVD);
break;
case KnownSystem.MeritIndustriesBoardwalk:
types.Add(DiscType.CD); // TODO: Confirm
types.Add(MediaType.CD); // TODO: Confirm
break;
case KnownSystem.MeritIndustriesMegaTouchAurora:
types.Add(DiscType.CD); // TODO: Confirm
types.Add(MediaType.CD); // TODO: Confirm
break;
case KnownSystem.MeritIndustriesMegaTouchForce:
types.Add(DiscType.CD);
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.CD);
types.Add(MediaType.DVD);
break;
case KnownSystem.MeritIndustriesMegaTouchION:
types.Add(DiscType.CD);
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.CD);
types.Add(MediaType.DVD);
break;
case KnownSystem.MeritIndustriesMegaTouchMaxx:
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.DVD);
break;
case KnownSystem.MeritIndustriesMegaTouchXL:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.NamcoCapcomSystem256:
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.DVD);
break;
case KnownSystem.NamcoCapcomTaitoSystem246:
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.DVD);
break;
case KnownSystem.NamcoSegaNintendoTriforce:
types.Add(DiscType.GDROM);
types.Add(MediaType.GDROM);
break;
case KnownSystem.NamcoSystem12:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.NamcoSystem357:
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(DiscType.BD25);
types.Add(DiscType.BD50);
types.Add(MediaType.DVD);
types.Add(MediaType.BluRay);
break;
case KnownSystem.NewJatreCDi:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.NichibutsuHighRateSystem:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.NichibutsuSuperCD:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.NichibutsuXRateSystem:
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.DVD);
break;
case KnownSystem.PhotoPlayVarious:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.RawThrillsVarious:
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.DVD);
break;
case KnownSystem.SegaChihiro:
types.Add(DiscType.GDROM);
types.Add(MediaType.GDROM);
break;
case KnownSystem.SegaEuropaR:
types.Add(DiscType.DVD5); // TODO: Confirm
types.Add(DiscType.DVD9); // TODO: Confirm
types.Add(MediaType.DVD); // TODO: Confirm
break;
case KnownSystem.SegaLindbergh:
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.DVD);
break;
case KnownSystem.SegaNaomi:
types.Add(DiscType.GDROM);
types.Add(MediaType.GDROM);
break;
case KnownSystem.SegaNaomi2:
types.Add(DiscType.GDROM);
types.Add(MediaType.GDROM);
break;
case KnownSystem.SegaNu:
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(DiscType.BD25);
types.Add(DiscType.BD50);
types.Add(MediaType.DVD);
types.Add(MediaType.BluRay);
break;
case KnownSystem.SegaRingEdge:
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.DVD);
break;
case KnownSystem.SegaRingEdge2:
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.DVD);
break;
case KnownSystem.SegaRingWide:
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.DVD);
break;
case KnownSystem.SegaSTV:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.SegaSystem32:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.SeibuCATSSystem:
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.DVD);
break;
case KnownSystem.TABAustriaQuizard:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.TandyMemorexVisualInformationSystem:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.TsunamiTsuMoMultiGameMotionSystem:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
#endregion
@@ -351,46 +324,47 @@ namespace DICUI.Utilities
#region Others
case KnownSystem.AudioCD:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.BDVideo:
types.Add(DiscType.BD25);
types.Add(DiscType.BD50);
types.Add(MediaType.BluRay);
break;
case KnownSystem.DVDVideo:
types.Add(DiscType.DVD5);
types.Add(DiscType.DVD9);
types.Add(MediaType.DVD);
break;
case KnownSystem.EnhancedCD:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.HDDVDVideo:
types.Add(MediaType.HDDVD);
break;
case KnownSystem.PalmOS:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.PhilipsCDiDigitalVideo:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.PhotoCD:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.PlayStationGameSharkUpdates:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.TaoiKTV:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.TomyKissSite:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
case KnownSystem.VideoCD:
types.Add(DiscType.CD);
types.Add(MediaType.CD);
break;
#endregion
case KnownSystem.NONE:
default:
types.Add(DiscType.NONE);
types.Add(MediaType.NONE);
break;
}
@@ -402,15 +376,12 @@ namespace DICUI.Utilities
/// </summary>
/// <returns>Systems matched to enums, if possible</returns>
/// <remarks>
/// This returns a List of Tuples whose structure is as follows:
/// Item 1: Printable name
/// Item 2: KnownSystem mapping
/// Item 3: DiscType mapping
/// If something has a "string, null, null" value, it should be assumed that it is a separator
/// If something has a "string, null" value, it should be assumed that it is a separator
/// </remarks>
public static List<Tuple<string, KnownSystem?, DiscType?>> CreateListOfSystems()
/// TODO: Figure out a way that the sections can be generated more automatically
public static OrderedDictionary<string, KnownSystem?> CreateListOfSystems()
{
List<Tuple<string, KnownSystem?, DiscType?>> mapping = new List<Tuple<string, KnownSystem?, DiscType?>>();
var systemsDict = new OrderedDictionary<string, KnownSystem?>();
foreach (KnownSystem system in Enum.GetValues(typeof(KnownSystem)))
{
@@ -419,47 +390,29 @@ namespace DICUI.Utilities
{
// Consoles section
case KnownSystem.BandaiPlaydiaQuickInteractiveSystem:
mapping.Add(new Tuple<string, KnownSystem?, DiscType?>("---------- Consoles ----------", null, null));
systemsDict.Add("---------- Consoles ----------", null);
break;
// Computers section
case KnownSystem.AcornArchimedes:
mapping.Add(new Tuple<string, KnownSystem?, DiscType?>("---------- Computers ----------", null, null));
systemsDict.Add("---------- Computers ----------", null);
break;
// Arcade section
case KnownSystem.AmigaCUBOCD32:
mapping.Add(new Tuple<string, KnownSystem?, DiscType?>("---------- Arcade ----------", null, null));
systemsDict.Add("---------- Arcade ----------", null);
break;
// Other section
case KnownSystem.AudioCD:
mapping.Add(new Tuple<string, KnownSystem?, DiscType?>("---------- Others ----------", null, null));
systemsDict.Add("---------- Others ----------", null);
break;
}
// First, get a list of all DiscTypes for a given KnownSystem
List<DiscType?> types = GetValidDiscTypes(system);
// If we have a single type, we don't want to postfix the system name with it
if (types.Count == 1)
{
mapping.Add(new Tuple<string, KnownSystem?, DiscType?>(Converters.KnownSystemToString(system), system, types[0]));
}
// Otherwise, postfix the system name properly
else
{
foreach (DiscType type in types)
{
mapping.Add(new Tuple<string, KnownSystem?, DiscType?>(Converters.KnownSystemToString(system) + " (" + Converters.DiscTypeToString(type) + ")", system, type));
}
}
systemsDict.Add(Converters.KnownSystemToString(system), system);
}
// Add final mapping for "Custom"
mapping.Add(new Tuple<string, KnownSystem?, DiscType?>("Custom Input", KnownSystem.NONE, DiscType.NONE));
return mapping;
return systemsDict;
}
/// <summary>
@@ -469,15 +422,11 @@ namespace DICUI.Utilities
/// <remarks>
/// https://stackoverflow.com/questions/3060796/how-to-distinguish-between-usb-and-floppy-devices?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
/// https://msdn.microsoft.com/en-us/library/aa394173(v=vs.85).aspx
/// This returns a List of Tuples whose structure is as follows:
/// Item 1: Drive letter
/// Item 2: Volume label
/// Item 3: (True for floppy drive, false otherwise)
/// </remarks>
public static List<Tuple<char, string, bool>> CreateListOfDrives()
public static OrderedDictionary<char, string> CreateListOfDrives()
{
// Get the floppy drives
List<Tuple<char, string, bool>> floppyDrives = new List<Tuple<char, string, bool>>();
var floppyDrives = new List<KeyValuePair<char, string>>();
try
{
ManagementObjectSearcher searcher =
@@ -491,7 +440,7 @@ namespace DICUI.Utilities
if (mediaType != null && ((mediaType > 0 && mediaType < 11) || (mediaType > 12 && mediaType < 22)))
{
char devId = queryObj["DeviceID"].ToString()[0];
floppyDrives.Add(new Tuple<char, string, bool>(devId, "FLOPPY", true));
floppyDrives.Add(new KeyValuePair<char, string>(devId, UIElements.FloppyDriveString));
}
}
}
@@ -501,14 +450,223 @@ namespace DICUI.Utilities
}
// Get the optical disc drives
List<Tuple<char, string, bool>> discDrives = DriveInfo.GetDrives()
List<KeyValuePair<char, string>> discDrives = DriveInfo.GetDrives()
.Where(d => d.DriveType == DriveType.CDRom && d.IsReady)
.Select(d => new Tuple<char, string, bool>(d.Name[0], d.VolumeLabel, false))
.Select(d => new KeyValuePair<char, string>(d.Name[0], d.VolumeLabel))
.ToList();
// Add the two lists together, order, and return
// Add the two lists together and order
floppyDrives.AddRange(discDrives);
return floppyDrives.OrderBy(i => i.Item1).ToList();
floppyDrives = floppyDrives.OrderBy(i => i.Key).ToList();
// Add to the ordered dictionary and return
var drivesDict = new OrderedDictionary<char, string>();
foreach (var drive in floppyDrives)
{
drivesDict.Add(drive.Key, drive.Value);
}
return drivesDict;
}
/// <summary>
/// Get the current disc type from drive letter
/// </summary>
/// <param name="driveLetter"></param>
/// <returns></returns>
/// <remarks>
/// https://stackoverflow.com/questions/11420365/detecting-if-disc-is-in-dvd-drive
/// </remarks>
public static MediaType? GetDiscType(char? driveLetter)
{
// Get the DeviceID from the current drive letter
string deviceId = null;
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_CDROMDrive WHERE Id = '" + driveLetter + ":\'");
var collection = searcher.Get();
foreach (ManagementObject queryObj in collection)
{
deviceId = (string)queryObj["DeviceID"];
}
}
catch
{
// We don't care what the error was
return null;
}
// If we got no valid device, we don't care and just return
if (deviceId == null)
{
return null;
}
// Get all relevant disc information
MsftDiscMaster2 discMaster = new MsftDiscMaster2();
deviceId = deviceId.ToLower().Replace('\\', '#');
string id = null;
foreach (var disc in discMaster)
{
if (disc.ToString().Contains(deviceId))
{
id = disc.ToString();
}
}
// If we couldn't find the drive, we don't care and return
if (id == null)
{
return null;
}
// Otherwise, we get the media type, if any
MsftDiscRecorder2 recorder = new MsftDiscRecorder2();
recorder.InitializeDiscRecorder(id);
MsftDiscFormat2Data dataWriter = new MsftDiscFormat2Data();
dataWriter.Recorder = recorder;
var media = dataWriter.CurrentPhysicalMediaType;
if (media != IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_UNKNOWN)
{
return Converters.IMAPIDiskTypeToMediaType(media);
}
return null;
}
/// <summary>
/// Get the drive speed of the currently selected drive
/// </summary>
/// <returns>Speed of the drive converted from kbps</returns>
/// <remarks>
/// DIC uses the SCSI_MODE_SENSE command to check this, so does QPXTool (a different one, but still)
/// See if SCSI_MODE_SENSE can be used here
/// Currently, the calculations get something that is technically accurate, but is different than the advertisised
/// capabilities of the drives (according to QPXTool)
/// </remarks>
public static int GetDriveSpeed(char driveLetter)
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_CDROMDrive WHERE Id = '" + driveLetter + ":\'");
var collection = searcher.Get();
double? transferRate = -1;
foreach (ManagementObject queryObj in collection)
{
var obj = queryObj["TransferRate"];
transferRate = (double?)queryObj["TransferRate"];
}
// Transfer Rates (bps)
double cdTransfer = 150 * 1024;
double dvdTransfer = 1353 * 1024;
double cdTransferTest = ((transferRate ?? -1) * 1024) / cdTransfer;
double cdTransferTestKilo = ((transferRate ?? -1) * 1000) / cdTransfer;
double dvdTransferTest = ((transferRate ?? -1) * 1024) / dvdTransfer;
double dvdTransferTestKilo = ((transferRate ?? -1) * 1000) / dvdTransfer;
return 0;
}
public static int GetDriveSpeedEx(char driveLetter, MediaType? mediaType)
{
// Get the DeviceID from the current drive letter
string deviceId = null;
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_CDROMDrive WHERE Id = '" + driveLetter + ":\'");
var collection = searcher.Get();
foreach (ManagementObject queryObj in collection)
{
deviceId = (string)queryObj["DeviceID"];
}
}
catch
{
// We don't care what the error was
return -1;
}
// If we got no valid device, we don't care and just return
if (deviceId == null)
{
return -1;
}
// Get all relevant disc information
MsftDiscMaster2 discMaster = new MsftDiscMaster2();
deviceId = deviceId.ToLower().Replace('\\', '#');
string id = null;
foreach (var disc in discMaster)
{
if (disc.ToString().Contains(deviceId))
{
id = disc.ToString();
}
}
// If we couldn't find the drive, we don't care and return
if (id == null)
{
return -1;
}
// Now we initialize the recorder to get disc info
MsftDiscRecorder2 recorder = new MsftDiscRecorder2();
recorder.InitializeDiscRecorder(id);
IDiscRecorder2Ex recorderEx = recorder as IDiscRecorder2Ex;
IMAPI_FEATURE_PAGE_TYPE ifpt = IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_PROFILE_LIST;
switch(mediaType)
{
case MediaType.CD:
ifpt = IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_CD_READ;
break;
case MediaType.DVD:
ifpt = IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_DVD_READ;
break;
case MediaType.HDDVD:
ifpt = IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_HD_DVD_READ;
break;
case MediaType.BluRay:
ifpt = IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_BD_READ;
break;
}
// If we couldn't determine the media type properly, we don't care and return
if (ifpt == IMAPI_FEATURE_PAGE_TYPE.IMAPI_FEATURE_PAGE_TYPE_PROFILE_LIST)
{
return -1;
}
// Now we get the requested mode data
IntPtr modeData = Marshal.AllocHGlobal(256 * sizeof(byte));
recorderEx.GetModePage(
IMAPI_MODE_PAGE_TYPE.IMAPI_MODE_PAGE_TYPE_LEGACY_CAPABILITIES,
IMAPI_MODE_PAGE_REQUEST_TYPE.IMAPI_MODE_PAGE_REQUEST_TYPE_CURRENT_VALUES,
modeData,
out uint modeDataSize);
byte[] outModeArray = new byte[modeDataSize];
Marshal.Copy(modeData, outModeArray, 0, (int)modeDataSize);
// Now we get the requested feature page
IntPtr featureData = Marshal.AllocHGlobal(32 * sizeof(byte));
recorderEx.GetFeaturePage(
ifpt,
(sbyte)1,
featureData,
out uint byteSize);
byte[] outArray = new byte[byteSize];
Marshal.Copy(featureData, outArray, 0, (int)byteSize);
return -1;
}
/// <summary>
@@ -713,7 +871,7 @@ namespace DICUI.Utilities
{
for (int i = index; i < parts.Count; i++)
{
switch(parts[i])
switch (parts[i])
{
case DICFlags.DisableBeep:
if (parts[0] != DICCommands.CompactDisc
@@ -819,7 +977,7 @@ namespace DICUI.Utilities
{
return false;
}
// If the next item doesn't exist, it's good
if (!DoesNextExist(parts, i))
{
@@ -1053,12 +1211,12 @@ namespace DICUI.Utilities
/// Determine the base flags to use for checking a commandline
/// </summary>
/// <param name="parameters">Parameters as a string to check</param>
/// <param name="type">Output nullable DiscType containing the found DiscType, if possible</param>
/// <param name="type">Output nullable MediaType containing the found MediaType, if possible</param>
/// <param name="system">Output nullable KnownSystem containing the found KnownSystem, if possible</param>
/// <param name="letter">Output string containing the found drive letter</param>
/// <param name="path">Output string containing the found path</param>
/// <returns>False on error (and all outputs set to null), true otherwise</returns>
public static bool DetermineFlags(string parameters, out DiscType? type, out KnownSystem? system, out string letter, out string path)
public static bool DetermineFlags(string parameters, out MediaType? type, out KnownSystem? system, out string letter, out string path)
{
// Populate all output variables with null
type = null; system = null; letter = null; path = null;
@@ -1077,7 +1235,7 @@ namespace DICUI.Utilities
.Select(m => m.Value)
.ToList();
type = Converters.BaseCommmandToDiscType(parts[0]);
type = Converters.BaseCommmandToMediaType(parts[0]);
system = Converters.BaseCommandToKnownSystem(parts[0]);
// Determine what the commandline should look like given the first item
@@ -1107,20 +1265,20 @@ namespace DICUI.Utilities
// Special case for GameCube/Wii
if (parts.Contains(DICFlags.Raw))
{
type = DiscType.GameCubeGameDisc;
type = MediaType.GameCubeGameDisc;
system = KnownSystem.NintendoGameCube;
}
// Special case for PlayStation
else if (parts.Contains(DICFlags.NoFixSubQLibCrypt)
|| parts.Contains(DICFlags.ScanAntiMod))
{
type = DiscType.CD;
type = MediaType.CD;
system = KnownSystem.SonyPlayStation;
}
// Special case for Saturn
else if (parts.Contains(DICFlags.SeventyFour))
{
type = DiscType.CD;
type = MediaType.CD;
system = KnownSystem.SegaSaturn;
}

36
appveyor.yml Normal file
View File

@@ -0,0 +1,36 @@
# version format
version: 1.06_{build}
# vm template
image: Visual Studio 2017
# environment variables
environment:
EnableNuGetPackageRestore: true
# msbuild configuration
platform:
- AnyCPU
configuration:
- Debug
# install dependencies
install:
- ps: appveyor DownloadFile https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
# pre-build script
before_build:
- nuget restore
# build step
build:
verbosity: minimal
# post-build step
after_build:
- 7z a dicui_%APPVEYOR_BUILD_VERSION%.zip bin\Debug
# artifact linking
artifacts:
- path: dicui_$(version).zip
name: DICUI