Compare commits

..

282 Commits
1.03 ... 1.15

Author SHA1 Message Date
Matt Nadareski
fbc9d04782 Advanced Support (#172)
* Who doesn't like drives?

* Add another TODO

* Use built in stuff, it's quicker

* More special handling for floppies, easier this time

* Fix broken test

* Set active drive priority, String -> string

* Track reason for no scanning

* Update DIC version and release notes
2019-11-17 01:06:41 -05:00
Matt Nadareski
24b08dd245 Update BurnOutSharp 2019-10-25 20:37:08 -07:00
Matt Nadareski
c7ebe69b05 Update BurnOutSharp 2019-10-24 13:25:28 -07:00
Matt Nadareski
22ffda4b5a Fix copy protection scan by preferring 32-bit 2019-10-19 02:42:01 -07:00
Matt Nadareski
b89c051d7d DICUI 1.14 Release 2019-10-01 11:57:15 -07:00
Matt Nadareski
8b41f03472 Update to new DIC version (#167)
* Remove `.` handling code since it should be in DIC now

* Add support for 3 new flags

* Fix dot tests

* Fix PS4 autodetect (Fixes #164)

* Fix PS4 version finding

* Update DIC archive path

* Add support for disk command (unused by default)
2019-10-01 11:53:44 -07:00
Matt Nadareski
700ff50eef Upgrades, people! (#166)
* First step: 4.6.2

* Make Check and Library .NET Core 3.0 compatible

* Enable 4.6.2 and 4.7.2 on DICUI

* DICUI .NET Core 3.0

* Solution items

* New Appeyor paths, environment

* Upgrade DICUI.Test for all frameworks too

* Fix .NET Core 3.0 difference in path handling
2019-10-01 11:36:01 -07:00
Matt Nadareski
95ac7236ff Fix PS4 version finding 2019-09-29 22:23:45 -07:00
Matt Nadareski
755f1b8e95 Root directories are weird (Fixes #163) 2019-09-29 21:28:20 -07:00
Matt Nadareski
d431a4c87f Fix PS4 autodetect (Fixes #164) 2019-09-29 21:18:02 -07:00
Matt Nadareski
04348d2d58 PSX.EXE is a valid filename to find 2019-09-17 20:59:10 -07:00
Matt Nadareski
6f5214c1a4 Even More Info (#161)
* Add (currently) hidden setting for disc info

* Show setting in Options menu

* Fix new window

* New place for combo box items

* Fixes to outputs

* Add category, fix a few things

* Actually use the custom converter

* Allow tabs in ringcode
2019-09-17 20:50:44 -07:00
Hennadiy Brych
1fe12be0b5 PSX date fixes (#157)
* Sony PlayStation date extraction fixed, 3 separate issues:
1. 190x year instead of 200x
2. Failure to get date for some titles where SYSTEM.CNF BOOT record doesn't have backslash after "cdrom:"
3. Date shift by one day due to Utc offset applied
Relaxed directory path requirements to allow dot and ampersand. DiscImageCreator had to be changed in order to support this, will be submitted separately.

* Reverted extra path characters modification.

* Reverted to UTC time
2019-08-28 00:02:13 -07:00
Matt Nadareski
9c9ca16366 Persist paths unless changing drive letters (fixes #154) 2019-08-12 14:08:55 -07:00
Matt Nadareski
1702db71d1 Add new Redump regions (GC; Uk,Au; U,Ca) 2019-08-05 11:07:51 -07:00
Matt Nadareski
0ba7ccdb9a HTML decode (fixes #150) 2019-07-30 00:19:02 -07:00
Matt Nadareski
3ccf65190e Migrate to archive.org 2019-07-18 11:26:17 -07:00
Matt Nadareski
6b9ee3d5ed Update AppVeyor config 2019-07-18 11:20:09 -07:00
Matt Nadareski
3ee0355034 Add speculative values for VideoNow dumping 2019-07-18 10:42:23 -07:00
Matt Nadareski
7074fa1e2c Update to newest DIC, create new release 2019-07-01 20:50:38 -07:00
Matt Nadareski
44b91a6611 Add initial type dectection, hopefully fixes #145 2019-06-17 14:36:54 -07:00
Matt Nadareski
b2185dbed9 Better ways of getting settings (defaults, existence, etc) 2019-05-26 22:30:06 -07:00
Matt Nadareski
ec4b69b6e6 Multiline outputs should lack prefix (force DAT multiline) 2019-05-26 00:57:06 -07:00
Matt Nadareski
b6db873a00 Settings and more (fixes #141) 2019-05-26 00:48:26 -07:00
Matt Nadareski
db9222b737 Accidential layerbreak infos 2019-05-24 14:26:11 -07:00
Matt Nadareski
b7bfa3ba28 Readonly Regex, Rather 2019-05-24 11:18:49 -07:00
Matt Nadareski
ab25687119 Better UMD support 2019-05-24 11:17:59 -07:00
Matt Nadareski
9bfa0a01ad I clearly remember how Remove works 2019-05-23 22:00:36 -07:00
Matt Nadareski
19c99fb7fe I'm having fun 2019-05-22 22:06:43 -07:00
Matt Nadareski
913244459e Oops, forgot a couple 2019-05-22 21:49:55 -07:00
Matt Nadareski
c66df99e22 Add a few more fun things that might get UI features later 2019-05-22 21:33:31 -07:00
Matt Nadareski
03f4a6e2e4 csproj cleanup 2019-05-22 16:13:47 -07:00
Matt Nadareski
31a243eeb4 Update changelist (been too long) 2019-05-22 16:07:15 -07:00
Matt Nadareski
043c0eff1c BluRay has a default layerbreak and known sizes 2019-05-22 15:49:15 -07:00
Matt Nadareski
ff44313e13 Buffs for potential future work 2019-05-21 00:22:16 -07:00
Matt Nadareski
e06ed31b21 Round 2, fight 2019-05-21 00:07:24 -07:00
Matt Nadareski
aeaec9e805 Add currently unused dump status 2019-05-20 23:39:37 -07:00
Matt Nadareski
6df0c76939 Stupid default namespace 2019-05-20 23:35:04 -07:00
Matt Nadareski
72efffcec4 Cleanup brigade 2019-05-20 22:14:53 -07:00
Matt Nadareski
930e4f7514 Only allow trailing spaces if there's no trailing directory marker 2019-05-20 15:08:41 -07:00
Matt Nadareski
85f71032b5 Fix trailing space handling for output directory 2019-05-20 15:00:41 -07:00
Matt Nadareski
ead530e2ec Code prettification 2019-05-20 00:12:06 -07:00
Matt Nadareski
dc14b1ea52 Both successes, not overwrite 2019-05-19 23:59:16 -07:00
Matt Nadareski
4628be2855 Simplify per-type and per-system code 2019-05-19 23:50:37 -07:00
Matt Nadareski
1f24c08770 Move some logic to SubmissionInfo, fix PS1/PS2/PS4 2019-05-19 22:13:57 -07:00
Matt Nadareski
4889b9d0bf Fix EXE parsing for PS1/PS2 discs 2019-05-14 21:05:05 -07:00
Matt Nadareski
b3d7422a66 Minor cleanup of fields and comments 2019-05-14 20:54:08 -07:00
Matt Nadareski
a0000528de Build date as string again 2019-05-14 20:50:17 -07:00
Matt Nadareski
2be46ec7a1 Trim fields that may have trailing whitespace 2019-05-14 01:56:39 -07:00
Matt Nadareski
f2510a08a4 Barcode, another low-hanging fruit 2019-05-14 01:51:48 -07:00
Matt Nadareski
2787377250 Add ability to get matching IDs from Redump 2019-05-14 01:46:10 -07:00
Matt Nadareski
e61ca31a3f Remove unused Forms version 2019-05-13 23:51:00 -07:00
Matt Nadareski
1b735b5d06 Migrate to SubmissionInfo object, add JSON output 2019-05-13 21:55:08 -07:00
Matt Nadareski
ad3d26cdea Better naming of blank-labeled discs 2019-05-12 21:18:07 -07:00
Matt Nadareski
f372ec4ccd Add new system, better submissioninfo, future 2019-05-11 22:32:22 -07:00
Matt Nadareski
44e75a50d7 Mass add of unused systems 2019-05-06 12:29:19 -07:00
Matt Nadareski
6f0ea2de3e Formats cleanup before adding more 2019-05-06 10:52:07 -07:00
Matt Nadareski
b4f0f7f4b3 Ensure all GD-ROM systems have LD optinos as well 2019-05-05 23:57:11 -07:00
Matt Nadareski
5027d67731 Add new VideoNow systems, cleanup 2019-04-27 17:11:39 -07:00
Matt Nadareski
6c8016345a Use full file path in Check (to correct relative paths) 2019-04-20 22:03:23 -07:00
Matt Nadareski
7ba04e63c7 Support JagCD (may need /ms still) 2019-04-11 21:12:36 -07:00
Matt Nadareski
77dc1d0029 Fix X360 DMI offset 2019-04-04 14:33:26 -07:00
Matt Nadareski
2b6538707f Add DMI extraction for XBOX/369 (fixes #139) 2019-04-04 01:09:51 -07:00
Matt Nadareski
902e4e5715 Make DICUI.Check better 2019-04-04 00:37:17 -07:00
Matt Nadareski
28f6d50e5a Better error checking; more DICUI.Check updates 2019-03-30 21:44:57 -07:00
Matt Nadareski
d8ed7d6ad7 Fix CD dumping with newest release; DICUI.Check minor update 2019-03-30 21:32:10 -07:00
Matt Nadareski
078d7d0ea3 Fix failing test 2019-03-27 17:37:03 -07:00
Matt Nadareski
5895a66c7a Update to DIC 20190326 2019-03-27 17:32:31 -07:00
Matt Nadareski
5ccff836e2 Add DVD for Panasonic M2 (fixes #138) 2019-02-26 11:57:12 -08:00
Matt Nadareski
b2c2e8c4d9 Reverse mould SID fields order (fixes #137) 2019-02-26 11:55:14 -08:00
Matt Nadareski
890959cfe0 Add DICUI.Check, standalone output parsing tool 2019-02-10 14:47:53 -08:00
Matt Nadareski
8729c7f20c Add new template to CD/GD as well 2019-01-28 21:15:07 -08:00
Matt Nadareski
74826909f4 Bump version to 1.12 2019-01-27 22:25:53 -08:00
Matt Nadareski
eb4904afb4 Add support for SCD/MCD headers (fixes #133) 2019-01-27 21:42:03 -08:00
Matt Nadareski
06975316b9 Add Panasonic M2 and Hasbro VideoNow to supported discs 2019-01-27 21:31:05 -08:00
Matt Nadareski
e0be24e54f Update links after organizational shift 2019-01-27 20:45:10 -08:00
Matt Nadareski
eb3cbc44a7 Add missing PVD text (fixes #128) 2019-01-27 16:30:15 -08:00
Matt Nadareski
d6f39bfd4c Ped-ant-ic (fixes #132) 2019-01-27 16:27:59 -08:00
Matt Nadareski
576fa07a2c Fix dumping status in Winforms 2018-11-07 20:27:35 -08:00
Matt Nadareski
ae2b26f84e Capitalization that's been bothering me 2018-11-05 20:30:39 -08:00
Matt Nadareski
1d9a2c9be7 Make sure that detected disc type is shown; cleanup 2018-11-05 20:27:01 -08:00
Matt Nadareski
538c0bba09 Fix output of the media type box in Winforms 2018-11-05 15:30:45 -08:00
Matt Nadareski
57c31cad48 Update AppVeyor build number 2018-11-05 14:51:14 -08:00
Matt Nadareski
093db36f44 Make Floppy Disk a supported format again 2018-11-05 14:51:00 -08:00
Matt Nadareski
fd4db3f8f0 Make SCM optional for Audio-CD (fixes #127) 2018-11-05 14:48:25 -08:00
Matt Nadareski
856a3161be Fix missing file extension 2018-10-22 11:09:28 -07:00
Matt Nadareski
dfafe9789a Update AppVeyor for new DIC version 2018-10-22 11:06:25 -07:00
Matt Nadareski
9f750d01c4 Correct submissionInfo output order (fixes #125) 2018-10-22 10:44:29 -07:00
Matt Nadareski
705ee82cbb Audio CDs don't have the _EdcEcc file right now 2018-10-22 10:41:10 -07:00
Matt Nadareski
d1f80efa41 Add DIC merge command and skip sector flag 2018-10-22 10:32:48 -07:00
Matt Nadareski
f88e6617e5 Fix some of the descriptions in submissionInfo (partial #115) 2018-10-15 17:22:42 -07:00
Matt Nadareski
1401422b08 Add DVD for PS3 (fixes #124) 2018-10-15 17:19:48 -07:00
Matt Nadareski
4539066af0 Update version numbers for 1.11 2018-10-08 12:53:59 -07:00
Matt Nadareski
ec23502275 Abstract out non-UI code to separate DLL (#122)
* Abstract out non-UI code to separate DLL

This change seems rather large, but it's mostly just moving anything that is not directly driving the UI to its own, separate library. This will make it easier at a later date for any UI improvements or changes as well as making the code much more discrete. One TODO has been added as a result of this change.

* Remove MessageBox from library

This change removes the last UI-driven elements from the library. This now makes the library (in theory) UI-agnostic and removes the TODO.

* Options is more UI-related

* Fix Nuget references in csproj

* Add Winforms UI

This is a clone of the current WPF UI but implemented in Windows Forms. WPF is not currently supported by Mono for Linux and macOS, so this can provide an alternative to those users who want to run on those systems instead. This also adds a second artifact for the Winforms build.
2018-10-08 11:06:22 -07:00
Matt Nadareski
331f875e7f Add better progress logging for dumps (fixes #121) 2018-09-24 12:17:57 -07:00
Matt Nadareski
e68f88062f Fix mundane test 2018-09-20 22:39:07 -07:00
Matt Nadareski
d1bb8184d1 Path correction 2018-09-20 22:18:07 -07:00
Matt Nadareski
b7b3f36402 Fix build 2018-09-20 21:30:13 -07:00
Matt Nadareski
859af8efea Format wars 2018-09-20 21:25:22 -07:00
Matt Nadareski
8594d7884c Update terminology (fixes #119) 2018-09-19 20:50:57 -07:00
Matt Nadareski
946dc929f1 Add profile for low-density part of GDROM
Currently, it's easier to just say "it's a CD" and call it a day
2018-09-19 20:49:33 -07:00
Matt Nadareski
1e5b1a205e Update DIC version for AppVeyor 2018-09-19 20:42:49 -07:00
Matt Nadareski
3271cd0ea3 Fix Saturn output info (fixes #118) 2018-09-10 18:27:13 -07:00
Matt Nadareski
647bab8cd3 Merge branch 'master' of https://github.com/reignstumble/DICUI 2018-09-10 16:44:49 -07:00
Matt Nadareski
89b2438dac Threefold fixes
1) Fix the issue where custom parameters that include the `/s 2` flag crash the program
2) Make editing custom parameters a little more intutive (still need to figure out either a way in-documentation or in-UI to explain the checkbox a little better). This part of the change needs to be more tested but there aren't many people using the current feature anyway.
3) Fix the random "Error count: -1" issue that some users were seeing (ended up being a result of more things being in the `_mainError.txt` file than originally anticipated)
2018-09-10 16:43:25 -07:00
Whovian9369
1dcd36d640 Change printable string misspellings relating to DIC (#117)
* Update DumpEnvironment.cs

Change Disk to Disc in printable strings of DumpEnvironment.cs

* Update OptionsWindow.xaml

Change Disk to Disc in printable strings of OptionsWindow.xaml
2018-09-03 13:16:03 -07:00
Matt Nadareski
2f63ebcd29 Fix unprotected DVD info; hopefully fix error count parsing 2018-09-03 00:38:52 -07:00
Matt Nadareski
316953f38c Add UmdImageCreator output parsing 2018-09-02 22:15:40 -07:00
Matt Nadareski
62813ac701 Fix tests 2018-09-01 18:03:48 -07:00
Matt Nadareski
22a936e60b XBOX CDs are not XISO formatted 2018-09-01 17:57:26 -07:00
Matt Nadareski
6412205fa3 Unknown sector ranges aren't recorded 2018-09-01 17:43:38 -07:00
Matt Nadareski
75c18ea3c4 Update for even more DIC changes 2018-09-01 17:02:09 -07:00
Matt Nadareski
6bdb93208e Add DVD-Video protection info 2018-08-29 14:40:35 -07:00
Matt Nadareski
588ed19692 Update README.md
The link for AppVeyor now goes directly to the artifacts page for easier downloading. Hopefully this reduces the issues that are seen with new users.
2018-08-28 21:44:07 -07:00
Matt Nadareski
d56ab5ab37 Update to new version of DIC in AppVeyor 2018-08-28 21:42:01 -07:00
Matt Nadareski
819d18112e My fault, this try/catch doesn't need to be here 2018-08-28 21:29:24 -07:00
Matt Nadareski
2e79cbb0db Fix XBOX/X360 outputs 2018-08-28 21:01:52 -07:00
Matt Nadareski
f024611de8 Take advantage of new XGD3 support in DIC (fixes #71) 2018-08-28 17:31:45 -07:00
Matt Nadareski
48e6283c37 Add PS4 PIC extraction (fixes #106) 2018-08-19 01:25:52 -07:00
Matt Nadareski
fec70f17bc ...wrong path 2018-08-19 00:50:58 -07:00
Matt Nadareski
257f7ab7df Last fix: subfoldering 2018-08-19 00:48:18 -07:00
Matt Nadareski
c1ed3aca02 Path is important 2018-08-19 00:43:32 -07:00
Matt Nadareski
ace6a78236 Attempt to fix AppVeyor 2018-08-19 00:41:34 -07:00
Matt Nadareski
f1e9f1d433 Add PS4 version finding, minor fixes (fixes #105) 2018-08-19 00:19:57 -07:00
Matt Nadareski
e83190c091 Writeback for updated path values (#111) 2018-08-17 20:22:08 -07:00
Matt Nadareski
82eabc12ca Try to fix output path checks (fixes #111) 2018-08-17 20:16:13 -07:00
Matt Nadareski
76b549d773 Add try/catch around dump (fixes #110) 2018-08-17 20:08:50 -07:00
Matt Nadareski
227688d7dc Fix PS2 VER spacing (fixes #112) 2018-08-17 19:24:55 -07:00
Matt Nadareski
4c9e2359af Update system info 2018-08-14 21:59:41 -07:00
Matt Nadareski
d179d7f464 Recognize new swap commands 2018-08-14 21:54:41 -07:00
Matt Nadareski
fff19e75fd Fix XBOX security sector format 2018-08-02 12:38:29 -07:00
Matt Nadareski
2175ccfb26 Update CHANGELIST 2018-07-29 12:44:46 -07:00
Matt Nadareski
621923bdba Add new Redump-recongized system 2018-07-24 19:27:45 -07:00
Matt Nadareski
3c216aa309 More accurate detection 2018-07-21 17:02:51 -07:00
Matt Nadareski
d85186e5cd Fix copy protection output again
This doesn't warrant a full PR
2018-07-19 23:40:17 -07:00
Matt Nadareski
1a94ad3d23 Don't try to get fancy 2018-07-19 15:34:16 -07:00
Matt Nadareski
91776d939c AppVeyor and Test (#103)
* Fixes to AppVeyor

* Fix tests
2018-07-19 15:31:25 -07:00
Matt Nadareski
3d058e633f Unblock and Update (#102)
* RAINBOW

* Add to FormatOutputData

* Update BurnOutSharp

* Fix parameter creation

* Minor improvements

* Update package versions
2018-07-19 14:11:58 -07:00
Matt Nadareski
94c0564fe8 Goodbye drive speed finders (#101)
* Goodbye drive speed finders

* More accurate scaling

* Ensure disposal
2018-07-17 16:42:38 -07:00
Matt Nadareski
87ecc7588e Update BurnOutSharp 2018-07-17 10:41:29 -07:00
Matt Nadareski
8a5c114a7e External and Fix (#100)
* Progress report updates log

* Logging additions

* Minor update

* Set halfway point only if nothing can be found

* Better population metrics

* QOL improvements

* More tiny logging updates

* Autoscroll

* Be consistent

* Update packages, use submodules

* Use NuGet

* Not 100% sure why I did it that way...

* Update README.md

* Make copy protect scan prompt an option

* Enhanced-CD might be Win/Mac

* Add unconfirmed formats

* Enhance!
2018-07-17 10:21:37 -07:00
ReignStumble
e307cb217f Fix DPI issue 2018-07-16 22:41:05 -04:00
Matt Nadareski
b8c56bea58 Whole Cleanup (#97)
* Cleanup TODOs

* Remove more TODOs

* Add case-insensitive dictionary for protection scans

* Namespace cleanups

* Space

* Minor fixes

* Oops

* Change layerbreak detect value
2018-07-15 22:26:22 -07:00
Matt Nadareski
564a6af9b8 Protection, Progress, and (Possibly) Empty Drives (#93)
* Include but mark inactive drives (fixes #87)

* Add more checks for the active flag

* Force users to choose on dump

* Fix quotes

* Update SolidShield 1

* Select first active by default

* Add TODO

* Add dumping progress indicator

* Clamp runtime

* Add first textfile scans; EA CdKey

* Slightly better executable detection

* Better file type detection

* Get as much into magic number checks as possible

* Nicer formatting

* Trailing slash

* Add back for benefit of the doubt

* Remove dead code

* Safer cabinet scanning

* Remove iXcomp; Add Unshield

* Fix build, add more comments

* Post-merge cleanup

* Add a new log line

* Make protection scan mechanics easier to see

* Add a space
2018-07-13 16:40:40 -07:00
Jacopo Santoni
5bcde889b3 Log Window enhancements (#95)
* 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 LogWindow and first tests of output gathering

* integrated all the proof of concept related to stream fetching of DIC output into LogWindow

* working on LogWindow\ncreated more efficient output matching management, improved handling of process termination

* 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

* fixes Dispatcher thread issue with progress bar

* 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

* merged conflicts

* moved log window

* working on LogWindow resize/location behavior

* working on message logging in LogWindow

* added working integration between MenuItem for LogWindow and its visibility status, fixes issues with positioning and visibility, correctly bound Verbose flag to property

* finished integrating LogWindow, added some verbose logs

* added logs

* fixed include order

* added option to show log window at startup, removed useless QuietMode property from MainWindow

* added precise calculation of MainWindow position when LogWindow is shown and fixed topmost cheat
2018-07-13 16:38:50 -07:00
Jacopo Santoni
b39c96cdd2 Log Window (#94)
* 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 LogWindow and first tests of output gathering

* integrated all the proof of concept related to stream fetching of DIC output into LogWindow

* working on LogWindow\ncreated more efficient output matching management, improved handling of process termination

* 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

* fixes Dispatcher thread issue with progress bar

* 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

* merged conflicts

* moved log window

* working on LogWindow resize/location behavior

* working on message logging in LogWindow

* added working integration between MenuItem for LogWindow and its visibility status, fixes issues with positioning and visibility, correctly bound Verbose flag to property

* finished integrating LogWindow, added some verbose logs

* added logs

* fixed include order

* added option to show log window at startup, removed useless QuietMode property from MainWindow
2018-07-13 15:48:35 -07:00
Matt Nadareski
2cc73a30f5 Protection Is Key (#92)
* Fix some protections, start adding IS scanning

* Fix IS CAB

* Update TODO
2018-07-10 10:23:52 -07:00
Matt Nadareski
be7d745d10 Create Parameters Class (#91)
* Update commented code

* Add Parameters class

This class is currently unused, but represents a set of parameters that can be passed to and from any given method. It has some copied/modified code from Validators.cs, for the time being due to the current overlap.

* Add better documentation

* Add and use DICFlag enumeration

* Port more things to Parameter-specific version

* Add commented code for later

* Added new options (#90)

* 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 4 new options: quiet mode, paranoid mode, disable media type detect and c2 reread amount

* added default C2 reread tries to config

* fixed issues for PR

* removed commented leftover

* Update commented code

* Add Parameters class

This class is currently unused, but represents a set of parameters that can be passed to and from any given method. It has some copied/modified code from Validators.cs, for the time being due to the current overlap.

* Add better documentation

* Add and use DICFlag enumeration

* Port more things to Parameter-specific version

* Add commented code for later

* Use Parameters object

* Fix dumping process

* Cleanup Validators
2018-07-09 21:42:02 -07:00
Jacopo Santoni
d51adccab4 Added new options (#90)
* 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 4 new options: quiet mode, paranoid mode, disable media type detect and c2 reread amount

* added default C2 reread tries to config

* fixed issues for PR

* removed commented leftover
2018-07-09 16:35:46 -07:00
Matt Nadareski
6141ce8539 Remove Disable Beep; Handle Error Case (#89)
* Disable beep not supported for these

* Remove testing code

This more or less ensures that the current run finishes properly

* Extra fixing for process issues

This, with the last 2 commits, make it so that geting disc speed works again. This was only found because in testing, many MANY instances of DiscImageCreator were made but never killed, polluting the process list. These issues should now be fixed.
2018-07-07 01:00:27 -07:00
Matt Nadareski
96d6e8bd2f Bits and Bobs (#88)
* Finally overhaul UI element naming

* Re-enable disk scan button

* Add cabfile scanning

* Fix csproj

* Fix TODO

* Add a couple more protections, disable one for now

* Fix SecuROM 7 detection

Thanks antimatter for helping test

* No beep for eject and speed check

* Fix Options after renames

* Ensure disc information in  couple places again
2018-07-07 00:08:22 -07:00
Matt Nadareski
c034df4266 More and more cleanup (#86)
* Namespace cleanups

* Make dump validation instanced

* Add note to Tasks

* Move stuff to DumpEnvironment

Most of the stuff in Tasks.cs acted on a single input parameter, namely a DumpEnvironment. Since that's the case, it was more logical to wrap those into DumpEnvironment and make them instance methods rather than keep them static. Due to this change, quite a few methods changed access, and some had to be marked internal due to wanting them to be tested separately.

* Gut Tasks

* One less thing in MainWindow

* Remove explicit cast

* Wrong check

* Create helper method

* Disable scan button on dump

* Remove unnecessary getters/setters

* Method name/description cleanup

* Address TODO

* Namespace cleanups

* Make dump validation instanced

* Add note to Tasks

* Move stuff to DumpEnvironment

Most of the stuff in Tasks.cs acted on a single input parameter, namely a DumpEnvironment. Since that's the case, it was more logical to wrap those into DumpEnvironment and make them instance methods rather than keep them static. Due to this change, quite a few methods changed access, and some had to be marked internal due to wanting them to be tested separately.

* Gut Tasks

* One less thing in MainWindow

* Remove explicit cast

* Wrong check

* Create helper method

* Disable scan button on dump

* Remove unnecessary getters/setters

* Method name/description cleanup

* Address TODO

* Clean up OnContentRendered

* Namespace cleanups

* Make dump validation instanced

* Add note to Tasks

* Move stuff to DumpEnvironment

Most of the stuff in Tasks.cs acted on a single input parameter, namely a DumpEnvironment. Since that's the case, it was more logical to wrap those into DumpEnvironment and make them instance methods rather than keep them static. Due to this change, quite a few methods changed access, and some had to be marked internal due to wanting them to be tested separately.

* Gut Tasks

* One less thing in MainWindow

* Remove explicit cast

* Wrong check

* Create helper method

* Disable scan button on dump

* Remove unnecessary getters/setters

* Method name/description cleanup

* Address TODO

* Clean up OnContentRendered

* Update event handlers
2018-07-05 21:34:04 -07:00
ReignStumble
fe04c6df73 Centered Window + No more resizable 2018-07-06 00:11:11 -04:00
ReignStumble
aff195eb71 Added Exit and About 2018-07-06 00:08:20 -04:00
ReignStumble
3aca999b63 New Menubar 2018-07-06 00:00:16 -04:00
ReignStumble
0e7ce76f01 Wait for UI to render before Populating 2018-07-05 23:43:01 -04:00
Matt Nadareski
6d72417512 Cleanups and mixups (#85)
Cleanups and Mixups
2018-07-05 16:52:34 -07:00
Matt Nadareski
ac89f06843 Separate out from Constants.cs 2018-07-05 13:33:08 -07:00
Matt Nadareski
39ce56d579 Post-merge cleanup 2018-07-05 13:18:01 -07:00
Matt Nadareski
9dbd30adba Merge DumpEnvironment/DumpInformation; Add Copy Protection Scan (#82)
* Merge DumpEnvironment and DumpInformation

* None of these need to be static

* Start adding protection checks

* Convert all BurnOut-related files from VB

* Placeholders for SafeDisc 3 and 4

* Fix some small things

* SubIntention not always output

* Make copy protect scan optional

* Try/catch on disc information to avoid crashes

* Add placeholders for Origin, Steam, UPlay

* Don't use copied method, for safety

* Protection cleanup

* More cleanup on SafeDisc v1/2

* Add area for cabfiles (for later); clean up more protections

* Comment out cabfile path, for now

* Underscores? Really?

* Namespace cleanup

* More Steam variations

* Add an actual UPlay installer name

* Skeleton for GFWL

* Add one for Origin

* More Steam, update note

* Add note kinda like GFWL

* Fix Origin installer name (IDK what I put there before...)

* Remove TODOs for ones with valid checks

* Add first GFWL installer name

* Move online services to last

Physical disc protections should ALWAYS come before an online service is mentioned. This makes sure that the physical media's information is not lost

* Add another TODO

* ...slightly longer comment

* Fix CDCops, start adding file lists

* More paths

* Even more paths

* Last paths for now

* Dictionary is smarter... so more work ahead

* Remind me why I'm doing this?

* Okay, recreated in dictionary now

* Reorganiation

* Alphabetization is fun

* Add unused call to new scan path

* Add TODO

* Remove TODO

* Remove TODO, comment out dummy files check

* Better state for no detected protection

* Make copy protect scan a Task so it can be used elsehwere later

* ScanEx -> Scan; cleanup

* Remove unused protection scan methods

These methods used to be a simple check for if a particular file existed. These are now captured in the "CreateProtectionMapping" dictionary

* Remove SuffixInStr

* Characters to literals, decimal to hex, start of consolidation

* Add remaining string-only mappings, cleanup

* Update summaries, remove unused flag

* Trim out unnecessary variables

These variables used to be used when a DLL or an EXE was found to have something in it but other files were needed to check against for better output. This also assumed a monolithic output in what protections were found. Now that we just list everything and all files are scanned, this should catch everything that comes through

* Remove unused path-based protections

* Accidentally wiped out Sysiphus

* CD Check is... special

* No more internal vars; static shock

* Add region tags

* Remove unused Dummy Files check

* Add scan for copy protection without dump

* Better checking of files

* Better message box

* Add TODO

* Clearer language for SafeDisc

* Fix SafeDisc scanning

Thanks to eientei95 for helping find this one

* Slight EVORE cleanup

* Fix SolidShield

Thanks to eientei95 for helping to fix this one

* Add sector scan note

* Add user-requested TODO

* Refactor of ComboBox underlying types (#84)

* 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

* Refactored KnownSystem combobox management

- created KnownSystemComboBoxItem to manage both header and system items
- totally rewrote KnownSystem category (through KnownSystemCategory enum and markers)
- fixed null access in EnsureDiscInformation caused by null _drives
- rewrote cmb_SystemType management to use new classes

* - created Drive class to keep drive letters, volume label and is floppy flag altogether
- changed all the code to use the new Drive class in combobox and in DumpEnvironment

* fixed retrieval of value from cmb_KnownSystem combobox

* removed OrderedDictionary, not needed anymore

* Merge DumpEnvironment and DumpInformation

* None of these need to be static

* Start adding protection checks

* Convert all BurnOut-related files from VB

* Placeholders for SafeDisc 3 and 4

* Fix some small things

* SubIntention not always output

* Make copy protect scan optional

* Try/catch on disc information to avoid crashes

* Add placeholders for Origin, Steam, UPlay

* Don't use copied method, for safety

* Protection cleanup

* More cleanup on SafeDisc v1/2

* Add area for cabfiles (for later); clean up more protections

* Comment out cabfile path, for now

* Underscores? Really?

* Namespace cleanup

* More Steam variations

* Add an actual UPlay installer name

* Skeleton for GFWL

* Add one for Origin

* More Steam, update note

* Add note kinda like GFWL

* Fix Origin installer name (IDK what I put there before...)

* Remove TODOs for ones with valid checks

* Add first GFWL installer name

* Move online services to last

Physical disc protections should ALWAYS come before an online service is mentioned. This makes sure that the physical media's information is not lost

* Add another TODO

* ...slightly longer comment

* Fix CDCops, start adding file lists

* More paths

* Even more paths

* Last paths for now

* Dictionary is smarter... so more work ahead

* Remind me why I'm doing this?

* Okay, recreated in dictionary now

* Reorganiation

* Alphabetization is fun

* Add unused call to new scan path

* Add TODO

* Remove TODO

* Remove TODO, comment out dummy files check

* Better state for no detected protection

* Make copy protect scan a Task so it can be used elsehwere later

* ScanEx -> Scan; cleanup

* Remove unused protection scan methods

These methods used to be a simple check for if a particular file existed. These are now captured in the "CreateProtectionMapping" dictionary

* Remove SuffixInStr

* Characters to literals, decimal to hex, start of consolidation

* Add remaining string-only mappings, cleanup

* Update summaries, remove unused flag

* Trim out unnecessary variables

These variables used to be used when a DLL or an EXE was found to have something in it but other files were needed to check against for better output. This also assumed a monolithic output in what protections were found. Now that we just list everything and all files are scanned, this should catch everything that comes through

* Remove unused path-based protections

* Accidentally wiped out Sysiphus

* CD Check is... special

* No more internal vars; static shock

* Add region tags

* Remove unused Dummy Files check

* Add scan for copy protection without dump

* Better checking of files

* Better message box

* Add TODO

* Clearer language for SafeDisc

* Fix SafeDisc scanning

Thanks to eientei95 for helping find this one

* Slight EVORE cleanup

* Fix SolidShield

Thanks to eientei95 for helping to fix this one

* Add sector scan note

* Add user-requested TODO
2018-07-05 12:58:20 -07:00
Jacopo Santoni
48de63513e Refactor of ComboBox underlying types (#84)
* 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

* Refactored KnownSystem combobox management

- created KnownSystemComboBoxItem to manage both header and system items
- totally rewrote KnownSystem category (through KnownSystemCategory enum and markers)
- fixed null access in EnsureDiscInformation caused by null _drives
- rewrote cmb_SystemType management to use new classes

* - created Drive class to keep drive letters, volume label and is floppy flag altogether
- changed all the code to use the new Drive class in combobox and in DumpEnvironment

* fixed retrieval of value from cmb_KnownSystem combobox

* removed OrderedDictionary, not needed anymore
2018-07-05 11:30:52 -07:00
Matt Nadareski
56eaf7c2c5 Add Test Project (#79)
* Add Test project; Migrate so there's not an external folder

* Add Test project; Migrate so that there's not an external folder

* Fix build; Add remaining test classes (skeletons)

* Fix more paths

* Make unit tests runnable, fix issue found by unit tests

* Add more tests, fix more things found by tests

* Add skeleton for ValidatorsTest, fix OrderedDictionary

* Add UIElementsTest

* Add new test classes, slightly update Result

* Implement DumpEnvirionment tests; fix minor things from testing

* Add Tasks testing skeletons; Reorder methods and change access modifiers for some

* Update notes for DumpInformation tests

* Implement a couple Validators tests; fix ValidateParameters

* Implement DetermineFlagsTest

* Make one test more readable

* More cleanup around ValidateParameters

* Split check

* WiiU is not supported by /raw command

* Add TODO question

* Update TODO with a plan
2018-06-28 19:41:18 -07:00
Matt Nadareski
c1bd30e008 Streamline Callbacks and Ensure MediaType (#78)
* Separate drive speeds; better ensuring of media type

This is the first attempt at separating out the drive speeds into separate categories. At the moment, it seems to be working just fine for CD and DVD.
This also includes some updated code to better ensure that the detected (or selected if the user has changed it) media type is kept between all of the regular changes

* Multiple medium

* Add more drive speed prototyping

* Strip out redundant calls

* Separate drive speeds; better ensuring of media type

This is the first attempt at separating out the drive speeds into separate categories. At the moment, it seems to be working just fine for CD and DVD.
This also includes some updated code to better ensure that the detected (or selected if the user has changed it) media type is kept between all of the regular changes

* Multiple medium

* Add more drive speed prototyping

* Strip out redundant calls

* Streamline merge

* Comment patrol; keep BluRay a first-class citizen

* HD-DVD is supported?!
2018-06-27 23:21:52 -07:00
Jacopo Santoni
4176f22d79 Added preferred dump speed option (#77)
* 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 max dump speed option
- added slider element into OptionsWindow
- moved drive speeds to UIElements from MainWindow
- added setting to Options which is saved

still need to understand how to manage DVD/CD-ROM different speeds

* kept working on max dump speed settings

- rewrote max speed list management in Options
- added second slider in OptionsWindow
- added callback from OptionsWindow to MainWindow on updated options

* final tweaks before PR

* renamed maxDumpSpeed to preferredDumpSpeed

* restored SetCurrentDiscType functionality

* fixes for PR

* fixes for PR
2018-06-27 20:06:19 -07:00
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
Matt Nadareski
61ce45667b Update for 1.06 2018-06-15 20:27:34 -07:00
Matt Nadareski
ababfdd2ed XBOX/360 Fixes (#50)
* Better creation of parameters (fixes Xbox/360)

* Split X360 into XDG2/3

* Don't enable drive speed if we're not supposed to

* Add first attempt at Xbox info extraction

* Trim or it never matches
2018-06-15 20:24:43 -07:00
Matt Nadareski
9683074197 Only eject when told 2018-06-14 20:18:01 -07:00
Matt Nadareski
ab2bc8f50c Worst typo ever 2018-06-14 20:11:49 -07:00
reignstumble
aa86ddaf47 Fix incorrectly enabled button 2018-06-14 20:40:41 -04:00
Matt Nadareski
68afebace4 Update for 1.05a 2018-06-14 16:37:43 -07:00
Matt Nadareski
bebe3ab8a0 Add specialty checking for PS1, PS2, and Saturn (#47)
* Setup upcoming work

* Add EXE date checking for PS1/PS2

* Add PS2 version checking

* Add Saturn header reading, fix validation again

* Get all Saturn build info
2018-06-14 16:33:40 -07:00
Matt Nadareski
1f314df8c1 Update for 1.05 2018-06-14 14:14:25 -07:00
Matt Nadareski
38c3638f21 Update Commands for new DIC Version (#46)
* Split constants further

* Fix TODOs in the dump information

* Add TODO for sg-raw

* Use DIC flags, add XBOX command

* Add .dat output for floppy disks, add note

* Better custom parameter checking

* Remove postfix from commands, add /74 flag

* Update DIC flag constant names

* Add descripion for Template constants

* Add description for UIElements

* New utilities namespace

* Add XBOX-specific information

* Add more disc-based arcade systems

* Add special check for PSX discs
2018-06-14 14:06:10 -07:00
Matt Nadareski
cde4b671fc Parameter Checking updates (#44)
* Fix custom parameter parsing, rename to just "parameters"

* Consolodate and fix param checking code
2018-06-13 22:15:53 -07:00
Matt Nadareski
578854cd3b Fixes and Floppies (#43)
* Fix button appearance on Settings window

* Add notes for floppy dumping later

* Support floppy disk reading (fixes #12)
2018-06-13 20:14:25 -07:00
Matt Nadareski
1cd7885194 More fixes (#42)
* Make custom parameters react to filename/directory changes

* Add subdump for Saturn (fixes #20)

* Add disc eject, fix minor issue (fixes #17)

* Fix spacing issue
2018-06-13 18:02:45 -07:00
Matt Nadareski
c0de39c229 Miscellaneous Fixes (#41)
* Make error count more accurate

* Extract dump information to separate file

* Remove TODO

* Add subIntention field check to other formats

* Correct Wii and WiiU disc types

* Nuon correction (hard to base on the limited releases)

* Update Sega Lindbergh

* Add two Sega arcade platforms

* Clearer TODO

* Validate "swap" command

* Remove hanging comma from TODO

* Remove TODO
This one I'm removing because technically, the "gd" command is the correct way of dumping via DIC. The "swap" command is a stopgap for drives that only support GD-ROM dumping via hacked TOC discs
2018-06-13 17:07:55 -07:00
Matt Nadareski
a1148f80c8 Updated for 1.04b 2018-06-13 16:11:22 -07:00
Matt Nadareski
632654d00b Fix "Custom Input" not working 2018-06-13 16:09:11 -07:00
Matt Nadareski
a6d6b800a5 Fix order of operations and extra extension 2018-06-13 16:06:18 -07:00
Matt Nadareski
8527cc5746 Add SubIntention (SecuROM) field (#40)
* Add SubIntention (SecuROM) field

* Fix issue with internationalization
2018-06-13 15:56:38 -07:00
Matt Nadareski
f94f54f4d7 Update for 1.04a 2018-06-13 14:55:08 -07:00
Matt Nadareski
2091ef1d92 Add properties dialog (#39) 2018-06-13 14:52:13 -07:00
Matt Nadareski
af865bca9e Fix case where empty tray causes a crash (#38) 2018-06-13 14:49:26 -07:00
Matt Nadareski
23588fa5ae Merge branch 'master' of https://github.com/reignstumble/DICUI 2018-06-13 12:38:25 -07:00
Matt Nadareski
e763fec01e Update README for 1.04 (#37)
Update README for 1.04
2018-06-13 12:27:42 -07:00
Matt Nadareski
732ff2ccca Update README for 1.04 2018-06-13 12:26:57 -07:00
Matt Nadareski
f960aca8a9 Populate drive speed (#35) (#1) (#36)
* Allow child process to be killed (#10)

* Add constants, use them, use child process more

* Try to automatically populate the drive speed
2018-06-13 12:23:35 -07:00
Matt Nadareski
335c1388d4 Merge branch 'master' of https://github.com/mnadareski/DICUI 2018-06-13 12:22:40 -07:00
Matt Nadareski
87c0d5b44b Populate drive speed (#35) (#1)
* Allow child process to be killed (#10)

* Add constants, use them, use child process more

* Try to automatically populate the drive speed
2018-06-13 12:20:24 -07:00
Matt Nadareski
1a44fb5c8a Merge branch 'master' into master 2018-06-13 12:20:14 -07:00
Matt Nadareski
285921cae3 Fix getting speed on changed drive letter 2018-06-13 12:18:06 -07:00
Matt Nadareski
2255dba640 Populate drive speed (#35)
* Allow child process to be killed (#10)

* Add constants, use them, use child process more

* Try to automatically populate the drive speed
2018-06-13 11:57:10 -07:00
Matt Nadareski
99158f31c9 Merge branch 'master' into master 2018-06-13 11:56:30 -07:00
Matt Nadareski
53a2ef227b Try to automatically populate the drive speed 2018-06-13 11:51:21 -07:00
Matt Nadareski
c0efc63741 Allow child process to be killed (#10) (#34)
* Allow child process to be killed (#10)

* Add constants, use them, use child process more
2018-06-13 11:31:19 -07:00
Matt Nadareski
905bd1a7dc Add constants, use them, use child process more 2018-06-13 11:30:33 -07:00
Matt Nadareski
5d49d4833f Allow child process to be killed (#10) 2018-06-13 11:26:40 -07:00
Matt Nadareski
8fd3e2d405 Merge pull request #33 from mnadareski/master
Split constants
2018-06-13 11:11:41 -07:00
Matt Nadareski
1521a918f3 Split constants 2018-06-13 10:39:03 -07:00
Matt Nadareski
5f580ee025 Merge pull request #32 from mnadareski/master
Enable validation of DIC parameters
2018-06-13 00:03:34 -07:00
Matt Nadareski
9c7cee0aa3 Fix validation, hook up to main dumping, fix dumping 2018-06-12 23:41:11 -07:00
Matt Nadareski
d549609a0f Add as many validations as humanly possible 2018-06-12 22:30:14 -07:00
Matt Nadareski
207fdbb49c Start adding validation to DIC command line 2018-06-12 22:06:16 -07:00
Matt Nadareski
63e63a0033 Add DIC command constants 2018-06-12 22:05:50 -07:00
Matt Nadareski
73be55a645 Merge pull request #31 from mnadareski/master
Add verification for overwrite
2018-06-12 20:30:54 -07:00
Matt Nadareski
d913aa247e Re-enable button on error 2018-06-12 20:29:40 -07:00
Matt Nadareski
d9a9f3bfd4 Add verification for overwrite 2018-06-12 20:22:49 -07:00
reignstumble
ea3e040b3f Merge pull request #29 from mnadareski/master
Add Custom Parameter Support
2018-06-12 20:47:54 -04:00
Matt Nadareski
ed67522675 Add custom parameter support 2018-06-12 16:49:33 -07:00
reignstumble
6e3902bbb1 Update README.md 2018-06-12 19:02:59 -04:00
Matt Nadareski
3f802e8548 Consistent UI states 2018-06-12 15:15:41 -07:00
reignstumble
c3c4cf6e5b Merge pull request #28 from mnadareski/master
Minor fixes
2018-06-12 17:43:33 -04:00
Matt Nadareski
39258c4e85 Use subfolder for indivdual dumps, change filename 2018-06-12 14:16:16 -07:00
Matt Nadareski
df81259fba Address feedback 2018-06-12 14:10:10 -07:00
reignstumble
a835c81951 Merge pull request #27 from mnadareski/master
Write Centralized Disc Information
2018-06-12 17:03:43 -04:00
Matt Nadareski
af4f3e8444 Add better default values, fix output 2018-06-12 13:48:30 -07:00
Matt Nadareski
085916e1e6 Fix minor issues with output, ordering 2018-06-12 13:34:25 -07:00
Matt Nadareski
557354c844 Fix build 2018-06-12 12:30:29 -07:00
Matt Nadareski
a23a74ffa4 Attempt to write out all information 2018-06-12 12:23:04 -07:00
Matt Nadareski
958aeeae32 Add constants, create formatted output 2018-06-12 11:39:10 -07:00
reignstumble
c73ff42500 Merge pull request #26 from mnadareski/master
Disc Information Framework
2018-06-12 09:38:11 -04:00
Matt Nadareski
24a93e298b Remove last batchfile 2018-06-12 01:03:10 -07:00
Matt Nadareski
ae81bb0743 Move unused code due to future dependencies 2018-06-12 00:40:41 -07:00
Matt Nadareski
cf7863fbb2 Add some system specific values, notes 2018-06-12 00:34:00 -07:00
Matt Nadareski
5e0e71120d Add layerbreak disc info for relevant discs 2018-06-12 00:06:30 -07:00
Matt Nadareski
5adbdd29e6 Add all CD-ROM info getters 2018-06-12 00:00:27 -07:00
Matt Nadareski
fd855b9024 More clariication of template, fix .dat reading 2018-06-11 23:43:38 -07:00
Matt Nadareski
17c283ff67 Add a couple more info grabbers 2018-06-11 22:07:42 -07:00
Matt Nadareski
a37e6aaf18 Add first two info extraction helpers 2018-06-11 21:51:35 -07:00
Matt Nadareski
1dbf23ca95 Add first iteration of getting output information (incomplete) 2018-06-11 21:23:32 -07:00
Matt Nadareski
2e52d00107 Add TODO 2018-06-11 21:02:39 -07:00
Matt Nadareski
eb69b74b4a Add check to ensure all output files are found 2018-06-11 21:01:50 -07:00
Matt Nadareski
db4a785558 Use path combination 2018-06-11 20:40:20 -07:00
Matt Nadareski
9bdd2d6951 First use of finding the first track 2018-06-11 20:37:44 -07:00
Matt Nadareski
de48c8f0f9 Add method to find the first (only) track of a dump 2018-06-11 20:32:04 -07:00
reignstumble
c59f7c2dae Merge pull request #25 from mnadareski/master
Cleanup/Automation
2018-06-11 23:12:49 -04:00
Matt Nadareski
2740a6a1c1 Don't blindly start processes 2018-06-11 00:14:37 -07:00
Matt Nadareski
56e8470069 Add note regarding issues/12 2018-06-10 23:57:26 -07:00
Matt Nadareski
a5f1a12aee Error checking and don't include speed in bd command 2018-06-10 23:35:25 -07:00
Matt Nadareski
8749b486a8 Separate paths to be configurable in future 2018-06-10 16:43:46 -07:00
Matt Nadareski
3446957f68 Better output names, misc cleanup 2018-06-10 16:37:05 -07:00
Matt Nadareski
cb9813db3d Spaces 2018-06-10 16:17:06 -07:00
Matt Nadareski
6e6b716c18 Remove all debug console writes 2018-06-10 16:16:47 -07:00
Matt Nadareski
400ef38c60 Make sure events don't have anything but calling a helper in them 2018-06-10 16:14:17 -07:00
Matt Nadareski
87d5fc0e66 More reasonable default drive speed 2018-06-10 16:10:09 -07:00
Matt Nadareski
d5d8ae0501 Fix build 2018-06-10 16:08:19 -07:00
Matt Nadareski
fae7a5254d Remove unnecessary event 2018-06-10 16:07:14 -07:00
Matt Nadareski
97be13f020 Make code more well-ordered, add default list of all drive speeds supported, privatize EVERYTHING 2018-06-10 16:06:20 -07:00
Matt Nadareski
dd0dfc5cf5 Move drive scanning to Utilities 2018-06-10 16:05:25 -07:00
Matt Nadareski
a7a295434d Simplification of rows, some renames 2018-06-10 16:04:58 -07:00
Matt Nadareski
319f5563cb More descriptive process names 2018-06-10 15:13:16 -07:00
Matt Nadareski
939174d8c4 Merge branch 'master' of https://github.com/mnadareski/DICUI 2018-06-10 15:11:30 -07:00
Matt Nadareski
1d5d7b265e Remove one unnecessary batch file creation step 2018-06-10 15:11:25 -07:00
Matt Nadareski
a2ac7222f9 Remove extra ECC check from PS1 2018-06-10 15:07:28 -07:00
reignstumble
4f0b5904c3 Merge pull request #24 from mnadareski/master
Add Enumerations; Helper Methods
2018-06-09 14:54:59 -04:00
Matt Nadareski
7ff848347c Merge branch 'master' into master 2018-06-08 16:24:11 -07:00
Matt Nadareski
a1c89d17b8 How did I miss this? 2018-06-08 16:16:50 -07:00
Matt Nadareski
3575c43703 Missed this one 2018-06-08 16:14:19 -07:00
Matt Nadareski
928c9966fa Cleanup, make some things work more intended 2018-06-08 16:12:46 -07:00
Matt Nadareski
a404a270f1 Make combobox entirely auto-generated 2018-06-08 15:54:23 -07:00
Matt Nadareski
dfba97685a Fix minor formatting issues 2018-06-08 15:15:47 -07:00
Matt Nadareski
8de2f1c9bb Add helper function to make list of systems 2018-06-08 14:55:17 -07:00
Matt Nadareski
f57b29615b Add other string conversion, update comments 2018-06-08 14:37:17 -07:00
reignstumble
565a9bb09a Update README.md 2018-06-08 17:20:33 -04:00
Matt Nadareski
d9d61cf665 Fix build 2018-06-08 14:15:05 -07:00
Matt Nadareski
8b600a6a35 Add enumerations and unused methods 2018-06-08 14:05:06 -07:00
61 changed files with 14156 additions and 979 deletions

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="DICUI.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<userSettings>
<DICUI.Properties.Settings>
<setting name="
" serializeAs="String">
<value>Release_ANSI\\DiscImageCreator.exe</value>
</setting>
</DICUI.Properties.Settings>
</userSettings>
</configuration>

View File

@@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace DICUI
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}

142
CHANGELIST.md Normal file
View File

@@ -0,0 +1,142 @@
### 1.15 (2019-11-16)
- Updated to DIC version 20191116
- Support non-optical, non-floppy stuff better
- Update protection scanning and fix some things
### 1.14 (2019-10-01)
- Updated to DIC version 20191001
- Added builds for .NET 4.6.2, .NET 4.7.2, and .NET Core 3.0
- Updated and fixed a bunch of things related to Redump
- Fixed path persistence when changing system and media type
- Added more system autodetects
- Added new, optional, disc information filling window (WIP)
### 1.13 (2019-07-02)
- Added new DIC commands and flags
- Made DICUI Check more robust
- Added and updated systems along with format cleanup
- Created a new SubmissionInfo template (and internals)
- Added automatic grabbing of Redump information, if possible
- Better media format support (BD, UMD)
- Initial disc type detection
### 1.12.2 (2019-04-19)
- Added DICUI Check, a new standalone tool for parsing DIC output from platforms unsupported by DICUI
- Added a few machines/formats
- Updated to DIC version 20190326
- Added DMI data extraction for Xbox and X360
### 1.12.1 (2019-01-28)
- Fixed !submissionInfo.txt output for CD-ROM and GD-ROM
### 1.12 (2019-01-27)
- Added a few new systems and formats
- Added new DIC commands and flags
- Updated the `!submissionInfo.txt` file order
- Fixed Audio CD handling
- Added Sega CD / Mega CD header extraction
- Readded Floppy Disk as a supported format
- And more! See the full Git commit list for more details
### 1.11 (2018-09-20)
- Fix formatting of XBOX and XBOX 360 security sector output
- Add new XBOX swap commands and outputs
- Fixes for some PlayStation 2 and 4 outputs
- Added external programs to AppVeyor builds
- Fixed `.` in path issues with DIC; attempted to fix issues with `&`
- Combined XBOX 360 XGD 2/3 due to new DIC support with Kreon drives
- Fixed (semi-)longstanding bug with XBOX disc layer detection
- Added DVD-Video protection output
- Made custom parameters work a little more intuitively
- Added *EXPERIMENTAL* Winforms-based UI
- And more! See the full Git commit list for more details
### 1.10 (2018-07-29)
- Added many new options for user customization
- Added unit testing and an AppVeyor build
- Many code refactorings
- **LOG WINDOW**
- Separated out protection scan and Unshield ports to new projects
- Added "empty drive" support; should help with 3DO and HFS dumping
- And much more! See the full Git commit list for more details
### 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.

6
DICUI.Check/App.config Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/>
</startup>
</configuration>

View File

@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net462;net472;netcoreapp3.0</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<OutputType>Exe</OutputType>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DICUI.Library\DICUI.Library.csproj">
<Project>{51ab0928-13f9-44bf-a407-b6957a43a056}</Project>
<Name>DICUI.Library</Name>
</ProjectReference>
</ItemGroup>
</Project>

180
DICUI.Check/Program.cs Normal file
View File

@@ -0,0 +1,180 @@
using System;
using System.IO;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI.Check
{
public class Program
{
public static void Main(string[] args)
{
// Help options
if (args.Length == 0
|| args[0] == "/h" || args[0] == "/?"
|| args[0] == "-h" || args[0] == "-?")
{
DisplayHelp();
return;
}
// List options
if (args[0] == "/lm" || args[0] == "/listmedia"
|| args[0] == "-lm" || args[0] == "--listmedia")
{
ListMediaTypes();
Console.ReadLine();
return;
}
else if (args[0] == "/ls" || args[0] == "/listsystems"
|| args[0] == "-ls" || args[0] == "--listsystems")
{
ListKnownSystems();
Console.ReadLine();
return;
}
// Normal operation check
if (args.Length < 3)
{
DisplayHelp("Invalid number of arguments");
return;
}
// Check the MediaType
var mediaType = Converters.StringToMediaType(args[0].Trim('"'));
if (mediaType == MediaType.NONE)
{
DisplayHelp($"{args[0]} is not a recognized media type");
return;
}
// Check the KnownSystem
var knownSystem = Converters.StringToKnownSystem(args[1].Trim('"'));
if (knownSystem == KnownSystem.NONE)
{
DisplayHelp($"{args[1]} is not a recognized system");
return;
}
// Check for Redump login credentials
string username = null, password = null;
int startIndex = 2;
if (args[2] == "-c" || args[2] == "--credentials")
{
username = args[3];
password = args[4];
startIndex = 5;
}
// Make a new Progress object
var progress = new Progress<Result>();
progress.ProgressChanged += ProgressUpdated;
// Loop through all the rest of the args
for (int i = startIndex; i < args.Length; i++)
{
// Check for a file
if (!File.Exists(args[i]))
{
DisplayHelp($"{args[i]} does not exist");
return;
}
// Get the full file path
string filepath = Path.GetFullPath(args[i]);
// Now populate an environment
var env = new DumpEnvironment
{
OutputDirectory = "",
OutputFilename = filepath,
System = knownSystem,
Type = mediaType,
ScanForProtection = false,
PromptForDiscInformation = false,
Username = username,
Password = password,
};
env.FixOutputPaths();
// Finally, attempt to do the output dance
var result = env.VerifyAndSaveDumpOutput(progress);
Console.WriteLine(result.Message);
}
}
/// <summary>
/// Display help for DICUI.Check
/// </summary>
/// <param name="error">Error string to prefix the help text with</param>
private static void DisplayHelp(string error = null)
{
if (error != null)
Console.WriteLine(error);
Console.WriteLine("Usage:");
Console.WriteLine("DICUI.Check.exe <mediatype> <system> [-c username password] </path/to/output.bin> ...");
Console.WriteLine();
Console.WriteLine(@"Common Media Types:\r\n
bd / bluray - BD-ROM
cd / cdrom - CD-ROM
dvd - DVD-ROM
fd / floppy - Floppy Disk
gd / gdrom - GD-ROM
umd - UMD");
Console.WriteLine("Run 'DICUI.Check.exe [-lm|--listmedia' for more options");
Console.WriteLine();
Console.WriteLine(@"Common Systems:\r\n
apple / mac - Apple Macintosh
cdi - Philips CD-i
ibm / ibmpc - IBM PC Compatible
psx / ps1 - Sony PlayStation
ps2 - Sony PlayStation 2
psp - Sony PlayStation Portable
saturn - Sega Saturn
xbox - Microsoft XBOX
x360 - Microsoft XBOX 360");
Console.WriteLine("Run 'DICUI.Check.exe [-ls|--listsystems' for more options");
}
/// <summary>
/// List all media types with their short usable names
/// </summary>
private static void ListMediaTypes()
{
Console.WriteLine("Supported Media Types:");
foreach (var val in Enum.GetValues(typeof(MediaType)))
{
if (((MediaType)val) == MediaType.NONE)
continue;
Console.WriteLine($"{((MediaType?)val).ShortName()} - {((MediaType?)val).LongName()}");
}
}
/// <summary>
/// List all known systems with their short usable names
/// </summary>
private static void ListKnownSystems()
{
Console.WriteLine("Supported Known Systems:");
foreach (var val in Enum.GetValues(typeof(KnownSystem)))
{
if (((KnownSystem)val) == KnownSystem.NONE)
continue;
Console.WriteLine($"{((KnownSystem?)val).ShortName()} - {((KnownSystem?)val).LongName()}");
}
}
/// <summary>
/// Simple process counter to write to console
/// </summary>
private static void ProgressUpdated(object sender, Result value)
{
Console.WriteLine(value.Message);
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DICUI.Check")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DICUI.Check")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("8cfde289-e171-4d49-a40d-5293265c1253")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,40 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net462;net472;netcoreapp3.0</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<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>
<ItemGroup>
<PackageReference Include="BurnOutSharp" Version="1.3.8.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="System.Management" Version="4.6.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Management" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,133 @@
namespace DICUI.Data
{
/// <summary>
/// Top-level commands for DiscImageCreator
/// </summary>
public static class DICCommandStrings
{
public const string Audio = "audio";
public const string BluRay = "bd";
public const string Close = "close";
public const string CompactDisc = "cd";
public const string Data = "data";
public const string DigitalVideoDisc = "dvd";
public const string Disk = "disk";
public const string DriveSpeed = "ls";
public const string Eject = "eject";
public const string Floppy = "fd";
public const string GDROM = "gd";
public const string MDS = "mds";
public const string Merge = "merge";
public const string Reset = "reset";
public const string SACD = "sacd";
public const string Start = "start";
public const string Stop = "stop";
public const string Sub = "sub";
public const string Swap = "swap";
public const string XBOX = "xbox";
public const string XBOXSwap = "xboxswap";
public const string XGD2Swap = "xgd2swap";
public const string XGD3Swap = "xgd3swap";
}
/// <summary>
/// Dumping flags for DiscImageCreator
/// </summary>
public static class DICFlagStrings
{
public const string AddOffset = "/a";
public const string AMSF = "/p";
public const string AtariJaguar = "/aj";
public const string BEOpcode = "/be";
public const string C2Opcode = "/c2";
public const string CopyrightManagementInformation = "/c";
public const string D8Opcode = "/d8";
public const string DisableBeep = "/q";
public const string ForceUnitAccess = "/f";
public const string MCN = "/m";
public const string MultiSession = "/ms";
public const string NoFixSubP = "/np";
public const string NoFixSubQ = "/nq";
public const string NoFixSubQLibCrypt = "/nl";
public const string NoFixSubRtoW = "/nr";
public const string NoFixSubQSecuROM = "/ns";
public const string NoSkipSS = "/nss";
public const string Raw = "/raw";
public const string Reverse = "/r";
public const string ScanAntiMod = "/am";
public const string ScanFileProtect = "/sf";
public const string ScanSectorProtect = "/ss";
public const string SeventyFour = "/74";
public const string SkipSector = "/sk";
public const string SubchannelReadLevel = "/s";
public const string VideoNow = "/vn";
public const string VideoNowColor = "/vnc";
}
/// <summary>
/// Template field values for submission info
/// </summary>
public static class Template
{
// Manual information
public const string TitleField = "Title";
public const string ForeignTitleField = "Foreign Title (Non-latin)";
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";
public const string PlaystationLanguageSelectionViaField = "Language Selection Via";
public const string DiscSerialField = "Disc Serial";
public const string BarcodeField = "Barcode";
public const string CommentsField = "Comments";
public const string ContentsField = "Contents";
public const string VersionField = "Version";
public const string EditionField = "Edition/Release";
public const string PlayStation3WiiDiscKeyField = "Disc Key";
public const string PlayStation3DiscIDField = "Disc ID";
public const string GameCubeWiiBCAField = "BCA";
public const string CopyProtectionField = "Copy Protection";
public const string MasteringRingField = "Mastering Code (laser branded/etched)";
public const string MasteringSIDField = "Mastering SID Code";
public const string MouldSIDField = "Mould SID Code";
public const string AdditionalMouldField = "Additional Mould";
public const string ToolstampField = "Toolstamp or Mastering Code (engraved/stamped)";
// Automatic Information
public const string PVDField = "Primary Volume Descriptor (PVD)";
public const string DATField = "DAT";
public const string SizeField = "Size";
public const string CRC32Field = "CRC32";
public const string MD5Field = "MD5";
public const string SHA1Field = "SHA1";
public const string MatchingIDsField = "Matching IDs";
public const string ErrorCountField = "Error Count";
public const string CuesheetField = "Cuesheet";
public const string SubIntentionField = "SubIntention Data (SecuROM/LibCrypt)";
public const string WriteOffsetField = "Write Offset";
public const string LayerbreakField = "Layerbreak";
public const string EXEDateBuildDate = "EXE/Build Date";
public const string HeaderField = "Header";
public const string PICField = "Permanent Information & Control (PIC)";
public const string PlayStationEDCField = "EDC";
public const string PlayStationAntiModchipField = "Anti-modchip";
public const string PlayStationLibCryptField = "LibCrypt";
public const string XBOXDMIHash = "DMI.bin Hashes";
public const string XBOXPFIHash = "PFI.bin Hashes";
public const string XBOXSSHash = "SS.bin Hashes";
public const string XBOXSSRanges = "Security Sector Ranges";
public const string XBOXSSVersion = "Security Sector Version";
// Default values
public const string RequiredValue = "(REQUIRED)";
public const string RequiredIfExistsValue = "(REQUIRED, IF EXISTS)";
public const string OptionalValue = "(OPTIONAL)";
public const string DiscNotDetected = "Disc Not Detected";
}
}

View File

@@ -0,0 +1,601 @@
namespace DICUI.Data
{
/// <summary>
/// Category for Redump
/// </summary>
public enum Category
{
Games = 1,
Demos = 2,
Video = 3,
Audio = 4,
Multimedia = 5,
Applications = 6,
Coverdiscs = 7,
Educational = 8,
BonusDiscs = 9,
Preproduction = 10,
AddOns = 11,
}
/// <summary>
/// Supported DIC commands
/// </summary>
public enum DICCommand
{
NONE = 0,
Audio,
BluRay,
Close,
CompactDisc,
Data,
DigitalVideoDisc,
Disk,
DriveSpeed,
Eject,
Floppy,
GDROM,
MDS,
Merge,
Reset,
SACD,
Start,
Stop,
Sub,
Swap,
XBOX,
XBOXSwap,
XGD2Swap,
XGD3Swap,
}
/// <summary>
/// Supported DIC flags
/// </summary>
public enum DICFlag
{
NONE = 0,
AddOffset,
AMSF,
AtariJaguar,
BEOpcode,
C2Opcode,
CopyrightManagementInformation,
D8Opcode,
DisableBeep,
ForceUnitAccess,
MCN,
MultiSession,
NoFixSubP,
NoFixSubQ,
NoFixSubQLibCrypt,
NoFixSubRtoW,
NoFixSubQSecuROM,
NoSkipSS,
Raw,
Reverse,
ScanAntiMod,
ScanFileProtect,
ScanSectorProtect,
SeventyFour,
SkipSector,
SubchannelReadLevel,
VideoNow,
VideoNowColor,
}
/// <summary>
/// Drive type for dumping
/// </summary>
public enum InternalDriveType
{
Optical,
Floppy,
HardDisk,
Removable,
}
/// <summary>
/// Dump status for Redump
/// </summary>
public enum DumpStatus
{
BadDumpRed = 2,
PossibleBadDumpYellow = 3,
OriginalMediaBlue = 4,
TwoOrMoreDumpsGreen = 5,
}
/// <summary>
/// Known systems
/// </summary>
public enum KnownSystem
{
NONE = 0,
#region Disc-Based Consoles
AtariJaguarCD,
BandaiPlaydiaQuickInteractiveSystem,
BandaiApplePippin,
CommodoreAmigaCD32,
CommodoreAmigaCDTV,
EnvizionsEVOSmartConsole,
FujitsuFMTownsMarty,
HasbroVideoNow,
HasbroVideoNowColor,
HasbroVideoNowJr,
HasbroVideoNowXP,
MattelHyperscan,
MicrosoftXBOX,
MicrosoftXBOX360,
MicrosoftXBOXOne,
NECPCEngineTurboGrafxCD,
NECPCFX,
NintendoGameCube,
NintendoSonySuperNESCDROMSystem,
NintendoWii,
NintendoWiiU,
Panasonic3DOInteractiveMultiplayer, // The 3DO Company 3DO Interactive Multiplayer
PhilipsCDi,
PioneerLaserActive,
SegaCDMegaCD,
SegaDreamcast,
SegaSaturn,
SNKNeoGeoCD,
SonyPlayStation,
SonyPlayStation2,
SonyPlayStation3,
SonyPlayStation4,
SonyPlayStationPortable,
TandyMemorexVisualInformationSystem,
VMLabsNuon,
VTechVFlashVSmilePro,
ZAPiTGamesGameWaveFamilyEntertainmentSystem,
MarkerDiscBasedConsoleEnd,
#endregion
#region Cartridge-Based and Other Consoles
/*
AmstradGX4000,
APFMicrocomputerSystem,
Atari2600VCS,
Atari5200,
Atari7800,
AtariJaguar,
AtariXEVideoGameSystem,
Audiosonic1292AdvancedProgrammableVideoSystem,
BallyAstrocade,
BitCorporationDina,
CasioLoopy,
CasioPV1000,
Commodore64GamesSystem,
DaewooElectronicsZemmix,
EmersonArcadia2001,
EpochCassetteVision,
EpochSuperCassetteVision,
FairchildChannelF,
FuntechSuperACan,
GeneralConsumerElectricVectrex,
HeberBBCBridgeCompanion,
IntertonVC4000,
JungleTacVii,
LeapFrogClickStart,
LJNVideoArt,
MagnavoxOdyssey2,
MattelIntellivision,
NECPCEngineTurboGrafx16,
NichibutsuMyVision,
Nintendo64,
Nintendo64DD,
NintendoFamilyComputerNintendoEntertainmentSystem,
NintendoFamilyComputerDiskSystem,
NintendoSuperFamicomSuperNintendoEntertainmentSystem,
NintendoSwitch,
PhilipsVideopacPlusG7400,
RCAStudioII,
Sega32X,
SegaMarkIIIMasterSystem,
SegaMegaDriveGenesis,
SegaSG1000,
SNKNeoGeo,
SSDCOMPANYLIMITEDXaviXPORT,
ViewMasterInteractiveVision,
VTechCreatiVision,
VTechVSmile,
VTechSocrates,
WorldsOfWonderActionMax,
MarkerOtherConsoleEnd,
*/
#endregion
#region Computers
AcornArchimedes,
AppleMacintosh,
CommodoreAmiga,
FujitsuFMTowns,
IBMPCCompatible,
NECPC88,
NECPC98,
SharpX68000,
MarkerComputerEnd,
#endregion
#region Arcade
AmigaCUBOCD32,
AmericanLaserGames3DO,
Atari3DO,
Atronic,
AUSCOMSystem1,
BallyGameMagic,
CapcomCPSystemIII,
GlobalVRVarious,
GlobalVRVortek,
GlobalVRVortekV3,
ICEPCHardware,
IncredibleTechnologiesEagle,
IncredibleTechnologiesVarious,
KonamieAmusement,
KonamiFirebeat,
KonamiGVSystem,
KonamiM2,
KonamiPython,
KonamiPython2,
KonamiSystem573,
KonamiTwinkle,
KonamiVarious,
MeritIndustriesBoardwalk,
MeritIndustriesMegaTouchForce,
MeritIndustriesMegaTouchION,
MeritIndustriesMegaTouchMaxx,
MeritIndustriesMegaTouchXL,
NamcoCapcomSystem256,
NamcoCapcomTaitoSystem246,
NamcoSegaNintendoTriforce,
NamcoSystem12,
NamcoSystem357,
NewJatreCDi,
NichibutsuHighRateSystem,
NichibutsuSuperCD,
NichibutsuXRateSystem,
PanasonicM2,
PhotoPlayVarious,
RawThrillsVarious,
SegaChihiro,
SegaEuropaR,
SegaLindbergh,
SegaNaomi,
SegaNaomi2,
SegaNu,
SegaRingEdge,
SegaRingEdge2,
SegaRingWide,
SegaTitanVideo,
SegaSystem32,
SeibuCATSSystem,
TABAustriaQuizard,
TsunamiTsuMoMultiGameMotionSystem,
MarkerArcadeEnd,
#endregion
#region Other
AudioCD,
BDVideo,
DVDVideo,
EnhancedCD,
HDDVDVideo,
NavisoftNaviken21,
PalmOS,
PhilipsCDiDigitalVideo,
PhotoCD,
PlayStationGameSharkUpdates,
RainbowDisc,
SuperAudioCD,
TaoiKTV,
TomyKissSite,
VideoCD,
MarkerOtherEnd,
#endregion
}
/// <summary>
/// Known system category
/// </summary>
public enum KnownSystemCategory
{
DiscBasedConsole = 0,
OtherConsole,
Computer,
Arcade,
Other,
Custom
};
/// <summary>
/// List of all disc langauges
/// </summary>
public enum Language
{
Afrikaans,
Arabic,
Basque,
Bulgarian,
Catalan,
Chinese,
Croatian,
Czech,
Danish,
Dutch,
English,
Finnish,
French,
Gaelic,
German,
Greek,
Hebrew,
Hindi,
Hungarian,
Italian,
Japanese,
Korean,
Norwegian,
Polish,
Portuguese,
Punjabi,
Romanian,
Russian,
Slovak,
Slovenian,
Spanish,
Swedish,
Tamil,
Thai,
Turkish,
Ukrainian,
}
/// <summary>
/// All possible language selections
/// </summary>
public enum LanguageSelection
{
BiosSettings,
LanguageSelector,
OptionsMenu,
}
/// <summary>
/// Known media types
/// </summary>
public enum MediaType
{
NONE = 0,
#region Punched Media
ApertureCard,
JacquardLoomCard,
MagneticStripeCard,
OpticalPhonecard,
PunchedCard,
PunchedTape,
#endregion
#region Tape
Cassette,
DataCartridge,
OpenReel,
#endregion
#region Disc / Disc
BluRay,
CDROM,
DVD,
FloppyDisk,
Floptical,
GDROM,
HDDVD,
HardDisk,
IomegaBernoulliDisk,
IomegaJaz,
IomegaZip,
LaserDisc, // LD-ROM and LV-ROM variants
Nintendo64DD,
NintendoFamicomDiskSystem,
NintendoGameCubeGameDisc,
NintendoWiiOpticalDisc,
NintendoWiiUOpticalDisc,
UMD,
#endregion
// Unsorted Formats
Cartridge,
CED,
CompactFlash,
MMC,
SDCard,
FlashDrive,
}
/// <summary>
/// List of all known Redump systems
/// </summary>
public enum RedumpSystem
{
// Special BIOS sets
MicrosoftXboxBIOS,
NintendoGameCubeBIOS,
SonyPlayStationBIOS,
SonyPlayStation2BIOS,
// Regular systems
AcornArchimedes,
AppleMacintosh,
AudioCD,
BDVideo,
BandaiPippin,
BandaiPlaydiaQuickInteractiveSystem,
CommodoreAmigaCD,
CommodoreAmigaCD32,
CommodoreAmigaCDTV,
DVDVideo,
FujitsuFMTownsseries,
HasbroVideoNow,
HasbroVideoNowColor,
HasbroVideoNowJr,
HasbroVideoNowXP,
IBMPCcompatible,
IncredibleTechnologiesEagle,
KonamiFireBeat,
KonamiM2,
KonamiSystem573,
KonamiSystemGV,
KonamiTwinkle,
KonamieAmusement,
MattelHyperScan,
MemorexVisualInformationSystem,
MicrosoftXbox,
MicrosoftXbox360,
MicrosoftXboxOne,
NECPC88series,
NECPC98series,
NECPCEngineCDTurboGrafxCD,
NECPCFXPCFXGA,
NamcoSystem12,
NamcoSystem246,
NavisoftNaviken21,
NinendoGameCube,
NintendoWii,
NintendoWiiU,
PalmOS,
Panasonic3DOInteractiveMultiplayer,
PanasonicM2,
PhilipsCDi,
PhilipsCDiDigitalVideo,
PhotoCD,
PlayStationGameSharkUpdates,
SegaChihiro,
SegaDreamcast,
SegaLindbergh,
SegaMegaCDSegaCD,
SegaNaomi,
SegaNaomi2,
SegaRingEdge,
SegaRingEdge2,
SegaSaturn,
SegaTitanVideo,
SegaTriforce,
SharpX68000,
SNKNeoGeoCD,
SonyPlayStation,
SonyPlayStation2,
SonyPlayStation3,
SonyPlayStation4,
SonyPlayStationPortable,
TABAustriaQuizard,
TaoiKTV,
TomyKissSite,
VideoCD,
VMLabsNUON,
VTechVFlashVSmilePro,
ZAPiTGamesGameWaveFamilyEntertainmentSystem,
}
/// <summary>
/// List of all known Redump regions
/// </summary>
public enum Region
{
Argentina,
Asia,
AsiaEurope,
AsiaUSA,
Australia,
Austria,
AustriaSwitzerland,
Belgium,
BelgiumNetherlands,
Brazil,
Canada,
China,
Croatia,
Czech,
Denmark,
Europe,
EuropeAsia,
EuropeAustralia,
Finland,
France,
FranceSpain,
Germany,
GreaterChina,
Greece,
Hungary,
India,
Ireland,
Israel,
Italy,
Japan,
JapanAsia,
JapanEurope,
JapanKorea,
JapanUSA,
Korea,
LatinAmerica,
Netherlands,
Norway,
Poland,
Portugal,
Russia,
Scandinavia,
Singapore,
Slovakia,
SouthAfrica,
Spain,
Sweden,
Switzerland,
Taiwan,
Thailand,
Turkey,
UnitedArabEmirates,
UK,
UKAustralia,
Ukraine,
USA,
USAAsia,
USABrazil,
USACanada,
USAEurope,
USAJapan,
World,
}
/// <summary>
/// Generic yes/no values for Redump
/// </summary>
public enum YesNo
{
NULL = 0,
No = 1,
Yes = 2,
}
}

View File

@@ -0,0 +1,500 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Net;
using DICUI.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
namespace DICUI.Data
{
public class SubmissionInfo
{
/// <summary>
/// List of matched Redump IDs
/// </summary>
[JsonIgnore]
public List<int> MatchedIDs { get; set; }
/// <summary>
/// DateTime of when the disc was added
/// </summary>
[JsonIgnore]
public DateTime? Added { get; set; }
/// <summary>
/// DateTime of when the disc was last modified
/// </summary>
[JsonIgnore]
public DateTime? LastModified { get; set; }
[JsonProperty(PropertyName = "common_disc_info", DefaultValueHandling = DefaultValueHandling.Ignore)]
public CommonDiscInfoSection CommonDiscInfo { get; set; } = new CommonDiscInfoSection();
[JsonProperty(PropertyName = "versions_and_editions", DefaultValueHandling = DefaultValueHandling.Ignore)]
public VersionAndEditionsSection VersionAndEditions { get; set; } = new VersionAndEditionsSection();
[JsonProperty(PropertyName = "edc", DefaultValueHandling = DefaultValueHandling.Ignore)]
public EDCSection EDC { get; set; } = new EDCSection();
[JsonProperty(PropertyName = "parent_clone_relationship", DefaultValueHandling = DefaultValueHandling.Ignore)]
public ParentCloneRelationshipSection ParentCloneRelationship { get; set; } = new ParentCloneRelationshipSection();
[JsonProperty(PropertyName = "extras", DefaultValueHandling = DefaultValueHandling.Ignore)]
public ExtrasSection Extras { get; set; } = new ExtrasSection();
[JsonProperty(PropertyName = "copy_protection", DefaultValueHandling = DefaultValueHandling.Ignore)]
public CopyProtectionSection CopyProtection { get; set; } = new CopyProtectionSection();
[JsonProperty(PropertyName = "dumpers_and_status", DefaultValueHandling = DefaultValueHandling.Ignore)]
public DumpersAndStatusSection DumpersAndStatus { get; set; } = new DumpersAndStatusSection();
[JsonProperty(PropertyName = "tracks_and_write_offsets", DefaultValueHandling = DefaultValueHandling.Ignore)]
public TracksAndWriteOffsetsSection TracksAndWriteOffsets { get; set; } = new TracksAndWriteOffsetsSection();
[JsonProperty(PropertyName = "size_and_checksums", DefaultValueHandling = DefaultValueHandling.Ignore)]
public SizeAndChecksumsSection SizeAndChecksums { get; set; } = new SizeAndChecksumsSection();
#region Regexes
private readonly Regex addedRegex = new Regex(@"<tr><th>Added</th><td>(.*?)</td></tr>");
private readonly Regex barcodeRegex = new Regex(@"<tr><th>Barcode</th></tr><tr><td>(.*?)</td></tr>");
private readonly Regex bcaRegex = new Regex(@"<h3>BCA .*?/></h3></td><td .*?></td></tr>"
+ "<tr><th>Row</th><th>Contents</th><th>ASCII</th></tr>"
+ "<tr><td>(?<row1number>.*?)</td><td>(?<row1contents>.*?)</td><td>(?<row1ascii>.*?)</td></tr>"
+ "<tr><td>(?<row2number>.*?)</td><td>(?<row2contents>.*?)</td><td>(?<row2ascii>.*?)</td></tr>"
+ "<tr><td>(?<row3number>.*?)</td><td>(?<row3contents>.*?)</td><td>(?<row3ascii>.*?)</td></tr>"
+ "<tr><td>(?<row4number>.*?)</td><td>(?<row4contents>.*?)</td><td>(?<row4ascii>.*?)</td></tr>");
private readonly Regex categoryRegex = new Regex(@"<tr><th>Category</th><td>(.*?)</td></tr>");
private readonly Regex commentsRegex = new Regex(@"<tr><th>Comments</th></tr><tr><td>(.*?)</td></tr>");
private readonly Regex contentsRegex = new Regex(@"<tr><th>Contents</th></tr><tr .*?><td>(.*?)</td></tr>");
private readonly Regex discNumberLetterRegex = new Regex(@"\((.*?)\)");
private readonly Regex dumpersRegex = new Regex(@"<a href=""/discs/dumper/(.*?)/"">");
private readonly Regex editionRegex = new Regex(@"<tr><th>Edition</th><td>(.*?)</td></tr>");
private readonly Regex errorCountRegex = new Regex(@"<tr><th>Errors count</th><td>(.*?)</td></tr>");
private readonly Regex foreignTitleRegex = new Regex(@"<h2>(.*?)</h2>");
private readonly Regex fullMatchRegex = new Regex(@"<td class=""static"">full match ids: (.*?)</td>");
private readonly Regex languagesRegex = new Regex(@"<img src=""/images/languages/(.*?)\.png"" alt="".*?"" title="".*?"" />\s*");
private readonly Regex lastModifiedRegex = new Regex(@"<tr><th>Last modified</th><td>(.*?)</td></tr>");
private readonly Regex mediaRegex = new Regex(@"<tr><th>Media</th><td>(.*?)</td></tr>");
private readonly Regex partialMatchRegex = new Regex(@"<td class=""static"">partial match ids: (.*?)</td>");
private readonly Regex pvdRegex = new Regex(@"<h3>Primary Volume Descriptor (PVD) <img .*?/></h3></td><td .*?></td></tr>"
+ @"<tr><th>Record / Entry</th><th>Contents</th><th>Date</th><th>Time</th><th>GMT</th></tr>"
+ @"<tr><td>Creation</td><td>(?<creationbytes>.*?)</td><td>(?<creationdate>.*?)</td><td>(?<creationtime>.*?)</td><td>(?<creationtimezone>.*?)</td></tr>"
+ @"<tr><td>Modification</td><td>(?<modificationbytes>.*?)</td><td>(?<modificationdate>.*?)</td><td>(?<modificationtime>.*?)</td><td>(?<modificationtimezone>.*?)</td></tr>"
+ @"<tr><td>Expiration</td><td>(?<expirationbytes>.*?)</td><td>(?<expirationdate>.*?)</td><td>(?<expirationtime>.*?)</td><td>(?<expirationtimezone>.*?)</td></tr>"
+ @"<tr><td>Effective</td><td>(?<effectivebytes>.*?)</td><td>(?<effectivedate>.*?)</td><td>(?<effectivetime>.*?)</td><td>(?<effectivetimezone>.*?)</td></tr>");
private readonly Regex regionRegex = new Regex(@"<tr><th>Region</th><td><a href=""/discs/region/(.*?)/"">");
private readonly Regex ringCodeDoubleRegex = new Regex(@""); // Varies based on available fields, like Addtional Mould
private readonly Regex ringCodeSingleRegex = new Regex(@""); // Varies based on available fields, like Addtional Mould
private readonly Regex serialRegex = new Regex(@"<tr><th>Serial</th><td>(.*?)</td></tr>");
private readonly Regex systemRegex = new Regex(@"<tr><th>System</th><td><a href=""/discs/system/(.*?)/"">");
private readonly Regex titleRegex = new Regex(@"<h1>(.*?)</h1>");
private readonly Regex trackRegex = new Regex(@"<tr><td>(?<number>.*?)</td><td>(?<type>.*?)</td><td>(?<pregap>.*?)</td><td>(?<length>.*?)</td><td>(?<sectors>.*?)</td><td>(?<size>.*?)</td><td>(?<crc32>.*?)</td><td>(?<md5>.*?)</td><td>(?<sha1>.*?)</td></tr>");
private readonly Regex trackCountRegex = new Regex(@"<tr><th>Number of tracks</th><td>(.*?)</td></tr>");
private readonly Regex versionRegex = new Regex(@"<tr><th>Version</th><td>(.*?)</td></tr>");
private readonly Regex writeOffsetRegex = new Regex(@"<tr><th>Write offset</th><td>(.*?)</td></tr>");
#endregion
/// <summary>
/// Fill in information from a Redump disc page
/// </summary>
/// <param name="discData">String representation of the disc page</param>
public void FillFromDiscPage(string discData)
{
// Title, Disc Number/Letter, Disc Title
var match = titleRegex.Match(discData);
if (match.Success)
{
string title = WebUtility.HtmlDecode(match.Groups[1].Value);
// If we have parenthesis, title is everything before the first one
int firstParenLocation = title.IndexOf(" (");
if (firstParenLocation >= 0)
{
this.CommonDiscInfo.Title = title.Substring(0, firstParenLocation);
var subMatches = discNumberLetterRegex.Match(title);
for (int i = 1; i < subMatches.Groups.Count; i++)
{
string subMatch = subMatches.Groups[i].Value;
// Disc number or letter
if (subMatch.StartsWith("Disc"))
this.CommonDiscInfo.DiscNumberLetter = subMatch.Remove(0, "Disc ".Length);
// Disc title
else
this.CommonDiscInfo.DiscTitle = subMatch;
}
}
// Otherwise, leave the title as-is
else
{
this.CommonDiscInfo.Title = title;
}
}
// Foreign Title
match = foreignTitleRegex.Match(discData);
if (match.Success)
this.CommonDiscInfo.ForeignTitleNonLatin = WebUtility.HtmlDecode(match.Groups[1].Value);
else
this.CommonDiscInfo.ForeignTitleNonLatin = null;
// Category
match = categoryRegex.Match(discData);
if (match.Success)
this.CommonDiscInfo.Category = Converters.StringToCategory(match.Groups[1].Value);
else
this.CommonDiscInfo.Category = Data.Category.Games;
// Region
match = regionRegex.Match(discData);
if (match.Success)
this.CommonDiscInfo.Region = Converters.StringToRegion(match.Groups[1].Value);
// Languages
var matches = languagesRegex.Matches(discData);
if (matches.Count > 0)
{
List<Language?> tempLanguages = new List<Language?>();
foreach (Match submatch in matches)
tempLanguages.Add(Converters.StringToLanguage(submatch.Groups[1].Value));
this.CommonDiscInfo.Languages = tempLanguages.ToArray();
}
// Serial
match = serialRegex.Match(discData);
if (match.Success)
this.CommonDiscInfo.Serial = WebUtility.HtmlDecode(match.Groups[1].Value);
// Error count
match = errorCountRegex.Match(discData);
if (match.Success)
{
// If the error counts don't match, then use the one from the disc page
if (!string.IsNullOrEmpty(this.CommonDiscInfo.ErrorsCount) && match.Groups[1].Value != this.CommonDiscInfo.ErrorsCount)
this.CommonDiscInfo.ErrorsCount = match.Groups[1].Value;
}
// Version
match = versionRegex.Match(discData);
if (match.Success)
this.VersionAndEditions.Version = WebUtility.HtmlDecode(match.Groups[1].Value);
// Edition
match = editionRegex.Match(discData);
if (match.Success)
this.VersionAndEditions.OtherEditions = WebUtility.HtmlDecode(match.Groups[1].Value);
// Dumpers
matches = dumpersRegex.Matches(discData);
if (matches.Count > 0)
{
// Start with any currently listed dumpers
List<string> tempDumpers = new List<string>();
if (this.DumpersAndStatus.Dumpers.Length > 0)
{
foreach (string dumper in this.DumpersAndStatus.Dumpers)
tempDumpers.Add(dumper);
}
foreach (Match submatch in matches)
tempDumpers.Add(WebUtility.HtmlDecode(submatch.Groups[1].Value));
this.DumpersAndStatus.Dumpers = tempDumpers.ToArray();
}
// Barcode
match = barcodeRegex.Match(discData);
if (match.Success)
this.CommonDiscInfo.Barcode = WebUtility.HtmlDecode(match.Groups[1].Value);
// Comments
match = commentsRegex.Match(discData);
if (match.Success)
{
this.CommonDiscInfo.Comments = WebUtility.HtmlDecode(match.Groups[1].Value)
.Replace("<br />", "\n")
.Replace("<b>ISBN</b>", "[T:ISBN]") + "\n";
}
// Contents
match = contentsRegex.Match(discData);
if (match.Success)
{
this.CommonDiscInfo.Contents = WebUtility.HtmlDecode(match.Groups[1].Value)
.Replace("<br />", "\n")
.Replace("</div>", "");
this.CommonDiscInfo.Contents = Regex.Replace(this.CommonDiscInfo.Contents, @"<div .*?>", "");
}
// Added
match = addedRegex.Match(discData);
if (match.Success)
this.Added = DateTime.Parse(match.Groups[1].Value);
// Last Modified
match = lastModifiedRegex.Match(discData);
if (match.Success)
this.LastModified = DateTime.Parse(match.Groups[1].Value);
}
}
/// <summary>
/// Common disc info section of New Disc Form
/// </summary>
public class CommonDiscInfoSection
{
// TODO: Name not defined
[JsonProperty(PropertyName = "d_system", Required = Required.AllowNull)]
[JsonConverter(typeof(KnownSystemConverter))]
public KnownSystem? System { get; set; }
// TODO: Name not defined
// TODO: Have this convert to a new `RedumpMedia?` if possible, for submission
[JsonProperty(PropertyName = "d_media", Required = Required.AllowNull)]
[JsonConverter(typeof(MediaTypeConverter))]
public MediaType? Media { get; set; }
[JsonProperty(PropertyName = "d_title", Required = Required.AllowNull)]
public string Title { get; set; }
[JsonProperty(PropertyName = "d_title_foreign", DefaultValueHandling = DefaultValueHandling.Ignore)]
public string ForeignTitleNonLatin { get; set; }
[JsonProperty(PropertyName = "d_number", NullValueHandling = NullValueHandling.Ignore)]
public string DiscNumberLetter { get; set; }
[JsonProperty(PropertyName = "d_label", NullValueHandling = NullValueHandling.Ignore)]
public string DiscTitle { get; set; }
[JsonProperty(PropertyName = "d_category", Required = Required.AllowNull)]
public Category? Category { get; set; }
[JsonProperty(PropertyName = "d_region", Required = Required.AllowNull)]
[JsonConverter(typeof(RegionConverter))]
public Region? Region { get; set; }
[JsonProperty(PropertyName = "d_languages", Required = Required.AllowNull)]
[JsonConverter(typeof(LanguagesConverter))]
public Language?[] Languages { get; set; }
[JsonProperty(PropertyName = "d_languages_selection", NullValueHandling = NullValueHandling.Ignore, DefaultValueHandling = DefaultValueHandling.Ignore)]
[JsonConverter(typeof(LanguageSelectionConverter))]
public LanguageSelection?[] LanguageSelection { get; set; }
[JsonProperty(PropertyName = "d_serial", NullValueHandling = NullValueHandling.Ignore)]
public string Serial { get; set; }
[JsonProperty(PropertyName = "d_ring", NullValueHandling = NullValueHandling.Ignore)]
public string Ring { get; }
[JsonProperty(PropertyName = "d_ring_0_id", NullValueHandling = NullValueHandling.Ignore)]
public string RingId { get; }
[JsonProperty(PropertyName = "d_ring_0_ma1", Required = Required.AllowNull)]
public string MasteringRingFirstLayerDataSide { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma1_sid", NullValueHandling = NullValueHandling.Ignore)]
public string MasteringSIDCodeFirstLayerDataSide { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ts1", NullValueHandling = NullValueHandling.Ignore)]
public string ToolstampMasteringCodeFirstLayerDataSide { get; set; }
[JsonProperty(PropertyName = "d_ring_0_mo1_sid", NullValueHandling = NullValueHandling.Ignore)]
public string MouldSIDCodeFirstLayerDataSide { get; set; }
[JsonProperty(PropertyName = "dr_ring_0_mo1", NullValueHandling = NullValueHandling.Ignore)]
public string AdditionalMouldFirstLayerDataSide { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma2", NullValueHandling = NullValueHandling.Ignore)]
public string MasteringRingSecondLayerLabelSide { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ma2_sid", NullValueHandling = NullValueHandling.Ignore)]
public string MasteringSIDCodeSecondLayerLabelSide { get; set; }
[JsonProperty(PropertyName = "d_ring_0_ts2", NullValueHandling = NullValueHandling.Ignore)]
public string ToolstampMasteringCodeSecondLayerLabelSide { get; set; }
[JsonProperty(PropertyName = "d_ring_0_mo2_sid", NullValueHandling = NullValueHandling.Ignore)]
public string MouldSIDCodeSecondLayerLabelSide { get; set; }
[JsonProperty(PropertyName = "dr_ring_0_mo2", NullValueHandling = NullValueHandling.Ignore)]
public string AdditionalMouldSecondLayerLabelSide { get; set; }
[JsonProperty(PropertyName = "d_ring_0_offsets", NullValueHandling = NullValueHandling.Ignore)]
public string RingOffsetsHidden { get { return "1"; } }
[JsonProperty(PropertyName = "d_ring_0_0_id", NullValueHandling = NullValueHandling.Ignore)]
public string RingZeroId { get; }
[JsonProperty(PropertyName = "d_ring_0_0_density", NullValueHandling = NullValueHandling.Ignore)]
public string RingZeroDensity { get; }
[JsonProperty(PropertyName = "d_ring_0_0_value", NullValueHandling = NullValueHandling.Ignore)]
public string RingWriteOffset { get; set; }
[JsonProperty(PropertyName = "d_ring_count", NullValueHandling = NullValueHandling.Ignore)]
public string RingCount { get { return "1"; } }
[JsonProperty(PropertyName = "d_barcode", NullValueHandling = NullValueHandling.Ignore)]
public string Barcode { get; set; }
[JsonProperty(PropertyName = "d_date", NullValueHandling = NullValueHandling.Ignore)]
public string EXEDateBuildDate { get; set; }
[JsonProperty(PropertyName = "d_errors", NullValueHandling = NullValueHandling.Ignore)]
public string ErrorsCount { get; set; }
[JsonProperty(PropertyName = "d_comments", NullValueHandling = NullValueHandling.Ignore)]
public string Comments { get; set; }
[JsonProperty(PropertyName = "d_contents", NullValueHandling = NullValueHandling.Ignore)]
public string Contents { get; set; }
}
/// <summary>
/// Version and editions section of New Disc form
/// </summary>
public class VersionAndEditionsSection
{
[JsonProperty(PropertyName = "d_version", NullValueHandling = NullValueHandling.Ignore)]
public string Version { get; set; }
[JsonProperty(PropertyName = "d_version_datfile", NullValueHandling = NullValueHandling.Ignore)]
public string VersionDatfile { get; set; }
[JsonProperty(PropertyName = "d_editions", NullValueHandling = NullValueHandling.Ignore)]
public string[] CommonEditions { get; set; }
[JsonProperty(PropertyName = "d_editions_text", NullValueHandling = NullValueHandling.Ignore)]
public string OtherEditions { get; set; }
}
/// <summary>
/// EDC section of New Disc form (PSX only)
/// </summary>
public class EDCSection
{
[JsonProperty(PropertyName = "d_edc", NullValueHandling = NullValueHandling.Ignore)]
public YesNo EDC { get; set; }
}
/// <summary>
/// Parent/Clone relationship section of New Disc form
/// </summary>
public class ParentCloneRelationshipSection
{
[JsonProperty(PropertyName = "d_parent_id", NullValueHandling = NullValueHandling.Ignore)]
public string ParentID { get; set; }
[JsonProperty(PropertyName = "d_is_regional_parent", NullValueHandling = NullValueHandling.Ignore)]
public bool RegionalParent { get; set; }
}
/// <summary>
/// Extras section of New Disc form
/// </summary>
public class ExtrasSection
{
[JsonProperty(PropertyName = "d_pvd", NullValueHandling = NullValueHandling.Ignore)]
public string PVD { get; set; }
[JsonProperty(PropertyName = "d_d1_key", NullValueHandling = NullValueHandling.Ignore)]
public string DiscKey { get; set; }
[JsonProperty(PropertyName = "d_d2_key", NullValueHandling = NullValueHandling.Ignore)]
public string DiscID { get; set; }
[JsonProperty(PropertyName = "d_pic_data", NullValueHandling = NullValueHandling.Ignore)]
public string PIC { get; set; }
[JsonProperty(PropertyName = "d_header", NullValueHandling = NullValueHandling.Ignore)]
public string Header { get; set; }
[JsonProperty(PropertyName = "d_bca", NullValueHandling = NullValueHandling.Ignore)]
public string BCA { get; set; }
[JsonProperty(PropertyName = "d_ssranges", NullValueHandling = NullValueHandling.Ignore)]
public string SecuritySectorRanges { get; set; }
}
/// <summary>
/// Copy protection section of New Disc form
/// </summary>
public class CopyProtectionSection
{
[JsonProperty(PropertyName = "d_protection_a", NullValueHandling = NullValueHandling.Ignore)]
public YesNo AntiModchip { get; set; }
[JsonProperty(PropertyName = "d_protection_1", NullValueHandling = NullValueHandling.Ignore)]
public YesNo LibCrypt { get; set; }
[JsonProperty(PropertyName = "d_libcrypt", NullValueHandling = NullValueHandling.Ignore)]
public string LibCryptData { get; set; }
[JsonProperty(PropertyName = "d_protection", NullValueHandling = NullValueHandling.Ignore)]
public string Protection { get; set; }
[JsonProperty(PropertyName = "d_securom", NullValueHandling = NullValueHandling.Ignore)]
public string SecuROMData { get; set; }
}
/// <summary>
/// Dumpers and status section of New Disc form (Moderator only)
/// </summary>
public class DumpersAndStatusSection
{
[JsonProperty(PropertyName = "d_status", NullValueHandling = NullValueHandling.Ignore)]
public DumpStatus Status { get; set; }
[JsonProperty(PropertyName = "d_dumpers", NullValueHandling = NullValueHandling.Ignore)]
public string[] Dumpers { get; set; }
[JsonProperty(PropertyName = "d_dumpers_text", NullValueHandling = NullValueHandling.Ignore)]
public string OtherDumpers { get; set; }
}
/// <summary>
/// Tracks and write offsets section of New Disc form (CD/GD-based)
/// </summary>
public class TracksAndWriteOffsetsSection
{
[JsonProperty(PropertyName = "d_tracks", NullValueHandling = NullValueHandling.Ignore)]
public string ClrMameProData { get; set; }
[JsonProperty(PropertyName = "d_cue", NullValueHandling = NullValueHandling.Ignore)]
public string Cuesheet { get; set; }
[JsonProperty(PropertyName = "d_offset", NullValueHandling = NullValueHandling.Ignore)]
public int[] CommonWriteOffsets { get; set; }
[JsonProperty(PropertyName = "d_offset_text", NullValueHandling = NullValueHandling.Ignore)]
public string OtherWriteOffsets { get; set; }
}
/// <summary>
/// Size & checksums section of New Disc form (DVD/BD/UMD-based)
/// </summary>
public class SizeAndChecksumsSection
{
[JsonProperty(PropertyName = "d_layerbreak", NullValueHandling = NullValueHandling.Ignore)]
public long Layerbreak { get; set; }
[JsonProperty(PropertyName = "d_size", NullValueHandling = NullValueHandling.Ignore)]
public long Size { get; set; }
[JsonProperty(PropertyName = "d_crc32", NullValueHandling = NullValueHandling.Ignore)]
public string CRC32 { get; set; }
[JsonProperty(PropertyName = "d_md5", NullValueHandling = NullValueHandling.Ignore)]
public string MD5 { get; set; }
[JsonProperty(PropertyName = "d_sha1", NullValueHandling = NullValueHandling.Ignore)]
public string SHA1 { get; set; }
}
}

View File

@@ -0,0 +1,37 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("DICUI.Library")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DICUI.Library")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("51ab0928-13f9-44bf-a407-b6957a43a056")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.13")]
[assembly: AssemblyFileVersion("1.13.0.0")]
[assembly: InternalsVisibleTo("DICUI.Test")]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,63 @@
using System.IO;
using DICUI.Data;
namespace DICUI.Utilities
{
/// <summary>
/// Represents information for a single drive
/// </summary>
public class Drive
{
/// <summary>
/// Represents drive type
/// </summary>
public InternalDriveType? InternalDriveType { get; set; }
/// <summary>
/// DriveInfo object representing the drive, if possible
/// </summary>
public DriveInfo DriveInfo { get; private set; }
/// <summary>
/// Windows drive letter
/// </summary>
public char Letter { get { return DriveInfo?.Name[0] ?? '\0'; } }
/// <summary>
/// Media label as read by Windows
/// </summary>
public string VolumeLabel
{
get
{
if (DriveInfo.IsReady)
{
if (string.IsNullOrWhiteSpace(DriveInfo.VolumeLabel))
return "track";
else
return DriveInfo.VolumeLabel;
}
else
{
return Template.DiscNotDetected;
}
}
}
/// <summary>
/// Drive partition format
/// </summary>
public string DriveFormat { get { return DriveInfo.DriveFormat; } }
/// <summary>
/// Represents if Windows has marked the drive as active
/// </summary>
public bool MarkedActive { get { return DriveInfo.IsReady; } }
public Drive(InternalDriveType? driveType, DriveInfo driveInfo)
{
this.InternalDriveType = driveType;
this.DriveInfo = driveInfo;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,252 @@
using DICUI.Data;
namespace DICUI.Utilities
{
public static class Extensions
{
#region Redump Information Lists
/// <summary>
/// List of systems that are not publically accessible
/// </summary>
public static readonly RedumpSystem[] BannedSystems = new RedumpSystem[]
{
RedumpSystem.AudioCD,
RedumpSystem.BDVideo,
RedumpSystem.DVDVideo,
RedumpSystem.HasbroVideoNow,
RedumpSystem.HasbroVideoNowColor,
RedumpSystem.HasbroVideoNowJr,
RedumpSystem.HasbroVideoNowXP,
RedumpSystem.KonamiM2,
RedumpSystem.MicrosoftXbox360,
RedumpSystem.MicrosoftXboxOne,
RedumpSystem.NavisoftNaviken21,
RedumpSystem.NintendoWii,
RedumpSystem.NintendoWiiU,
RedumpSystem.PanasonicM2,
RedumpSystem.PhilipsCDiDigitalVideo,
RedumpSystem.SegaRingEdge,
RedumpSystem.SegaRingEdge2,
RedumpSystem.SonyPlayStation3,
RedumpSystem.SonyPlayStation4,
RedumpSystem.VideoCD,
};
/// <summary>
/// List of systems that have a Cues pack
/// </summary>
public static readonly RedumpSystem[] HasCues = new RedumpSystem[]
{
RedumpSystem.AppleMacintosh,
RedumpSystem.AudioCD,
RedumpSystem.BandaiPippin,
RedumpSystem.BandaiPlaydiaQuickInteractiveSystem,
RedumpSystem.CommodoreAmigaCD,
RedumpSystem.CommodoreAmigaCD32,
RedumpSystem.CommodoreAmigaCDTV,
RedumpSystem.FujitsuFMTownsseries,
RedumpSystem.HasbroVideoNow,
RedumpSystem.HasbroVideoNowJr,
RedumpSystem.IBMPCcompatible,
RedumpSystem.IncredibleTechnologiesEagle,
RedumpSystem.KonamieAmusement,
RedumpSystem.KonamiFireBeat,
RedumpSystem.KonamiM2,
RedumpSystem.KonamiSystemGV,
RedumpSystem.MattelHyperScan,
RedumpSystem.MicrosoftXbox,
RedumpSystem.MicrosoftXbox360,
RedumpSystem.NamcoSystem246,
RedumpSystem.NavisoftNaviken21,
RedumpSystem.NECPC88series,
RedumpSystem.NECPC98series,
RedumpSystem.NECPCEngineCDTurboGrafxCD,
RedumpSystem.NECPCFXPCFXGA,
RedumpSystem.PalmOS,
RedumpSystem.Panasonic3DOInteractiveMultiplayer,
RedumpSystem.PanasonicM2,
RedumpSystem.PhilipsCDi,
RedumpSystem.PhilipsCDiDigitalVideo,
RedumpSystem.PhotoCD,
RedumpSystem.PlayStationGameSharkUpdates,
RedumpSystem.SegaChihiro,
RedumpSystem.SegaDreamcast,
RedumpSystem.SegaMegaCDSegaCD,
RedumpSystem.SegaNaomi,
RedumpSystem.SegaNaomi2,
RedumpSystem.SegaSaturn,
RedumpSystem.SegaTriforce,
RedumpSystem.SNKNeoGeoCD,
RedumpSystem.SonyPlayStation,
RedumpSystem.SonyPlayStation2,
RedumpSystem.SonyPlayStation3,
RedumpSystem.TABAustriaQuizard,
RedumpSystem.TomyKissSite,
RedumpSystem.VideoCD,
RedumpSystem.VTechVFlashVSmilePro,
};
/// <summary>
/// List of systems that has a Dat pack
/// </summary>
public static readonly RedumpSystem[] HasDat = new RedumpSystem[]
{
RedumpSystem.MicrosoftXboxBIOS,
RedumpSystem.NintendoGameCubeBIOS,
RedumpSystem.SonyPlayStationBIOS,
RedumpSystem.SonyPlayStation2BIOS,
RedumpSystem.AppleMacintosh,
RedumpSystem.AudioCD,
RedumpSystem.BDVideo,
RedumpSystem.BandaiPippin,
RedumpSystem.BandaiPlaydiaQuickInteractiveSystem,
RedumpSystem.CommodoreAmigaCD,
RedumpSystem.CommodoreAmigaCD32,
RedumpSystem.CommodoreAmigaCDTV,
RedumpSystem.DVDVideo,
RedumpSystem.FujitsuFMTownsseries,
RedumpSystem.HasbroVideoNow,
RedumpSystem.HasbroVideoNowJr,
RedumpSystem.IBMPCcompatible,
RedumpSystem.IncredibleTechnologiesEagle,
RedumpSystem.KonamiFireBeat,
RedumpSystem.KonamiM2,
RedumpSystem.KonamiSystemGV,
RedumpSystem.KonamieAmusement,
RedumpSystem.MattelHyperScan,
RedumpSystem.MicrosoftXbox,
RedumpSystem.MicrosoftXbox360,
RedumpSystem.MicrosoftXboxOne,
RedumpSystem.NamcoSystem246,
RedumpSystem.NavisoftNaviken21,
RedumpSystem.NECPC88series,
RedumpSystem.NECPC98series,
RedumpSystem.NECPCEngineCDTurboGrafxCD,
RedumpSystem.NECPCFXPCFXGA,
RedumpSystem.NinendoGameCube,
RedumpSystem.NintendoWii,
RedumpSystem.NintendoWiiU,
RedumpSystem.PalmOS,
RedumpSystem.Panasonic3DOInteractiveMultiplayer,
RedumpSystem.PanasonicM2,
RedumpSystem.PhilipsCDi,
RedumpSystem.PhilipsCDiDigitalVideo,
RedumpSystem.PhotoCD,
RedumpSystem.PlayStationGameSharkUpdates,
RedumpSystem.SegaChihiro,
RedumpSystem.SegaDreamcast,
RedumpSystem.SegaLindbergh,
RedumpSystem.SegaMegaCDSegaCD,
RedumpSystem.SegaNaomi,
RedumpSystem.SegaNaomi2,
RedumpSystem.SegaRingEdge,
RedumpSystem.SegaRingEdge2,
RedumpSystem.SegaSaturn,
RedumpSystem.SegaTriforce,
RedumpSystem.SNKNeoGeoCD,
RedumpSystem.SonyPlayStation,
RedumpSystem.SonyPlayStation2,
RedumpSystem.SonyPlayStation3,
RedumpSystem.SonyPlayStation4,
RedumpSystem.SonyPlayStationPortable,
RedumpSystem.TABAustriaQuizard,
RedumpSystem.TomyKissSite,
RedumpSystem.VideoCD,
RedumpSystem.VMLabsNUON,
RedumpSystem.VTechVFlashVSmilePro,
RedumpSystem.ZAPiTGamesGameWaveFamilyEntertainmentSystem,
};
/// <summary>
/// List of systems that has a Decrypted Keys pack
/// </summary>
public static readonly RedumpSystem[] HasDkeys = new RedumpSystem[]
{
RedumpSystem.SonyPlayStation3,
};
/// <summary>
/// List of systems that has a GDI pack
/// </summary>
public static readonly RedumpSystem[] HasGdi = new RedumpSystem[]
{
RedumpSystem.SegaChihiro,
RedumpSystem.SegaDreamcast,
RedumpSystem.SegaNaomi,
RedumpSystem.SegaNaomi2,
RedumpSystem.SegaTriforce,
};
/// <summary>
/// List of systems that has a Keys pack
/// </summary>
public static readonly RedumpSystem[] HasKeys = new RedumpSystem[]
{
RedumpSystem.NintendoWiiU,
RedumpSystem.SonyPlayStation3,
};
/// <summary>
/// List of systems that has an SBI pack
/// </summary>
public static readonly RedumpSystem[] HasSbi = new RedumpSystem[]
{
RedumpSystem.IBMPCcompatible,
RedumpSystem.SonyPlayStation,
};
#endregion
public static bool DoesSupportDriveSpeed(this MediaType? type)
{
switch (type)
{
case MediaType.CDROM:
case MediaType.DVD:
case MediaType.GDROM:
case MediaType.HDDVD:
case MediaType.BluRay:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return true;
default:
return false;
}
}
public static KnownSystemCategory Category(this KnownSystem? system)
{
if (system < KnownSystem.MarkerDiscBasedConsoleEnd)
return KnownSystemCategory.DiscBasedConsole;
/*
else if (system < KnownSystem.MarkerOtherConsoleEnd)
return KnownSystemCategory.OtherConsole;
*/
else if (system < KnownSystem.MarkerComputerEnd)
return KnownSystemCategory.Computer;
else if (system < KnownSystem.MarkerArcadeEnd)
return KnownSystemCategory.Arcade;
else if (system < KnownSystem.MarkerOtherEnd)
return KnownSystemCategory.Other;
else
return KnownSystemCategory.Custom;
}
public static bool IsMarker(this KnownSystem? system)
{
switch (system)
{
case KnownSystem.MarkerArcadeEnd:
case KnownSystem.MarkerComputerEnd:
case KnownSystem.MarkerDiscBasedConsoleEnd:
// case KnownSystem.MarkerOtherConsoleEnd:
case KnownSystem.MarkerOtherEnd:
return true;
default:
return false;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,66 @@
namespace DICUI.Utilities
{
/// <summary>
/// Generic success/failure result object, with optional message
/// </summary>
public class Result
{
/// <summary>
/// Internal representation of success
/// </summary>
private readonly bool success;
/// <summary>
/// Optional message for the result
/// </summary>
public string Message { get; private set; }
private Result(bool success, string message)
{
this.success = success;
this.Message = message;
}
/// <summary>
/// Create a default success result with no message
/// </summary>
public static Result Success() => new Result(true, "");
/// <summary>
/// Create a success result with a custom message
/// </summary>
/// <param name="message">String to add as a message</param>
public static Result Success(string message) => new Result(true, message);
/// <summary>
/// Create a success result with a custom message with format parameters
/// </summary>
/// <param name="message">String to add as a message</param>
/// <param name="args">Formatting parameters for the string</param>
public static Result Success(string message, params object[] args) => new Result(true, string.Format(message, args));
/// <summary>
/// Create a default failure result with no message
/// </summary>
/// <returns></returns>
public static Result Failure() => new Result(false, "");
/// <summary>
/// Create a failure result with a custom message
/// </summary>
/// <param name="message">String to add as a message</param>
public static Result Failure(string message) => new Result(false, message);
/// <summary>
/// Create a failure result with a custom message with format parameters
/// </summary>
/// <param name="message">String to add as a message</param>
/// <param name="args">Formatting parameters for the string</param>
public static Result Failure(string message, params object[] args) => new Result(false, string.Format(message, args));
/// <summary>
/// Results can be compared to boolean values based on the success value
/// </summary>
public static implicit operator bool(Result result) => result.success;
}
}

View File

@@ -0,0 +1,956 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management;
using System.Threading.Tasks;
using BurnOutSharp;
using IMAPI2;
using DICUI.Data;
namespace DICUI.Utilities
{
public static class Validators
{
/// <summary>
/// Get a list of valid MediaTypes for a given KnownSystem
/// </summary>
/// <param name="sys">KnownSystem value to check</param>
/// <returns>MediaTypes, if possible</returns>
public static List<MediaType?> GetValidMediaTypes(KnownSystem? sys)
{
var types = new List<MediaType?>();
switch (sys)
{
#region Consoles
// https://en.wikipedia.org/wiki/Atari_Jaguar_CD
case KnownSystem.AtariJaguarCD:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Playdia
case KnownSystem.BandaiPlaydiaQuickInteractiveSystem:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Apple_Bandai_Pippin
case KnownSystem.BandaiApplePippin:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Amiga_CD32
case KnownSystem.CommodoreAmigaCD32:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Commodore_CDTV
case KnownSystem.CommodoreAmigaCDTV:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/EVO_Smart_Console
case KnownSystem.EnvizionsEVOSmartConsole:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/FM_Towns_Marty
case KnownSystem.FujitsuFMTownsMarty:
types.Add(MediaType.CDROM);
types.Add(MediaType.FloppyDisk);
break;
// https://en.wikipedia.org/wiki/VideoNow
case KnownSystem.HasbroVideoNow:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/VideoNow
case KnownSystem.HasbroVideoNowColor:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/VideoNow
case KnownSystem.HasbroVideoNowJr:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/VideoNow
case KnownSystem.HasbroVideoNowXP:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/HyperScan
case KnownSystem.MattelHyperscan:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Xbox_(console)
case KnownSystem.MicrosoftXBOX:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/Xbox_360
case KnownSystem.MicrosoftXBOX360:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/Xbox_One
case KnownSystem.MicrosoftXBOXOne:
types.Add(MediaType.BluRay);
break;
// https://en.wikipedia.org/wiki/TurboGrafx-16
case KnownSystem.NECPCEngineTurboGrafxCD:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/PC-FX
case KnownSystem.NECPCFX:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/GameCube
case KnownSystem.NintendoGameCube:
types.Add(MediaType.NintendoGameCubeGameDisc);
break;
// https://en.wikipedia.org/wiki/Super_NES_CD-ROM
case KnownSystem.NintendoSonySuperNESCDROMSystem:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Wii
case KnownSystem.NintendoWii:
types.Add(MediaType.NintendoWiiOpticalDisc);
break;
// https://en.wikipedia.org/wiki/Wii_U
case KnownSystem.NintendoWiiU:
types.Add(MediaType.NintendoWiiUOpticalDisc);
break;
// https://en.wikipedia.org/wiki/3DO_Interactive_Multiplayer
case KnownSystem.Panasonic3DOInteractiveMultiplayer:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Philips_CD-i
case KnownSystem.PhilipsCDi:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/LaserActive
case KnownSystem.PioneerLaserActive:
types.Add(MediaType.CDROM);
types.Add(MediaType.LaserDisc);
break;
// https://en.wikipedia.org/wiki/Sega_CD
case KnownSystem.SegaCDMegaCD:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Dreamcast
case KnownSystem.SegaDreamcast:
types.Add(MediaType.CDROM); // Low density partition, MIL-CD
types.Add(MediaType.GDROM); // High density partition
break;
// https://en.wikipedia.org/wiki/Sega_Saturn
case KnownSystem.SegaSaturn:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Neo_Geo_CD
case KnownSystem.SNKNeoGeoCD:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/PlayStation_(console)
case KnownSystem.SonyPlayStation:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/PlayStation_2
case KnownSystem.SonyPlayStation2:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/PlayStation_3
case KnownSystem.SonyPlayStation3:
types.Add(MediaType.BluRay);
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/PlayStation_4
case KnownSystem.SonyPlayStation4:
types.Add(MediaType.BluRay);
break;
// https://en.wikipedia.org/wiki/PlayStation_Portable
case KnownSystem.SonyPlayStationPortable:
types.Add(MediaType.UMD);
types.Add(MediaType.CDROM); // Development discs only
types.Add(MediaType.DVD); // Development discs only
break;
// https://en.wikipedia.org/wiki/Tandy_Video_Information_System
case KnownSystem.TandyMemorexVisualInformationSystem:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Nuon_(DVD_technology)
case KnownSystem.VMLabsNuon:
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/V.Flash
case KnownSystem.VTechVFlashVSmilePro:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Game_Wave_Family_Entertainment_System
case KnownSystem.ZAPiTGamesGameWaveFamilyEntertainmentSystem:
types.Add(MediaType.DVD);
break;
#endregion
#region Computers
// https://en.wikipedia.org/wiki/Acorn_Archimedes
case KnownSystem.AcornArchimedes:
types.Add(MediaType.CDROM);
types.Add(MediaType.FloppyDisk);
break;
// https://en.wikipedia.org/wiki/Macintosh
case KnownSystem.AppleMacintosh:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
types.Add(MediaType.FloppyDisk);
types.Add(MediaType.HardDisk);
break;
// https://en.wikipedia.org/wiki/Amiga
case KnownSystem.CommodoreAmiga:
types.Add(MediaType.CDROM);
types.Add(MediaType.FloppyDisk);
break;
// https://en.wikipedia.org/wiki/FM_Towns
case KnownSystem.FujitsuFMTowns:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/IBM_PC_compatible
case KnownSystem.IBMPCCompatible:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
types.Add(MediaType.FloppyDisk);
types.Add(MediaType.HardDisk);
break;
// https://en.wikipedia.org/wiki/PC-8800_series
case KnownSystem.NECPC88:
types.Add(MediaType.CDROM);
types.Add(MediaType.FloppyDisk);
break;
// https://en.wikipedia.org/wiki/PC-9800_series
case KnownSystem.NECPC98:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
types.Add(MediaType.FloppyDisk);
break;
// https://en.wikipedia.org/wiki/X68000
case KnownSystem.SharpX68000:
types.Add(MediaType.CDROM);
types.Add(MediaType.FloppyDisk);
break;
#endregion
#region Arcade
// https://www.bigbookofamigahardware.com/bboah/product.aspx?id=36
case KnownSystem.AmigaCUBOCD32:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Orbatak
case KnownSystem.AmericanLaserGames3DO:
types.Add(MediaType.CDROM);
break;
// http://system16.com/hardware.php?id=779
case KnownSystem.Atari3DO:
types.Add(MediaType.CDROM);
break;
// http://newlifegames.net/nlg/index.php?topic=22003.0
// http://newlifegames.net/nlg/index.php?topic=5486.msg119440
case KnownSystem.Atronic:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://www.arcade-museum.com/members/member_detail.php?member_id=406530
case KnownSystem.AUSCOMSystem1:
types.Add(MediaType.CDROM);
break;
// http://newlifegames.net/nlg/index.php?topic=285.0
case KnownSystem.BallyGameMagic:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/CP_System_III
case KnownSystem.CapcomCPSystemIII:
types.Add(MediaType.CDROM);
break;
// UNKNOWN
case KnownSystem.GlobalVRVarious:
types.Add(MediaType.CDROM);
break;
// https://service.globalvr.com/troubleshooting/vortek.html
case KnownSystem.GlobalVRVortek:
types.Add(MediaType.CDROM);
break;
// https://service.globalvr.com/downloads/v3/040-1001-01c-V3-System-Manual.pdf
case KnownSystem.GlobalVRVortekV3:
types.Add(MediaType.CDROM);
break;
// https://www.icegame.com/games
case KnownSystem.ICEPCHardware:
types.Add(MediaType.DVD);
break;
// https://github.com/mamedev/mame/blob/master/src/mame/drivers/iteagle.cpp
case KnownSystem.IncredibleTechnologiesEagle:
types.Add(MediaType.CDROM);
break;
// UNKNOWN
case KnownSystem.IncredibleTechnologiesVarious:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/E-Amusement
case KnownSystem.KonamieAmusement:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=828
case KnownSystem.KonamiFirebeat:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=577
case KnownSystem.KonamiGVSystem:
types.Add(MediaType.CDROM);
break;
// http://system16.com/hardware.php?id=575
case KnownSystem.KonamiM2:
types.Add(MediaType.CDROM);
break;
// http://system16.com/hardware.php?id=586
// http://system16.com/hardware.php?id=977
case KnownSystem.KonamiPython:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=976
// http://system16.com/hardware.php?id=831
case KnownSystem.KonamiPython2:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=582
// http://system16.com/hardware.php?id=822
// http://system16.com/hardware.php?id=823
case KnownSystem.KonamiSystem573:
types.Add(MediaType.CDROM);
break;
// http://system16.com/hardware.php?id=827
case KnownSystem.KonamiTwinkle:
types.Add(MediaType.CDROM);
break;
// UNKNOWN
case KnownSystem.KonamiVarious:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://www.meritgames.com/Support_Center/manuals/PM0591-01.pdf
case KnownSystem.MeritIndustriesBoardwalk:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://www.meritgames.com/Support_Center/Force%20Elite/PM0380-09.pdf
// http://www.meritgames.com/Support_Center/Force%20Upright/PM0382-07%20FORCE%20Upright%20manual.pdf
// http://www.meritgames.com/Support_Center/Force%20Upright/PM0383-07%20FORCE%20Upright%20manual.pdf
case KnownSystem.MeritIndustriesMegaTouchForce:
types.Add(MediaType.CDROM);
break;
// http://www.meritgames.com/Service%20Center/Ion%20Troubleshooting.pdf
case KnownSystem.MeritIndustriesMegaTouchION:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://www.meritgames.com/Support_Center/EZ%20Maxx/Manuals/MAXX%20Elite%20with%20coin.pdf
// http://www.meritgames.com/Support_Center/EZ%20Maxx/Manuals/MAXX%20Elite.pdf
// http://www.meritgames.com/Support_Center/manuals/90003010%20Maxx%20TSM_Rev%20C.pdf
case KnownSystem.MeritIndustriesMegaTouchMaxx:
types.Add(MediaType.CDROM);
break;
// http://www.meritgames.com/Support_Center/manuals/pm0076_OA_Megatouch%20XL%20Trouble%20Shooting%20Manual.pdf
// http://www.meritgames.com/Support_Center/MEGA%20XL/manuals/Megatouch_XL_pm0109-0D.pdf
// http://www.meritgames.com/Support_Center/MEGA%20XL/manuals/Megatouch_XL_Super_5000_manual.pdf
case KnownSystem.MeritIndustriesMegaTouchXL:
types.Add(MediaType.CDROM);
break;
// http://system16.com/hardware.php?id=546
// http://system16.com/hardware.php?id=872
case KnownSystem.NamcoCapcomSystem256:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=543
case KnownSystem.NamcoCapcomTaitoSystem246:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=545
case KnownSystem.NamcoSegaNintendoTriforce:
types.Add(MediaType.CDROM); // Low density partition
types.Add(MediaType.GDROM); // High density partition
break;
// http://system16.com/hardware.php?id=535
case KnownSystem.NamcoSystem12:
types.Add(MediaType.CDROM);
break;
// http://system16.com/hardware.php?id=900
case KnownSystem.NamcoSystem357:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
types.Add(MediaType.BluRay);
break;
// https://www.arcade-history.com/?n=the-yakyuuken-part-1&page=detail&id=33049
case KnownSystem.NewJatreCDi:
types.Add(MediaType.CDROM);
break;
// http://blog.system11.org/?p=2499
case KnownSystem.NichibutsuHighRateSystem:
types.Add(MediaType.DVD);
break;
// http://blog.system11.org/?p=2514
case KnownSystem.NichibutsuSuperCD:
types.Add(MediaType.CDROM);
break;
// http://collectedit.com/collectors/shou-time-213/arcade-pcbs-281/x-rate-dvd-series-17-newlywed-life-japan-by-nichibutsu-32245
case KnownSystem.NichibutsuXRateSystem:
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/Panasonic_M2
case KnownSystem.PanasonicM2:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
// https://github.com/mamedev/mame/blob/master/src/mame/drivers/photoply.cpp
case KnownSystem.PhotoPlayVarious:
types.Add(MediaType.CDROM);
break;
// UNKNOWN
case KnownSystem.RawThrillsVarious:
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=729
case KnownSystem.SegaChihiro:
types.Add(MediaType.CDROM); // Low density partition
types.Add(MediaType.GDROM); // High density partition
break;
// http://system16.com/hardware.php?id=907
case KnownSystem.SegaEuropaR:
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=985
// http://system16.com/hardware.php?id=731
// http://system16.com/hardware.php?id=984
// http://system16.com/hardware.php?id=986
case KnownSystem.SegaLindbergh:
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=721
// http://system16.com/hardware.php?id=723
// http://system16.com/hardware.php?id=906
// http://system16.com/hardware.php?id=722
case KnownSystem.SegaNaomi:
types.Add(MediaType.CDROM); // Low density partition
types.Add(MediaType.GDROM); // High density partition
break;
// http://system16.com/hardware.php?id=725
// http://system16.com/hardware.php?id=726
// http://system16.com/hardware.php?id=727
case KnownSystem.SegaNaomi2:
types.Add(MediaType.CDROM); // Low density partition
types.Add(MediaType.GDROM); // High density partition
break;
// http://system16.com/hardware.php?id=975
// https://en.wikipedia.org/wiki/List_of_Sega_arcade_system_boards#Sega_Nu
case KnownSystem.SegaNu:
types.Add(MediaType.BluRay);
break;
// http://system16.com/hardware.php?id=910
// https://en.wikipedia.org/wiki/List_of_Sega_arcade_system_boards#Sega_Ring_series
case KnownSystem.SegaRingEdge:
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=982
// https://en.wikipedia.org/wiki/List_of_Sega_arcade_system_boards#Sega_Ring_series
case KnownSystem.SegaRingEdge2:
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=911
// https://en.wikipedia.org/wiki/List_of_Sega_arcade_system_boards#Sega_Ring_series
case KnownSystem.SegaRingWide:
types.Add(MediaType.DVD);
break;
// http://system16.com/hardware.php?id=711
case KnownSystem.SegaTitanVideo:
types.Add(MediaType.CDROM);
break;
// http://system16.com/hardware.php?id=709
// http://system16.com/hardware.php?id=710
case KnownSystem.SegaSystem32:
types.Add(MediaType.CDROM);
break;
// https://github.com/mamedev/mame/blob/master/src/mame/drivers/seibucats.cpp
case KnownSystem.SeibuCATSSystem:
types.Add(MediaType.DVD);
break;
// https://www.tab.at/en/support/support/downloads
case KnownSystem.TABAustriaQuizard:
types.Add(MediaType.CDROM);
break;
// https://primetimeamusements.com/product/tsumo-multi-game-motion-system/
// https://www.highwaygames.com/arcade-machines/tsumo-tsunami-motion-8117/
case KnownSystem.TsunamiTsuMoMultiGameMotionSystem:
types.Add(MediaType.CDROM);
break;
#endregion
#region Others
// https://en.wikipedia.org/wiki/Audio_CD
case KnownSystem.AudioCD:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Blu-ray#Player_profiles
case KnownSystem.BDVideo:
types.Add(MediaType.BluRay);
break;
// https://en.wikipedia.org/wiki/DVD-Video
case KnownSystem.DVDVideo:
types.Add(MediaType.DVD);
break;
// https://en.wikipedia.org/wiki/Blue_Book_(CD_standard)
case KnownSystem.EnhancedCD:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/HD_DVD
case KnownSystem.HDDVDVideo:
types.Add(MediaType.HDDVD);
break;
// UNKNOWN
case KnownSystem.NavisoftNaviken21:
types.Add(MediaType.CDROM);
break;
// UNKNOWN
case KnownSystem.PalmOS:
types.Add(MediaType.CDROM);
break;
// UNKNOWN
case KnownSystem.PhilipsCDiDigitalVideo:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Photo_CD
case KnownSystem.PhotoCD:
types.Add(MediaType.CDROM);
break;
// UNKNOWN
case KnownSystem.PlayStationGameSharkUpdates:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Doors_and_Windows_(EP)
case KnownSystem.RainbowDisc:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Super_Audio_CD
case KnownSystem.SuperAudioCD:
types.Add(MediaType.CDROM);
break;
// https://www.cnet.com/products/tao-music-iktv-karaoke-station-karaoke-system-series/
case KnownSystem.TaoiKTV:
types.Add(MediaType.CDROM);
break;
// http://ultimateconsoledatabase.com/golden/kiss_site.htm
case KnownSystem.TomyKissSite:
types.Add(MediaType.CDROM);
break;
// https://en.wikipedia.org/wiki/Video_CD
case KnownSystem.VideoCD:
types.Add(MediaType.CDROM);
break;
#endregion
case KnownSystem.NONE:
default:
types.Add(MediaType.NONE);
break;
}
return types;
}
/// <summary>
/// Create a list of systems
/// </summary>
/// <returns>KnownSystems, if possible</returns>
public static List<KnownSystem?> CreateListOfSystems()
{
return Enum.GetValues(typeof(KnownSystem))
.OfType<KnownSystem?>()
.Where(s => !s.IsMarker() && s != KnownSystem.NONE)
.ToList();
}
/// <summary>
/// Create a list of active drives matched to their volume labels
/// </summary>
/// <returns>Active drives, matched to labels, if possible</returns>
/// <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
/// </remarks>
public static List<Drive> CreateListOfDrives()
{
// Get all supported drive types
var drives = DriveInfo.GetDrives()
.Where(d => d.DriveType == DriveType.CDRom || d.DriveType == DriveType.Fixed || d.DriveType == DriveType.Removable)
.Select(d => new Drive(Converters.ToInternalDriveType(d.DriveType), d))
.ToList();
// Get the floppy drives and set the flag from removable
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_LogicalDisk");
var collection = searcher.Get();
foreach (ManagementObject queryObj in collection)
{
uint? mediaType = (uint?)queryObj["MediaType"];
if (mediaType != null && ((mediaType > 0 && mediaType < 11) || (mediaType > 12 && mediaType < 22)))
{
char devId = queryObj["DeviceID"].ToString()[0];
drives.ForEach(d => { if (d.Letter == devId) { d.InternalDriveType = InternalDriveType.Floppy; } });
}
}
}
catch
{
// No-op
}
// Order the drives by drive letter
drives = drives.OrderBy(i => i.Letter).ToList();
return drives;
}
/// <summary>
/// Get the current media type from drive letter
/// </summary>
/// <param name="drive"></param>
/// <returns></returns>
/// <remarks>
/// https://stackoverflow.com/questions/11420365/detecting-if-disc-is-in-dvd-drive
/// </remarks>
public static MediaType? GetMediaType(Drive drive)
{
// Take care of the non-optical stuff first
// TODO: See if any of these can be more granular, like Optical is
if (drive.InternalDriveType == InternalDriveType.Floppy)
return MediaType.FloppyDisk;
else if (drive.InternalDriveType == InternalDriveType.HardDisk)
return MediaType.HardDisk;
else if (drive.InternalDriveType == InternalDriveType.Removable)
return MediaType.FlashDrive;
// Get the DeviceID from the current drive letter
string deviceId = null;
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_CDROMDrive WHERE Id = '" + drive.Letter + ":\'");
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
try
{
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.ToMediaType(media);
}
catch
{
// We don't care what the error is
}
return null;
}
/// <summary>
/// Get the current system from drive
/// </summary>
/// <param name="drive"></param>
/// <returns></returns>
public static KnownSystem? GetKnownSystem(Drive drive)
{
// If drive or drive letter are provided, we can't do anything
if (drive?.Letter == null)
return null;
string drivePath = $"{drive.Letter}:\\";
// If we can't read the media in that drive, we can't do anything
if (!Directory.Exists(drivePath))
return null;
// We're going to assume for floppies, HDDs, and removable drives
// TODO: Try to be smarter about this
if (drive.InternalDriveType != InternalDriveType.Optical)
return KnownSystem.IBMPCCompatible;
// Sega Dreamcast
if (File.Exists(Path.Combine(drivePath, "IP.BIN")))
{
return KnownSystem.SegaDreamcast;
}
// Sega Mega-CD / Sega-CD
if (File.Exists(Path.Combine(drivePath, "_BOOT", "IP.BIN"))
|| File.Exists(Path.Combine(drivePath, "_BOOT", "SP.BIN"))
|| File.Exists(Path.Combine(drivePath, "_BOOT", "SP_AS.BIN"))
|| File.Exists(Path.Combine(drivePath, "FILESYSTEM.BIN")))
{
return KnownSystem.SegaCDMegaCD;
}
// Sony PlayStation and Sony PlayStation 2
if (File.Exists(Path.Combine(drivePath, "SYSTEM.CNF")))
{
// Check for either BOOT or BOOT2
using (StreamReader reader = File.OpenText(Path.Combine(drivePath, "SYSTEM.CNF")))
{
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
if (line.Contains("BOOT2"))
return KnownSystem.SonyPlayStation2;
else if (line.Contains("BOOT"))
return KnownSystem.SonyPlayStation;
}
}
// If we have a weird disc, just assume PS1
return KnownSystem.SonyPlayStation;
}
// Sony PlayStation 4
if (drive.VolumeLabel.Equals("PS4VOLUME", StringComparison.OrdinalIgnoreCase))
{
return KnownSystem.SonyPlayStation4;
}
// V.Tech V.Flash / V.Smile Pro
if (File.Exists(Path.Combine(drivePath, "0SYSTEM")))
{
return KnownSystem.VTechVFlashVSmilePro;
}
// Default return
return KnownSystem.NONE;
}
/// <summary>
/// Verify that, given a system and a media type, they are correct
/// </summary>
public static Result GetSupportStatus(KnownSystem? system, MediaType? type)
{
// No system chosen, update status
if (system == KnownSystem.NONE)
return Result.Failure("Please select a valid system");
// If we're on an unsupported type, update the status accordingly
switch (type)
{
// Fully supported types
case MediaType.BluRay:
case MediaType.CDROM:
case MediaType.DVD:
case MediaType.FloppyDisk:
case MediaType.HardDisk:
case MediaType.CompactFlash:
case MediaType.SDCard:
case MediaType.FlashDrive:
case MediaType.HDDVD:
return Result.Success("{0} ready to dump", type.LongName());
// Partially supported types
case MediaType.GDROM:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return Result.Success("{0} partially supported for dumping", type.LongName());
// Special case for other supported tools
case MediaType.UMD:
return Result.Success("{0} supported for submission info parsing", type.LongName());
// Specifically unknown type
case MediaType.NONE:
return Result.Failure("Please select a valid media type");
// Undumpable but recognized types
default:
return Result.Failure("{0} media are not supported for dumping", type.LongName());
}
}
/// <summary>
/// Run protection scan on a given dump environment
/// </summary>
/// <param name="env">DumpEnvirionment containing all required information</param>
/// <returns>Copy protection detected in the envirionment, if any</returns>
public static async Task<string> RunProtectionScanOnPath(string path)
{
try
{
var found = await Task.Run(() =>
{
return ProtectionFind.Scan(path);
});
if (found == null || found.Count == 0)
return "None found";
return string.Join("\n", found.Select(kvp => kvp.Key + ": " + kvp.Value).ToArray());
}
catch (Exception ex)
{
return $"Path could not be scanned! {ex}";
}
}
}
}

View File

@@ -0,0 +1,36 @@
using System;
using System.Net;
namespace DICUI.Web
{
// https://stackoverflow.com/questions/1777221/using-cookiecontainer-with-webclient-class
public class CookieAwareWebClient : WebClient
{
private readonly CookieContainer m_container = new CookieContainer();
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
HttpWebRequest webRequest = request as HttpWebRequest;
if (webRequest != null)
{
webRequest.CookieContainer = m_container;
}
return request;
}
/// <summary>
/// Get the last downloaded filename, if possible
/// </summary>
/// <returns></returns>
public string GetLastFilename()
{
// Try to extract the filename from the Content-Disposition header
if (!string.IsNullOrEmpty(this.ResponseHeaders["Content-Disposition"]))
return this.ResponseHeaders["Content-Disposition"].Substring(this.ResponseHeaders["Content-Disposition"].IndexOf("filename=") + 9).Replace("\"", "");
return null;
}
}
}

View File

@@ -0,0 +1,385 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI.Web
{
public class RedumpAccess
{
#region Base URLs
private const string loginUrl = "http://forum.redump.org/login/";
#endregion
#region Disc URLs and Extensions
private const string discPageUrl = @"http://redump.org/disc/{0}/";
private const string wipDiscPageUrl = @"http://redump.org/newdisc/{0}/";
private const string changesExt = "/changes/";
private const string cueExt = "cue/";
private const string gdiExt = "gdi/";
private const string keyExt = "key/";
private const string md5Ext = "md5/";
private const string sbiExt = "sbi/";
private const string sfvExt = "sfv/";
private const string sha1Ext = "sha1/";
#endregion
#region List URLs
private const string lastModifiedUrl = @"http://redump.org/discs/sort/modified/dir/desc?page={0}";
private const string quickSearchUrl = @"http://redump.org/discs/quicksearch/{0}/?page={1}";
private const string userDumpsUrl = @"http://redump.org/discs/dumper/{0}/?page={1}";
private const string wipDumpsUrl = @"http://redump.org/discs-wip/";
#endregion
#region Pack URLs
private const string packCuesUrl = @"http://redump.org/cues/{0}/";
private const string packDatfileUrl = @"http://redump.org/datfile/{0}/";
private const string packDkeysUrl = @"http://redump.org/dkeys/{0}/";
private const string packGdiUrl = @"http://redump.org/gdi/{0}/";
private const string packKeysUrl = @"http://redump.org/keys/{0}/";
private const string packSbiUrl = @"http://redump.org/sbi/{0}/";
#endregion
#region Regexes
private readonly Regex discRegex = new Regex(@"<a href=""/disc/(\d+)/"">");
private readonly Regex newDiscRegex = new Regex(@"<a href=""/newdisc/(\d+)/"">");
private readonly Regex tokenRegex = new Regex(@"<input type=""hidden"" name=""csrf_token"" value=""(.*?)"" />");
#endregion
/// <summary>
/// Login to Redump, if possible
/// </summary>
/// <param name="wc">CookieAwareWebClient to hold the login state</param>
/// <param name="username">Redump username to log in for protected systems</param>
/// <param name="password">Redump password to log in for protected systems</param>
/// <returns>True login was successful, false otherwise</returns>
public bool RedumpLogin(CookieAwareWebClient wc, string username, string password)
{
if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
return false;
var loginPage = wc.DownloadString(loginUrl);
string token = this.tokenRegex.Match(loginPage).Groups[1].Value;
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
wc.Encoding = Encoding.UTF8;
var response = wc.UploadString(loginUrl, $"form_sent=1&redirect_url=&csrf_token={token}&req_username={username}&req_password={password}&save_pass=0");
if (response.Contains("Incorrect username and/or password."))
return false;
else
return true;
}
#region Process IDs and Pages
/// <summary>
/// Get the list of the last modified IDs, in order of appearance
/// </summary>
/// <param name="wc">CookieAwareWebClient to hold the login state</param>
/// <param name="pageCount">Number of pages to grab until stopping; -1 means continue until end</param>
/// <returns>A list of IDs in order of last modified</returns>
private List<int> ProcessLastModified(CookieAwareWebClient wc, int pageCount = -1)
{
List<int> ids = new List<int>();
// If we have a -1 page count, set the maximum page limit
if (pageCount == -1)
pageCount = Int32.MaxValue;
// Keep getting last modified pages until there are none left
int pageNumber = 1;
while (pageNumber < pageCount)
{
List<int> pageIds = CheckSingleSitePage(wc, string.Format(lastModifiedUrl, pageNumber++));
ids.AddRange(pageIds);
if (pageIds.Count < 2)
break;
}
return ids;
}
/// <summary>
/// Retrieve premade packs from Redump
/// </summary>
/// <param name="wc">CookieAwareWebClient to hold the login state</param>
private void ProcessAllPacks(CookieAwareWebClient wc)
{
var cuesPacks = this.DownloadPacks(wc, packCuesUrl, Extensions.HasCues, "CUEs");
var datPacks = this.DownloadPacks(wc, packDatfileUrl, Extensions.HasDat, "DATs");
var dkeyPacks = this.DownloadPacks(wc, packDkeysUrl, Extensions.HasDkeys, "Decrypted KEYS");
var gdiPacks = this.DownloadPacks(wc, packGdiUrl, Extensions.HasGdi, "GDIs");
var keysPacks = this.DownloadPacks(wc, packKeysUrl, Extensions.HasKeys, "KEYS");
var sbiPacks = this.DownloadPacks(wc, packSbiUrl, Extensions.HasSbi, "SBIs");
}
/// <summary>
/// Retrieve premade packs from Redump
/// </summary>
/// <param name="wc">CookieAwareWebClient to hold the login state</param>
/// <param name="system">RedumpSystem to get all possible packs for</param>
private void ProcessPacksForSystem(CookieAwareWebClient wc, RedumpSystem system)
{
var packs = new Dictionary<string, byte[]>();
if (Extensions.HasCues.Contains(system))
packs.Add("cues", this.DownloadPack(wc, packCuesUrl, system, "CUEs"));
if (Extensions.HasDat.Contains(system))
packs.Add("dat", this.DownloadPack(wc, packDatfileUrl, system, "DATs"));
if (Extensions.HasDkeys.Contains(system))
packs.Add("dkeys", this.DownloadPack(wc, packDkeysUrl, system, "Decrypted KEYS"));
if (Extensions.HasGdi.Contains(system))
packs.Add("gdi", this.DownloadPack(wc, packGdiUrl, system, "GDIs"));
if (Extensions.HasKeys.Contains(system))
packs.Add("keys", this.DownloadPack(wc, packKeysUrl, system, "KEYS"));
if (Extensions.HasSbi.Contains(system))
packs.Add("sbi", this.DownloadPack(wc, packSbiUrl, system, "SBIs"));
}
/// <summary>
/// Get the list of IDs that associate with a given string
/// </summary>
/// <param name="wc">CookieAwareWebClient to hold the login state</param>
/// <param name="query">Value to search for in Redump</param>
/// <returns>A list of IDs associated with that value</returns>
public List<int> ProcessSearch(CookieAwareWebClient wc, string query)
{
List<int> ids = new List<int>();
// Keep getting quicksearch pages until there are none left
int pageNumber = 1;
while (true)
{
List<int> pageIds = CheckSingleSitePage(wc, string.Format(quickSearchUrl, query, pageNumber++));
ids.AddRange(pageIds);
if (pageIds.Count < 2)
break;
}
return ids;
}
/// <summary>
/// Get the list of IDs associated with the given user
/// </summary>
/// <param name="wc">CookieAwareWebClient to hold the login state</param>
/// <param name="username">Redump username to get the list of IDs for</param>
/// <returns>A list of IDs associated with that user</returns>
private List<int> ProcessUser(CookieAwareWebClient wc, string username)
{
List<int> ids = new List<int>();
// Keep getting user pages until there are none left
int pageNumber = 1;
while (true)
{
List<int> pageIds = CheckSingleSitePage(wc, string.Format(userDumpsUrl, username, pageNumber++));
ids.AddRange(pageIds);
if (pageIds.Count < 2)
break;
}
return ids;
}
#endregion
#region Single item processing
/// <summary>
/// Process a Redump site page as a list of possible IDs or disc page
/// </summary>
/// <param name="wc">CookieAwareWebClient to access the pages</param>
/// <param name="url">Page URL to check and parse</param>
/// <returns>List of matching IDs</returns>
private List<int> CheckSingleSitePage(CookieAwareWebClient wc, string url)
{
List<int> ids = new List<int>();
var dumpsPage = wc.DownloadString(url);
// If we have no dumps left
if (dumpsPage.Contains("No discs found."))
return ids;
// If we have a single disc page already
if (dumpsPage.Contains("<b>Download:</b>"))
{
var value = Regex.Match(dumpsPage, @"/disc/(\d+)/sfv/").Groups[1].Value;
if (Int32.TryParse(value, out int id))
ids.Add(id);
return ids;
}
// Otherwise, traverse each dump on the page
var matches = discRegex.Matches(dumpsPage);
foreach (Match match in matches)
{
try
{
if (Int32.TryParse(match.Groups[1].Value, out int value))
ids.Add(value);
}
catch (Exception ex)
{
Console.WriteLine($"An exception has occurred: {ex}");
continue;
}
}
return ids;
}
/// <summary>
/// Process a Redump WIP page as a list of possible IDs or disc page
/// </summary>
/// <param name="wc">CookieAwareWebClient to access the pages</param>
/// <param name="url">Page URL to check and parse</param>
/// <returns>List of matching IDs</returns>
private List<int> CheckSingleWIPPage(CookieAwareWebClient wc, string url)
{
List<int> ids = new List<int>();
var wipDumpsPage = wc.DownloadString(url);
// If we have no WIP dumps left
if (wipDumpsPage.Contains("No WIP discs found."))
return ids;
// Otherwise, traverse each dump on the page
var matches = newDiscRegex.Matches(wipDumpsPage);
foreach (Match match in matches)
{
try
{
if (Int32.TryParse(match.Groups[1].Value, out int value))
ids.Add(value);
}
catch (Exception ex)
{
Console.WriteLine($"An exception has occurred: {ex}");
continue;
}
}
return ids;
}
/// <summary>
/// Download an individual pack
/// </summary>
/// <param name="wc">CookieAwareWebClient to access the packs</param>
/// <param name="url">Base URL to download using</param>
/// <param name="system">System to download packs for</param>
/// <param name="title">Name of the pack that is downloading</param>
private byte[] DownloadPack(CookieAwareWebClient wc, string url, RedumpSystem system, string title)
{
Console.WriteLine($"Downloading {title}");
Console.Write($"\r{system.LongName()}{new string(' ', Console.BufferWidth - system.LongName().Length - 1)}");
var pack = wc.DownloadData(string.Format(url, system.ShortName()));
Console.Write($"\rComplete!{new string(' ', Console.BufferWidth - 10)}");
Console.WriteLine();
return pack;
}
/// <summary>
/// Download a set of packs
/// </summary>
/// <param name="wc">CookieAwareWebClient to access the packs</param>
/// <param name="url">Base URL to download using</param>
/// <param name="systems">List of systems to download packs for</param>
/// <param name="title">Name of the pack that is downloading</param>
private Dictionary<RedumpSystem, byte[]> DownloadPacks(CookieAwareWebClient wc, string url, RedumpSystem[] systems, string title)
{
var dict = new Dictionary<RedumpSystem, byte[]>();
Console.WriteLine($"Downloading {title}");
foreach (var system in systems)
{
Console.Write($"\r{system.LongName()}{new string(' ', Console.BufferWidth - system.LongName().Length - 1)}");
dict.Add(system, wc.DownloadData(string.Format(url, system.ShortName())));
}
Console.Write($"\rComplete!{new string(' ', Console.BufferWidth - 10)}");
Console.WriteLine();
return dict;
}
/// <summary>
/// Download an individual site ID page as a string, if possible
/// </summary>
/// <param name="wc">CookieAwareWebClient to access the pages</param>
/// <param name="id">Redump disc ID to retrieve</param>
/// <returns>Disc page as a string, null on error</returns>
public string DownloadSingleSiteID(CookieAwareWebClient wc, int id)
{
string paddedId = id.ToString().PadLeft(5, '0');
Console.WriteLine($"Processing ID: {paddedId}");
try
{
string discPage = wc.DownloadString(string.Format(discPageUrl, +id));
if (discPage.Contains($"Disc with ID \"{id}\" doesn't exist"))
return null;
else
return discPage;
}
catch (Exception ex)
{
Console.WriteLine($"An exception has occurred: {ex}");
return null;
}
}
/// <summary>
/// Download an individual WIP ID page as a string, if possible
/// </summary>
/// <param name="wc">CookieAwareWebClient to access the pages</param>
/// <param name="id">Redump disc ID to retrieve</param>
/// <returns>WIP disc page as a string, null on error</returns>
private string DownloadSingleWIPID(CookieAwareWebClient wc, int id)
{
string paddedId = id.ToString().PadLeft(5, '0');
Console.WriteLine($"Processing WIP ID: {paddedId}");
try
{
string discPage = wc.DownloadString(string.Format(wipDiscPageUrl, +id));
if (discPage.Contains($"WIP Disc with ID \"{id}\" doesn't exist"))
return null;
else
return discPage;
}
catch (Exception ex)
{
Console.WriteLine($"An exception has occurred: {ex}");
return null;
}
}
#endregion
}
}

View File

@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net462;net472;netcoreapp3.0</TargetFrameworks>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\DICUI.Library\DICUI.Library.csproj">
<Project>{51ab0928-13f9-44bf-a407-b6957a43a056}</Project>
<Name>DICUI.Library</Name>
</ProjectReference>
<ProjectReference Include="..\DICUI\DICUI.csproj">
<Project>{7b1b75eb-8940-466f-bd51-76471a57f9be}</Project>
<Name>DICUI</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeCoverage" Version="16.3.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
<PackageReference Include="xunit.analyzers" Version="0.10.0" />
<PackageReference Include="xunit.assert" Version="2.4.1" />
<PackageReference Include="xunit.core" Version="2.4.1" />
<PackageReference Include="xunit.extensibility.core" Version="2.4.1" />
<PackageReference Include="xunit.extensibility.execution" Version="2.4.1" />
<PackageReference Include="xunit.runner.console" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
</ItemGroup>
</Project>

40
DICUI.Test/ResultTest.cs Normal file
View File

@@ -0,0 +1,40 @@
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test
{
public class ResultTest
{
[Fact]
public void ResultSuccessTest()
{
Result actual = Result.Success();
Assert.Empty(actual.Message);
string message = "Success!";
actual = Result.Success(message);
Assert.Equal(message, actual.Message);
message = "Success! {0}";
string parameter = "Parameter";
actual = Result.Success(message, parameter);
Assert.Equal(string.Format(message, parameter), actual.Message);
}
[Fact]
public void ResultFailureTest()
{
Result actual = Result.Failure();
Assert.Empty(actual.Message);
string message = "Failure!";
actual = Result.Failure(message);
Assert.Equal(message, actual.Message);
message = "Failure! {0}";
string parameter = "Parameter";
actual = Result.Failure(message, parameter);
Assert.Equal(string.Format(message, parameter), actual.Message);
}
}
}

View File

@@ -0,0 +1,21 @@
using System.Linq;
using DICUI.Data;
using Xunit;
namespace DICUI.Test.Data
{
public class UIElementsTest
{
[Theory]
[InlineData(MediaType.CDROM, 72)]
[InlineData(MediaType.DVD, 24)]
[InlineData(MediaType.BluRay, 16)]
[InlineData(MediaType.LaserDisc, 72)] // TODO: Update when fully determined
[InlineData(null, 72)] // TODO: Update when fully determined
public void GetAllowedDriveSpeedForMediaTypeTest(MediaType? mediaType, int maxExpected)
{
var actual = Constants.GetSpeedsForMediaType(mediaType);
Assert.Equal(maxExpected, actual.Last());
}
}
}

View File

@@ -0,0 +1,129 @@
using System;
using DICUI.Data;
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test.Utilities
{
public class ConvertersTest
{
[Theory]
[InlineData(DICCommand.Audio, MediaType.CDROM)]
[InlineData(DICCommand.BluRay, MediaType.BluRay)]
[InlineData(DICCommand.Close, null)]
[InlineData(DICCommand.CompactDisc, MediaType.CDROM)]
[InlineData(DICCommand.Data, MediaType.CDROM)]
[InlineData(DICCommand.DigitalVideoDisc, MediaType.DVD)]
[InlineData(DICCommand.Eject, null)]
[InlineData(DICCommand.Floppy, MediaType.FloppyDisk)]
[InlineData(DICCommand.GDROM, MediaType.GDROM)]
[InlineData(DICCommand.MDS, null)]
[InlineData(DICCommand.Reset, null)]
[InlineData(DICCommand.SACD, MediaType.CDROM)]
[InlineData(DICCommand.Start, null)]
[InlineData(DICCommand.Stop, null)]
[InlineData(DICCommand.Sub, null)]
[InlineData(DICCommand.Swap, MediaType.GDROM)]
[InlineData(DICCommand.XBOX, MediaType.DVD)]
public void BaseCommandToMediaTypeTest(DICCommand command, MediaType? expected)
{
MediaType? actual = command.ToMediaType();
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(DICCommand.Audio, KnownSystem.AudioCD)]
[InlineData(DICCommand.BluRay, KnownSystem.SonyPlayStation3)]
[InlineData(DICCommand.Close, null)]
[InlineData(DICCommand.CompactDisc, KnownSystem.IBMPCCompatible)]
[InlineData(DICCommand.Data, KnownSystem.IBMPCCompatible)]
[InlineData(DICCommand.DigitalVideoDisc, KnownSystem.IBMPCCompatible)]
[InlineData(DICCommand.Eject, null)]
[InlineData(DICCommand.Floppy, KnownSystem.IBMPCCompatible)]
[InlineData(DICCommand.GDROM, KnownSystem.SegaDreamcast)]
[InlineData(DICCommand.MDS, null)]
[InlineData(DICCommand.Reset, null)]
[InlineData(DICCommand.SACD, KnownSystem.SuperAudioCD)]
[InlineData(DICCommand.Start, null)]
[InlineData(DICCommand.Stop, null)]
[InlineData(DICCommand.Sub, null)]
[InlineData(DICCommand.Swap, KnownSystem.SegaDreamcast)]
[InlineData(DICCommand.XBOX, KnownSystem.MicrosoftXBOX)]
public void BaseCommandToKnownSystemTest(DICCommand command, KnownSystem? expected)
{
KnownSystem? actual = Converters.ToKnownSystem(command);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(MediaType.CDROM, ".bin")]
[InlineData(MediaType.DVD, ".iso")]
[InlineData(MediaType.LaserDisc, ".raw")]
[InlineData(MediaType.NintendoWiiUOpticalDisc, ".wud")]
[InlineData(MediaType.FloppyDisk, ".img")]
[InlineData(MediaType.Cassette, ".wav")]
[InlineData(MediaType.NONE, null)]
public void MediaTypeToExtensionTest(MediaType? mediaType, string expected)
{
string actual = Converters.Extension(mediaType);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(MediaType.CDROM, "CD-ROM")]
[InlineData(MediaType.LaserDisc, "LD-ROM / LV-ROM")]
[InlineData(MediaType.NONE, "Unknown")]
public void MediaTypeToStringTest(MediaType? mediaType, string expected)
{
string actual = Converters.LongName(mediaType);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(KnownSystem.MicrosoftXBOX, "Microsoft XBOX")]
[InlineData(KnownSystem.NECPC88, "NEC PC-88")]
[InlineData(KnownSystem.KonamiPython, "Konami Python")]
[InlineData(KnownSystem.HDDVDVideo, "HD-DVD-Video")]
[InlineData(KnownSystem.NONE, "Unknown")]
public void KnownSystemToStringTest(KnownSystem? knownSystem, string expected)
{
string actual = Converters.LongName(knownSystem);
Assert.Equal(expected, actual);
}
[Fact]
public void KnownSystemHasValidCategory()
{
var values = Validators.CreateListOfSystems();
KnownSystem[] markers = { KnownSystem.MarkerArcadeEnd, KnownSystem.MarkerDiscBasedConsoleEnd, /* KnownSystem.MarkerOtherConsoleEnd, */ KnownSystem.MarkerComputerEnd, KnownSystem.MarkerOtherEnd };
values.ForEach(system => {
if (system == KnownSystem.NONE)
return;
// we check that the category is the first category value higher than the system
KnownSystemCategory category = ((KnownSystem?)system).Category();
KnownSystem marker = KnownSystem.NONE;
switch (category)
{
case KnownSystemCategory.Arcade: marker = KnownSystem.MarkerArcadeEnd; break;
case KnownSystemCategory.DiscBasedConsole: marker = KnownSystem.MarkerDiscBasedConsoleEnd; break;
/* case KnownSystemCategory.OtherConsole: marker = KnownSystem.MarkerOtherConsoleEnd; break; */
case KnownSystemCategory.Computer: marker = KnownSystem.MarkerComputerEnd; break;
case KnownSystemCategory.Other: marker = KnownSystem.MarkerOtherEnd; break;
}
Assert.NotEqual(KnownSystem.NONE, marker);
Assert.True(marker > system);
Array.ForEach(markers, mmarker =>
{
// a marker can be the same of the found one, or one of a category before or a category after but never in the middle between
// the system and the mapped category
Assert.True(mmarker == marker || mmarker < system || mmarker > marker);
});
});
}
}
}

View File

@@ -0,0 +1,96 @@
using System.IO;
using DICUI.Data;
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test
{
public class DumpEnvironmentTest
{
[Theory]
[InlineData(null, 'D', false, MediaType.NONE, false)]
[InlineData("", 'D', false, MediaType.NONE, false)]
[InlineData("cd F test.bin 8 /c2 20", 'F', false, MediaType.CDROM, true)]
[InlineData("fd A test.img", 'A', true, MediaType.FloppyDisk, true)]
[InlineData("dvd X test.iso 8 /raw", 'X', false, MediaType.FloppyDisk, false)]
[InlineData("stop D", 'D', false, MediaType.DVD, true)]
public void ParametersValidTest(string parameters, char letter, bool isFloppy, MediaType? mediaType, bool expected)
{
var env = new DumpEnvironment
{
DICParameters = new Parameters(parameters),
Drive = isFloppy
? new Drive(InternalDriveType.Floppy, new DriveInfo(letter.ToString()))
: new Drive(InternalDriveType.Optical, new DriveInfo(letter.ToString())),
Type = mediaType,
};
bool actual = env.ParametersValid();
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(null, null, null, null)]
[InlineData(" ", "", " ", "")]
[InlineData("super", "blah.bin", "super", "blah.bin")]
[InlineData("super\\hero", "blah.bin", "super\\hero", "blah.bin")]
[InlineData("super.hero", "blah.bin", "super.hero", "blah.bin")]
[InlineData("superhero", "blah.rev.bin", "superhero", "blah.rev.bin")]
[InlineData("super&hero", "blah.bin", "super_hero", "blah.bin")]
[InlineData("superhero", "blah&foo.bin", "superhero", "blah_foo.bin")]
public void FixOutputPathsTest(string outputDirectory, string outputFilename, string expectedOutputDirectory, string expectedOutputFilename)
{
var env = new DumpEnvironment
{
OutputDirectory = outputDirectory,
OutputFilename = outputFilename,
};
env.FixOutputPaths();
Assert.Equal(expectedOutputDirectory, env.OutputDirectory);
Assert.Equal(expectedOutputFilename, env.OutputFilename);
}
[Fact]
public void GetFirstTrackTest()
{
// TODO: Implement
Assert.True(true);
}
[Fact]
public void FormatOutputDataTest()
{
// TODO: Implement
Assert.True(true);
}
[Fact]
public void WriteOutputDataTest()
{
// TODO: Implement
Assert.True(true);
}
[Fact]
public void EjectDiscTest()
{
// TODO: Implement
Assert.True(true);
}
[Fact]
public void CancelDumpingTest()
{
// TODO: Implement
Assert.True(true);
}
[Fact]
public void StartDumpingTest()
{
// TODO: Implement
Assert.True(true);
}
}
}

View File

@@ -0,0 +1,37 @@
using System;
using DICUI.Data;
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test.Utilities
{
public class KnownSystemExtensionsTest
{
[Fact]
public void IsMarkerTest()
{
var values = (KnownSystem[])Enum.GetValues(typeof(KnownSystem));
foreach(var system in values)
{
bool expected = system == KnownSystem.MarkerArcadeEnd || system == KnownSystem.MarkerComputerEnd ||
system == KnownSystem.MarkerOtherEnd || system == KnownSystem.MarkerDiscBasedConsoleEnd;
// || system == KnownSystem.MarkerOtherConsoleEnd;
bool actual = ((KnownSystem?)system).IsMarker();
Assert.Equal(expected, actual);
}
}
[Fact]
public void CategoryNameNotEmptyTest()
{
var values = (KnownSystemCategory[])Enum.GetValues(typeof(KnownSystemCategory));
foreach (var system in values)
{
string actual = ((KnownSystem?)system).LongName();
Assert.NotEqual("", actual);
}
}
}
}

View File

@@ -0,0 +1,46 @@
using DICUI.Data;
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test.Utilities
{
public class MediaTypeExtensionsTest
{
[Theory]
[InlineData(MediaType.CDROM, "CD-ROM")]
[InlineData(MediaType.LaserDisc, "LD-ROM / LV-ROM")]
[InlineData(MediaType.NONE, "Unknown")]
public void NameTest(MediaType? mediaType, string expected)
{
string actual = mediaType.LongName();
Assert.NotNull(actual);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(MediaType.CDROM, ".bin")]
[InlineData(MediaType.DVD, ".iso")]
[InlineData(MediaType.LaserDisc, ".raw")]
[InlineData(MediaType.FloppyDisk, ".img")]
[InlineData(MediaType.NONE, null)]
public void ExtensionTest(MediaType? mediaType, string expected)
{
string actual = mediaType.Extension();
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(MediaType.CDROM, true)]
[InlineData(MediaType.DVD, true)]
[InlineData(MediaType.FloppyDisk, false)]
[InlineData(MediaType.BluRay, true)]
[InlineData(MediaType.LaserDisc, false)]
public void DriveSpeedSupportedTest(MediaType? mediaType, bool expected)
{
bool actual = mediaType.DoesSupportDriveSpeed();
Assert.Equal(expected, actual);
}
}
}

View File

@@ -0,0 +1,85 @@
using System.Collections.Generic;
using System.Linq;
using DICUI.Data;
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test.Utilities
{
public class ParametersTest
{
[Theory]
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.CDROM, DICCommand.CompactDisc)]
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.DVD, DICCommand.XBOX)]
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.LaserDisc, DICCommand.NONE)]
[InlineData(KnownSystem.SegaNu, MediaType.BluRay, DICCommand.BluRay)]
[InlineData(KnownSystem.AppleMacintosh, MediaType.FloppyDisk, DICCommand.Floppy)]
[InlineData(KnownSystem.RawThrillsVarious, MediaType.GDROM, DICCommand.NONE)]
public void ParametersFromSystemAndTypeTest(KnownSystem? knownSystem, MediaType? mediaType, DICCommand expected)
{
Parameters actual = new Parameters(knownSystem, mediaType, 'D', "disc.bin", 16, true, -1);
Assert.Equal(expected, actual.Command);
}
[Theory]
[InlineData(KnownSystem.AppleMacintosh, MediaType.LaserDisc, true, 20, null, null)]
[InlineData(KnownSystem.NintendoGameCube, MediaType.NintendoGameCubeGameDisc, false, 20, null, new DICFlag[] { DICFlag.Raw })]
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, false, 20, null, new DICFlag[] { })]
/* paranoid mode tests */
[InlineData(KnownSystem.IBMPCCompatible, MediaType.CDROM, true, 1000, 2, new DICFlag[] { DICFlag.C2Opcode, DICFlag.NoFixSubQSecuROM, DICFlag.ScanFileProtect, DICFlag.ScanSectorProtect, DICFlag.SubchannelReadLevel })]
[InlineData(KnownSystem.AppleMacintosh, MediaType.CDROM, false, 20, null, new DICFlag[] { DICFlag.C2Opcode, DICFlag.NoFixSubQSecuROM, DICFlag.ScanFileProtect })]
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, true, 500, null, new DICFlag[] { DICFlag.CopyrightManagementInformation, DICFlag.ScanFileProtect })]
[InlineData(KnownSystem.HDDVDVideo, MediaType.HDDVD, true, 500, null, new DICFlag[] { DICFlag.CopyrightManagementInformation })]
[InlineData(KnownSystem.IBMPCCompatible, MediaType.DVD, false, 500, null, new DICFlag[] { })]
[InlineData(KnownSystem.HDDVDVideo, MediaType.HDDVD, false, 500, null, new DICFlag[] { })]
/* reread c2 */
[InlineData(KnownSystem.SegaDreamcast, MediaType.GDROM, false, 1000, null, new DICFlag[] { DICFlag.C2Opcode })]
[InlineData(KnownSystem.SegaDreamcast, MediaType.GDROM, false, -1, null, new DICFlag[] { DICFlag.C2Opcode })]
public void ParametersFromOptionsTest(KnownSystem? knownSystem, MediaType? mediaType, bool paranoid, int rereadC2, int? subchannelLevel, DICFlag[] expected)
{
Parameters actual = new Parameters(knownSystem, mediaType, 'D', "disc.bin", 16, paranoid, rereadC2);
HashSet<DICFlag> expectedSet = new HashSet<DICFlag>(expected ?? new DICFlag[0]);
HashSet<DICFlag> actualSet = new HashSet<DICFlag>(actual.Keys ?? new DICFlag[0]);
Assert.Equal(expectedSet, actualSet);
if (rereadC2 == -1 || !Validators.GetValidMediaTypes(knownSystem).Contains(mediaType))
Assert.Null(actual.C2OpcodeValue[0]);
else
Assert.Equal(rereadC2, actual.C2OpcodeValue[0]);
Assert.Equal(subchannelLevel, actual.SubchannelReadLevelValue);
}
[Theory]
[InlineData(null, null, null, null, null)]
[InlineData("", null, null, null, null)]
[InlineData("cd F test.bin 8 /c2 20", MediaType.CDROM, KnownSystem.IBMPCCompatible, "F", "test.bin")]
[InlineData("fd A blah\\test.img", MediaType.FloppyDisk, KnownSystem.IBMPCCompatible, "A", "blah\\test.img")]
[InlineData("dvd X super\\blah\\test.iso 8 /raw", MediaType.NintendoGameCubeGameDisc, KnownSystem.NintendoGameCube, "X", "super\\blah\\test.iso")]
[InlineData("stop D", null, null, "D", null)]
public void DetermineFlagsTest(string parameters, MediaType? expectedMediaType, KnownSystem? expectedKnownSystem, string expectedDriveLetter, string expectedPath)
{
Parameters actualParams = new Parameters(parameters);
bool actual = actualParams.DetermineFlags(out MediaType? actualMediaType, out KnownSystem? actualKnownSystem, out string actualDriveLetter, out string actualPath);
Assert.Equal(expectedMediaType, actualMediaType);
Assert.Equal(expectedKnownSystem, actualKnownSystem);
Assert.Equal(expectedDriveLetter, actualDriveLetter);
Assert.Equal(expectedPath, actualPath);
}
[Theory]
[InlineData(null, false)]
[InlineData("", false)]
[InlineData("cd F test.bin 8 /c2 20", true)]
[InlineData("fd A test.img", true)]
[InlineData("dvd X super\\test.iso 8 /raw", true)]
[InlineData("bd D longer\\path_test.iso 16", true)]
[InlineData("stop D", true)]
[InlineData("ls", false)]
public void ValidateParametersTest(string parameters, bool expected)
{
Parameters actual = new Parameters(parameters);
Assert.Equal(expected, actual.IsValid());
}
}
}

View File

@@ -0,0 +1,45 @@
using System;
using DICUI.Data;
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test.Utilities
{
public class ValidatorsTest
{
[Theory]
[InlineData(KnownSystem.BandaiApplePippin, MediaType.CDROM)]
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.DVD)]
[InlineData(KnownSystem.NintendoGameCube, MediaType.NintendoGameCubeGameDisc)]
[InlineData(KnownSystem.NintendoWii, MediaType.NintendoWiiOpticalDisc)]
[InlineData(KnownSystem.NintendoWiiU, MediaType.NintendoWiiUOpticalDisc)]
[InlineData(KnownSystem.SonyPlayStationPortable, MediaType.UMD)]
public void GetValidMediaTypesTest(KnownSystem? knownSystem, MediaType? expected)
{
var actual = Validators.GetValidMediaTypes(knownSystem);
Assert.Contains(expected, actual);
}
[Fact]
public void CreateListOfSystemsTest()
{
int expected = Enum.GetValues(typeof(KnownSystem)).Length - 5; // - 4 -1 for markers categories and KnownSystem.NONE
var actual = Validators.CreateListOfSystems();
Assert.Equal(expected, actual.Count);
}
[Fact]
public void CreateListOfDrivesTest()
{
// TODO: Implement
Assert.True(true);
}
[Fact]
public void GetDiscTypeTest()
{
// TODO: Implement
Assert.True(true);
}
}
}

View File

@@ -1,136 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7B1B75EB-8940-466F-BD51-76471A57F9BE}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>DICUI</RootNamespace>
<AssemblyName>DICUI</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>C:\Users\admin\Desktop\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>1</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<PublishWizardCompleted>true</PublishWizardCompleted>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Icon.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<ManifestCertificateThumbprint>654CEE5FEAF46C8C1C369D7ED34DA157828A8D2F</ManifestCertificateThumbprint>
</PropertyGroup>
<PropertyGroup>
<ManifestKeyFile>WpfApp1_TemporaryKey.pfx</ManifestKeyFile>
</PropertyGroup>
<PropertyGroup>
<GenerateManifests>true</GenerateManifests>
</PropertyGroup>
<PropertyGroup>
<SignManifests>false</SignManifests>
</PropertyGroup>
<PropertyGroup />
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.6.1">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.6.1 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Resource Include="Icon.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -1,9 +1,22 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2036
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.156
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI", "DICUI.csproj", "{7B1B75EB-8940-466F-BD51-76471A57F9BE}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI", "DICUI\DICUI.csproj", "{7B1B75EB-8940-466F-BD51-76471A57F9BE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI.Test", "DICUI.Test\DICUI.Test.csproj", "{7CC064D2-38AB-4A05-8519-28660DE4562A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI.Library", "DICUI.Library\DICUI.Library.csproj", "{51AB0928-13F9-44BF-A407-B6957A43A056}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI.Check", "DICUI.Check\DICUI.Check.csproj", "{8CFDE289-E171-4D49-A40D-5293265C1253}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4D1DCF5A-F0B0-4E81-A05B-F1A7D37C9D9D}"
ProjectSection(SolutionItems) = preProject
appveyor.yml = appveyor.yml
CHANGELIST.md = CHANGELIST.md
README.md = README.md
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -15,6 +28,18 @@ Global
{7B1B75EB-8940-466F-BD51-76471A57F9BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B1B75EB-8940-466F-BD51-76471A57F9BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B1B75EB-8940-466F-BD51-76471A57F9BE}.Release|Any CPU.Build.0 = Release|Any CPU
{7CC064D2-38AB-4A05-8519-28660DE4562A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7CC064D2-38AB-4A05-8519-28660DE4562A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7CC064D2-38AB-4A05-8519-28660DE4562A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7CC064D2-38AB-4A05-8519-28660DE4562A}.Release|Any CPU.Build.0 = Release|Any CPU
{51AB0928-13F9-44BF-A407-B6957A43A056}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{51AB0928-13F9-44BF-A407-B6957A43A056}.Debug|Any CPU.Build.0 = Debug|Any CPU
{51AB0928-13F9-44BF-A407-B6957A43A056}.Release|Any CPU.ActiveCfg = Release|Any CPU
{51AB0928-13F9-44BF-A407-B6957A43A056}.Release|Any CPU.Build.0 = Release|Any CPU
{8CFDE289-E171-4D49-A40D-5293265C1253}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8CFDE289-E171-4D49-A40D-5293265C1253}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8CFDE289-E171-4D49-A40D-5293265C1253}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8CFDE289-E171-4D49-A40D-5293265C1253}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

22
DICUI/App.config Normal file
View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="DICPath" value="Programs\DiscImageCreator.exe"/>
<add key="SubDumpPath" value="subdump.exe"/>
<add key="DefaultOutputPath" value="ISO"/>
<add key="PreferredDumpSpeedCD" value="72"/>
<add key="PreferredDumpSpeedDVD" value="24"/>
<add key="PreferredDumpSpeedBD" value="16"/>
<add key="QuietMode" value="false"/>
<add key="ParanoidMode" value="false"/>
<add key="ScanForProtection" value="true"/>
<add key="SkipMediaTypeDetection" value="false"/>
<add key="SkipSystemDetection" value="false"/>
<add key="RereadAmountForC2" value="20"/>
<add key="VerboseLogging" value="true"/>
<add key="OpenLogWindowAtStartup" value="true"/>
<add key="AddPlaceholders" value="true"/>
<add key="Username" value=""/>
<add key="Password" value=""/>
</appSettings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2"/></startup></configuration>

View File

@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DICUI"
StartupUri="MainWindow.xaml">
StartupUri="Windows\MainWindow.xaml">
<Application.Resources>
</Application.Resources>

11
DICUI/App.xaml.cs Normal file
View File

@@ -0,0 +1,11 @@
using System.Windows;
namespace DICUI
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}

View File

@@ -0,0 +1,29 @@
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI
{
/// <summary>
/// Represents a single item in the Category combo box
/// </summary>
public class CategoryComboBoxItem
{
private object data;
public CategoryComboBoxItem(Category? category) => data = category;
public static implicit operator Category? (CategoryComboBoxItem item) => item.data as Category?;
public string Name
{
get { return (data as Category?).LongName(); }
}
public bool IsChecked { get; set; }
public Category? Value
{
get { return data as Category?; }
}
}
}

View File

@@ -0,0 +1,35 @@
using System.Windows.Media;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI
{
/// <summary>
/// Represents a single item in the System combo box
/// </summary>
public class KnownSystemComboBoxItem
{
private object data;
public KnownSystemComboBoxItem(KnownSystem? system) => data = system;
public KnownSystemComboBoxItem(KnownSystemCategory? category) => data = category;
public Brush Foreground { get => IsHeader() ? Brushes.Gray : Brushes.Black; }
public bool IsHeader() => data is KnownSystemCategory?;
public bool IsSystem() => data is KnownSystem?;
public static implicit operator KnownSystem? (KnownSystemComboBoxItem item) => item.data as KnownSystem?;
public string Name
{
get
{
if (IsHeader())
return "---------- " + (data as KnownSystemCategory?).LongName() + " ----------";
else
return (data as KnownSystem?).LongName();
}
}
}
}

View File

@@ -0,0 +1,29 @@
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI
{
/// <summary>
/// Represents a single item in the Language combo box
/// </summary>
public class LanguageComboBoxItem
{
private object data;
public LanguageComboBoxItem(Language? region) => data = region;
public static implicit operator Language? (LanguageComboBoxItem item) => item.data as Language?;
public string Name
{
get { return (data as Language?).LongName(); }
}
public bool IsChecked { get; set; }
public Language? Value
{
get { return data as Language?; }
}
}
}

View File

@@ -0,0 +1,20 @@
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI
{
/// <summary>
/// Represents a single item in the MediaType combo box
/// </summary>
public class MediaTypeComboBoxItem
{
private MediaType? data;
public MediaTypeComboBoxItem(MediaType? mediaType) => data = mediaType;
public static implicit operator MediaType? (MediaTypeComboBoxItem item) => item.data;
public string Name { get { return data.LongName(); }
}
}
}

View File

@@ -0,0 +1,30 @@
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI
{
/// <summary>
/// Represents a single item in the Region combo box
/// </summary>
public class RegionComboBoxItem
{
private object data;
public RegionComboBoxItem(Region? region) => data = region;
public static implicit operator Region? (RegionComboBoxItem item) => item.data as Region?;
public string Name
{
get
{
return (data as Region?).LongName();
}
}
public Region? Value
{
get { return data as Region?; }
}
}
}

56
DICUI/Constants.cs Normal file
View File

@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media;
using DICUI.Data;
namespace DICUI
{
/// <summary>
/// Variables for UI elements
/// </summary>
public static class Constants
{
public const string StartDumping = "Start Dumping";
public const string StopDumping = "Stop Dumping";
public const int LogWindowMarginFromMainWindow = 10;
// Private lists of known drive speed ranges
private static IReadOnlyList<int> cd { get; } = new List<int> { 1, 2, 3, 4, 6, 8, 12, 16, 20, 24, 32, 40, 44, 48, 52, 56, 72 };
private static IReadOnlyList<int> dvd { get; } = cd.Where(s => s <= 24).ToList();
private static IReadOnlyList<int> bd { get; } = cd.Where(s => s <= 16).ToList();
private static IReadOnlyList<int> unknown { get; } = cd; // TODO: All or {1}? Maybe null?
/// <summary>
/// Get list of all drive speeds for a given MediaType
/// </summary>
/// <param name="type">MediaType? that represents the current item</param>
/// <returns>Read-only list of drive speeds</returns>
public static IReadOnlyList<int> GetSpeedsForMediaType(MediaType? type)
{
switch (type)
{
case MediaType.CDROM:
case MediaType.GDROM:
return cd;
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return dvd;
case MediaType.BluRay:
return bd;
default:
return unknown;
}
}
// Create collections for UI based on known drive speeds
public static DoubleCollection SpeedsForCDAsCollection { get; } = GetDoubleCollectionFromIntList(cd);
public static DoubleCollection SpeedsForDVDAsCollection { get; } = GetDoubleCollectionFromIntList(dvd);
public static DoubleCollection SpeedsForBDAsCollection { get; } = GetDoubleCollectionFromIntList(bd);
private static DoubleCollection GetDoubleCollectionFromIntList(IReadOnlyList<int> list)
=> new DoubleCollection(list.Select(i => Convert.ToDouble(i)).ToList());
}
}

28
DICUI/DICUI.csproj Normal file
View File

@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<TargetFrameworks>net462;net472;netcoreapp3.0</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<OutputType>WinExe</OutputType>
<UseWindowsForms>true</UseWindowsForms>
<UseWPF>true</UseWPF>
<Prefer32Bit>true</Prefer32Bit>
<ApplicationIcon>Icon.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.6.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DICUI.Library\DICUI.Library.csproj">
<Project>{51ab0928-13f9-44bf-a407-b6957a43a056}</Project>
<Name>DICUI.Library</Name>
</ProjectReference>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,33 @@
using System;
using System.Globalization;
using System.Windows.Data;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI
{
/// <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 DICCommand)
return ((DICCommand)value).LongName();
else if (value is DICFlag)
return ((DICFlag)value).LongName();
else if (value is MediaType?)
return ((MediaType?)value).LongName();
else if (value is KnownSystem?)
return ((KnownSystem?)value).LongName();
else
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return string.Empty;
}
}
}

View File

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

199
DICUI/Options.cs Normal file
View File

@@ -0,0 +1,199 @@
using System;
using System.Configuration;
using System.Linq;
using System.Reflection;
using DICUI.Data;
namespace DICUI
{
public class Options
{
public string DefaultOutputPath { get; private set; }
public string DICPath { get; private set; }
public string SubDumpPath { get; private set; }
public int PreferredDumpSpeedCD { get; set; }
public int PreferredDumpSpeedDVD { get; set; }
public int PreferredDumpSpeedBD { get; set; }
public bool QuietMode { get; set; }
public bool ParanoidMode { get; set; }
public bool ScanForProtection { get; set; }
public int RereadAmountForC2 { get; set; }
public bool AddPlaceholders { get; set; }
public bool PromptForDiscInformation { get; set; }
public bool SkipMediaTypeDetection { get; set; }
public bool SkipSystemDetection { get; set; }
public bool VerboseLogging { get; set; }
public bool OpenLogWindowAtStartup { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public void Save()
{
Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
//TODO: reflection is used
//TODO: is remove needed, doesn't the value get directly overridden
Array.ForEach(
GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance),
p => {
configFile.AppSettings.Settings.Remove(p.Name);
configFile.AppSettings.Settings.Add(p.Name, Convert.ToString(p.GetValue(this)));
}
);
configFile.Save(ConfigurationSaveMode.Modified);
}
public void Load()
{
Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
//TODO: hardcoded, we should find a better way
this.DICPath = GetStringSetting(configFile, "DICPath", "Programs\\DiscImageCreator.exe");
this.SubDumpPath = GetStringSetting(configFile, "SubDumpPath", "subdump.exe");
this.DefaultOutputPath = GetStringSetting(configFile, "DefaultOutputPath", "ISO");
this.PreferredDumpSpeedCD = GetInt32Setting(configFile, "PreferredDumpSpeedCD", 72);
this.PreferredDumpSpeedDVD = GetInt32Setting(configFile, "PreferredDumpSpeedDVD", 24);
this.PreferredDumpSpeedBD = GetInt32Setting(configFile, "PreferredDumpSpeedBD", 16);
this.QuietMode = GetBooleanSetting(configFile, "QuietMode", false);
this.ParanoidMode = GetBooleanSetting(configFile, "ParanoidMode", false);
this.ScanForProtection = GetBooleanSetting(configFile, "ScanForProtection", true);
this.SkipMediaTypeDetection = GetBooleanSetting(configFile, "SkipMediaTypeDetection", false);
this.SkipSystemDetection = GetBooleanSetting(configFile, "SkipSystemDetection", false);
this.RereadAmountForC2 = GetInt32Setting(configFile, "RereadAmountForC2", 20);
this.VerboseLogging = GetBooleanSetting(configFile, "VerboseLogging", true);
this.OpenLogWindowAtStartup = GetBooleanSetting(configFile, "OpenLogWindowAtStartup", true);
this.AddPlaceholders = GetBooleanSetting(configFile, "AddPlaceholders", true);
this.PromptForDiscInformation = GetBooleanSetting(configFile, "PromptForDiscInformation", true);
this.Username = GetStringSetting(configFile, "Username", "");
this.Password = GetStringSetting(configFile, "Password", "");
}
/// <summary>
/// Get a boolean setting from a configuration
/// </summary>
/// <param name="configFile">Current configuration file</param>
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
public bool GetBooleanSetting(Configuration configFile, string key, bool defaultValue)
{
var settings = configFile.AppSettings.Settings;
if (settings.AllKeys.Contains(key))
{
if (Boolean.TryParse(settings[key].Value, out bool value))
return value;
else
return defaultValue;
}
else
{
return defaultValue;
}
}
/// <summary>
/// Get a boolean setting from a configuration
/// </summary>
/// <param name="configFile">Current configuration file</param>
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
public int GetInt32Setting(Configuration configFile, string key, int defaultValue)
{
var settings = configFile.AppSettings.Settings;
if (settings.AllKeys.Contains(key))
{
if (Int32.TryParse(settings[key].Value, out int value))
return value;
else
return defaultValue;
}
else
{
return defaultValue;
}
}
/// <summary>
/// Get a boolean setting from a configuration
/// </summary>
/// <param name="configFile">Current configuration file</param>
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
public long GetInt64Setting(Configuration configFile, string key, long defaultValue)
{
var settings = configFile.AppSettings.Settings;
if (settings.AllKeys.Contains(key))
{
if (Int64.TryParse(settings[key].Value, out long value))
return value;
else
return defaultValue;
}
else
{
return defaultValue;
}
}
/// <summary>
/// Get a boolean setting from a configuration
/// </summary>
/// <param name="configFile">Current configuration file</param>
/// <param name="key">Setting key to get a value for</param>
/// <param name="defaultValue">Default value to return if no value is found</param>
/// <returns>Setting value if possible, default value otherwise</returns>
public string GetStringSetting(Configuration configFile, string key, string defaultValue)
{
var settings = configFile.AppSettings.Settings;
if (settings.AllKeys.Contains(key))
return settings[key].Value;
else
return defaultValue;
}
//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;
}
public int GetPreferredDumpSpeedForMediaType(MediaType? type)
{
switch (type)
{
case MediaType.CDROM:
case MediaType.GDROM:
return PreferredDumpSpeedCD;
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return PreferredDumpSpeedDVD;
case MediaType.BluRay:
return PreferredDumpSpeedBD;
default:
return 8;
}
}
}
}

View File

@@ -12,7 +12,7 @@ using System.Windows;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DICUI")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -51,5 +51,8 @@ using System.Windows;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.15")]
[assembly: AssemblyFileVersion("1.15.0.0")]
// Anything marked as internal can be used by the test methods
[assembly: InternalsVisibleTo("DICUI.Test")]

113
DICUI/ViewModels.cs Normal file
View File

@@ -0,0 +1,113 @@
using System;
using System.Windows.Media;
using DICUI.Windows;
namespace DICUI
{
public class OptionsViewModel
{
private Options _options;
public OptionsViewModel(Options options)
{
this._options = options;
}
public bool QuietMode
{
get { return _options.QuietMode; }
set { _options.QuietMode = value; }
}
public bool ParanoidMode
{
get { return _options.ParanoidMode; }
set { _options.ParanoidMode = value; }
}
public bool ScanForProtection
{
get { return _options.ScanForProtection; }
set { _options.ScanForProtection = value; }
}
public bool SkipMediaTypeDetection
{
get { return _options.SkipMediaTypeDetection; }
set { _options.SkipMediaTypeDetection = value; }
}
public bool SkipSystemDetection
{
get { return _options.SkipSystemDetection; }
set { _options.SkipSystemDetection = value; }
}
public string RereadAmountForC2
{
get { return Convert.ToString(_options.RereadAmountForC2); }
set
{
if (Int32.TryParse(value, out int result))
_options.RereadAmountForC2 = result;
}
}
public bool VerboseLogging
{
get { return _options.VerboseLogging; }
set
{
_options.VerboseLogging = value;
_options.Save();
}
}
public bool OpenLogWindowAtStartup
{
get { return _options.OpenLogWindowAtStartup; }
set
{
_options.OpenLogWindowAtStartup = value;
_options.Save();
}
}
}
public class LoggerViewModel
{
private LogWindow _logWindow;
public void SetWindow(LogWindow logWindow) => _logWindow = logWindow;
public bool WindowVisible
{
get => _logWindow != null ? _logWindow.IsVisible : false;
set
{
if (value)
{
_logWindow.AdjustPositionToMainWindow();
_logWindow.Show();
}
else
_logWindow.Hide();
}
}
public void VerboseLog(string text)
{
if (ViewModels.OptionsViewModel.VerboseLogging)
_logWindow.AppendToTextBox(text, Brushes.Yellow);
}
public void VerboseLog(string format, params object[] args) => VerboseLog(string.Format(format, args));
public void VerboseLogLn(string format, params object[] args) => VerboseLog(string.Format(format, args) + "\n");
}
public static class ViewModels
{
public static OptionsViewModel OptionsViewModel { get; set; }
public static LoggerViewModel LoggerViewModel { get; set; } = new LoggerViewModel();
}
}

View File

@@ -0,0 +1,156 @@
<Window x:Class="DICUI.Windows.DiscInformationWindow"
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="Disc Information" Height="705" Width="515.132" ResizeMode="NoResize"
Closed="OnClosed">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="585"/>
<RowDefinition Height="80"/>
</Grid.RowDefinitions>
<GroupBox Grid.Row="0" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Common Disc Information">
<Grid Margin="10,15,10,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Title" />
<TextBox x:Name="TitleTextBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Foreign Title (Non-Latin)" />
<TextBox x:Name="ForeignTitleTextBox" Grid.Row="1" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Disc Number / Letter" />
<TextBox x:Name="DiscNumberLetterTextBox" Grid.Row="2" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Disc Title" />
<TextBox x:Name="DiscTitleTextBox" Grid.Row="3" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Category" />
<ComboBox x:Name="CategoryComboBox" Grid.Row="4" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Grid.Row="5" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Region" />
<ComboBox x:Name="RegionComboBox" Grid.Row="5" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Grid.Row="6" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Languages" />
<ListBox x:Name="LanguagesComboBox" Grid.Row="6" Grid.Column="1" Height="24" HorizontalAlignment="Stretch" SelectionMode="Multiple">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked}" Content="{Binding Path=Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Label Grid.Row="7" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Serial" />
<TextBox x:Name="SerialTextBox" Grid.Row="7" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<!-- Layer 0 / Data Side -->
<Label Grid.Row="8" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Data/L0 Mastering Ring" />
<TextBox x:Name="L0MasteringRingTextBox" Grid.Row="8" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" AcceptsTab="True" />
<Label Grid.Row="9" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Data/L0 Mastering SID" />
<TextBox x:Name="L0MasteringSIDTextBox" Grid.Row="9" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="10" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Data/L0 Toolstamp/Mastering Code" />
<TextBox x:Name="L0ToolstampTextBox" Grid.Row="10" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="11" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Data/L0 Mould SID" />
<TextBox x:Name="L0MouldSIDTextBox" Grid.Row="11" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="12" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Data/L0 Additional Mould" />
<TextBox x:Name="L0AdditionalMouldTextBox" Grid.Row="12" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<!-- Layer 1 / Label Side -->
<Label Grid.Row="13" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Label/L1 Mastering Ring" />
<TextBox x:Name="L1MasteringRingTextBox" Grid.Row="13" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" AcceptsTab="True" />
<Label Grid.Row="14" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Label/L1 Mastering SID" />
<TextBox x:Name="L1MasteringSIDTextBox" Grid.Row="14" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="15" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Label/L1 Toolstamp/Mastering Code" />
<TextBox x:Name="L1ToolstampTextBox" Grid.Row="15" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="16" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Label/L1 Mould SID" />
<TextBox x:Name="L1MouldSIDTextBox" Grid.Row="16" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="17" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Label/L1 Additional Mould" />
<TextBox x:Name="L1AdditionalMouldTextBox" Grid.Row="17" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="18" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Barcode" />
<TextBox x:Name="BarcodeTextBox" Grid.Row="18" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<!-- This needs to be a multiline textbox -->
<Label Grid.Row="19" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Comments" />
<TextBox x:Name="CommentsTextBox" Grid.Row="19" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" AcceptsReturn="True" AcceptsTab="True" />
<!-- This needs to be a multiline textbox -->
<Label Grid.Row="20" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Contents" />
<TextBox x:Name="ContentsTextBox" Grid.Row="20" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" AcceptsReturn="True" AcceptsTab="True"/>
</Grid>
</GroupBox>
<GroupBox Grid.Row="1" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Version and Editions">
<Grid Height="60">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="24"/>
<RowDefinition Height="24"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Version" />
<TextBox x:Name="VersionTextBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Edition" />
<TextBox x:Name="EditionTextBox" Grid.Row="1" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
</Grid>
</GroupBox>
</Grid>
</Window>

View File

@@ -0,0 +1,163 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using DICUI.Data;
namespace DICUI.Windows
{
/// <summary>
/// Interaction logic for DiscInformationWindow.xaml
/// </summary>
public partial class DiscInformationWindow : Window
{
private readonly MainWindow _mainWindow;
private readonly SubmissionInfo _submissionInfo;
private List<CategoryComboBoxItem> _categories;
private List<RegionComboBoxItem> _regions;
private List<LanguageComboBoxItem> _languages;
public DiscInformationWindow(MainWindow mainWindow, SubmissionInfo submissionInfo)
{
InitializeComponent();
_mainWindow = mainWindow;
_submissionInfo = submissionInfo;
PopulateCategories();
PopulateRegions();
PopulateLanguages();
}
public void Refresh()
{
TitleTextBox.Text = _submissionInfo.CommonDiscInfo.Title ?? "";
ForeignTitleTextBox.Text = _submissionInfo.CommonDiscInfo.ForeignTitleNonLatin ?? "";
DiscNumberLetterTextBox.Text = _submissionInfo.CommonDiscInfo.DiscNumberLetter ?? "";
DiscTitleTextBox.Text = _submissionInfo.CommonDiscInfo.DiscTitle ?? "";
CategoryComboBox.SelectedIndex = _categories.FindIndex(r => r == _submissionInfo.CommonDiscInfo.Category);
RegionComboBox.SelectedIndex = _regions.FindIndex(r => r == _submissionInfo.CommonDiscInfo.Region);
if (_submissionInfo.CommonDiscInfo.Languages != null)
{
foreach (var language in _submissionInfo.CommonDiscInfo.Languages)
_languages.Find(l => l == language).IsChecked = true;
}
SerialTextBox.Text = _submissionInfo.CommonDiscInfo.Serial ?? "";
L0MasteringRingTextBox.Text = _submissionInfo.CommonDiscInfo.MasteringRingFirstLayerDataSide ?? "";
L0MasteringSIDTextBox.Text = _submissionInfo.CommonDiscInfo.MasteringSIDCodeFirstLayerDataSide ?? "";
L0ToolstampTextBox.Text = _submissionInfo.CommonDiscInfo.ToolstampMasteringCodeFirstLayerDataSide ?? "";
L0MouldSIDTextBox.Text = _submissionInfo.CommonDiscInfo.MouldSIDCodeFirstLayerDataSide ?? "";
L0AdditionalMouldTextBox.Text = _submissionInfo.CommonDiscInfo.AdditionalMouldFirstLayerDataSide ?? "";
L1MasteringRingTextBox.Text = _submissionInfo.CommonDiscInfo.MasteringRingSecondLayerLabelSide ?? "";
L1MasteringSIDTextBox.Text = _submissionInfo.CommonDiscInfo.MasteringSIDCodeSecondLayerLabelSide ?? "";
L1ToolstampTextBox.Text = _submissionInfo.CommonDiscInfo.ToolstampMasteringCodeSecondLayerLabelSide ?? "";
L1MouldSIDTextBox.Text = _submissionInfo.CommonDiscInfo.MouldSIDCodeSecondLayerLabelSide ?? "";
L1AdditionalMouldTextBox.Text = _submissionInfo.CommonDiscInfo.AdditionalMouldSecondLayerLabelSide ?? "";
BarcodeTextBox.Text = _submissionInfo.CommonDiscInfo.Barcode ?? "";
CommentsTextBox.Text = _submissionInfo.CommonDiscInfo.Comments ?? "";
ContentsTextBox.Text = _submissionInfo.CommonDiscInfo.Contents ?? "";
VersionTextBox.Text = _submissionInfo.VersionAndEditions.Version ?? "";
EditionTextBox.Text = _submissionInfo.VersionAndEditions.OtherEditions ?? "";
}
/// <summary>
/// Get a complete list of categories and fill the combo box
/// </summary>
private void PopulateCategories()
{
var categories = Enum.GetValues(typeof(Category)).OfType<Category?>().ToList();
ViewModels.LoggerViewModel.VerboseLogLn("Populating categories, {0} categories found.", categories.Count);
_categories = new List<CategoryComboBoxItem>();
foreach (var category in categories)
{
_categories.Add(new CategoryComboBoxItem(category));
}
CategoryComboBox.ItemsSource = _categories;
CategoryComboBox.SelectedIndex = 0;
}
/// <summary>
/// Get a complete list of regions and fill the combo box
/// </summary>
private void PopulateRegions()
{
var regions = Enum.GetValues(typeof(Region)).OfType<Region?>().ToList();
ViewModels.LoggerViewModel.VerboseLogLn("Populating regions, {0} regions found.", regions.Count);
_regions = new List<RegionComboBoxItem>();
foreach (var region in regions)
{
_regions.Add(new RegionComboBoxItem(region));
}
RegionComboBox.ItemsSource = _regions;
RegionComboBox.SelectedIndex = 0;
}
/// <summary>
/// Get a complete list of languages and fill the combo box
/// </summary>
private void PopulateLanguages()
{
var languages = Enum.GetValues(typeof(Language)).OfType<Language?>().ToList();
ViewModels.LoggerViewModel.VerboseLogLn("Populating languages, {0} languages found.", languages.Count);
_languages = new List<LanguageComboBoxItem>();
foreach (var language in languages)
{
_languages.Add(new LanguageComboBoxItem(language));
}
LanguagesComboBox.ItemsSource = _languages;
LanguagesComboBox.SelectedIndex = 0;
}
#region Event Handlers
private void OnClosed(object sender, EventArgs e)
{
_submissionInfo.CommonDiscInfo.Title = TitleTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.ForeignTitleNonLatin = ForeignTitleTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.DiscNumberLetter = DiscNumberLetterTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.DiscTitle = DiscTitleTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.Category = (CategoryComboBox.SelectedItem as CategoryComboBoxItem)?.Value ?? Category.Games;
_submissionInfo.CommonDiscInfo.Region = (RegionComboBox.SelectedItem as RegionComboBoxItem)?.Value ?? Region.World;
var languages = new List<Language?>();
foreach (var language in _languages)
{
if (language.IsChecked)
languages.Add(language.Value);
}
if (languages.Count == 0)
languages.Add(null);
_submissionInfo.CommonDiscInfo.Languages = languages.ToArray();
_submissionInfo.CommonDiscInfo.Serial = SerialTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.MasteringRingFirstLayerDataSide = L0MasteringRingTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.MasteringSIDCodeFirstLayerDataSide = L0MasteringSIDTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.ToolstampMasteringCodeFirstLayerDataSide = L0ToolstampTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.MouldSIDCodeFirstLayerDataSide = L0MouldSIDTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.AdditionalMouldFirstLayerDataSide = L0AdditionalMouldTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.MasteringRingSecondLayerLabelSide = L1MasteringRingTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.MasteringSIDCodeSecondLayerLabelSide = L1MasteringSIDTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.ToolstampMasteringCodeSecondLayerLabelSide = L1ToolstampTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.MouldSIDCodeSecondLayerLabelSide = L1MouldSIDTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.AdditionalMouldSecondLayerLabelSide = L1AdditionalMouldTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.Barcode = BarcodeTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.Comments = CommentsTextBox.Text ?? "";
_submissionInfo.CommonDiscInfo.Contents = ContentsTextBox.Text ?? "";
_submissionInfo.VersionAndEditions.Version = VersionTextBox.Text ?? "";
_submissionInfo.VersionAndEditions.OtherEditions = EditionTextBox.Text ?? "";
Hide();
}
#endregion
}
}

View File

@@ -0,0 +1,54 @@
<Window x:Class="DICUI.Windows.LogWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DICUI"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
Title="Log Window" Height="350" Width="600" Closed="OnWindowClosed" Loaded="OnWindowLoaded"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Height="22" Margin="10 10 10 0">
<ProgressBar x:Name="progressBar" />
<TextBlock x:Name="progressLabel" Grid.Row="0" Height="22" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="0 2 0 0" />
</Grid>
<Border Grid.Row="1" Background="White" BorderBrush="Gainsboro" BorderThickness="1" Margin="10">
<ScrollViewer Name="outputViewer" SizeChanged="ScrollViewer_SizeChanged">
<RichTextBox Name="output" FontFamily="Consolas" Background="#202020" IsReadOnly="true" TextChanged="OnTextChanged" />
</ScrollViewer>
</Border>
<Grid Grid.Row="2">
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition Width="4*"/>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<CheckBox Content="Verbose" Margin="10 0 0 10" Grid.Column="0" VerticalAlignment="Center"
ToolTip="Enable verbose logging of tasks"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=VerboseLogging}"
/>
<CheckBox Content="Open at startup" Margin="10 0 0 10" Grid.Column="1" Grid.ColumnSpan="2" VerticalAlignment="Center"
ToolTip="Open this window at startup"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=OpenLogWindowAtStartup}"
/>
<Button Margin="0 0 10 10" Grid.Column="3" Height="22" Width="60" Content="Clear" HorizontalAlignment="Right" Click="OnClearButton" />
<Button Margin="0 0 10 10" Grid.Column="4" Height="22" Width="60" Content="Hide" HorizontalAlignment="Right" Click="OnHideButton" />
<Button Visibility="Hidden" Name="AbortButton" Margin="0 0 10 10" Grid.Column="2" Height="22" Width="80" Content="Abort" HorizontalAlignment="Right" Click="OnAbortButton" />
</Grid>
</Grid>
</Window>

View File

@@ -0,0 +1,385 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Interop;
using System.Windows.Media;
namespace DICUI.Windows
{
public partial class LogWindow : Window
{
private const int GWL_STYLE = -16;
private const int WS_SYSMENU = 0x80000;
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
private MainWindow _mainWindow;
private FlowDocument _document;
private Paragraph _paragraph;
private List<Matcher> _matchers;
volatile Process _process;
public LogWindow(MainWindow mainWindow)
{
InitializeComponent();
this._mainWindow = mainWindow;
_document = new FlowDocument();
_paragraph = new Paragraph();
_document.Blocks.Add(_paragraph);
output.Document = _document;
_matchers = new List<Matcher>();
_matchers.Add(new Matcher(
"Descrambling data sector of img (LBA)",
@"\s*(\d+)\/\s*(\d+)$",
match => {
if (UInt32.TryParse(match.Groups[1].Value, out uint current) && UInt32.TryParse(match.Groups[2].Value, out uint total))
{
float percentProgress = (current / (float)total) * 100;
progressBar.Value = percentProgress;
progressLabel.Text = string.Format("Descrambling image.. ({0:##.##}%)", percentProgress);
}
}));
_matchers.Add(new Matcher(
@"Creating .scm (LBA)",
@"\s*(\d+)\/\s*(\d+)$",
match => {
if (UInt32.TryParse(match.Groups[1].Value, out uint current) && UInt32.TryParse(match.Groups[2].Value, out uint total))
{
float percentProgress = (current / (float)total) * 100;
progressBar.Value = percentProgress;
progressLabel.Text = string.Format("Creating scrambled image.. ({0:##.##}%)", percentProgress);
}
}));
_matchers.Add(new Matcher(
"Checking sectors (LBA)",
@"\s*(\d+)\/\s*(\d+)$",
match => {
if (UInt32.TryParse(match.Groups[1].Value, out uint current) && UInt32.TryParse(match.Groups[2].Value, out uint total))
{
float percentProgress = (current / (float)total) * 100;
progressBar.Value = percentProgress;
progressLabel.Text = string.Format("Checking for errors.. ({0:##.##}%)", percentProgress);
}
}));
_matchers.Add(new Matcher(
"Scanning sector (LBA)",
@"\s*(\d+)\/\s*(\d+)$",
match => {
if (UInt32.TryParse(match.Groups[1].Value, out uint current) && UInt32.TryParse(match.Groups[2].Value, out uint total))
{
float percentProgress = (current / (float)total) * 100;
progressBar.Value = percentProgress;
progressLabel.Text = string.Format("Scanning sectors for protection.. ({0:##.##}%)", percentProgress);
}
}));
}
public void StartDump(string args)
{
AppendToTextBox(string.Format("Launching DIC with args: {0}\r\n", args), Brushes.Orange);
Task.Run(() =>
{
_process = new Process()
{
StartInfo = new ProcessStartInfo()
{
FileName = @"Programs/DiscImageCreator.exe",
Arguments = args,
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
},
};
StreamState stdoutState = new StreamState(false);
StreamState stderrState = new StreamState(true);
//_cmd.ErrorDataReceived += (process, text) => Dispatcher.Invoke(() => UpdateConsole(text.Data, Brushes.Red));
_process.Start();
var _1 = ConsumeOutput(_process.StandardOutput, s => Dispatcher.Invoke(() => UpdateConsole(s, stdoutState)));
var _2 = ConsumeOutput(_process.StandardError, s => Dispatcher.Invoke(() => UpdateConsole(s, stderrState)));
_process.EnableRaisingEvents = true;
_process.Exited += OnProcessExit;
});
}
public void AdjustPositionToMainWindow()
{
this.Left = _mainWindow.Left;
this.Top = _mainWindow.Top + _mainWindow.Height + Constants.LogWindowMarginFromMainWindow;
}
private void GracefullyTerminateProcess()
{
if (_process != null)
{
_process.Exited -= OnProcessExit;
bool isForced = !_process.HasExited;
if (isForced)
{
AppendToTextBox("\r\nForcefully Killing the process\r\n", Brushes.Red);
_process.Kill();
_process.WaitForExit();
}
AppendToTextBox(string.Format("\r\nExit Code: {0}\r\n", _process.ExitCode), _process.ExitCode == 0 ? Brushes.Green : Brushes.Red);
if (_process.ExitCode == 0)
{
Dispatcher.Invoke(() =>
{
progressLabel.Text = "Done!";
progressBar.Value = 100;
progressBar.Foreground = Brushes.Green;
});
}
else
{
Dispatcher.Invoke(() =>
{
progressLabel.Text = isForced ? "Aborted by user" : "Error, please check log!";
progressBar.Value = 100;
progressBar.Foreground = Brushes.Red;
});
}
_process.Close();
}
_process = null;
}
private void ScrollViewer_SizeChanged(object sender, SizeChangedEventArgs e)
{
outputViewer.ScrollToBottom();
}
async Task ConsumeOutput(TextReader reader, Action<string> callback)
{
char[] buffer = new char[256];
int cch;
while ((cch = await reader.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
callback(new string(buffer, 0, cch));
}
}
// this is used to optimize the work since we need to process A LOT of text
struct Matcher
{
private readonly string prefix;
private readonly Regex regex;
private readonly int start;
private readonly Action<Match> lambda;
public Matcher(string prefix, string regex, Action<Match> lambda)
{
this.prefix = prefix;
this.regex = new Regex(regex);
this.start = prefix.Length;
this.lambda = lambda;
}
public bool Matches(ref string text) => text.StartsWith(prefix);
public void Apply(ref string text)
{
Match match = regex.Match(text, start);
lambda.Invoke(match);
}
}
private void ProcessStringForProgressBar(string text)
{
foreach (Matcher matcher in _matchers)
{
if (matcher.Matches(ref text))
{
matcher.Apply(ref text);
return;
}
}
}
class StreamState
{
public enum State
{
BEGIN,
READ_CARRIAGE,
};
public State state;
public readonly StringBuilder buffer;
public readonly bool isError;
public StreamState(bool isError)
{
this.state = State.BEGIN;
this.buffer = new StringBuilder();
this.isError = isError;
}
public bool HasData() => buffer.Length > 0;
public string Fetch() => buffer.ToString();
public void Clear() => buffer.Clear();
public void Append(char c) => buffer.Append(c);
public bool Is(State state) => this.state == state;
public void Set(State state) => this.state = state;
}
public void AppendToTextBox(string text, Brush color)
{
if (Application.Current.Dispatcher.CheckAccess())
{
Run run = new Run(text) { Foreground = color };
_paragraph.Inlines.Add(run);
}
else
Dispatcher.Invoke(() =>
{
Run run = new Run(text) { Foreground = color };
_paragraph.Inlines.Add(run);
});
}
private void UpdateConsole(string text, StreamState state)
{
/*if (c == '\r') { output.Inlines.Add(@"\r"); file.Write("\\r"); }
else if (c == '\n') { output.Inlines.Add(@"\n"); file.Write("\\n\n"); }
output.Inlines.Add(""+c);
file.Write(c);
file.Flush();
continue;*/
if (text != null)
{
foreach (char c in text)
{
switch (c)
{
case '\r' when (state.Is(StreamState.State.BEGIN)):
{
state.Set(StreamState.State.READ_CARRIAGE);
break;
}
case '\n' when (state.Is(StreamState.State.READ_CARRIAGE)):
{
if (state.buffer.Length > 0)
{
string buffer = state.Fetch();
AppendToTextBox(buffer, state.isError ? Brushes.Red : Brushes.White);
if (!state.isError)
ProcessStringForProgressBar(buffer);
}
_paragraph.Inlines.Add(new LineBreak());
state.Clear();
state.Set(StreamState.State.BEGIN);
break;
}
default:
if (state.Is(StreamState.State.READ_CARRIAGE) && state.HasData())
{
if (!(_paragraph.Inlines.LastInline is LineBreak))
_paragraph.Inlines.Remove(_paragraph.Inlines.LastInline);
string buffer = state.Fetch();
AppendToTextBox(buffer, state.isError ? Brushes.Red : Brushes.White);
if (!state.isError)
ProcessStringForProgressBar(buffer);
state.Clear();
}
state.Set(StreamState.State.BEGIN);
state.Append(c);
break;
}
}
}
}
#region EventHandlers
private void OnWindowClosed(object sender, EventArgs e)
{
GracefullyTerminateProcess();
}
private void OnWindowLoaded(object sender, EventArgs e)
{
var hwnd = new WindowInteropHelper(this).Handle;
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
}
void OnProcessExit(object sender, EventArgs e)
{
Dispatcher.Invoke(() => AbortButton.IsEnabled = false);
GracefullyTerminateProcess();
}
private void OnHideButton(object sender, EventArgs e)
{
ViewModels.LoggerViewModel.WindowVisible = false;
//TODO: this should be bound directly to WindowVisible property in two way fashion
// we need to study how to properly do it in XAML
_mainWindow.ShowLogMenuItem.IsChecked = false;
}
private void OnClearButton(object sender, EventArgs e)
{
output.Document.Blocks.Clear();
}
private void OnAbortButton(object sender, EventArgs args)
{
GracefullyTerminateProcess();
}
private void OnStartButton(object sender, EventArgs args)
{
StartDump("cd e Gam.iso 16");
}
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
outputViewer.ScrollToBottom();
}
#endregion
}
}

View File

@@ -0,0 +1,130 @@
<Window x:Class="DICUI.Windows.MainWindow"
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="Disc Image Creator GUI" Height="450" Width="600" WindowStartupLocation="CenterScreen" ResizeMode="CanMinimize"
LocationChanged="MainWindowLocationChanged" Activated="MainWindowActivated" Closing="MainWindowClosing">
<Window.Resources>
<local:EnumDescriptionConverter x:Key="enumConverter" />
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="13*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="4*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<StackPanel VerticalAlignment="Top" Grid.ColumnSpan="4">
<Menu Width="Auto" Height="20" >
<MenuItem Header="_File">
<MenuItem x:Name="AppExit" Header="E_xit" HorizontalAlignment="Left" Width="140" Click="AppExitClick" />
</MenuItem>
<MenuItem Header="_Tools">
<MenuItem x:Name="OptionsMenuItem" Header="_Options" HorizontalAlignment="Left" Width="140" Click="OptionsClick"/>
<MenuItem x:Name="ShowLogMenuItem" Header="Show _Log Window" IsCheckable="true" HorizontalAlignment="Left"
DataContext="{Binding Source={x:Static local:ViewModels.LoggerViewModel}}"
IsChecked="{Binding Path=WindowVisible}"
/>
</MenuItem>
<MenuItem Header="_Help">
<MenuItem x:Name="About" Header="_About" HorizontalAlignment="Left" Width="140" Click="AboutClick"/>
</MenuItem>
</Menu>
</StackPanel>
<GroupBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,5,5.2,5.4" HorizontalAlignment="Stretch" Header="Settings"/>
<GroupBox Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,4.6,5.2,4.8" HorizontalAlignment="Stretch" Header="Controls"/>
<GroupBox Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,5.2,5.2,4.8" HorizontalAlignment="Stretch" Header="Status"/>
<Grid Grid.Row="1" Grid.Column="0" Margin="15,25,15.2,10.4" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="2.5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Content="System/Media Type" />
<ComboBox x:Name="SystemTypeComboBox" Grid.Row="0" Grid.Column="1" Height="22" Width="250" HorizontalAlignment="Left" SelectionChanged="SystemTypeComboBoxSelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" Foreground="{Binding Path=Foreground}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox x:Name="MediaTypeComboBox" Grid.Row="0" Grid.Column="1" Height="22" Width="140" HorizontalAlignment="Right" SelectionChanged="MediaTypeComboBoxSelectionChanged">
<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="OutputFilenameTextBox" Grid.Row="1" Grid.Column="1" Height="22" TextChanged="OutputFilenameTextBoxTextChanged" />
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center">Output Directory</Label>
<TextBox x:Name="OutputDirectoryTextBox" Grid.Row="2" Grid.Column="1" Height="22" Width="345" HorizontalAlignment="Left" TextChanged="OutputDirectoryTextBoxTextChanged" />
<Button x:Name="OutputDirectoryBrowseButton" Grid.Row="2" Grid.Column="1" Height="22" Width="50" HorizontalAlignment="Right" Content="Browse" Click="OutputDirectoryBrowseButtonClick"/>
<Label Grid.Row="3" Grid.Column="0" VerticalAlignment="Center">Drive Letter</Label>
<ComboBox x:Name="DriveLetterComboBox" Grid.Row="3" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="Left" SelectionChanged="DriveLetterComboBoxSelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Letter}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Grid.Row="4" Grid.Column="0" VerticalAlignment="Center">Drive Speed</Label>
<ComboBox x:Name="DriveSpeedComboBox" Grid.Row="4" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="Left" SelectionChanged="DriveSpeedComboBoxSelectionChanged" />
<Label Grid.Row="5" Grid.Column="0" VerticalAlignment="Center">Parameters</Label>
<TextBox x:Name="ParametersTextBox" Grid.Row="5" Grid.Column="1" Height="22" Width="370" HorizontalAlignment="Left" IsEnabled="False" />
<CheckBox x:Name="EnableParametersCheckBox" Grid.Row="5" Grid.Column="1" Height="22" HorizontalAlignment="Right" IsChecked="False" Click="EnableParametersCheckBoxClick" />
</Grid>
<Grid Grid.Row="2" Grid.Column="0" Margin="15,19.6,15.2,9.8" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Button x:Name="StartStopButton" Grid.Row="0" Grid.Column="0" Height="22" Width="125" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Start Dumping" Click="StartStopButtonClick" IsEnabled="False" />
<Button x:Name="DiskScanButton" Grid.Row="0" Grid.Column="1" Height="22" Width="125" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Scan for disks" Click="DiskScanButtonClick" />
<Button x:Name="CopyProtectScanButton" Grid.Row="0" Grid.Column="2" Height="22" Width="125" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Scan for protection" Click="CopyProtectScanButtonClick" />
<CheckBox x:Name="EjectWhenDoneCheckBox" Grid.Row="0" Grid.Column="3" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Eject When Done" IsChecked="False" />
</Grid>
<Grid Grid.Row="3" Grid.Column="0" Margin="15,20.2,15.2,9.8" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Label x:Name="StatusLabel" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Waiting for media..." />
</Grid>
</Grid>
</Window>

View File

@@ -0,0 +1,791 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using WinForms = System.Windows.Forms;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI.Windows
{
public partial class MainWindow : Window
{
// Private UI-related variables
private List<Drive> _drives;
private MediaType? _currentMediaType;
private List<KnownSystemComboBoxItem> _systems;
private List<MediaType?> _mediaTypes;
private bool _alreadyShown;
private DumpEnvironment _env;
// Option related
private Options _options;
private OptionsWindow _optionsWindow;
// User input related
private DiscInformationWindow _discInformationWindow;
private LogWindow _logWindow;
public MainWindow()
{
InitializeComponent();
// Initializes and load Options object
_options = new Options();
_options.Load();
ViewModels.OptionsViewModel = new OptionsViewModel(_options);
_logWindow = new LogWindow(this);
ViewModels.LoggerViewModel.SetWindow(_logWindow);
// Disable buttons until we load fully
StartStopButton.IsEnabled = false;
DiskScanButton.IsEnabled = false;
CopyProtectScanButton.IsEnabled = false;
if (_options.OpenLogWindowAtStartup)
{
this.WindowStartupLocation = WindowStartupLocation.Manual;
double combinedHeight = this.Height + _logWindow.Height + Constants.LogWindowMarginFromMainWindow;
Rectangle bounds = GetScaledCoordinates(WinForms.Screen.PrimaryScreen.WorkingArea);
this.Left = bounds.Left + (bounds.Width - this.Width) / 2;
this.Top = bounds.Top + (bounds.Height - combinedHeight) / 2;
}
}
#region Events
protected override void OnContentRendered(EventArgs e)
{
base.OnContentRendered(e);
if (_alreadyShown)
return;
_alreadyShown = true;
if (_options.OpenLogWindowAtStartup)
{
//TODO: this should be bound directly to WindowVisible property in two way fashion
// we need to study how to properly do it in XAML
ShowLogMenuItem.IsChecked = true;
ViewModels.LoggerViewModel.WindowVisible = true;
}
// Populate the list of systems
StatusLabel.Content = "Creating system list, please wait!";
PopulateSystems();
// Populate the list of drives
StatusLabel.Content = "Creating drive list, please wait!";
PopulateDrives();
}
private void StartStopButtonClick(object sender, RoutedEventArgs e)
{
// Dump or stop the dump
if ((string)StartStopButton.Content == Constants.StartDumping)
{
StartDumping();
}
else if ((string)StartStopButton.Content == Constants.StopDumping)
{
ViewModels.LoggerViewModel.VerboseLogLn("Canceling dumping process...");
_env.CancelDumping();
CopyProtectScanButton.IsEnabled = true;
if (EjectWhenDoneCheckBox.IsChecked == true)
{
ViewModels.LoggerViewModel.VerboseLogLn($"Ejecting disc in drive {_env.Drive.Letter}");
_env.EjectDisc();
}
}
}
private void OutputDirectoryBrowseButtonClick(object sender, RoutedEventArgs e)
{
BrowseFolder();
EnsureDiscInformation();
}
private void DiskScanButtonClick(object sender, RoutedEventArgs e)
{
PopulateDrives();
}
private void CopyProtectScanButtonClick(object sender, RoutedEventArgs e)
{
ScanAndShowProtection();
}
private void SystemTypeComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
// If we're on a separator, go to the next item and return
if ((SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem).IsHeader())
{
SystemTypeComboBox.SelectedIndex++;
return;
}
ViewModels.LoggerViewModel.VerboseLogLn("Changed system to: {0}", (SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem).Name);
PopulateMediaType();
GetOutputNames(false);
EnsureDiscInformation();
}
private void MediaTypeComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
// Only change the media type if the selection and not the list has changed
if (e.RemovedItems.Count == 1 && e.AddedItems.Count == 1)
{
_currentMediaType = MediaTypeComboBox.SelectedItem as MediaType?;
SetSupportedDriveSpeed();
}
GetOutputNames(false);
EnsureDiscInformation();
}
private void DriveLetterComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
CacheCurrentDiscType();
SetCurrentDiscType();
GetOutputNames(true);
SetSupportedDriveSpeed();
}
private void DriveSpeedComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
EnsureDiscInformation();
}
private void OutputFilenameTextBoxTextChanged(object sender, TextChangedEventArgs e)
{
EnsureDiscInformation();
}
private void OutputDirectoryTextBoxTextChanged(object sender, TextChangedEventArgs e)
{
EnsureDiscInformation();
}
private void ProgressUpdated(object sender, Result value)
{
StatusLabel.Content = value.Message;
ViewModels.LoggerViewModel.VerboseLogLn(value.Message);
}
private void MainWindowLocationChanged(object sender, EventArgs e)
{
if (_logWindow.IsVisible)
_logWindow.AdjustPositionToMainWindow();
}
private void MainWindowActivated(object sender, EventArgs e)
{
if (_logWindow.IsVisible && !this.Topmost)
{
_logWindow.Topmost = true;
_logWindow.Topmost = false;
}
}
private void MainWindowClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
if (_logWindow.IsVisible)
_logWindow.Close();
}
private void EnableParametersCheckBoxClick(object sender, RoutedEventArgs e)
{
if (EnableParametersCheckBox.IsChecked == true)
ParametersTextBox.IsEnabled = true;
else
{
ParametersTextBox.IsEnabled = false;
ProcessCustomParameters();
}
}
// Toolbar Events
private void AppExitClick(object sender, RoutedEventArgs e)
{
Application.Current.Shutdown();
}
private void AboutClick(object sender, RoutedEventArgs e)
{
MessageBox.Show($"ReignStumble - Project Lead / UI Design{Environment.NewLine}" +
$"darksabre76 - Project Co-Lead / Backend Design{Environment.NewLine}" +
$"Jakz - Feature Contributor{Environment.NewLine}" +
$"NHellFire - Feature Contributor{Environment.NewLine}" +
$"Dizzzy - Concept/Ideas/Beta tester{Environment.NewLine}", "About", MessageBoxButton.OK, MessageBoxImage.Information);
}
private void OptionsClick(object sender, RoutedEventArgs e)
{
// lazy initialization
if (_optionsWindow == null)
{
_optionsWindow = new OptionsWindow(this, _options);
_optionsWindow.Closed += delegate
{
_optionsWindow = null;
};
}
_optionsWindow.Owner = this;
_optionsWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;
_optionsWindow.Refresh();
_optionsWindow.Show();
}
public void OnOptionsUpdated()
{
GetOutputNames(false);
SetSupportedDriveSpeed();
EnsureDiscInformation();
}
#endregion
#region Helpers
/// <summary>
/// Populate media type according to system type
/// </summary>
private void PopulateMediaType()
{
KnownSystem? currentSystem = SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem;
if (currentSystem != null)
{
_mediaTypes = Validators.GetValidMediaTypes(currentSystem);
MediaTypeComboBox.ItemsSource = _mediaTypes;
MediaTypeComboBox.IsEnabled = _mediaTypes.Count > 1;
MediaTypeComboBox.SelectedIndex = (_mediaTypes.IndexOf(_currentMediaType) >= 0 ? _mediaTypes.IndexOf(_currentMediaType) : 0);
}
else
{
MediaTypeComboBox.IsEnabled = false;
MediaTypeComboBox.ItemsSource = null;
MediaTypeComboBox.SelectedIndex = -1;
}
}
/// <summary>
/// Get a complete list of supported systems and fill the combo box
/// </summary>
private void PopulateSystems()
{
var knownSystems = Validators.CreateListOfSystems();
ViewModels.LoggerViewModel.VerboseLogLn("Populating systems, {0} systems found.", knownSystems.Count);
Dictionary<KnownSystemCategory, List<KnownSystem?>> mapping = knownSystems
.GroupBy(s => s.Category())
.ToDictionary(
k => k.Key,
v => v
.OrderBy(s => s.LongName())
.ToList()
);
_systems = new List<KnownSystemComboBoxItem>();
_systems.Add(new KnownSystemComboBoxItem(KnownSystem.NONE));
foreach (var group in mapping)
{
_systems.Add(new KnownSystemComboBoxItem(group.Key));
group.Value.ForEach(system => _systems.Add(new KnownSystemComboBoxItem(system)));
}
SystemTypeComboBox.ItemsSource = _systems;
SystemTypeComboBox.SelectedIndex = 0;
StartStopButton.IsEnabled = false;
}
/// <summary>
/// Get a complete list of active disc drives and fill the combo box
/// </summary>
/// <remarks>TODO: Find a way for this to periodically run, or have it hook to a "drive change" event</remarks>
private void PopulateDrives()
{
ViewModels.LoggerViewModel.VerboseLogLn("Scanning for drives..");
// Always enable the disk scan
DiskScanButton.IsEnabled = true;
// Populate the list of drives and add it to the combo box
_drives = Validators.CreateListOfDrives();
DriveLetterComboBox.ItemsSource = _drives;
if (DriveLetterComboBox.Items.Count > 0)
{
// Check for active optical drives first
int index = _drives.FindIndex(d => d.MarkedActive && d.InternalDriveType == InternalDriveType.Optical);
// Then we check for floppy drives
if (index == -1)
index = _drives.FindIndex(d => d.MarkedActive && d.InternalDriveType == InternalDriveType.Floppy);
// Then we try all other drive types
if (index == -1)
index = _drives.FindIndex(d => d.MarkedActive);
// Set the selected index
DriveLetterComboBox.SelectedIndex = (index != -1 ? index : 0);
StatusLabel.Content = "Valid drive found! Choose your Media Type";
CopyProtectScanButton.IsEnabled = true;
// Get the current media type
if (!_options.SkipSystemDetection && index != -1)
{
ViewModels.LoggerViewModel.VerboseLog("Trying to detect system for drive {0}.. ", _drives[index].Letter);
var currentSystem = Validators.GetKnownSystem(_drives[index]);
ViewModels.LoggerViewModel.VerboseLogLn(currentSystem == null || currentSystem == KnownSystem.NONE ? "unable to detect." : ("detected " + currentSystem.LongName() + "."));
if (currentSystem != null && currentSystem != KnownSystem.NONE)
{
int sysIndex = _systems.FindIndex(s => s == currentSystem);
SystemTypeComboBox.SelectedIndex = sysIndex;
}
}
// Only enable the start/stop if we don't have the default selected
StartStopButton.IsEnabled = (SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem) != KnownSystem.NONE;
ViewModels.LoggerViewModel.VerboseLogLn("Found {0} drives: {1}", _drives.Count, string.Join(", ", _drives.Select(d => d.Letter)));
}
else
{
DriveLetterComboBox.SelectedIndex = -1;
StatusLabel.Content = "No valid drive found!";
StartStopButton.IsEnabled = false;
CopyProtectScanButton.IsEnabled = false;
ViewModels.LoggerViewModel.VerboseLogLn("Found no drives");
}
}
/// <summary>
/// Browse for an output folder
/// </summary>
private void BrowseFolder()
{
WinForms.FolderBrowserDialog folderDialog = new WinForms.FolderBrowserDialog { ShowNewFolderButton = false, SelectedPath = System.AppDomain.CurrentDomain.BaseDirectory };
WinForms.DialogResult result = folderDialog.ShowDialog();
if (result == WinForms.DialogResult.OK)
{
OutputDirectoryTextBox.Text = folderDialog.SelectedPath;
}
}
/// <summary>
/// Create a DumpEnvironment with all current settings
/// </summary>
/// <returns>Filled DumpEnvironment instance</returns>
private DumpEnvironment DetermineEnvironment()
{
// Populate the new environment
var env = new DumpEnvironment()
{
// Paths to tools
SubdumpPath = _options.SubDumpPath,
DICPath = _options.DICPath,
OutputDirectory = OutputDirectoryTextBox.Text,
OutputFilename = OutputFilenameTextBox.Text,
// Get the currently selected options
Drive = DriveLetterComboBox.SelectedItem as Drive,
DICParameters = new Parameters(ParametersTextBox.Text),
QuietMode = _options.QuietMode,
ParanoidMode = _options.ParanoidMode,
ScanForProtection = _options.ScanForProtection,
RereadAmountC2 = _options.RereadAmountForC2,
AddPlaceholders = _options.AddPlaceholders,
PromptForDiscInformation = _options.PromptForDiscInformation,
Username = _options.Username,
Password = _options.Password,
System = SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem,
Type = MediaTypeComboBox.SelectedItem as MediaType?,
};
// Fix the output paths
env.FixOutputPaths();
// Disable automatic reprocessing of the textboxes until we're done
OutputDirectoryTextBox.TextChanged -= OutputDirectoryTextBoxTextChanged;
OutputFilenameTextBox.TextChanged -= OutputFilenameTextBoxTextChanged;
OutputDirectoryTextBox.Text = env.OutputDirectory;
OutputFilenameTextBox.Text = env.OutputFilename;
OutputDirectoryTextBox.TextChanged += OutputDirectoryTextBoxTextChanged;
OutputFilenameTextBox.TextChanged += OutputFilenameTextBoxTextChanged;
return env;
}
/// <summary>
/// Begin the dumping process using the given inputs
/// </summary>
private async void StartDumping()
{
if (_env == null)
_env = DetermineEnvironment();
// If still in custom parameter mode, check that users meant to continue or not
if (EnableParametersCheckBox.IsChecked == true)
{
MessageBoxResult result = MessageBox.Show("It looks like you have custom parameters that have not been saved. Would you like to apply those changes before starting to dump?", "Custom Changes", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
if (result == MessageBoxResult.Yes)
{
EnableParametersCheckBox.IsChecked = false;
ParametersTextBox.IsEnabled = false;
ProcessCustomParameters();
}
else if (result == MessageBoxResult.Cancel)
return;
// If "No", then we continue with the current known environment
}
try
{
// Check for the firmware first
// TODO: Remove this (and method) once DIC end-to-end logging becomes a thing
if (!await _env.DriveHasLatestFimrware())
{
MessageBox.Show($"DiscImageCreator has reported that drive {_env.Drive.Letter} is not updated to the most recent firmware. Please update the firmware for your drive and try again.", "Outdated Firmware", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
// Validate that the user explicitly wants an inactive drive to be considered for dumping
if (!_env.Drive.MarkedActive)
{
MessageBoxResult mbresult = MessageBox.Show("The currently selected drive does not appear to contain a disc! Are you sure you want to continue?", "Missing Disc", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
if (mbresult == MessageBoxResult.No || mbresult == MessageBoxResult.Cancel || mbresult == MessageBoxResult.None)
{
ViewModels.LoggerViewModel.VerboseLogLn("Dumping aborted!");
return;
}
}
// If a complete dump already exists
if (_env.FoundAllFiles())
{
MessageBoxResult mbresult = MessageBox.Show("A complete dump already exists! Are you sure you want to overwrite?", "Overwrite?", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
if (mbresult == MessageBoxResult.No || mbresult == MessageBoxResult.Cancel || mbresult == MessageBoxResult.None)
{
ViewModels.LoggerViewModel.VerboseLogLn("Dumping aborted!");
return;
}
}
StartStopButton.Content = Constants.StopDumping;
CopyProtectScanButton.IsEnabled = false;
StatusLabel.Content = "Beginning dumping process";
ViewModels.LoggerViewModel.VerboseLogLn("Starting dumping process..");
var progress = new Progress<Result>();
progress.ProgressChanged += ProgressUpdated;
Result result = await _env.StartDumping(progress);
if (result)
{
// Verify dump output and save it
result = _env.VerifyAndSaveDumpOutput(progress,
(si) =>
{
// lazy initialization
if (_discInformationWindow == null)
{
_discInformationWindow = new DiscInformationWindow(this, si);
_discInformationWindow.Closed += delegate
{
_discInformationWindow = null;
};
}
_discInformationWindow.Owner = this;
_discInformationWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;
_discInformationWindow.Refresh();
return _discInformationWindow.ShowDialog();
}
);
}
StatusLabel.Content = result ? "Dumping complete!" : result.Message;
ViewModels.LoggerViewModel.VerboseLogLn(result ? "Dumping complete!" : result.Message);
}
catch
{
// No-op, we don't care what it was
}
finally
{
StartStopButton.Content = Constants.StartDumping;
CopyProtectScanButton.IsEnabled = true;
}
if (EjectWhenDoneCheckBox.IsChecked == true)
{
ViewModels.LoggerViewModel.VerboseLogLn($"Ejecting disc in drive {_env.Drive.Letter}");
_env.EjectDisc();
}
}
/// <summary>
/// Ensure information is consistent with the currently selected disc type
/// </summary>
private void EnsureDiscInformation()
{
// Get the current environment information
_env = DetermineEnvironment();
// Take care of null cases
if (_env.System == null)
_env.System = KnownSystem.NONE;
if (_env.Type == null)
_env.Type = MediaType.NONE;
// Get the status to write out
Result result = Validators.GetSupportStatus(_env.System, _env.Type);
StatusLabel.Content = result.Message;
// Set the index for the current disc type
SetCurrentDiscType();
StartStopButton.IsEnabled = result && (_drives != null && _drives.Count > 0 ? true : false);
// If we're in a type that doesn't support drive speeds
DriveSpeedComboBox.IsEnabled = _env.Type.DoesSupportDriveSpeed();
// If input params are not enabled, generate the full parameters from the environment
if (!ParametersTextBox.IsEnabled)
{
string generated = _env.GetFullParameters((int?)DriveSpeedComboBox.SelectedItem);
if (generated != null)
ParametersTextBox.Text = generated;
}
}
/// <summary>
/// Get the default output directory name from the currently selected drive
/// </summary>
/// <param name="driveChanged">Force an updated name if the drive letter changes</param>
private void GetOutputNames(bool driveChanged)
{
Drive drive = DriveLetterComboBox.SelectedItem as Drive;
KnownSystem? systemType = SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem;
MediaType? mediaType = MediaTypeComboBox.SelectedItem as MediaType?;
// Set the output directory, if we changed drives or it's not already
if (driveChanged || string.IsNullOrEmpty(OutputDirectoryTextBox.Text))
OutputDirectoryTextBox.Text = Path.Combine(_options.DefaultOutputPath, drive?.VolumeLabel ?? string.Empty);
// Set the output filename, if we changed drives or it's not already
if (driveChanged || string.IsNullOrEmpty(OutputFilenameTextBox.Text))
OutputFilenameTextBox.Text = (drive?.VolumeLabel ?? systemType.LongName()) + (mediaType.Extension() ?? ".bin");
// If the extension for the file changed, update that automatically
else if (Path.GetExtension(OutputFilenameTextBox.Text) != mediaType.Extension())
OutputFilenameTextBox.Text = Path.GetFileNameWithoutExtension(OutputFilenameTextBox.Text) + (mediaType.Extension() ?? ".bin");
}
/// <summary>
/// Scan and show copy protection for the current disc
/// </summary>
private async void ScanAndShowProtection()
{
if (_env == null)
_env = DetermineEnvironment();
if (_env.Drive.Letter != default(char))
{
ViewModels.LoggerViewModel.VerboseLogLn("Scanning for copy protection in {0}", _env.Drive.Letter);
var tempContent = StatusLabel.Content;
StatusLabel.Content = "Scanning for copy protection... this might take a while!";
StartStopButton.IsEnabled = false;
DiskScanButton.IsEnabled = false;
CopyProtectScanButton.IsEnabled = false;
string protections = await Validators.RunProtectionScanOnPath(_env.Drive.Letter + ":\\");
if (!ViewModels.LoggerViewModel.WindowVisible)
MessageBox.Show(protections, "Detected Protection", MessageBoxButton.OK, MessageBoxImage.Information);
ViewModels.LoggerViewModel.VerboseLog("Detected the following protections in {0}:\r\n\r\n{1}", _env.Drive.Letter, protections);
StatusLabel.Content = tempContent;
StartStopButton.IsEnabled = true;
DiskScanButton.IsEnabled = true;
CopyProtectScanButton.IsEnabled = true;
}
}
/// <summary>
/// Set the drive speed based on reported maximum and user-defined option
/// </summary>
private void SetSupportedDriveSpeed()
{
// Set the drive speed list that's appropriate
var values = Constants.GetSpeedsForMediaType(_currentMediaType);
DriveSpeedComboBox.ItemsSource = values;
ViewModels.LoggerViewModel.VerboseLogLn("Supported media speeds: {0}", string.Join(",", values));
// Find the minimum set to compare against
int preferred = 100;
switch (_currentMediaType)
{
case MediaType.CDROM:
case MediaType.GDROM:
preferred = _options.PreferredDumpSpeedCD;
break;
case MediaType.DVD:
case MediaType.HDDVD:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
preferred = _options.PreferredDumpSpeedDVD;
break;
case MediaType.BluRay:
preferred = _options.PreferredDumpSpeedBD;
break;
default:
preferred = _options.PreferredDumpSpeedCD;
break;
}
// Choose the lower of the two speeds between the allowed speeds and the user-defined one
// TODO: Inform more users about setting preferences in the settings so this comparison doesn't need to happen
int chosenSpeed = Math.Min(
values.Where(s => s <= values[values.Count / 2]).Last(),
preferred
);
// Set the selected speed
ViewModels.LoggerViewModel.VerboseLogLn("Setting drive speed to: {0}", chosenSpeed);
DriveSpeedComboBox.SelectedValue = chosenSpeed;
}
/// <summary>
/// Cache the current disc type to internal variable
/// </summary>
private void CacheCurrentDiscType()
{
// Get the drive letter from the selected item
Drive drive = DriveLetterComboBox.SelectedItem as Drive;
if (drive == null)
return;
// Get the current media type
if (!_options.SkipMediaTypeDetection)
{
ViewModels.LoggerViewModel.VerboseLog("Trying to detect media type for drive {0}.. ", drive.Letter);
_currentMediaType = Validators.GetMediaType(drive);
ViewModels.LoggerViewModel.VerboseLogLn(_currentMediaType == null ? "unable to detect." : ("detected " + _currentMediaType.LongName() + "."));
}
}
/// <summary>
/// Set the current disc type in the combo box
/// </summary>
private void SetCurrentDiscType()
{
// If we have an invalid current type, we don't care and return
if (_currentMediaType == null || _currentMediaType == MediaType.NONE)
return;
// Now set the selected item, if possible
int index = _mediaTypes.FindIndex(kvp => kvp.Value == _currentMediaType);
if (index != -1)
MediaTypeComboBox.SelectedIndex = index;
else
StatusLabel.Content = $"Disc of type '{Converters.LongName(_currentMediaType)}' found, but the current system does not support it!";
}
/// <summary>
/// Process the current custom parameters back into UI values
/// </summary>
private void ProcessCustomParameters()
{
_env.DICParameters = new Parameters(ParametersTextBox.Text);
int driveIndex = _drives.Select(d => d.Letter).ToList().IndexOf(_env.DICParameters.DriveLetter[0]);
if (driveIndex > -1)
DriveLetterComboBox.SelectedIndex = driveIndex;
int driveSpeed = _env.DICParameters.DriveSpeed ?? -1;
if (driveSpeed > 0)
DriveSpeedComboBox.SelectedValue = driveSpeed;
else
_env.DICParameters.DriveSpeed = (int?)DriveSpeedComboBox.SelectedValue;
string trimmedPath = _env.DICParameters.Filename?.Trim('"') ?? string.Empty;
string outputDirectory = Path.GetDirectoryName(trimmedPath);
string outputFilename = Path.GetFileName(trimmedPath);
if (!string.IsNullOrWhiteSpace(outputDirectory))
OutputDirectoryTextBox.Text = outputDirectory;
else
outputDirectory = OutputDirectoryTextBox.Text;
if (!string.IsNullOrWhiteSpace(outputFilename))
OutputFilenameTextBox.Text = outputFilename;
else
outputFilename = OutputFilenameTextBox.Text;
MediaType? mediaType = _env.DICParameters.Command.ToMediaType();
int mediaTypeIndex = _mediaTypes.IndexOf(mediaType);
if (mediaTypeIndex > -1)
MediaTypeComboBox.SelectedIndex = mediaTypeIndex;
}
#endregion
#region UI Helpers
/// <summary>
/// Get pixel coordinates based on DPI scaling
/// </summary>
/// <param name="bounds">Rectangle representing the bounds to transform</param>
/// <returns>Rectangle representing the scaled bounds</returns>
private Rectangle GetScaledCoordinates(Rectangle bounds)
{
using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
{
return new Rectangle(
TransformCoordinate(bounds.Left, g.DpiX),
TransformCoordinate(bounds.Top, g.DpiY),
TransformCoordinate(bounds.Width, g.DpiX),
TransformCoordinate(bounds.Height, g.DpiY));
}
}
/// <summary>
/// Transform an individual coordinate using DPI scaling
/// </summary>
/// <param name="coord">Current integer coordinate</param>
/// <param name="dpi">DPI scaling factor</param>
/// <returns>Scaled integer coordinate</returns>
private int TransformCoordinate(int coord, float dpi)
{
return (int)(coord / ((double)dpi / 96));
}
#endregion
}
}

View File

@@ -0,0 +1,177 @@
<Window x:Class="DICUI.Windows.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="580" Width="515.132">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="150"/>
<RowDefinition Height="100"/>
<RowDefinition Height="80"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<GroupBox Grid.Column="0" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Paths" />
<Grid Margin="10,15,10,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="DiscImageCreator Path" />
<TextBox x:Name="DICPathTextBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="DICPathButton" Grid.Row="0" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick" />
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="subdump Path" />
<TextBox x:Name="SubDumpPathTextBox" Grid.Row="1" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="SubDumpPathButton" Grid.Row="1" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick"/>
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Default Output Path" />
<TextBox x:Name="DefaultOutputPathTextBox" Grid.Row="2" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Button x:Name="DefaultOutputPathButton" Grid.Row="2" Grid.Column="2" Height="22" Width="22" Content="..." Click="BrowseForPathClick" />
</Grid>
<GroupBox Grid.Row="1" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Preferred Dump Speed">
<Grid Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="2.0*"/>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="CD-ROM" />
<Slider x:Name="DumpSpeedCDSlider" Grid.Row="0" Grid.Column="1" Minimum="1" Maximum="72" IsSnapToTickEnabled="True" TickPlacement="BottomRight" Ticks="{Binding Source={x:Static local:Constants.SpeedsForCDAsCollection}}" />
<TextBox x:Name="DumpSpeedCDTextBox" Grid.Row="0" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" IsReadOnlyCaretVisible="False" VerticalAlignment="Center" Text="{Binding ElementName=DumpSpeedCDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
<Label Grid.Row="1" Grid.Column="0" Content="DVD-ROM" />
<Slider x:Name="DumpSpeedDVDSlider" Grid.Row="1" Grid.Column="1" Minimum="1" Maximum="24" IsSnapToTickEnabled="True" TickPlacement="BottomRight" Ticks="{Binding Source={x:Static local:Constants.SpeedsForDVDAsCollection}}" />
<TextBox x:Name="DumpSpeedDVDTextBox" Grid.Row="1" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" IsReadOnlyCaretVisible="False" VerticalAlignment="Center" Text="{Binding ElementName=DumpSpeedDVDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
<Label Grid.Row="2" Grid.Column="0" Content="BD-ROM" />
<Slider x:Name="DumpSpeedBDSlider" Grid.Row="2" Grid.Column="1" Minimum="1" Maximum="16" IsSnapToTickEnabled="True" TickPlacement="BottomRight" Ticks="{Binding Source={x:Static local:Constants.SpeedsForBDAsCollection}}" />
<TextBox x:Name="DumpSpeedBDTextBox" Grid.Row="2" Grid.Column="2" Width="22" Height="22" TextAlignment="Center" IsReadOnly="True" IsReadOnlyCaretVisible="False" VerticalAlignment="Center" Text="{Binding ElementName=DumpSpeedBDSlider, Path=Value, UpdateSourceTrigger=PropertyChanged}" Background="LightGray" Foreground="Gray"/>
</Grid>
</GroupBox>
<GroupBox Grid.Row="2" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Options" Padding="10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="24*" />
<RowDefinition Height="13*" />
<RowDefinition Height="11*"/>
</Grid.RowDefinitions>
<CheckBox Grid.Column="0" VerticalAlignment="Center" Content="Quiet Mode"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=QuietMode}"
ToolTip="Disable DiscImageCreator sounds" Margin="0,4"
/>
<CheckBox Grid.Column="1" VerticalAlignment="Center" Content="Paranoid Mode"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=ParanoidMode}"
ToolTip="Enable pedantic and super-safe flags" Margin="0,4"
/>
<Grid Grid.Column="2" Grid.ColumnSpan="2" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="C2 Reread Tries:" />
<TextBox Grid.Column="1" VerticalAlignment="Center"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
Text="{Binding Path=RereadAmountForC2}"
ToolTip="Specifies how many rereads are attempted on C2 error"
/>
</Grid>
<CheckBox Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" VerticalAlignment="Top" Content="Protection Scan"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=ScanForProtection}"
ToolTip="Enable automatic checking for copy protection on dumped media" Margin="0,4,0,0" Grid.RowSpan="2"
/>
<CheckBox Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" Content="Skip Type Detect"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=SkipMediaTypeDetection}"
ToolTip="Disable trying to guess media type inserted (may improve performance at startup)" Margin="0,4" Grid.RowSpan="2"
/>
<CheckBox Grid.Column="2" Grid.Row="1" VerticalAlignment="Center" Content="Add Placeholders"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=AddPlaceholders}"
ToolTip="Enable adding placeholder text in the submissioninfo output for required and optional fields" Margin="0,4" Grid.RowSpan="2"
/>
<CheckBox Grid.Column="3" Grid.Row="1" VerticalAlignment="Center" Content="Show Disc Info"
DataContext="{Binding Source={x:Static local:ViewModels.OptionsViewModel}}"
IsChecked="{Binding Path=PromptForDiscInformation}"
ToolTip="Enable showing the disc information output after dumping" Margin="0,4" Grid.RowSpan="2"
/>
</Grid>
</GroupBox>
<GroupBox Grid.Row="3" Margin="5,5,5,5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Header="Redump Login" Padding="10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Username" />
<TextBox x:Name="RedumpUsernameTextBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" />
<Label Grid.Row="0" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Password" />
<TextBox x:Name="RedumpPasswordTextBox" Grid.Row="0" Grid.Column="3" Height="22" HorizontalAlignment="Stretch" />
</Grid>
</GroupBox>
<Grid Height="22" Grid.Row="4" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Button x:Name="AcceptButton" Grid.Row="0" Grid.Column="1" Height="22" Width="80" Content="Accept" Click="OnAcceptClick" />
<Button x:Name="CancelButton" Grid.Row="0" Grid.Column="2" Height="22" Width="80" Content="Cancel" Click="OnCancelClick" />
</Grid>
</Grid>
</Window>

View File

@@ -0,0 +1,138 @@
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.Windows
{
/// <summary>
/// Interaction logic for OptionsWindow.xaml
/// </summary>
public partial class OptionsWindow : Window
{
private readonly MainWindow _mainWindow;
private readonly Options _options;
public OptionsWindow(MainWindow mainWindow, Options options)
{
InitializeComponent();
_mainWindow = mainWindow;
_options = options;
}
private OpenFileDialog CreateOpenFileDialog()
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.InitialDirectory = 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(name + "TextBox") as TextBox;
}
private void BrowseForPathClick(object sender, EventArgs e)
{
Button button = sender as Button;
// strips button prefix to obtain the setting name
string pathSettingName = button.Name.Substring(0, button.Name.IndexOf("Button"));
// 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
);
}
}
}
}
public void Refresh()
{
Array.ForEach(PathSettings(), setting => TextBoxForPathSetting(setting).Text = _options.Get(setting));
DumpSpeedCDSlider.Value = _options.PreferredDumpSpeedCD;
DumpSpeedDVDSlider.Value = _options.PreferredDumpSpeedDVD;
DumpSpeedBDSlider.Value = _options.PreferredDumpSpeedBD;
RedumpUsernameTextBox.Text = _options.Username;
RedumpPasswordTextBox.Text = _options.Password;
}
#region Event Handlers
private void OnAcceptClick(object sender, EventArgs e)
{
Array.ForEach(PathSettings(), setting => _options.Set(setting, TextBoxForPathSetting(setting).Text));
_options.PreferredDumpSpeedCD = Convert.ToInt32(DumpSpeedCDSlider.Value);
_options.PreferredDumpSpeedDVD = Convert.ToInt32(DumpSpeedDVDSlider.Value);
_options.PreferredDumpSpeedBD = Convert.ToInt32(DumpSpeedBDSlider.Value);
_options.Username = RedumpUsernameTextBox.Text;
_options.Password = RedumpPasswordTextBox.Text;
_options.Save();
Hide();
_mainWindow.OnOptionsUpdated();
}
private void OnCancelClick(object sender, EventArgs e)
{
// just hide the window and don't care
Hide();
}
#endregion
}
}

View File

@@ -1,130 +0,0 @@
<Window x:Class="DICUI.MainWindow"
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="Disc Image Creator GUI" Height="400" Width="600">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="13*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="4*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<GroupBox Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,5,5.2,5.4" HorizontalAlignment="Stretch" Header="Settings"/>
<GroupBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,4.6,5.2,4.8" HorizontalAlignment="Stretch" Header="Controls"/>
<GroupBox Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Margin="5,5.2,5.2,4.8" HorizontalAlignment="Stretch" Header="Status"/>
<Grid Grid.Row="0" Grid.Column="0" Margin="15,25,15.2,10.4" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="2.5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center">Disc Type</Label>
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center">Output Filename</Label>
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center">Output Directory</Label>
<Label Grid.Row="3" Grid.Column="0" VerticalAlignment="Center">Drive Letter</Label>
<Label Grid.Row="4" Grid.Column="0" VerticalAlignment="Center">Drive Speed</Label>
<ComboBox x:Name="cmb_DiscType" Grid.Row="0" Grid.Column="1" Height="22" Text="Bandai Playdia Quick Interactive System" DropDownClosed="cmb_DiscType_DropDownClosed" SelectionChanged="cmb_DiscType_SelectionChanged">
<ComboBoxItem Content="Unknown"/>
<ComboBoxItem Content="---------- Consoles ----------" IsEnabled="False"/>
<ComboBoxItem Content="Bandai Playdia Quick Interactive System"/>
<ComboBoxItem Content="Bandai / Apple Pippin"/>
<ComboBoxItem Content="Commodore Amiga CD / CD32 / CDTV"/>
<ComboBoxItem Content="Mattel HyperScan"/>
<ComboBoxItem Content="Microsoft XBOX One"/>
<ComboBoxItem Content="NEC PC-Engine / TurboGrafx CD"/>
<ComboBoxItem Content="NEC PC-FX / PC-FXGA"/>
<ComboBoxItem Content="Panasonic 3DO"/>
<ComboBoxItem Content="Philips CD-i"/>
<ComboBoxItem Content="Sega CD / Mega CD"/>
<ComboBoxItem Content="Sega Saturn"/>
<ComboBoxItem Content="SNK Neo Geo CD"/>
<ComboBoxItem Content="Sony PlayStation"/>
<ComboBoxItem Content="Sony PlayStation 2 (CD-Rom)"/>
<ComboBoxItem Content="Sony PlayStation 2 (DVD-Rom)"/>
<ComboBoxItem Content="Sony PlayStation 4"/>
<ComboBoxItem Content="VTech V.Flash - V.Smile Pro"/>
<ComboBoxItem Content="---------- Computers ----------" IsEnabled="False"/>
<ComboBoxItem Content="Apple Macintosh (CD-Rom)"/>
<ComboBoxItem Content="Apple Macintosh (DVD-Rom)"/>
<ComboBoxItem Content="Fujitsu FM Towns series"/>
<ComboBoxItem Content="IBM PC Compatible (CD-Rom)"/>
<ComboBoxItem Content="IBM PC Compatible (DVD-Rom)"/>
<ComboBoxItem Content="NEC PC-88"/>
<ComboBoxItem Content="NEC PC-98"/>
<ComboBoxItem Content="---------- Arcade ----------" IsEnabled="False"/>
<ComboBoxItem Content="Sega Lindbergh"/>
<ComboBoxItem Content="---------- Others ----------" IsEnabled="False"/>
<ComboBoxItem Content="Audio CD"/>
<ComboBoxItem Content="BD-Video"/>
<ComboBoxItem Content="DVD-Video"/>
<ComboBoxItem Content="PalmOS"/>
<ComboBoxItem Content="Photo CD"/>
<ComboBoxItem Content="PlayStation GameShark Updates"/>
<ComboBoxItem Content="Tomy Kiss-Site"/>
<ComboBoxItem Content="Video CD"/>
</ComboBox>
<TextBox x:Name="txt_OutputFilename" Grid.Row="1" Grid.Column="1" Height="22"></TextBox>
<TextBox x:Name="txt_OutputDirectory" Grid.Row="2" Grid.Column="1" Height="22" Width="345" HorizontalAlignment="left" Text="ISO" ></TextBox>
<Button x:Name="BTN_OutputDirectoryBrowse" Grid.Row="2" Grid.Column="1" Height="22" Width="50" HorizontalAlignment="Right" Content="Browse" Click="BTN_OutputDirectoryBrowse_Click" ></Button>
<ComboBox x:Name="cmb_DriveLetter" Grid.Row="3" Grid.Column="1" Height="22" Width="397" HorizontalAlignment="left" SelectionChanged="cmb_DriveLetter_SelectionChanged"></ComboBox>
<ComboBox x:Name="cmb_DriveSpeed" Grid.Row="4" Grid.Column="1" Height="22" Width="60" HorizontalAlignment="left" SelectionChanged="cmb_DriveSpeed_SelectionChanged">
<ComboBoxItem Content="4"/>
<ComboBoxItem Content="8"/>
<ComboBoxItem Content="16"/>
<ComboBoxItem Content="48"/>
<ComboBoxItem Content="Custom"/>
</ComboBox>
</Grid>
<Grid Grid.Row="1" Grid.Column="0" Margin="15,19.6,15.2,9.8" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Button x:Name="btn_Start" Grid.Row="0" Grid.Column="0" Height="22" Width="150" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Start Dumping" Click="btn_Start_Click" IsEnabled="False" />
<Button x:Name="btn_Search" Grid.Row="0" Grid.Column="1" Height="22" Width="150" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Scan for disks" Click="btn_Search_Click" />
</Grid>
<Grid Grid.Row="2" Grid.Column="0" Margin="15,20.2,15.2,9.8" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Label x:Name="lbl_Status" Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center" Content="Waiting for CD or DVD..." />
</Grid>
</Grid>
</Window>

View File

@@ -1,462 +0,0 @@
using System;
using System.Linq;
using System.Windows;
using System.IO;
using WinForms = System.Windows.Forms;
using System.Diagnostics;
using System.Threading.Tasks;
namespace DICUI
{
public partial class MainWindow : Window
{
public String discType;
public String processArguments;
public String dicPath = "Programs\\DiscImageCreator.exe";
public String driveLetter;
public String outputDirectory;
public String outputFileName;
public String driveSpeed;
public Boolean isCDRom = false;
public Boolean isPSX = false;
public Boolean isXboneOrPS4 = false;
public void ScanForDisk()
{
btn_Search.IsEnabled = false;
cmb_DriveLetter.Items.Clear();
foreach (var d in DriveInfo.GetDrives().Where(d => d.DriveType == DriveType.CDRom))
{
if (d.IsReady == true)
{
txt_OutputFilename.Text = d.VolumeLabel;
if (txt_OutputFilename.Text == "")
{
txt_OutputFilename.Text = "unknown";
}
cmb_DriveLetter.Items.Add(d.Name + d.VolumeLabel);
cmb_DriveLetter.SelectedIndex = 0;
txt_OutputDirectory.Text = "ISO" + "\\" + txt_OutputFilename.Text;
lbl_Status.Content = "CD or DVD found ! Choose your Disc Type";
btn_Start.IsEnabled = true;
cmb_DriveSpeed.Text = "8";
}
else
{
cmb_DriveLetter.Items.Add(d.Name + " (No Disc Found or Not supported by Windows)");
}
btn_Search.IsEnabled = true;
}
}
public void BrowseFolder()
{
WinForms.FolderBrowserDialog folderDialog = new WinForms.FolderBrowserDialog { ShowNewFolderButton = false, SelectedPath = System.AppDomain.CurrentDomain.BaseDirectory };
WinForms.DialogResult result = folderDialog.ShowDialog();
if (result == WinForms.DialogResult.OK)
{
String sPath = folderDialog.SelectedPath;
txt_OutputDirectory.Text = sPath;
}
}
public async void StartDumping()
{
driveLetter = cmb_DriveLetter.Text;
outputDirectory = txt_OutputDirectory.Text;
outputFileName = txt_OutputFilename.Text;
driveSpeed = cmb_DriveSpeed.Text;
btn_Start.IsEnabled = false;
switch (Convert.ToString(cmb_DiscType.Text))
{
#region Consoles
case "Bandai Playdia Quick Interactive System":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "Bandai / Apple Pippin":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "Commodore Amiga CD / CD32 / CDTV":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "Mattel HyperScan":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "Microsoft XBOX":
// Placeholder for later use
break;
case "Microsoft XBOX 360":
// Placeholder for later use
break;
case "Microsoft XBOX One":
discType = "bd";
processArguments = "";
isXboneOrPS4 = true;
break;
case "NEC PC-Engine / TurboGrafx CD":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "NEC PC-FX / PC-FXGA":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "Nintendo GameCube":
// Placeholder for later use
break;
case "Nintendo Wii":
// Placeholder for later use
break;
case "Nintendo Wii U":
// Placeholder for later use
break;
case "Panasonic 3DO":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "Philips CD-i":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "Sega CD / Mega CD":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "Sega Dreamcast":
// Placeholder for later use
break;
case "Sega Saturn":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "SNK Neo Geo CD":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "Sony PlayStation":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
isPSX = true;
break;
case "Sony PlayStation 2 (CD-Rom)":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "Sony PlayStation 2 (DVD-Rom)":
discType = "dvd";
processArguments = "";
break;
case "Sony PlayStation 3":
// Placeholder for later use
break;
case "Sony PlayStation 4":
discType = "bd";
processArguments = "";
isXboneOrPS4 = true;
break;
case "Sony PlayStation Portable":
// No-op - PSP can't be dumped with DIC
break;
case "VM Labs NUON":
// Placeholder for later use
break;
case "VTech V.Flash - V.Smile Pro":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "ZAPiT Games Game Wave Family Entertainment System":
// Placeholder for later use
break;
#endregion
#region Computers
case "Acorn Archimedes":
// Placeholder for later use
break;
case "Apple Macintosh (CD-Rom)":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "Apple Macintosh (DVD-Rom)":
discType = "dvd";
processArguments = "";
break;
case "Fujitsu FM Towns series":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "IBM PC Compatible (CD-Rom)":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20 /ns /sf /ss";
break;
case "IBM PC Compatible (DVD-Rom)":
discType = "dvd";
processArguments = "";
break;
case "NEC PC-88":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "NEC PC-98":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "Sharp X68000":
// Placeholder for later use
break;
#endregion
#region Arcade
case "Namco / Sega / Nintendo Triforce":
// Placeholder for later use
break;
case "Sega Chihiro":
// Placeholder for later use
break;
case "Sega Lindbergh":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "Sega Naomi":
// Placeholder for later use
break;
case "Sega Naomi 2":
// Placeholder for later use
break;
case "TAB-Austria Quizard":
// Placeholder for later use
break;
case "Tandy / Memorex Visual Information System":
// Placeholder for later use
break;
#endregion
#region Others
case "Audio CD":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "BD-Video":
discType = "bd";
processArguments = "";
break;
case "DVD-Video":
discType = "dvd";
break;
case "PalmOS":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "Philips CD-i Digital Video":
// Placeholder for later use
break;
case "Photo CD":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "PlayStation GameShark Updates":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "Tao iKTV":
// Placeholder for later use
break;
case "Tomy Kiss-Site":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
case "Video CD":
discType = "cd";
isCDRom = true;
processArguments = "/c2 20";
break;
#endregion
case "Unknown":
default:
discType = "";
processArguments = "";
break;
}
await Task.Run(
() =>
{
Process process = new Process();
process.StartInfo.FileName = dicPath; // TODO: Make this configurable in UI
process.StartInfo.Arguments = discType + " " + driveLetter + " \"" + outputDirectory + "\\" + outputFileName + "\" " + driveSpeed + " " + processArguments;
Console.WriteLine(process.StartInfo.Arguments);
process.Start();
process.WaitForExit();
});
if (isXboneOrPS4 == true)
{
// TODO: Add random string / GUID to end of batch file name so that multiple instances can run at once
using (StreamWriter writetext = new StreamWriter("XboneOrPS4.bat"))
{
writetext.WriteLine("sg_raw.exe -v -r 4100 -R " + driveLetter + ": " + "ad 01 00 00 00 00 00 00 10 04 00 00 -o \"PIC.bin\"");
}
Process processXboneOrPS4 = new Process();
processXboneOrPS4.StartInfo.FileName = "XboneOrPS4.bat";
processXboneOrPS4.Start();
processXboneOrPS4.WaitForExit();
}
if (isPSX == true)
{
// TODO: Add random string / GUID to end of batch file name so that multiple instances can run at once
using (StreamWriter writetext = new StreamWriter("PSX.bat"))
{
writetext.WriteLine("edccchk" + " " + "\"" + outputDirectory + "\\" + outputFileName + ".bin" + "\" > " + "\"" + outputDirectory + "\\" + "edccchk1.txt");
writetext.WriteLine("edccchk" + " " + "\"" + outputDirectory + "\\" + outputFileName + " (Track 1).bin" + "\" > " + "\"" + outputDirectory + "\\" + "edccchk1.txt");
writetext.WriteLine("edccchk" + " " + "\"" + outputDirectory + "\\" + outputFileName + " (Track 01).bin" + "\" > " + "\"" + outputDirectory + "\\" + "edccchk1.txt");
writetext.WriteLine("psxt001z" + " " + "\"" + outputDirectory + "\\" + outputFileName + ".bin" + "\" > " + "\"" + outputDirectory + "\\" + "psxt001z1.txt");
writetext.WriteLine("psxt001z" + " " + "\"" + outputDirectory + "\\" + outputFileName + " (Track 1).bin" + "\" > " + "\"" + outputDirectory + "\\" + "psxt001z2.txt");
writetext.WriteLine("psxt001z" + " " + "\"" + outputDirectory + "\\" + outputFileName + " (Track 01).bin" + "\" > " + "\"" + outputDirectory + "\\" + "psxt001z3.txt");
writetext.WriteLine("psxt001z" + " " + "--libcrypt " + "\"" + outputDirectory + "\\" + outputFileName + ".sub\" > " + "\"" + outputDirectory + "\\" + "libcrypt.txt");
writetext.WriteLine("psxt001z" + " " + "--libcryptdrvfast " + driveLetter + " > " + "\"" + outputDirectory + "\\" + "libcryptdrv.log");
}
Process processpsx = new Process();
processpsx.StartInfo.FileName = "PSX.bat";
processpsx.Start();
processpsx.WaitForExit();
}
if (isCDRom == true)
{
// TODO: Add random string / GUID to end of batch file name so that multiple instances can run at once
using (StreamWriter writetext = new StreamWriter("CDRom.bat"))
{
writetext.WriteLine("edccchk" + " " + "\"" + outputDirectory + "\\" + outputFileName + ".bin" + "\" > " + "\"" + outputDirectory + "\\" + "edccchk1.txt");
writetext.WriteLine("edccchk" + " " + "\"" + outputDirectory + "\\" + outputFileName + " (Track 1).bin" + "\" > " + "\"" + outputDirectory + "\\" + "edccchk1.txt");
writetext.WriteLine("edccchk" + " " + "\"" + outputDirectory + "\\" + outputFileName + " (Track 01).bin" + "\" > " + "\"" + outputDirectory + "\\" + "edccchk1.txt");
}
Process processpsx = new Process();
processpsx.StartInfo.FileName = "CDRom.bat";
processpsx.Start();
processpsx.WaitForExit();
}
btn_Start.IsEnabled = true;
}
public MainWindow()
{
InitializeComponent();
ScanForDisk();
}
private void btn_Start_Click(object sender, RoutedEventArgs e)
{
StartDumping();
}
private void BTN_OutputDirectoryBrowse_Click(object sender, RoutedEventArgs e)
{
BrowseFolder();
}
private void btn_Search_Click(object sender, RoutedEventArgs e)
{
ScanForDisk();
}
private void cmb_DiscType_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
lbl_Status.Content = "Ready to dump";
}
private void cmb_DriveSpeed_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
// TODO: Figure out how to keep the list of items while also allowing the custom input
if (cmb_DriveSpeed.SelectedIndex == 4)
{
cmb_DriveSpeed.Items.Clear();
cmb_DriveSpeed.IsEditable = true;
}
}
private void cmb_DiscType_DropDownClosed(object sender, EventArgs e)
{
switch (Convert.ToString(cmb_DiscType.Text))
{
case "Sony PlayStation 4":
cmb_DriveSpeed.Items.Clear();
cmb_DriveSpeed.IsEnabled = false;
break;
case "Microsoft XBOX One":
cmb_DriveSpeed.Items.Clear();
cmb_DriveSpeed.IsEnabled = false;
break;
default:
cmb_DriveSpeed.IsEnabled = true;
cmb_DriveSpeed.Items.Clear();
cmb_DriveSpeed.Items.Add("4");
cmb_DriveSpeed.Items.Add("8");
cmb_DriveSpeed.Items.Add("16");
cmb_DriveSpeed.Items.Add("48");
cmb_DriveSpeed.Items.Add("Custom");
cmb_DriveSpeed.SelectedIndex = 1;
break;
}
}
private void cmb_DriveLetter_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
driveLetter = cmb_DriveLetter.SelectedValue.ToString().Substring(0, 1);
Console.WriteLine(driveLetter);
btn_Start.IsEnabled = true;
}
}
}

View File

@@ -1,63 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace DICUI.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DICUI.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -1,43 +1,51 @@
# 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
[![Build status](https://ci.appveyor.com/api/projects/status/3ldav3v0c373jeqa?svg=true)](https://ci.appveyor.com/project/mnadareski/dicui/build/artifacts)
I'm a hobbyist programmer, so this code might not be optimal, feel free to make your recommendation / Pull request.
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 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 :)
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)
--------------------------------------------------------------------------
Currently working on the project:
ReignStumble - Lead Developer
This project relies on two open-source code ports to help perform copy protection scanning: [BurnOutSharp](https://github.com/mnadareski/BurnOutSharp) and [UnshieldSharp](https://github.com/mnadareski/UnshieldSharp)
darksabre76 - Contributer
## System Requirements
NHellFire - Contributer
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. There is some preliminary support for Linux underway, and we will try to integrate with that when the time comes.
Dizzzy - Concept/Ideas/Beta tester
- Windows 7 (newest version of Windows recommended)
- .NET Framework 4.6.2, .NET Framework 4.7.2, or .NET Core 3.0 Runtimes
- 128 MB of free RAM
- As much hard drive space as amount of discs you will be dumping (20+ GB recommended)
--------------------------------------------------------------------------
2018-05-18
--------------------------------------------------------------------------
Ensure that your operating system is as up-to-date as possible, since some features may rely on those updates.
Version 1.02b released:
## Releases
- 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)
For those who would rather the most recently stable build, ownload the latest release here:
[Releases Page](https://github.com/SabreTools/DICUI/releases)
--------------------------------------------------------------------------
2018-05-14
--------------------------------------------------------------------------
Version 1.01d released:
For those who like to test the newest features, download the latest AppVeyor WIP build here: [AppVeyor](https://ci.appveyor.com/project/mnadareski/dicui/build/artifacts)
## Changelist
Download the latest release here:
https://github.com/reignstumble/DICUI/releases
A list of all changes can now be found [here](https://github.com/SabreTools/DICUI/blob/master/CHANGELIST.md).
## Contributors
Here are the talented people who have contributed to the project so far:
- **darksabre76** - Project Lead / Backend Design
- **ReignStumble** - Former Project Lead / UI Design
- **Jakz** - Primary Feature Contributor
- **NHellFire** - Feature Contributor
## Notable Testers
These are the tireless individuals who have dedicated countless hours to help test the many features of DICUI and have worked with the development team closely:
- **Dizzzy/user7** - Concept, ideas, tester
- **Kludge** - Primary stress tester
- **ajshell1** - Tester
- **eientei95** - Tester

54
appveyor.yml Normal file
View File

@@ -0,0 +1,54 @@
# version format
version: 1.15-{build}
# pull request template
pull_requests:
do_not_increment_build_number: true
# vm template
image: Visual Studio 2019
# environment variables
environment:
EnableNuGetPackageRestore: true
# msbuild configuration
platform:
- Any CPU
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:
- ps: appveyor DownloadFile https://github.com/saramibreak/DiscImageCreator/files/3854216/DiscImageCreator_20191116.zip
- ps: appveyor DownloadFile https://archive.org/download/subdump_fua_0x28/subdump_fua_0x28.zip
- 7z e DiscImageCreator_20191116.zip -oDICUI\bin\Debug\net462\Programs Release_ANSI\*
- 7z e DiscImageCreator_20191116.zip -oDICUI\bin\Debug\net472\Programs Release_ANSI\*
- 7z e DiscImageCreator_20191116.zip -oDICUI\bin\Debug\netcoreapp3.0\Programs Release_ANSI\*
- 7z e subdump_fua_0x28.zip -oDICUI\bin\Debug\net462 *
- mv DICUI\bin\Debug\net462\subdump_fua_0x28.exe DICUI\bin\Debug\net462\subdump.exe
- 7z e subdump_fua_0x28.zip -oDICUI\bin\Debug\net472 *
- mv DICUI\bin\Debug\net472\subdump_fua_0x28.exe DICUI\bin\Debug\net472\subdump.exe
- 7z e subdump_fua_0x28.zip -oDICUI\bin\Debug\netcoreapp3.0 *
- mv DICUI\bin\Debug\netcoreapp3.0\subdump_fua_0x28.exe DICUI\bin\Debug\netcoreapp3.0\subdump.exe
- 7z a DICUI.zip DICUI\bin\Debug\*
- 7z a DICUI-Check.zip DICUI.Check\bin\Debug\*
# artifact linking
artifacts:
- path: DICUI.zip
name: DICUI
- path: DICUI-Check.zip
name: DICUI Check