Compare commits

..

658 Commits
1.12.2 ... 2.2

Author SHA1 Message Date
Matt Nadareski
bdea1593be Bump version to 2.2 2021-12-30 09:47:44 -08:00
Matt Nadareski
f6b78c07ca Add safety around volume labels 2021-12-29 10:00:28 -08:00
Matt Nadareski
982a217d32 Temporarily disable pulling comments from Redump pages 2021-12-27 13:10:48 -08:00
Matt Nadareski
06588752ad Allow for better matching of multi track discs 2021-12-25 21:37:19 -08:00
Matt Nadareski
9b057d7141 Validate track count when matching Redump 2021-12-25 21:23:24 -08:00
Matt Nadareski
93fb3a85b5 Update changelist 2021-12-25 14:22:17 -08:00
Matt Nadareski
7320f9ba66 Fix ISN string 2021-12-25 14:22:05 -08:00
Matt Nadareski
a94f43ae0c Fix missing ISN usages 2021-12-25 13:54:06 -08:00
Matt Nadareski
e19a3f02e5 Move constants to proper place 2021-12-24 21:53:53 -08:00
Matt Nadareski
375c2c896c Invert condition for volume label 2021-12-24 21:32:45 -08:00
Matt Nadareski
b151e79aed Capture newlines in Redump fields 2021-12-24 21:06:07 -08:00
Matt Nadareski
b45901c133 Fix default value bug 2021-12-24 15:37:10 -08:00
Matt Nadareski
fab54ca0ae Use the Volume Label special site code (fixes #337) 2021-12-24 15:13:06 -08:00
Matt Nadareski
31dd32f19b Add internal support for all Redump site codes (fixes #336) 2021-12-24 14:30:50 -08:00
Matt Nadareski
f51c79d282 Allow default system if skipping system detection enabled 2021-12-21 21:11:18 -08:00
Matt Nadareski
743c943363 Fix saving path settings if set from dialog 2021-12-21 20:49:35 -08:00
Matt Nadareski
91f6e266d1 Fix output dialog issues in Options window 2021-12-21 12:50:19 -08:00
Matt Nadareski
8e843647bf Overhaul XeMID handling (fixes #334) 2021-12-21 10:54:57 -08:00
Matt Nadareski
151402dc50 Detect BD-Video (fixes #332) 2021-12-11 21:00:27 -08:00
Matt Nadareski
057f340c9c Refine the "missing disc" text (fixes #329) 2021-11-30 15:03:14 -08:00
Matt Nadareski
f3f9c63156 Add and overhaul some more tests 2021-11-26 14:07:07 -08:00
Matt Nadareski
7910a79917 Minor code cleanups 2021-11-26 14:06:57 -08:00
Matt Nadareski
cc7acfcd00 Minor usings cleanup 2021-11-25 22:45:13 -08:00
Matt Nadareski
5580e208f5 More test changes/additions, new helper method 2021-11-25 22:38:59 -08:00
Matt Nadareski
56ef06d651 Add enum converter tests, fix other related things 2021-11-25 22:05:35 -08:00
Matt Nadareski
204dfca126 Remove unused converter class 2021-11-25 21:21:27 -08:00
Matt Nadareski
eb337a8aaf Reorganize result tests 2021-11-25 21:06:19 -08:00
TonyLizard
aa6fd781e8 Adding a space to the -No Title Key- string in the DVD Protection section (#328) 2021-11-25 21:03:28 -08:00
Matt Nadareski
32bcfa1d42 Add SubmissionInfo serialization tests 2021-11-24 23:58:08 -08:00
Matt Nadareski
3b2e14d0de Finish filling out first round of Extension tests 2021-11-24 23:36:12 -08:00
Matt Nadareski
88a0ce38f9 Fill in another significant chunk of extension tests 2021-11-24 23:19:58 -08:00
Matt Nadareski
110c8337aa Overhaul cross-enumeration RedumpLib tests 2021-11-24 23:02:13 -08:00
Matt Nadareski
3dc79fea6b Cleanup some old test classes 2021-11-24 22:19:57 -08:00
Matt Nadareski
fb036385f9 Update changelog 2021-11-24 22:11:56 -08:00
Matt Nadareski
428bb2817b Strip ";1" from DVD protection results (fixes #327) 2021-11-24 22:10:10 -08:00
Matt Nadareski
791caff240 Minor cleanups and safety checks 2021-11-24 22:05:10 -08:00
Matt Nadareski
d92015d071 Add sanitization for StarForce 2021-11-19 11:03:24 -08:00
Matt Nadareski
de98bd9e0b Update to DIC 20211101 2021-11-19 10:33:13 -08:00
Matt Nadareski
67f5a7794a Fix protection sanitization; add tests 2021-11-19 10:09:34 -08:00
Matt Nadareski
fbef94f634 Only exclude Audio CDs from offset writing 2021-11-12 11:06:27 -08:00
Matt Nadareski
0e8363f06e Ensure parameters box is safer during options save 2021-11-08 20:45:37 -08:00
Matt Nadareski
a1bafe0426 Update changelist 2021-11-08 10:18:15 -08:00
Matt Nadareski
c51461592c Start adding regression tests for DIC 2021-11-05 14:44:58 -07:00
Matt Nadareski
ef5f996ec4 Remove offset from DIC output (fixes #326) 2021-11-05 11:25:45 -07:00
Matt Nadareski
aa5998a52e Be consistent with LBA values (fixes #325) 2021-11-04 22:20:52 -07:00
Matt Nadareski
37207c1cb0 Remove lower bound checking on LBA values 2021-11-04 21:59:26 -07:00
Matt Nadareski
d1813fdbc7 Make anti-modchip scans safer 2021-11-04 15:23:40 -07:00
Matt Nadareski
faf9d1d6f8 Add retry to Redump calls (fixes #309) 2021-11-02 11:35:31 -07:00
Matt Nadareski
0360df0604 Wrap directory checks in case of corruption 2021-11-02 10:54:08 -07:00
Matt Nadareski
fe6487eeb4 Fix enum converters (fixes #306) 2021-11-01 12:02:07 -07:00
Matt Nadareski
b9eedd1cf6 Add submission JSON option to check 2021-11-01 10:43:55 -07:00
Shiz
26281b8f0b Fix various arcade system metadata issues (#324)
* redumplib: correct media type for Sega Nu

* redumplib: merge Namco System 246 and System 256

* redumplib: drop Namco System 357 / 369

This was not a disc-based system, none of its released forms
have a disc reader.

* redumplib: add SEGA ALLS
2021-10-26 10:30:14 -07:00
sadikyo
f0508fdf93 Minor spelling fix. (#321)
Co-authored-by: sadik <sadik@TONY-HOME>
2021-10-22 16:51:40 -07:00
Matt Nadareski
166d69c7ec Fix NRE in InfoTool 2021-10-03 13:53:23 -07:00
Matt Nadareski
fabf08ba55 HTTP encode password for Redump login, again (fixes #314) 2021-10-01 09:01:41 -07:00
Matt Nadareski
0e5d8af0e9 Update to DIC 20211101 2021-09-30 22:09:09 -07:00
Matt Nadareski
3e1263ebff Update to Aaru v5.3.0 LTS 2021-09-30 20:59:13 -07:00
Matt Nadareski
c0ed830241 These should live in Drive 2021-09-29 16:37:28 -07:00
Matt Nadareski
4209158807 Extract anything that can be static 2021-09-29 16:16:54 -07:00
Matt Nadareski
6d79ebf449 Post-separation cleanup 2021-09-29 15:18:35 -07:00
Matt Nadareski
88ab691f07 Simplify remaining structure in MPF.Library 2021-09-29 15:05:17 -07:00
Matt Nadareski
37b1dc574c Separate out modules into own library; fix csproj's 2021-09-29 14:56:15 -07:00
Matt Nadareski
ad56e249ed Small cleanups for dead code 2021-09-29 12:24:03 -07:00
Matt Nadareski
f28cfe3d69 Segment out protection checks a bit more 2021-09-29 12:17:34 -07:00
Matt Nadareski
9643442281 Create MPF.Core and move a lot to there 2021-09-29 11:48:37 -07:00
Matt Nadareski
dd44ec7ac1 Clean up usings 2021-09-29 10:28:15 -07:00
Matt Nadareski
801c1126cf Remove now-unnecessary excludes from csproj 2021-09-29 09:40:01 -07:00
Matt Nadareski
4fd72efc46 Move CICMMetadata to top-level 2021-09-29 09:36:13 -07:00
Matt Nadareski
9ec045cb21 Move cuesheet code to separate DLL 2021-09-29 09:08:10 -07:00
Matt Nadareski
52801ee94c Null-safeguard RedumpLib conversions 2021-09-28 11:58:11 -07:00
Matt Nadareski
2077d53964 Don't print entire exception to popup 2021-09-28 11:46:37 -07:00
Matt Nadareski
14046e9217 Catch exception on update check 2021-09-28 11:29:23 -07:00
Matt Nadareski
2766debffc Fix double include 2021-09-27 22:12:32 -07:00
Matt Nadareski
4f4688899c Attempt to use Aaru.Devices and fail 2021-09-27 21:38:35 -07:00
Matt Nadareski
8151db9696 Remove non-4.8 from AppVeyor artifacts 2021-09-27 20:59:56 -07:00
Matt Nadareski
227c61b588 Add .NET 5.0 as build target 2021-09-27 20:59:37 -07:00
Matt Nadareski
61224fba7b Update to Aaru v5.3.0-rc2 2021-09-27 14:27:56 -07:00
Matt Nadareski
1dbf5516d8 Forgot ToLowerInvariant (fixes #304) 2021-09-22 14:38:24 -07:00
Matt Nadareski
10fe6ac32a Write out label-side data, if it exists (fixes #311) 2021-09-22 13:25:16 -07:00
Matt Nadareski
e39ee66726 Fix BOS-related things 2021-09-22 12:46:43 -07:00
Matt Nadareski
fff2db75d0 Add on-startup "check for updates" option (fixes #302) 2021-09-22 11:30:56 -07:00
Matt Nadareski
3a14db53c6 Update packages 2021-09-22 11:19:01 -07:00
Matt Nadareski
8b76b82e0f Update default Aaru dumping parameters 2021-09-17 22:23:11 -07:00
Matt Nadareski
e110c55e1a Create proper section for previous change 2021-09-16 14:08:07 -07:00
Matt Nadareski
85c30fbad3 Try to use another method of success/failure in AppVeyor 2021-09-16 14:07:19 -07:00
Matt Nadareski
14e5c74c65 Try to fix AppVeyor config 2021-09-16 13:37:24 -07:00
Matt Nadareski
b180e31b56 Update to Aaru v5.3.0-rc1 2021-09-16 12:02:19 -07:00
Matt Nadareski
d172a45891 Start adding special filtering to BOS outputs 2021-09-13 15:32:45 -07:00
Matt Nadareski
e74289116e Change how aux hashes are displayed (fixes #308) 2021-09-13 12:13:12 -07:00
Matt Nadareski
68b932bad0 Fix extension and conversion methods 2021-08-18 23:17:47 -07:00
Matt Nadareski
c4793e849c Move a bit more 2021-08-18 22:48:31 -07:00
Matt Nadareski
1c525a6d2e Update library, move more things there 2021-08-18 22:13:38 -07:00
Matt Nadareski
c8610ee16a Convert to using separate Redump library code 2021-08-18 15:32:45 -07:00
Matt Nadareski
0fb3bc1106 Clarify CUE or ISO in Check help text 2021-08-09 22:55:17 -07:00
Matt Nadareski
3cf133d750 Add HD-DVD-Video Redump support 2021-08-08 21:53:27 -07:00
Matt Nadareski
f0be6b0bc9 MVVM Overhaul (#300)
* Start migrating to MVVM

* Finish gutting LogOutput

* Remove now-useless regions

* Incremental initialization of the UI

* Add options directly to App-level

* Move options globally

* Accept -> OK

* Add future work notes to App.xaml.cs

* Add back cancel to DiscInformationWindow

* Enable/Disable instead of Add/Remove

* Add disc eject reminder option

* Add PS3VOLUME check
2021-08-04 14:17:53 -07:00
Matt Nadareski
e0ccb8b10d Add drive size check (fixes #299) 2021-08-02 20:40:37 -07:00
Matt Nadareski
940afae1fd Update PPC for Redump values 2021-08-01 13:24:39 -07:00
Matt Nadareski
94ba339ef2 Add Pocket PC support (fixes #298) 2021-07-30 13:04:21 -07:00
Matt Nadareski
bfead10d87 Use MCN check for Sega header, not CVD (fixes #297) 2021-07-27 22:06:26 -07:00
Matt Nadareski
97f9a73fc1 Fix Saturn header finding 2021-07-24 13:40:38 -07:00
Matt Nadareski
7f4921a47c Bump version to 2.1 2021-07-22 21:02:32 -07:00
Matt Nadareski
07359d2a63 Tweak Linq statement 2021-07-22 20:59:08 -07:00
Matt Nadareski
e5ba670c04 Update to BurnOutSharp 1.7.0 2021-07-22 11:19:58 -07:00
Matt Nadareski
3096c369d3 Update changelog 2021-07-19 22:47:25 -07:00
Matt Nadareski
333368675a Add DMI/PFI/SS to zipfile (fixes #296) 2021-07-19 13:38:16 -07:00
Wilson
d78d744ae2 Fixed log window background turning white after some "time". (#295)
* Fixed launching MPF in Windows 7.

* Potential fix for log window background 'random' color change.

* Updated the color to use hex digits.
2021-07-17 20:35:38 -07:00
Wilson
a8efe056c1 Fixed launching MPF in Windows 7. (#292) 2021-07-12 16:46:30 -07:00
Matt Nadareski
9b2475a854 Add BD to list of supported types for PC (fixes #291) 2021-07-05 22:31:58 -07:00
Matt Nadareski
33e2b27e6d Add new header for mainInfo 2021-07-05 13:26:23 -07:00
Matt Nadareski
91fe9d9bec Support /mr value parameter 2021-07-02 22:57:07 -07:00
Matt Nadareski
b1b9b3134f Update to DIC 20210701 2021-07-01 14:19:25 -07:00
Matt Nadareski
ca5386b529 Update changelog 2021-06-20 11:23:30 -07:00
Matt Nadareski
347beca874 Handle Redump 503s / Timeouts (fixes #289) 2021-06-20 11:21:43 -07:00
Matt Nadareski
27ca4fd1af Check for updates logs as well 2021-06-19 20:47:41 -07:00
Matt Nadareski
6d57a05f8c Encode params for login 2021-06-19 16:12:42 -07:00
Matt Nadareski
4d81449cfa Minor updates 2021-06-19 15:51:18 -07:00
Matt Nadareski
76fcb3ae10 Separate "Include Artifacts" into a separate setting (fixes #287) 2021-06-19 15:41:46 -07:00
Matt Nadareski
b913f5f9ae Update Xbox disc detection (fixes #288) 2021-06-19 15:25:43 -07:00
Matt Nadareski
68fa1eecfb Replace dumping program output processing 2021-06-15 10:24:19 -07:00
Matt Nadareski
dc84f17ac5 Set the matcher for carriage returns 2021-06-15 10:23:14 -07:00
Matt Nadareski
c91137130b Fix newline processing, add changelog 2021-06-15 10:20:13 -07:00
Matt Nadareski
972b07551f Add Logging utility class 2021-06-15 09:55:14 -07:00
Matt Nadareski
61562fe995 Handle carriage returns even without fancy formatting 2021-06-15 09:35:11 -07:00
Matt Nadareski
01b6c3cc98 Minor formatting change in ProcessingQueue 2021-06-14 22:37:47 -07:00
Matt Nadareski
b461dc76b9 Fix incorrect normalization for Aaru 2021-06-14 22:15:36 -07:00
Matt Nadareski
03eeed4113 Update nuget packages 2021-06-03 22:39:50 -07:00
Matt Nadareski
07615cb336 Update nuget packages 2021-06-03 22:19:03 -07:00
Matt Nadareski
9a9a977cc4 Simplify flag validation
Instead of trying to determine if something is a flag, just check if it's one of the supported flags. This should reduce the amount of potential issues that come along with making assumptions about what a parameter could look like.
2021-06-03 22:13:50 -07:00
Matt Nadareski
ab5869331b Add throwability to cuesheet code 2021-06-03 21:58:52 -07:00
Matt Nadareski
1c9ebfd703 TODO additions 2021-06-03 21:20:45 -07:00
Matt Nadareski
a9bc3587a6 Update to DIC 20210601 2021-06-03 21:19:33 -07:00
BadAd84
b1af2b6061 Fix for high cpu usage, issue with loop. (#286) 2021-05-30 12:58:08 -07:00
Matt Nadareski
2fccd53098 Ensure CSSKey file included in log zipping 2021-05-27 12:07:21 -07:00
Matt Nadareski
a7ad3e41d9 Change offset value for HVN discs (fixes #285) 2021-05-27 11:49:24 -07:00
Matt Nadareski
1fc6476f71 Be smarter about checking for zipped logs 2021-05-27 11:46:47 -07:00
Matt Nadareski
53e5a1b1b1 Check for the zipped logs for dealing with overwrites (fixes #277) 2021-05-27 11:20:48 -07:00
Matt Nadareski
119e9dc4cc Always check for all DIC log files, just in case (fixes #281) 2021-05-27 11:00:56 -07:00
Matt Nadareski
9263769906 Fix negative offsets (fixes #282) 2021-05-27 10:41:25 -07:00
Matt Nadareski
ebaf9539b2 Allow users to customize protection scanning 2021-05-06 21:47:57 -07:00
Matt Nadareski
818fb5ab34 Add right click menu with theming 2021-04-28 11:07:54 -07:00
Matt Nadareski
2f514082a9 Replace WindowChrome with dragable titles instead 2021-04-28 10:08:18 -07:00
Matt Nadareski
5c5379e972 Update ScrollViewer style 2021-04-27 11:07:07 -07:00
Matt Nadareski
c39894d9fc Update ProgressBar style 2021-04-27 10:51:32 -07:00
Matt Nadareski
2c6cf0e736 Custom UI elements v2 2021-04-26 23:08:21 -07:00
Matt Nadareski
7e96bbee27 Custom UI elements v1
This enables full-window dark mode to be a reality. The problem is that my design skills are very low
2021-04-26 22:32:05 -07:00
Matt Nadareski
f7019546d1 Add experimental dark mode (fixes #272) 2021-04-26 12:07:21 -07:00
Matt Nadareski
086f54abf0 Topsy-turvy (fixes #274) 2021-04-25 14:08:00 -07:00
Matt Nadareski
143a4149bd Parametrics (#276)
* Begin reducing complexity of parameters classes

* Make the method virtual, not the field

* Consolidate helper methods

* Fix "empty" commands; Fix DD generation

* Handle all sorts of numerical values

* Rip out remaining unneeded enum
2021-04-25 14:03:55 -07:00
Whovian9369
20aed68d58 Fix README formatting in "Notable Testers" Section (#275) 2021-04-25 10:19:15 -07:00
Matt Nadareski
7a2061a36e Bump version for first MPF rebranded stable 2021-04-23 10:30:44 -07:00
Matt Nadareski
191c7b080e Add offset for all HVN discs 2021-04-18 10:42:09 -07:00
Matt Nadareski
aab0813688 Remove HVN-specific flags for now
These flags may cause dumping issues for some, if not a majority, of VideoNow discs
2021-04-16 21:18:48 -07:00
Matt Nadareski
9ad564772c Add content alignment to user input control 2021-04-15 12:59:44 -07:00
Matt Nadareski
20bb34c3c7 Handle Enter/Esc for relevant buttons 2021-04-14 22:26:23 -07:00
Matt Nadareski
b15ddf390b Update to BurnOutSharp 1.6.1 2021-04-14 09:27:42 -07:00
Matt Nadareski
18d1562ad3 Update changelog 2021-04-13 09:31:23 -07:00
Matt Nadareski
d6f2ecbd25 Add version from Git commit (fixes #271)
This also ensures that the new version check still works as well, so the commit hash addition doesn't screw anything up.
2021-04-13 09:30:26 -07:00
Matt Nadareski
3620686afa Change window title 2021-04-13 09:28:26 -07:00
Matt Nadareski
1524224bc3 Fix cursor positioning issue 2021-04-12 22:04:54 -07:00
Matt Nadareski
35200d53d6 Update changelog 2021-04-12 14:59:22 -07:00
Matt Nadareski
4b7d4e05e7 Streamline output path textbox handling
Addresses issue of cursor moving during typing
Addresses issue of extraneous spaces appearing
2021-04-12 13:25:12 -07:00
Matt Nadareski
7e73f69433 Fix Optuons XAML 2021-04-12 08:42:22 -07:00
Matt Nadareski
9e1a972df5 Remove needless UIOptions intermediate class 2021-04-11 22:30:23 -07:00
Matt Nadareski
1edac34c1a Handle dialog return properly
Also fixes an issue where dumpable media with no ring would show a ringcode tab
2021-04-11 09:31:22 -07:00
Matt Nadareski
9adc588c9c Reintroduce options cancel button 2021-04-11 00:09:13 -07:00
Matt Nadareski
71bfdcba8f Proofreading 2021-04-09 13:52:03 -07:00
Matt Nadareski
9854c9970a Add descriptions to new options, change defaults
The default changes are:
- Setting `CompressLogFiles` to `true`
- Setting `ToolsInSeparateWindow` to `true`
- Setting `EnableLogFormatting` to `false`
- Setting `EnableProgressProcessing` to `false`

The last two don't really matter if `ToolsInSeparateWindow` is `true` since no UI-derived logs will ever trigger them, so they're being disabled for now.
2021-04-09 13:31:23 -07:00
Matt Nadareski
0c68164d6d Add option for log formatting 2021-04-09 12:03:30 -07:00
Matt Nadareski
a413357b57 Help users be more patient when starting a dump 2021-04-09 11:47:12 -07:00
Matt Nadareski
5e283c9e80 Add option to enable progress processing
This is one of the larger pain-points for redirecting the output as it involves a regex. Make it optional so people with weaker systems have a better chance.
2021-04-09 11:16:50 -07:00
Matt Nadareski
500eb66e30 Fix the text... got it inverted 2021-04-09 10:59:00 -07:00
Matt Nadareski
411e5245a5 Update tooltip to help a bit more 2021-04-09 10:57:48 -07:00
Matt Nadareski
d270501c2d Update to BurnOutSharp 1.6.0 2021-04-09 10:31:27 -07:00
Matt Nadareski
f7f924593f Add Audio CD detection
On Windows 10, at least, when a purely Audio CD is put in, it gets the volume label of "Audio CD", conveniently. We can use this to at least attempt to match, even if this could be a false positive for some CD-i or things like Jag CD
2021-04-07 10:04:59 -07:00
Matt Nadareski
5126a66eb9 Color code the text 2021-04-06 13:35:47 -07:00
Matt Nadareski
7fddef238d Update changelog 2021-04-06 11:31:27 -07:00
Matt Nadareski
ace673f90d Integrate ring code guide into submission window
Adds a new button to show the ring code guide for easier reference
2021-04-06 11:05:03 -07:00
Matt Nadareski
e063df63df Merge pull request #269 from SabreTools/logjam
Add option to compress log files after dumping
2021-04-02 22:47:26 -07:00
Matt Nadareski
22b15710d0 Take output of compression into account for log 2021-04-02 22:34:46 -07:00
Matt Nadareski
87199c1b0d Update changelog 2021-04-02 22:28:01 -07:00
Matt Nadareski
7e5952bbb8 Add log file lsits for CleanRip and UIC 2021-04-02 22:23:15 -07:00
Matt Nadareski
1a52a3a205 Add Check parameter for compression 2021-04-02 22:20:15 -07:00
Matt Nadareski
742db4c854 Change default archive name 2021-04-02 22:12:32 -07:00
Matt Nadareski
4fd51dbe45 Default to false, for now 2021-04-02 21:57:00 -07:00
Matt Nadareski
096a8a6a06 Add Aaru log file paths, remove TODO in DIC 2021-04-02 21:56:14 -07:00
Matt Nadareski
ad5cd5b8f9 Only encode artifacts if we're outputting JSON 2021-04-02 21:53:41 -07:00
Matt Nadareski
3230d59f6a Fix options window 2021-04-02 21:49:57 -07:00
Matt Nadareski
96fa8d8cef Add DiscImageCreator log paths 2021-04-02 21:36:14 -07:00
Matt Nadareski
01bf3c9efb Add log file compression 2021-04-02 21:21:50 -07:00
Matt Nadareski
da0bf64e94 Add log compression option 2021-04-02 20:55:20 -07:00
Matt Nadareski
d39cf5d13f Make JSON optional (fixes #268) 2021-04-02 18:57:25 -07:00
Matt Nadareski
7c7e78fd4e Errors during dumping should be more verbose
This should *hopefully* be a temporary change in order to determine what is failing after many dumps in a row.
2021-04-02 14:23:02 -07:00
Matt Nadareski
d2c504898a Empty the queue at least 2021-04-01 19:08:39 -07:00
Matt Nadareski
58028b4f18 Reset queue entirely to prevent issues 2021-04-01 15:11:30 -07:00
Matt Nadareski
54e835687b Only rely on cancellation not disposal 2021-04-01 15:10:43 -07:00
Matt Nadareski
10f2318541 Update to DIC 20210401 2021-03-31 22:11:02 -07:00
Matt Nadareski
eb4e95e5db Fix ProcessingQueue disposal (fixes #267) 2021-03-31 21:26:55 -07:00
Matt Nadareski
203418eebc CD-i is a fake audio format 2021-03-31 20:36:06 -07:00
Matt Nadareski
136c6c8fbf Remove two useless TODOs 2021-03-29 13:11:45 -07:00
Matt Nadareski
2c216d6a58 Use BurnOutSharp for PSX scanning 2021-03-29 13:10:49 -07:00
Matt Nadareski
f7ec19cc5d Clean up a couple more TODOs 2021-03-29 13:05:46 -07:00
Matt Nadareski
e8c4a97158 Fix flag value 2021-03-29 12:14:06 -07:00
Matt Nadareski
5e5fc4c812 Factor in size to media type output 2021-03-29 12:12:20 -07:00
Matt Nadareski
5e0d99ff5d Remove unnecessary TODOs 2021-03-29 12:12:05 -07:00
Matt Nadareski
e88e67c927 Fix broken test 2021-03-29 11:56:28 -07:00
Matt Nadareski
d963dbbd5f Move some classes around and cleanup 2021-03-29 11:55:29 -07:00
Matt Nadareski
11ce78fca2 Fix and use ProcessingQueue 2021-03-29 10:50:43 -07:00
Matt Nadareski
fd4022ba84 Add ProcessingQueue (nw) 2021-03-29 10:23:34 -07:00
Matt Nadareski
f91aecad8e Add queueing mechanism to DumpEnvironment 2021-03-29 09:35:39 -07:00
Matt Nadareski
709b7d357f It's a secret... 2021-03-28 22:29:22 -07:00
Matt Nadareski
59980fa160 Clear button should clear progress bar too 2021-03-28 22:25:03 -07:00
Matt Nadareski
180caf83cc Forgot to update param comment and changelog 2021-03-28 22:22:27 -07:00
Matt Nadareski
7047ee832a Simplify null checks 2021-03-28 22:15:33 -07:00
Matt Nadareski
4b5532e1b0 Log levels, struct methods, simpler constructor 2021-03-28 22:10:17 -07:00
Matt Nadareski
137155d3dc Forgot summary comment 2021-03-28 21:34:27 -07:00
Matt Nadareski
793dd8289a Safer queue, use LogLine struct again
Once ConcurrentQueue was used, there were issues with using Run objects in the queue. Even with Dispatcher, there were access issues. So back to the minimal struct.
2021-03-28 21:30:42 -07:00
Matt Nadareski
bcf298e40b Change name of log queue 2021-03-28 20:38:59 -07:00
Matt Nadareski
589aef1e21 Use Run instead of custom wrapper
This simplifies a whole bunch of logic that had to convert from one type to another.
2021-03-28 20:38:15 -07:00
Matt Nadareski
9ab0b7ab3b Clean up var and methods in logger 2021-03-28 20:28:59 -07:00
Matt Nadareski
4c5ea13aac Add log queuing 2021-03-28 15:38:51 -07:00
Matt Nadareski
0cf48bbdaa Cache last line object instead 2021-03-28 13:58:11 -07:00
Matt Nadareski
8fc9cc18a3 Simplify dispatcher calls 2021-03-28 00:21:48 -07:00
Matt Nadareski
b1e156eed6 Smarter about matchers 2021-03-27 22:23:29 -07:00
Matt Nadareski
a8b3a837ef Simplify matchers, fix percentages 2021-03-27 13:21:42 -07:00
Matt Nadareski
3f3a1c9a44 Support new Redump languages and regions 2021-03-27 10:28:45 -07:00
Matt Nadareski
cf4d2f5055 Fix typo in progress 2021-03-25 22:56:17 -07:00
Matt Nadareski
2d19d51bc7 Add matcher for anti-mod string search 2021-03-25 18:48:19 -07:00
Matt Nadareski
4842bdd38b Have the log catch exceptions during matching 2021-03-24 20:20:24 -07:00
Matt Nadareski
7cc4f6d6a7 Only list protections found, not the files
This may be gated behind a flag in the future as having the full list of files and their associated protections can be useful.
2021-03-21 15:38:52 -07:00
Matt Nadareski
b284ffd99d Fix build 2021-03-20 12:47:51 -07:00
Matt Nadareski
81d0cc2cc2 Replace . with _ for DIC output paths (fixes #264) 2021-03-19 21:14:33 -07:00
Matt Nadareski
70f368d6e9 Make copy scan errors separate (fixes #263) 2021-03-19 17:44:42 -07:00
Matt Nadareski
bfbae5cf5c Fix default output directory in UI 2021-03-15 22:06:31 -07:00
Matt Nadareski
7cc231f5fd Fix incorrectly disposing stream 2021-03-15 22:06:14 -07:00
Matt Nadareski
eda34b3477 Fix text alignment 2021-03-14 19:37:06 -07:00
Matt Nadareski
bfb67ec0c9 Make UI more consistent for dump button 2021-03-12 15:29:26 -08:00
Matt Nadareski
275fd0da48 Rearrange DumpEnvironment code 2021-03-12 15:14:40 -08:00
Matt Nadareski
1ad5c25ed0 Remove .NET Framework 4.7.2, update copyright dates 2021-03-12 15:05:33 -08:00
Matt Nadareski
512f7ae016 Clean up parameters and related
This makes some former virtual methods into properties, cleans up the location of some logic, and makes the BaseParameters class a little neater
2021-03-12 14:59:04 -08:00
Matt Nadareski
3a00efc7fd Make dumping path a little easier to follow
Resets the progress bar a bit earlier
Disables/enables UI elements during dumping to avoid weird interactions
Handle more things that shouldn't be verbose logs
2021-03-11 22:14:19 -08:00
Matt Nadareski
3068c74ad7 DVD/BD have more label info possible 2021-03-11 18:50:06 -08:00
Matt Nadareski
9bdead5616 Various bits of maintenence
Added and fixed some of the CD DIC Matchers
Added caching for last line of text and last matcher used
Made replacing the last line more efficient
Fixed default system handling
Fixed potential issue with sector reading
2021-03-11 13:02:48 -08:00
Matt Nadareski
0ed5feb96b Support a new Matcher for DIC DVD 2021-03-10 19:11:31 -08:00
Matt Nadareski
ec80ef2ede Sort matchers and add a couple more 2021-03-10 16:08:08 -08:00
Matt Nadareski
617591cc26 Fix redump username binding 2021-03-10 15:25:42 -08:00
Matt Nadareski
c855aa5cef Make outputting to separate window a setting 2021-03-10 15:13:11 -08:00
Matt Nadareski
e2a27479f5 Display dump progress in log window (fixes #131)
This builds heavily upon the work that Jack put into capturing and processing DIC outputs. For now, there are only matchers for DIC outputs. All other programs will still direct to the log window, but may not be processed as neatly
2021-03-10 14:51:13 -08:00
Matt Nadareski
c8cfe76aa3 Better text bindings 2021-03-09 16:38:15 -08:00
Matt Nadareski
ecb0234258 Make inner and outer layers more apparent
Also makes label and data side data make more sense
2021-03-09 14:06:18 -08:00
Matt Nadareski
24ce4bcc51 Make layers more clearly named 2021-03-09 13:32:10 -08:00
Matt Nadareski
162af3de31 Hook up default system in options (fixes #246) 2021-03-09 12:01:45 -08:00
Matt Nadareski
7c0af96dc9 Make XGD extension 2021-03-09 09:55:08 -08:00
Matt Nadareski
026f999b46 VideoNow discs are audio only (fixes #261) 2021-03-09 09:41:39 -08:00
Matt Nadareski
bbbc3e98a0 One more pass on options 2021-03-08 22:19:22 -08:00
Matt Nadareski
f78ad4e7b6 Fix incorrect eject value for Check 2021-03-08 20:48:51 -08:00
Matt Nadareski
d756ae2163 Fix poorly designed tests 2021-03-08 16:19:53 -08:00
Matt Nadareski
701738ce25 Forgot about nulls 2021-03-08 15:47:29 -08:00
Matt Nadareski
620bdc9132 Reduce logic weirdness, possibly fix PIC layerbreak 2021-03-08 15:40:30 -08:00
Matt Nadareski
71f474c26c CMI is its own option 2021-03-08 15:20:13 -08:00
Matt Nadareski
c48137a5c1 Update changelog (fixes #259) 2021-03-08 15:11:11 -08:00
Matt Nadareski
e248368484 Add force dumping option for Aaru 2021-03-08 15:10:09 -08:00
Matt Nadareski
7225b8c32d Make eject after dump an option 2021-03-08 15:06:40 -08:00
Matt Nadareski
20e475e130 Separate out Aaru and DIC options 2021-03-08 14:56:26 -08:00
Matt Nadareski
88dc005592 Use aaruf instead of aif 2021-03-08 14:51:44 -08:00
Matt Nadareski
40792ff0eb Update changelist 2021-03-07 14:20:01 -08:00
Matt Nadareski
6ae59e91de Shuffle things for Redump obviousness 2021-03-07 14:17:25 -08:00
Matt Nadareski
5c7aa5f7f5 Hook up language selection for PS2 2021-03-07 13:45:24 -08:00
Matt Nadareski
aaa1ed674f Fix path population on drive scan 2021-03-07 10:19:59 -08:00
Matt Nadareski
42def3bbe5 Fix dropdown population 2021-03-07 10:05:54 -08:00
Matt Nadareski
9cdab52556 Fix system selection regression 2021-03-06 21:49:33 -08:00
Matt Nadareski
5c104ebf3d Fix tests 2021-03-06 21:47:02 -08:00
Matt Nadareski
7ab72e542c Fix auto extension filling 2021-03-05 17:18:08 -08:00
Matt Nadareski
3a8420cd2f Fix broken dumping 2021-03-05 17:14:15 -08:00
Matt Nadareski
916aa9fd70 Move things around like Shadow 2021-03-02 11:34:48 -08:00
Matt Nadareski
8809df10b6 Use Shadow's disable code for categories 2021-03-02 09:55:50 -08:00
Matt Nadareski
34d65a9d70 KnownSystem cleanup based on Shadow's stuff 2021-03-02 09:48:36 -08:00
Matt Nadareski
2830d7c8a2 Use Shadow's combined element model 2021-03-02 09:08:56 -08:00
Matt Nadareski
c702c8b0ac Update to DIC 20210301 2021-03-02 09:05:44 -08:00
Matt Nadareski
e1df9a9754 Use Shadow's description converter implementation 2021-03-01 23:02:45 -08:00
Matt Nadareski
03fe5ce8a5 Take Shadow's advice about lists 2021-03-01 22:58:55 -08:00
Matt Nadareski
432a9dda16 Clean up options binding 2021-03-01 21:51:40 -08:00
Matt Nadareski
1dfc0f731e UniformGrid 2021-03-01 21:09:26 -08:00
Matt Nadareski
af515e0adf Update attributions 2021-02-28 13:19:55 -08:00
Matt Nadareski
2222b57143 Fix spelling 2021-02-28 11:37:53 -08:00
Matt Nadareski
d8cfa2e6a4 Quick touch-up on disc info window 2021-02-28 11:36:29 -08:00
Matt Nadareski
a622cdd4e0 Clean up tabified Options window 2021-02-28 11:20:38 -08:00
Matt Nadareski
2a4ec83d0d 1 to 1 tabification of Options window 2021-02-28 11:02:21 -08:00
Matt Nadareski
b1d144d091 A little more log view cleanup 2021-02-28 10:55:49 -08:00
Matt Nadareski
23a8b66c16 Get rid of warning 2021-02-28 10:29:51 -08:00
Matt Nadareski
381ebd5961 Clean up logging view 2021-02-28 10:28:31 -08:00
Matt Nadareski
b4d1f7d6c3 LogWindow -> LogOutput 2021-02-28 02:28:53 -08:00
Matt Nadareski
b3eff64275 Get fancy with expander 2021-02-28 00:46:38 -08:00
Matt Nadareski
f15c00acca Multiline comments and contents 2021-02-28 00:36:36 -08:00
Matt Nadareski
a66d0d4722 Perform some cleanup on Options window 2021-02-27 23:23:12 -08:00
Matt Nadareski
66cdade01b Fix layerbreak reading (wrong endianness) 2021-02-27 23:04:25 -08:00
Matt Nadareski
9e9f001768 More StackPanel stuff 2021-02-27 22:39:07 -08:00
Matt Nadareski
3514bdcbc4 Update changelist 2021-02-27 22:32:37 -08:00
Matt Nadareski
312df37365 Use tabs, enable layers 2 and 3 2021-02-27 22:32:03 -08:00
Matt Nadareski
6214d91940 Rename ring fields in SubmissionInfo 2021-02-27 21:47:10 -08:00
Matt Nadareski
23d500434b Add and use UserInput
Please note that this only affects the disc information window for now. This may end up in the others later.
2021-02-27 21:33:37 -08:00
Matt Nadareski
7ee5e3ab43 Add PIC parsing 2021-02-27 16:58:09 -08:00
Matt Nadareski
6be4bb7c85 Boilerplate for 4 layer support 2021-02-26 22:52:28 -08:00
Matt Nadareski
d620c13e22 Update changelist 2021-02-26 22:38:21 -08:00
Matt Nadareski
73b585cdd2 Add PS5 version extraction (fixes #258) 2021-02-26 22:36:43 -08:00
Matt Nadareski
2f33581e4a Add PS5 console to list 2021-02-26 22:27:36 -08:00
Matt Nadareski
f3dba9a026 Add Xbox Series consoles to list 2021-02-26 22:13:18 -08:00
Matt Nadareski
d7d0af369c Boilerplate for 3 layer support 2021-02-26 21:58:10 -08:00
Matt Nadareski
2ab9a45a71 Update changelist 2021-02-04 22:06:13 -08:00
Matt Nadareski
dc0bf642a9 Better handling of drive changes
Similar to how things like changed options, UI initialization, and media scan all share basically the same path, most of what goes into changing drive letter is the same. So with a small tweak to that code, it is viable to use that method for all 4 paths.
2021-02-04 21:52:26 -08:00
Matt Nadareski
9e32435972 Reorganize Drive class a little 2021-02-04 21:38:57 -08:00
Matt Nadareski
c2b724e949 Auto-detect VCD (fixes #257) 2021-02-04 21:16:42 -08:00
Matt Nadareski
195d3c6ff7 Update to DIC 20210202 2021-02-01 21:16:59 -08:00
Matt Nadareski
04a8079cee Add better notes and outputs for process 2021-01-26 22:46:06 -08:00
Matt Nadareski
0b2daf7d30 Add notes, remove a couple files from serialization 2021-01-26 22:45:38 -08:00
Matt Nadareski
1353ee603b Fix serialization issue 2021-01-26 22:45:04 -08:00
Matt Nadareski
e9d272d139 Potentially massive file gets compressed 2021-01-26 20:55:45 -08:00
Matt Nadareski
0308c7a81e Direct to Base64 for binary files 2021-01-26 17:12:44 -08:00
Matt Nadareski
4caad10c9b Comment out binary files for now 2021-01-26 14:36:35 -08:00
Matt Nadareski
85c1623d33 Forgot the DVD/BD binary files 2021-01-26 13:55:05 -08:00
Matt Nadareski
5be1825bb5 Add all output files as encoded artifacts to JSON 2021-01-26 13:45:12 -08:00
Matt Nadareski
ec5e533bd8 Rename currently unused variable 2021-01-26 13:44:38 -08:00
Matt Nadareski
c3e4c7fa78 Add artifacts section to submission info 2021-01-26 11:39:45 -08:00
Matt Nadareski
bf66a3fcbd Add version to submission info 2021-01-25 17:05:32 -08:00
Matt Nadareski
101193cb78 Streamline statuses from trying to execute 2021-01-25 13:11:20 -08:00
Matt Nadareski
b610c29be6 Log exceptions on dumping as well 2021-01-25 12:05:46 -08:00
Matt Nadareski
999c4dceb5 Ensure the executable exists before trying to run it 2021-01-25 11:55:18 -08:00
Matt Nadareski
2957370fac Missed a couple of places 2021-01-25 10:21:50 -08:00
Matt Nadareski
5dd36d7b06 Inline all of those params during logging 2021-01-25 10:02:34 -08:00
Matt Nadareski
47b5bbe7e7 Update to BurnOutSharp 1.5.1 2021-01-22 12:03:12 -08:00
Matt Nadareski
5a2e4ca77e Add link to BOS in issue templates 2021-01-21 11:15:10 -08:00
Matt Nadareski
c479ddb80b Fix duplicate security sector data 2021-01-15 22:06:19 -08:00
Matt Nadareski
da1f59e0c1 Fix UIC output parsing and generation 2021-01-15 14:31:31 -08:00
Matt Nadareski
9574832e86 Add ability to get hashes for UIC outputs 2021-01-15 12:52:55 -08:00
Matt Nadareski
3df7842d23 Add ability to hash a file to base parameters 2021-01-15 12:13:27 -08:00
Matt Nadareski
62a0f6e49a Port most hashing code from SabreTools
Note that this explcitly omits both the formerly-supported RIPEMD160 as well as the currently-Aaru-specific SpamSum.
2021-01-15 11:57:24 -08:00
Matt Nadareski
60c180e4dd UIC outputs don't contain a datfile 2021-01-15 11:49:27 -08:00
Matt Nadareski
343d937362 Fix BCA formatting for CleanRip outputs (fixes #251) 2021-01-12 15:36:02 -08:00
Matt Nadareski
f20b321433 Add *tmp file support for DIC 2021-01-07 09:52:00 -08:00
Matt Nadareski
ba19b0825f Update changelist 2021-01-06 09:58:50 -08:00
Matt Nadareski
5abb44957c Add common path for init of full UI
This unites the code that runs when the application is loaded, when options are updated, and when a drive scan is initiated. All 3 situations require that nearly every bit of the UI and possibly even the disc to be re-scanned.
2021-01-05 21:39:46 -08:00
Matt Nadareski
b9d9cf812f Slightly different _mainInfo wording now... 2021-01-03 14:22:25 -08:00
Matt Nadareski
d1529f428a Updated to DIC version 20210102 2021-01-02 22:03:18 -08:00
Matt Nadareski
5061a79c4c Make initial window load more accurate 2020-12-31 14:57:06 -08:00
Matt Nadareski
eab3e25cf2 Fix crash on drive scan 2020-12-31 13:39:19 -08:00
Matt Nadareski
33e73a8992 More messages isnt a bad thing 2020-12-31 11:02:14 -08:00
Matt Nadareski
a63972b549 Get reasonable defaults based on selected system 2020-12-30 22:57:36 -08:00
Matt Nadareski
bc57df7fc1 Add a note for later 2020-12-30 22:29:42 -08:00
Matt Nadareski
e16f616286 Safer queries on getting disc type 2020-12-30 22:20:47 -08:00
Matt Nadareski
c5497d787b Ensure parameters have system and type set 2020-12-30 21:14:06 -08:00
Matt Nadareski
64f60004c4 Error messages on Redump errors 2020-12-30 15:00:52 -08:00
Matt Nadareski
020c063177 Parameters should know their state better 2020-12-30 14:49:28 -08:00
Matt Nadareski
a3e6f8157f Extension cleanup 2020-12-30 14:28:46 -08:00
Matt Nadareski
f27040cd1c Add informational issue template 2020-12-30 14:07:11 -08:00
Matt Nadareski
3a490cfc8d Add note about DIC-only dumps 2020-12-30 14:02:51 -08:00
Matt Nadareski
1f8c5998c1 Fix copy-paste error 2020-12-29 11:15:24 -08:00
Matt Nadareski
f96d4ee37e More safety around listing operations 2020-12-29 11:10:15 -08:00
Matt Nadareski
d0d15f03af Remove Avalonia UI (fixes #245) 2020-12-29 10:56:25 -08:00
Matt Nadareski
eff6407206 Remove CD-i DV from supported profiles 2020-12-27 13:39:26 -08:00
Matt Nadareski
c1e559568a Fix build 2020-12-26 14:31:59 -08:00
Matt Nadareski
ef030b290c Add support for new Redump regions 2020-12-26 14:03:24 -08:00
Matt Nadareski
71630591a1 Add short-circuit for unmatched tracks 2020-12-12 13:37:33 -08:00
Matt Nadareski
31505745be Update to Aaru v5.2 2020-12-02 20:51:56 -08:00
Matt Nadareski
e40444b60c Update changelist 2020-11-30 21:24:15 -08:00
Matt Nadareski
44edf387a6 Relabel labels depending on media type 2020-11-30 16:12:54 -08:00
Matt Nadareski
d3d225644d Add preliminary "default system" support 2020-11-23 14:00:15 -08:00
Matt Nadareski
3afd9200a9 Multiline fields require matching newlines 2020-11-23 13:45:36 -08:00
Matt Nadareski
c5c340ff12 Make label SID change for Avalonia too 2020-11-23 13:22:30 -08:00
Matt Nadareski
b28b85f7c6 Don't gray out label SID for DVD, HD-DVD, BD (fixes #247) 2020-11-23 13:20:37 -08:00
Matt Nadareski
c60684b83c Pass through progress in missing place 2020-11-23 13:17:27 -08:00
Matt Nadareski
a183a1ec91 Fix issue with 0xbe drives, again 2020-11-12 14:43:24 -08:00
Matt Nadareski
abd8488185 Fix remaining links 2020-11-10 20:42:04 -08:00
Matt Nadareski
e6dea158e5 Rename to MPF 2020-11-10 17:43:21 -08:00
Matt Nadareski
24150c7b3c Bump version to 1.18 2020-11-10 10:55:29 -08:00
Matt Nadareski
040720a1c2 Detect HD-DVD-Video 2020-11-08 13:40:30 -08:00
Matt Nadareski
70d30d370f Update to BurnOutSharp 1.5.0 2020-11-03 21:49:59 -08:00
Matt Nadareski
a50b99da07 Use older version of DIC for now 2020-11-01 16:08:57 -08:00
Matt Nadareski
2cecbe69ad Support the /ps command for DIC 2020-10-31 23:05:11 -07:00
Matt Nadareski
557410660f Update to DIC 20201101 2020-10-31 22:55:07 -07:00
Matt Nadareski
0d75dbaaa2 Add dumping program selection finally 2020-10-11 22:06:40 -07:00
Matt Nadareski
d38f95c73a Check sector 0 for Saturn, if possible (fixes #241) 2020-10-11 21:15:35 -07:00
Matt Nadareski
c9d59a90e4 Default to CD-ROM when detection fails as well 2020-10-11 21:07:28 -07:00
Matt Nadareski
fc6a34d987 Use CD-ROM as default when no type detection (fixes #237) 2020-10-11 20:46:24 -07:00
Matt Nadareski
8acabb692f Remove default config file (fixes #238) 2020-10-11 20:36:12 -07:00
Matt Nadareski
61f8871839 Change default for fixed drive detection (fixes #233) 2020-10-11 20:35:39 -07:00
Matt Nadareski
69d61ad185 Use selected drive in UI for copy protect scan (fixes #235) 2020-10-11 20:31:27 -07:00
Matt Nadareski
27391ed31b Remove subdump (fixes #234)
Note that it still downloaads the subdump executable and puts it in the same place. This won't be changing anytime soon since it's useful. It also is flat out removing the option in the menu without replacing or reshaping the menu. This will be addressed at a later date.
2020-10-11 20:24:41 -07:00
Matt Nadareski
ed56c92101 Clean up sector read method a bit more (nw) 2020-10-08 21:21:11 -07:00
Matt Nadareski
ab8ae1524f Actually use the drive letter (nw) 2020-10-08 14:18:23 -07:00
Matt Nadareski
de7c247583 Add initial version of sector reading to library 2020-10-08 12:26:28 -07:00
Matt Nadareski
997fd8f7ac Why do I keep forgetting changelist? 2020-10-01 11:46:55 -07:00
Matt Nadareski
e39e07246a Fix archive naming 2020-10-01 11:34:27 -07:00
Matt Nadareski
e0b0406d76 Let's see how badly this goes... 2020-10-01 11:28:39 -07:00
Matt Nadareski
1efbe9a784 Update BurnOutSharp version; fix autobuild 2020-10-01 09:44:49 -07:00
Matt Nadareski
fab921c2dd Added feature request template 2020-09-29 13:01:28 -07:00
Matt Nadareski
56896b4bea Update issue templates 2020-09-29 12:57:19 -07:00
Matt Nadareski
54eb7d8ecd Forgot the changelog 2020-09-28 11:26:47 -07:00
Matt Nadareski
114587b9f6 Reset paragraph state on clear (fixes #231) 2020-09-28 11:22:40 -07:00
Matt Nadareski
cad33c6c07 Don't lose automatic comments 2020-09-24 15:25:56 -07:00
Matt Nadareski
8154999f1c Fix alternate mainInfo parsing 2020-09-24 15:08:17 -07:00
Matt Nadareski
3a30c14085 Make this apparent on the main page 2020-09-24 11:42:28 -07:00
Matt Nadareski
db8b1df480 Add rolling changelog section 2020-09-24 11:35:16 -07:00
Matt Nadareski
e20cac8a80 Sync 2020-09-24 10:57:09 -07:00
Matt Nadareski
ce9b4e39f5 Add more internal info for GD-ROM LD 2020-09-24 10:49:27 -07:00
Matt Nadareski
ddff4b2e58 SCD has internal serial 2020-09-24 10:26:51 -07:00
Matt Nadareski
16a470475c Remember, no Disc 2020-09-24 10:21:35 -07:00
Matt Nadareski
6e01473e87 Saturn serial -> internal serial, strip 'V' from version 2020-09-24 10:19:34 -07:00
Matt Nadareski
8682089151 Update to DIC 20200921 2020-09-23 10:11:38 -07:00
Matt Nadareski
f45cb0075f Remove superflous check for PVD retrieval (fixes #229) 2020-09-19 14:31:17 -07:00
Matt Nadareski
afccb48798 Specify solution file 2020-09-19 13:40:36 -07:00
Matt Nadareski
ce6995fba0 It was seriously a directory marker issue 2020-09-17 22:04:31 -07:00
Matt Nadareski
3328d1adea Try without the git extension 2020-09-17 22:00:51 -07:00
Matt Nadareski
33d79df9a8 Update AppVeyor 2020-09-17 21:59:07 -07:00
Matt Nadareski
4fb64b19d6 Remove weird csproj stuff 2020-09-17 21:57:00 -07:00
Matt Nadareski
bf0f495c8b Ignore all files except the compiled cicm.cs 2020-09-17 21:54:50 -07:00
Matt Nadareski
5d5f8e8d8c Use official repo as submodule for CICM 2020-09-17 21:52:40 -07:00
Matt Nadareski
91aa248355 A little more cleanup and safety 2020-09-17 21:38:45 -07:00
Matt Nadareski
633c6c1efb Slight tweaks, mostly naming 2020-09-17 21:25:22 -07:00
Matt Nadareski
facb1f673f Wrap login call with try/catch 2020-09-17 15:52:29 -07:00
Matt Nadareski
9c8938c7f2 Get some more layerbreak stuff 2020-09-17 13:30:35 -07:00
Matt Nadareski
17f75f3ce6 First parts of layerbreak info 2020-09-17 10:37:04 -07:00
Matt Nadareski
b99c48afa2 First part of DVD protection extraction for Aaru 2020-09-16 20:45:07 -07:00
Matt Nadareski
9481fada23 Fix writing of valid indexes for Aaru cuesheet 2020-09-16 17:13:15 -07:00
Matt Nadareski
7efbc5043c Add error count for Aaru outputs 2020-09-16 17:00:11 -07:00
Matt Nadareski
92880d3148 Fix discs with ISO extension 2020-09-16 16:25:33 -07:00
Matt Nadareski
9800f2b8ae Use spans instead of Linq (and accidental commit) 2020-09-16 16:09:34 -07:00
Matt Nadareski
a5d01604cb Strip out hard-to-find CD Check instances 2020-09-16 16:01:16 -07:00
Matt Nadareski
aaab84f90a Fix multiple things in Aaru
Addresses overlooked issue with DatFile generation, consolidates common code into methods, fixes PVD generation and write
2020-09-16 15:59:11 -07:00
Matt Nadareski
318a1a303c Fix multiline outputs 2020-09-16 15:58:02 -07:00
Matt Nadareski
0061de6b2e Fix cuesheet write-to-stream 2020-09-16 15:57:22 -07:00
Matt Nadareski
b3db7c547f Generate cuesheet using new classes for Aaru 2020-09-16 14:31:29 -07:00
Matt Nadareski
1da29464a8 Add writing of cuesheets 2020-09-16 14:09:02 -07:00
Matt Nadareski
d1d4ff41c6 Fix reading (assumes reasonably sized cuesheets) 2020-09-16 13:41:00 -07:00
Matt Nadareski
673c2745a9 Fix index check 2020-09-16 13:00:42 -07:00
Matt Nadareski
4ad88441cc Add parsing in of cuesheets 2020-09-16 12:53:28 -07:00
Matt Nadareski
71bb822856 Add cuesheet structures 2020-09-16 11:22:33 -07:00
Matt Nadareski
2a7789bd12 Bump version to 1.17.1 2020-09-15 10:03:39 -07:00
Matt Nadareski
1d0417cc1c Fix DiscInformationWindow issues 2020-09-14 13:51:26 -07:00
Matt Nadareski
905c578d90 Fix DIC flags based on the code 2020-09-14 13:30:14 -07:00
Matt Nadareski
a457c85e53 Better internal handling of Options window 2020-09-13 21:01:53 -07:00
Matt Nadareski
36630fc0ed Fix the tests I broke 2020-09-13 20:52:08 -07:00
Matt Nadareski
f509ac60da Make DiscInformationWindow more robust 2020-09-13 20:41:23 -07:00
Matt Nadareski
bf8aac6f81 Move some constants around 2020-09-13 20:41:09 -07:00
Matt Nadareski
ceddcc0722 Remove useless passthrough vars 2020-09-12 14:11:55 -07:00
Matt Nadareski
3a2bda6fb6 Bump version to 1.17 2020-09-11 21:31:46 -07:00
Matt Nadareski
aea2403153 Remove fields that are too variable 2020-09-11 11:48:45 -07:00
Matt Nadareski
6e334df42f Cleanup now that .NET 4.6.2 is gone 2020-09-10 23:30:07 -07:00
Matt Nadareski
04cb68c9bd Rearrange based on Avalonia 2020-09-10 23:21:18 -07:00
Matt Nadareski
06060c071b Update all libraries, including BurnOutSharp 2020-09-10 22:45:36 -07:00
Matt Nadareski
02903686ad Remove accidental add 2020-09-10 22:02:12 -07:00
Matt Nadareski
00cbed725d Only fill error count if it's missing 2020-09-10 21:09:35 -07:00
Matt Nadareski
dabccd3a8a Fix for LibCrypt detect until BOS updated 2020-09-10 21:00:16 -07:00
Matt Nadareski
0e1e499a66 Guard against false positive LibCrypt (fixes #226) 2020-09-10 20:46:43 -07:00
Matt Nadareski
b4f485a0cc Add PS1/PS2 internal serial to comments (fixes #227) 2020-09-10 20:32:51 -07:00
Matt Nadareski
5bad68b9ff Include warning count with error count 2020-09-10 20:14:08 -07:00
Matt Nadareski
2db686fc47 Backport accept/cancel from Avalonia 2020-09-10 11:44:44 -07:00
Matt Nadareski
d705a4b316 UmdImageCreator stands alone 2020-09-10 11:27:25 -07:00
Matt Nadareski
0154ee5bb6 Start wiring through DCDumper a bit 2020-09-10 11:11:26 -07:00
Matt Nadareski
29f14f5690 Remove .NET 4.6.2 from readme 2020-09-10 10:54:47 -07:00
Matt Nadareski
dd6f7b0794 Consolidate version checking 2020-09-10 10:53:47 -07:00
Matt Nadareski
e5c9591d64 Merge pull request #225 from SabreTools/crossplat
Add Avalonia UI
2020-09-10 10:37:13 -07:00
Matt Nadareski
df8da8bd46 Fix PS1 copy protect output (fixes #222) 2020-09-10 10:32:21 -07:00
Matt Nadareski
c9b21006d1 Fix update check (fixes #220) 2020-09-09 14:34:50 -07:00
Matt Nadareski
2b37882322 Reformat CSS data (fixes #224) 2020-09-09 14:07:12 -07:00
Matt Nadareski
8a2b3f2c89 Separation of Creators 2020-09-09 11:08:20 -07:00
Matt Nadareski
c16a9aeb70 Couple more 2020-09-09 10:38:00 -07:00
Matt Nadareski
d5a0797c92 Couple more mapped values 2020-09-09 10:36:43 -07:00
Matt Nadareski
a55a769886 Fix conversion issue 2020-09-09 10:05:09 -07:00
Matt Nadareski
fd18c60f28 Let's reference the Wiki 2020-09-08 23:30:02 -07:00
Matt Nadareski
2704d1f88d Add 'private' flag to Paranoia mode for Aaru (fixes #212) 2020-09-08 22:53:43 -07:00
Matt Nadareski
c16c938fa4 Change end of section marker for XGD (fixes #219) 2020-09-08 22:51:17 -07:00
Matt Nadareski
497e2a09fd Add as many default regions as possible 2020-09-08 22:41:36 -07:00
Matt Nadareski
8bc8887ce6 Set Region name default again 2020-09-08 22:22:52 -07:00
Matt Nadareski
7e5a5586f9 Merge pull request #221 from sadikyo/patch-1
Update README.md
2020-09-08 22:14:56 -07:00
sadikyo
eee068db7e Update README.md
A few minor spelling and grammar corrections
2020-08-27 13:31:47 -04:00
Matt Nadareski
79e70173fa Add more standard programs to doc 2020-08-14 16:12:57 -07:00
Matt Nadareski
4f732557b9 Drive label should not contain bad chars 2020-08-14 12:59:23 -07:00
Matt Nadareski
6cbcebd661 Do the README shuffle 2020-08-14 11:06:57 -07:00
Matt Nadareski
f74dc01657 Fix percentage in Avalonia 2020-08-07 22:05:04 -07:00
Matt Nadareski
4735bef7b4 Merge branch 'master' into crossplat 2020-08-07 22:01:56 -07:00
Matt Nadareski
52a925df12 Fix percentage output 2020-08-07 22:00:15 -07:00
Matt Nadareski
3e10199cb0 Add path and scan to Check 2020-08-07 21:15:36 -07:00
Matt Nadareski
470e641a8c Protection scan output to Avalonia 2020-08-06 22:53:11 -07:00
Matt Nadareski
f61b84d058 Okay, fine 2020-08-06 22:53:11 -07:00
Matt Nadareski
5e77b43be1 Add icon, fix version, copyright, appveyor 2020-08-06 22:53:09 -07:00
Matt Nadareski
46530a9fca Add Avalonia, remove NET462 2020-08-06 22:53:07 -07:00
Matt Nadareski
12610c0d69 Add missing file feedback 2020-08-06 22:52:25 -07:00
Matt Nadareski
9bb9d3f407 Add progress to protection scan 2020-08-06 22:05:16 -07:00
Matt Nadareski
a0ed20042c Explain components 2020-08-04 13:53:33 -07:00
Matt Nadareski
37c253aac2 Preliminary use of cicm.cs 2020-08-03 12:52:53 -07:00
Matt Nadareski
68135c58ae Vut default hol output 2020-08-02 22:22:33 -07:00
Matt Nadareski
f9efa71fcc Better categorization 2020-08-02 22:00:07 -07:00
Matt Nadareski
184913ad28 Fix a couple of small things 2020-08-02 21:51:19 -07:00
Matt Nadareski
ff52767a02 Add DVD-Audio 2020-08-02 21:41:38 -07:00
Matt Nadareski
34ac5f9ba0 Fix audio disc error count (fixes #215) 2020-08-02 21:22:24 -07:00
Matt Nadareski
7296d109cc Set default categories (fixes #214) 2020-08-02 20:46:30 -07:00
Matt Nadareski
9be705ae30 Remove erroneous return (fixes #213) 2020-07-30 14:32:39 -07:00
Matt Nadareski
af8b376f5a Clarify wording 2020-07-28 14:28:54 -07:00
Matt Nadareski
03f9668048 Update README with more information 2020-07-28 14:10:29 -07:00
Matt Nadareski
3bb23fa7cc Update to Aaru v5.1 2020-07-24 21:04:43 -07:00
Matt Nadareski
f85c9d4e7e Move submission info to more proper place 2020-07-22 21:49:20 -07:00
Matt Nadareski
5de3d209be Migrate more to the proper place 2020-07-22 21:45:58 -07:00
Matt Nadareski
f1b136c817 Remote stands alone 2020-07-22 21:11:40 -07:00
Matt Nadareski
c18829e0b3 Sync 2020-07-22 13:54:45 -07:00
Matt Nadareski
d114b7f868 Add missing media dump params 2020-07-22 11:17:38 -07:00
Matt Nadareski
445cc173ce Fix incorrect PIC formatting 2020-07-16 14:45:51 -07:00
Matt Nadareski
1e28fcad2e Fix usage of avdp flag 2020-07-16 11:46:50 -07:00
Matt Nadareski
8d4e5155d9 Update to DIC 20200716 2020-07-16 11:06:58 -07:00
Matt Nadareski
027f562573 Change types order for XBOX/360 (fixes #209) 2020-07-07 13:13:18 -07:00
Matt Nadareski
74caf084ca Read entire PIC file (fixes #189) 2020-07-07 13:09:54 -07:00
Matt Nadareski
7396b02543 Update to DIC 20200620 2020-07-06 22:15:10 -07:00
Matt Nadareski
8035826b1b Fix datetime parsing 2020-06-25 12:39:27 -07:00
Matt Nadareski
c6e73582c5 More Aaru improvements and fixes 2020-06-25 11:19:16 -07:00
Matt Nadareski
ca09d8c703 Add Aaru to official list in Check 2020-06-25 11:17:26 -07:00
Matt Nadareski
40b6551c7a Fix README formatting 2020-06-16 17:05:17 -07:00
Matt Nadareski
95b664705d Command and DICer 2020-06-16 17:02:28 -07:00
Matt Nadareski
6bda7b35a2 Make async things async 2020-06-16 15:25:55 -07:00
Matt Nadareski
6fedebf2a9 Lower-case SHA-1 for search 2020-06-16 13:57:11 -07:00
Matt Nadareski
02f98c674b Trim on input files for Check 2020-06-16 13:25:45 -07:00
Matt Nadareski
fb1e4130df More CleanRip fixes 2020-06-16 13:25:24 -07:00
Matt Nadareski
c507f52b80 Add a hack for DICUI check in CleanRip 2020-06-16 12:50:04 -07:00
Matt Nadareski
7b2784f1a2 Wii needs CMP for Redump, separate for submission 2020-06-16 12:00:23 -07:00
Matt Nadareski
7a7c83e8cf Fix Redump check for DIC 2020-06-16 11:41:55 -07:00
Matt Nadareski
b86ef09763 Inform Check users if credentials invalid 2020-06-16 11:16:39 -07:00
Matt Nadareski
71c050edf6 Make subdump optional 2020-06-12 11:17:57 -07:00
Matt Nadareski
988f25b514 Fix INI parsing 2020-06-11 21:46:25 -07:00
Matt Nadareski
e878e8b904 Anti-modchip for the rest of us 2020-06-05 15:38:48 -07:00
Matt Nadareski
bd3484cb3d Better common methods 2020-06-05 14:15:06 -07:00
Matt Nadareski
3d769ed707 Private again 2020-06-05 11:15:51 -07:00
Matt Nadareski
613be66f91 Add INI parser, use for PS1/2 discs 2020-06-05 11:13:40 -07:00
Matt Nadareski
81e0ffbc3c Update to DIC 20200604, static 2020-06-04 16:36:09 -07:00
Matt Nadareski
8f3d325e7d Update to version 1.16.1 2020-05-07 15:40:29 -07:00
Matt Nadareski
a63472c6e6 Options (#201)
* Start reorganizing options and internals

* Make entire options flow more robust

* Few more TODOs, slightly cleaner code

* Simplify Options constructor

* Fix eject and reset

* Some other abstractions

* Enforce readonly

* Fix tests, like the TODO said

* Move specific output file parsing to specific parameters

* Add some future enums, add notes around .NET Core build path

* Wrap last incompatible .NET Core stuff

* Extract out CleanRip, fix a bunch of other spaghetti
2020-05-07 14:36:06 -07:00
Matt Nadareski
8c98005605 Fix CleanRip support 2020-05-07 14:23:49 -07:00
Matt Nadareski
8062d6cf17 Extract out CleanRip, fix a bunch of other spaghetti 2020-05-07 13:56:21 -07:00
Matt Nadareski
78bf6e63ed Wrap last incompatible .NET Core stuff 2020-05-07 13:03:24 -07:00
Matt Nadareski
68e0d759f7 Add some future enums, add notes around .NET Core build path 2020-05-07 12:58:37 -07:00
Matt Nadareski
26e72284af Move specific output file parsing to specific parameters 2020-05-06 20:24:33 -07:00
Matt Nadareski
0efecd6601 Fix tests, like the TODO said 2020-05-06 17:00:34 -07:00
Matt Nadareski
9a3c2eb626 Enforce readonly 2020-05-06 16:46:26 -07:00
Matt Nadareski
ca753b4526 Some other abstractions 2020-05-06 16:37:33 -07:00
Matt Nadareski
230b6ca721 Fix eject and reset 2020-05-06 16:06:30 -07:00
Matt Nadareski
dc90f9af3f Simplify Options constructor 2020-05-06 15:56:08 -07:00
Matt Nadareski
b5898c7ea3 Few more TODOs, slightly cleaner code 2020-05-06 15:44:46 -07:00
Matt Nadareski
36f1aea509 Make entire options flow more robust 2020-05-06 15:33:28 -07:00
Matt Nadareski
6742444182 Start reorganizing options and internals 2020-05-06 14:24:37 -07:00
Matt Nadareski
e01fd37e6b Typo 2020-05-05 14:37:34 -07:00
Matt Nadareski
ca7071f82a Update Aaru version for WIP builds 2020-05-05 14:23:23 -07:00
Matt Nadareski
3cb67e3e65 Add Python2 CNF parsing, forgot DumpEnv fixes 2020-05-01 15:02:58 -07:00
Matt Nadareski
e67dd589b5 Fix options, add fallbacks, consolidate code 2020-05-01 14:59:29 -07:00
Matt Nadareski
74f491eaaa Forgot the flag 2020-04-21 17:03:45 -07:00
Matt Nadareski
9ebd28ef5a More dd stuff, including AppVeyor. Why? Because. 2020-04-21 16:09:37 -07:00
Matt Nadareski
2a58052bfd So, I added DD support 2020-04-21 15:52:57 -07:00
Matt Nadareski
5ed73aff2b Mock out the basics needed for DD 2020-04-21 14:39:39 -07:00
Matt Nadareski
5a6ad09004 No DIC firmware check temporarily (fixes https://github.com/SabreTools/DICUI/issues/199) 2020-04-21 11:24:22 -07:00
Matt Nadareski
6a43b74043 Fix file location in AppVeyor builds 2020-04-13 12:17:17 -07:00
Matt Nadareski
69dc91aa1a Update to 1.16 2020-04-13 12:03:58 -07:00
Matt Nadareski
f840db5143 Cleanup and Upgrades (#197)
* First part of cleanup

* Second part of cleanup

* Second part of cleanup, part two

* Second part of cleanup, part three

* Second part of cleanup, part four

* Third part of cleanup

* Fourth part of cleanup (nw)

* Rebranding

* Aaru-fication

* Try to fix .NET Core builds

* Strip out CD Check for false positives

* Update DIC to 20200403

* Add .NET 4.8 to automated builds

* Address a couple of TODOs

* Typo

* Aaru is up to date

* Fix AppVeyor

* Add new systems (fixes #196)

* Fix build

Co-authored-by: Matt Nadareski <mnadareski@mparticle.com>
2020-04-13 11:55:21 -07:00
Matt Nadareski
f33cd41ebb Update BurnOutSharp (fixes #191) 2020-02-18 14:27:44 -08:00
Matt Nadareski
da7896e62a Make it super apparent they're disabled 2020-02-18 11:43:49 -08:00
Matt Nadareski
08b5b4a1aa Condiitionally disable L1 for single-layer discs 2020-02-18 11:34:57 -08:00
Matt Nadareski
c397701818 Better check for submission info write (fixes #190 2020-02-18 11:25:34 -08:00
Matt Nadareski
617eb00f21 Fix PS regex matching (fixes #192) 2020-02-18 11:15:26 -08:00
Matt Nadareski
751fd0cf1e Check PSX.EXE date second (fixes #193) 2020-02-18 11:05:15 -08:00
Matt Nadareski
84c64e6073 Add Chef as Check flag 2020-02-06 23:54:49 -08:00
Matt Nadareski
ff5bc464ab Non-dumping commands shouldn't cause issues 2020-02-04 13:25:50 -08:00
Matt Nadareski
b09a87c7e4 Partial datfile and cuesheet support for Chef 2020-02-04 00:44:12 -08:00
Matt Nadareski
4032b48e63 Calculate start better 2020-02-04 00:41:52 -08:00
Matt Nadareski
12fad35065 Fix Chef flag handling for debug, verbose, and version 2020-02-04 00:20:13 -08:00
Matt Nadareski
c28be2da72 Update Creator version... again 2020-02-04 00:16:19 -08:00
Matt Nadareski
122cc0d20b Support similarly named parameters for DiscImageChef 2020-02-03 14:17:42 -08:00
Matt Nadareski
89db32dd53 Preliminary Support for DiscImageChef (#188)
* Professional cook

* Accuracy improvements

* Better yet

* Spicy

* Simplify and reduce

* You eye note

* More info for validation

* Read you

* Verbose

* Typo

* Custom fix

* Of note

* Clearly the same

* Creator update

* Creator MCN flag gone

* Missed a spot

* Fix issues after code walkthrough
2020-02-03 14:02:24 -08:00
Matt Nadareski
59040ae0f0 Update naming schemes 2020-01-30 14:47:23 -08:00
Matt Nadareski
d8035745a9 Add button to save console output 2020-01-29 13:28:27 -08:00
Matt Nadareski
c73e13c1f0 Update packages, better LibCrypt handling (fixes #134) 2020-01-29 12:21:41 -08:00
Matt Nadareski
af75c7c949 Add .NET Core 3.0 note to README 2020-01-29 10:18:43 -08:00
Matt Nadareski
896eb28308 Upgrade EDC check for PS1 (fixes #148) 2020-01-29 10:17:56 -08:00
Matt Nadareski
6ca3d39e5f Manual protect scan can handle SmartE weirdness 2020-01-28 21:25:26 -08:00
Matt Nadareski
a7af0d0d7b Add P* serials for PlayStation (fixes #187) 2020-01-27 22:38:07 -08:00
Matt Nadareski
04f5a7ea8d Add remote version check (fixes #45) 2020-01-27 22:27:40 -08:00
Matt Nadareski
5d82cc5622 Add option to reset drive after dump (fixes #143) 2020-01-27 13:33:30 -08:00
Matt Nadareski
2f37f51c0c Simplify serial matching for PS1/PS2 (fixes #186) 2020-01-27 11:58:08 -08:00
Matt Nadareski
4690db61e1 Add CleanRip formatting support (fixes #185) 2020-01-27 03:06:11 -08:00
Matt Nadareski
672ec42903 Don't overwrite region if it already exists 2020-01-27 01:38:52 -08:00
Matt Nadareski
cb39599a46 Get region from PS1/2 executable name (fixes #175) 2020-01-27 01:34:39 -08:00
Matt Nadareski
80b5ff3920 Fix options UI, add ignore fixed drives setting (fixes #182) 2020-01-27 00:42:58 -08:00
Matt Nadareski
f27d3a91d3 Fix Check build 2020-01-27 00:04:17 -08:00
Matt Nadareski
b18357bff5 Better eject location 2020-01-27 00:03:03 -08:00
Matt Nadareski
e3cd5b7082 Move eject to before user input (fixes #173) 2020-01-26 23:59:05 -08:00
Matt Nadareski
16d7a6224b Fix drive speed selection (fixes #177) 2020-01-26 23:18:20 -08:00
Matt Nadareski
f8e32ec06c Multi-select language dropdown in submission info (fixes #170) 2020-01-26 23:06:52 -08:00
Matt Nadareski
7073d4e298 Allow testing of credentials from UI (fixes #171) 2020-01-26 22:59:03 -08:00
Matt Nadareski
f7f464920b Fix ampersand tests 2020-01-26 22:45:59 -08:00
Matt Nadareski
e677dc20e9 Add missing default setting 2020-01-26 22:45:46 -08:00
Matt Nadareski
9871eb9928 Save path fixing until the very end (fixes #176) 2020-01-26 22:24:10 -08:00
Matt Nadareski
12b43cf688 Remove ampersand filtering (fixes #180) 2020-01-26 22:06:38 -08:00
Matt Nadareski
7dd6db66ee GD-ROM LD area header extraction 2019-12-23 13:07:23 -08:00
Matt Nadareski
d7726a070e Update to DIC 20191223 2019-12-23 10:28:42 -08:00
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
189 changed files with 30930 additions and 14431 deletions

View File

@@ -0,0 +1,28 @@
---
name: Feature Request
about: For when you know better than me what you want
title: "[Request]"
labels: enhancement
assignees: mnadareski
---
**Before You Submit**
- Remember to try the [latest WIP build](https://ci.appveyor.com/project/mnadareski/mpf/build/artifacts) to see if the feature already exists.
- Is it copy protection related? If so, report the issue [here](https://github.com/mnadareski/BurnOutSharp/issues) instead.
- .NET Core 3.1 and .NET 5.0 have known limitations, so make sure that what you're asking for isn't already in another build.
- Check [previous issues](https://github.com/SabreTools/MPF/issues) to see if any of those are related to what you're about to ask for.
If none of those apply, then continue...
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

22
.github/ISSUE_TEMPLATE/informational.md vendored Normal file
View File

@@ -0,0 +1,22 @@
---
name: Info
about: Something you need to tell me
title: "[Info]"
labels: question
assignees: mnadareski
---
**Before You Submit**
- Remember to try the [latest WIP build](https://ci.appveyor.com/project/mnadareski/mpf/build/artifacts) to see if the feature already exists.
- Is it copy protection related? If so, report the issue [here](https://github.com/mnadareski/BurnOutSharp/issues) instead.
- .NET Core 3.1 and .NET 5.0 have known limitations, so make sure that what you're giving information on isn't already in another build.
- Check [previous issues](https://github.com/SabreTools/MPF/issues) to see if any of those are related to what you're about to ask for.
If none of those apply, then continue...
**Is your information related to one of the dumping programs supported or something that isn't a bug in the code? Please describe.**
A clear and concise description of what the information is. Ex. With the latest build of DumpingProgram, it [...]
**Additional context**
Add any other context or screenshots about the information here.

49
.github/ISSUE_TEMPLATE/issue-report.md vendored Normal file
View File

@@ -0,0 +1,49 @@
---
name: Issue Report
about: Tell me what's wrong, seriously
title: "[Problem]"
labels: bug
assignees: mnadareski
---
**Before You Submit**
- Remember to try the [latest WIP build](https://ci.appveyor.com/project/mnadareski/mpf/build/artifacts) to see if the issue has already been addressed.
- Is it copy protection related? If so, report the issue [here](https://github.com/mnadareski/BurnOutSharp/issues) instead.
- .NET Core 3.1 and .NET 5.0 have known issues, please try using another build to reproduce the error
- Check multiple discs to help narrow down the issue
- Check the Options to see if changing any of those affects your issue.
If all of those fail, then continue...
**Version**
What version are you using?
- [ ] Stable release (version here)
- [ ] WIP release (version here)
**Build**
What runtime version are you using?
- [ ] .NET Framework 4.7.2 running on (Operating System)
- [ ] .NET Framework 4.8 running on (Operating System)
- [ ] .NET Core 3.1 running on (Operating System)
**Describe the issue**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "MPF.Library/Aaru/CICMMetadata"]
path = CICMMetadata
url = https://github.com/claunia/CICMMetadata

27
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,27 @@
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/MPF/bin/Debug/netcoreapp3.1/MPF.dll",
"args": [],
"cwd": "${workspaceFolder}/MPF",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}

42
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,42 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/MPF/MPF.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/MPF/MPF.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"${workspaceFolder}/MPF/MPF.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}

View File

@@ -1,4 +1,238 @@
### 2.2 (2021-12-30)
- Fix Saturn header finding
- Add Pocket PC support
- Add HD-DVD-Video support
- Convert to using separate Redump library code
- Update to Aaru v5.3.0-rc1
- Update to BurnOutSharp 1.8.0
- Update support packages
- Add on-startup "check for updates" option
- Update to Aaru v5.3.0-rc2
- Add .NET 5.0 as build target
- Remove .NET Core 3.1 and .NET 5.0 from AppVeyor build artifacts
- Null-safeguard RedumpLib conversions
- Move cuesheet code to separate DLL
- Move CICMMetadata to top-level
- Separate out remaining functionality into individual DLLs
- Update to Aaru v5.3.0 LTS
- Update to DIC 20211001
- HTTP encode password for Redump login, again
- Fix NullReferenceException in anti-modchip scans
- Update arcade metadata (Shizmob)
- Add JSON output option for MPF.Check
- Fix JSON output serialization
- Ensure corrupt directories on media don't throw errors
- Add retry to Redump external calls
- Make anti-modchip scans even safer
- Remove lower bound checking on LBA values for DIC
- Remove offset for audio discs on DIC output
- Start adding regression tests for DIC
- Ensure parameters box is safer during options save
- Fix protection sanitization and add regression tests
- Update to DIC 20211101
- Add protection sanitization for StarForce
- Trim filenames for DVD protection from DIC
- Fill out internal tests around Redump library
- Refine the "missing disc" text
- Overhaul XeMID handling
- Fix output dialog issues in Options window
- Fix saving path settings if set from dialog
- Allow default system if skipping system detection enabled
- Add internal support for all Redump site codes
- Use the Volume Label special site code
- Capture newlines in Redump fields
- Invert condition for volume label
- Fix missing ISN usages
- Fix ISN string
- Validate track count when matching Redump
- Allow for better matching of multi track discs
- Temporarily disable pulling comments from Redump pages
- Add safety around volume labels
### 2.1 (2021-07-22)
- Enum, no more
- Sony works backward
- Add experimental dark mode
- Allow users to customize protection scanning
- Fix negative offsets for `/a` flag
- Always check for all DIC log files, just in case
- Check for the zipped logs for dealing with overwrites
- Be smarter about checking for zipped logs
- Change offset value for HVN discs
- Update to DIC 20210601
- Fix Aaru command normalization
- Handle carriage returns better
- Add logging helper class
- Set matcher on carriage return for log formatting
- Replace dumping program output processing
- Fix volume name detection for XBOX discs
- Add new setting for including artifacts in serialzied JSON
- Fix logging in to Redump for verifications
- Gracefully handle timeouts during login
- Update to DIC 20210701
- Support `/mr` value parameter
- Support new mainInfo header
- Add BD to IBM-PC supported discs
- Fix launching MPF on Windows 7
- Fix log window background turning white
- Add DMI/PFI/SS to log zipfile
- Update to BurnOutSharp 1.7.0
### 2.0 (2021-04-23)
- Rename DICUI to Media Preservation Frontend (MPF)
- Add handling for BEh drive _mainInfo.txt changes
- Fix multiline regex fields during info pulling
- Add preliminary support for user-defined default system
- Change labels in media info window depending on media type
- Update to Aaru v5.2
- Only pull disc information if every track returns at least one ID
- Add new supported Redump regions
- Remove Philips CD-i Digital Video from supported profiles
- Remove experimental Avalonia UI, will wait for MAUI next year
- ~~Updated to DIC version 20210102~~
- Add support for `/mr` DIC flag
- UI initialization code refactored to have more consistent results
- Support DIC `.imgtmp`, `.scmtmp`, and `.subtmp` possible output files
- Fix BCA formatting for CleanRip outputs
- Add hashing for UMDs from UIC outputs
- Fix information gathering for UIC outputs
- Fix issue with duplicate security sector data in XGD DiscImageCreator outputs
- ~~Update to BurnOutSharp 1.5.1~~
- ~~Update to DIC version 20210202~~
- Add VCD detection
- Fix UI not updating properly on drive change
- Add Xbox Series and PS5 to supported systems
- Add PS5 type detection and version extraction
- Add internal support for 3- and 4-layer discs
- Revamp disc information window
- Add PIC layerbreak extraction
- Overhaul main window and logging panel
- Overhaul options window
- Update attributions and about text
- ~~Updated to DIC version 20210301~~
- Add user-selectable Language Selection via dropdown in disc submission window for PS2
- Separate out Aaru- and DIC-specific settings
- Add new options based on original "Paranoid Mode" mega-option
- Internal overhaul of options and dump environment
- VideoNow discs are audio only
- Hook up default system in options
- Make inner and outer layers in UI and outputs more clear
- Program output to log by default, setting otherwise
- DVDs and BDs can have label-side data
- Remove .NET Framework 4.7.2 support
- Make logging window a bit safer
- Support new Redump languages and regions
- Implement internal log queue
- It's a secret...
- Updated to DIC version 20210401
- Support log file compression
- Add ring code guide button to disc submission window
- ~~Update to BurnOutSharp 1.6.0~~
- Fix "rewinding" issue when inputting output paths with spaces
- Add version to About box
- Update to BurnOutSharp 1.6.1
### 1.18 (2020-11-10)
- Add more information extraction and generation for Aaru
- Remove instances of CD Check from copy protection (again, sorry)
- Fix multiline submission info outputs
- Fix PVD retrieval for multi-session discs
- Updated to DIC version 20200921
- Add and fix multiple Sega disc header pieces or submission info
- Fixed issues in parsing the alternate mainInfo format
- Fixed issue with logging clear not working properly
- ~~Updated to BurnOutSharp 1.4.1~~
- Added split archives for AppVeyor builds
- Remove subdump from both UI and run steps
- Removed default config file
- Fixed copy protect scan using wrong drive when using UI option
- Changed default to skip fixed drives
- Fixed default media type when skipping type detection
- Attempt sector reading for Saturn system detection
- Fixed default media type when detection fails
- Add option to allow users to select dumping program
- ~~Updated to DIC version 20201101~~
- Add support for `/ps` DIC flag
- Updated to BurnOutSharp 1.5.0
- Added HD-DVD-Video detection
### 1.17.1 (2020-09-14)
- Shuffled some shared, internal UI variables
- Synced WPF and Avalonia UI internals
- Made the disc information window less prone to bugs
- Fixed DIC flags based on code (not documentation)
- Added support for old(?) DIC flags: `/fix` and `/re`
### 1.17 (2020-09-12)
- Updated to Aaru version 5.1
- Updated to BurnOutSharp version 1.4.0
- Updated to DIC version 20200716
- Added experimental Avalonia UI
- Created wiki
- Removed .NET 4.6.2 and .NET Core 3.0 builds
- Added .NET 4.8 and .NET Core 3.1 builds
- Fix numerous things related to PS1/PS2
- Make subdump running optional
- Overhaul DICUI.Check with more options
- Numerous small bug- and regression-fixes
### 1.16.1 (2020-05-07)
- Add preliminary support for DD for Windows (end to end still NW)
- Add CNF parsing for Konami Python 2 discs (PS2-based)
- Updated included Aaru version
- Massive cleanup effort to detangle large chunks of code
- Miscellaneous bugfixes that came from the above
### 1.16 (2020-04-13)
- Updated to DIC version 20200403
- UI updates based on user feedback
- Added support for Aaru (formerly DiscImageChef)
- Added more support for different output file formats (such as CleanRip)
- Add PS1/PS2 serial extraction and matching
- Fix PS1 date support when both PSX.EXE and normal executable are both present
- Update BurnOutSharp
- Many MANY bits of internal cleanup
### 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

1
CICMMetadata Submodule

Submodule CICMMetadata added at 7944bca8e6

View File

@@ -1,59 +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>{8CFDE289-E171-4D49-A40D-5293265C1253}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>DICUI.Check</RootNamespace>
<AssemblyName>DICUI.Check</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</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>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<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>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -1,163 +0,0 @@
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;
}
// Make a new Progress object
var progress = new Progress<Result>();
progress.ProgressChanged += ProgressUpdated;
// Loop through all the rest of the args
for (int i = 2; i < args.Length; i++)
{
// Check for a file
if (!File.Exists(args[i]))
{
DisplayHelp($"{args[i]} does not exist");
return;
}
// Now populate an environment
var env = new DumpEnvironment
{
OutputDirectory = "",
OutputFilename = args[i],
System = knownSystem,
Type = mediaType,
ScanForProtection = false,
};
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> </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).Name()}");
}
}
/// <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).Name()}");
}
}
/// <summary>
/// Simple process counter to write to console
/// </summary>
private static void ProgressUpdated(object sender, Result value)
{
Console.WriteLine(value.Message);
}
}
}

View File

@@ -1,36 +0,0 @@
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

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

View File

@@ -1,56 +0,0 @@
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.NintendoGameCube:
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());
}
}

View File

@@ -1,117 +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>{A6719A99-BF0E-4637-9A8E-CB38B1E16971}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>DICUI.Forms</RootNamespace>
<AssemblyName>DICUI.Forms</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</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>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing.Design" />
<Reference Include="System.Windows" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="Constants.cs" />
<Compile Include="EnumDescriptionConverter.cs" />
<Compile Include="KnownSystemComboBoxItem.cs" />
<Compile Include="MediaTypeComboBoxItem.cs" />
<Compile Include="Options.cs" />
<Compile Include="Properties\Settings1.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings1.settings</DependentUpon>
</Compile>
<Compile Include="ViewModels.cs" />
<Compile Include="Windows\LogWindow.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Windows\LogWindow.Designer.cs">
<DependentUpon>LogWindow.cs</DependentUpon>
</Compile>
<Compile Include="Windows\MainWindow.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Windows\MainWindow.Designer.cs">
<DependentUpon>MainWindow.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Windows\OptionsWindow.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Windows\OptionsWindow.Designer.cs">
<DependentUpon>OptionsWindow.cs</DependentUpon>
</Compile>
<EmbeddedResource Include="Windows\LogWindow.resx">
<DependentUpon>LogWindow.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Windows\MainWindow.resx">
<DependentUpon>MainWindow.cs</DependentUpon>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Windows\OptionsWindow.resx">
<DependentUpon>OptionsWindow.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="Properties\Settings1.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings1.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<Resource Include="Icon.ico" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DICUI.Library\DICUI.Library.csproj">
<Project>{51ab0928-13f9-44bf-a407-b6957a43a056}</Project>
<Name>DICUI.Library</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

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

View File

@@ -1,34 +0,0 @@
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; } // TODO: Re-enable this
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?).Name() + " ----------";
else
return (data as KnownSystem?).Name();
}
}
}
}

View File

@@ -1,20 +0,0 @@
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI.Forms
{
/// <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.Name(); }
}
}
}

View File

@@ -1,97 +0,0 @@
using System;
using System.Configuration;
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 SkipMediaTypeDetection { get; set; }
public bool VerboseLogging { get; set; }
public bool OpenLogWindowAtStartup { 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()
{
//TODO: hardcoded, we should find a better way
DICPath = ConfigurationManager.AppSettings["DICPath"] ?? @"Programs\DiscImageCreator.exe";
SubDumpPath = ConfigurationManager.AppSettings["SubDumpPath"] ?? "subdump.exe";
DefaultOutputPath = ConfigurationManager.AppSettings["DefaultOutputPath"] ?? "ISO";
this.PreferredDumpSpeedCD = Int32.TryParse(ConfigurationManager.AppSettings["preferredDumpSpeedCD"], out int maxDumpSpeedCD) ? maxDumpSpeedCD : 72;
this.PreferredDumpSpeedDVD = Int32.TryParse(ConfigurationManager.AppSettings["preferredDumpSpeedDVD"], out int maxDumpSpeedDVD) ? maxDumpSpeedDVD : 24;
this.PreferredDumpSpeedBD = Int32.TryParse(ConfigurationManager.AppSettings["preferredDumpSpeedBD"], out int maxDumpSpeedBD) ? maxDumpSpeedBD : 16;
this.QuietMode = Boolean.TryParse(ConfigurationManager.AppSettings["QuietMode"], out bool quietMode) ? quietMode : false;
this.ParanoidMode = Boolean.TryParse(ConfigurationManager.AppSettings["ParanoidMode"], out bool paranoidMode) ? paranoidMode : false;
this.ScanForProtection = Boolean.TryParse(ConfigurationManager.AppSettings["ScanForProtection"], out bool scanForProtection) ? scanForProtection : true;
this.SkipMediaTypeDetection = Boolean.TryParse(ConfigurationManager.AppSettings["SkipMediaTypeDetection"], out bool skipMediaTypeDetection) ? skipMediaTypeDetection : false;
this.RereadAmountForC2 = Int32.TryParse(ConfigurationManager.AppSettings["RereadAmountForC2"], out int rereadAmountForC2) ? rereadAmountForC2 : 20;
this.VerboseLogging = Boolean.TryParse(ConfigurationManager.AppSettings["VerboseLogging"], out bool verboseLogging) ? verboseLogging : true;
this.OpenLogWindowAtStartup = Boolean.TryParse(ConfigurationManager.AppSettings["OpenLogWindowAtStartup"], out bool openLogWindowAtStartup) ? openLogWindowAtStartup : true;
}
//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.NintendoGameCube:
case MediaType.NintendoWiiOpticalDisc:
return PreferredDumpSpeedDVD;
case MediaType.BluRay:
return PreferredDumpSpeedBD;
default:
return 8;
}
}
}
}

View File

@@ -1,20 +0,0 @@
using System;
using System.Windows.Forms;
using DICUI.Forms.Windows;
namespace DICUI.Forms
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainWindow());
}
}
}

View File

@@ -1,36 +0,0 @@
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.Forms")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DICUI.Forms")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[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("a6719a99-bf0e-4637-9a8e-cb38b1e16971")]
// 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.11")]
[assembly: AssemblyFileVersion("1.11.0.0")]

View File

@@ -1,26 +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.Forms.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.8.0.0")]
internal sealed partial class Settings1 : global::System.Configuration.ApplicationSettingsBase {
private static Settings1 defaultInstance = ((Settings1)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings1())));
public static Settings1 Default {
get {
return defaultInstance;
}
}
}
}

View File

@@ -1,6 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
</SettingsFile>

View File

@@ -1,106 +0,0 @@
using System;
using DICUI.Forms.Windows;
namespace DICUI.Forms
{
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 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.Visible : false;
set
{
if (value)
{
_logWindow.AdjustPositionToMainWindow();
_logWindow.Show();
}
else
_logWindow.Hide();
}
}
public void VerboseLog(string text)
{
if (ViewModels.OptionsViewModel.VerboseLogging)
_logWindow.AppendToTextBox(text, System.Drawing.Color.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

@@ -1,175 +0,0 @@
namespace DICUI.Forms.Windows
{
partial class LogWindow
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.progressBar = new System.Windows.Forms.ProgressBar();
this.output = new System.Windows.Forms.RichTextBox();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.Verbose = new System.Windows.Forms.CheckBox();
this.OpenAtStartupCheckBox = new System.Windows.Forms.CheckBox();
this.ClearButton = new System.Windows.Forms.Button();
this.HideButton = new System.Windows.Forms.Button();
this.tableLayoutPanel1.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.SuspendLayout();
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 1;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.Controls.Add(this.progressBar, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.output, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 0, 2);
this.tableLayoutPanel1.Location = new System.Drawing.Point(12, 12);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 3;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 40F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 40F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(560, 287);
this.tableLayoutPanel1.TabIndex = 0;
//
// progressBar
//
this.progressBar.Dock = System.Windows.Forms.DockStyle.Fill;
this.progressBar.Location = new System.Drawing.Point(3, 3);
this.progressBar.Name = "progressBar";
this.progressBar.Size = new System.Drawing.Size(554, 34);
this.progressBar.TabIndex = 0;
//
// output
//
this.output.BackColor = System.Drawing.Color.DimGray;
this.output.Dock = System.Windows.Forms.DockStyle.Fill;
this.output.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.output.Location = new System.Drawing.Point(3, 43);
this.output.Name = "output";
this.output.ReadOnly = true;
this.output.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical;
this.output.Size = new System.Drawing.Size(554, 201);
this.output.TabIndex = 1;
this.output.Text = "";
this.output.TextChanged += new System.EventHandler(this.OnTextChanged);
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 5;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 15F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 20F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 35F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 15F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 15F));
this.tableLayoutPanel2.Controls.Add(this.Verbose, 0, 0);
this.tableLayoutPanel2.Controls.Add(this.OpenAtStartupCheckBox, 1, 0);
this.tableLayoutPanel2.Controls.Add(this.ClearButton, 3, 0);
this.tableLayoutPanel2.Controls.Add(this.HideButton, 4, 0);
this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 250);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 1;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(554, 34);
this.tableLayoutPanel2.TabIndex = 2;
//
// Verbose
//
this.Verbose.AutoSize = true;
this.Verbose.Dock = System.Windows.Forms.DockStyle.Left;
this.Verbose.Location = new System.Drawing.Point(3, 3);
this.Verbose.Name = "Verbose";
this.Verbose.Size = new System.Drawing.Size(65, 28);
this.Verbose.TabIndex = 1;
this.Verbose.Text = "Verbose";
this.Verbose.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.Verbose.UseVisualStyleBackColor = true;
//
// OpenAtStartupCheckBox
//
this.OpenAtStartupCheckBox.AutoSize = true;
this.OpenAtStartupCheckBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.OpenAtStartupCheckBox.Location = new System.Drawing.Point(86, 3);
this.OpenAtStartupCheckBox.Name = "OpenAtStartupCheckBox";
this.OpenAtStartupCheckBox.Size = new System.Drawing.Size(104, 28);
this.OpenAtStartupCheckBox.TabIndex = 2;
this.OpenAtStartupCheckBox.Text = "Open at startup";
this.OpenAtStartupCheckBox.UseVisualStyleBackColor = true;
//
// ClearButton
//
this.ClearButton.Dock = System.Windows.Forms.DockStyle.Fill;
this.ClearButton.Location = new System.Drawing.Point(389, 3);
this.ClearButton.Name = "ClearButton";
this.ClearButton.Size = new System.Drawing.Size(77, 28);
this.ClearButton.TabIndex = 3;
this.ClearButton.Text = "Clear";
this.ClearButton.UseVisualStyleBackColor = true;
this.ClearButton.Click += new System.EventHandler(this.OnClearButton);
//
// HideButton
//
this.HideButton.Dock = System.Windows.Forms.DockStyle.Fill;
this.HideButton.Location = new System.Drawing.Point(472, 3);
this.HideButton.Name = "HideButton";
this.HideButton.Size = new System.Drawing.Size(79, 28);
this.HideButton.TabIndex = 4;
this.HideButton.Text = "Hide";
this.HideButton.UseVisualStyleBackColor = true;
this.HideButton.SizeChanged += new System.EventHandler(this.ScrollViewer_SizeChanged);
this.HideButton.Click += new System.EventHandler(this.OnHideButton);
//
// LogWindow
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(584, 311);
this.Controls.Add(this.tableLayoutPanel1);
this.Name = "LogWindow";
this.ShowIcon = false;
this.Text = "Log Window";
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OnWindowClosed);
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel2.ResumeLayout(false);
this.tableLayoutPanel2.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.ProgressBar progressBar;
private System.Windows.Forms.RichTextBox output;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.CheckBox Verbose;
private System.Windows.Forms.CheckBox OpenAtStartupCheckBox;
private System.Windows.Forms.Button ClearButton;
private System.Windows.Forms.Button HideButton;
}
}

View File

@@ -1,380 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Threading;
namespace DICUI.Forms.Windows
{
public partial class LogWindow : Form
{
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 List<Matcher> _matchers;
volatile Process _process;
public LogWindow(MainWindow mainWindow)
{
InitializeComponent();
this._mainWindow = mainWindow;
_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 = (int)percentProgress;
//progressBar.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 = (int)percentProgress;
//progressBar.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 = (int)percentProgress;
//progressBar.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 = (int)percentProgress;
//progressBar.Text = string.Format("Scanning sectors for protection.. ({0:##.##}%)", percentProgress);
}
}));
}
protected override bool ShowWithoutActivation
{
get { return true; }
}
public void StartDump(string args)
{
AppendToTextBox(string.Format("Launching DIC with args: {0}\r\n", args), System.Drawing.Color.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.CurrentDispatcher.Invoke(() => UpdateConsole(text.Data, Brushes.Red));
_process.Start();
var _1 = ConsumeOutput(_process.StandardOutput, s => Dispatcher.CurrentDispatcher.Invoke(() => UpdateConsole(s, stdoutState)));
var _2 = ConsumeOutput(_process.StandardError, s => Dispatcher.CurrentDispatcher.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;
this.BringToFront();
}
private void GracefullyTerminateProcess()
{
if (_process != null)
{
_process.Exited -= OnProcessExit;
bool isForced = !_process.HasExited;
if (isForced)
{
AppendToTextBox("\r\nForcefully Killing the process\r\n", System.Drawing.Color.Red);
_process.Kill();
_process.WaitForExit();
}
AppendToTextBox(string.Format("\r\nExit Code: {0}\r\n", _process.ExitCode), _process.ExitCode == 0 ? System.Drawing.Color.Green : System.Drawing.Color.Red);
if (_process.ExitCode == 0)
{
Dispatcher.CurrentDispatcher.Invoke(() =>
{
//progressBar.Text = "Done!";
progressBar.Value = 100;
progressBar.ForeColor = System.Drawing.Color.Green;
});
}
else
{
Dispatcher.CurrentDispatcher.Invoke(() =>
{
//progressBar.Text = isForced ? "Aborted by user" : "Error, please check log!";
progressBar.Value = 100;
progressBar.ForeColor = System.Drawing.Color.Red;
});
}
_process.Close();
}
_process = null;
}
private void ScrollViewer_SizeChanged(object sender, EventArgs e)
{
output.ScrollToCaret();
}
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, System.Drawing.Color color)
{
if (Dispatcher.CurrentDispatcher.CheckAccess())
{
output.ForeColor = color;
output.AppendText(text);
}
else
Dispatcher.CurrentDispatcher.Invoke(() =>
{
output.ForeColor = color;
output.AppendText(text);
});
}
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 ? System.Drawing.Color.Red : System.Drawing.Color.White);
if (!state.isError)
ProcessStringForProgressBar(buffer);
}
output.AppendText(Environment.NewLine);
state.Clear();
state.Set(StreamState.State.BEGIN);
break;
}
default:
if (state.Is(StreamState.State.READ_CARRIAGE) && state.HasData())
{
if (!String.IsNullOrEmpty(output.Lines.Last()))
output.Lines[output.Lines.Length] = string.Empty;
string buffer = state.Fetch();
AppendToTextBox(buffer, state.isError ? System.Drawing.Color.Red : System.Drawing.Color.White);
if (!state.isError)
ProcessStringForProgressBar(buffer);
state.Clear();
}
state.Set(StreamState.State.BEGIN);
state.Append(c);
break;
}
}
}
}
#region EventHandlers
private void OnWindowClosed(object sender, FormClosedEventArgs e)
{
GracefullyTerminateProcess();
}
private void OnWindowLoaded(object sender, EventArgs e)
{
var hwnd = this.Handle;
SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SYSMENU);
}
void OnProcessExit(object sender, EventArgs e)
{
//Dispatcher.CurrentDispatcher.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.showLogWindowToolStripMenuItem.Checked = false;
}
private void OnClearButton(object sender, EventArgs e)
{
output.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, EventArgs e)
{
output.ScrollToCaret();
}
#endregion
}
}

View File

@@ -1,123 +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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="$this.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

@@ -1,532 +0,0 @@
namespace DICUI.Forms.Windows
{
partial class MainWindow
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainWindow));
this.MenuBar = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mainWindowLayout = new System.Windows.Forms.TableLayoutPanel();
this.settingsGroupBox = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.parametersLabel = new System.Windows.Forms.Label();
this.driveSpeedLabel = new System.Windows.Forms.Label();
this.driveLetterLabel = new System.Windows.Forms.Label();
this.outputDirectoryLabel = new System.Windows.Forms.Label();
this.outputFilenameLabel = new System.Windows.Forms.Label();
this.systemMediaTypeLabel = new System.Windows.Forms.Label();
this.OutputFilenameTextBox = new System.Windows.Forms.TextBox();
this.SystemTypeComboBox = new System.Windows.Forms.ComboBox();
this.MediaTypeComboBox = new System.Windows.Forms.ComboBox();
this.OutputDirectoryTextBox = new System.Windows.Forms.TextBox();
this.OutputDirectoryBrowseButton = new System.Windows.Forms.Button();
this.DriveLetterComboBox = new System.Windows.Forms.ComboBox();
this.DriveSpeedComboBox = new System.Windows.Forms.ComboBox();
this.ParametersTextBox = new System.Windows.Forms.TextBox();
this.EnableParametersCheckBox = new System.Windows.Forms.CheckBox();
this.controlsGroupBox = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.StartStopButton = new System.Windows.Forms.Button();
this.DiscScanButton = new System.Windows.Forms.Button();
this.CopyProtectScanButton = new System.Windows.Forms.Button();
this.EjectWhenDoneCheckBox = new System.Windows.Forms.CheckBox();
this.statusGroupBox = new System.Windows.Forms.GroupBox();
this.StatusLabel = new System.Windows.Forms.TextBox();
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.showLogWindowToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.MenuBar.SuspendLayout();
this.mainWindowLayout.SuspendLayout();
this.settingsGroupBox.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.controlsGroupBox.SuspendLayout();
this.tableLayoutPanel3.SuspendLayout();
this.statusGroupBox.SuspendLayout();
this.SuspendLayout();
//
// MenuBar
//
this.MenuBar.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.toolsToolStripMenuItem,
this.helpToolStripMenuItem});
this.MenuBar.Location = new System.Drawing.Point(0, 0);
this.MenuBar.Name = "MenuBar";
this.MenuBar.Size = new System.Drawing.Size(584, 24);
this.MenuBar.TabIndex = 0;
this.MenuBar.Text = "menuStrip1";
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.F)));
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "File";
//
// toolsToolStripMenuItem
//
this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem";
this.toolsToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.T)));
this.toolsToolStripMenuItem.Size = new System.Drawing.Size(47, 20);
this.toolsToolStripMenuItem.Text = "Tools";
//
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
this.helpToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.H)));
this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.helpToolStripMenuItem.Text = "Help";
//
// mainWindowLayout
//
this.mainWindowLayout.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.mainWindowLayout.ColumnCount = 1;
this.mainWindowLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.mainWindowLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.mainWindowLayout.Controls.Add(this.settingsGroupBox, 0, 0);
this.mainWindowLayout.Controls.Add(this.controlsGroupBox, 0, 1);
this.mainWindowLayout.Controls.Add(this.statusGroupBox, 0, 2);
this.mainWindowLayout.Location = new System.Drawing.Point(13, 28);
this.mainWindowLayout.Name = "mainWindowLayout";
this.mainWindowLayout.RowCount = 3;
this.mainWindowLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 82.66254F));
this.mainWindowLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 17.33746F));
this.mainWindowLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 47F));
this.mainWindowLayout.Size = new System.Drawing.Size(559, 371);
this.mainWindowLayout.TabIndex = 1;
//
// settingsGroupBox
//
this.settingsGroupBox.Controls.Add(this.tableLayoutPanel2);
this.settingsGroupBox.Location = new System.Drawing.Point(3, 3);
this.settingsGroupBox.Name = "settingsGroupBox";
this.settingsGroupBox.Size = new System.Drawing.Size(553, 259);
this.settingsGroupBox.TabIndex = 0;
this.settingsGroupBox.TabStop = false;
this.settingsGroupBox.Text = "Settings";
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 3;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 26.32794F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 73.67206F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 145F));
this.tableLayoutPanel2.Controls.Add(this.parametersLabel, 0, 5);
this.tableLayoutPanel2.Controls.Add(this.driveSpeedLabel, 0, 4);
this.tableLayoutPanel2.Controls.Add(this.driveLetterLabel, 0, 3);
this.tableLayoutPanel2.Controls.Add(this.outputDirectoryLabel, 0, 2);
this.tableLayoutPanel2.Controls.Add(this.outputFilenameLabel, 0, 1);
this.tableLayoutPanel2.Controls.Add(this.systemMediaTypeLabel, 0, 0);
this.tableLayoutPanel2.Controls.Add(this.OutputFilenameTextBox, 1, 1);
this.tableLayoutPanel2.Controls.Add(this.SystemTypeComboBox, 1, 0);
this.tableLayoutPanel2.Controls.Add(this.MediaTypeComboBox, 2, 0);
this.tableLayoutPanel2.Controls.Add(this.OutputDirectoryTextBox, 1, 2);
this.tableLayoutPanel2.Controls.Add(this.OutputDirectoryBrowseButton, 2, 2);
this.tableLayoutPanel2.Controls.Add(this.DriveLetterComboBox, 1, 3);
this.tableLayoutPanel2.Controls.Add(this.DriveSpeedComboBox, 1, 4);
this.tableLayoutPanel2.Controls.Add(this.ParametersTextBox, 1, 5);
this.tableLayoutPanel2.Controls.Add(this.EnableParametersCheckBox, 2, 5);
this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 19);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.Padding = new System.Windows.Forms.Padding(0, 5, 0, 5);
this.tableLayoutPanel2.RowCount = 6;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 16.66667F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(553, 234);
this.tableLayoutPanel2.TabIndex = 0;
//
// parametersLabel
//
this.parametersLabel.AutoSize = true;
this.parametersLabel.Dock = System.Windows.Forms.DockStyle.Fill;
this.parametersLabel.Location = new System.Drawing.Point(3, 190);
this.parametersLabel.Name = "parametersLabel";
this.parametersLabel.Size = new System.Drawing.Size(101, 39);
this.parametersLabel.TabIndex = 10;
this.parametersLabel.Text = "Parameters";
this.parametersLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// driveSpeedLabel
//
this.driveSpeedLabel.AutoSize = true;
this.driveSpeedLabel.Dock = System.Windows.Forms.DockStyle.Fill;
this.driveSpeedLabel.Location = new System.Drawing.Point(3, 153);
this.driveSpeedLabel.Name = "driveSpeedLabel";
this.driveSpeedLabel.Size = new System.Drawing.Size(101, 37);
this.driveSpeedLabel.TabIndex = 8;
this.driveSpeedLabel.Text = "Drive Speed";
this.driveSpeedLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// driveLetterLabel
//
this.driveLetterLabel.AutoSize = true;
this.driveLetterLabel.Dock = System.Windows.Forms.DockStyle.Fill;
this.driveLetterLabel.Location = new System.Drawing.Point(3, 116);
this.driveLetterLabel.Name = "driveLetterLabel";
this.driveLetterLabel.Size = new System.Drawing.Size(101, 37);
this.driveLetterLabel.TabIndex = 6;
this.driveLetterLabel.Text = "Drive Letter";
this.driveLetterLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// outputDirectoryLabel
//
this.outputDirectoryLabel.AutoSize = true;
this.outputDirectoryLabel.Dock = System.Windows.Forms.DockStyle.Fill;
this.outputDirectoryLabel.Location = new System.Drawing.Point(3, 79);
this.outputDirectoryLabel.Name = "outputDirectoryLabel";
this.outputDirectoryLabel.Size = new System.Drawing.Size(101, 37);
this.outputDirectoryLabel.TabIndex = 4;
this.outputDirectoryLabel.Text = "Output Directory";
this.outputDirectoryLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// outputFilenameLabel
//
this.outputFilenameLabel.AutoSize = true;
this.outputFilenameLabel.Dock = System.Windows.Forms.DockStyle.Fill;
this.outputFilenameLabel.Location = new System.Drawing.Point(3, 42);
this.outputFilenameLabel.Name = "outputFilenameLabel";
this.outputFilenameLabel.Size = new System.Drawing.Size(101, 37);
this.outputFilenameLabel.TabIndex = 2;
this.outputFilenameLabel.Text = "Output Filename";
this.outputFilenameLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// systemMediaTypeLabel
//
this.systemMediaTypeLabel.AutoSize = true;
this.systemMediaTypeLabel.Dock = System.Windows.Forms.DockStyle.Fill;
this.systemMediaTypeLabel.Location = new System.Drawing.Point(3, 5);
this.systemMediaTypeLabel.Name = "systemMediaTypeLabel";
this.systemMediaTypeLabel.Size = new System.Drawing.Size(101, 37);
this.systemMediaTypeLabel.TabIndex = 0;
this.systemMediaTypeLabel.Text = "System/Media Type";
this.systemMediaTypeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// OutputFilenameTextBox
//
this.OutputFilenameTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
this.tableLayoutPanel2.SetColumnSpan(this.OutputFilenameTextBox, 2);
this.OutputFilenameTextBox.Location = new System.Drawing.Point(111, 50);
this.OutputFilenameTextBox.Name = "OutputFilenameTextBox";
this.OutputFilenameTextBox.Size = new System.Drawing.Size(438, 20);
this.OutputFilenameTextBox.TabIndex = 11;
this.OutputFilenameTextBox.TextChanged += new System.EventHandler(this.OutputFilenameTextBoxTextChanged);
//
// SystemTypeComboBox
//
this.SystemTypeComboBox.Anchor = System.Windows.Forms.AnchorStyles.None;
this.SystemTypeComboBox.DisplayMember = "Name";
this.SystemTypeComboBox.DropDownWidth = 250;
this.SystemTypeComboBox.FormattingEnabled = true;
this.SystemTypeComboBox.Location = new System.Drawing.Point(110, 13);
this.SystemTypeComboBox.Name = "SystemTypeComboBox";
this.SystemTypeComboBox.Size = new System.Drawing.Size(294, 21);
this.SystemTypeComboBox.TabIndex = 13;
this.SystemTypeComboBox.SelectedIndexChanged += new System.EventHandler(this.SystemTypeComboBoxSelectionChanged);
//
// MediaTypeComboBox
//
this.MediaTypeComboBox.Anchor = System.Windows.Forms.AnchorStyles.None;
this.MediaTypeComboBox.DisplayMember = "Name";
this.MediaTypeComboBox.FormattingEnabled = true;
this.MediaTypeComboBox.Location = new System.Drawing.Point(414, 13);
this.MediaTypeComboBox.Name = "MediaTypeComboBox";
this.MediaTypeComboBox.Size = new System.Drawing.Size(131, 21);
this.MediaTypeComboBox.TabIndex = 14;
this.MediaTypeComboBox.SelectedIndexChanged += new System.EventHandler(this.MediaTypeComboBoxSelectionChanged);
//
// OutputDirectoryTextBox
//
this.OutputDirectoryTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
this.OutputDirectoryTextBox.Location = new System.Drawing.Point(110, 87);
this.OutputDirectoryTextBox.Name = "OutputDirectoryTextBox";
this.OutputDirectoryTextBox.Size = new System.Drawing.Size(294, 20);
this.OutputDirectoryTextBox.TabIndex = 15;
this.OutputDirectoryTextBox.TextChanged += new System.EventHandler(this.OutputDirectoryTextBoxTextChanged);
//
// OutputDirectoryBrowseButton
//
this.OutputDirectoryBrowseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
this.OutputDirectoryBrowseButton.Location = new System.Drawing.Point(410, 84);
this.OutputDirectoryBrowseButton.Name = "OutputDirectoryBrowseButton";
this.OutputDirectoryBrowseButton.Size = new System.Drawing.Size(140, 26);
this.OutputDirectoryBrowseButton.TabIndex = 16;
this.OutputDirectoryBrowseButton.Text = "Browse";
this.OutputDirectoryBrowseButton.UseVisualStyleBackColor = true;
this.OutputDirectoryBrowseButton.Click += new System.EventHandler(this.OutputDirectoryBrowseButtonClick);
//
// DriveLetterComboBox
//
this.DriveLetterComboBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.DriveLetterComboBox.DisplayMember = "Letter";
this.DriveLetterComboBox.FormattingEnabled = true;
this.DriveLetterComboBox.Location = new System.Drawing.Point(110, 124);
this.DriveLetterComboBox.Name = "DriveLetterComboBox";
this.DriveLetterComboBox.Size = new System.Drawing.Size(121, 21);
this.DriveLetterComboBox.TabIndex = 17;
this.DriveLetterComboBox.SelectedIndexChanged += new System.EventHandler(this.DriveLetterComboBoxSelectionChanged);
//
// DriveSpeedComboBox
//
this.DriveSpeedComboBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.DriveSpeedComboBox.FormattingEnabled = true;
this.DriveSpeedComboBox.Location = new System.Drawing.Point(110, 161);
this.DriveSpeedComboBox.Name = "DriveSpeedComboBox";
this.DriveSpeedComboBox.Size = new System.Drawing.Size(121, 21);
this.DriveSpeedComboBox.TabIndex = 18;
this.DriveSpeedComboBox.SelectedIndexChanged += new System.EventHandler(this.DriveSpeedComboBoxSelectionChanged);
//
// ParametersTextBox
//
this.ParametersTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
this.ParametersTextBox.Enabled = false;
this.ParametersTextBox.Location = new System.Drawing.Point(110, 199);
this.ParametersTextBox.Name = "ParametersTextBox";
this.ParametersTextBox.ReadOnly = true;
this.ParametersTextBox.Size = new System.Drawing.Size(294, 20);
this.ParametersTextBox.TabIndex = 19;
//
// EnableParametersCheckBox
//
this.EnableParametersCheckBox.AutoSize = true;
this.EnableParametersCheckBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.EnableParametersCheckBox.Location = new System.Drawing.Point(410, 193);
this.EnableParametersCheckBox.Name = "EnableParametersCheckBox";
this.EnableParametersCheckBox.Size = new System.Drawing.Size(140, 33);
this.EnableParametersCheckBox.TabIndex = 20;
this.EnableParametersCheckBox.Text = "Enable Editing";
this.EnableParametersCheckBox.UseVisualStyleBackColor = true;
this.EnableParametersCheckBox.CheckedChanged += new System.EventHandler(this.EnableParametersCheckBoxClick);
//
// controlsGroupBox
//
this.controlsGroupBox.Controls.Add(this.tableLayoutPanel3);
this.controlsGroupBox.Location = new System.Drawing.Point(3, 270);
this.controlsGroupBox.Name = "controlsGroupBox";
this.controlsGroupBox.Size = new System.Drawing.Size(553, 50);
this.controlsGroupBox.TabIndex = 1;
this.controlsGroupBox.TabStop = false;
this.controlsGroupBox.Text = "Controls";
//
// tableLayoutPanel3
//
this.tableLayoutPanel3.ColumnCount = 4;
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tableLayoutPanel3.Controls.Add(this.StartStopButton, 0, 0);
this.tableLayoutPanel3.Controls.Add(this.DiscScanButton, 1, 0);
this.tableLayoutPanel3.Controls.Add(this.CopyProtectScanButton, 2, 0);
this.tableLayoutPanel3.Controls.Add(this.EjectWhenDoneCheckBox, 3, 0);
this.tableLayoutPanel3.Location = new System.Drawing.Point(0, 20);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowCount = 1;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel3.Size = new System.Drawing.Size(553, 32);
this.tableLayoutPanel3.TabIndex = 0;
//
// StartStopButton
//
this.StartStopButton.Dock = System.Windows.Forms.DockStyle.Fill;
this.StartStopButton.Enabled = false;
this.StartStopButton.Location = new System.Drawing.Point(3, 3);
this.StartStopButton.Name = "StartStopButton";
this.StartStopButton.Size = new System.Drawing.Size(132, 26);
this.StartStopButton.TabIndex = 0;
this.StartStopButton.Text = "Start Dumping";
this.StartStopButton.UseVisualStyleBackColor = true;
this.StartStopButton.Click += new System.EventHandler(this.StartStopButtonClick);
//
// DiscScanButton
//
this.DiscScanButton.Dock = System.Windows.Forms.DockStyle.Fill;
this.DiscScanButton.Location = new System.Drawing.Point(141, 3);
this.DiscScanButton.Name = "DiscScanButton";
this.DiscScanButton.Size = new System.Drawing.Size(132, 26);
this.DiscScanButton.TabIndex = 1;
this.DiscScanButton.Text = "Scan For Discs";
this.DiscScanButton.UseVisualStyleBackColor = true;
this.DiscScanButton.Click += new System.EventHandler(this.DiscScanButtonClick);
//
// CopyProtectScanButton
//
this.CopyProtectScanButton.Dock = System.Windows.Forms.DockStyle.Fill;
this.CopyProtectScanButton.Location = new System.Drawing.Point(279, 3);
this.CopyProtectScanButton.Name = "CopyProtectScanButton";
this.CopyProtectScanButton.Size = new System.Drawing.Size(132, 26);
this.CopyProtectScanButton.TabIndex = 2;
this.CopyProtectScanButton.Text = "Scan For Protection";
this.CopyProtectScanButton.UseVisualStyleBackColor = true;
this.CopyProtectScanButton.Click += new System.EventHandler(this.CopyProtectScanButtonClick);
//
// EjectWhenDoneCheckBox
//
this.EjectWhenDoneCheckBox.AutoSize = true;
this.EjectWhenDoneCheckBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.EjectWhenDoneCheckBox.Location = new System.Drawing.Point(417, 3);
this.EjectWhenDoneCheckBox.Name = "EjectWhenDoneCheckBox";
this.EjectWhenDoneCheckBox.Size = new System.Drawing.Size(133, 26);
this.EjectWhenDoneCheckBox.TabIndex = 3;
this.EjectWhenDoneCheckBox.Text = "Eject When Done";
this.EjectWhenDoneCheckBox.UseVisualStyleBackColor = true;
//
// statusGroupBox
//
this.statusGroupBox.Controls.Add(this.StatusLabel);
this.statusGroupBox.Location = new System.Drawing.Point(3, 326);
this.statusGroupBox.Name = "statusGroupBox";
this.statusGroupBox.Size = new System.Drawing.Size(553, 42);
this.statusGroupBox.TabIndex = 2;
this.statusGroupBox.TabStop = false;
this.statusGroupBox.Text = "Status";
//
// StatusLabel
//
this.StatusLabel.Dock = System.Windows.Forms.DockStyle.Fill;
this.StatusLabel.Enabled = false;
this.StatusLabel.Location = new System.Drawing.Point(3, 16);
this.StatusLabel.Name = "StatusLabel";
this.StatusLabel.ReadOnly = true;
this.StatusLabel.Size = new System.Drawing.Size(547, 20);
this.StatusLabel.TabIndex = 0;
this.StatusLabel.Text = "Waiting for media...";
this.StatusLabel.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
//
// exitToolStripMenuItem
//
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
this.exitToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.X)));
this.exitToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.exitToolStripMenuItem.Text = "Exit";
this.exitToolStripMenuItem.Click += new System.EventHandler(this.AppExitClick);
//
// optionsToolStripMenuItem
//
this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
this.optionsToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.O)));
this.optionsToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
this.optionsToolStripMenuItem.Text = "Options";
this.optionsToolStripMenuItem.Click += new System.EventHandler(this.OptionsClick);
//
// showLogWindowToolStripMenuItem
//
this.showLogWindowToolStripMenuItem.Checked = true;
this.showLogWindowToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
this.showLogWindowToolStripMenuItem.Name = "showLogWindowToolStripMenuItem";
this.showLogWindowToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.L)));
this.showLogWindowToolStripMenuItem.Size = new System.Drawing.Size(209, 22);
this.showLogWindowToolStripMenuItem.Text = "Show Log Window";
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.A)));
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.aboutToolStripMenuItem.Text = "About";
this.aboutToolStripMenuItem.Click += new System.EventHandler(this.AboutClick);
//
// MainWindow
//
this.AcceptButton = this.StartStopButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(584, 411);
this.Controls.Add(this.mainWindowLayout);
this.Controls.Add(this.MenuBar);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MainMenuStrip = this.MenuBar;
this.Name = "MainWindow";
this.Text = "DiscImageCreator GUI";
this.Activated += new System.EventHandler(this.MainWindowActivated);
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainWindowClosing);
this.Load += new System.EventHandler(this.OnContentRendered);
this.LocationChanged += new System.EventHandler(this.MainWindowLocationChanged);
this.MenuBar.ResumeLayout(false);
this.MenuBar.PerformLayout();
this.mainWindowLayout.ResumeLayout(false);
this.settingsGroupBox.ResumeLayout(false);
this.tableLayoutPanel2.ResumeLayout(false);
this.tableLayoutPanel2.PerformLayout();
this.controlsGroupBox.ResumeLayout(false);
this.tableLayoutPanel3.ResumeLayout(false);
this.tableLayoutPanel3.PerformLayout();
this.statusGroupBox.ResumeLayout(false);
this.statusGroupBox.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.MenuStrip MenuBar;
private System.Windows.Forms.TableLayoutPanel mainWindowLayout;
private System.Windows.Forms.GroupBox settingsGroupBox;
private System.Windows.Forms.GroupBox controlsGroupBox;
private System.Windows.Forms.GroupBox statusGroupBox;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.Label systemMediaTypeLabel;
private System.Windows.Forms.Label parametersLabel;
private System.Windows.Forms.Label driveSpeedLabel;
private System.Windows.Forms.Label driveLetterLabel;
private System.Windows.Forms.Label outputDirectoryLabel;
private System.Windows.Forms.Label outputFilenameLabel;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
private System.Windows.Forms.Button StartStopButton;
private System.Windows.Forms.Button DiscScanButton;
private System.Windows.Forms.Button CopyProtectScanButton;
private System.Windows.Forms.CheckBox EjectWhenDoneCheckBox;
private System.Windows.Forms.TextBox OutputFilenameTextBox;
private System.Windows.Forms.ComboBox SystemTypeComboBox;
private System.Windows.Forms.ComboBox MediaTypeComboBox;
private System.Windows.Forms.TextBox OutputDirectoryTextBox;
private System.Windows.Forms.Button OutputDirectoryBrowseButton;
private System.Windows.Forms.ComboBox DriveLetterComboBox;
private System.Windows.Forms.ComboBox DriveSpeedComboBox;
private System.Windows.Forms.TextBox ParametersTextBox;
private System.Windows.Forms.CheckBox EnableParametersCheckBox;
private System.Windows.Forms.TextBox StatusLabel;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem helpToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem;
internal System.Windows.Forms.ToolStripMenuItem showLogWindowToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem;
}
}

View File

@@ -1,727 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Forms;
using DICUI.Data;
using DICUI.Utilities;
namespace DICUI.Forms.Windows
{
public partial class MainWindow : Form
{
// Private UI-related variables
private List<Drive> _drives;
private MediaType? _currentMediaType;
private List<KnownSystem?> _systems;
private List<MediaType?> _mediaTypes;
private bool _alreadyShown;
private DumpEnvironment _env;
// Option related
private Options _options;
private OptionsWindow _optionsWindow;
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.Enabled = false;
DiscScanButton.Enabled = false;
CopyProtectScanButton.Enabled = false;
if (_options.OpenLogWindowAtStartup)
{
this.StartPosition = FormStartPosition.CenterScreen;
double combinedHeight = this.Height + _logWindow.Height + Constants.LogWindowMarginFromMainWindow;
Rectangle bounds = GetScaledCoordinates(Screen.PrimaryScreen.WorkingArea);
this.Left = (int)(bounds.Left + (bounds.Width - this.Width) / 2);
this.Top = (int)(bounds.Top + (bounds.Height - combinedHeight) / 2);
}
}
#region Events
private void OnContentRendered(object sender, EventArgs 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
showLogWindowToolStripMenuItem.Checked = true;
ViewModels.LoggerViewModel.WindowVisible = true;
}
// Populate the list of systems
StatusLabel.Text = "Creating system list, please wait!";
PopulateSystems();
// Populate the list of drives
StatusLabel.Text = "Creating drive list, please wait!";
PopulateDrives();
// Set the position of the log window
if (_logWindow.Visible)
{
_logWindow.AdjustPositionToMainWindow();
this.Focus();
}
}
private void StartStopButtonClick(object sender, EventArgs e)
{
// Dump or stop the dump
if (StartStopButton.Text == Constants.StartDumping)
{
StartDumping();
}
else if (StartStopButton.Text == Constants.StopDumping)
{
ViewModels.LoggerViewModel.VerboseLogLn("Canceling dumping process...");
_env.CancelDumping();
CopyProtectScanButton.Enabled = true;
if (EjectWhenDoneCheckBox.Checked == true)
{
ViewModels.LoggerViewModel.VerboseLogLn($"Ejecting disc in drive {_env.Drive.Letter}");
_env.EjectDisc();
}
}
}
private void OutputDirectoryBrowseButtonClick(object sender, EventArgs e)
{
BrowseFolder();
EnsureDiscInformation();
}
private void DiscScanButtonClick(object sender, EventArgs e)
{
PopulateDrives();
}
private void CopyProtectScanButtonClick(object sender, EventArgs e)
{
ScanAndShowProtection();
}
private void SystemTypeComboBoxSelectionChanged(object sender, EventArgs 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();
EnsureDiscInformation();
}
private void MediaTypeComboBoxSelectionChanged(object sender, EventArgs e)
{
_currentMediaType = MediaTypeComboBox.SelectedItem as MediaType?;
SetSupportedDriveSpeed();
GetOutputNames();
EnsureDiscInformation();
}
private void DriveLetterComboBoxSelectionChanged(object sender, EventArgs e)
{
CacheCurrentDiscType();
SetCurrentDiscType();
GetOutputNames();
SetSupportedDriveSpeed();
}
private void DriveSpeedComboBoxSelectionChanged(object sender, EventArgs e)
{
EnsureDiscInformation();
}
private void OutputFilenameTextBoxTextChanged(object sender, EventArgs e)
{
EnsureDiscInformation();
}
private void OutputDirectoryTextBoxTextChanged(object sender, EventArgs e)
{
EnsureDiscInformation();
}
private void ProgressUpdated(object sender, Result value)
{
StatusLabel.Text = value.Message;
ViewModels.LoggerViewModel.VerboseLogLn(value.Message);
}
private void MainWindowLocationChanged(object sender, EventArgs e)
{
if (_logWindow.Visible)
_logWindow.AdjustPositionToMainWindow();
}
private void MainWindowActivated(object sender, EventArgs e)
{
if (!_logWindow.Visible)
_logWindow.BringToFront();
this.BringToFront();
}
private void MainWindowClosing(object sender, FormClosingEventArgs e)
{
if (_logWindow.Visible)
_logWindow.Close();
}
private void EnableParametersCheckBoxClick(object sender, EventArgs e)
{
if (EnableParametersCheckBox.Checked)
{
ParametersTextBox.ReadOnly = false;
ParametersTextBox.Enabled = true;
}
else
{
ParametersTextBox.ReadOnly = true;
ParametersTextBox.Enabled = false;
ProcessCustomParameters();
}
}
// Toolbar Events
private void AppExitClick(object sender, EventArgs e)
{
System.Windows.Application.Current.Shutdown();
}
private void AboutClick(object sender, EventArgs e)
{
System.Windows.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, EventArgs e)
{
// lazy initialization
if (_optionsWindow == null)
{
_optionsWindow = new OptionsWindow(this, _options);
_optionsWindow.Closed += delegate
{
_optionsWindow = null;
};
}
_optionsWindow.Owner = this;
_optionsWindow.StartPosition = FormStartPosition.CenterParent;
_optionsWindow.RefreshSettings();
_optionsWindow.Show();
}
public void OnOptionsUpdated()
{
GetOutputNames();
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).ToList();
var comboBoxItems = new List<MediaTypeComboBoxItem>();
foreach (var mediaType in _mediaTypes)
comboBoxItems.Add(new MediaTypeComboBoxItem(mediaType));
MediaTypeComboBox.DataSource = comboBoxItems;
MediaTypeComboBox.Enabled = _mediaTypes.Count > 1;
MediaTypeComboBox.SelectedIndex = (_mediaTypes.IndexOf(_currentMediaType) >= 0 ? _mediaTypes.IndexOf(_currentMediaType) : 0);
}
else
{
MediaTypeComboBox.Enabled = false;
MediaTypeComboBox.DataSource = null;
MediaTypeComboBox.SelectedIndex = -1;
}
}
/// <summary>
/// Get a complete list of supported systems and fill the combo box
/// </summary>
private void PopulateSystems()
{
_systems = Validators.CreateListOfSystems();
ViewModels.LoggerViewModel.VerboseLogLn("Populating systems, {0} systems found.", _systems.Count);
Dictionary<KnownSystemCategory, List<KnownSystem?>> mapping = _systems
.GroupBy(s => s.Category())
.ToDictionary(
k => k.Key,
v => v
.OrderBy(s => s.Name())
.ToList()
);
List<KnownSystemComboBoxItem> comboBoxItems = new List<KnownSystemComboBoxItem>();
comboBoxItems.Add(new KnownSystemComboBoxItem(KnownSystem.NONE));
foreach (var group in mapping)
{
comboBoxItems.Add(new KnownSystemComboBoxItem(group.Key));
group.Value.ForEach(system => comboBoxItems.Add(new KnownSystemComboBoxItem(system)));
}
SystemTypeComboBox.DataSource = comboBoxItems;
SystemTypeComboBox.SelectedIndex = 0;
StartStopButton.Enabled = 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
DiscScanButton.Enabled = true;
// Populate the list of drives and add it to the combo box
_drives = Validators.CreateListOfDrives();
DriveLetterComboBox.DataSource = _drives;
if (DriveLetterComboBox.Items.Count > 0)
{
int index = _drives.FindIndex(d => d.MarkedActive);
DriveLetterComboBox.SelectedIndex = (index != -1 ? index : 0);
StatusLabel.Text = "Valid drive found! Choose your Media Type";
StartStopButton.Enabled = true;
CopyProtectScanButton.Enabled = true;
ViewModels.LoggerViewModel.VerboseLogLn("Found {0} drives: {1}", _drives.Count, String.Join(", ", _drives.Select(d => d.Letter)));
}
else
{
DriveLetterComboBox.SelectedIndex = -1;
StatusLabel.Text = "No valid drive found!";
StartStopButton.Enabled = false;
CopyProtectScanButton.Enabled = false;
ViewModels.LoggerViewModel.VerboseLogLn("Found no drives");
}
}
/// <summary>
/// Browse for an output folder
/// </summary>
private void BrowseFolder()
{
FolderBrowserDialog folderDialog = new FolderBrowserDialog { ShowNewFolderButton = false, SelectedPath = System.AppDomain.CurrentDomain.BaseDirectory };
DialogResult result = folderDialog.ShowDialog();
if (result == 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,
System = SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem,
Type = MediaTypeComboBox.SelectedItem as MediaTypeComboBoxItem,
};
// 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.Checked == true)
{
MessageBoxResult result = System.Windows.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.Checked = false;
ParametersTextBox.Enabled = 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())
{
System.Windows.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 = System.Windows.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 = System.Windows.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.Text = Constants.StopDumping;
CopyProtectScanButton.Enabled = false;
StatusLabel.Text = "Beginning dumping process";
ViewModels.LoggerViewModel.VerboseLogLn("Starting dumping process..");
var progress = new Progress<Result>();
progress.ProgressChanged += ProgressUpdated;
Result result = await _env.StartDumping(progress);
StatusLabel.Text = 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.Text = Constants.StartDumping;
CopyProtectScanButton.Enabled = true;
}
if (EjectWhenDoneCheckBox.Checked == 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.Text = result.Message;
// Set the index for the current disc type
SetCurrentDiscType();
StartStopButton.Enabled = result && (_drives != null && _drives.Count > 0 ? true : false);
// If we're in a type that doesn't support drive speeds
DriveSpeedComboBox.Enabled = _env.Type.DoesSupportDriveSpeed();
// If input params are not enabled, generate the full parameters from the environment
if (!ParametersTextBox.Enabled)
{
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>
private void GetOutputNames()
{
Drive drive = DriveLetterComboBox.SelectedItem as Drive;
KnownSystem? systemType = SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem;
MediaType? mediaType = MediaTypeComboBox.SelectedItem as MediaType?;
OutputDirectoryTextBox.Text = Path.Combine(_options.DefaultOutputPath, drive?.VolumeLabel ?? string.Empty);
OutputFilenameTextBox.Text = (drive?.VolumeLabel ?? "disc") + (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.Text;
StatusLabel.Text = "Scanning for copy protection... this might take a while!";
StartStopButton.Enabled = false;
DiscScanButton.Enabled = false;
CopyProtectScanButton.Enabled = false;
string protections = await Validators.RunProtectionScanOnPath(_env.Drive.Letter + ":\\");
if (!ViewModels.LoggerViewModel.WindowVisible)
System.Windows.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.Text = tempContent;
StartStopButton.Enabled = true;
DiscScanButton.Enabled = true;
CopyProtectScanButton.Enabled = 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.DataSource = 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.NintendoGameCube:
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.SelectedIndex = values.ToList().IndexOf(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 || drive.IsFloppy)
return;
// Get the current optical disc type
if (!_options.SkipMediaTypeDetection)
{
ViewModels.LoggerViewModel.VerboseLog("Trying to detect media type for drive {0}.. ", drive.Letter);
_currentMediaType = Validators.GetDiscType(drive.Letter);
ViewModels.LoggerViewModel.VerboseLogLn(_currentMediaType == null ? "unable to detect." : ("detected " + _currentMediaType.Name() + "."));
}
}
/// <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.Text = $"Disc of type '{Converters.MediaTypeToString(_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.SelectedIndex = ((IReadOnlyList<int>)(DriveSpeedComboBox.DataSource)).ToList().IndexOf(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 = Converters.BaseCommmandToMediaType(_env.DICParameters.Command);
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
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,565 +0,0 @@
namespace DICUI.Forms.Windows
{
partial class OptionsWindow
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.pathsGroupBox = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.DefaultOutputPathButton = new System.Windows.Forms.Button();
this.SubDumpPathButton = new System.Windows.Forms.Button();
this.discImageCreatorPathLabel = new System.Windows.Forms.Label();
this.subdumpPathLabel = new System.Windows.Forms.Label();
this.defaultOutputPathLabel = new System.Windows.Forms.Label();
this.DICPathTextBox = new System.Windows.Forms.TextBox();
this.SubDumpPathTextBox = new System.Windows.Forms.TextBox();
this.DefaultOutputPathTextBox = new System.Windows.Forms.TextBox();
this.DICPathButton = new System.Windows.Forms.Button();
this.preferredSpeedGroupBox = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.DumpSpeedCDLabel = new System.Windows.Forms.Label();
this.DumpSpeedDVDLabel = new System.Windows.Forms.Label();
this.DumpSpeedBDLabel = new System.Windows.Forms.Label();
this.DumpSpeedCDSlider = new System.Windows.Forms.TrackBar();
this.DumpSpeedDVDSlider = new System.Windows.Forms.TrackBar();
this.DumpSpeedBDSlider = new System.Windows.Forms.TrackBar();
this.DumpSpeedCDTextBox = new System.Windows.Forms.TextBox();
this.DumpSpeedDVDTextBox = new System.Windows.Forms.TextBox();
this.DumpSpeedBDTextBox = new System.Windows.Forms.TextBox();
this.optionsGroupBox = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
this.QuietModeCheckBox = new System.Windows.Forms.CheckBox();
this.AutoScanCheckBox = new System.Windows.Forms.CheckBox();
this.ParanoidModeCheckBox = new System.Windows.Forms.CheckBox();
this.SkipDetectionCheckBox = new System.Windows.Forms.CheckBox();
this.C2RereadTimesTextBox = new System.Windows.Forms.TextBox();
this.C2RereadLabel = new System.Windows.Forms.Label();
this.tableLayoutPanel5 = new System.Windows.Forms.TableLayoutPanel();
this.AcceptButton = new System.Windows.Forms.Button();
this.CancelButton = new System.Windows.Forms.Button();
this.tableLayoutPanel1.SuspendLayout();
this.pathsGroupBox.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.preferredSpeedGroupBox.SuspendLayout();
this.tableLayoutPanel3.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.DumpSpeedCDSlider)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.DumpSpeedDVDSlider)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.DumpSpeedBDSlider)).BeginInit();
this.optionsGroupBox.SuspendLayout();
this.tableLayoutPanel4.SuspendLayout();
this.tableLayoutPanel5.SuspendLayout();
this.SuspendLayout();
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 1;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Controls.Add(this.pathsGroupBox, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.preferredSpeedGroupBox, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.optionsGroupBox, 0, 2);
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel5, 0, 3);
this.tableLayoutPanel1.Location = new System.Drawing.Point(12, 12);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 4;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 150F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 100F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 40F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(475, 417);
this.tableLayoutPanel1.TabIndex = 0;
this.tableLayoutPanel1.UseWaitCursor = true;
//
// pathsGroupBox
//
this.pathsGroupBox.Controls.Add(this.tableLayoutPanel2);
this.pathsGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.pathsGroupBox.Location = new System.Drawing.Point(3, 3);
this.pathsGroupBox.Name = "pathsGroupBox";
this.pathsGroupBox.Size = new System.Drawing.Size(469, 121);
this.pathsGroupBox.TabIndex = 0;
this.pathsGroupBox.TabStop = false;
this.pathsGroupBox.Text = "Paths";
this.pathsGroupBox.UseWaitCursor = true;
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 3;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 29.41176F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 58.82353F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 11.76471F));
this.tableLayoutPanel2.Controls.Add(this.DefaultOutputPathButton, 2, 2);
this.tableLayoutPanel2.Controls.Add(this.SubDumpPathButton, 2, 1);
this.tableLayoutPanel2.Controls.Add(this.discImageCreatorPathLabel, 0, 0);
this.tableLayoutPanel2.Controls.Add(this.subdumpPathLabel, 0, 1);
this.tableLayoutPanel2.Controls.Add(this.defaultOutputPathLabel, 0, 2);
this.tableLayoutPanel2.Controls.Add(this.DICPathTextBox, 1, 0);
this.tableLayoutPanel2.Controls.Add(this.SubDumpPathTextBox, 1, 1);
this.tableLayoutPanel2.Controls.Add(this.DefaultOutputPathTextBox, 1, 2);
this.tableLayoutPanel2.Controls.Add(this.DICPathButton, 2, 0);
this.tableLayoutPanel2.Location = new System.Drawing.Point(6, 15);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 3;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(457, 100);
this.tableLayoutPanel2.TabIndex = 0;
this.tableLayoutPanel2.UseWaitCursor = true;
//
// DefaultOutputPathButton
//
this.DefaultOutputPathButton.Location = new System.Drawing.Point(405, 69);
this.DefaultOutputPathButton.Name = "DefaultOutputPathButton";
this.DefaultOutputPathButton.Size = new System.Drawing.Size(49, 23);
this.DefaultOutputPathButton.TabIndex = 8;
this.DefaultOutputPathButton.Text = "...";
this.DefaultOutputPathButton.UseVisualStyleBackColor = true;
this.DefaultOutputPathButton.UseWaitCursor = true;
this.DefaultOutputPathButton.Click += new System.EventHandler(this.BrowseForPathClick);
//
// SubDumpPathButton
//
this.SubDumpPathButton.Location = new System.Drawing.Point(405, 36);
this.SubDumpPathButton.Name = "SubDumpPathButton";
this.SubDumpPathButton.Size = new System.Drawing.Size(49, 23);
this.SubDumpPathButton.TabIndex = 7;
this.SubDumpPathButton.Text = "...";
this.SubDumpPathButton.UseVisualStyleBackColor = true;
this.SubDumpPathButton.UseWaitCursor = true;
this.SubDumpPathButton.Click += new System.EventHandler(this.BrowseForPathClick);
//
// discImageCreatorPathLabel
//
this.discImageCreatorPathLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.discImageCreatorPathLabel.AutoSize = true;
this.discImageCreatorPathLabel.Cursor = System.Windows.Forms.Cursors.WaitCursor;
this.discImageCreatorPathLabel.Location = new System.Drawing.Point(15, 10);
this.discImageCreatorPathLabel.Name = "discImageCreatorPathLabel";
this.discImageCreatorPathLabel.Size = new System.Drawing.Size(116, 13);
this.discImageCreatorPathLabel.TabIndex = 0;
this.discImageCreatorPathLabel.Text = "DiscImageCreator Path";
//
// subdumpPathLabel
//
this.subdumpPathLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.subdumpPathLabel.AutoSize = true;
this.subdumpPathLabel.Location = new System.Drawing.Point(56, 43);
this.subdumpPathLabel.Name = "subdumpPathLabel";
this.subdumpPathLabel.Size = new System.Drawing.Size(75, 13);
this.subdumpPathLabel.TabIndex = 1;
this.subdumpPathLabel.Text = "subdump Path";
this.subdumpPathLabel.UseWaitCursor = true;
//
// defaultOutputPathLabel
//
this.defaultOutputPathLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.defaultOutputPathLabel.AutoSize = true;
this.defaultOutputPathLabel.Location = new System.Drawing.Point(30, 76);
this.defaultOutputPathLabel.Name = "defaultOutputPathLabel";
this.defaultOutputPathLabel.Size = new System.Drawing.Size(101, 13);
this.defaultOutputPathLabel.TabIndex = 2;
this.defaultOutputPathLabel.Text = "Default Output Path";
this.defaultOutputPathLabel.UseWaitCursor = true;
//
// DICPathTextBox
//
this.DICPathTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
this.DICPathTextBox.Location = new System.Drawing.Point(138, 6);
this.DICPathTextBox.Name = "DICPathTextBox";
this.DICPathTextBox.Size = new System.Drawing.Size(259, 20);
this.DICPathTextBox.TabIndex = 3;
this.DICPathTextBox.UseWaitCursor = true;
//
// SubDumpPathTextBox
//
this.SubDumpPathTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
this.SubDumpPathTextBox.Location = new System.Drawing.Point(138, 39);
this.SubDumpPathTextBox.Name = "SubDumpPathTextBox";
this.SubDumpPathTextBox.Size = new System.Drawing.Size(259, 20);
this.SubDumpPathTextBox.TabIndex = 4;
this.SubDumpPathTextBox.UseWaitCursor = true;
//
// DefaultOutputPathTextBox
//
this.DefaultOutputPathTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
this.DefaultOutputPathTextBox.Location = new System.Drawing.Point(138, 73);
this.DefaultOutputPathTextBox.Name = "DefaultOutputPathTextBox";
this.DefaultOutputPathTextBox.Size = new System.Drawing.Size(259, 20);
this.DefaultOutputPathTextBox.TabIndex = 5;
this.DefaultOutputPathTextBox.UseWaitCursor = true;
//
// DICPathButton
//
this.DICPathButton.Location = new System.Drawing.Point(405, 3);
this.DICPathButton.Name = "DICPathButton";
this.DICPathButton.Size = new System.Drawing.Size(49, 23);
this.DICPathButton.TabIndex = 6;
this.DICPathButton.Text = "...";
this.DICPathButton.UseVisualStyleBackColor = true;
this.DICPathButton.UseWaitCursor = true;
this.DICPathButton.Click += new System.EventHandler(this.BrowseForPathClick);
//
// preferredSpeedGroupBox
//
this.preferredSpeedGroupBox.Controls.Add(this.tableLayoutPanel3);
this.preferredSpeedGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.preferredSpeedGroupBox.Location = new System.Drawing.Point(3, 130);
this.preferredSpeedGroupBox.Name = "preferredSpeedGroupBox";
this.preferredSpeedGroupBox.Size = new System.Drawing.Size(469, 144);
this.preferredSpeedGroupBox.TabIndex = 1;
this.preferredSpeedGroupBox.TabStop = false;
this.preferredSpeedGroupBox.Text = "Preferred Dump Speed";
this.preferredSpeedGroupBox.UseWaitCursor = true;
//
// tableLayoutPanel3
//
this.tableLayoutPanel3.ColumnCount = 3;
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80F));
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 40F));
this.tableLayoutPanel3.Controls.Add(this.DumpSpeedCDLabel, 0, 0);
this.tableLayoutPanel3.Controls.Add(this.DumpSpeedDVDLabel, 0, 1);
this.tableLayoutPanel3.Controls.Add(this.DumpSpeedBDLabel, 0, 2);
this.tableLayoutPanel3.Controls.Add(this.DumpSpeedCDSlider, 1, 0);
this.tableLayoutPanel3.Controls.Add(this.DumpSpeedDVDSlider, 1, 1);
this.tableLayoutPanel3.Controls.Add(this.DumpSpeedBDSlider, 1, 2);
this.tableLayoutPanel3.Controls.Add(this.DumpSpeedCDTextBox, 2, 0);
this.tableLayoutPanel3.Controls.Add(this.DumpSpeedDVDTextBox, 2, 1);
this.tableLayoutPanel3.Controls.Add(this.DumpSpeedBDTextBox, 2, 2);
this.tableLayoutPanel3.Location = new System.Drawing.Point(6, 19);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowCount = 3;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
this.tableLayoutPanel3.Size = new System.Drawing.Size(457, 119);
this.tableLayoutPanel3.TabIndex = 0;
this.tableLayoutPanel3.UseWaitCursor = true;
//
// DumpSpeedCDLabel
//
this.DumpSpeedCDLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.DumpSpeedCDLabel.AutoSize = true;
this.DumpSpeedCDLabel.Location = new System.Drawing.Point(3, 13);
this.DumpSpeedCDLabel.Name = "DumpSpeedCDLabel";
this.DumpSpeedCDLabel.Size = new System.Drawing.Size(50, 13);
this.DumpSpeedCDLabel.TabIndex = 0;
this.DumpSpeedCDLabel.Text = "CD-ROM";
this.DumpSpeedCDLabel.UseWaitCursor = true;
//
// DumpSpeedDVDLabel
//
this.DumpSpeedDVDLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.DumpSpeedDVDLabel.AutoSize = true;
this.DumpSpeedDVDLabel.Location = new System.Drawing.Point(3, 52);
this.DumpSpeedDVDLabel.Name = "DumpSpeedDVDLabel";
this.DumpSpeedDVDLabel.Size = new System.Drawing.Size(58, 13);
this.DumpSpeedDVDLabel.TabIndex = 1;
this.DumpSpeedDVDLabel.Text = "DVD-ROM";
this.DumpSpeedDVDLabel.UseWaitCursor = true;
//
// DumpSpeedBDLabel
//
this.DumpSpeedBDLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.DumpSpeedBDLabel.AutoSize = true;
this.DumpSpeedBDLabel.Location = new System.Drawing.Point(3, 92);
this.DumpSpeedBDLabel.Name = "DumpSpeedBDLabel";
this.DumpSpeedBDLabel.Size = new System.Drawing.Size(50, 13);
this.DumpSpeedBDLabel.TabIndex = 2;
this.DumpSpeedBDLabel.Text = "BD-ROM";
this.DumpSpeedBDLabel.UseWaitCursor = true;
//
// DumpSpeedCDSlider
//
this.DumpSpeedCDSlider.Dock = System.Windows.Forms.DockStyle.Fill;
this.DumpSpeedCDSlider.Location = new System.Drawing.Point(83, 3);
this.DumpSpeedCDSlider.Name = "DumpSpeedCDSlider";
this.DumpSpeedCDSlider.Size = new System.Drawing.Size(331, 33);
this.DumpSpeedCDSlider.TabIndex = 3;
this.DumpSpeedCDSlider.UseWaitCursor = true;
this.DumpSpeedCDSlider.Value = 1;
this.DumpSpeedCDSlider.Scroll += new System.EventHandler(this.SliderChanged);
//
// DumpSpeedDVDSlider
//
this.DumpSpeedDVDSlider.Dock = System.Windows.Forms.DockStyle.Fill;
this.DumpSpeedDVDSlider.Location = new System.Drawing.Point(83, 42);
this.DumpSpeedDVDSlider.Name = "DumpSpeedDVDSlider";
this.DumpSpeedDVDSlider.Size = new System.Drawing.Size(331, 33);
this.DumpSpeedDVDSlider.TabIndex = 4;
this.DumpSpeedDVDSlider.UseWaitCursor = true;
this.DumpSpeedDVDSlider.Value = 1;
this.DumpSpeedDVDSlider.Scroll += new System.EventHandler(this.SliderChanged);
//
// DumpSpeedBDSlider
//
this.DumpSpeedBDSlider.Dock = System.Windows.Forms.DockStyle.Fill;
this.DumpSpeedBDSlider.Location = new System.Drawing.Point(83, 81);
this.DumpSpeedBDSlider.Name = "DumpSpeedBDSlider";
this.DumpSpeedBDSlider.Size = new System.Drawing.Size(331, 35);
this.DumpSpeedBDSlider.TabIndex = 5;
this.DumpSpeedBDSlider.UseWaitCursor = true;
this.DumpSpeedBDSlider.Value = 1;
this.DumpSpeedBDSlider.Scroll += new System.EventHandler(this.SliderChanged);
//
// DumpSpeedCDTextBox
//
this.DumpSpeedCDTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
this.DumpSpeedCDTextBox.Enabled = false;
this.DumpSpeedCDTextBox.Location = new System.Drawing.Point(420, 9);
this.DumpSpeedCDTextBox.Name = "DumpSpeedCDTextBox";
this.DumpSpeedCDTextBox.ReadOnly = true;
this.DumpSpeedCDTextBox.Size = new System.Drawing.Size(34, 20);
this.DumpSpeedCDTextBox.TabIndex = 6;
this.DumpSpeedCDTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.DumpSpeedCDTextBox.UseWaitCursor = true;
//
// DumpSpeedDVDTextBox
//
this.DumpSpeedDVDTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
this.DumpSpeedDVDTextBox.Enabled = false;
this.DumpSpeedDVDTextBox.Location = new System.Drawing.Point(420, 48);
this.DumpSpeedDVDTextBox.Name = "DumpSpeedDVDTextBox";
this.DumpSpeedDVDTextBox.ReadOnly = true;
this.DumpSpeedDVDTextBox.Size = new System.Drawing.Size(34, 20);
this.DumpSpeedDVDTextBox.TabIndex = 7;
this.DumpSpeedDVDTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.DumpSpeedDVDTextBox.UseWaitCursor = true;
//
// DumpSpeedBDTextBox
//
this.DumpSpeedBDTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
this.DumpSpeedBDTextBox.Enabled = false;
this.DumpSpeedBDTextBox.Location = new System.Drawing.Point(420, 88);
this.DumpSpeedBDTextBox.Name = "DumpSpeedBDTextBox";
this.DumpSpeedBDTextBox.ReadOnly = true;
this.DumpSpeedBDTextBox.Size = new System.Drawing.Size(34, 20);
this.DumpSpeedBDTextBox.TabIndex = 8;
this.DumpSpeedBDTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.DumpSpeedBDTextBox.UseWaitCursor = true;
//
// optionsGroupBox
//
this.optionsGroupBox.Controls.Add(this.tableLayoutPanel4);
this.optionsGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.optionsGroupBox.Location = new System.Drawing.Point(3, 280);
this.optionsGroupBox.Name = "optionsGroupBox";
this.optionsGroupBox.Size = new System.Drawing.Size(469, 94);
this.optionsGroupBox.TabIndex = 2;
this.optionsGroupBox.TabStop = false;
this.optionsGroupBox.Text = "Options";
//
// tableLayoutPanel4
//
this.tableLayoutPanel4.ColumnCount = 4;
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tableLayoutPanel4.Controls.Add(this.QuietModeCheckBox, 0, 0);
this.tableLayoutPanel4.Controls.Add(this.AutoScanCheckBox, 0, 1);
this.tableLayoutPanel4.Controls.Add(this.ParanoidModeCheckBox, 1, 0);
this.tableLayoutPanel4.Controls.Add(this.SkipDetectionCheckBox, 2, 1);
this.tableLayoutPanel4.Controls.Add(this.C2RereadTimesTextBox, 3, 0);
this.tableLayoutPanel4.Controls.Add(this.C2RereadLabel, 2, 0);
this.tableLayoutPanel4.Location = new System.Drawing.Point(6, 19);
this.tableLayoutPanel4.Name = "tableLayoutPanel4";
this.tableLayoutPanel4.RowCount = 2;
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel4.Size = new System.Drawing.Size(457, 69);
this.tableLayoutPanel4.TabIndex = 0;
//
// QuietModeCheckBox
//
this.QuietModeCheckBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.QuietModeCheckBox.AutoSize = true;
this.QuietModeCheckBox.Location = new System.Drawing.Point(3, 8);
this.QuietModeCheckBox.Name = "QuietModeCheckBox";
this.QuietModeCheckBox.Size = new System.Drawing.Size(81, 17);
this.QuietModeCheckBox.TabIndex = 0;
this.QuietModeCheckBox.Text = "Quiet Mode";
this.QuietModeCheckBox.UseVisualStyleBackColor = true;
//
// AutoScanCheckBox
//
this.AutoScanCheckBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.AutoScanCheckBox.AutoSize = true;
this.tableLayoutPanel4.SetColumnSpan(this.AutoScanCheckBox, 2);
this.AutoScanCheckBox.Location = new System.Drawing.Point(3, 43);
this.AutoScanCheckBox.Name = "AutoScanCheckBox";
this.AutoScanCheckBox.Size = new System.Drawing.Size(182, 17);
this.AutoScanCheckBox.TabIndex = 1;
this.AutoScanCheckBox.Text = "Automatically Scan for Protection";
this.AutoScanCheckBox.UseVisualStyleBackColor = true;
//
// ParanoidModeCheckBox
//
this.ParanoidModeCheckBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.ParanoidModeCheckBox.AutoSize = true;
this.ParanoidModeCheckBox.Location = new System.Drawing.Point(117, 8);
this.ParanoidModeCheckBox.Name = "ParanoidModeCheckBox";
this.ParanoidModeCheckBox.Size = new System.Drawing.Size(98, 17);
this.ParanoidModeCheckBox.TabIndex = 2;
this.ParanoidModeCheckBox.Text = "Paranoid Mode";
this.ParanoidModeCheckBox.UseVisualStyleBackColor = true;
//
// SkipDetectionCheckBox
//
this.SkipDetectionCheckBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.SkipDetectionCheckBox.AutoSize = true;
this.tableLayoutPanel4.SetColumnSpan(this.SkipDetectionCheckBox, 2);
this.SkipDetectionCheckBox.Location = new System.Drawing.Point(231, 43);
this.SkipDetectionCheckBox.Name = "SkipDetectionCheckBox";
this.SkipDetectionCheckBox.Size = new System.Drawing.Size(155, 17);
this.SkipDetectionCheckBox.TabIndex = 3;
this.SkipDetectionCheckBox.Text = "Skip Media Type Detection";
this.SkipDetectionCheckBox.UseVisualStyleBackColor = true;
//
// C2RereadTimesTextBox
//
this.C2RereadTimesTextBox.Anchor = System.Windows.Forms.AnchorStyles.None;
this.C2RereadTimesTextBox.Location = new System.Drawing.Point(349, 7);
this.C2RereadTimesTextBox.Name = "C2RereadTimesTextBox";
this.C2RereadTimesTextBox.Size = new System.Drawing.Size(100, 20);
this.C2RereadTimesTextBox.TabIndex = 4;
//
// C2RereadLabel
//
this.C2RereadLabel.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.C2RereadLabel.AutoSize = true;
this.C2RereadLabel.Location = new System.Drawing.Point(250, 10);
this.C2RereadLabel.Name = "C2RereadLabel";
this.C2RereadLabel.Size = new System.Drawing.Size(89, 13);
this.C2RereadLabel.TabIndex = 5;
this.C2RereadLabel.Text = "C2 Reread Times";
//
// tableLayoutPanel5
//
this.tableLayoutPanel5.ColumnCount = 2;
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel5.Controls.Add(this.AcceptButton, 0, 0);
this.tableLayoutPanel5.Controls.Add(this.CancelButton, 1, 0);
this.tableLayoutPanel5.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel5.Location = new System.Drawing.Point(3, 380);
this.tableLayoutPanel5.Name = "tableLayoutPanel5";
this.tableLayoutPanel5.RowCount = 1;
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel5.Size = new System.Drawing.Size(469, 34);
this.tableLayoutPanel5.TabIndex = 3;
//
// AcceptButton
//
this.AcceptButton.Anchor = System.Windows.Forms.AnchorStyles.None;
this.AcceptButton.Location = new System.Drawing.Point(79, 5);
this.AcceptButton.Name = "AcceptButton";
this.AcceptButton.Size = new System.Drawing.Size(75, 23);
this.AcceptButton.TabIndex = 0;
this.AcceptButton.Text = "Accept";
this.AcceptButton.UseVisualStyleBackColor = true;
this.AcceptButton.Click += new System.EventHandler(this.OnAcceptClick);
//
// CancelButton
//
this.CancelButton.Anchor = System.Windows.Forms.AnchorStyles.None;
this.CancelButton.Location = new System.Drawing.Point(314, 5);
this.CancelButton.Name = "CancelButton";
this.CancelButton.Size = new System.Drawing.Size(75, 23);
this.CancelButton.TabIndex = 1;
this.CancelButton.Text = "Cancel";
this.CancelButton.UseVisualStyleBackColor = true;
this.CancelButton.Click += new System.EventHandler(this.OnCancelClick);
//
// OptionsWindow
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(499, 441);
this.Controls.Add(this.tableLayoutPanel1);
this.Name = "OptionsWindow";
this.ShowIcon = false;
this.Text = "Options";
this.UseWaitCursor = true;
this.tableLayoutPanel1.ResumeLayout(false);
this.pathsGroupBox.ResumeLayout(false);
this.tableLayoutPanel2.ResumeLayout(false);
this.tableLayoutPanel2.PerformLayout();
this.preferredSpeedGroupBox.ResumeLayout(false);
this.tableLayoutPanel3.ResumeLayout(false);
this.tableLayoutPanel3.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.DumpSpeedCDSlider)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.DumpSpeedDVDSlider)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.DumpSpeedBDSlider)).EndInit();
this.optionsGroupBox.ResumeLayout(false);
this.tableLayoutPanel4.ResumeLayout(false);
this.tableLayoutPanel4.PerformLayout();
this.tableLayoutPanel5.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.GroupBox pathsGroupBox;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.Label discImageCreatorPathLabel;
private System.Windows.Forms.Label subdumpPathLabel;
private System.Windows.Forms.Label defaultOutputPathLabel;
private System.Windows.Forms.TextBox DICPathTextBox;
private System.Windows.Forms.TextBox SubDumpPathTextBox;
private System.Windows.Forms.TextBox DefaultOutputPathTextBox;
private System.Windows.Forms.Button DICPathButton;
private System.Windows.Forms.Button DefaultOutputPathButton;
private System.Windows.Forms.Button SubDumpPathButton;
private System.Windows.Forms.GroupBox preferredSpeedGroupBox;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
private System.Windows.Forms.Label DumpSpeedCDLabel;
private System.Windows.Forms.Label DumpSpeedDVDLabel;
private System.Windows.Forms.Label DumpSpeedBDLabel;
private System.Windows.Forms.TrackBar DumpSpeedCDSlider;
private System.Windows.Forms.TrackBar DumpSpeedDVDSlider;
private System.Windows.Forms.TrackBar DumpSpeedBDSlider;
private System.Windows.Forms.TextBox DumpSpeedCDTextBox;
private System.Windows.Forms.TextBox DumpSpeedDVDTextBox;
private System.Windows.Forms.TextBox DumpSpeedBDTextBox;
private System.Windows.Forms.GroupBox optionsGroupBox;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
private System.Windows.Forms.CheckBox QuietModeCheckBox;
private System.Windows.Forms.CheckBox AutoScanCheckBox;
private System.Windows.Forms.CheckBox ParanoidModeCheckBox;
private System.Windows.Forms.CheckBox SkipDetectionCheckBox;
private System.Windows.Forms.TextBox C2RereadTimesTextBox;
private System.Windows.Forms.Label C2RereadLabel;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel5;
private System.Windows.Forms.Button AcceptButton;
private System.Windows.Forms.Button CancelButton;
}
}

View File

@@ -1,179 +0,0 @@
using System;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Forms;
namespace DICUI.Forms.Windows
{
/// <summary>
/// Interaction logic for OptionsWindow
/// </summary>
public partial class OptionsWindow : Form
{
private readonly MainWindow _mainWindow;
private readonly Options _options;
public OptionsWindow(MainWindow mainWindow, Options options)
{
InitializeComponent();
_mainWindow = mainWindow;
_options = options;
// Create data sets
DumpSpeedCDSlider.Minimum = (int)Constants.SpeedsForCDAsCollection.First();
DumpSpeedCDSlider.Maximum = (int)Constants.SpeedsForCDAsCollection.Last();
DumpSpeedDVDSlider.Minimum = (int)Constants.SpeedsForDVDAsCollection.First();
DumpSpeedDVDSlider.Maximum = (int)Constants.SpeedsForDVDAsCollection.Last();
DumpSpeedBDSlider.Minimum = (int)Constants.SpeedsForBDAsCollection.First();
DumpSpeedBDSlider.Maximum = (int)Constants.SpeedsForBDAsCollection.Last();
// Select the current values
DumpSpeedCDSlider.Value = _options.PreferredDumpSpeedCD;
DumpSpeedDVDSlider.Value = _options.PreferredDumpSpeedDVD;
DumpSpeedBDSlider.Value = _options.PreferredDumpSpeedBD;
// Create textbox outputs
DumpSpeedCDTextBox.Text = DumpSpeedCDSlider.Value.ToString();
DumpSpeedDVDTextBox.Text = DumpSpeedDVDSlider.Value.ToString();
DumpSpeedBDTextBox.Text = DumpSpeedBDSlider.Value.ToString();
// Set options
QuietModeCheckBox.Checked = _options.QuietMode;
ParanoidModeCheckBox.Checked = _options.ParanoidMode;
C2RereadTimesTextBox.Text = _options.RereadAmountForC2.ToString();
AutoScanCheckBox.Checked = _options.ScanForProtection;
SkipDetectionCheckBox.Checked = _options.SkipMediaTypeDetection;
}
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)
{
switch (name)
{
case "DICPath":
return DICPathTextBox;
case "SubDumpPath":
return SubDumpPathTextBox;
case "DefaultOutputPath":
return DefaultOutputPathTextBox;
default:
return null;
}
}
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 RefreshSettings()
{
Array.ForEach(PathSettings(), setting => TextBoxForPathSetting(setting).Text = _options.Get(setting));
DumpSpeedCDSlider.Value = _options.PreferredDumpSpeedCD;
DumpSpeedDVDSlider.Value = _options.PreferredDumpSpeedDVD;
DumpSpeedBDSlider.Value = _options.PreferredDumpSpeedBD;
}
#region Event Handlers
private void SliderChanged(object sender, EventArgs e)
{
DumpSpeedCDTextBox.Text = DumpSpeedCDSlider.Value.ToString();
DumpSpeedDVDTextBox.Text = DumpSpeedDVDSlider.Value.ToString();
DumpSpeedBDTextBox.Text = DumpSpeedBDSlider.Value.ToString();
}
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.QuietMode = QuietModeCheckBox.Checked;
_options.ParanoidMode = ParanoidModeCheckBox.Checked;
_options.RereadAmountForC2 = Convert.ToInt32(C2RereadTimesTextBox.Text);
_options.ScanForProtection = AutoScanCheckBox.Checked;
_options.SkipMediaTypeDetection = SkipDetectionCheckBox.Checked;
_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,123 +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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
<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" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</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" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="$this.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

@@ -1,101 +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>{51AB0928-13F9-44BF-A407-B6957A43A056}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DICUI.Library</RootNamespace>
<AssemblyName>DICUI.Library</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<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' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="BurnOutSharp, Version=1.3.7.1, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\BurnOutSharp.1.3.7.1\lib\net461\BurnOutSharp.dll</HintPath>
</Reference>
<Reference Include="LessIO, Version=0.5.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\LessIO.0.5.0\lib\net40\LessIO.dll</HintPath>
</Reference>
<Reference Include="libmspackn, Version=0.8.0.0, Culture=neutral, processorArchitecture=x86">
<HintPath>..\packages\libmspack4n.0.8.0\lib\net40\libmspackn.dll</HintPath>
</Reference>
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Management" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="UnshieldSharp, Version=1.4.2.2, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\UnshieldSharp.1.4.2.2\lib\net461\UnshieldSharp.dll</HintPath>
</Reference>
<Reference Include="zlib.net, Version=1.0.3.0, Culture=neutral, PublicKeyToken=47d7877cb3620160">
<HintPath>..\packages\zlib.net.1.0.4.0\lib\zlib.net.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Data\Constants.cs" />
<Compile Include="Data\Enumerations.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utilities\Converters.cs" />
<Compile Include="Utilities\DumpEnvironment.cs" />
<Compile Include="Utilities\Extensions.cs" />
<Compile Include="Utilities\Parameters.cs" />
<Compile Include="Utilities\Result.cs" />
<Compile Include="Utilities\Validators.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="mspack.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<COMReference Include="IMAPI2">
<Guid>{2735412F-7F64-5B0F-8F00-5D77AFBE261E}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
<COMReference Include="IMAPI2FS">
<Guid>{2C941FD0-975B-59BE-A960-9A2A262853A5}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -1,121 +0,0 @@
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 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 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 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 NoFixSubQSecuROM = "/ns";
public const string NoFixSubRtoW = "/nr";
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";
}
/// <summary>
/// Template field values for submission info
/// </summary>
public static class Template
{
// Manual information
public const string TitleField = "Title";
public const string DiscNumberField = "Disc Number / Letter";
public const string DiscTitleField = "Disc Title";
public const string SystemField = "System";
public const string MediaTypeField = "Media Type";
public const string CategoryField = "Category";
public const string RegionField = "Region";
public const string LanguagesField = "Languages";
public const string DiscSerialField = "Disc Serial";
public const string BarcodeField = "Barcode";
public const string ISBNField = "ISBN";
public const string CommentsField = "Comments";
public const string ContentsField = "Contents";
public const string VersionField = "Version";
public const string EditionField = "Edition/Release";
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 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 PlaystationEXEDateField = "EXE Date";
public const string PlayStationEDCField = "EDC";
public const string PlayStationAntiModchipField = "Anti-modchip";
public const string PlayStationLibCryptField = "LibCrypt";
public const string PlayStation4PICField = "Permanent Information & Control (PIC)";
public const string SegaHeaderField = "Header";
public const string SegaBuildDateField = "Build Date";
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 YesNoValue = "Yes/No";
public const string DiscNotDetected = "Disc Not Detected";
}
}

View File

@@ -1,272 +0,0 @@
namespace DICUI.Data
{
/// <summary>
/// Supported DIC commands
/// </summary>
public enum DICCommand
{
NONE = 0,
Audio,
BluRay,
Close,
CompactDisc,
Data,
DigitalVideoDisc,
DriveSpeed,
Eject,
Floppy,
GDROM,
MDS,
Merge,
Reset,
Start,
Stop,
Sub,
Swap,
XBOX,
XBOXSwap,
XGD2Swap,
XGD3Swap,
}
/// <summary>
/// Supported DIC flags
/// </summary>
public enum DICFlag
{
NONE = 0,
AddOffset,
AMSF,
BEOpcode,
C2Opcode,
CopyrightManagementInformation,
D8Opcode,
DisableBeep,
ForceUnitAccess,
MCN,
MultiSession,
NoFixSubP,
NoFixSubQ,
NoFixSubQLibCrypt,
NoFixSubQSecuROM,
NoFixSubRtoW,
Raw,
Reverse,
ScanAntiMod,
ScanFileProtect,
ScanSectorProtect,
SeventyFour,
SkipSector,
SubchannelReadLevel,
VideoNow,
}
/// <summary>
/// Known systems
/// </summary>
public enum KnownSystem
{
NONE = 0,
#region Consoles
AtariJaguarCD,
BandaiPlaydiaQuickInteractiveSystem,
BandaiApplePippin,
CommodoreAmigaCD32,
CommodoreAmigaCDTV,
MattelHyperscan,
MicrosoftXBOX,
MicrosoftXBOX360,
MicrosoftXBOXOne,
NECPCEngineTurboGrafxCD,
NECPCFX,
NintendoGameCube,
NintendoWii,
NintendoWiiU,
Panasonic3DOInteractiveMultiplayer,
PhilipsCDi,
SegaCDMegaCD,
SegaDreamcast,
SegaSaturn,
SNKNeoGeoCD,
SonyPlayStation,
SonyPlayStation2,
SonyPlayStation3,
SonyPlayStation4,
SonyPlayStationPortable,
VMLabsNuon,
VTechVFlashVSmilePro,
ZAPiTGamesGameWaveFamilyEntertainmentSystem,
MarkerConsoleEnd,
#endregion
#region Computers
AcornArchimedes,
AppleMacintosh,
CommodoreAmigaCD,
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,
MeritIndustriesMegaTouchAurora,
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,
TandyMemorexVisualInformationSystem,
TsunamiTsuMoMultiGameMotionSystem,
MarkerArcadeEnd,
#endregion
#region Other
AudioCD,
BDVideo,
DVDVideo,
EnhancedCD,
EnhancedDVD,
EnhancedBD,
HasbroVideoNow,
HDDVDVideo,
PalmOS,
PhilipsCDiDigitalVideo,
PhotoCD,
PlayStationGameSharkUpdates,
RainbowDisc,
TaoiKTV,
TomyKissSite,
VideoCD,
MarkerOtherEnd,
#endregion
}
/// <summary>
/// Known system category
/// </summary>
public enum KnownSystemCategory
{
Console = 0,
Computer,
Arcade,
Other,
Custom
};
/// <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,
NintendoGameCube,
NintendoWiiOpticalDisc,
NintendoWiiUOpticalDisc,
UMD,
#endregion
// Unsorted Formats
Cartridge,
CED,
}
}

View File

@@ -1,36 +0,0 @@
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 © 2018")]
[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.11")]
[assembly: AssemblyFileVersion("1.11.0.0")]

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,136 +0,0 @@
using DICUI.Data;
namespace DICUI.Utilities
{
/// <summary>
/// Extensions for DICCommand for easier calling
/// </summary>
public static class DICCommandExtensions
{
public static string Name(this DICCommand command)
{
return Converters.DICCommandToString(command);
}
}
/// <summary>
/// Extensions for DICFlag for easier calling
/// </summary>
public static class DICFlagExtensions
{
public static string Name(this DICFlag command)
{
return Converters.DICFlagToString(command);
}
}
/// <summary>
/// Extensions for MediaType? for easier calling
/// </summary>
public static class MediaTypeExtensions
{
public static string Name(this MediaType? type)
{
return Converters.MediaTypeToString(type);
}
public static string ShortName(this MediaType? type)
{
return Converters.MediaTypeToShortString(type);
}
public static string Extension(this MediaType? type)
{
return Converters.MediaTypeToExtension(type);
}
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.NintendoGameCube:
case MediaType.NintendoWiiOpticalDisc:
return true;
default:
return false;
}
}
}
/// <summary>
/// Extensions for KnownSystem? for easier calling
/// </summary>
public static class KnownSystemExtensions
{
public static string Name(this KnownSystem? system)
{
return Converters.KnownSystemToString(system);
}
public static string ShortName(this KnownSystem? system)
{
return Converters.KnownSystemToShortString(system);
}
public static KnownSystemCategory Category(this KnownSystem? system)
{
if (system < KnownSystem.MarkerConsoleEnd)
return KnownSystemCategory.Console;
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.MarkerConsoleEnd:
case KnownSystem.MarkerOtherEnd:
return true;
default:
return false;
}
}
}
/// <summary>
/// Extensions for KnownSystemCategory?
/// </summary>
public static class KnownSystemCategoryExtensions
{
/// <summary>
/// Get the string representation of a KnownSystemCategory
/// </summary>
public static string Name(this KnownSystemCategory? category)
{
switch (category)
{
case KnownSystemCategory.Arcade:
return "Arcade";
case KnownSystemCategory.Computer:
return "Computers";
case KnownSystemCategory.Console:
return "Consoles";
case KnownSystemCategory.Other:
return "Other";
case KnownSystemCategory.Custom:
return "Custom";
default:
return "";
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,27 +0,0 @@
namespace DICUI.Utilities
{
/// <summary>
/// Generic success/failure result object, with optional message
/// </summary>
public class Result
{
private bool success;
public string Message { get; private set; }
private Result(bool success, string message)
{
this.success = success;
this.Message = message;
}
public static Result Success() => new Result(true, "");
public static Result Success(string message) => new Result(true, message);
public static Result Success(string message, params object[] args) => new Result(true, string.Format(message, args));
public static Result Failure() => new Result(false, "");
public static Result Failure(string message) => new Result(false, message);
public static Result Failure(string message, params object[] args) => new Result(false, string.Format(message, args));
public static implicit operator bool(Result result) => result.success;
}
}

View File

@@ -1,585 +0,0 @@
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
case KnownSystem.AtariJaguarCD:
types.Add(MediaType.CDROM);
break;
case KnownSystem.BandaiPlaydiaQuickInteractiveSystem:
types.Add(MediaType.CDROM);
break;
case KnownSystem.BandaiApplePippin:
types.Add(MediaType.CDROM);
break;
case KnownSystem.CommodoreAmigaCD32:
types.Add(MediaType.CDROM);
break;
case KnownSystem.CommodoreAmigaCDTV:
types.Add(MediaType.CDROM);
break;
case KnownSystem.MattelHyperscan:
types.Add(MediaType.CDROM);
break;
case KnownSystem.MicrosoftXBOX:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
case KnownSystem.MicrosoftXBOX360:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
case KnownSystem.MicrosoftXBOXOne:
types.Add(MediaType.BluRay);
break;
case KnownSystem.NECPCEngineTurboGrafxCD:
types.Add(MediaType.CDROM);
break;
case KnownSystem.NECPCFX:
types.Add(MediaType.CDROM);
break;
case KnownSystem.NintendoGameCube:
types.Add(MediaType.NintendoGameCube);
break;
case KnownSystem.NintendoWii:
types.Add(MediaType.NintendoWiiOpticalDisc);
break;
case KnownSystem.NintendoWiiU:
types.Add(MediaType.NintendoWiiUOpticalDisc);
break;
case KnownSystem.Panasonic3DOInteractiveMultiplayer:
types.Add(MediaType.CDROM);
break;
case KnownSystem.PhilipsCDi:
types.Add(MediaType.CDROM);
break;
case KnownSystem.SegaCDMegaCD:
types.Add(MediaType.CDROM);
break;
case KnownSystem.SegaDreamcast:
types.Add(MediaType.CDROM); // Low density partition
types.Add(MediaType.GDROM); // Hight density partition
break;
case KnownSystem.SegaSaturn:
types.Add(MediaType.CDROM);
break;
case KnownSystem.SNKNeoGeoCD:
types.Add(MediaType.CDROM);
break;
case KnownSystem.SonyPlayStation:
types.Add(MediaType.CDROM);
break;
case KnownSystem.SonyPlayStation2:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
case KnownSystem.SonyPlayStation3:
types.Add(MediaType.BluRay);
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
case KnownSystem.SonyPlayStation4:
types.Add(MediaType.BluRay);
break;
case KnownSystem.SonyPlayStationPortable:
types.Add(MediaType.UMD);
types.Add(MediaType.DVD); // TODO: Confirm this
break;
case KnownSystem.VMLabsNuon:
types.Add(MediaType.DVD);
break;
case KnownSystem.VTechVFlashVSmilePro:
types.Add(MediaType.CDROM);
break;
case KnownSystem.ZAPiTGamesGameWaveFamilyEntertainmentSystem:
types.Add(MediaType.DVD);
break;
#endregion
#region Computers
case KnownSystem.AcornArchimedes:
types.Add(MediaType.CDROM);
break;
case KnownSystem.AppleMacintosh:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
types.Add(MediaType.FloppyDisk);
break;
case KnownSystem.CommodoreAmigaCD:
types.Add(MediaType.CDROM);
break;
case KnownSystem.FujitsuFMTowns:
types.Add(MediaType.CDROM);
break;
case KnownSystem.IBMPCCompatible:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
types.Add(MediaType.FloppyDisk);
break;
case KnownSystem.NECPC88:
types.Add(MediaType.CDROM);
break;
case KnownSystem.NECPC98:
types.Add(MediaType.CDROM);
break;
case KnownSystem.SharpX68000:
types.Add(MediaType.CDROM);
break;
#endregion
#region Arcade
case KnownSystem.AmigaCUBOCD32:
types.Add(MediaType.CDROM);
break;
case KnownSystem.AmericanLaserGames3DO:
types.Add(MediaType.CDROM);
break;
case KnownSystem.Atari3DO:
types.Add(MediaType.CDROM);
break;
case KnownSystem.Atronic:
types.Add(MediaType.CDROM);
break;
case KnownSystem.AUSCOMSystem1:
types.Add(MediaType.CDROM);
break;
case KnownSystem.BallyGameMagic:
types.Add(MediaType.CDROM);
break;
case KnownSystem.CapcomCPSystemIII:
types.Add(MediaType.CDROM);
break;
case KnownSystem.GlobalVRVarious:
types.Add(MediaType.CDROM);
break;
case KnownSystem.GlobalVRVortek:
types.Add(MediaType.CDROM);
break;
case KnownSystem.GlobalVRVortekV3:
types.Add(MediaType.DVD); // TODO: Confirm
break;
case KnownSystem.ICEPCHardware:
types.Add(MediaType.DVD);
break;
case KnownSystem.IncredibleTechnologiesEagle:
types.Add(MediaType.CDROM);
break;
case KnownSystem.IncredibleTechnologiesVarious:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
case KnownSystem.KonamieAmusement:
types.Add(MediaType.CDROM);
break;
case KnownSystem.KonamiFirebeat:
types.Add(MediaType.CDROM);
break;
case KnownSystem.KonamiGVSystem:
types.Add(MediaType.CDROM);
break;
case KnownSystem.KonamiM2:
types.Add(MediaType.CDROM);
break;
case KnownSystem.KonamiPython:
types.Add(MediaType.DVD); // TODO: Confirm
break;
case KnownSystem.KonamiPython2:
types.Add(MediaType.DVD); // TODO: Confirm
break;
case KnownSystem.KonamiSystem573:
types.Add(MediaType.CDROM);
break;
case KnownSystem.KonamiTwinkle:
types.Add(MediaType.CDROM);
break;
case KnownSystem.KonamiVarious:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
case KnownSystem.MeritIndustriesBoardwalk:
types.Add(MediaType.CDROM); // TODO: Confirm
break;
case KnownSystem.MeritIndustriesMegaTouchAurora:
types.Add(MediaType.CDROM); // TODO: Confirm
break;
case KnownSystem.MeritIndustriesMegaTouchForce:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
case KnownSystem.MeritIndustriesMegaTouchION:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
case KnownSystem.MeritIndustriesMegaTouchMaxx:
types.Add(MediaType.DVD);
break;
case KnownSystem.MeritIndustriesMegaTouchXL:
types.Add(MediaType.CDROM);
break;
case KnownSystem.NamcoCapcomSystem256:
types.Add(MediaType.DVD);
break;
case KnownSystem.NamcoCapcomTaitoSystem246:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
case KnownSystem.NamcoSegaNintendoTriforce:
types.Add(MediaType.GDROM);
break;
case KnownSystem.NamcoSystem12:
types.Add(MediaType.CDROM);
break;
case KnownSystem.NamcoSystem357:
types.Add(MediaType.DVD);
types.Add(MediaType.BluRay);
break;
case KnownSystem.NewJatreCDi:
types.Add(MediaType.CDROM);
break;
case KnownSystem.NichibutsuHighRateSystem:
types.Add(MediaType.CDROM);
break;
case KnownSystem.NichibutsuSuperCD:
types.Add(MediaType.CDROM);
break;
case KnownSystem.NichibutsuXRateSystem:
types.Add(MediaType.DVD);
break;
case KnownSystem.PanasonicM2:
types.Add(MediaType.CDROM);
types.Add(MediaType.DVD);
break;
case KnownSystem.PhotoPlayVarious:
types.Add(MediaType.CDROM);
break;
case KnownSystem.RawThrillsVarious:
types.Add(MediaType.DVD);
break;
case KnownSystem.SegaChihiro:
types.Add(MediaType.GDROM);
break;
case KnownSystem.SegaEuropaR:
types.Add(MediaType.DVD); // TODO: Confirm
break;
case KnownSystem.SegaLindbergh:
types.Add(MediaType.DVD);
break;
case KnownSystem.SegaNaomi:
types.Add(MediaType.GDROM);
break;
case KnownSystem.SegaNaomi2:
types.Add(MediaType.GDROM);
break;
case KnownSystem.SegaNu:
types.Add(MediaType.DVD);
types.Add(MediaType.BluRay);
break;
case KnownSystem.SegaRingEdge:
types.Add(MediaType.DVD);
break;
case KnownSystem.SegaRingEdge2:
types.Add(MediaType.DVD);
break;
case KnownSystem.SegaRingWide:
types.Add(MediaType.DVD);
break;
case KnownSystem.SegaTitanVideo:
types.Add(MediaType.CDROM);
break;
case KnownSystem.SegaSystem32:
types.Add(MediaType.CDROM);
break;
case KnownSystem.SeibuCATSSystem:
types.Add(MediaType.DVD);
break;
case KnownSystem.TABAustriaQuizard:
types.Add(MediaType.CDROM);
break;
case KnownSystem.TandyMemorexVisualInformationSystem:
types.Add(MediaType.CDROM);
break;
case KnownSystem.TsunamiTsuMoMultiGameMotionSystem:
types.Add(MediaType.CDROM);
break;
#endregion
#region Others
case KnownSystem.AudioCD:
types.Add(MediaType.CDROM);
break;
case KnownSystem.BDVideo:
types.Add(MediaType.BluRay);
break;
case KnownSystem.DVDVideo:
types.Add(MediaType.DVD);
break;
case KnownSystem.EnhancedCD:
types.Add(MediaType.CDROM);
break;
case KnownSystem.EnhancedDVD:
types.Add(MediaType.DVD);
break;
case KnownSystem.EnhancedBD:
types.Add(MediaType.BluRay);
break;
case KnownSystem.HasbroVideoNow:
types.Add(MediaType.CDROM);
break;
case KnownSystem.HDDVDVideo:
types.Add(MediaType.HDDVD);
break;
case KnownSystem.PalmOS:
types.Add(MediaType.CDROM);
break;
case KnownSystem.PhilipsCDiDigitalVideo:
types.Add(MediaType.CDROM);
break;
case KnownSystem.PhotoCD:
types.Add(MediaType.CDROM);
break;
case KnownSystem.PlayStationGameSharkUpdates:
types.Add(MediaType.CDROM);
break;
case KnownSystem.RainbowDisc:
types.Add(MediaType.CDROM);
break;
case KnownSystem.TaoiKTV:
types.Add(MediaType.CDROM);
break;
case KnownSystem.TomyKissSite:
types.Add(MediaType.CDROM);
break;
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()
{
var drives = new List<Drive>();
// Get the floppy drives
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.Add(Drive.Floppy(devId));
}
}
}
catch
{
// No-op
}
// Get the optical disc drives
List<Drive> discDrives = DriveInfo.GetDrives()
.Where(d => d.DriveType == DriveType.CDRom)
.Select(d => Drive.Optical(d.Name[0], (d.IsReady ? d.VolumeLabel : Template.DiscNotDetected), d.IsReady))
.ToList();
// Add the two lists together and order
drives.AddRange(discDrives);
drives = drives.OrderBy(i => i.Letter).ToList();
return drives;
}
/// <summary>
/// Get the current disc type from drive letter
/// </summary>
/// <param name="driveLetter"></param>
/// <returns></returns>
/// <remarks>
/// https://stackoverflow.com/questions/11420365/detecting-if-disc-is-in-dvd-drive
/// </remarks>
public static MediaType? GetDiscType(char? driveLetter)
{
// Get the DeviceID from the current drive letter
string deviceId = null;
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT * FROM Win32_CDROMDrive WHERE Id = '" + driveLetter + ":\'");
var collection = searcher.Get();
foreach (ManagementObject queryObj in collection)
deviceId = (string)queryObj["DeviceID"];
}
catch
{
// We don't care what the error was
return null;
}
// If we got no valid device, we don't care and just return
if (deviceId == null)
return null;
// Get all relevant disc information
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.IMAPIDiskTypeToMediaType(media);
}
catch
{
// We don't care what the error is
}
return null;
}
/// <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.HDDVD:
return Result.Success("{0} ready to dump", type.Name());
// Partially supported types
case MediaType.GDROM:
case MediaType.NintendoGameCube:
case MediaType.NintendoWiiOpticalDisc:
return Result.Success("{0} partially supported for dumping", type.Name());
// Special case for other supported tools
case MediaType.UMD:
return Result.Success("{0} supported for submission info parsing", type.Name());
// Specifically unknown type
case MediaType.NONE:
return Result.Failure("Please select a valid disc type");
// Undumpable but recognized types
default:
return Result.Failure("{0} discs are not supported for dumping", type.Name());
}
}
/// <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
{
return "Disc could not be scanned!";
}
}
}
}

Binary file not shown.

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="BurnOutSharp" version="1.3.7.1" targetFramework="net461" />
<package id="LessIO" version="0.5.0" targetFramework="net461" />
<package id="libmspack4n" version="0.8.0" targetFramework="net461" />
<package id="UnshieldSharp" version="1.4.2.2" targetFramework="net461" />
<package id="zlib.net" version="1.0.4.0" targetFramework="net461" />
</packages>

View File

@@ -1,111 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.props" Condition="Exists('..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.props')" />
<Import Project="..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.props" Condition="Exists('..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.props')" />
<Import Project="..\packages\xunit.runner.visualstudio.2.3.1\build\net20\xunit.runner.visualstudio.props" Condition="Exists('..\packages\xunit.runner.visualstudio.2.3.1\build\net20\xunit.runner.visualstudio.props')" />
<Import Project="..\packages\xunit.runner.console.2.3.1\build\xunit.runner.console.props" Condition="Exists('..\packages\xunit.runner.console.2.3.1\build\xunit.runner.console.props')" />
<Import Project="..\packages\xunit.core.2.3.1\build\xunit.core.props" Condition="Exists('..\packages\xunit.core.2.3.1\build\xunit.core.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7CC064D2-38AB-4A05-8519-28660DE4562A}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>DICUI.Test</RootNamespace>
<AssemblyName>DICUI.Test</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<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' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.CodeCoverage.Shim, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.CodeCoverage.15.8.0\lib\net45\Microsoft.VisualStudio.CodeCoverage.Shim.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll</HintPath>
</Reference>
<Reference Include="xunit.assert, Version=2.3.1.3858, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll</HintPath>
</Reference>
<Reference Include="xunit.core, Version=2.3.1.3858, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll</HintPath>
</Reference>
<Reference Include="xunit.execution.desktop, Version=2.3.1.3858, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c, processorArchitecture=MSIL">
<HintPath>..\packages\xunit.extensibility.execution.2.3.1\lib\net452\xunit.execution.desktop.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="UI\AllowedSpeedsTest.cs" />
<Compile Include="Utilities\DICFlagExtensionsTest.cs" />
<Compile Include="Utilities\DumpEnvironmentTest.cs" />
<Compile Include="ResultTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utilities\DriveTest.cs" />
<Compile Include="Utilities\ConvertersTest.cs" />
<Compile Include="Utilities\DICCommandExtensionsTest.cs" />
<Compile Include="Utilities\KnownSystemExtensionsTest.cs" />
<Compile Include="Utilities\MediaTypeExtensionsTest.cs" />
<Compile Include="Utilities\ParametersTest.cs" />
<Compile Include="Utilities\ValidatorsTest.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\xunit.analyzers.0.10.0\analyzers\dotnet\cs\xunit.analyzers.dll" />
</ItemGroup>
<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>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\xunit.core.2.3.1\build\xunit.core.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.core.2.3.1\build\xunit.core.props'))" />
<Error Condition="!Exists('..\packages\xunit.core.2.3.1\build\xunit.core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.core.2.3.1\build\xunit.core.targets'))" />
<Error Condition="!Exists('..\packages\xunit.runner.console.2.3.1\build\xunit.runner.console.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.runner.console.2.3.1\build\xunit.runner.console.props'))" />
<Error Condition="!Exists('..\packages\xunit.runner.visualstudio.2.3.1\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\xunit.runner.visualstudio.2.3.1\build\net20\xunit.runner.visualstudio.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.targets'))" />
</Target>
<Import Project="..\packages\xunit.core.2.3.1\build\xunit.core.targets" Condition="Exists('..\packages\xunit.core.2.3.1\build\xunit.core.targets')" />
<Import Project="..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.targets" Condition="Exists('..\packages\Microsoft.CodeCoverage.15.8.0\build\netstandard1.0\Microsoft.CodeCoverage.targets')" />
<Import Project="..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.targets" Condition="Exists('..\packages\Microsoft.NET.Test.Sdk.15.8.0\build\net45\Microsoft.Net.Test.Sdk.targets')" />
</Project>

View File

@@ -1,20 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("DICUI.Test")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DICUI.Test")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("7cc064d2-38ab-4a05-8519-28660de4562a")]
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,40 +0,0 @@
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

@@ -1,126 +0,0 @@
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.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 = Converters.BaseCommmandToMediaType(command);
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.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.BaseCommandToKnownSystem(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.MediaTypeToExtension(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.MediaTypeToString(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.KnownSystemToString(knownSystem);
Assert.Equal(expected, actual);
}
[Fact]
public void KnownSystemHasValidCategory()
{
var values = Validators.CreateListOfSystems();
KnownSystem[] markers = { KnownSystem.MarkerArcadeEnd, KnownSystem.MarkerConsoleEnd, 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.Console: marker = KnownSystem.MarkerConsoleEnd; 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

@@ -1,23 +0,0 @@
using System;
using DICUI.Data;
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test.Utilities
{
public class DICCommandExtensionsTest
{
[Fact]
public void NameTest()
{
var values = (DICCommand[])Enum.GetValues(typeof(DICCommand));
foreach(var command in values)
{
string expected = Converters.DICCommandToString(command);
string actual = command.Name();
Assert.Equal(expected, actual);
}
}
}
}

View File

@@ -1,23 +0,0 @@
using System;
using DICUI.Data;
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test.Utilities
{
public class DICFlagExtensionsTest
{
[Fact]
public void NameTest()
{
var values = (DICFlag[])Enum.GetValues(typeof(DICFlag));
foreach(var command in values)
{
string expected = Converters.DICFlagToString(command);
string actual = command.Name();
Assert.Equal(expected, actual);
}
}
}
}

View File

@@ -1,15 +0,0 @@
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test.Utilities
{
public class DriveTest
{
[Fact]
public void DriveConstructorsTest()
{
Assert.True(Drive.Floppy('a').IsFloppy);
Assert.False(Drive.Optical('d', "test", true).IsFloppy);
}
}
}

View File

@@ -1,126 +0,0 @@
using System;
using System.Linq;
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 ? Drive.Floppy(letter) : Drive.Optical(letter, "", true),
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);
}
[Theory]
[InlineData(MediaType.CDROM)]
[InlineData(MediaType.DVD)]
[InlineData(MediaType.FloppyDisk)]
[InlineData(MediaType.LaserDisc)]
public void FoundAllFilesTest(MediaType? mediaType)
{
// TODO: Implement
// TODO: Get sample output data for each of the major types
Assert.True(true);
}
[Theory]
[InlineData(KnownSystem.AppleMacintosh, MediaType.CDROM)]
[InlineData(KnownSystem.PhilipsCDi, MediaType.CDROM)]
[InlineData(KnownSystem.SegaSaturn, MediaType.CDROM)]
[InlineData(KnownSystem.SonyPlayStation, MediaType.CDROM)]
[InlineData(KnownSystem.SonyPlayStation2, MediaType.CDROM)]
[InlineData(KnownSystem.AppleMacintosh, MediaType.DVD)]
[InlineData(KnownSystem.DVDVideo, MediaType.DVD)]
[InlineData(KnownSystem.MicrosoftXBOX, MediaType.DVD)]
[InlineData(KnownSystem.SonyPlayStation2, MediaType.DVD)]
[InlineData(KnownSystem.BDVideo, MediaType.BluRay)]
[InlineData(KnownSystem.AUSCOMSystem1, MediaType.Cassette)]
public void ExtractOutputInformation(KnownSystem? knownSystem, MediaType? mediaType)
{
// TODO: Implement
// TODO: Get sample output data for each of the major types
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

@@ -1,49 +0,0 @@
using System;
using DICUI.Data;
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test.Utilities
{
public class KnownSystemExtensionsTest
{
[Fact]
public void NameTest()
{
var values = (KnownSystem[])Enum.GetValues(typeof(KnownSystem));
foreach(var system in values)
{
string expected = Converters.KnownSystemToString(system);
string actual = ((KnownSystem?)system).Name();
Assert.Equal(expected, actual);
}
}
[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.MarkerConsoleEnd;
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).Name();
Assert.NotEqual("", actual);
}
}
}
}

View File

@@ -1,48 +0,0 @@
using DICUI.Data;
using DICUI.Utilities;
using Xunit;
namespace DICUI.Test.Utilities
{
public class MediaTypeExtensionsTest
{
[Theory]
[InlineData(MediaType.CDROM)]
[InlineData(MediaType.LaserDisc)]
[InlineData(MediaType.NONE)]
public void NameTest(MediaType? mediaType)
{
string expected = Converters.MediaTypeToString(mediaType);
string actual = mediaType.Name();
Assert.NotNull(actual);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(MediaType.CDROM)]
[InlineData(MediaType.DVD)]
[InlineData(MediaType.LaserDisc)]
[InlineData(MediaType.FloppyDisk)]
[InlineData(MediaType.NONE)]
public void ExtensionTest(MediaType? mediaType)
{
string expected = Converters.MediaTypeToExtension(mediaType);
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

@@ -1,85 +0,0 @@
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.NintendoGameCube, 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.NintendoGameCube, 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

@@ -1,45 +0,0 @@
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.NintendoGameCube)]
[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,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.CodeCoverage" version="15.8.0" targetFramework="net461" />
<package id="Microsoft.NET.Test.Sdk" version="15.8.0" targetFramework="net461" />
<package id="xunit" version="2.3.1" targetFramework="net461" />
<package id="xunit.abstractions" version="2.0.1" targetFramework="net461" />
<package id="xunit.analyzers" version="0.10.0" targetFramework="net461" />
<package id="xunit.assert" version="2.3.1" targetFramework="net461" />
<package id="xunit.core" version="2.3.1" targetFramework="net461" />
<package id="xunit.extensibility.core" version="2.3.1" targetFramework="net461" />
<package id="xunit.extensibility.execution" version="2.3.1" targetFramework="net461" />
<package id="xunit.runner.console" version="2.3.1" targetFramework="net461" developmentDependency="true" />
<package id="xunit.runner.visualstudio" version="2.3.1" targetFramework="net461" developmentDependency="true" />
</packages>

View File

@@ -1,49 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2036
MinimumVisualStudioVersion = 10.0.40219.1
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.Forms", "DICUI.Forms\DICUI.Forms.csproj", "{A6719A99-BF0E-4637-9A8E-CB38B1E16971}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DICUI.Check", "DICUI.Check\DICUI.Check.csproj", "{8CFDE289-E171-4D49-A40D-5293265C1253}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7B1B75EB-8940-466F-BD51-76471A57F9BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{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
{A6719A99-BF0E-4637-9A8E-CB38B1E16971}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A6719A99-BF0E-4637-9A8E-CB38B1E16971}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A6719A99-BF0E-4637-9A8E-CB38B1E16971}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A6719A99-BF0E-4637-9A8E-CB38B1E16971}.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
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {73C62E6A-6584-4D93-83B5-ECB1FBDB469B}
EndGlobalSection
EndGlobal

View File

@@ -1,14 +0,0 @@
<?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="QuietMode" value="false"/>
<add key="RereadAmountForC2" value="20"/>
<add key="VerboseLogging" value="true"/>
<add key="OpenLogWindowAtStartup" value="true"/>
</appSettings>
</configuration>

View File

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

View File

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

View File

@@ -1,56 +0,0 @@
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.NintendoGameCube:
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());
}
}

View File

@@ -1,153 +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>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</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.Configuration" />
<Reference Include="System.Drawing" />
<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.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>
<Compile Include="Constants.cs" />
<Compile Include="EnumDescriptionConverter.cs" />
<Compile Include="MediaTypeComboBoxItem.cs" />
<Compile Include="Options.cs" />
<Compile Include="Windows\LogWindow.xaml.cs">
<DependentUpon>LogWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Windows\OptionsWindow.xaml.cs">
<DependentUpon>OptionsWindow.xaml</DependentUpon>
</Compile>
<Compile Include="KnownSystemComboBoxItem.cs" />
<Compile Include="ViewModels.cs" />
<Page Include="Windows\LogWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Windows\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="Windows\MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Page Include="Windows\OptionsWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
</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>
<ItemGroup>
<ProjectReference Include="..\DICUI.Library\DICUI.Library.csproj">
<Project>{51ab0928-13f9-44bf-a407-b6957a43a056}</Project>
<Name>DICUI.Library</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -1,33 +0,0 @@
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).Name();
else if (value is DICFlag)
return ((DICFlag)value).Name();
else if (value is MediaType?)
return ((MediaType?)value).Name();
else if (value is KnownSystem?)
return ((KnownSystem?)value).Name();
else
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return string.Empty;
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

View File

@@ -1,35 +0,0 @@
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?).Name() + " ----------";
else
return (data as KnownSystem?).Name();
}
}
}
}

View File

@@ -1,20 +0,0 @@
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.Name(); }
}
}
}

View File

@@ -1,97 +0,0 @@
using System;
using System.Configuration;
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 SkipMediaTypeDetection { get; set; }
public bool VerboseLogging { get; set; }
public bool OpenLogWindowAtStartup { 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()
{
//TODO: hardcoded, we should find a better way
DICPath = ConfigurationManager.AppSettings["DICPath"] ?? @"Programs\DiscImageCreator.exe";
SubDumpPath = ConfigurationManager.AppSettings["SubDumpPath"] ?? "subdump.exe";
DefaultOutputPath = ConfigurationManager.AppSettings["DefaultOutputPath"] ?? "ISO";
this.PreferredDumpSpeedCD = Int32.TryParse(ConfigurationManager.AppSettings["preferredDumpSpeedCD"], out int maxDumpSpeedCD) ? maxDumpSpeedCD : 72;
this.PreferredDumpSpeedDVD = Int32.TryParse(ConfigurationManager.AppSettings["preferredDumpSpeedDVD"], out int maxDumpSpeedDVD) ? maxDumpSpeedDVD : 24;
this.PreferredDumpSpeedBD = Int32.TryParse(ConfigurationManager.AppSettings["preferredDumpSpeedBD"], out int maxDumpSpeedBD) ? maxDumpSpeedBD : 16;
this.QuietMode = Boolean.TryParse(ConfigurationManager.AppSettings["QuietMode"], out bool quietMode) ? quietMode : false;
this.ParanoidMode = Boolean.TryParse(ConfigurationManager.AppSettings["ParanoidMode"], out bool paranoidMode) ? paranoidMode : false;
this.ScanForProtection = Boolean.TryParse(ConfigurationManager.AppSettings["ScanForProtection"], out bool scanForProtection) ? scanForProtection : true;
this.SkipMediaTypeDetection = Boolean.TryParse(ConfigurationManager.AppSettings["SkipMediaTypeDetection"], out bool skipMediaTypeDetection) ? skipMediaTypeDetection : false;
this.RereadAmountForC2 = Int32.TryParse(ConfigurationManager.AppSettings["RereadAmountForC2"], out int rereadAmountForC2) ? rereadAmountForC2 : 20;
this.VerboseLogging = Boolean.TryParse(ConfigurationManager.AppSettings["VerboseLogging"], out bool verboseLogging) ? verboseLogging : true;
this.OpenLogWindowAtStartup = Boolean.TryParse(ConfigurationManager.AppSettings["OpenLogWindowAtStartup"], out bool openLogWindowAtStartup) ? openLogWindowAtStartup : true;
}
//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.NintendoGameCube:
case MediaType.NintendoWiiOpticalDisc:
return PreferredDumpSpeedDVD;
case MediaType.BluRay:
return PreferredDumpSpeedBD;
default:
return 8;
}
}
}
}

View File

@@ -1,58 +0,0 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
// 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")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DICUI")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[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)]
//In order to begin building localizable applications, set
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
//inside a <PropertyGroup>. For example, if you are using US english
//in your source files, set the <UICulture> to en-US. Then uncomment
//the NeutralResourceLanguage attribute below. Update the "en-US" in
//the line below to match the UICulture setting in the project file.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
// 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.11")]
[assembly: AssemblyFileVersion("1.11.0.0")]
// Anything marked as internal can be used by the test methods
[assembly: InternalsVisibleTo("DICUI.Test")]

View File

@@ -1,107 +0,0 @@
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 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

@@ -1,54 +0,0 @@
<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

@@ -1,385 +0,0 @@
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

@@ -1,130 +0,0 @@
<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

@@ -1,721 +0,0 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
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<KnownSystem?> _systems;
private List<MediaType?> _mediaTypes;
private bool _alreadyShown;
private DumpEnvironment _env;
// Option related
private Options _options;
private OptionsWindow _optionsWindow;
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();
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();
EnsureDiscInformation();
}
private void DriveLetterComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
CacheCurrentDiscType();
SetCurrentDiscType();
GetOutputNames();
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();
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()
{
_systems = Validators.CreateListOfSystems();
ViewModels.LoggerViewModel.VerboseLogLn("Populating systems, {0} systems found.", _systems.Count);
Dictionary<KnownSystemCategory, List<KnownSystem?>> mapping = _systems
.GroupBy(s => s.Category())
.ToDictionary(
k => k.Key,
v => v
.OrderBy(s => s.Name())
.ToList()
);
List<KnownSystemComboBoxItem> comboBoxItems = new List<KnownSystemComboBoxItem>();
comboBoxItems.Add(new KnownSystemComboBoxItem(KnownSystem.NONE));
foreach (var group in mapping)
{
comboBoxItems.Add(new KnownSystemComboBoxItem(group.Key));
group.Value.ForEach(system => comboBoxItems.Add(new KnownSystemComboBoxItem(system)));
}
SystemTypeComboBox.ItemsSource = comboBoxItems;
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)
{
int index = _drives.FindIndex(d => d.MarkedActive);
DriveLetterComboBox.SelectedIndex = (index != -1 ? index : 0);
StatusLabel.Content = "Valid drive found! Choose your Media Type";
StartStopButton.IsEnabled = true;
CopyProtectScanButton.IsEnabled = true;
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,
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);
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>
private void GetOutputNames()
{
Drive drive = DriveLetterComboBox.SelectedItem as Drive;
KnownSystem? systemType = SystemTypeComboBox.SelectedItem as KnownSystemComboBoxItem;
MediaType? mediaType = MediaTypeComboBox.SelectedItem as MediaType?;
OutputDirectoryTextBox.Text = Path.Combine(_options.DefaultOutputPath, drive?.VolumeLabel ?? string.Empty);
OutputFilenameTextBox.Text = (drive?.VolumeLabel ?? "disc") + (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.NintendoGameCube:
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 || drive.IsFloppy)
return;
// Get the current optical disc type
if (!_options.SkipMediaTypeDetection)
{
ViewModels.LoggerViewModel.VerboseLog("Trying to detect media type for drive {0}.. ", drive.Letter);
_currentMediaType = Validators.GetDiscType(drive.Letter);
ViewModels.LoggerViewModel.VerboseLogLn(_currentMediaType == null ? "unable to detect." : ("detected " + _currentMediaType.Name() + "."));
}
}
/// <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.MediaTypeToString(_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 = Converters.BaseCommmandToMediaType(_env.DICParameters.Command);
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

@@ -1,142 +0,0 @@
<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="480" Width="515.132">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="150"/>
<RowDefinition Height="100"/>
<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="DicImageCreator 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 />
<RowDefinition />
</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"
/>
<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"
/>
<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="Automatically Scan for Protection"
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"
/>
<CheckBox Grid.Column="2" Grid.Row="1" Grid.ColumnSpan="2" VerticalAlignment="Center" Content="Skip Media Type Detection"
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)"
/>
</Grid>
</GroupBox>
<Grid Height="22" Grid.Row="3" 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

@@ -1,132 +0,0 @@
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;
}
#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.Save();
Hide();
_mainWindow.OnOptionsUpdated();
}
private void OnCancelClick(object sender, EventArgs e)
{
// just hide the window and don't care
Hide();
}
#endregion
}
}

View File

@@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
DICUI Copyright (C) 2018 ReignStumble
MPF Copyright (C) 2018 ReignStumble
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.

View File

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

View File

@@ -0,0 +1,52 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net48;netcoreapp3.1;net5.0</TargetFrameworks>
<PlatformTarget>x86</PlatformTarget>
<OutputType>Exe</OutputType>
<Title>MPF Check</Title>
<AssemblyName>MPF.Check</AssemblyName>
<Description>Validator for various dumping programs</Description>
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
<Copyright>Copyright (c)2019-2021</Copyright>
<RepositoryUrl>https://github.com/SabreTools/MPF</RepositoryUrl>
<Version>2.2</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<FileVersion>$(Version)</FileVersion>
<IncludeSource>true</IncludeSource>
<IncludeSymbols>true</IncludeSymbols>
</PropertyGroup>
<PropertyGroup>
<NrtRevisionFormat>$(Version)-{chash:8}</NrtRevisionFormat>
<NrtResolveSimpleAttributes>true</NrtResolveSimpleAttributes>
<NrtShowRevision>false</NrtShowRevision>
</PropertyGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BurnOutSharp" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="1.8.0" GeneratePathProperty="true">
<IncludeAssets>runtime; compile; build; native; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Content Include="$(PkgBurnOutSharp)\content\**" PackagePath="contentFiles\any\any;content" CopyToOutputDirectory="Always" PackageCopyToOutput="true" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MPF.Library\MPF.Library.csproj">
<Project>{51ab0928-13f9-44bf-a407-b6957a43a056}</Project>
<Name>MPF.Library</Name>
</ProjectReference>
<ProjectReference Include="..\RedumpLib\RedumpLib.csproj" />
</ItemGroup>
</Project>

290
MPF.Check/Program.cs Normal file
View File

@@ -0,0 +1,290 @@
using System;
using System.IO;
using System.Linq;
using BurnOutSharp;
using MPF.Core.Converters;
using MPF.Core.Data;
using MPF.Core.Utilities;
using MPF.Library;
using RedumpLib.Data;
using RedumpLib.Web;
namespace MPF.Check
{
public class Program
{
public static void Main(string[] args)
{
// Help options
if (args.Length == 0 || args[0] == "-h" || args[0] == "-?")
{
DisplayHelp();
return;
}
// List options
if (args[0] == "-lm" || args[0] == "--listmedia")
{
ListMediaTypes();
Console.ReadLine();
return;
}
else if (args[0] == "-lp" || args[0] == "--listprograms")
{
ListPrograms();
Console.ReadLine();
return;
}
else if (args[0] == "-ls" || args[0] == "--listsystems")
{
ListSystems();
Console.ReadLine();
return;
}
// Normal operation check
if (args.Length < 3)
{
DisplayHelp("Invalid number of arguments");
return;
}
// Check the MediaType
var mediaType = EnumConverter.ToMediaType(args[0].Trim('"'));
if (mediaType == MediaType.NONE)
{
DisplayHelp($"{args[0]} is not a recognized media type");
return;
}
// Check the RedumpSystem
var knownSystem = Extensions.ToRedumpSystem(args[1].Trim('"'));
if (knownSystem == null)
{
DisplayHelp($"{args[1]} is not a recognized system");
return;
}
// Default values
string username = null, password = null;
string internalProgram = "DiscImageCreator";
string path = string.Empty;
bool scan = false, compress = false, json = false;
// Loop through and process options
int startIndex = 2;
for (; startIndex < args.Length; startIndex++)
{
// Redump login
if (args[startIndex].StartsWith("-c=") || args[startIndex].StartsWith("--credentials="))
{
string[] credentials = args[startIndex].Split('=')[1].Split(';');
username = credentials[0];
password = credentials[1];
}
else if (args[startIndex] == "-c" || args[startIndex] == "--credentials")
{
username = args[startIndex + 1];
password = args[startIndex + 2];
startIndex += 2;
}
// Use specific program
else if (args[startIndex].StartsWith("-u=") || args[startIndex].StartsWith("--use="))
{
internalProgram = args[startIndex].Split('=')[1];
}
else if (args[startIndex] == "-u" || args[startIndex] == "--use")
{
internalProgram = args[startIndex + 1];
startIndex++;
}
// Use a device path for physical checks
else if (args[startIndex].StartsWith("-p=") || args[startIndex].StartsWith("--path="))
{
path = args[startIndex].Split('=')[1];
}
else if (args[startIndex] == "-p" || args[startIndex] == "--path")
{
path = args[startIndex + 1];
startIndex++;
}
// Scan for protection (requires device path)
else if (args[startIndex].Equals("-s") || args[startIndex].Equals("--scan"))
{
scan = true;
}
// Output submission JSON
else if (args[startIndex].Equals("-j") || args[startIndex].Equals("--json"))
{
json = true;
}
// Compress log and extraneous files
else if (args[startIndex].Equals("-z") || args[startIndex].Equals("--zip"))
{
compress = true;
}
// Default, we fall out
else
{
break;
}
}
// Make new Progress objects
var resultProgress = new Progress<Result>();
resultProgress.ProgressChanged += ProgressUpdated;
var protectionProgress = new Progress<ProtectionProgress>();
protectionProgress.ProgressChanged += ProgressUpdated;
// If credentials are invalid, alert the user
if (!string.IsNullOrWhiteSpace(username) && !string.IsNullOrWhiteSpace(password))
{
using (RedumpWebClient wc = new RedumpWebClient())
{
bool? loggedIn = wc.Login(username, password);
if (loggedIn == true)
Console.WriteLine("Redump username and password accepted!");
else if (loggedIn == false)
Console.WriteLine("Redump username and password denied!");
else
Console.WriteLine("An error occurred validating your crendentials!");
}
}
// 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].Trim('"')))
{
DisplayHelp($"{args[i].Trim('"')} does not exist");
return;
}
// Get the full file path
string filepath = Path.GetFullPath(args[i].Trim('"'));
// Now populate an environment
var options = new Options
{
InternalProgram = EnumConverter.ToInternalProgram(internalProgram),
ScanForProtection = scan && !string.IsNullOrWhiteSpace(path),
PromptForDiscInformation = false,
ShowDiscEjectReminder = false,
OutputSubmissionJSON = json,
CompressLogFiles = compress,
RedumpUsername = username,
RedumpPassword = password,
};
Drive drive = null;
if (!string.IsNullOrWhiteSpace(path))
drive = new Drive(null, new DriveInfo(path));
var env = new DumpEnvironment(options, "", filepath, drive, knownSystem, mediaType, null);
// Finally, attempt to do the output dance
var result = env.VerifyAndSaveDumpOutput(resultProgress, protectionProgress).ConfigureAwait(false).GetAwaiter().GetResult();
Console.WriteLine(result.Message);
}
}
/// <summary>
/// Display help for MPF.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("MPF.Check.exe <mediatype> <system> [options] </path/to/output.cue/iso> ...");
Console.WriteLine();
Console.WriteLine("Standalone Options:");
Console.WriteLine("-h, -? Show this help text");
Console.WriteLine("-lm, --listmedia List supported media types");
Console.WriteLine("-ls, --listsystems List supported system types");
Console.WriteLine("-lp, --listprograms List supported dumping program outputs");
Console.WriteLine();
Console.WriteLine("Check Options:");
Console.WriteLine("-c, --credentials <user> <pw> Redump username and password");
Console.WriteLine("-u, --use <program> Dumping program output type");
Console.WriteLine("-p, --path <drivepath> Physical drive path for additional checks");
Console.WriteLine("-s, --scan Enable copy protection scan (requires --path)");
Console.WriteLine("-j, --json Enable submission JSON output");
Console.WriteLine("-z, --zip Enable log file compression");
Console.WriteLine();
}
/// <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 programs with their short usable names
/// </summary>
private static void ListPrograms()
{
Console.WriteLine("Supported Programs:");
foreach (var val in Enum.GetValues(typeof(InternalProgram)))
{
if (((InternalProgram)val) == InternalProgram.NONE)
continue;
Console.WriteLine($"{((InternalProgram?)val).LongName()}");
}
}
/// <summary>
/// List all systems with their short usable names
/// </summary>
private static void ListSystems()
{
Console.WriteLine("Supported Known Systems:");
var knownSystems = Enum.GetValues(typeof(RedumpSystem))
.OfType<RedumpSystem?>()
.Where(s => s != null && !s.IsMarker() && s.GetCategory() != SystemCategory.NONE)
.OrderBy(s => s.LongName() ?? string.Empty);
foreach (var val in knownSystems)
{
Console.WriteLine($"{val.ShortName()} - {val.LongName()}");
}
}
/// <summary>
/// Simple process counter to write to console
/// </summary>
private static void ProgressUpdated(object sender, Result value)
{
Console.WriteLine(value.Message);
}
/// <summary>
/// Simple process counter to write to console
/// </summary>
private static void ProgressUpdated(object sender, ProtectionProgress value)
{
Console.WriteLine($"{value.Percentage * 100:N2}%: {value.Filename} - {value.Protection}");
}
}
}

View File

@@ -0,0 +1,7 @@
{
"profiles": {
"MPF.Check": {
"commandName": "Project"
}
}
}

4
MPF.Core/AssemblyInfo.cs Normal file
View File

@@ -0,0 +1,4 @@
using System.Runtime.CompilerServices;
// Anything marked as internal can be used by the test methods
[assembly: InternalsVisibleTo("MPF.Test")]

View File

@@ -0,0 +1,381 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using System.Reflection;
#if NET_FRAMEWORK
using IMAPI2;
#endif
using MPF.Core.Data;
using RedumpLib.Data;
namespace MPF.Core.Converters
{
public static class EnumConverter
{
#region Cross-enumeration conversions
/// <summary>
/// Convert drive type to internal version, if possible
/// </summary>
/// <param name="driveType">DriveType value to check</param>
/// <returns>InternalDriveType, if possible, null on error</returns>
public static InternalDriveType? ToInternalDriveType(this DriveType driveType)
{
switch (driveType)
{
case DriveType.CDRom:
return InternalDriveType.Optical;
case DriveType.Fixed:
return InternalDriveType.HardDisk;
case DriveType.Removable:
return InternalDriveType.Removable;
default:
return null;
}
}
#if NET_FRAMEWORK
/// <summary>
/// Convert IMAPI physical media type to a MediaType
/// </summary>
/// <param name="type">IMAPI_MEDIA_PHYSICAL_TYPE value to check</param>
/// <returns>MediaType if possible, null on error</returns>
public static MediaType? IMAPIToMediaType(this IMAPI_MEDIA_PHYSICAL_TYPE type)
{
switch (type)
{
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_UNKNOWN:
return MediaType.NONE;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDRW:
return MediaType.CDROM;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDRAM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSRW:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSR_DUALLAYER:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHRW:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDDASHR_DUALLAYER:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DISK:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_DVDPLUSRW_DUALLAYER:
return MediaType.DVD;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_HDDVDRAM:
return MediaType.HDDVD;
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDROM:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDR:
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_BDRE:
return MediaType.BluRay;
default:
return null;
}
}
#endif
#endregion
#region Convert to Long Name
/// <summary>
/// Long name method cache
/// </summary>
private static readonly ConcurrentDictionary<Type, MethodInfo> LongNameMethods = new ConcurrentDictionary<Type, MethodInfo>();
/// <summary>
/// Get the string representation of a generic enumerable value
/// </summary>
/// <param name="value">Enum value to convert</param>
/// <returns>String representation of that value if possible, empty string on error</returns>
public static string GetLongName(Enum value)
{
try
{
var sourceType = value?.GetType();
sourceType = Nullable.GetUnderlyingType(sourceType) ?? sourceType;
if (!LongNameMethods.TryGetValue(sourceType, out MethodInfo method))
{
method = typeof(RedumpLib.Data.Extensions).GetMethod("LongName", new[] { typeof(Nullable<>).MakeGenericType(sourceType) });
if (method == null)
method = typeof(EnumConverter).GetMethod("LongName", new[] { typeof(Nullable<>).MakeGenericType(sourceType) });
LongNameMethods.TryAdd(sourceType, method);
}
if (method != null)
return method.Invoke(null, new[] { value }) as string;
else
return string.Empty;
}
catch
{
// Converter is not implemented for the given type
return string.Empty;
}
}
/// <summary>
/// Get the string representation of the InternalProgram enum values
/// </summary>
/// <param name="prog">InternalProgram value to convert</param>
/// <returns>String representing the value, if possible</returns>
public static string LongName(this InternalProgram? prog)
{
switch (prog)
{
#region Dumping support
case InternalProgram.Aaru:
return "Aaru";
case InternalProgram.DD:
return "dd";
case InternalProgram.DiscImageCreator:
return "DiscImageCreator";
#endregion
#region Verification support only
case InternalProgram.CleanRip:
return "CleanRip";
case InternalProgram.DCDumper:
return "DCDumper";
case InternalProgram.UmdImageCreator:
return "UmdImageCreator";
#endregion
case InternalProgram.NONE:
default:
return "Unknown";
}
}
#endregion
#region Convert From String
/// <summary>
/// Get the InternalProgram enum value for a given string
/// </summary>
/// <param name="internalProgram">String value to convert</param>
/// <returns>InternalProgram represented by the string, if possible</returns>
public static InternalProgram ToInternalProgram(string internalProgram)
{
switch (internalProgram.ToLowerInvariant())
{
// Dumping support
case "aaru":
case "chef":
case "dichef":
case "discimagechef":
return InternalProgram.Aaru;
case "creator":
case "dic":
case "dicreator":
case "discimagecreator":
return InternalProgram.DiscImageCreator;
case "dd":
return InternalProgram.DD;
// Verification support only
case "cleanrip":
case "cr":
return InternalProgram.CleanRip;
case "dc":
case "dcd":
case "dcdumper":
return InternalProgram.DCDumper;
case "uic":
case "umd":
case "umdcreator":
case "umdimagecreator":
return InternalProgram.UmdImageCreator;
default:
return InternalProgram.NONE;
}
}
/// <summary>
/// Get the MediaType enum value for a given string
/// </summary>
/// <param name="type">String value to convert</param>
/// <returns>MediaType represented by the string, if possible</returns>
public static MediaType ToMediaType(string type)
{
switch (type.ToLowerInvariant())
{
#region Punched Media
case "aperture":
case "aperturecard":
case "aperture card":
return MediaType.ApertureCard;
case "jacquardloom":
case "jacquardloomcard":
case "jacquard loom card":
return MediaType.JacquardLoomCard;
case "magneticstripe":
case "magneticstripecard":
case "magnetic stripe card":
return MediaType.MagneticStripeCard;
case "opticalphone":
case "opticalphonecard":
case "optical phonecard":
return MediaType.OpticalPhonecard;
case "punchcard":
case "punchedcard":
case "punched card":
return MediaType.PunchedCard;
case "punchtape":
case "punchedtape":
case "punched tape":
return MediaType.PunchedTape;
#endregion
#region Tape
case "openreel":
case "openreeltape":
case "open reel tape":
return MediaType.OpenReel;
case "datacart":
case "datacartridge":
case "datatapecartridge":
case "data tape cartridge":
return MediaType.DataCartridge;
case "cassette":
case "cassettetape":
case "cassette tape":
return MediaType.Cassette;
#endregion
#region Disc / Disc
case "bd":
case "bdrom":
case "bd-rom":
case "bluray":
return MediaType.BluRay;
case "cd":
case "cdrom":
case "cd-rom":
return MediaType.CDROM;
case "dvd":
case "dvd5":
case "dvd-5":
case "dvd9":
case "dvd-9":
case "dvdrom":
case "dvd-rom":
return MediaType.DVD;
case "fd":
case "floppy":
case "floppydisk":
case "floppy disk":
case "floppy diskette":
return MediaType.FloppyDisk;
case "floptical":
return MediaType.Floptical;
case "gd":
case "gdrom":
case "gd-rom":
return MediaType.GDROM;
case "hddvd":
case "hd-dvd":
case "hddvdrom":
case "hd-dvd-rom":
return MediaType.HDDVD;
case "hdd":
case "harddisk":
case "hard disk":
return MediaType.HardDisk;
case "bernoullidisk":
case "iomegabernoullidisk":
case "bernoulli disk":
case "iomega bernoulli disk":
return MediaType.IomegaBernoulliDisk;
case "jaz":
case "iomegajaz":
case "iomega jaz":
return MediaType.IomegaJaz;
case "zip":
case "zipdisk":
case "iomegazip":
case "iomega zip":
return MediaType.IomegaZip;
case "ldrom":
case "lvrom":
case "ld-rom":
case "lv-rom":
case "laserdisc":
case "laservision":
case "ld-rom / lv-rom":
return MediaType.LaserDisc;
case "64dd":
case "n64dd":
case "64dddisk":
case "n64dddisk":
case "64dd disk":
case "n64dd disk":
return MediaType.Nintendo64DD;
case "fds":
case "famicom":
case "nfds":
case "nintendofamicom":
case "famicomdisksystem":
case "famicom disk system":
case "famicom disk system disk":
return MediaType.NintendoFamicomDiskSystem;
case "gc":
case "gamecube":
case "nintendogamecube":
case "nintendo gamecube":
case "gamecube disc":
case "gamecube game disc":
return MediaType.NintendoGameCubeGameDisc;
case "wii":
case "nintendowii":
case "nintendo wii":
case "nintendo wii disc":
case "wii optical disc":
return MediaType.NintendoWiiOpticalDisc;
case "wiiu":
case "nintendowiiu":
case "nintendo wiiu":
case "nintendo wiiu disc":
case "wiiu optical disc":
case "wii u optical disc":
return MediaType.NintendoWiiUOpticalDisc;
case "umd":
return MediaType.UMD;
#endregion
// Unsorted Formats
case "cartridge":
return MediaType.Cartridge;
case "ced":
case "rcaced":
case "rca ced":
case "videodisc":
case "rca videodisc":
return MediaType.CED;
default:
return MediaType.NONE;
}
}
#endregion
}
}

117
MPF.Core/Data/Constants.cs Normal file
View File

@@ -0,0 +1,117 @@
using System.Collections.Generic;
using System.Linq;
using RedumpLib.Data;
namespace MPF.Core.Data
{
/// <summary>
/// Constant values for UI
/// </summary>
public static class Interface
{
// Button values
public const string StartDumping = "Start Dumping";
public const string StopDumping = "Stop Dumping";
// Byte arrays for signatures
public static readonly byte[] SaturnSectorZeroStart = new byte[] { 0x53, 0x45, 0x47, 0x41, 0x20, 0x53, 0x45, 0x47, 0x41, 0x53, 0x41, 0x54, 0x55, 0x52, 0x4E, 0x20 };
// 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; } = new List<int> { 1 };
/// <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;
}
}
}
/// <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";
public const string XBOXPFIHash = "PFI";
public const string XBOXSSHash = "SS";
public const string XBOXSSRanges = "Security Sector Ranges";
public const string XBOXSSVersion = "Security Sector Version";
public const string XBOXXeMID = "XeMID";
// 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";
}
}

448
MPF.Core/Data/Drive.cs Normal file
View File

@@ -0,0 +1,448 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management;
using MPF.Core.Converters;
using MPF.Core.Utilities;
using RedumpLib.Data;
#if NET_FRAMEWORK
using IMAPI2;
#else
using Aaru.CommonTypes.Enums;
using AaruDevices = Aaru.Devices;
#endif
namespace MPF.Core.Data
{
/// <summary>
/// Represents information for a single drive
/// </summary>
public class Drive
{
/// <summary>
/// Represents drive type
/// </summary>
public InternalDriveType? InternalDriveType { get; set; }
/// <summary>
/// Drive partition format
/// </summary>
public string DriveFormat => driveInfo?.DriveFormat;
/// <summary>
/// Windows drive letter
/// </summary>
public char Letter => driveInfo?.Name[0] ?? '\0';
/// <summary>
/// Windows drive path
/// </summary>
public string Name => driveInfo?.Name;
/// <summary>
/// Represents if Windows has marked the drive as active
/// </summary>
public bool MarkedActive => driveInfo?.IsReady ?? false;
/// <summary>
/// Media label as read by Windows
/// </summary>
/// <remarks>The try/catch is needed because Windows will throw an exception if the drive is not marked as active</remarks>
public string VolumeLabel
{
get
{
try
{
return driveInfo?.VolumeLabel;
}
catch
{
return null;
}
}
}
/// <summary>
/// Media label as read by Windows, formatted to avoid odd outputs
/// </summary>
public string FormattedVolumeLabel
{
get
{
string volumeLabel = Template.DiscNotDetected;
if (driveInfo.IsReady)
{
if (string.IsNullOrWhiteSpace(driveInfo.VolumeLabel))
volumeLabel = "track";
else
volumeLabel = driveInfo.VolumeLabel;
}
foreach (char c in Path.GetInvalidFileNameChars())
volumeLabel = volumeLabel.Replace(c, '_');
return volumeLabel;
}
}
/// <summary>
/// DriveInfo object representing the drive, if possible
/// </summary>
private readonly DriveInfo driveInfo;
public Drive(InternalDriveType? driveType, DriveInfo driveInfo)
{
this.InternalDriveType = driveType;
this.driveInfo = driveInfo;
}
/// <summary>
/// Create a list of active drives matched to their volume labels
/// </summary>
/// <param name="ignoreFixedDrives">Ture to ignore fixed drives from population, false otherwise</param>
/// <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(bool ignoreFixedDrives)
{
var desiredDriveTypes = new List<DriveType>() { DriveType.CDRom };
if (!ignoreFixedDrives)
{
desiredDriveTypes.Add(DriveType.Fixed);
desiredDriveTypes.Add(DriveType.Removable);
}
// Get all supported drive types
var drives = DriveInfo.GetDrives()
.Where(d => desiredDriveTypes.Contains(d.DriveType))
.Select(d => new Drive(EnumConverter.ToInternalDriveType(d.DriveType), d))
.ToList();
// TODO: Management searcher stuff is not supported on other platforms
// 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 = Data.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>
/// This may eventually be replaced by Aaru.Devices being able to be about 10x more accurate.
/// This will also end up making it so that IMAPI2 is no longer necessary. Unfortunately, that
/// will only work for .NET Core 3.1 and beyond.
/// </remarks>
public (MediaType?, string) GetMediaType()
{
// Take care of the non-optical stuff first
// TODO: See if any of these can be more granular, like Optical is
if (this.InternalDriveType == Data.InternalDriveType.Floppy)
return (MediaType.FloppyDisk, null);
else if (this.InternalDriveType == Data.InternalDriveType.HardDisk)
return (MediaType.HardDisk, null);
else if (this.InternalDriveType == Data.InternalDriveType.Removable)
return (MediaType.FlashDrive, null);
#if NET_FRAMEWORK
// Get the current drive information
string deviceId = null;
bool loaded = false;
try
{
// Get the device ID first
var searcher = new ManagementObjectSearcher(
"root\\CIMV2",
$"SELECT * FROM Win32_CDROMDrive WHERE Id = '{this.Letter}:\'");
foreach (ManagementObject queryObj in searcher.Get())
{
deviceId = (string)queryObj["DeviceID"];
loaded = (bool)queryObj["MediaLoaded"];
}
// If we got no valid device, we don't care and just return
if (deviceId == null)
return (null, "Device could not be found");
else if (!loaded)
return (null, "Device is not reporting media loaded");
MsftDiscMaster2 discMaster = new MsftDiscMaster2();
deviceId = deviceId.ToLower().Replace('\\', '#').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, "Device ID could not be found");
// Create the required objects for reading from the drive
MsftDiscRecorder2 recorder = new MsftDiscRecorder2();
recorder.InitializeDiscRecorder(id);
MsftDiscFormat2Data dataWriter = new MsftDiscFormat2Data();
// If the recorder is not supported, just return
if (!dataWriter.IsRecorderSupported(recorder))
return (null, "IMAPI2 recorder not supported");
// Otherwise, set the recorder to get information from
dataWriter.Recorder = recorder;
var media = dataWriter.CurrentPhysicalMediaType;
return (media.IMAPIToMediaType(), null);
}
catch (Exception ex)
{
return (null, ex.Message);
}
#else
try
{
var device = new AaruDevices.Device(this.Name);
if (device.Error)
return (null, "Could not open device");
else if (device.Type != DeviceType.ATAPI && device.Type != DeviceType.SCSI)
return (null, "Device does not support media type detection");
// TODO: In order to get the disc type, Aaru.Core will need to be included as a
// package. Unfortunately, it currently has a conflict with one of the required libraries:
// System.Text.Encoding.CodePages (BOS uses >= 5.0.0, DotNetZip uses >= 4.5.0 && < 5.0.0)
}
catch (Exception ex)
{
return (null, ex.Message);
}
return (null, "Media detection only supported on .NET Framework");
#endif
}
/// <summary>
/// Get the current system from drive
/// </summary>
/// <param name="defaultValue"></param>
/// <returns></returns>
public RedumpSystem? GetRedumpSystem(RedumpSystem? defaultValue)
{
string drivePath = $"{this.Letter}:\\";
// If we can't read the media in that drive, we can't do anything
if (!Directory.Exists(drivePath))
return defaultValue;
// We're going to assume for floppies, HDDs, and removable drives
// TODO: Try to be smarter about this
if (this.InternalDriveType != Data.InternalDriveType.Optical)
return RedumpSystem.IBMPCcompatible;
// Audio CD
if (this.FormattedVolumeLabel.Equals("Audio CD", StringComparison.OrdinalIgnoreCase))
{
return RedumpSystem.AudioCD;
}
// BD-Video
if (Directory.Exists(Path.Combine(drivePath, "BDMV")))
{
// Technically BD-Audio has this as well, but it's hard to split that out right now
return RedumpSystem.BDVideo;
}
// DVD-Audio
try
{
if (Directory.Exists(Path.Combine(drivePath, "AUDIO_TS"))
&& Directory.EnumerateFiles(Path.Combine(drivePath, "AUDIO_TS")).Any())
{
return RedumpSystem.DVDAudio;
}
}
catch { }
// DVD-Video and Xbox
try
{
if (Directory.Exists(Path.Combine(drivePath, "VIDEO_TS"))
&& Directory.EnumerateFiles(Path.Combine(drivePath, "VIDEO_TS")).Any())
{
// TODO: Maybe add video track hashes to compare for Xbox and X360?
if (this.FormattedVolumeLabel.StartsWith("SEP13011042", StringComparison.OrdinalIgnoreCase))
return RedumpSystem.MicrosoftXbox;
return RedumpSystem.DVDVideo;
}
}
catch { }
// HD-DVD-Video
try
{
if (Directory.Exists(Path.Combine(drivePath, "HVDVD_TS"))
&& Directory.EnumerateFiles(Path.Combine(drivePath, "HVDVD_TS")).Any())
{
return RedumpSystem.HDDVDVideo;
}
}
catch
{
}
// Sega Dreamcast
if (File.Exists(Path.Combine(drivePath, "IP.BIN")))
{
return RedumpSystem.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 RedumpSystem.SegaMegaCDSegaCD;
}
// Sega Saturn
try
{
byte[] sector = ReadSector(0);
if (sector != null)
{
if (sector.StartsWith(Interface.SaturnSectorZeroStart))
return RedumpSystem.SegaSaturn;
}
}
catch { }
// Sony PlayStation and Sony PlayStation 2
string psxExePath = Path.Combine(drivePath, "PSX.EXE");
string systemCnfPath = Path.Combine(drivePath, "SYSTEM.CNF");
if (File.Exists(systemCnfPath))
{
// Check for either BOOT or BOOT2
var systemCnf = new IniFile(systemCnfPath);
if (systemCnf.ContainsKey("BOOT"))
return RedumpSystem.SonyPlayStation;
else if (systemCnf.ContainsKey("BOOT2"))
return RedumpSystem.SonyPlayStation2;
}
else if (File.Exists(psxExePath))
{
return RedumpSystem.SonyPlayStation;
}
// Sony PlayStation 3
if (this.FormattedVolumeLabel.Equals("PS3VOLUME", StringComparison.OrdinalIgnoreCase))
{
return RedumpSystem.SonyPlayStation3;
}
// Sony PlayStation 4
if (this.FormattedVolumeLabel.Equals("PS4VOLUME", StringComparison.OrdinalIgnoreCase))
{
return RedumpSystem.SonyPlayStation4;
}
// Sony PlayStation 5
if (this.FormattedVolumeLabel.Equals("PS5VOLUME", StringComparison.OrdinalIgnoreCase))
{
return RedumpSystem.SonyPlayStation5;
}
// V.Tech V.Flash / V.Smile Pro
if (File.Exists(Path.Combine(drivePath, "0SYSTEM")))
{
return RedumpSystem.VTechVFlashVSmilePro;
}
// VCD
try
{
if (Directory.Exists(Path.Combine(drivePath, "VCD"))
&& Directory.EnumerateFiles(Path.Combine(drivePath, "VCD")).Any())
{
return RedumpSystem.VideoCD;
}
}
catch { }
// Default return
return defaultValue;
}
/// <summary>
/// Read a sector with a specified size from the drive
/// </summary>
/// <param name="num">Sector number, non-negative</param>
/// <param name="size">Size of a sector in bytes</param>
/// <returns>Byte array representing the sector, null on error</returns>
public byte[] ReadSector(long num, int size = 2048)
{
// Missing drive leter is not supported
if (string.IsNullOrEmpty(this.driveInfo?.Name))
return null;
// We don't support negative sectors
if (num < 0)
return null;
// Wrap the following in case of device access errors
Stream fs = null;
try
{
// Open the drive as a device
fs = File.OpenRead($"\\\\?\\{this.Letter}:");
// Seek to the start of the sector, if possible
long start = num * size;
fs.Seek(start, SeekOrigin.Begin);
// Read and return the sector
byte[] buffer = new byte[size];
fs.Read(buffer, 0, size);
return buffer;
}
catch
{
return null;
}
finally
{
fs?.Dispose();
}
}
}
}

View File

@@ -0,0 +1,31 @@
namespace MPF.Core.Data
{
/// <summary>
/// Drive type for dumping
/// </summary>
public enum InternalDriveType
{
Optical,
Floppy,
HardDisk,
Removable,
}
/// <summary>
/// Program that is being used to dump media
/// </summary>
public enum InternalProgram
{
NONE = 0,
// Dumping support
Aaru,
DD,
DiscImageCreator,
// Verification support only
CleanRip,
DCDumper,
UmdImageCreator,
}
}

296
MPF.Core/Data/IniFile.cs Normal file
View File

@@ -0,0 +1,296 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace MPF.Core.Data
{
public class IniFile : IDictionary<string, string>
{
private Dictionary<string, string> _keyValuePairs = new Dictionary<string, string>();
public string this[string key]
{
get
{
if (_keyValuePairs == null)
_keyValuePairs = new Dictionary<string, string>();
key = key.ToLowerInvariant();
if (_keyValuePairs.ContainsKey(key))
return _keyValuePairs[key];
return null;
}
set
{
if (_keyValuePairs == null)
_keyValuePairs = new Dictionary<string, string>();
key = key.ToLowerInvariant();
_keyValuePairs[key] = value;
}
}
/// <summary>
/// Create an empty INI file
/// </summary>
public IniFile()
{
}
/// <summary>
/// Populate an INI file from path
/// </summary>
public IniFile(string path)
{
this.Parse(path);
}
/// <summary>
/// Populate an INI file from stream
/// </summary>
public IniFile(Stream stream)
{
this.Parse(stream);
}
/// <summary>
/// Add or update a key and value to the INI file
/// </summary>
public void AddOrUpdate(string key, string value)
{
_keyValuePairs[key.ToLowerInvariant()] = value;
}
/// <summary>
/// Remove a key from the INI file
/// </summary>
public void Remove(string key)
{
_keyValuePairs.Remove(key.ToLowerInvariant());
}
/// <summary>
/// Read an INI file based on the path
/// </summary>
public bool Parse(string path)
{
// If we don't have a file, we can't read it
if (!File.Exists(path))
return false;
using (var fileStream = File.OpenRead(path))
{
return Parse(fileStream);
}
}
/// <summary>
/// Read an INI file from a stream
/// </summary>
public bool Parse(Stream stream)
{
// If the stream is invalid or unreadable, we can't process it
if (stream == null || !stream.CanRead || stream.Position >= stream.Length - 1)
return false;
// Keys are case-insensitive by default
try
{
using (StreamReader sr = new StreamReader(stream))
{
string section = string.Empty;
while (!sr.EndOfStream)
{
string line = sr.ReadLine().Trim();
// Comments start with ';'
if (line.StartsWith(";"))
{
// No-op, we don't process comments
}
// Section titles are surrounded by square brackets
else if (line.StartsWith("["))
{
section = line.TrimStart('[').TrimEnd(']');
}
// Valid INI lines are in the format key=value
else if (line.Contains("="))
{
// Split the line by '=' for key-value pairs
string[] data = line.Split('=');
// If the value field contains an '=', we need to put them back in
string key = data[0].Trim();
string value = string.Join("=", data.Skip(1)).Trim();
// Section names are prepended to the key with a '.' separating
if (!string.IsNullOrEmpty(section))
key = $"{section}.{key}";
// Set or overwrite keys in the returned dictionary
_keyValuePairs[key.ToLowerInvariant()] = value;
}
// All other lines are ignored
}
}
}
catch
{
// We don't care what the error was, just catch and return
return false;
}
return true;
}
/// <summary>
/// Write an INI file to a path
/// </summary>
public bool Write(string path)
{
// If we don't have a valid dictionary with values, we can't write out
if (_keyValuePairs == null || _keyValuePairs.Count == 0)
return false;
using (var fileStream = File.OpenWrite(path))
{
return Write(fileStream);
}
}
/// <summary>
/// Write an INI file to a stream
/// </summary>
public bool Write(Stream stream)
{
// If we don't have a valid dictionary with values, we can't write out
if (_keyValuePairs == null || _keyValuePairs.Count == 0)
return false;
// If the stream is invalid or unwritable, we can't output to it
if (stream == null || !stream.CanWrite || stream.Position >= stream.Length - 1)
return false;
try
{
using (StreamWriter sw = new StreamWriter(stream))
{
// Order the dictionary by keys to link sections together
var orderedKeyValuePairs = _keyValuePairs.OrderBy(kvp => kvp.Key);
string section = string.Empty;
foreach (var keyValuePair in orderedKeyValuePairs)
{
// Extract the key and value
string key = keyValuePair.Key;
string value = keyValuePair.Value;
// We assume '.' is a section name separator
if (key.Contains('.'))
{
// Split the key by '.'
string[] data = keyValuePair.Key.Split('.');
// If the key contains an '.', we need to put them back in
string newSection = data[0].Trim();
key = string.Join(".", data.Skip(1)).Trim();
// If we have a new section, write it out
if (!string.Equals(newSection, section, StringComparison.OrdinalIgnoreCase))
{
sw.WriteLine($"[{newSection}]");
section = newSection;
}
}
// Now write out the key and value in a standardized way
sw.WriteLine($"{key}={value}");
}
}
}
catch
{
// We don't care what the error was, just catch and return
return false;
}
return true;
}
#region IDictionary Impelementations
public ICollection<string> Keys => ((IDictionary<string, string>)_keyValuePairs).Keys;
public ICollection<string> Values => ((IDictionary<string, string>)_keyValuePairs).Values;
public int Count => ((ICollection<KeyValuePair<string, string>>)_keyValuePairs).Count;
public bool IsReadOnly => ((ICollection<KeyValuePair<string, string>>)_keyValuePairs).IsReadOnly;
public void Add(string key, string value)
{
((IDictionary<string, string>)_keyValuePairs).Add(key.ToLowerInvariant(), value);
}
bool IDictionary<string, string>.Remove(string key)
{
return ((IDictionary<string, string>)_keyValuePairs).Remove(key.ToLowerInvariant());
}
public bool TryGetValue(string key, out string value)
{
return ((IDictionary<string, string>)_keyValuePairs).TryGetValue(key.ToLowerInvariant(), out value);
}
public void Add(KeyValuePair<string, string> item)
{
var newItem = new KeyValuePair<string, string>(item.Key.ToLowerInvariant(), item.Value);
((ICollection<KeyValuePair<string, string>>)_keyValuePairs).Add(newItem);
}
public void Clear()
{
((ICollection<KeyValuePair<string, string>>)_keyValuePairs).Clear();
}
public bool Contains(KeyValuePair<string, string> item)
{
var newItem = new KeyValuePair<string, string>(item.Key.ToLowerInvariant(), item.Value);
return ((ICollection<KeyValuePair<string, string>>)_keyValuePairs).Contains(newItem);
}
public bool ContainsKey(string key)
{
return _keyValuePairs.ContainsKey(key.ToLowerInvariant());
}
public void CopyTo(KeyValuePair<string, string>[] array, int arrayIndex)
{
((ICollection<KeyValuePair<string, string>>)_keyValuePairs).CopyTo(array, arrayIndex);
}
public bool Remove(KeyValuePair<string, string> item)
{
var newItem = new KeyValuePair<string, string>(item.Key.ToLowerInvariant(), item.Value);
return ((ICollection<KeyValuePair<string, string>>)_keyValuePairs).Remove(newItem);
}
public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
{
return ((IEnumerable<KeyValuePair<string, string>>)_keyValuePairs).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)_keyValuePairs).GetEnumerator();
}
#endregion
}
}

587
MPF.Core/Data/Options.cs Normal file
View File

@@ -0,0 +1,587 @@
using System;
using System.Collections;
using System.Collections.Generic;
using MPF.Core.Converters;
using RedumpLib.Data;
namespace MPF.Core.Data
{
public class Options : IDictionary<string, string>, ICloneable
{
private readonly Dictionary<string, string> _settings;
#region Internal Program
/// <summary>
/// Path to Aaru
/// </summary>
public string AaruPath
{
get { return GetStringSetting(_settings, "AaruPath", "Programs\\Aaru\\Aaru.exe"); }
set { _settings["AaruPath"] = value; }
}
/// <summary>
/// Path to DiscImageCreator
/// </summary>
public string DiscImageCreatorPath
{
get { return GetStringSetting(_settings, "DiscImageCreatorPath", "Programs\\Creator\\DiscImageCreator.exe"); }
set { _settings["DiscImageCreatorPath"] = value; }
}
/// <summary>
/// Path to dd for Windows
/// </summary>
public string DDPath
{
get { return GetStringSetting(_settings, "DDPath", "Programs\\DD\\dd.exe"); }
set { _settings["DDPath"] = value; }
}
/// <summary>
/// Currently selected dumping program
/// </summary>
public InternalProgram InternalProgram
{
get
{
string valueString = GetStringSetting(_settings, "InternalProgram", InternalProgram.DiscImageCreator.ToString());
var valueEnum = EnumConverter.ToInternalProgram(valueString);
return valueEnum == InternalProgram.NONE ? InternalProgram.DiscImageCreator : valueEnum;
}
set
{
_settings["InternalProgram"] = value.ToString();
}
}
#endregion
#region UI Defaults
/// <summary>
/// Enable dark mode for UI elements
/// </summary>
public bool EnableDarkMode
{
get { return GetBooleanSetting(_settings, "EnableDarkMode", false); }
set { _settings["EnableDarkMode"] = value.ToString(); }
}
/// <summary>
/// Check for updates on startup
/// </summary>
public bool CheckForUpdatesOnStartup
{
get { return GetBooleanSetting(_settings, "CheckForUpdatesOnStartup", true); }
set { _settings["CheckForUpdatesOnStartup"] = value.ToString(); }
}
/// <summary>
/// Default output path for dumps
/// </summary>
public string DefaultOutputPath
{
get { return GetStringSetting(_settings, "DefaultOutputPath", "ISO"); }
set { _settings["DefaultOutputPath"] = value; }
}
/// <summary>
/// Default system if none can be detected
/// </summary>
public RedumpSystem? DefaultSystem
{
get
{
string valueString = GetStringSetting(_settings, "DefaultSystem", null);
var valueEnum = Extensions.ToRedumpSystem(valueString);
return valueEnum;
}
set
{
_settings["DefaultSystem"] = value.LongName();
}
}
#endregion
#region Dumping Speeds
/// <summary>
/// Default CD dumping speed
/// </summary>
public int PreferredDumpSpeedCD
{
get { return GetInt32Setting(_settings, "PreferredDumpSpeedCD", 72); }
set { _settings["PreferredDumpSpeedCD"] = value.ToString(); }
}
/// <summary>
/// Default DVD dumping speed
/// </summary>
public int PreferredDumpSpeedDVD
{
get { return GetInt32Setting(_settings, "PreferredDumpSpeedDVD", 24); }
set { _settings["PreferredDumpSpeedDVD"] = value.ToString(); }
}
/// <summary>
/// Default BD dumping speed
/// </summary>
public int PreferredDumpSpeedBD
{
get { return GetInt32Setting(_settings, "PreferredDumpSpeedBD", 16); }
set { _settings["PreferredDumpSpeedBD"] = value.ToString(); }
}
#endregion
#region Aaru
/// <summary>
/// Enable debug output while dumping by default
/// </summary>
public bool AaruEnableDebug
{
get { return GetBooleanSetting(_settings, "AaruEnableDebug", false); }
set { _settings["AaruEnableDebug"] = value.ToString(); }
}
/// <summary>
/// Enable verbose output while dumping by default
/// </summary>
public bool AaruEnableVerbose
{
get { return GetBooleanSetting(_settings, "AaruEnableVerbose", false); }
set { _settings["AaruEnableVerbose"] = value.ToString(); }
}
/// <summary>
/// Enable force dumping of media by default
/// </summary>
public bool AaruForceDumping
{
get { return GetBooleanSetting(_settings, "AaruForceDumping", true); }
set { _settings["AaruForceDumping"] = value.ToString(); }
}
/// <summary>
/// Default number of sector/subchannel rereads
/// </summary>
public int AaruRereadCount
{
get { return GetInt32Setting(_settings, "AaruRereadCount", 5); }
set { _settings["AaruRereadCount"] = value.ToString(); }
}
/// <summary>
/// Strip personal data information from Aaru metadata by default
/// </summary>
public bool AaruStripPersonalData
{
get { return GetBooleanSetting(_settings, "AaruStripPersonalData", false); }
set { _settings["AaruStripPersonalData"] = value.ToString(); }
}
#endregion
#region DiscImageCreator
/// <summary>
/// Enable overly-secure dumping flags by default
/// </summary>
/// <remarks>
/// Split this into component parts later. Currently does:
/// - Scan sector protection and set subchannel read level to 2 for CD
/// - Set scan file protect flag for DVD
/// </remarks>
public bool DICParanoidMode
{
get { return GetBooleanSetting(_settings, "DICParanoidMode", false); }
set { _settings["DICParanoidMode"] = value.ToString(); }
}
/// <summary>
/// Enable the Quiet flag by default
/// </summary>
public bool DICQuietMode
{
get { return GetBooleanSetting(_settings, "DICQuietMode", false); }
set { _settings["DICQuietMode"] = value.ToString(); }
}
/// <summary>
/// Default number of C2 rereads
/// </summary>
public int DICRereadCount
{
get { return GetInt32Setting(_settings, "DICRereadCount", 20); }
set { _settings["DICRereadCount"] = value.ToString(); }
}
/// <summary>
/// Reset drive after dumping (useful for older drives)
/// </summary>
public bool DICResetDriveAfterDump
{
get { return GetBooleanSetting(_settings, "DICResetDriveAfterDump", false); }
set { _settings["DICResetDriveAfterDump"] = value.ToString(); }
}
/// <summary>
/// Use the CMI flag for supported disc types
/// </summary>
public bool DICUseCMIFlag
{
get { return GetBooleanSetting(_settings, "DICUseCMIFlag", false); }
set { _settings["DICUseCMIFlag"] = value.ToString(); }
}
#endregion
#region Extra Dumping Options
/// <summary>
/// Scan the disc for protection after dumping
/// </summary>
public bool ScanForProtection
{
get { return GetBooleanSetting(_settings, "ScanForProtection", true); }
set { _settings["ScanForProtection"] = value.ToString(); }
}
/// <summary>
/// Add placeholder values in the submission info
/// </summary>
public bool AddPlaceholders
{
get { return GetBooleanSetting(_settings, "AddPlaceholders", true); }
set { _settings["AddPlaceholders"] = value.ToString(); }
}
/// <summary>
/// Show the disc information window after dumping
/// </summary>
public bool PromptForDiscInformation
{
get { return GetBooleanSetting(_settings, "PromptForDiscInformation", true); }
set { _settings["PromptForDiscInformation"] = value.ToString(); }
}
/// <summary>
/// Show disc eject reminder before the disc information window is shown
/// </summary>
public bool ShowDiscEjectReminder
{
get { return GetBooleanSetting(_settings, "ShowDiscEjectReminder", true); }
set { _settings["ShowDiscEjectReminder"] = value.ToString(); }
}
/// <summary>
/// Eject the disc after dumping
/// </summary>
public bool EjectAfterDump
{
get { return GetBooleanSetting(_settings, "EjectAfterDump", false); }
set { _settings["EjectAfterDump"] = value.ToString(); }
}
/// <summary>
/// Ignore fixed drives when populating the list
/// </summary>
public bool IgnoreFixedDrives
{
get { return GetBooleanSetting(_settings, "IgnoreFixedDrives", true); }
set { _settings["IgnoreFixedDrives"] = value.ToString(); }
}
/// <summary>
/// Show dumping tools in their own window instead of in the log
/// </summary>
public bool ToolsInSeparateWindow
{
get { return GetBooleanSetting(_settings, "ToolsInSeparateWindow", true); }
set { _settings["ToolsInSeparateWindow"] = value.ToString(); }
}
/// <summary>
/// Output the compressed JSON version of the submission info
/// </summary>
public bool OutputSubmissionJSON
{
get { return GetBooleanSetting(_settings, "OutputSubmissionJSON", false); }
set { _settings["OutputSubmissionJSON"] = value.ToString(); }
}
/// <summary>
/// Include log files in serialized JSON data
/// </summary>
public bool IncludeArtifacts
{
get { return GetBooleanSetting(_settings, "IncludeArtifacts", false); }
set { _settings["IncludeArtifacts"] = value.ToString(); }
}
/// <summary>
/// Compress output log files to reduce space
/// </summary>
public bool CompressLogFiles
{
get { return GetBooleanSetting(_settings, "CompressLogFiles", true); }
set { _settings["CompressLogFiles"] = value.ToString(); }
}
#endregion
#region Skip Options
/// <summary>
/// Skip detecting media type on disc scan
/// </summary>
public bool SkipMediaTypeDetection
{
get { return GetBooleanSetting(_settings, "SkipMediaTypeDetection", false); }
set { _settings["SkipMediaTypeDetection"] = value.ToString(); }
}
/// <summary>
/// Skip detecting known system on disc scan
/// </summary>
public bool SkipSystemDetection
{
get { return GetBooleanSetting(_settings, "SkipSystemDetection", false); }
set { _settings["SkipSystemDetection"] = value.ToString(); }
}
#endregion
#region Protection Scanning Options
/// <summary>
/// Scan archive contents during protection scanning
/// </summary>
public bool ScanArchivesForProtection
{
get { return GetBooleanSetting(_settings, "ScanArchivesForProtection", true); }
set { _settings["ScanArchivesForProtection"] = value.ToString(); }
}
/// <summary>
/// Scan for executable packers during protection scanning
/// </summary>
public bool ScanPackersForProtection
{
get { return GetBooleanSetting(_settings, "ScanPackersForProtection", false); }
set { _settings["ScanPackersForProtection"] = value.ToString(); }
}
/// <summary>
/// Force scanning all files for protection
/// </summary>
public bool ForceScanningForProtection
{
get { return GetBooleanSetting(_settings, "ForceScanningForProtection", false); }
set { _settings["ForceScanningForProtection"] = value.ToString(); }
}
/// <summary>
/// Include debug information with scan results
/// </summary>
public bool IncludeDebugProtectionInformation
{
get { return GetBooleanSetting(_settings, "IncludeDebugProtectionInformation", false); }
set { _settings["IncludeDebugProtectionInformation"] = value.ToString(); }
}
#endregion
#region Logging Options
/// <summary>
/// Enable verbose and debug logs to be written
/// </summary>
public bool VerboseLogging
{
get { return GetBooleanSetting(_settings, "VerboseLogging", true); }
set { _settings["VerboseLogging"] = value.ToString(); }
}
/// <summary>
/// Have the log panel expanded by default on startup
/// </summary>
public bool OpenLogWindowAtStartup
{
get { return GetBooleanSetting(_settings, "OpenLogWindowAtStartup", true); }
set { _settings["OpenLogWindowAtStartup"] = value.ToString(); }
}
/// <summary>
/// Enable fancy formatting of log statements
/// Disables EnableProgressProcessing if disabled
/// </summary>
/// <remarks>
/// This is mainly for outputting redirected console outputs. Not many
/// other bits of the logs include any specially handled outputs.
/// </remarks>
public bool EnableLogFormatting
{
get { return GetBooleanSetting(_settings, "EnableLogFormatting", false); }
set { _settings["EnableLogFormatting"] = value.ToString(); }
}
/// <summary>
/// Enable progress bar updating based on log text
/// Disabled if EnableLogFormatting is disabled
/// </summary>
public bool EnableProgressProcessing
{
get { return GetBooleanSetting(_settings, "EnableProgressProcessing", false); }
set { _settings["EnableProgressProcessing"] = value.ToString(); }
}
#endregion
#region Redump Login Information
public string RedumpUsername
{
get { return GetStringSetting(_settings, "RedumpUsername", ""); }
set { _settings["RedumpUsername"] = value; }
}
// TODO: Figure out a way to keep this encrypted in some way, BASE64 to start?
public string RedumpPassword
{
get { return GetStringSetting(_settings, "RedumpPassword", ""); }
set { _settings["RedumpPassword"] = value; }
}
/// <summary>
/// Determine if a complete set of Redump credentials might exist
/// </summary>
public bool HasRedumpLogin { get => !string.IsNullOrWhiteSpace(RedumpUsername) && !string.IsNullOrWhiteSpace(RedumpPassword); }
#endregion
/// <summary>
/// Constructor taking a dictionary for settings
/// </summary>
/// <param name="settings"></param>
public Options(Dictionary<string, string> settings = null)
{
this._settings = settings ?? new Dictionary<string, string>();
}
/// <summary>
/// Create a clone of the object
/// </summary>
public object Clone()
{
return new Options(new Dictionary<string, string>(_settings));
}
#region Helpers
/// <summary>
/// Get a Boolean setting from a settings, dictionary
/// </summary>
/// <param name="settings">Dictionary representing the settings</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>
private bool GetBooleanSetting(Dictionary<string, string> settings, string key, bool defaultValue)
{
if (settings.ContainsKey(key))
{
if (Boolean.TryParse(settings[key], out bool value))
return value;
else
return defaultValue;
}
else
{
return defaultValue;
}
}
/// <summary>
/// Get an Int32 setting from a settings, dictionary
/// </summary>
/// <param name="settings">Dictionary representing the settings</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>
private int GetInt32Setting(Dictionary<string, string> settings, string key, int defaultValue)
{
if (settings.ContainsKey(key))
{
if (Int32.TryParse(settings[key], out int value))
return value;
else
return defaultValue;
}
else
{
return defaultValue;
}
}
/// <summary>
/// Get a String setting from a settings, dictionary
/// </summary>
/// <param name="settings">Dictionary representing the settings</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>
private string GetStringSetting(Dictionary<string, string> settings, string key, string defaultValue)
{
if (settings.ContainsKey(key))
return settings[key];
else
return defaultValue;
}
#endregion
#region IDictionary implementations
public ICollection<string> Keys => _settings.Keys;
public ICollection<string> Values => _settings.Values;
public int Count => _settings.Count;
public bool IsReadOnly => ((IDictionary<string, string>)_settings).IsReadOnly;
public string this[string key]
{
get { return (_settings.ContainsKey(key) ? _settings[key] : null); }
set { _settings[key] = value; }
}
public bool ContainsKey(string key) => _settings.ContainsKey(key);
public void Add(string key, string value) => _settings.Add(key, value);
public bool Remove(string key) => _settings.Remove(key);
public bool TryGetValue(string key, out string value) => _settings.TryGetValue(key, out value);
public void Add(KeyValuePair<string, string> item) => _settings.Add(item.Key, item.Value);
public void Clear() => _settings.Clear();
public bool Contains(KeyValuePair<string, string> item) => ((IDictionary<string, string>)_settings).Contains(item);
public void CopyTo(KeyValuePair<string, string>[] array, int arrayIndex) => ((IDictionary<string, string>)_settings).CopyTo(array, arrayIndex);
public bool Remove(KeyValuePair<string, string> item) => ((IDictionary<string, string>)_settings).Remove(item);
public IEnumerator<KeyValuePair<string, string>> GetEnumerator() => _settings.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => _settings.GetEnumerator();
#endregion
}
}

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
namespace MPF.Core.Data
{
public class ProcessingQueue<T> : IDisposable
{
/// <summary>
/// Internal queue to hold data to process
/// </summary>
private readonly ConcurrentQueue<T> InternalQueue;
/// <summary>
/// Custom processing step for dequeued data
/// </summary>
private readonly Action<T> CustomProcessing;
/// <summary>
/// Cancellation method for the processing task
/// </summary>
private readonly CancellationTokenSource TokenSource;
public ProcessingQueue(Action<T> customProcessing)
{
this.InternalQueue = new ConcurrentQueue<T>();
this.CustomProcessing = customProcessing;
this.TokenSource = new CancellationTokenSource();
Task.Run(() => ProcessQueue(), this.TokenSource.Token);
}
/// <summary>
/// Dispose the current instance
/// </summary>
public void Dispose() => this.TokenSource.Cancel();
/// <summary>
/// Enqueue a new item for processing
/// </summary>
/// <param name="item"></param>
public void Enqueue(T item)
{
// Only accept new data when not cancelled
if (!this.TokenSource.IsCancellationRequested)
this.InternalQueue.Enqueue(item);
}
/// <summary>
/// Process
/// </summary>
private void ProcessQueue()
{
while (true)
{
// Nothing in the queue means we get to idle
if (this.InternalQueue.Count == 0)
{
if (this.TokenSource.IsCancellationRequested)
break;
Thread.Sleep(10);
continue;
}
// Get the next item from the queue
if (!this.InternalQueue.TryDequeue(out T nextItem))
continue;
// Invoke the lambda, if possible
this.CustomProcessing?.Invoke(nextItem);
}
}
}
}

52
MPF.Core/Data/Result.cs Normal file
View File

@@ -0,0 +1,52 @@
namespace MPF.Core.Data
{
/// <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 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>
/// Results can be compared to boolean values based on the success value
/// </summary>
public static implicit operator bool(Result result) => result.success;
}
}

423
MPF.Core/Data/XgdInfo.cs Normal file
View File

@@ -0,0 +1,423 @@
using RedumpLib.Data;
namespace MPF.Core.Data
{
/// <summary>
/// Contains information specific to an XGD disc
/// </summary>
/// <remarks>
/// XGD1 XeMID Format Information:
///
/// AABBBCCD
/// - AA => The two-ASCII-character publisher identifier (see GetPublisher for details)
/// - BBB => Game ID
/// - CC => Version number
/// - D => Region identifier (see GetRegion for details)
///
/// XGD2/3 XeMID Format Information:
///
/// AABCCCDDEFFGHH(IIIIIIII)
/// - AA => The two-ASCII-character publisher identifier (see GetPublisher for details)
/// - B => Platform identifier; 2 indicates Xbox 360.
/// - CCC => Game ID
/// - DD => SKU number (unique per SKU of a title)
/// - E => Region identifier (see GetRegion for details)
/// - FF => Base version; usually starts at 01 (can be 1 or 2 characters)
/// - G => Media type identifier (see GetMediaSubtype for details)
/// - HH => Disc number stored in [disc number][total discs] format
/// - IIIIIIII => 8-hex-digit certification submission identifier; usually on test discs only
/// </remarks>
public class XgdInfo
{
#region Fields
/// <summary>
/// Indicates whether the information in this object is fully instantiated or not
/// </summary>
public bool Initialized { get; private set; }
/// <summary>
/// Raw XeMID string that all other information is derived from
/// </summary>
public string XeMID { get; private set; }
/// <summary>
/// 2-character publisher identifier
/// </summary>
public string PublisherIdentifier { get; private set; }
/// <summary>
/// Platform disc is made for, 2 indicates Xbox 360
/// </summary>
public char? PlatformIdentifier { get; private set; }
/// <summary>
/// Game ID
/// </summary>
public string GameID { get; private set; }
/// <summary>
/// For XGD1: Internal version number
/// For XGD2/3: Title-specific SKU
/// </summary>
public string SKU { get; private set; }
/// <summary>
/// Region identifier character
/// </summary>
public char RegionIdentifier { get; private set; }
/// <summary>
/// Base version of executables, usually starts at 01
/// </summary>
/// <remarks>
/// TODO: Check if this is always 2 characters for XGD2/3
/// </remarks>
public string BaseVersion { get; private set; }
/// <summary>
/// Media subtype identifier
/// </summary>
public char MediaSubtypeIdentifier { get; private set; }
/// <summary>
/// Disc number stored in [disc number][total discs] format
/// </summary>
public string DiscNumberIdentifier { get; private set; }
/// <summary>
/// 8-hex-digit certification submission identifier; usually on test discs only
/// </summary>
public string CertificationSubmissionIdentifier { get; private set; }
#endregion
#region Auto-Generated Information
/// <summary>
/// Human-readable name derived from the publisher identifier
/// </summary>
public string PublisherName => GetPublisher(this.PublisherIdentifier);
/// <summary>
/// Internally represented region
/// </summary>
public Region? InternalRegion => GetRegion(this.RegionIdentifier);
/// <summary>
/// Human-readable subtype derived from the media identifier
/// </summary>
public string MediaSubtype => GetMediaSubtype(this.MediaSubtypeIdentifier);
#endregion
/// <summary>
/// Populate a set of XGD information from a Master ID (XeMID) string
/// </summary>
/// <param name="xemid">XeMID string representing the DMI information</param>
/// <param name="validate">True if value validation should be performed, false otherwise</param>
public XgdInfo(string xemid, bool validate = false)
{
this.Initialized = false;
if (string.IsNullOrWhiteSpace(xemid))
return;
this.XeMID = xemid.TrimEnd('\0');
if (string.IsNullOrWhiteSpace(this.XeMID))
return;
// XGD1 information is 8 characters
if (this.XeMID.Length == 8)
this.Initialized = ParseXGD1XeMID(this.XeMID, validate);
// XGD2/3 information is semi-variable length
else if (this.XeMID.Length == 13 || this.XeMID.Length == 14 || this.XeMID.Length == 21 || this.XeMID.Length == 22)
this.Initialized = ParseXGD23XeMID(this.XeMID, validate);
}
/// <summary>
/// Get the human-readable serial string
/// </summary>
/// <returns>Formatted serial string, null on error</returns>
public string GetSerial()
{
if (!this.Initialized)
return null;
try
{
// XGD1 doesn't use PlatformIdentifier
if (this.PlatformIdentifier == null)
return $"{this.PublisherIdentifier}-{this.GameID}";
// XGD2/3 uses a specific identifier
else if (this.PlatformIdentifier == '2')
return $"{this.PublisherIdentifier}-{this.PlatformIdentifier}{this.GameID}";
return null;
}
catch
{
return null;
}
}
/// <summary>
/// Get the human-readable version string
/// </summary>
/// <returns>Formatted version string, null on error</returns>
/// <remarks>This may differ for XGD2/3 in the future</remarks>
public string GetVersion()
{
if (!this.Initialized)
return null;
try
{
// XGD1 doesn't use PlatformIdentifier
if (this.PlatformIdentifier == null)
return $"1.{this.SKU}";
// XGD2/3 uses a specific identifier
else if (this.PlatformIdentifier == '2')
return $"1.{this.SKU}";
return null;
}
catch
{
return null;
}
}
/// <summary>
/// Parse an XGD1 XeMID string
/// </summary>
/// <param name="xemid">XeMID string to attempt to parse</param>
/// <param name="validate">True if value validation should be performed, false otherwise</param>
/// <returns>True if the XeMID could be parsed, false otherwise</returns>
private bool ParseXGD1XeMID(string xemid, bool validate)
{
if (xemid == null || xemid.Length != 8)
return false;
this.PublisherIdentifier = xemid.Substring(0, 2);
if (validate && string.IsNullOrEmpty(this.PublisherName))
return false;
this.GameID = xemid.Substring(2, 3);
this.SKU = xemid.Substring(5, 2);
this.RegionIdentifier = xemid[7];
if (validate && this.InternalRegion == null)
return false;
return true;
}
/// <summary>
/// Parse an XGD2/3 XeMID string
/// </summary>
/// <param name="xemid">XeMID string to attempt to parse</param>
/// <param name="validate">True if value validation should be performed, false otherwise</param>
/// <returns>True if the XeMID could be parsed, false otherwise</returns>
private bool ParseXGD23XeMID(string xemid, bool validate)
{
if (xemid == null
|| (xemid.Length != 13 && xemid.Length != 14
&& xemid.Length != 21 && xemid.Length != 22))
return false;
this.PublisherIdentifier = xemid.Substring(0, 2);
if (validate && string.IsNullOrEmpty(this.PublisherName))
return false;
this.PlatformIdentifier = xemid[2];
if (validate && this.PlatformIdentifier != '2')
return false;
this.GameID = xemid.Substring(3, 3);
this.SKU = xemid.Substring(6, 2);
this.RegionIdentifier = xemid[8];
if (validate && this.InternalRegion == null)
return false;
if (xemid.Length == 13 || xemid.Length == 21)
{
this.BaseVersion = xemid.Substring(9, 1);
this.MediaSubtypeIdentifier = xemid[10];
if (validate && string.IsNullOrEmpty(this.MediaSubtype))
return false;
this.DiscNumberIdentifier = xemid.Substring(11, 2);
}
else if (xemid.Length == 14 || xemid.Length == 22)
{
this.BaseVersion = xemid.Substring(9, 2);
this.MediaSubtypeIdentifier = xemid[11];
if (validate && string.IsNullOrEmpty(this.MediaSubtype))
return false;
this.DiscNumberIdentifier = xemid.Substring(12, 2);
}
if (xemid.Length == 21)
this.CertificationSubmissionIdentifier = xemid.Substring(13);
else if (xemid.Length == 22)
this.CertificationSubmissionIdentifier = xemid.Substring(14);
return true;
}
#region Helpers
/// <summary>
/// Determine the XGD type based on the XGD2/3 media type identifier character
/// </summary>
/// <param name="mediaTypeIdentifier">Character denoting the media type</param>
/// <returns>Media subtype as a string, if possible</returns>
private static string GetMediaSubtype(char mediaTypeIdentifier)
{
switch (mediaTypeIdentifier)
{
case 'F': return "XGD3";
case 'X': return "XGD2";
case 'Z': return "Games on Demand / Marketplace Demo";
default: return null;
}
}
/// <summary>
/// Get the full name of the publisher from the 2-character identifier
/// </summary>
/// <param name="publisherIdentifier">Case-sensitive 2-character identifier</param>
/// <returns>Publisher name, if possible</returns>
/// <see cref="https://xboxdevwiki.net/Xbe#Title_ID"/>
private static string GetPublisher(string publisherIdentifier)
{
switch (publisherIdentifier)
{
case "AC": return "Acclaim Entertainment";
case "AH": return "ARUSH Entertainment";
case "AQ": return "Aqua System";
case "AS": return "ASK";
case "AT": return "Atlus";
case "AV": return "Activision";
case "AY": return "Aspyr Media";
case "BA": return "Bandai";
case "BL": return "Black Box";
case "BM": return "BAM! Entertainment";
case "BR": return "Broccoli Co.";
case "BS": return "Bethesda Softworks";
case "BU": return "Bunkasha Co.";
case "BV": return "Buena Vista Games";
case "BW": return "BBC Multimedia";
case "BZ": return "Blizzard";
case "CC": return "Capcom";
case "CK": return "Kemco Corporation"; // TODO: Confirm
case "CM": return "Codemasters";
case "CV": return "Crave Entertainment";
case "DC": return "DreamCatcher Interactive";
case "DX": return "Davilex";
case "EA": return "Electronic Arts (EA)";
case "EC": return "Encore inc";
case "EL": return "Enlight Software";
case "EM": return "Empire Interactive";
case "ES": return "Eidos Interactive";
case "FI": return "Fox Interactive";
case "FS": return "From Software";
case "GE": return "Genki Co.";
case "GV": return "Groove Games";
case "HE": return "Tru Blu (Entertainment division of Home Entertainment Suppliers)";
case "HP": return "Hip games";
case "HU": return "Hudson Soft";
case "HW": return "Highwaystar";
case "IA": return "Mad Catz Interactive";
case "IF": return "Idea Factory";
case "IG": return "Infogrames";
case "IL": return "Interlex Corporation";
case "IM": return "Imagine Media";
case "IO": return "Ignition Entertainment";
case "IP": return "Interplay Entertainment";
case "IX": return "InXile Entertainment"; // TODO: Confirm
case "JA": return "Jaleco";
case "JW": return "JoWooD";
case "KB": return "Kemco"; // TODO: Confirm
case "KI": return "Kids Station Inc."; // TODO: Confirm
case "KN": return "Konami";
case "KO": return "KOEI";
case "KU": return "Kobi and / or GAE (formerly Global A Entertainment)"; // TODO: Confirm
case "LA": return "LucasArts";
case "LS": return "Black Bean Games (publishing arm of Leader S.p.A.)";
case "MD": return "Metro3D";
case "ME": return "Medix";
case "MI": return "Microïds";
case "MJ": return "Majesco Entertainment";
case "MM": return "Myelin Media";
case "MP": return "MediaQuest"; // TODO: Confirm
case "MS": return "Microsoft Game Studios";
case "MW": return "Midway Games";
case "MX": return "Empire Interactive"; // TODO: Confirm
case "NK": return "NewKidCo";
case "NL": return "NovaLogic";
case "NM": return "Namco";
case "OX": return "Oxygen Interactive";
case "PC": return "Playlogic Entertainment";
case "PL": return "Phantagram Co., Ltd.";
case "RA": return "Rage";
case "SA": return "Sammy";
case "SC": return "SCi Games";
case "SE": return "SEGA";
case "SN": return "SNK";
case "SS": return "Simon & Schuster";
case "SU": return "Success Corporation";
case "SW": return "Swing! Deutschland";
case "TA": return "Takara";
case "TC": return "Tecmo";
case "TD": return "The 3DO Company (or just 3DO)";
case "TK": return "Takuyo";
case "TM": return "TDK Mediactive";
case "TQ": return "THQ";
case "TS": return "Titus Interactive";
case "TT": return "Take-Two Interactive Software";
case "US": return "Ubisoft";
case "VC": return "Victor Interactive Software";
case "VN": return "Vivendi Universal (just took Interplays publishing rights)"; // TODO: Confirm
case "VU": return "Vivendi Universal Games";
case "VV": return "Vivendi Universal Games"; // TODO: Confirm
case "WE": return "Wanadoo Edition";
case "WR": return "Warner Bros. Interactive Entertainment"; // TODO: Confirm
case "XI": return "XPEC Entertainment and Idea Factory";
case "XK": return "Xbox kiosk disk?"; // TODO: Confirm
case "XL": return "Xbox special bundled or live demo disk?"; // TODO: Confirm
case "XM": return "Evolved Games"; // TODO: Confirm
case "XP": return "XPEC Entertainment";
case "XR": return "Panorama";
case "YB": return "YBM Sisa (South-Korea)";
case "ZD": return "Zushi Games (formerly Zoo Digital Publishing)";
default: return null;
}
}
/// <summary>
/// Determine the region based on the XGD serial character
/// </summary>
/// <param name="region">Character denoting the region</param>
/// <returns>Region, if possible</returns>
private static Region? GetRegion(char region)
{
switch (region)
{
case 'W': return Region.World;
case 'A': return Region.USA;
case 'J': return Region.JapanAsia;
case 'E': return Region.Europe;
case 'K': return Region.USAJapan;
case 'L': return Region.USAEurope;
case 'H': return Region.JapanEurope;
default: return null;
}
}
#endregion
}
}

176
MPF.Core/Hashing/Hasher.cs Normal file
View File

@@ -0,0 +1,176 @@
using System;
using System.Linq;
using System.Security.Cryptography;
namespace MPF.Core.Hashing
{
/// <summary>
/// Available hashing types
/// </summary>
[Flags]
public enum Hash
{
CRC = 1 << 0,
MD5 = 1 << 1,
SHA1 = 1 << 2,
SHA256 = 1 << 3,
SHA384 = 1 << 4,
SHA512 = 1 << 5,
// Special combinations
Standard = CRC | MD5 | SHA1,
All = CRC | MD5 | SHA1 | SHA256 | SHA384 | SHA512,
}
/// <summary>
/// Async hashing class wraper
/// </summary>
public class Hasher
{
public Hash HashType { get; private set; }
private IDisposable _hasher;
public Hasher(Hash hashType)
{
this.HashType = hashType;
GetHasher();
}
/// <summary>
/// Generate the correct hashing class based on the hash type
/// </summary>
private void GetHasher()
{
switch (HashType)
{
case Hash.CRC:
_hasher = new OptimizedCRC();
break;
case Hash.MD5:
_hasher = MD5.Create();
break;
case Hash.SHA1:
_hasher = SHA1.Create();
break;
case Hash.SHA256:
_hasher = SHA256.Create();
break;
case Hash.SHA384:
_hasher = SHA384.Create();
break;
case Hash.SHA512:
_hasher = SHA512.Create();
break;
}
}
public void Dispose()
{
_hasher.Dispose();
}
/// <summary>
/// Process a buffer of some length with the internal hash algorithm
/// </summary>
public void Process(byte[] buffer, int size)
{
switch (HashType)
{
case Hash.CRC:
(_hasher as OptimizedCRC).Update(buffer, 0, size);
break;
case Hash.MD5:
case Hash.SHA1:
case Hash.SHA256:
case Hash.SHA384:
case Hash.SHA512:
(_hasher as HashAlgorithm).TransformBlock(buffer, 0, size, null, 0);
break;
}
}
/// <summary>
/// Finalize the internal hash algorigthm
/// </summary>
public void Terminate()
{
byte[] emptyBuffer = new byte[0];
switch (HashType)
{
case Hash.CRC:
(_hasher as OptimizedCRC).Update(emptyBuffer, 0, 0);
break;
case Hash.MD5:
case Hash.SHA1:
case Hash.SHA256:
case Hash.SHA384:
case Hash.SHA512:
(_hasher as HashAlgorithm).TransformFinalBlock(emptyBuffer, 0, 0);
break;
}
}
/// <summary>
/// Get internal hash as a byte array
/// </summary>
public byte[] GetHash()
{
switch (HashType)
{
case Hash.CRC:
return BitConverter.GetBytes((_hasher as OptimizedCRC).Value).Reverse().ToArray();
case Hash.MD5:
case Hash.SHA1:
case Hash.SHA256:
case Hash.SHA384:
case Hash.SHA512:
return (_hasher as HashAlgorithm).Hash;
}
return null;
}
/// <summary>
/// Get internal hash as a string
/// </summary>
public string GetHashString()
{
byte[] hash = GetHash();
if (hash == null)
return null;
return ByteArrayToString(hash);
}
/// <summary>
/// Convert a byte array to a hex string
/// </summary>
/// <param name="bytes">Byte array to convert</param>
/// <returns>Hex string representing the byte array</returns>
/// <link>http://stackoverflow.com/questions/311165/how-do-you-convert-byte-array-to-hexadecimal-string-and-vice-versa</link>
private static string ByteArrayToString(byte[] bytes)
{
// If we get null in, we send null out
if (bytes == null)
return null;
try
{
string hex = BitConverter.ToString(bytes);
return hex.Replace("-", string.Empty).ToLowerInvariant();
}
catch
{
return null;
}
}
}
}

View File

@@ -0,0 +1,154 @@
/*
Copyright (c) 2012-2015 Eugene Larchenko (spct@mail.ru)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System;
//namespace OptimizedCRC
namespace MPF.Core.Hashing
{
internal class OptimizedCRC : IDisposable
{
private const uint kCrcPoly = 0xEDB88320;
private const uint kInitial = 0xFFFFFFFF;
private const int CRC_NUM_TABLES = 8;
private static readonly uint[] Table;
static OptimizedCRC()
{
unchecked
{
Table = new uint[256 * CRC_NUM_TABLES];
int i;
for (i = 0; i < 256; i++)
{
uint r = (uint)i;
for (int j = 0; j < 8; j++)
{
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
}
Table[i] = r;
}
for (; i < 256 * CRC_NUM_TABLES; i++)
{
uint r = Table[i - 256];
Table[i] = Table[r & 0xFF] ^ (r >> 8);
}
}
}
public uint UnsignedValue;
public OptimizedCRC()
{
Init();
}
/// <summary>
/// Reset CRC
/// </summary>
public void Init()
{
UnsignedValue = kInitial;
}
public int Value
{
get { return (int)~UnsignedValue; }
}
public void Update(byte[] data, int offset, int count)
{
new ArraySegment<byte>(data, offset, count); // check arguments
if (count == 0)
{
return;
}
var table = OptimizedCRC.Table;
uint crc = UnsignedValue;
for (; (offset & 7) != 0 && count != 0; count--)
{
crc = (crc >> 8) ^ table[(byte)crc ^ data[offset++]];
}
if (count >= 8)
{
/*
* Idea from 7-zip project sources (http://7-zip.org/sdk.html)
*/
int end = (count - 8) & ~7;
count -= end;
end += offset;
while (offset != end)
{
crc ^= (uint)(data[offset] + (data[offset + 1] << 8) + (data[offset + 2] << 16) + (data[offset + 3] << 24));
uint high = (uint)(data[offset + 4] + (data[offset + 5] << 8) + (data[offset + 6] << 16) + (data[offset + 7] << 24));
offset += 8;
crc = table[(byte)crc + 0x700]
^ table[(byte)(crc >>= 8) + 0x600]
^ table[(byte)(crc >>= 8) + 0x500]
^ table[/*(byte)*/(crc >> 8) + 0x400]
^ table[(byte)(high) + 0x300]
^ table[(byte)(high >>= 8) + 0x200]
^ table[(byte)(high >>= 8) + 0x100]
^ table[/*(byte)*/(high >> 8) + 0x000];
}
}
while (count-- != 0)
{
crc = (crc >> 8) ^ table[(byte)crc ^ data[offset++]];
}
UnsignedValue = crc;
}
static public int Compute(byte[] data, int offset, int count)
{
var crc = new OptimizedCRC();
crc.Update(data, offset, count);
return crc.Value;
}
static public int Compute(byte[] data)
{
return Compute(data, 0, data.Length);
}
static public int Compute(ArraySegment<byte> block)
{
return Compute(block.Array, block.Offset, block.Count);
}
public void Dispose()
{
UnsignedValue = 0;
}
}
}

View File

@@ -0,0 +1,80 @@
using System;
using System.IO;
using System.Threading;
//namespace Compress.ThreadReaders
namespace MPF.Core.Hashing
{
public class ThreadLoadBuffer : IDisposable
{
private readonly AutoResetEvent _waitEvent;
private readonly AutoResetEvent _outEvent;
private readonly Thread _tWorker;
private byte[] _buffer;
private int _size;
private readonly Stream _ds;
private bool _finished;
public bool errorState;
public int SizeRead;
public ThreadLoadBuffer(Stream ds)
{
_waitEvent = new AutoResetEvent(false);
_outEvent = new AutoResetEvent(false);
_finished = false;
_ds = ds;
errorState = false;
_tWorker = new Thread(MainLoop);
_tWorker.Start();
}
public void Dispose()
{
_waitEvent.Close();
_outEvent.Close();
}
private void MainLoop()
{
while (true)
{
_waitEvent.WaitOne();
if (_finished)
{
break;
}
try
{
SizeRead = _ds.Read(_buffer, 0, _size);
}
catch (Exception)
{
errorState = true;
}
_outEvent.Set();
}
}
public void Trigger(byte[] buffer, int size)
{
_buffer = buffer;
_size = size;
_waitEvent.Set();
}
public void Wait()
{
_outEvent.WaitOne();
}
public void Finish()
{
_finished = true;
_waitEvent.Set();
_tWorker.Join();
}
}
}

65
MPF.Core/MPF.Core.csproj Normal file
View File

@@ -0,0 +1,65 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net48;netcoreapp3.1;net5.0</TargetFrameworks>
<PlatformTarget>x86</PlatformTarget>
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
<Copyright>Copyright (c)2019-2021</Copyright>
<RepositoryUrl>https://github.com/SabreTools/MPF</RepositoryUrl>
<Version>2.2</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<FileVersion>$(Version)</FileVersion>
<IncludeSource>true</IncludeSource>
<IncludeSymbols>true</IncludeSymbols>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup>
<NrtRevisionFormat>$(Version)-{chash:8}</NrtRevisionFormat>
<NrtResolveSimpleAttributes>true</NrtResolveSimpleAttributes>
<NrtShowRevision>false</NrtShowRevision>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)'=='net48'">
<DefineConstants>NET_FRAMEWORK</DefineConstants>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)'=='net48'">
<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>
<ProjectReference Include="..\RedumpLib\RedumpLib.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="System.Management" Version="6.0.0-rc.1.21451.13" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'!='net48'">
<PackageReference Include="Aaru.Devices" Version="5.3.0-rc2" />
</ItemGroup>
<ItemGroup>
<Reference Include="System.Management" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,174 @@
using System;
using System.IO;
namespace MPF.Core.Utilities
{
/// <summary>
/// Big endian reading overloads for BinaryReader
/// </summary>
public static class BinaryReaderExtensions
{
/// <summary>
/// Reads the specified number of bytes from the stream, starting from a specified point in the byte array.
/// </summary>
/// <param name="buffer">The buffer to read data into.</param>
/// <param name="index">The starting point in the buffer at which to begin reading into the buffer.</param>
/// <param name="count">The number of bytes to read.</param>
/// <returns>The number of bytes read into buffer. This might be less than the number of bytes requested if that many bytes are not available, or it might be zero if the end of the stream is reached.</returns>
public static int ReadBigEndian(this BinaryReader reader, byte[] buffer, int index, int count)
{
int retval = reader.Read(buffer, index, count);
Array.Reverse(buffer);
return retval;
}
/// <summary>
/// Reads the specified number of characters from the stream, starting from a specified point in the character array.
/// </summary>
/// <param name="buffer">The buffer to read data into.</param>
/// <param name="index">The starting point in the buffer at which to begin reading into the buffer.</param>
/// <param name="count">The number of characters to read.</param>
/// <returns>The total number of characters read into the buffer. This might be less than the number of characters requested if that many characters are not currently available, or it might be zero if the end of the stream is reached.</returns>
public static int ReadBigEndian(this BinaryReader reader, char[] buffer, int index, int count)
{
int retval = reader.Read(buffer, index, count);
Array.Reverse(buffer);
return retval;
}
/// <summary>
/// Reads the specified number of bytes from the current stream into a byte array and advances the current position by that number of bytes.
/// </summary>
/// <param name="count">The number of bytes to read. This value must be 0 or a non-negative number or an exception will occur.</param>
/// <returns>A byte array containing data read from the underlying stream. This might be less than the number of bytes requested if the end of the stream is reached.</returns>
public static byte[] ReadBytesBigEndian(this BinaryReader reader, int count)
{
byte[] retval = reader.ReadBytes(count);
Array.Reverse(retval);
return retval;
}
/// <summary>
/// Reads the specified number of characters from the current stream, returns the data in a character array, and advances the current position in accordance with the Encoding used and the specific character being read from the stream.
/// </summary>
/// <param name="count">The number of characters to read. This value must be 0 or a non-negative number or an exception will occur.</param>
/// <returns>A character array containing data read from the underlying stream. This might be less than the number of bytes requested if the end of the stream is reached.</returns>
public static char[] ReadCharsBigEndian(this BinaryReader reader, int count)
{
char[] retval = reader.ReadChars(count);
Array.Reverse(retval);
return retval;
}
/// <summary>
/// Reads a decimal value from the current stream and advances the current position of the stream by sixteen bytes.
/// </summary>
/// <returns>A decimal value read from the current stream.</returns>
public static decimal ReadDecimalBigEndian(this BinaryReader reader)
{
byte[] retval = reader.ReadBytes(16);
Array.Reverse(retval);
int i1 = BitConverter.ToInt32(retval, 0);
int i2 = BitConverter.ToInt32(retval, 4);
int i3 = BitConverter.ToInt32(retval, 8);
int i4 = BitConverter.ToInt32(retval, 12);
return new decimal(new int[] { i1, i2, i3, i4 });
}
/// <summary>
/// eads an 8-byte floating point value from the current stream and advances the current position of the stream by eight bytes.
/// </summary>
/// <returns>An 8-byte floating point value read from the current stream.</returns>
public static double ReadDoubleBigEndian(this BinaryReader reader)
{
byte[] retval = reader.ReadBytes(8);
Array.Reverse(retval);
return BitConverter.ToDouble(retval, 0);
}
/// <summary>
/// Reads a 2-byte signed integer from the current stream and advances the current position of the stream by two bytes.
/// </summary>
/// <returns>A 2-byte signed integer read from the current stream.</returns>
public static short ReadInt16BigEndian(this BinaryReader reader)
{
byte[] retval = reader.ReadBytes(2);
Array.Reverse(retval);
return BitConverter.ToInt16(retval, 0);
}
/// <summary>
/// Reads a 4-byte signed integer from the current stream and advances the current position of the stream by four bytes.
/// </summary>
/// <returns>A 4-byte signed integer read from the current stream.</returns>
public static int ReadInt32BigEndian(this BinaryReader reader)
{
byte[] retval = reader.ReadBytes(4);
Array.Reverse(retval);
return BitConverter.ToInt32(retval, 0);
}
/// <summary>
/// Reads an 8-byte signed integer from the current stream and advances the current position of the stream by eight bytes.
/// </summary>
/// <returns>An 8-byte signed integer read from the current stream.</returns>
public static long ReadInt64BigEndian(this BinaryReader reader)
{
byte[] retval = reader.ReadBytes(8);
Array.Reverse(retval);
return BitConverter.ToInt64(retval, 0);
}
/// <summary>
/// Reads a 4-byte floating point value from the current stream and advances the current position of the stream by four bytes.
/// </summary>
/// <returns>A 4-byte floating point value read from the current stream.</returns>
public static float ReadSingleBigEndian(this BinaryReader reader)
{
byte[] retval = reader.ReadBytes(4);
Array.Reverse(retval);
return BitConverter.ToSingle(retval, 0);
}
/// <summary>
/// Reads a 2-byte unsigned integer from the current stream using little-endian encoding and advances the position of the stream by two bytes.
///
/// This API is not CLS-compliant.
/// </summary>
/// <returns>A 2-byte unsigned integer read from this stream.</returns>
public static ushort ReadUInt16BigEndian(this BinaryReader reader)
{
byte[] retval = reader.ReadBytes(2);
Array.Reverse(retval);
return BitConverter.ToUInt16(retval, 0);
}
/// <summary>
/// Reads a 4-byte unsigned integer from the current stream and advances the position of the stream by four bytes.
///
/// This API is not CLS-compliant.
/// </summary>
/// <returns>A 4-byte unsigned integer read from this stream.</returns>
public static uint ReadUInt32BigEndian(this BinaryReader reader)
{
byte[] retval = reader.ReadBytes(4);
Array.Reverse(retval);
return BitConverter.ToUInt32(retval, 0);
}
/// <summary>
/// Reads an 8-byte unsigned integer from the current stream and advances the position of the stream by eight bytes.
///
/// This API is not CLS-compliant.
/// </summary>
/// <returns>An 8-byte unsigned integer read from this stream.</returns>
public static ulong ReadUInt64BigEndian(this BinaryReader reader)
{
byte[] retval = reader.ReadBytes(8);
Array.Reverse(retval);
return BitConverter.ToUInt64(retval, 0);
}
}
}

View File

@@ -0,0 +1,144 @@
using RedumpLib.Data;
namespace MPF.Core.Utilities
{
public static class EnumExtensions
{
/// <summary>
/// Determine if a system is okay if it's not detected by Windows
/// </summary>
/// <param name="system">RedumpSystem value to check</param>
/// <returns>True if Windows show see a disc when dumping, false otherwise</returns>
public static bool DetectedByWindows(this RedumpSystem? system)
{
switch (system)
{
case RedumpSystem.AmericanLaserGames3DO:
case RedumpSystem.AppleMacintosh:
case RedumpSystem.Atari3DO:
case RedumpSystem.AtariJaguarCDInteractiveMultimediaSystem:
case RedumpSystem.NewJatreCDi:
case RedumpSystem.NintendoGameCube:
case RedumpSystem.NintendoWii:
case RedumpSystem.NintendoWiiU:
case RedumpSystem.PhilipsCDi:
case RedumpSystem.PhilipsCDiDigitalVideo:
case RedumpSystem.Panasonic3DOInteractiveMultiplayer:
case RedumpSystem.PanasonicM2:
case RedumpSystem.PioneerLaserActive:
case RedumpSystem.SuperAudioCD:
return false;
default:
return true;
}
}
/// <summary>
/// Determine if the media supports drive speeds
/// </summary>
/// <param name="type">MediaType value to check</param>
/// <returns>True if the media has variable dumping speeds, false otherwise</returns>
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;
}
}
/// <summary>
/// Determine if a system has reversed ringcodes
/// </summary>
/// <param name="system">RedumpSystem value to check</param>
/// <returns>True if the system has reversed ringcodes, false otherwise</returns>
public static bool HasReversedRingcodes(this RedumpSystem? system)
{
switch (system)
{
case RedumpSystem.SonyPlayStation2:
case RedumpSystem.SonyPlayStation3:
case RedumpSystem.SonyPlayStation4:
//case RedumpSystem.SonyPlayStation5:
return true;
default:
return false;
}
}
/// <summary>
/// Determine if a system is considered audio-only
/// </summary>
/// <param name="system">RedumpSystem value to check</param>
/// <returns>True if the system is audio-only, false otherwise</returns>
/// <remarks>
/// Philips CD-i should NOT be in this list. It's being included until there's a
/// reasonable distinction between CD-i and CD-i ready on the database side.
/// </remarks>
public static bool IsAudio(this RedumpSystem? system)
{
switch (system)
{
case RedumpSystem.AtariJaguarCDInteractiveMultimediaSystem:
case RedumpSystem.AudioCD:
case RedumpSystem.DVDAudio:
case RedumpSystem.HasbroVideoNow:
case RedumpSystem.HasbroVideoNowColor:
case RedumpSystem.HasbroVideoNowJr:
case RedumpSystem.HasbroVideoNowXP:
case RedumpSystem.PhilipsCDi:
case RedumpSystem.SuperAudioCD:
return true;
default:
return false;
}
}
/// <summary>
/// Determine if a system is a marker value
/// </summary>
/// <param name="system">RedumpSystem value to check</param>
/// <returns>True if the system is a marker value, false otherwise</returns>
public static bool IsMarker(this RedumpSystem? system)
{
switch (system)
{
case RedumpSystem.MarkerArcadeEnd:
case RedumpSystem.MarkerComputerEnd:
case RedumpSystem.MarkerDiscBasedConsoleEnd:
// case RedumpSystem.MarkerOtherConsoleEnd:
case RedumpSystem.MarkerOtherEnd:
return true;
default:
return false;
}
}
/// <summary>
/// Determine if a system is considered XGD
/// </summary>
/// <param name="system">RedumpSystem value to check</param>
/// <returns>True if the system is XGD, false otherwise</returns>
public static bool IsXGD(this RedumpSystem? system)
{
switch (system)
{
case RedumpSystem.MicrosoftXbox:
case RedumpSystem.MicrosoftXbox360:
case RedumpSystem.MicrosoftXboxOne:
case RedumpSystem.MicrosoftXboxSeriesXS:
return true;
default:
return false;
}
}
}
}

View File

@@ -0,0 +1,121 @@
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MPF.Core.Utilities
{
public static class Logging
{
/// <summary>
/// Process a chunk of text and send it to a handler
/// </summary>
/// <param name="reader">TextReader representing the input</param>
/// <param name="baseClass">Invoking class, passed on to the event handler</param>
/// <param name="handler">Event handler to be invoked to write to log</param>
public static async Task OutputToLog(TextReader reader, object baseClass, EventHandler<string> handler)
{
// Initialize the required variables
char[] buffer = new char[256];
int read = 0;
var sb = new StringBuilder();
try
{
while (true)
{
// Try to read the next chunk of characters
read = await reader.ReadAsync(buffer, 0, buffer.Length);
if (read == 0)
{
Thread.Sleep(10);
continue;
}
// Convert the characters into a string
string line = new string(buffer, 0, read);
// If we have no newline characters, store in the string builder
if (!line.Contains("\r") && !line.Contains("\n"))
sb.Append(line);
// If we have a newline, append and log
else if (line.Contains("\n") || line.Contains("\r\n"))
ProcessNewLines(sb, line, baseClass, handler);
// If we have a carriage return only, append and log first and last instances
else if (line.Contains("\r"))
ProcessCarriageReturns(sb, line, baseClass, handler);
}
}
catch { }
finally
{
handler?.Invoke(baseClass, sb.ToString());
}
}
/// <summary>
/// Process a chunk that contains newlines
/// </summary>
/// <param name="sb">StringBuilder to write from and append to</param>
/// <param name="line">Current line to process</param>
/// <param name="baseClass">Invoking class, passed on to the event handler</param>
/// <param name="handler">Event handler to be invoked to write to log</param>
private static void ProcessNewLines(StringBuilder sb, string line, object baseClass, EventHandler<string> handler)
{
line = line.Replace("\r\n", "\n");
var split = line.Split('\n');
for (int i = 0; i < split.Length; i++)
{
// If the chunk contains a carriage return, handle it like a separate line
if (split[i].Contains("\r"))
{
ProcessCarriageReturns(sb, split[i], baseClass, handler);
continue;
}
// For the first item, append to anything existing and then write out
if (i == 0)
{
sb.Append(split[i]);
handler?.Invoke(baseClass, sb.ToString());
sb.Clear();
}
// For the last item, just append so it's dealt with the next time
else if (i == split.Length - 1)
{
sb.Append(split[i]);
}
// For everything else, directly write out
else
{
handler?.Invoke(baseClass, split[i]);
}
}
}
/// <summary>
/// Process a chunk that contains carriage returns
/// </summary>
/// <param name="sb">StringBuilder to write from and append to</param>
/// <param name="line">Current line to process</param>
/// <param name="baseClass">Invoking class, passed on to the event handler</param>
/// <param name="handler">Event handler to be invoked to write to log</param>
private static void ProcessCarriageReturns(StringBuilder sb, string line, object baseClass, EventHandler<string> handler)
{
var split = line.Split('\r');
// Append and log the first
sb.Append(split[0]);
handler?.Invoke(baseClass, sb.ToString());
// Append the last
sb.Clear();
sb.Append($"\r{split[split.Length - 1]}");
}
}
}

191
MPF.Core/Utilities/Tools.cs Normal file
View File

@@ -0,0 +1,191 @@
using System;
using System.Net;
using System.Reflection;
using MPF.Core.Data;
using Newtonsoft.Json.Linq;
using RedumpLib.Data;
namespace MPF.Core.Utilities
{
public static class Tools
{
#region Byte Arrays
/// <summary>
/// Search for a byte array in another array
/// </summary>
public static bool Contains(this byte[] stack, byte[] needle, out int position, int start = 0, int end = -1)
{
// Initialize the found position to -1
position = -1;
// If either array is null or empty, we can't do anything
if (stack == null || stack.Length == 0 || needle == null || needle.Length == 0)
return false;
// If the needle array is larger than the stack array, it can't be contained within
if (needle.Length > stack.Length)
return false;
// If start or end are not set properly, set them to defaults
if (start < 0)
start = 0;
if (end < 0)
end = stack.Length - needle.Length;
for (int i = start; i < end; i++)
{
if (stack.EqualAt(needle, i))
{
position = i;
return true;
}
}
return false;
}
/// <summary>
/// See if a byte array starts with another
/// </summary>
public static bool StartsWith(this byte[] stack, byte[] needle)
{
return stack.Contains(needle, out int _, start: 0, end: 1);
}
/// <summary>
/// Get if a stack at a certain index is equal to a needle
/// </summary>
private static bool EqualAt(this byte[] stack, byte[] needle, int index)
{
// If we're too close to the end of the stack, return false
if (needle.Length >= stack.Length - index)
return false;
for (int i = 0; i < needle.Length; i++)
{
if (stack[i + index] != needle[i])
return false;
}
return true;
}
#endregion
#region Support
/// <summary>
/// Verify that, given a system and a media type, they are correct
/// </summary>
public static Result GetSupportStatus(RedumpSystem? system, MediaType? type)
{
// No system chosen, update status
if (system == null)
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($"{type.LongName()} ready to dump");
// Partially supported types
case MediaType.GDROM:
case MediaType.NintendoGameCubeGameDisc:
case MediaType.NintendoWiiOpticalDisc:
return Result.Success($"{type.LongName()} partially supported for dumping");
// Special case for other supported tools
case MediaType.UMD:
return Result.Failure($"{type.LongName()} supported for submission info parsing");
// Specifically unknown type
case MediaType.NONE:
return Result.Failure($"Please select a valid media type");
// Undumpable but recognized types
default:
return Result.Failure($"{type.LongName()} media are not supported for dumping");
}
}
#endregion
#region Versioning
/// <summary>
/// Check for a new MPF version
/// </summary>
/// <returns>
/// Bool representing if the values are different.
/// String representing the message to display the the user.
/// String representing the new release URL.
/// </returns>
public static (bool different, string message, string url) CheckForNewVersion()
{
try
{
// Get current assembly version
var assemblyVersion = Assembly.GetEntryAssembly().GetName().Version;
string version = $"{assemblyVersion.Major}.{assemblyVersion.Minor}" + (assemblyVersion.Build != 0 ? $".{assemblyVersion.Build}" : string.Empty);
// Get the latest tag from GitHub
(string tag, string url) = GetRemoteVersionAndUrl();
bool different = version != tag;
string message = $"Local version: {version}"
+ $"{Environment.NewLine}Remote version: {tag}"
+ (different
? $"{Environment.NewLine}The update URL has been added copied to your clipboard"
: $"{Environment.NewLine}You have the newest version!");
return (different, message, url);
}
catch (Exception ex)
{
return (false, ex.ToString(), null);
}
}
/// <summary>
/// Get the current informational version formatted as a string
/// </summary>
public static string GetCurrentVersion()
{
var assemblyVersion = Attribute.GetCustomAttribute(Assembly.GetEntryAssembly(), typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute;
return assemblyVersion.InformationalVersion;
}
/// <summary>
/// Get the latest version of MPF from GitHub and the release URL
/// </summary>
private static (string tag, string url) GetRemoteVersionAndUrl()
{
using (WebClient wc = new WebClient())
{
wc.Headers["User-Agent"] = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0";
// TODO: Figure out a better way than having this hardcoded...
string url = "https://api.github.com/repos/SabreTools/MPF/releases/latest";
string latestReleaseJsonString = wc.DownloadString(url);
var latestReleaseJson = JObject.Parse(latestReleaseJsonString);
string latestTag = latestReleaseJson["tag_name"].ToString();
string releaseUrl = latestReleaseJson["html_url"].ToString();
return (latestTag, releaseUrl);
}
}
#endregion
}
}

238
MPF.CueSheets/CueFile.cs Normal file
View File

@@ -0,0 +1,238 @@
using System;
using System.Collections.Generic;
using System.IO;
/// <remarks>
/// Information sourced from http://web.archive.org/web/20070221154246/http://www.goldenhawk.com/download/cdrwin.pdf
/// </remarks>
namespace MPF.CueSheets
{
/// <summary>
/// The audio or data files filetype
/// </summary>
public enum CueFileType
{
/// <summary>
/// Intel binary file (least significant byte first). Use for data files.
/// </summary>
BINARY,
/// <summary>
/// Motorola binary file (most significant byte first). Use for data files.
/// </summary>
MOTOROLA,
/// <summary>
/// Audio AIFF file (44.1KHz 16-bit stereo)
/// </summary>
AIFF,
/// <summary>
/// Audio WAVE file (44.1KHz 16-bit stereo)
/// </summary>
WAVE,
/// <summary>
/// Audio MP3 file (44.1KHz 16-bit stereo)
/// </summary>
MP3,
}
/// <summary>
/// Represents a single FILE in a cuesheet
/// </summary>
public class CueFile
{
/// <summary>
/// filename
/// </summary>
public string FileName { get; set; }
/// <summary>
/// filetype
/// </summary>
public CueFileType FileType { get; set; }
/// <summary>
/// List of TRACK in FILE
/// </summary>
public List<CueTrack> Tracks { get; set; }
/// <summary>
/// Create an empty FILE
/// </summary>
public CueFile()
{
}
/// <summary>
/// Fill a FILE from an array of lines
/// </summary>
/// <param name="fileName">File name to set</param>
/// <param name="fileType">File type to set</param>
/// <param name="cueLines">Lines array to pull from</param>
/// <param name="i">Reference to index in array</param>
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
public CueFile(string fileName, string fileType, string[] cueLines, ref int i, bool throwOnError = false)
{
if (cueLines == null)
{
if (throwOnError)
throw new ArgumentNullException(nameof(cueLines));
return;
}
else if (i < 0 || i > cueLines.Length)
{
if (throwOnError)
throw new IndexOutOfRangeException();
return;
}
// Set the current fields
this.FileName = fileName.Trim('"');
this.FileType = GetFileType(fileType);
// Increment to start
i++;
for (; i < cueLines.Length; i++)
{
string line = cueLines[i].Trim();
string[] splitLine = line.Split(' ');
// If we have an empty line, we skip
if (string.IsNullOrWhiteSpace(line))
continue;
switch (splitLine[0])
{
// Read comments
case "REM":
// We ignore all comments for now
break;
// Read track information
case "TRACK":
if (splitLine.Length < 3)
{
if (throwOnError)
throw new FormatException($"TRACK line malformed: {line}");
continue;
}
if (this.Tracks == null)
this.Tracks = new List<CueTrack>();
var track = new CueTrack(splitLine[1], splitLine[2], cueLines, ref i);
if (track == default)
{
if (throwOnError)
throw new FormatException($"TRACK line malformed: {line}");
continue;
}
this.Tracks.Add(track);
break;
// Default means return
default:
i--;
return;
}
}
}
/// <summary>
/// Write the FILE out to a stream
/// </summary>
/// <param name="sw">StreamWriter to write to</param>
/// <param name="throwOnError">True if errors throw an exception, false otherwise</param>
public void Write(StreamWriter sw, bool throwOnError = false)
{
// If we don't have any tracks, it's invalid
if (this.Tracks == null)
{
if (throwOnError)
throw new ArgumentNullException(nameof(this.Tracks));
return;
}
else if (this.Tracks.Count == 0)
{
if (throwOnError)
throw new ArgumentException("No tracks provided to write");
return;
}
sw.WriteLine($"FILE \"{this.FileName}\" {FromFileType(this.FileType)}");
foreach (var track in Tracks)
{
track.Write(sw);
}
}
/// <summary>
/// Get the file type from a given string
/// </summary>
/// <param name="fileType">String to get value from</param>
/// <returns>CueFileType, if possible</returns>
private CueFileType GetFileType(string fileType)
{
switch (fileType.ToLowerInvariant())
{
case "binary":
return CueFileType.BINARY;
case "motorola":
return CueFileType.MOTOROLA;
case "aiff":
return CueFileType.AIFF;
case "wave":
return CueFileType.WAVE;
case "mp3":
return CueFileType.MP3;
default:
return CueFileType.BINARY;
}
}
/// <summary>
/// Get the string from a given file type
/// </summary>
/// <param name="fileType">CueFileType to get value from</param>
/// <returns>String, if possible (default BINARY)</returns>
private string FromFileType(CueFileType fileType)
{
switch (fileType)
{
case CueFileType.BINARY:
return "BINARY";
case CueFileType.MOTOROLA:
return "MOTOROLA";
case CueFileType.AIFF:
return "AIFF";
case CueFileType.WAVE:
return "WAVE";
case CueFileType.MP3:
return "MP3";
default:
return string.Empty;
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More