mirror of
https://github.com/SabreTools/MPF.git
synced 2026-02-04 13:45:29 +00:00
Compare commits
1224 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
def499769f | ||
|
|
5e1e61a441 | ||
|
|
4896a12ec5 | ||
|
|
b28ad5d3cd | ||
|
|
4cdbbcedf0 | ||
|
|
6ab63ba651 | ||
|
|
d36c5099f3 | ||
|
|
8ba8347a0c | ||
|
|
4c5184eac5 | ||
|
|
9914b94716 | ||
|
|
150e69eca5 | ||
|
|
f09923974b | ||
|
|
d98bc28930 | ||
|
|
ee4a7ab653 | ||
|
|
6b20aee320 | ||
|
|
a5849325f3 | ||
|
|
86d2d83fbe | ||
|
|
308e0d6937 | ||
|
|
3541bca2d0 | ||
|
|
2496099532 | ||
|
|
6001395181 | ||
|
|
fa2192a284 | ||
|
|
f09155936e | ||
|
|
a07fca6a7b | ||
|
|
5fe7a1dac8 | ||
|
|
16ed2f9595 | ||
|
|
9004d2bc7b | ||
|
|
cc98b38290 | ||
|
|
18ef0cddff | ||
|
|
d9ca55d96c | ||
|
|
816c94de58 | ||
|
|
c2ba58148a | ||
|
|
d9533f2448 | ||
|
|
5126d1854c | ||
|
|
6baaf132a7 | ||
|
|
98a30e6558 | ||
|
|
0912b78568 | ||
|
|
d92a1d566d | ||
|
|
ff40d18ed3 | ||
|
|
4d9cd85ba6 | ||
|
|
b6ae390cee | ||
|
|
4692028cfb | ||
|
|
3ada7db916 | ||
|
|
aa4b2f415d | ||
|
|
56e91bf177 | ||
|
|
228c752585 | ||
|
|
6ce7ccfa91 | ||
|
|
c8c98278b6 | ||
|
|
0fc57c58cf | ||
|
|
3dcac28488 | ||
|
|
4cd7073bf6 | ||
|
|
1af21e7aba | ||
|
|
52adcd0b46 | ||
|
|
8a91593e58 | ||
|
|
729f8273fc | ||
|
|
78df6f6583 | ||
|
|
dc8dae4df7 | ||
|
|
53db9dbf81 | ||
|
|
22755a4af9 | ||
|
|
ba28b414ba | ||
|
|
95d10ecb1e | ||
|
|
c5ab2c747a | ||
|
|
476c494f4e | ||
|
|
758c49c1cc | ||
|
|
d80ad3b3cf | ||
|
|
3d06f80703 | ||
|
|
7344460409 | ||
|
|
19f58d9dde | ||
|
|
ad9f39f832 | ||
|
|
d51117b058 | ||
|
|
0d65d5114a | ||
|
|
30fec3c3d0 | ||
|
|
8eb86fde90 | ||
|
|
7616c6b2ba | ||
|
|
e0742cdfc7 | ||
|
|
a19937d630 | ||
|
|
fa92402bc5 | ||
|
|
cdc3da5839 | ||
|
|
3430f8c1db | ||
|
|
12fd55e76c | ||
|
|
0013606d61 | ||
|
|
4d520d7d63 | ||
|
|
7bfe174680 | ||
|
|
4951e7bf42 | ||
|
|
d7d9c468ae | ||
|
|
32faa33ad3 | ||
|
|
8a5475380a | ||
|
|
1dd5542390 | ||
|
|
5156b89eca | ||
|
|
83ea04c880 | ||
|
|
8695d2981e | ||
|
|
e0c299e6f0 | ||
|
|
16ec54f389 | ||
|
|
998bf5d5fa | ||
|
|
07ec821e9a | ||
|
|
56cf8f3574 | ||
|
|
c6ebfcd6d9 | ||
|
|
6ceffce63d | ||
|
|
f43aafc00d | ||
|
|
ab598d8377 | ||
|
|
dbd876a1c1 | ||
|
|
fd102cb56b | ||
|
|
0afb49b657 | ||
|
|
be980fe0c4 | ||
|
|
08b4e8d602 | ||
|
|
e483e1cdc6 | ||
|
|
5c2dce78e2 | ||
|
|
26ea383775 | ||
|
|
64938fd7f1 | ||
|
|
22318ee3c1 | ||
|
|
b2b54a2706 | ||
|
|
40f04e0321 | ||
|
|
a7638b8063 | ||
|
|
2abcad2a0f | ||
|
|
e088b05de4 | ||
|
|
a31d894b79 | ||
|
|
34fae4572d | ||
|
|
1ecf0ad1fa | ||
|
|
7c7509020f | ||
|
|
7c6b118282 | ||
|
|
c154a844e3 | ||
|
|
088f1b8545 | ||
|
|
fc3c636bdd | ||
|
|
14c807c882 | ||
|
|
d0e9c51786 | ||
|
|
b428bc0ba0 | ||
|
|
6dbbb91438 | ||
|
|
2066d36424 | ||
|
|
29552cd39d | ||
|
|
640e7091cc | ||
|
|
af12c18d2e | ||
|
|
f28cf614c3 | ||
|
|
888cb8ec9f | ||
|
|
04035ac524 | ||
|
|
600374eb2d | ||
|
|
6ecb932a82 | ||
|
|
4cbc9ac109 | ||
|
|
5ee0b7345b | ||
|
|
cc55330fad | ||
|
|
6589380fdf | ||
|
|
bd45482bf7 | ||
|
|
e14c8a8f03 | ||
|
|
4ac00e9a1a | ||
|
|
edf983e304 | ||
|
|
01a69ef9b3 | ||
|
|
a368afc14a | ||
|
|
d83fed16f5 | ||
|
|
949df08690 | ||
|
|
ab3abb5b3e | ||
|
|
d16e73a530 | ||
|
|
3f8c55ca47 | ||
|
|
2e9aaa50f9 | ||
|
|
36951dc5da | ||
|
|
b39c8dd738 | ||
|
|
a1155cf9b7 | ||
|
|
1d151d213e | ||
|
|
6dc0c1438a | ||
|
|
8739569db6 | ||
|
|
0dcba9ce71 | ||
|
|
8d37b85e12 | ||
|
|
43cf8e1a45 | ||
|
|
7317553483 | ||
|
|
0b342e265c | ||
|
|
08359dd45f | ||
|
|
a24415cae6 | ||
|
|
59f8161308 | ||
|
|
51f955a14c | ||
|
|
ddebdef00c | ||
|
|
6a4b6d613a | ||
|
|
97aef5e29c | ||
|
|
9549178c3a | ||
|
|
c531539c87 | ||
|
|
fa04461631 | ||
|
|
83d230dfe1 | ||
|
|
ca18bbb72c | ||
|
|
de0f2c1ad9 | ||
|
|
2f0019282e | ||
|
|
72ca479c9f | ||
|
|
de3c4362e7 | ||
|
|
987348fee8 | ||
|
|
100e012fe6 | ||
|
|
af59ebe1ff | ||
|
|
0762c88655 | ||
|
|
bbe9c94545 | ||
|
|
c7efda7da8 | ||
|
|
5c78f9bc29 | ||
|
|
e7c17c7b4b | ||
|
|
7a2497f168 | ||
|
|
5172f6f253 | ||
|
|
9017472fa4 | ||
|
|
6659c410c6 | ||
|
|
8c7b66a2f5 | ||
|
|
8f57d78200 | ||
|
|
ad2ee9efa8 | ||
|
|
192964f65a | ||
|
|
672f30af35 | ||
|
|
a7a17298f2 | ||
|
|
e17ad8e4a1 | ||
|
|
2a544676e6 | ||
|
|
6abfa9581d | ||
|
|
a6de548e5d | ||
|
|
9dc3e579b5 | ||
|
|
c5be7d7f73 | ||
|
|
70c0da703b | ||
|
|
1cbe81fba6 | ||
|
|
420e356f34 | ||
|
|
0e0ff0cb80 | ||
|
|
9003d05ae2 | ||
|
|
c247225cac | ||
|
|
4bccaa8ecf | ||
|
|
b579fec7ab | ||
|
|
37e4525c98 | ||
|
|
2269537848 | ||
|
|
441fb91222 | ||
|
|
89e0473019 | ||
|
|
3e13b35c84 | ||
|
|
fd4910fc36 | ||
|
|
964685770f | ||
|
|
634d64b5a1 | ||
|
|
19ec1c448f | ||
|
|
e3532d6f02 | ||
|
|
aaf0aabb55 | ||
|
|
575a5936ca | ||
|
|
391d265353 | ||
|
|
f90d19821c | ||
|
|
b79babf57e | ||
|
|
a929bb0022 | ||
|
|
975eb97e27 | ||
|
|
49800cf0ed | ||
|
|
de18609e00 | ||
|
|
9911446bf9 | ||
|
|
a9223211ab | ||
|
|
54c4eeba03 | ||
|
|
a30ee3e6ff | ||
|
|
1fa19489a3 | ||
|
|
f6298dfe89 | ||
|
|
79802a53f6 | ||
|
|
54bf43fd6b | ||
|
|
bb2b2f668b | ||
|
|
ecca27e012 | ||
|
|
fe0699ca48 | ||
|
|
73b2f0921f | ||
|
|
c56230c3af | ||
|
|
919b62822d | ||
|
|
21b0c9a08d | ||
|
|
63fafd05b3 | ||
|
|
0a2493a953 | ||
|
|
87ab750714 | ||
|
|
5cf3eca9eb | ||
|
|
b4a079b65f | ||
|
|
7f2d501edf | ||
|
|
c981f94092 | ||
|
|
afba46b8b0 | ||
|
|
4e416df3c8 | ||
|
|
1b54e52351 | ||
|
|
5e1568a148 | ||
|
|
8f0ac56cf8 | ||
|
|
37f0f9d4a4 | ||
|
|
a48f75c704 | ||
|
|
58a683e3c9 | ||
|
|
907637b128 | ||
|
|
85f3e97a44 | ||
|
|
beae9691fd | ||
|
|
b7876d54cc | ||
|
|
5b24223cb5 | ||
|
|
88cadff9ef | ||
|
|
b92b39e7eb | ||
|
|
8d29a29591 | ||
|
|
daf516bf9c | ||
|
|
115d9857af | ||
|
|
b322146e9e | ||
|
|
b6e3c9da82 | ||
|
|
6abdc632dc | ||
|
|
335ca6d5ac | ||
|
|
8752426694 | ||
|
|
5357ba5900 | ||
|
|
f2686096bd | ||
|
|
c4ef14ea3c | ||
|
|
03668bd6af | ||
|
|
2d90a63ca7 | ||
|
|
11e6e37331 | ||
|
|
b229a2d59e | ||
|
|
c61af9316f | ||
|
|
02e3040e1b | ||
|
|
60bbe29435 | ||
|
|
3274ea08aa | ||
|
|
97a61dea32 | ||
|
|
6cccf20b03 | ||
|
|
0a7e17ed00 | ||
|
|
706f75c0eb | ||
|
|
022e87c4bb | ||
|
|
8b29ac7e47 | ||
|
|
4d5b8baf6f | ||
|
|
e199e5a08c | ||
|
|
6cc2351bf7 | ||
|
|
c391dbd3c8 | ||
|
|
709d980b67 | ||
|
|
0903855d5c | ||
|
|
6ad2505bf8 | ||
|
|
5db8756639 | ||
|
|
5d176408a2 | ||
|
|
ab0b569798 | ||
|
|
ee76d49e56 | ||
|
|
c75d2dcae2 | ||
|
|
7c411d36db | ||
|
|
ca767cf576 | ||
|
|
b57e0bb97e | ||
|
|
5f059253a4 | ||
|
|
e0f8443653 | ||
|
|
4c23a4bbf3 | ||
|
|
0c1486bbce | ||
|
|
6f41c9a331 | ||
|
|
2879dd29d6 | ||
|
|
42e1ef45b4 | ||
|
|
19493fdf0c | ||
|
|
5870ad0673 | ||
|
|
cbd2850d1b | ||
|
|
e7c36c104a | ||
|
|
960840d9ba | ||
|
|
b8ac1bc9d4 | ||
|
|
89edf9a8f6 | ||
|
|
eb8db0b311 | ||
|
|
b10cf8b78a | ||
|
|
1dd5c0d6d0 | ||
|
|
a1e00d23a4 | ||
|
|
1a9d38dd0e | ||
|
|
2f3e7d105d | ||
|
|
a72b3c32b1 | ||
|
|
a479b16ae2 | ||
|
|
a9e7b6f5b3 | ||
|
|
60605d7d00 | ||
|
|
9dc7f726e9 | ||
|
|
46134032d6 | ||
|
|
9847c8f351 | ||
|
|
7b506586cd | ||
|
|
40bbd422b7 | ||
|
|
285fd69ab4 | ||
|
|
b436e19bbb | ||
|
|
bf6e079289 | ||
|
|
b623866b6e | ||
|
|
df7046723c | ||
|
|
3cd3047790 | ||
|
|
abd60612c5 | ||
|
|
02292acee1 | ||
|
|
c923899898 | ||
|
|
fcdd2ad036 | ||
|
|
02d3af0ac1 | ||
|
|
0516bccece | ||
|
|
2d6389d54d | ||
|
|
60d5a117b5 | ||
|
|
9b7e2e35f5 | ||
|
|
ddfb383f23 | ||
|
|
a1707486f4 | ||
|
|
451101ec67 | ||
|
|
83c583b7e6 | ||
|
|
33cb3d3c97 | ||
|
|
3d98f345c1 | ||
|
|
de8ce5c110 | ||
|
|
fd9ed77316 | ||
|
|
d974b73cce | ||
|
|
da8a67fcad | ||
|
|
471bc60ed7 | ||
|
|
fef46be34c | ||
|
|
9a92dbdedb | ||
|
|
d6be0a4154 | ||
|
|
d3ae372903 | ||
|
|
7621ef1a13 | ||
|
|
148fdd0590 | ||
|
|
232256310a | ||
|
|
5e938791ef | ||
|
|
08405dd9b4 | ||
|
|
512c637ea3 | ||
|
|
909ebd72a1 | ||
|
|
123136e90e | ||
|
|
299d25af27 | ||
|
|
9eee2f6444 | ||
|
|
2afb10b73b | ||
|
|
1b016e5915 | ||
|
|
1c403e1748 | ||
|
|
a372a133ca | ||
|
|
08a7df504b | ||
|
|
39f9d9a86d | ||
|
|
bdd5af65ce | ||
|
|
92d7d2ab91 | ||
|
|
8d4d7ce449 | ||
|
|
d2d650cace | ||
|
|
772cefd700 | ||
|
|
e20350160b | ||
|
|
08f4e91b27 | ||
|
|
021237bc38 | ||
|
|
78c36db2f9 | ||
|
|
7fd2562cb5 | ||
|
|
15a3be2e66 | ||
|
|
9b6a540ec6 | ||
|
|
2b51085bc2 | ||
|
|
822134070b | ||
|
|
26cd874779 | ||
|
|
9f21b68541 | ||
|
|
e49d95663b | ||
|
|
2c70392ada | ||
|
|
1b2248b1e7 | ||
|
|
a322dc6353 | ||
|
|
7c78ae47c6 | ||
|
|
a14dec1b7e | ||
|
|
53b5862697 | ||
|
|
83d379c7b5 | ||
|
|
be33db8339 | ||
|
|
97e9924a0b | ||
|
|
7daab55639 | ||
|
|
9d70b7469a | ||
|
|
b5504902c4 | ||
|
|
f5e82ccd75 | ||
|
|
f4c4c21a10 | ||
|
|
661d2440f2 | ||
|
|
f4af8097f6 | ||
|
|
e1822905e7 | ||
|
|
e5154dad5b | ||
|
|
30f8932039 | ||
|
|
c4f0792c77 | ||
|
|
79c7f13ff9 | ||
|
|
dbeeb0c69b | ||
|
|
58c53ff5e2 | ||
|
|
87c441887a | ||
|
|
8ee4dab239 | ||
|
|
e01ebf8d8e | ||
|
|
e92bcd378c | ||
|
|
80156e73d1 | ||
|
|
97803cd860 | ||
|
|
9a5feee095 | ||
|
|
84410056bd | ||
|
|
acd0e41703 | ||
|
|
c7dfb9dca7 | ||
|
|
0efd82bd59 | ||
|
|
426ceff451 | ||
|
|
f2be7ed34c | ||
|
|
5dcc783b95 | ||
|
|
d1c641e934 | ||
|
|
59be63785d | ||
|
|
0bf85ec729 | ||
|
|
b54c2dc254 | ||
|
|
021fcd0641 | ||
|
|
f2dadae7a3 | ||
|
|
7ce7df2625 | ||
|
|
09fcd384ab | ||
|
|
5f8625a384 | ||
|
|
621011af7a | ||
|
|
a0b81941d1 | ||
|
|
e735335773 | ||
|
|
7b62572a56 | ||
|
|
0f921c926b | ||
|
|
4d8a4d23c0 | ||
|
|
9d7eaa46fd | ||
|
|
cc9664f7d6 | ||
|
|
573b3e9d1c | ||
|
|
9808694d89 | ||
|
|
d70d8f5b6e | ||
|
|
b75c2d80bf | ||
|
|
aa747ff651 | ||
|
|
bcbf5daf0d | ||
|
|
aee1c05a45 | ||
|
|
0bb96a8dd3 | ||
|
|
1e1d2c7b63 | ||
|
|
f12375cddc | ||
|
|
ed26e6611a | ||
|
|
98f77eca07 | ||
|
|
1b2b560f8f | ||
|
|
b49cc0c9bd | ||
|
|
4ba58ea861 | ||
|
|
3f52a20c90 | ||
|
|
580089d06e | ||
|
|
1397ab0fa6 | ||
|
|
87400793eb | ||
|
|
45f79d95b1 | ||
|
|
c8a4a61028 | ||
|
|
44091981b2 | ||
|
|
d3352643fc | ||
|
|
114c7fb38a | ||
|
|
dc7da708dc | ||
|
|
72e56aa1c7 | ||
|
|
99ceab07ad | ||
|
|
c0f6c072ce | ||
|
|
e039124f6c | ||
|
|
c96e4a4c7a | ||
|
|
622a08acf3 | ||
|
|
f44b6bf0d0 | ||
|
|
a6d75e15ea | ||
|
|
a02f03c4cb | ||
|
|
d48f5132fb | ||
|
|
ed4ac24efa | ||
|
|
9f3b8a7c2c | ||
|
|
612d4bb1f5 | ||
|
|
b58a50d246 | ||
|
|
af83811d57 | ||
|
|
66835fe6ab | ||
|
|
34cc1d33c6 | ||
|
|
a42d14e3b8 | ||
|
|
87aa165edf | ||
|
|
d217d62007 | ||
|
|
27bcc0d40a | ||
|
|
e1df075cde | ||
|
|
8358692e8d | ||
|
|
e1fae01dab | ||
|
|
d206ab140a | ||
|
|
9d8722ab17 | ||
|
|
c4fa40c403 | ||
|
|
1d0b06bfbe | ||
|
|
2cdf473dcb | ||
|
|
1af9e2c2da | ||
|
|
9a1815fa1e | ||
|
|
f601961c49 | ||
|
|
406acd34c5 | ||
|
|
31cdcbbc25 | ||
|
|
2215ce71c9 | ||
|
|
1872fbb1c8 | ||
|
|
d99f912ac2 | ||
|
|
00a76fb648 | ||
|
|
187e951a47 | ||
|
|
c0b9b27aae | ||
|
|
b76bb17396 | ||
|
|
2efa6d3623 | ||
|
|
3972ce633d | ||
|
|
0dc7901393 | ||
|
|
a25ba6eaa5 | ||
|
|
4ea48dfe57 | ||
|
|
8f7ad8b2ee | ||
|
|
3b9800df07 | ||
|
|
4c80d3234e | ||
|
|
9e4af1d66b | ||
|
|
73555df2ea | ||
|
|
3ca78604fd | ||
|
|
0138046923 | ||
|
|
2129184209 | ||
|
|
dd2116f8a6 | ||
|
|
814c2d9149 | ||
|
|
b3f7276044 | ||
|
|
ad88aa980b | ||
|
|
aca55e9203 | ||
|
|
cc3330bb27 | ||
|
|
1370909db7 | ||
|
|
08cc0c394b | ||
|
|
cb6692aea3 | ||
|
|
b3badb3a55 | ||
|
|
cbf73901d3 | ||
|
|
4822e45d58 | ||
|
|
1d930d36bf | ||
|
|
9effcc403d | ||
|
|
05dcc039bd | ||
|
|
cb08656abc | ||
|
|
69b22fc736 | ||
|
|
bf857f6ce7 | ||
|
|
7ebf2378b3 | ||
|
|
aec25dab37 | ||
|
|
e11969780d | ||
|
|
02c98b1547 | ||
|
|
c864589478 | ||
|
|
bdea1593be | ||
|
|
f6b78c07ca | ||
|
|
982a217d32 | ||
|
|
06588752ad | ||
|
|
9b057d7141 | ||
|
|
93fb3a85b5 | ||
|
|
7320f9ba66 | ||
|
|
a94f43ae0c | ||
|
|
e19a3f02e5 | ||
|
|
375c2c896c | ||
|
|
b151e79aed | ||
|
|
b45901c133 | ||
|
|
fab54ca0ae | ||
|
|
31dd32f19b | ||
|
|
f51c79d282 | ||
|
|
743c943363 | ||
|
|
91f6e266d1 | ||
|
|
8e843647bf | ||
|
|
151402dc50 | ||
|
|
057f340c9c | ||
|
|
f3f9c63156 | ||
|
|
7910a79917 | ||
|
|
cc7acfcd00 | ||
|
|
5580e208f5 | ||
|
|
56ef06d651 | ||
|
|
204dfca126 | ||
|
|
eb337a8aaf | ||
|
|
aa6fd781e8 | ||
|
|
32bcfa1d42 | ||
|
|
3b2e14d0de | ||
|
|
88a0ce38f9 | ||
|
|
110c8337aa | ||
|
|
3dc79fea6b | ||
|
|
fb036385f9 | ||
|
|
428bb2817b | ||
|
|
791caff240 | ||
|
|
d92015d071 | ||
|
|
de98bd9e0b | ||
|
|
67f5a7794a | ||
|
|
fbef94f634 | ||
|
|
0e8363f06e | ||
|
|
a1bafe0426 | ||
|
|
c51461592c | ||
|
|
ef5f996ec4 | ||
|
|
aa5998a52e | ||
|
|
37207c1cb0 | ||
|
|
d1813fdbc7 | ||
|
|
faf9d1d6f8 | ||
|
|
0360df0604 | ||
|
|
fe6487eeb4 | ||
|
|
b9eedd1cf6 | ||
|
|
26281b8f0b | ||
|
|
f0508fdf93 | ||
|
|
166d69c7ec | ||
|
|
fabf08ba55 | ||
|
|
0e5d8af0e9 | ||
|
|
3e1263ebff | ||
|
|
c0ed830241 | ||
|
|
4209158807 | ||
|
|
6d79ebf449 | ||
|
|
88ab691f07 | ||
|
|
37b1dc574c | ||
|
|
ad56e249ed | ||
|
|
f28cfe3d69 | ||
|
|
9643442281 | ||
|
|
dd44ec7ac1 | ||
|
|
801c1126cf | ||
|
|
4fd72efc46 | ||
|
|
9ec045cb21 | ||
|
|
52801ee94c | ||
|
|
2077d53964 | ||
|
|
14046e9217 | ||
|
|
2766debffc | ||
|
|
4f4688899c | ||
|
|
8151db9696 | ||
|
|
227c61b588 | ||
|
|
61224fba7b | ||
|
|
1dbf5516d8 | ||
|
|
10fe6ac32a | ||
|
|
e39ee66726 | ||
|
|
fff2db75d0 | ||
|
|
3a14db53c6 | ||
|
|
8b76b82e0f | ||
|
|
e110c55e1a | ||
|
|
85c30fbad3 | ||
|
|
14e5c74c65 | ||
|
|
b180e31b56 | ||
|
|
d172a45891 | ||
|
|
e74289116e | ||
|
|
68b932bad0 | ||
|
|
c4793e849c | ||
|
|
1c525a6d2e | ||
|
|
c8610ee16a | ||
|
|
0fb3bc1106 | ||
|
|
3cf133d750 | ||
|
|
f0be6b0bc9 | ||
|
|
e0ccb8b10d | ||
|
|
940afae1fd | ||
|
|
94ba339ef2 | ||
|
|
bfead10d87 | ||
|
|
97f9a73fc1 | ||
|
|
7f4921a47c | ||
|
|
07359d2a63 | ||
|
|
e5ba670c04 | ||
|
|
3096c369d3 | ||
|
|
333368675a | ||
|
|
d78d744ae2 | ||
|
|
a8efe056c1 | ||
|
|
9b2475a854 | ||
|
|
33e2b27e6d | ||
|
|
91fe9d9bec | ||
|
|
b1b9b3134f | ||
|
|
ca5386b529 | ||
|
|
347beca874 | ||
|
|
27ca4fd1af | ||
|
|
6d57a05f8c | ||
|
|
4d81449cfa | ||
|
|
76fcb3ae10 | ||
|
|
b913f5f9ae | ||
|
|
68fa1eecfb | ||
|
|
dc84f17ac5 | ||
|
|
c91137130b | ||
|
|
972b07551f | ||
|
|
61562fe995 | ||
|
|
01b6c3cc98 | ||
|
|
b461dc76b9 | ||
|
|
03eeed4113 | ||
|
|
07615cb336 | ||
|
|
9a9a977cc4 | ||
|
|
ab5869331b | ||
|
|
1c9ebfd703 | ||
|
|
a9bc3587a6 | ||
|
|
b1af2b6061 | ||
|
|
2fccd53098 | ||
|
|
a7ad3e41d9 | ||
|
|
1fc6476f71 | ||
|
|
53e5a1b1b1 | ||
|
|
119e9dc4cc | ||
|
|
9263769906 | ||
|
|
ebaf9539b2 | ||
|
|
818fb5ab34 | ||
|
|
2f514082a9 | ||
|
|
5c5379e972 | ||
|
|
c39894d9fc | ||
|
|
2c6cf0e736 | ||
|
|
7e96bbee27 | ||
|
|
f7019546d1 | ||
|
|
086f54abf0 | ||
|
|
143a4149bd | ||
|
|
20aed68d58 | ||
|
|
7a2061a36e | ||
|
|
191c7b080e | ||
|
|
aab0813688 | ||
|
|
9ad564772c | ||
|
|
20bb34c3c7 | ||
|
|
b15ddf390b | ||
|
|
18d1562ad3 | ||
|
|
d6f2ecbd25 | ||
|
|
3620686afa | ||
|
|
1524224bc3 | ||
|
|
35200d53d6 | ||
|
|
4b7d4e05e7 | ||
|
|
7e73f69433 | ||
|
|
9e1a972df5 | ||
|
|
1edac34c1a | ||
|
|
9adc588c9c | ||
|
|
71bfdcba8f | ||
|
|
9854c9970a | ||
|
|
0c68164d6d | ||
|
|
a413357b57 | ||
|
|
5e283c9e80 | ||
|
|
500eb66e30 | ||
|
|
411e5245a5 | ||
|
|
d270501c2d | ||
|
|
f7f924593f | ||
|
|
5126a66eb9 | ||
|
|
7fddef238d | ||
|
|
ace673f90d | ||
|
|
e063df63df | ||
|
|
22b15710d0 | ||
|
|
87199c1b0d | ||
|
|
7e5952bbb8 | ||
|
|
1a52a3a205 | ||
|
|
742db4c854 | ||
|
|
4fd51dbe45 | ||
|
|
096a8a6a06 | ||
|
|
ad5cd5b8f9 | ||
|
|
3230d59f6a | ||
|
|
96fa8d8cef | ||
|
|
01bf3c9efb | ||
|
|
da0bf64e94 | ||
|
|
d39cf5d13f | ||
|
|
7c7e78fd4e | ||
|
|
d2c504898a | ||
|
|
58028b4f18 | ||
|
|
54e835687b | ||
|
|
10f2318541 | ||
|
|
eb4e95e5db | ||
|
|
203418eebc | ||
|
|
136c6c8fbf | ||
|
|
2c216d6a58 | ||
|
|
f7ec19cc5d | ||
|
|
e8c4a97158 | ||
|
|
5e5fc4c812 | ||
|
|
5e0d99ff5d | ||
|
|
e88e67c927 | ||
|
|
d963dbbd5f | ||
|
|
11ce78fca2 | ||
|
|
fd4022ba84 | ||
|
|
f91aecad8e | ||
|
|
709b7d357f | ||
|
|
59980fa160 | ||
|
|
180caf83cc | ||
|
|
7047ee832a | ||
|
|
4b5532e1b0 | ||
|
|
137155d3dc | ||
|
|
793dd8289a | ||
|
|
bcf298e40b | ||
|
|
589aef1e21 | ||
|
|
9ab0b7ab3b | ||
|
|
4c5ea13aac | ||
|
|
0cf48bbdaa | ||
|
|
8fc9cc18a3 | ||
|
|
b1e156eed6 | ||
|
|
a8b3a837ef | ||
|
|
3f3a1c9a44 | ||
|
|
cf4d2f5055 | ||
|
|
2d19d51bc7 | ||
|
|
4842bdd38b | ||
|
|
7cc4f6d6a7 | ||
|
|
b284ffd99d | ||
|
|
81d0cc2cc2 | ||
|
|
70f368d6e9 | ||
|
|
bfbae5cf5c | ||
|
|
7cc231f5fd | ||
|
|
eda34b3477 | ||
|
|
bfb67ec0c9 | ||
|
|
275fd0da48 | ||
|
|
1ad5c25ed0 | ||
|
|
512f7ae016 | ||
|
|
3a00efc7fd | ||
|
|
3068c74ad7 | ||
|
|
9bdead5616 | ||
|
|
0ed5feb96b | ||
|
|
ec80ef2ede | ||
|
|
617591cc26 | ||
|
|
c855aa5cef | ||
|
|
e2a27479f5 | ||
|
|
c8cfe76aa3 | ||
|
|
ecb0234258 | ||
|
|
24ce4bcc51 | ||
|
|
162af3de31 | ||
|
|
7c0af96dc9 | ||
|
|
026f999b46 | ||
|
|
bbbc3e98a0 | ||
|
|
f78ad4e7b6 | ||
|
|
d756ae2163 | ||
|
|
701738ce25 | ||
|
|
620bdc9132 | ||
|
|
71f474c26c | ||
|
|
c48137a5c1 | ||
|
|
e248368484 | ||
|
|
7225b8c32d | ||
|
|
20e475e130 | ||
|
|
88dc005592 | ||
|
|
40792ff0eb | ||
|
|
6ae59e91de | ||
|
|
5c7aa5f7f5 | ||
|
|
aaa1ed674f | ||
|
|
42def3bbe5 | ||
|
|
9cdab52556 | ||
|
|
5c104ebf3d | ||
|
|
7ab72e542c | ||
|
|
3a8420cd2f | ||
|
|
916aa9fd70 | ||
|
|
8809df10b6 | ||
|
|
34d65a9d70 | ||
|
|
2830d7c8a2 | ||
|
|
c702c8b0ac | ||
|
|
e1df9a9754 | ||
|
|
03fe5ce8a5 | ||
|
|
432a9dda16 | ||
|
|
1dfc0f731e | ||
|
|
af515e0adf | ||
|
|
2222b57143 | ||
|
|
d8cfa2e6a4 | ||
|
|
a622cdd4e0 | ||
|
|
2a4ec83d0d | ||
|
|
b1d144d091 | ||
|
|
23a8b66c16 | ||
|
|
381ebd5961 | ||
|
|
b4d1f7d6c3 | ||
|
|
b3eff64275 | ||
|
|
f15c00acca | ||
|
|
a66d0d4722 | ||
|
|
66cdade01b | ||
|
|
9e9f001768 | ||
|
|
3514bdcbc4 | ||
|
|
312df37365 | ||
|
|
6214d91940 | ||
|
|
23d500434b | ||
|
|
7ee5e3ab43 | ||
|
|
6be4bb7c85 | ||
|
|
d620c13e22 | ||
|
|
73b585cdd2 | ||
|
|
2f33581e4a | ||
|
|
f3dba9a026 | ||
|
|
d7d0af369c | ||
|
|
2ab9a45a71 | ||
|
|
dc0bf642a9 | ||
|
|
9e32435972 | ||
|
|
c2b724e949 | ||
|
|
195d3c6ff7 | ||
|
|
04a8079cee | ||
|
|
0b2daf7d30 | ||
|
|
1353ee603b | ||
|
|
e9d272d139 | ||
|
|
0308c7a81e | ||
|
|
4caad10c9b | ||
|
|
85c1623d33 | ||
|
|
5be1825bb5 | ||
|
|
ec5e533bd8 | ||
|
|
c3e4c7fa78 | ||
|
|
bf66a3fcbd | ||
|
|
101193cb78 | ||
|
|
b610c29be6 | ||
|
|
999c4dceb5 | ||
|
|
2957370fac | ||
|
|
5dd36d7b06 | ||
|
|
47b5bbe7e7 | ||
|
|
5a2e4ca77e | ||
|
|
c479ddb80b | ||
|
|
da1f59e0c1 | ||
|
|
9574832e86 | ||
|
|
3df7842d23 | ||
|
|
62a0f6e49a | ||
|
|
60c180e4dd | ||
|
|
343d937362 | ||
|
|
f20b321433 | ||
|
|
ba19b0825f | ||
|
|
5abb44957c | ||
|
|
b9d9cf812f | ||
|
|
d1529f428a | ||
|
|
5061a79c4c | ||
|
|
eab3e25cf2 | ||
|
|
33e73a8992 | ||
|
|
a63972b549 | ||
|
|
bc57df7fc1 | ||
|
|
e16f616286 | ||
|
|
c5497d787b | ||
|
|
64f60004c4 | ||
|
|
020c063177 | ||
|
|
a3e6f8157f | ||
|
|
f27040cd1c | ||
|
|
3a490cfc8d | ||
|
|
1f8c5998c1 | ||
|
|
f96d4ee37e | ||
|
|
d0d15f03af | ||
|
|
eff6407206 | ||
|
|
c1e559568a | ||
|
|
ef030b290c | ||
|
|
71630591a1 | ||
|
|
31505745be | ||
|
|
e40444b60c | ||
|
|
44edf387a6 | ||
|
|
d3d225644d | ||
|
|
3afd9200a9 | ||
|
|
c5c340ff12 | ||
|
|
b28b85f7c6 | ||
|
|
c60684b83c | ||
|
|
a183a1ec91 | ||
|
|
abd8488185 | ||
|
|
e6dea158e5 | ||
|
|
24150c7b3c | ||
|
|
040720a1c2 | ||
|
|
70d30d370f | ||
|
|
a50b99da07 | ||
|
|
2cecbe69ad | ||
|
|
557410660f | ||
|
|
0d75dbaaa2 | ||
|
|
d38f95c73a | ||
|
|
c9d59a90e4 | ||
|
|
fc6a34d987 | ||
|
|
8acabb692f | ||
|
|
61f8871839 | ||
|
|
69d61ad185 | ||
|
|
27391ed31b | ||
|
|
ed56c92101 | ||
|
|
ab8ae1524f | ||
|
|
de7c247583 | ||
|
|
997fd8f7ac | ||
|
|
e39e07246a | ||
|
|
e0b0406d76 | ||
|
|
1efbe9a784 | ||
|
|
fab921c2dd | ||
|
|
56896b4bea | ||
|
|
54eb7d8ecd | ||
|
|
114587b9f6 | ||
|
|
cad33c6c07 | ||
|
|
8154999f1c | ||
|
|
3a30c14085 | ||
|
|
db8b1df480 | ||
|
|
e20cac8a80 | ||
|
|
ce9b4e39f5 | ||
|
|
ddff4b2e58 | ||
|
|
16a470475c | ||
|
|
6e01473e87 | ||
|
|
8682089151 | ||
|
|
f45cb0075f | ||
|
|
afccb48798 | ||
|
|
ce6995fba0 | ||
|
|
3328d1adea | ||
|
|
33d79df9a8 | ||
|
|
4fb64b19d6 | ||
|
|
bf0f495c8b | ||
|
|
5d5f8e8d8c | ||
|
|
91aa248355 | ||
|
|
633c6c1efb | ||
|
|
facb1f673f | ||
|
|
9c8938c7f2 | ||
|
|
17f75f3ce6 | ||
|
|
b99c48afa2 | ||
|
|
9481fada23 | ||
|
|
7efbc5043c | ||
|
|
92880d3148 | ||
|
|
9800f2b8ae | ||
|
|
a5d01604cb | ||
|
|
aaab84f90a | ||
|
|
318a1a303c | ||
|
|
0061de6b2e | ||
|
|
b3db7c547f | ||
|
|
1da29464a8 | ||
|
|
d1d4ff41c6 | ||
|
|
673c2745a9 | ||
|
|
4ad88441cc | ||
|
|
71bb822856 | ||
|
|
2a7789bd12 | ||
|
|
1d0417cc1c | ||
|
|
905c578d90 | ||
|
|
a457c85e53 | ||
|
|
36630fc0ed | ||
|
|
f509ac60da | ||
|
|
bf8aac6f81 | ||
|
|
ceddcc0722 | ||
|
|
3a2bda6fb6 | ||
|
|
aea2403153 | ||
|
|
6e334df42f | ||
|
|
04cb68c9bd | ||
|
|
06060c071b | ||
|
|
02903686ad | ||
|
|
00cbed725d | ||
|
|
dabccd3a8a | ||
|
|
0e1e499a66 | ||
|
|
b4f485a0cc | ||
|
|
5bad68b9ff | ||
|
|
2db686fc47 | ||
|
|
d705a4b316 | ||
|
|
0154ee5bb6 | ||
|
|
29f14f5690 | ||
|
|
dd6f7b0794 | ||
|
|
e5c9591d64 | ||
|
|
df8da8bd46 | ||
|
|
c9b21006d1 | ||
|
|
2b37882322 | ||
|
|
8a2b3f2c89 | ||
|
|
c16a9aeb70 | ||
|
|
d5a0797c92 | ||
|
|
a55a769886 | ||
|
|
fd18c60f28 | ||
|
|
2704d1f88d | ||
|
|
c16c938fa4 | ||
|
|
497e2a09fd | ||
|
|
8bc8887ce6 | ||
|
|
7e5a5586f9 | ||
|
|
eee068db7e | ||
|
|
79e70173fa | ||
|
|
4f732557b9 | ||
|
|
6cbcebd661 | ||
|
|
f74dc01657 | ||
|
|
4735bef7b4 | ||
|
|
52a925df12 | ||
|
|
3e10199cb0 | ||
|
|
470e641a8c | ||
|
|
f61b84d058 | ||
|
|
5e77b43be1 | ||
|
|
46530a9fca | ||
|
|
12610c0d69 | ||
|
|
9bb9d3f407 | ||
|
|
a0ed20042c | ||
|
|
37c253aac2 | ||
|
|
68135c58ae | ||
|
|
f9efa71fcc | ||
|
|
184913ad28 | ||
|
|
ff52767a02 | ||
|
|
34ac5f9ba0 | ||
|
|
7296d109cc | ||
|
|
9be705ae30 | ||
|
|
af8b376f5a | ||
|
|
03f9668048 | ||
|
|
3bb23fa7cc | ||
|
|
f85c9d4e7e | ||
|
|
5de3d209be | ||
|
|
f1b136c817 | ||
|
|
c18829e0b3 | ||
|
|
d114b7f868 | ||
|
|
445cc173ce | ||
|
|
1e28fcad2e | ||
|
|
8d4e5155d9 | ||
|
|
027f562573 | ||
|
|
74caf084ca | ||
|
|
7396b02543 | ||
|
|
8035826b1b | ||
|
|
c6e73582c5 | ||
|
|
ca09d8c703 | ||
|
|
40b6551c7a | ||
|
|
95b664705d | ||
|
|
6bda7b35a2 | ||
|
|
6fedebf2a9 | ||
|
|
02f98c674b | ||
|
|
fb1e4130df | ||
|
|
c507f52b80 | ||
|
|
7b2784f1a2 | ||
|
|
7a7c83e8cf | ||
|
|
b86ef09763 | ||
|
|
71c050edf6 | ||
|
|
988f25b514 | ||
|
|
e878e8b904 | ||
|
|
bd3484cb3d | ||
|
|
3d769ed707 | ||
|
|
613be66f91 | ||
|
|
81e0ffbc3c | ||
|
|
8f3d325e7d | ||
|
|
a63472c6e6 | ||
|
|
8c98005605 | ||
|
|
8062d6cf17 | ||
|
|
78bf6e63ed | ||
|
|
68e0d759f7 | ||
|
|
26e72284af | ||
|
|
0efecd6601 | ||
|
|
9a3c2eb626 | ||
|
|
ca753b4526 | ||
|
|
230b6ca721 | ||
|
|
dc90f9af3f | ||
|
|
b5898c7ea3 | ||
|
|
36f1aea509 | ||
|
|
6742444182 | ||
|
|
e01fd37e6b | ||
|
|
ca7071f82a | ||
|
|
3cb67e3e65 | ||
|
|
e67dd589b5 | ||
|
|
74f491eaaa | ||
|
|
9ebd28ef5a | ||
|
|
2a58052bfd | ||
|
|
5ed73aff2b | ||
|
|
5a6ad09004 | ||
|
|
6a43b74043 | ||
|
|
69dc91aa1a | ||
|
|
f840db5143 | ||
|
|
f33cd41ebb | ||
|
|
da7896e62a | ||
|
|
08b5b4a1aa | ||
|
|
c397701818 | ||
|
|
617eb00f21 | ||
|
|
751fd0cf1e | ||
|
|
84c64e6073 | ||
|
|
ff5bc464ab | ||
|
|
b09a87c7e4 | ||
|
|
4032b48e63 | ||
|
|
12fad35065 | ||
|
|
c28be2da72 | ||
|
|
122cc0d20b | ||
|
|
89db32dd53 | ||
|
|
59040ae0f0 | ||
|
|
d8035745a9 | ||
|
|
c73e13c1f0 | ||
|
|
af75c7c949 | ||
|
|
896eb28308 | ||
|
|
6ca3d39e5f | ||
|
|
a7af0d0d7b | ||
|
|
04f5a7ea8d | ||
|
|
5d82cc5622 | ||
|
|
2f37f51c0c | ||
|
|
4690db61e1 | ||
|
|
672ec42903 | ||
|
|
cb39599a46 | ||
|
|
80b5ff3920 | ||
|
|
f27d3a91d3 | ||
|
|
b18357bff5 | ||
|
|
e3cd5b7082 | ||
|
|
16d7a6224b | ||
|
|
f8e32ec06c | ||
|
|
7073d4e298 | ||
|
|
f7f464920b | ||
|
|
e677dc20e9 | ||
|
|
9871eb9928 | ||
|
|
12b43cf688 | ||
|
|
7dd6db66ee | ||
|
|
d7726a070e | ||
|
|
fbc9d04782 | ||
|
|
24b08dd245 | ||
|
|
c7ebe69b05 | ||
|
|
22ffda4b5a | ||
|
|
b89c051d7d | ||
|
|
8b41f03472 | ||
|
|
700ff50eef | ||
|
|
95ac7236ff | ||
|
|
755f1b8e95 | ||
|
|
d431a4c87f | ||
|
|
04348d2d58 | ||
|
|
6f5214c1a4 | ||
|
|
1fe12be0b5 | ||
|
|
9c9ca16366 | ||
|
|
1702db71d1 | ||
|
|
0ba7ccdb9a | ||
|
|
3ccf65190e | ||
|
|
6b9ee3d5ed | ||
|
|
3ee0355034 | ||
|
|
7074fa1e2c | ||
|
|
44b91a6611 | ||
|
|
b2185dbed9 | ||
|
|
ec4b69b6e6 | ||
|
|
b6db873a00 | ||
|
|
db9222b737 | ||
|
|
b7bfa3ba28 | ||
|
|
ab25687119 | ||
|
|
9bfa0a01ad | ||
|
|
19c99fb7fe | ||
|
|
913244459e | ||
|
|
c66df99e22 | ||
|
|
03f4a6e2e4 | ||
|
|
31a243eeb4 | ||
|
|
043c0eff1c | ||
|
|
ff44313e13 | ||
|
|
e06ed31b21 | ||
|
|
aeaec9e805 | ||
|
|
6df0c76939 | ||
|
|
72efffcec4 | ||
|
|
930e4f7514 | ||
|
|
85f71032b5 | ||
|
|
ead530e2ec | ||
|
|
dc14b1ea52 | ||
|
|
4628be2855 | ||
|
|
1f24c08770 | ||
|
|
4889b9d0bf | ||
|
|
b3d7422a66 | ||
|
|
a0000528de | ||
|
|
2be46ec7a1 | ||
|
|
f2510a08a4 | ||
|
|
2787377250 | ||
|
|
e61ca31a3f | ||
|
|
1b735b5d06 | ||
|
|
ad3d26cdea | ||
|
|
f372ec4ccd | ||
|
|
44e75a50d7 | ||
|
|
6f0ea2de3e | ||
|
|
b4f0f7f4b3 | ||
|
|
5027d67731 | ||
|
|
6c8016345a | ||
|
|
7ba04e63c7 | ||
|
|
77dc1d0029 | ||
|
|
2b6538707f | ||
|
|
902e4e5715 | ||
|
|
28f6d50e5a | ||
|
|
d8ed7d6ad7 | ||
|
|
078d7d0ea3 | ||
|
|
5895a66c7a | ||
|
|
5ccff836e2 | ||
|
|
b2c2e8c4d9 | ||
|
|
890959cfe0 |
28
.github/ISSUE_TEMPLATE/feature-request.md
vendored
Normal file
28
.github/ISSUE_TEMPLATE/feature-request.md
vendored
Normal 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 6.0 has 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
22
.github/ISSUE_TEMPLATE/informational.md
vendored
Normal 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 6.0 has 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.
|
||||
48
.github/ISSUE_TEMPLATE/issue-report.md
vendored
Normal file
48
.github/ISSUE_TEMPLATE/issue-report.md
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
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 6.0 has 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.8 running on (Operating System)
|
||||
- [ ] .NET 6.0 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.
|
||||
0
.gitmodules
vendored
Normal file
0
.gitmodules
vendored
Normal file
27
.vscode/launch.json
vendored
Normal file
27
.vscode/launch.json
vendored
Normal 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.Check/bin/Debug/net6.0/MPF.Check.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}/MPF.Check",
|
||||
// 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}"
|
||||
}
|
||||
]
|
||||
}
|
||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"omnisharp.projectLoadTimeout": 480
|
||||
}
|
||||
39
.vscode/tasks.json
vendored
Normal file
39
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build",
|
||||
"command": "msbuild",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"${workspaceFolder}/MPF.sln",
|
||||
"-property:RuntimeIdentifiers=win7-x64"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "publish",
|
||||
"command": "msbuild",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"${workspaceFolder}/MPF/MPF.csproj",
|
||||
"-target:Publish",
|
||||
"-property:RuntimeIdentifiers=win7-x64"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "watch",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"watch",
|
||||
"run",
|
||||
"${workspaceFolder}/MPF/MPF.csproj",
|
||||
"/property:GenerateFullPaths=true",
|
||||
"/consoleloggerparameters:NoSummary"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
}
|
||||
]
|
||||
}
|
||||
777
CHANGELIST.md
777
CHANGELIST.md
@@ -1,4 +1,777 @@
|
||||
### 2.6.4 (2023-09-25)
|
||||
|
||||
- Add CD Projekt ID field
|
||||
- Fix speed setting in Aaru
|
||||
- Add helper for changing dumping program from UI
|
||||
- Handle extension changing only
|
||||
- Swap order of operations for changing program
|
||||
- Fix dumping path in DD
|
||||
- Fix PlayStation serial code region parsing (Deterous)
|
||||
- Retrofit README
|
||||
- Migrate to Nuget package for Redump
|
||||
- Remove dd for Windows
|
||||
- Migrate to Nuget package for XMID
|
||||
- Migrate to Nuget package for cuesheets
|
||||
- Migrate to Nuget package for PIC
|
||||
- Fix timestamp (Ragowit)
|
||||
- Not building against .NET Standard
|
||||
- Move RedumpSystemComboBoxItem
|
||||
- Move Constants
|
||||
- Move WPFCustomMessageBox
|
||||
- Remove EnableProgressProcessing
|
||||
- Remove EnableLogFormatting
|
||||
- Remove App references from LogViewModel
|
||||
- Remove log formatting code
|
||||
- Move LogOutput
|
||||
- Move to csproj tag for internals
|
||||
- Move OptionsWindow
|
||||
- Begin decoupling App
|
||||
- Fix build
|
||||
- More decoupling App
|
||||
- Make Options non-cloneable
|
||||
- Set parent on MainViewModel init
|
||||
- Make logger a local reference
|
||||
- Move options into MainViewModel
|
||||
- Move MainWindow
|
||||
- Add .NET 7 as a build target (not AppVeyor)
|
||||
- Fix tests that have been broken for a while
|
||||
|
||||
### 2.6.3 (2023-08-15)
|
||||
|
||||
- Update redumper to build 195
|
||||
- Add known .NET 6 limitations to README
|
||||
- Remove `_drive.txt` from required UIC outputs
|
||||
- Make `use` flag required for MPF.Check
|
||||
- Add dumping date to log
|
||||
- Non-zero data start only for audio discs
|
||||
- Update SafeDisc Sanitization (TheRogueArchivist)
|
||||
|
||||
### 2.6.2 (2023-07-25)
|
||||
|
||||
- Ensure custom parameters properly set
|
||||
- Universal hash only for audio discs
|
||||
- Support LibCrypt data from Redumper
|
||||
- Always show extension for Redumper
|
||||
- Normalize old universal hash text
|
||||
- Skip extra tracks during checking
|
||||
- Modify the track count on checking
|
||||
- Attempt to match universal hash
|
||||
- Fix .NET Framework 4.8 build
|
||||
- Fix universal hash URL generation
|
||||
- Add Windows publish script
|
||||
- Add *nix publish script
|
||||
- Add build instructions to README
|
||||
- Clarify build instructions
|
||||
|
||||
### 2.6.1 (2023-07-19)
|
||||
|
||||
- Simplify Redumper error value extraction
|
||||
- Don't pull comment fields that auto-populate
|
||||
- Set best compression levels for log files
|
||||
- Be more explicit about .NET 6 limitation
|
||||
- Set extensions for Redumper in UI
|
||||
- Fix comment field pulling again
|
||||
|
||||
### 2.6 (2023-07-14)
|
||||
|
||||
- Update README
|
||||
- Add warning to login tab
|
||||
- Pull hardware info from redumper log (fuzz6001)
|
||||
- Increase the version of AppVeyor (fuzz6001)
|
||||
- Add Windows 7 note to README
|
||||
- Update redumper to build 113
|
||||
- Split MMI invocation in drive listing
|
||||
- Update README
|
||||
- Add Hasbro iON
|
||||
- Get the write offset from the latest redumper (fuzz6001)
|
||||
- Update redumper to build 115
|
||||
- Update to DIC 20230401
|
||||
- Add DIC `.` notice to README
|
||||
- Resync with Redump
|
||||
- Update redumper to build 118
|
||||
- Clarify non-Redump systems
|
||||
- Add UltraCade
|
||||
- Re-enable BD33 and BD66
|
||||
- Add PIC models for BD (unused)
|
||||
- Handle PIC based on disc type
|
||||
- UMDs always have "2 layers"
|
||||
- Add dumping program selection to main UI
|
||||
- Update to DIC 20230413
|
||||
- Comment out `.` handling for DIC
|
||||
- Ensure dumping program box can enable/disable
|
||||
- Disable special SmartE handling for DIC
|
||||
- Remove path from PS1/PS2 serial
|
||||
- Make TOC file optional for CD/GD
|
||||
- Add datafile models
|
||||
- Add datafile helper method
|
||||
- Start migrating to datafile serialization
|
||||
- Prepare for future DIC changes
|
||||
- Add suppl support to Xbox
|
||||
- Support single digit subs
|
||||
- Fix info tool hash finding
|
||||
- Fix missing size for ISO data
|
||||
- Attempt to more accurately parse layerbreaks
|
||||
- Fix upcoming suppl DAT parsing
|
||||
- Ensure blank lines don't interfere
|
||||
- De-indent ringcode data
|
||||
- Be more specific with runtime identifiers
|
||||
- Fix subdump output path in AV config
|
||||
- Fix subdump mkdir path in AV config
|
||||
- Single file packing for .NET 6 again
|
||||
- Add missing BD disc type identifier string
|
||||
- Truncate PIC data for PS4/PS5
|
||||
- Add internal theme support with class
|
||||
- Add PIC identifier to SubmissionInfo
|
||||
- Fix other media type method
|
||||
- Fix non-zero offset text
|
||||
- Add executable listing for XSX
|
||||
- Update redumper to build 151
|
||||
- Add more safety to DAT generation
|
||||
- Get write offset from redumper 119 (fuzz6001)
|
||||
- Update hardware information pull from redumper (fuzz6001)
|
||||
- Add MCD/SS header support for Redumper
|
||||
- Fix MCD region(s) parsing
|
||||
- Update to DIC 20230606
|
||||
- Update redumper to build 166
|
||||
- Unblock Redumper DVD support
|
||||
- Support Redumper DVD layerbreak
|
||||
- Add placeholder and TODOs for Redumper
|
||||
- Add TODO with notes to Redumper
|
||||
- Fix 2-layer DVD support in Redumper
|
||||
- Fix VSCode build
|
||||
- Fix Redumper DAT/layer parsing
|
||||
- Update Redumper PS1 output parsing
|
||||
- Fix previous commit, clean up helpers
|
||||
- Update redumper to build 173
|
||||
- Initial support for Redumper CSS outputs
|
||||
- Hook up CSS output for testing
|
||||
- Update redumper to build 174
|
||||
- Add support for redumper CD synonyms
|
||||
- Adjust CSS title key parsing
|
||||
- Fix non-reading loop
|
||||
- Normalize Redumper CSS outputs
|
||||
- Normalize multi-instance site tags
|
||||
- Add missing Aaru error log to zip
|
||||
- Check Redumper dat section for completeness
|
||||
- Update redumper to build 176
|
||||
- UMDs are Sony discs
|
||||
- Strip colons from Redumper disc key
|
||||
- Use `HashSet` for disc or book type
|
||||
- Add ordering to disc or book type
|
||||
- Update redumper to build 183
|
||||
- Parse and format Redumper CD multisession data
|
||||
- New layerbreak takes precedence
|
||||
- Reduce pulled information for Xbox and X360
|
||||
- Ensure we found the tags we're skipping
|
||||
- Omit pulling universal hash
|
||||
- Update Nuget packages to newest stable
|
||||
|
||||
### 2.5 (2023-03-12)
|
||||
|
||||
- Add _drive file to zip for UIC
|
||||
- Add Xbox Series X and PS5 to list, fix Acorn
|
||||
- Add Xbox Series X short name to list
|
||||
- Remove windows from test target
|
||||
- Remove .NET 6.0 from tests, add TODO
|
||||
- Add .NET 6.0 to tests, remove msbuild args
|
||||
- Add HD-DVD to speed definitions
|
||||
- Add PS3 internal serial and version parsing (tjanas)
|
||||
- Update Nuget packages to newest stable
|
||||
- Simplify path selection in UI
|
||||
- Fix broken normalization test
|
||||
- Update drive info before dumping
|
||||
- Update redumper strings
|
||||
- Add new parameter and mode validation
|
||||
- Add redumper to the UI
|
||||
- Update redumper to build 81
|
||||
- Fix incorrect naming in Options window
|
||||
- Initial attempt at parsing redumper outputs
|
||||
- Update README
|
||||
- Reenable write offset for all CDs
|
||||
- Add missing redumper output file
|
||||
- Force a filename for redumper
|
||||
- Fix incorrect SetParameters
|
||||
- Fix a couple redumper things
|
||||
- Update AppVeyor version
|
||||
- Output security sectors to info
|
||||
- Remove x86 requirement for build
|
||||
- Fix XGD media type outputs
|
||||
- Fix typo in ToInternalProgram
|
||||
- Fix redumper error count parsing
|
||||
- Update to Aaru v5.3.2 LTS
|
||||
- Update options loader with sane defaults
|
||||
- Fix AppVeyor pathing
|
||||
- Skip during detection
|
||||
- Address some UI concerns
|
||||
- Tweak AppVeyor, show Check 6.0 builds
|
||||
- More strict when custom parameters editing
|
||||
- Use msbuild for .NET Framework 4.8
|
||||
- Update nuget packages
|
||||
- ReadAllText not ReadAllLines
|
||||
- Add drive format (fs) to log
|
||||
- Go back to pre .NET 7 Aaru
|
||||
- Be smarter about old paths
|
||||
- Fix relative paths for DIC
|
||||
- Add nicer failure message
|
||||
- Update to DIC 20230201
|
||||
- Use relative path output for DIC
|
||||
- Remove usage of Aaru
|
||||
- Remove Aaru as submodule
|
||||
- Fix Aaru removal
|
||||
- Enable .NET 6 Windows builds
|
||||
- Update Redumper to build_106
|
||||
- Reformat CICM for old .NET versions
|
||||
- Attempt to handle no drives
|
||||
- Handle no drives better
|
||||
- Handle no drives betterer
|
||||
- Packaging requires `-windows` for framework
|
||||
- Fix other `-windows` places for .NET 6
|
||||
- Fix typo in DICMultiSectorReadValue
|
||||
- Semi-unify drive finding
|
||||
- Introduce cross-platform MMI
|
||||
- Remove System.Management
|
||||
- Add Redumper Universal Hash support
|
||||
- Fix Redumper write offset support
|
||||
- Add Redumper non-zero data start
|
||||
- Use media size for type detection on .NET 6
|
||||
- Trim PIC for PS3
|
||||
- Get the version of redumper (fuzz6001)
|
||||
- Update VSCode config files
|
||||
- Can't publish single file for UI
|
||||
- Handle missing extension gracefully
|
||||
- Fix incorrect option slider display
|
||||
- Handle undetected discs on refresh
|
||||
- Originally intended behaviour of the Update Label button (IcySon55)
|
||||
- Update to BurnOutSharp 2.7.0
|
||||
- Get error count from recent redumper log (fuzz6001)
|
||||
- Minor cosmetic changes
|
||||
- Set saner defaults for dumping speeds
|
||||
- Attempt to support Windows 7
|
||||
- Add `win7-x64` to identifier list
|
||||
- Remove unsupported identifiers
|
||||
- Add identifiers in more places
|
||||
- Move drive finding inside of the try/catch
|
||||
- Update to DIC 20230309
|
||||
- Fix errant forward slashes
|
||||
- Add TOC back as optional file
|
||||
- Fix Redumper path generation
|
||||
- Use and trim quotes for Redumper
|
||||
- Fix incorrect image name setting
|
||||
- Ensure Redumper parameters are set
|
||||
- Ensure min values are taken care of
|
||||
- Update parameters with `=` handling
|
||||
- Ensure drive and speed are set
|
||||
- Handle quotes embedded
|
||||
- Return list of missing files for Redumper
|
||||
- Readd accidentally deleted line
|
||||
- Detect EOF during the search for error counts (fuzz6001)
|
||||
|
||||
### 2.4 (2022-10-26)
|
||||
|
||||
- Update to DIC 20211001
|
||||
- Fix Redump disc title pulling
|
||||
- Add /mr default flag options
|
||||
- Make FillFromRedump private again
|
||||
- Fix DVD layer finding corner case
|
||||
- Fix failing module tests
|
||||
- Add option to limit region and language selections
|
||||
- Cap X360 directory check to 500MB
|
||||
- Assign normalized path to parameters
|
||||
- Move path normalization to better place
|
||||
- Specifically include Unsafe Nuget package
|
||||
- Update Nuget packages to newest stable
|
||||
- Add Xbox One system detection
|
||||
- Update to DIC 20220301
|
||||
- Force internal drive refresh
|
||||
- Add single drive refresh button (IcySon55)
|
||||
- Fix "missing" option in window
|
||||
- Track last used drive on refresh
|
||||
- Clean up pre-dump validation
|
||||
- Update to Aaru v5.3.1 LTS
|
||||
- Add upper case `<TAB>` processing
|
||||
- Reorder event handers
|
||||
- Handle sanitized protections edge case
|
||||
- Update Aaru Nuget package
|
||||
- Return faster on empty protection sets
|
||||
- Remove redundant check around volume label
|
||||
- Fix tabs in Games and Videos boxes
|
||||
- Make fully and partially matching IDs more apparent
|
||||
- Add write offset as read-only field
|
||||
- Explicitly clear list, just in case
|
||||
- Add both fully and partially matching to info file
|
||||
- Fix submission info clone
|
||||
- Clear out fully matched IDs from the partial list
|
||||
- Refine copy protection section showing
|
||||
- Update Nuget packages
|
||||
- Normalize newlines in comments and contents
|
||||
- Increase JSON accuracy for disc types
|
||||
- Further separate out protection scan outputs
|
||||
- Compress JSON for artifacts alone
|
||||
- Even stricter output for copy protection section
|
||||
- Report dictionary to InfoTool
|
||||
- Even even stricter copy protection output
|
||||
- Disable PVD creation for Aaru
|
||||
- Explicitly sanitize '?' from path
|
||||
- Combine cases in protection scan
|
||||
- Convert status label to TextBlock
|
||||
- Add option for copy protection file output
|
||||
- Make protection field user-editable
|
||||
- Add warning to tooltip
|
||||
- Create core UI library
|
||||
- Rename MPF.GUI to MPF.UI
|
||||
- Add multisession pseudo-tag
|
||||
- Add multisession helper method skeleton
|
||||
- Move and update options loader; clean up Check
|
||||
- Move helper methods around
|
||||
- Consolidate Redump login testing
|
||||
- Separate common arguments to new helper
|
||||
- Parse and format CD multisession data
|
||||
- Convert triple space to tab
|
||||
- Fix clone issue with copy protection
|
||||
- Be more picky about multisession
|
||||
- Sanitize whitespace around tabs
|
||||
- Convert internal libraries to .NET Standard 2.0
|
||||
- Update AppVeyor to VS2022
|
||||
- Update Nuget packages
|
||||
- Remove needless csproj constants
|
||||
- Update copyright date to 2022
|
||||
- Revert AppVeyor to VS2019 for now
|
||||
- Add size-based media type detection for non-Framework
|
||||
- Gate ManagmentObject use further
|
||||
- Use built-in NETFRAMEWORK directive
|
||||
- Update to BurnOutSharp 2.1.0
|
||||
- .NET 6.0 and Cleanup
|
||||
- Remove .NET Core 3.1 from test project for now
|
||||
- Remove .NET Core 3.1 entirely
|
||||
- Add filesystem logging for .NET 6
|
||||
- Avoid whitespace changes for PVD, Header, and Cuesheet
|
||||
- Sync to newest CICM
|
||||
- Update solution file for VS2022
|
||||
- Add Aaru as a submodule for .NET 6
|
||||
- Multisession is multi-line
|
||||
- Use Aaru for media type retrival (.NET 6)
|
||||
- Fix CD-R multisession info
|
||||
- Better get drive list (.NET 6)
|
||||
- Add optical media support method (.NET 6)
|
||||
- Simplify IsOptical (.NET 6)
|
||||
- Reorganize GetMediaType
|
||||
- Possibly fix tab regex replacement
|
||||
- Add PIC.bin to log zip
|
||||
- Organize projects in solution
|
||||
- Implement Drive.Create for safety
|
||||
- Fix incomplete system name detection
|
||||
- Add Sharp X68k detection
|
||||
- Add Bandai Playdia QIS detection
|
||||
- Framework for XBONE filenames
|
||||
- Add files for XBONE
|
||||
- Update to DIC 20220707
|
||||
- Fix .bin file paths; update internal filename generation
|
||||
- Disable nonstandard BD-ROM sizes
|
||||
- Trim leading file paths for XBONE
|
||||
- Give .NET 6 priority for web calls
|
||||
- Update to BurnOutSharp 2.3.0 (nw)
|
||||
- Add Mattel Fisher-Price iXL detection
|
||||
- Update to BurnOutSharp 2.3.1 (nw)
|
||||
- Fix serial parsing for Dreamcast
|
||||
- Fix missing parenthesis
|
||||
- Add internal name for Cleanrip outputs
|
||||
- Fix psxt001z namespace
|
||||
- Fix missing assignment
|
||||
- Update to new constructor
|
||||
- Update PSX content check
|
||||
- Update Aaru submodule to latest devel
|
||||
- Add Sony Electronic Book system
|
||||
- Verify GD-ROM outputs, finally
|
||||
- Electronic not Electric
|
||||
- Fix ringcode guide images
|
||||
- Add skeleton for Redumper
|
||||
- Download Redumper with AppVeyor
|
||||
- Add Redumper constants
|
||||
- Add Redumper parameter values
|
||||
- Add Redumper command support and reset
|
||||
- Add Redumper dumping command
|
||||
- Add Redumper command validation
|
||||
- Add Redumper command generation
|
||||
- Create Redumper extensions class
|
||||
- Minor Redumper cleanup
|
||||
- Add important Redumper note
|
||||
- Update to DIC 20220909
|
||||
- Possibly fix PIC parsing
|
||||
- Add PS3 folder/file checks for detection
|
||||
- Use default directory for folder browsing, if possible
|
||||
- Add unused command filename parser
|
||||
- Add initial framework for reporting dumping program
|
||||
- Report specific DIC version, if possible
|
||||
- Add dumping info section skeleton
|
||||
- Update Aaru submodules
|
||||
- Fix missing info reference change
|
||||
- Enable separated protection info output by default
|
||||
- Try adding MPF logs to zip
|
||||
- Create MPF log helper and filter for deletion
|
||||
- Fix missing info in Aaru
|
||||
- Add hardware info to DIC and Aaru
|
||||
- Fix hardware info
|
||||
- Add specialized CDS/SafeDisc filter
|
||||
- Add unused article formatter
|
||||
- Add language filtering to formatter
|
||||
- Add multi-language helper for filter
|
||||
- Update Nuget packages
|
||||
- Remove deprecated protection setting
|
||||
- Update BurnOutSharp to 2.3.4
|
||||
- Add compression result reason to log
|
||||
- Add System.Memory package to MPF.Library
|
||||
- Add CodePages package to MPF.Library
|
||||
- Remove extraneous packages
|
||||
- Change location of dumping info
|
||||
- Add MS ZipFile package to MPF.Library
|
||||
- Add + to positive offsets
|
||||
- Disable layerbreak generation for BD
|
||||
- Disable XGD version reporting
|
||||
- Disable XGD layerbreak reporting
|
||||
- Disable XGD1 PVD reporting
|
||||
- Put Redump limitations behind existing flag
|
||||
- Add framework for reported disc type
|
||||
- Add disc type parsing for Aaru and DIC
|
||||
- Fix multiple DiscType for DIC
|
||||
- Fix multiple DiscType* for DIC
|
||||
- Add logging to !submissionInfo writing failure
|
||||
- Add logging to !submissionInfo formatting failure
|
||||
- Update issue templates to be more accurate
|
||||
- Fix NRE with offsets
|
||||
- Fix readonly Filename info display
|
||||
- Fix layerbreak-based checks
|
||||
- Add PS4 serial finding (tjanas)
|
||||
- Add unused notification method
|
||||
- Move to unused Chime class
|
||||
- Add PS5 serial finding (tjanas)
|
||||
- Fix offset formatting (fuzz6001)
|
||||
|
||||
### 2.3 (2022-02-05)
|
||||
|
||||
- Start overhauling Redump information pulling, again
|
||||
- Add internal structure for special site codes
|
||||
- Add new tabs for special site information
|
||||
- Clean up default handling of fields
|
||||
- Try to handle multi-line fields during parsing
|
||||
- Fix CSSKey log handling
|
||||
- Show most read-only fields in new tab
|
||||
- Add horizontal scroll to user input
|
||||
- Tweak new disc information fields and tabs
|
||||
- Allow internal serial and volume label to be hidden
|
||||
- Be smarter about showing update checks
|
||||
- Ensure all fields are read-only on read-only tab
|
||||
- Add model for 2-layer ringcode guide
|
||||
- Add first attempt 2-layer ringcode guide
|
||||
- Add even more safety to clone
|
||||
- Sanitize filename after check
|
||||
- Handle pulled linebreaks better
|
||||
- Skip anti-modchip string in some cases
|
||||
- Handle pulled linebreaks better, again
|
||||
- Tweak more Disc Info window formatting
|
||||
- Skip unnecessary newlines in parsing
|
||||
- Force scroll visibility, tweak text sizes again
|
||||
- Fix newline skipping
|
||||
- Add missing continue statement
|
||||
- Add newlines for mutliline special fields
|
||||
- Omit volume label for "Audio CD"
|
||||
- Remove Enter/Escape registration on disc info window
|
||||
- Logically group more things in disc info window
|
||||
- Remove tab key from disc info window
|
||||
- Add `<tab>` processing
|
||||
- Unban newly opened consoles
|
||||
- Tweak minimalized layout a bit more
|
||||
- Add tab setting
|
||||
- Further disc info window tweaks
|
||||
- Changed IsEnabled to IsReadOnly
|
||||
- Fix scrolling issues in disc info window
|
||||
- Convert postgap and VCD fields to checkboxes
|
||||
- Adjust width ratios for disc info window
|
||||
- Fix IsReadOnly
|
||||
- Only include booleans if the value is true
|
||||
- Add hidden debug option for "ShowDebugViewMenuItem"
|
||||
- Fix incorrect header check
|
||||
- Make protection read-only field multiline
|
||||
- Reformat Saturn internal date
|
||||
- Fix Sega CD internal serial reading
|
||||
- Fix crash on invalid parameters
|
||||
- Differentiate XMID and XeMID
|
||||
- Conditionally pull region from Redump
|
||||
- Be smarter about volume labels
|
||||
- Use volume label in checks, not formatted version
|
||||
- Sync with Redump region and language selection
|
||||
- Try to delete old log archive before writing
|
||||
- Add support for all ISO language codes
|
||||
- Add support for all ISO region codes
|
||||
- Ensure ordering in output site tags
|
||||
- Make site code formatting helper method
|
||||
- Better helper method organization
|
||||
- Start supporting ordered tags and non-tags
|
||||
- Add more non-tag support; rearrange info window
|
||||
- Fix incorrect language three-letter code
|
||||
- Hook up additional Xbox field to disc info window
|
||||
- Fix non-tag tag shortnames
|
||||
- Fix parsing of non-tag tags again
|
||||
- Disable unnecessary cuesheet parsing
|
||||
- Fix incorrect region two-letter code
|
||||
- Adjust long names for some languages
|
||||
- Add Sierra ID to list of pseudo-tags
|
||||
- Add another hand-formatted version of SS tag
|
||||
- Move internal serial before volume label
|
||||
- Check for $SystemUpdate folder for X360 discs
|
||||
- Slightly rename UK and USA regions for UI
|
||||
- Add another hand-formatted version of SS tag
|
||||
- Add verification reminders for pulled tags
|
||||
- Read longer string for Saturn internal serial
|
||||
- Ensure version only pulled if one doesn't exist
|
||||
- Ensure Games pseudo-tag is multi-line
|
||||
- Add alternate pseudo-tag for Playable Demos
|
||||
- Make error clearer if something is unsupported in Check
|
||||
- Ensure drive is not null for volume labels
|
||||
- Check explicitly for no matches on Redump pull
|
||||
- Normalize PS1/PS2 executable names
|
||||
- Adjust paths for DIC just before dumping
|
||||
|
||||
### 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
|
||||
@@ -89,7 +862,7 @@
|
||||
- edccchk now run on all CD-Roms
|
||||
- Discs unsupported by Windows are now regonized
|
||||
- Extra \ when accepting default save has been removed.
|
||||
|
||||
|
||||
### 1.02b (2018-05-18)
|
||||
|
||||
- Added missing DLL
|
||||
@@ -102,4 +875,4 @@
|
||||
|
||||
### 1.01d (2018-05-18)
|
||||
|
||||
-Combine IBM PC-CD options, misc fixes.
|
||||
-Combine IBM PC-CD options, misc fixes.
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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")]
|
||||
26
DICUI.Forms/Properties/Settings1.Designer.cs
generated
26
DICUI.Forms/Properties/Settings1.Designer.cs
generated
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
175
DICUI.Forms/Windows/LogWindow.Designer.cs
generated
175
DICUI.Forms/Windows/LogWindow.Designer.cs
generated
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
532
DICUI.Forms/Windows/MainWindow.Designer.cs
generated
532
DICUI.Forms/Windows/MainWindow.Designer.cs
generated
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
565
DICUI.Forms/Windows/OptionsWindow.Designer.cs
generated
565
DICUI.Forms/Windows/OptionsWindow.Designer.cs
generated
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -1,120 +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";
|
||||
}
|
||||
|
||||
/// <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";
|
||||
}
|
||||
}
|
||||
@@ -1,270 +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,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Known systems
|
||||
/// </summary>
|
||||
public enum KnownSystem
|
||||
{
|
||||
NONE = 0,
|
||||
|
||||
#region Consoles
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
@@ -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")]
|
||||
@@ -1,604 +0,0 @@
|
||||
using IMAPI2;
|
||||
using DICUI.Data;
|
||||
|
||||
namespace DICUI.Utilities
|
||||
{
|
||||
public static class Converters
|
||||
{
|
||||
/// <summary>
|
||||
/// Get the MediaType associated with a given base command
|
||||
/// </summary>
|
||||
/// <param name="baseCommand">DICCommand value to check</param>
|
||||
/// <returns>MediaType if possible, null on error</returns>
|
||||
/// <remarks>This takes the "safe" route by assuming the larger of any given format</remarks>
|
||||
public static MediaType? BaseCommmandToMediaType(DICCommand baseCommand)
|
||||
{
|
||||
switch (baseCommand)
|
||||
{
|
||||
case DICCommand.Audio:
|
||||
case DICCommand.CompactDisc:
|
||||
case DICCommand.Data:
|
||||
return MediaType.CDROM;
|
||||
case DICCommand.GDROM:
|
||||
case DICCommand.Swap:
|
||||
return MediaType.GDROM;
|
||||
case DICCommand.DigitalVideoDisc:
|
||||
case DICCommand.XBOX:
|
||||
case DICCommand.XBOXSwap:
|
||||
case DICCommand.XGD2Swap:
|
||||
case DICCommand.XGD3Swap:
|
||||
return MediaType.DVD;
|
||||
case DICCommand.BluRay:
|
||||
return MediaType.BluRay;
|
||||
|
||||
// Non-optical
|
||||
case DICCommand.Floppy:
|
||||
return MediaType.FloppyDisk;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the most common known system for a given MediaType
|
||||
/// </summary>
|
||||
/// <param name="baseCommand">DICCommand value to check</param>
|
||||
/// <returns>KnownSystem if possible, null on error</returns>
|
||||
public static KnownSystem? BaseCommandToKnownSystem(DICCommand baseCommand)
|
||||
{
|
||||
switch (baseCommand)
|
||||
{
|
||||
case DICCommand.Audio:
|
||||
return KnownSystem.AudioCD;
|
||||
case DICCommand.CompactDisc:
|
||||
case DICCommand.Data:
|
||||
case DICCommand.DigitalVideoDisc:
|
||||
case DICCommand.Floppy:
|
||||
return KnownSystem.IBMPCCompatible;
|
||||
case DICCommand.GDROM:
|
||||
case DICCommand.Swap:
|
||||
return KnownSystem.SegaDreamcast;
|
||||
case DICCommand.BluRay:
|
||||
return KnownSystem.SonyPlayStation3;
|
||||
case DICCommand.XBOX:
|
||||
case DICCommand.XBOXSwap:
|
||||
return KnownSystem.MicrosoftXBOX;
|
||||
case DICCommand.XGD2Swap:
|
||||
case DICCommand.XGD3Swap:
|
||||
return KnownSystem.MicrosoftXBOX360;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the string representation of the DICCommand enum values
|
||||
/// </summary>
|
||||
/// <param name="command">DICCommand value to convert</param>
|
||||
/// <returns>String representing the value, if possible</returns>
|
||||
public static string DICCommandToString(DICCommand command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case DICCommand.Audio:
|
||||
return DICCommandStrings.Audio;
|
||||
case DICCommand.BluRay:
|
||||
return DICCommandStrings.BluRay;
|
||||
case DICCommand.Close:
|
||||
return DICCommandStrings.Close;
|
||||
case DICCommand.CompactDisc:
|
||||
return DICCommandStrings.CompactDisc;
|
||||
case DICCommand.Data:
|
||||
return DICCommandStrings.Data;
|
||||
case DICCommand.DigitalVideoDisc:
|
||||
return DICCommandStrings.DigitalVideoDisc;
|
||||
case DICCommand.DriveSpeed:
|
||||
return DICCommandStrings.DriveSpeed;
|
||||
case DICCommand.Eject:
|
||||
return DICCommandStrings.Eject;
|
||||
case DICCommand.Floppy:
|
||||
return DICCommandStrings.Floppy;
|
||||
case DICCommand.GDROM:
|
||||
return DICCommandStrings.GDROM;
|
||||
case DICCommand.MDS:
|
||||
return DICCommandStrings.MDS;
|
||||
case DICCommand.Merge:
|
||||
return DICCommandStrings.Merge;
|
||||
case DICCommand.Reset:
|
||||
return DICCommandStrings.Reset;
|
||||
case DICCommand.Start:
|
||||
return DICCommandStrings.Start;
|
||||
case DICCommand.Stop:
|
||||
return DICCommandStrings.Stop;
|
||||
case DICCommand.Sub:
|
||||
return DICCommandStrings.Sub;
|
||||
case DICCommand.Swap:
|
||||
return DICCommandStrings.Swap;
|
||||
case DICCommand.XBOX:
|
||||
return DICCommandStrings.XBOX;
|
||||
case DICCommand.XBOXSwap:
|
||||
return DICCommandStrings.XBOXSwap;
|
||||
case DICCommand.XGD2Swap:
|
||||
return DICCommandStrings.XGD2Swap;
|
||||
case DICCommand.XGD3Swap:
|
||||
return DICCommandStrings.XGD3Swap;
|
||||
|
||||
case DICCommand.NONE:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the string representation of the DICFlag enum values
|
||||
/// </summary>
|
||||
/// <param name="command">DICFlag value to convert</param>
|
||||
/// <returns>String representing the value, if possible</returns>
|
||||
public static string DICFlagToString(DICFlag flag)
|
||||
{
|
||||
switch (flag)
|
||||
{
|
||||
case DICFlag.AddOffset:
|
||||
return DICFlagStrings.AddOffset;
|
||||
case DICFlag.AMSF:
|
||||
return DICFlagStrings.AMSF;
|
||||
case DICFlag.BEOpcode:
|
||||
return DICFlagStrings.BEOpcode;
|
||||
case DICFlag.C2Opcode:
|
||||
return DICFlagStrings.C2Opcode;
|
||||
case DICFlag.CopyrightManagementInformation:
|
||||
return DICFlagStrings.CopyrightManagementInformation;
|
||||
case DICFlag.D8Opcode:
|
||||
return DICFlagStrings.D8Opcode;
|
||||
case DICFlag.DisableBeep:
|
||||
return DICFlagStrings.DisableBeep;
|
||||
case DICFlag.ForceUnitAccess:
|
||||
return DICFlagStrings.ForceUnitAccess;
|
||||
case DICFlag.MCN:
|
||||
return DICFlagStrings.MCN;
|
||||
case DICFlag.MultiSession:
|
||||
return DICFlagStrings.MultiSession;
|
||||
case DICFlag.NoFixSubP:
|
||||
return DICFlagStrings.NoFixSubP;
|
||||
case DICFlag.NoFixSubQ:
|
||||
return DICFlagStrings.NoFixSubQ;
|
||||
case DICFlag.NoFixSubQLibCrypt:
|
||||
return DICFlagStrings.NoFixSubQLibCrypt;
|
||||
case DICFlag.NoFixSubQSecuROM:
|
||||
return DICFlagStrings.NoFixSubQSecuROM;
|
||||
case DICFlag.NoFixSubRtoW:
|
||||
return DICFlagStrings.NoFixSubRtoW;
|
||||
case DICFlag.Raw:
|
||||
return DICFlagStrings.Raw;
|
||||
case DICFlag.Reverse:
|
||||
return DICFlagStrings.Reverse;
|
||||
case DICFlag.ScanAntiMod:
|
||||
return DICFlagStrings.ScanAntiMod;
|
||||
case DICFlag.ScanFileProtect:
|
||||
return DICFlagStrings.ScanFileProtect;
|
||||
case DICFlag.ScanSectorProtect:
|
||||
return DICFlagStrings.ScanSectorProtect;
|
||||
case DICFlag.SeventyFour:
|
||||
return DICFlagStrings.SeventyFour;
|
||||
case DICFlag.SkipSector:
|
||||
return DICFlagStrings.SkipSector;
|
||||
case DICFlag.SubchannelReadLevel:
|
||||
return DICFlagStrings.SubchannelReadLevel;
|
||||
|
||||
case DICFlag.NONE:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert IMAPI physical media type to a MediaType
|
||||
/// </summary>
|
||||
/// <param name="type">IMAPI_MEDIA_PHYSICAL_TYPE value to check</param>
|
||||
/// <returns>MediaType if possible, null on error</returns>
|
||||
public static MediaType? IMAPIDiskTypeToMediaType(IMAPI_MEDIA_PHYSICAL_TYPE type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_UNKNOWN:
|
||||
return MediaType.NONE;
|
||||
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDROM:
|
||||
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDR:
|
||||
case IMAPI_MEDIA_PHYSICAL_TYPE.IMAPI_MEDIA_TYPE_CDRW:
|
||||
return MediaType.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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the default extension for a given disc type
|
||||
/// </summary>
|
||||
/// <param name="type">MediaType value to check</param>
|
||||
/// <returns>Valid extension (with leading '.'), null on error</returns>
|
||||
public static string MediaTypeToExtension(MediaType? type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case MediaType.CDROM:
|
||||
case MediaType.GDROM:
|
||||
case MediaType.Cartridge:
|
||||
return ".bin";
|
||||
case MediaType.DVD:
|
||||
case MediaType.HDDVD:
|
||||
case MediaType.BluRay:
|
||||
case MediaType.NintendoWiiOpticalDisc:
|
||||
case MediaType.UMD:
|
||||
return ".iso";
|
||||
case MediaType.LaserDisc:
|
||||
case MediaType.NintendoGameCube:
|
||||
return ".raw";
|
||||
case MediaType.NintendoWiiUOpticalDisc:
|
||||
return ".wud";
|
||||
case MediaType.FloppyDisk:
|
||||
return ".img";
|
||||
case MediaType.Cassette:
|
||||
return ".wav";
|
||||
case MediaType.NONE:
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the string representation of the MediaType enum values
|
||||
/// </summary>
|
||||
/// <param name="type">MediaType value to convert</param>
|
||||
/// <returns>String representing the value, if possible</returns>
|
||||
public static string MediaTypeToString(MediaType? type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
#region Punched Media
|
||||
|
||||
case MediaType.ApertureCard:
|
||||
return "Aperture card";
|
||||
case MediaType.JacquardLoomCard:
|
||||
return "Jacquard Loom card";
|
||||
case MediaType.MagneticStripeCard:
|
||||
return "Magnetic stripe card";
|
||||
case MediaType.OpticalPhonecard:
|
||||
return "Optical phonecard";
|
||||
case MediaType.PunchedCard:
|
||||
return "Punched card";
|
||||
case MediaType.PunchedTape:
|
||||
return "Punched tape";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tape
|
||||
|
||||
case MediaType.OpenReel:
|
||||
return "Open Reel Tape";
|
||||
case MediaType.DataCartridge:
|
||||
return "Data Tape Cartridge";
|
||||
case MediaType.Cassette:
|
||||
return "Cassette Tape";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Disc / Disc
|
||||
|
||||
case MediaType.BluRay:
|
||||
return "BD-ROM";
|
||||
case MediaType.CDROM:
|
||||
return "CD-ROM";
|
||||
case MediaType.DVD:
|
||||
return "DVD-ROM";
|
||||
case MediaType.FloppyDisk:
|
||||
return "Floppy Disk";
|
||||
case MediaType.Floptical:
|
||||
return "Floptical";
|
||||
case MediaType.GDROM:
|
||||
return "GD-ROM";
|
||||
case MediaType.HDDVD:
|
||||
return "HD-DVD-ROM";
|
||||
case MediaType.HardDisk:
|
||||
return "Hard Disk";
|
||||
case MediaType.IomegaBernoulliDisk:
|
||||
return "Iomega Bernoulli Disk";
|
||||
case MediaType.IomegaJaz:
|
||||
return "Iomega Jaz";
|
||||
case MediaType.IomegaZip:
|
||||
return "Iomega Zip";
|
||||
case MediaType.LaserDisc:
|
||||
return "LD-ROM / LV-ROM";
|
||||
case MediaType.Nintendo64DD:
|
||||
return "64DD Disk";
|
||||
case MediaType.NintendoFamicomDiskSystem:
|
||||
return "Famicom Disk System Disk";
|
||||
case MediaType.NintendoGameCube:
|
||||
return "GameCube Disc";
|
||||
case MediaType.NintendoWiiOpticalDisc:
|
||||
return "Wii Optical Disc";
|
||||
case MediaType.NintendoWiiUOpticalDisc:
|
||||
return "Wii U Optical Disc";
|
||||
case MediaType.UMD:
|
||||
return "UMD";
|
||||
|
||||
#endregion
|
||||
|
||||
// Unsorted Formats
|
||||
case MediaType.Cartridge:
|
||||
return "Cartridge";
|
||||
case MediaType.CED:
|
||||
return "CED";
|
||||
|
||||
case MediaType.NONE:
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the string representation of the KnownSystem enum values
|
||||
/// </summary>
|
||||
/// <param name="sys">KnownSystem value to convert</param>
|
||||
/// <returns>String representing the value, if possible</returns>
|
||||
public static string KnownSystemToString(KnownSystem? sys)
|
||||
{
|
||||
switch (sys)
|
||||
{
|
||||
#region Consoles
|
||||
|
||||
case KnownSystem.BandaiPlaydiaQuickInteractiveSystem:
|
||||
return "Bandai Playdia Quick Interactive System";
|
||||
case KnownSystem.BandaiApplePippin:
|
||||
return "Bandai / Apple Pippin";
|
||||
case KnownSystem.CommodoreAmigaCD32:
|
||||
return "Commodore Amiga CD32";
|
||||
case KnownSystem.CommodoreAmigaCDTV:
|
||||
return "Commodore Amiga CDTV";
|
||||
case KnownSystem.MattelHyperscan:
|
||||
return "Mattel HyperScan";
|
||||
case KnownSystem.MicrosoftXBOX:
|
||||
return "Microsoft XBOX";
|
||||
case KnownSystem.MicrosoftXBOX360:
|
||||
return "Microsoft XBOX 360";
|
||||
case KnownSystem.MicrosoftXBOXOne:
|
||||
return "Microsoft XBOX One";
|
||||
case KnownSystem.NECPCEngineTurboGrafxCD:
|
||||
return "NEC PC-Engine / TurboGrafx CD";
|
||||
case KnownSystem.NECPCFX:
|
||||
return "NEC PC-FX / PC-FXGA";
|
||||
case KnownSystem.NintendoGameCube:
|
||||
return "Nintendo GameCube";
|
||||
case KnownSystem.NintendoWii:
|
||||
return "Nintendo Wii";
|
||||
case KnownSystem.NintendoWiiU:
|
||||
return "Nintendo Wii U";
|
||||
case KnownSystem.Panasonic3DOInteractiveMultiplayer:
|
||||
return "Panasonic 3DO Interactive Multiplayer";
|
||||
case KnownSystem.PhilipsCDi:
|
||||
return "Philips CD-i";
|
||||
case KnownSystem.SegaCDMegaCD:
|
||||
return "Sega CD / Mega CD";
|
||||
case KnownSystem.SegaDreamcast:
|
||||
return "Sega Dreamcast";
|
||||
case KnownSystem.SegaSaturn:
|
||||
return "Sega Saturn";
|
||||
case KnownSystem.SNKNeoGeoCD:
|
||||
return "SNK Neo Geo CD";
|
||||
case KnownSystem.SonyPlayStation:
|
||||
return "Sony PlayStation";
|
||||
case KnownSystem.SonyPlayStation2:
|
||||
return "Sony PlayStation 2";
|
||||
case KnownSystem.SonyPlayStation3:
|
||||
return "Sony PlayStation 3";
|
||||
case KnownSystem.SonyPlayStation4:
|
||||
return "Sony PlayStation 4";
|
||||
case KnownSystem.SonyPlayStationPortable:
|
||||
return "Sony PlayStation Portable";
|
||||
case KnownSystem.VMLabsNuon:
|
||||
return "VM Labs NUON";
|
||||
case KnownSystem.VTechVFlashVSmilePro:
|
||||
return "VTech V.Flash - V.Smile Pro";
|
||||
case KnownSystem.ZAPiTGamesGameWaveFamilyEntertainmentSystem:
|
||||
return "ZAPiT Games Game Wave Family Entertainment System";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Computers
|
||||
|
||||
case KnownSystem.AcornArchimedes:
|
||||
return "Acorn Archimedes";
|
||||
case KnownSystem.AppleMacintosh:
|
||||
return "Apple Macintosh";
|
||||
case KnownSystem.CommodoreAmigaCD:
|
||||
return "Commodore Amiga CD";
|
||||
case KnownSystem.FujitsuFMTowns:
|
||||
return "Fujitsu FM Towns series";
|
||||
case KnownSystem.IBMPCCompatible:
|
||||
return "IBM PC Compatible";
|
||||
case KnownSystem.NECPC88:
|
||||
return "NEC PC-88";
|
||||
case KnownSystem.NECPC98:
|
||||
return "NEC PC-98";
|
||||
case KnownSystem.SharpX68000:
|
||||
return "Sharp X68000";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Arcade
|
||||
|
||||
case KnownSystem.AmigaCUBOCD32:
|
||||
return "Amiga CUBO CD32";
|
||||
case KnownSystem.AmericanLaserGames3DO:
|
||||
return "American Laser Games 3DO";
|
||||
case KnownSystem.Atari3DO:
|
||||
return "Atari 3DO";
|
||||
case KnownSystem.Atronic:
|
||||
return "Atronic";
|
||||
case KnownSystem.AUSCOMSystem1:
|
||||
return "AUSCOM System 1";
|
||||
case KnownSystem.BallyGameMagic:
|
||||
return "Bally Game Magic";
|
||||
case KnownSystem.CapcomCPSystemIII:
|
||||
return "Capcom CP System III";
|
||||
case KnownSystem.GlobalVRVarious:
|
||||
return "Global VR PC-based Systems";
|
||||
case KnownSystem.GlobalVRVortek:
|
||||
return "Global VR Vortek";
|
||||
case KnownSystem.GlobalVRVortekV3:
|
||||
return "Global VR Vortek V3";
|
||||
case KnownSystem.ICEPCHardware:
|
||||
return "ICE PC-based Hardware";
|
||||
case KnownSystem.IncredibleTechnologiesEagle:
|
||||
return "Incredible Technologies Eagle";
|
||||
case KnownSystem.IncredibleTechnologiesVarious:
|
||||
return "Incredible Technologies PC-based Systems";
|
||||
case KnownSystem.KonamieAmusement:
|
||||
return "Konami e-Amusement";
|
||||
case KnownSystem.KonamiFirebeat:
|
||||
return "Konami Firebeat";
|
||||
case KnownSystem.KonamiGVSystem:
|
||||
return "Konami GV System";
|
||||
case KnownSystem.KonamiM2:
|
||||
return "Konami M2";
|
||||
case KnownSystem.KonamiPython:
|
||||
return "Konami Python";
|
||||
case KnownSystem.KonamiPython2:
|
||||
return "Konami Python 2";
|
||||
case KnownSystem.KonamiSystem573:
|
||||
return "Konami System 573";
|
||||
case KnownSystem.KonamiTwinkle:
|
||||
return "Konami Twinkle";
|
||||
case KnownSystem.KonamiVarious:
|
||||
return "Konami PC-based Systems";
|
||||
case KnownSystem.MeritIndustriesBoardwalk:
|
||||
return "Merit Industries Boardwalk";
|
||||
case KnownSystem.MeritIndustriesMegaTouchAurora:
|
||||
return "Merit Industries MegaTouch Aurora";
|
||||
case KnownSystem.MeritIndustriesMegaTouchForce:
|
||||
return "Merit Industries MegaTouch Force";
|
||||
case KnownSystem.MeritIndustriesMegaTouchION:
|
||||
return "Merit Industries MegaTouch ION";
|
||||
case KnownSystem.MeritIndustriesMegaTouchMaxx:
|
||||
return "Merit Industries MegaTouch Maxx";
|
||||
case KnownSystem.MeritIndustriesMegaTouchXL:
|
||||
return "Merit Industries MegaTouch XL";
|
||||
case KnownSystem.NamcoCapcomSystem256:
|
||||
return "Namco / Capcom System 256/Super System 256";
|
||||
case KnownSystem.NamcoCapcomTaitoSystem246:
|
||||
return "Namco / Capcom / Taito System 246";
|
||||
case KnownSystem.NamcoSegaNintendoTriforce:
|
||||
return "Namco / Sega / Nintendo Triforce";
|
||||
case KnownSystem.NamcoSystem12:
|
||||
return "Namco System 12";
|
||||
case KnownSystem.NamcoSystem357:
|
||||
return "Namco System 357";
|
||||
case KnownSystem.NewJatreCDi:
|
||||
return "New Jatre CD-i";
|
||||
case KnownSystem.NichibutsuHighRateSystem:
|
||||
return "Nichibutsu High Rate System";
|
||||
case KnownSystem.NichibutsuSuperCD:
|
||||
return "Nichibutsu Super CD";
|
||||
case KnownSystem.NichibutsuXRateSystem:
|
||||
return "NichibutsuX-Rate System";
|
||||
case KnownSystem.PanasonicM2:
|
||||
return "Panasonic M2";
|
||||
case KnownSystem.PhotoPlayVarious:
|
||||
return "PhotoPlay PC-based Systems";
|
||||
case KnownSystem.RawThrillsVarious:
|
||||
return "Raw Thrills PC-based Systems";
|
||||
case KnownSystem.SegaChihiro:
|
||||
return "Sega Chihiro";
|
||||
case KnownSystem.SegaEuropaR:
|
||||
return "Sega Europa-R";
|
||||
case KnownSystem.SegaLindbergh:
|
||||
return "Sega Lindbergh";
|
||||
case KnownSystem.SegaNaomi:
|
||||
return "Sega Naomi";
|
||||
case KnownSystem.SegaNaomi2:
|
||||
return "Sega Naomi 2";
|
||||
case KnownSystem.SegaNu:
|
||||
return "Sega Nu";
|
||||
case KnownSystem.SegaRingEdge:
|
||||
return "Sega RingEdge";
|
||||
case KnownSystem.SegaRingEdge2:
|
||||
return "Sega RingEdge 2";
|
||||
case KnownSystem.SegaRingWide:
|
||||
return "Sega RingWide";
|
||||
case KnownSystem.SegaTitanVideo:
|
||||
return "Sega Titan Video";
|
||||
case KnownSystem.SegaSystem32:
|
||||
return "Sega System 32";
|
||||
case KnownSystem.SeibuCATSSystem:
|
||||
return "Seibu CATS System";
|
||||
case KnownSystem.TABAustriaQuizard:
|
||||
return "TAB-Austria Quizard";
|
||||
case KnownSystem.TandyMemorexVisualInformationSystem:
|
||||
return "Tandy / Memorex Visual Information System";
|
||||
case KnownSystem.TsunamiTsuMoMultiGameMotionSystem:
|
||||
return "Tsunami TsuMo Multi-Game Motion System";
|
||||
|
||||
#endregion
|
||||
|
||||
#region Others
|
||||
|
||||
case KnownSystem.AudioCD:
|
||||
return "Audio CD";
|
||||
case KnownSystem.BDVideo:
|
||||
return "BD-Video";
|
||||
case KnownSystem.DVDVideo:
|
||||
return "DVD-Video";
|
||||
case KnownSystem.EnhancedCD:
|
||||
return "Enhanced CD";
|
||||
case KnownSystem.EnhancedDVD:
|
||||
return "Enhanced DVD";
|
||||
case KnownSystem.EnhancedBD:
|
||||
return "Enhanced BD";
|
||||
case KnownSystem.HasbroVideoNow:
|
||||
return "Hasbro VideoNow";
|
||||
case KnownSystem.HDDVDVideo:
|
||||
return "HD-DVD-Video";
|
||||
case KnownSystem.PalmOS:
|
||||
return "PalmOS";
|
||||
case KnownSystem.PhilipsCDiDigitalVideo:
|
||||
return "Philips CD-i Digital Video";
|
||||
case KnownSystem.PhotoCD:
|
||||
return "Photo CD";
|
||||
case KnownSystem.PlayStationGameSharkUpdates:
|
||||
return "PlayStation GameShark Updates";
|
||||
case KnownSystem.RainbowDisc:
|
||||
return "Rainbow Disc";
|
||||
case KnownSystem.TaoiKTV:
|
||||
return "Tao iKTV";
|
||||
case KnownSystem.TomyKissSite:
|
||||
return "Tomy Kiss-Site";
|
||||
case KnownSystem.VideoCD:
|
||||
return "Video CD";
|
||||
|
||||
#endregion
|
||||
|
||||
case KnownSystem.NONE:
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,126 +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 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 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
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,581 +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.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);
|
||||
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.
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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")]
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 })]
|
||||
[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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
43
DICUI.sln
43
DICUI.sln
@@ -1,43 +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
|
||||
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
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {73C62E6A-6584-4D93-83B5-ECB1FBDB469B}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -1,11 +0,0 @@
|
||||
using System.Windows;
|
||||
|
||||
namespace DICUI
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
DICUI/Icon.ico
BIN
DICUI/Icon.ico
Binary file not shown.
|
Before Width: | Height: | Size: 71 KiB |
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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")]
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
2
LICENSE
2
LICENSE
@@ -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.
|
||||
|
||||
@@ -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>
|
||||
48
MPF.Check/MPF.Check.csproj
Normal file
48
MPF.Check/MPF.Check.csproj
Normal file
@@ -0,0 +1,48 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net48;net6.0;net7.0</TargetFrameworks>
|
||||
<RuntimeIdentifiers>win7-x64;win8-x64;win81-x64;win10-x64;linux-x64;osx-x64</RuntimeIdentifiers>
|
||||
<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-2023</Copyright>
|
||||
<RepositoryUrl>https://github.com/SabreTools/MPF</RepositoryUrl>
|
||||
<Version>2.6.4</Version>
|
||||
<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>
|
||||
<ProjectReference Include="..\MPF.Core\MPF.Core.csproj" />
|
||||
<ProjectReference Include="..\MPF.Library\MPF.Library.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BurnOutSharp" PrivateAssets="build; analyzers" ExcludeAssets="contentFiles" Version="2.8.0" GeneratePathProperty="true">
|
||||
<IncludeAssets>runtime; compile; build; native; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="SabreTools.RedumpLib" Version="1.1.1" />
|
||||
<PackageReference Include="Unclassified.NetRevisionTask" Version="0.4.3">
|
||||
<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>
|
||||
|
||||
</Project>
|
||||
199
MPF.Check/Program.cs
Normal file
199
MPF.Check/Program.cs
Normal file
@@ -0,0 +1,199 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using BurnOutSharp;
|
||||
using MPF.Core.Converters;
|
||||
using MPF.Core.Data;
|
||||
using MPF.Core.Utilities;
|
||||
using MPF.Library;
|
||||
using SabreTools.RedumpLib.Data;
|
||||
using SabreTools.RedumpLib.Web;
|
||||
|
||||
namespace MPF.Check
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
// Try processing the standalone arguments
|
||||
if (ProcessStandaloneArguments(args))
|
||||
return;
|
||||
|
||||
// Try processing the common arguments
|
||||
(bool success, MediaType mediaType, RedumpSystem? knownSystem) = ProcessCommonArguments(args);
|
||||
if (!success)
|
||||
return;
|
||||
|
||||
// Loop through and process options
|
||||
(Core.Data.Options options, string path, int startIndex) = OptionsLoader.LoadFromArguments(args, startIndex: 2);
|
||||
if (options.InternalProgram == InternalProgram.NONE)
|
||||
{
|
||||
DisplayHelp("A program name needs to be provided");
|
||||
return;
|
||||
}
|
||||
|
||||
// Make new Progress objects
|
||||
var resultProgress = new Progress<Result>();
|
||||
resultProgress.ProgressChanged += ProgressUpdated;
|
||||
var protectionProgress = new Progress<ProtectionProgress>();
|
||||
protectionProgress.ProgressChanged += ProgressUpdated;
|
||||
|
||||
// Validate the supplied credentials
|
||||
#if NET48
|
||||
(bool? _, string message) = RedumpWebClient.ValidateCredentials(options?.RedumpUsername, options?.RedumpPassword);
|
||||
#else
|
||||
(bool? _, string message) = RedumpHttpClient.ValidateCredentials(options?.RedumpUsername, options?.RedumpPassword).ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
#endif
|
||||
if (!string.IsNullOrWhiteSpace(message))
|
||||
Console.WriteLine(message);
|
||||
|
||||
// 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
|
||||
Drive drive = null;
|
||||
if (!string.IsNullOrWhiteSpace(path))
|
||||
drive = Drive.Create(null, path);
|
||||
|
||||
var env = new DumpEnvironment(options, filepath, drive, knownSystem, mediaType, internalProgram: null, parameters: 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:");
|
||||
var supportedArguments = OptionsLoader.PrintSupportedArguments();
|
||||
foreach (string argument in supportedArguments)
|
||||
{
|
||||
Console.WriteLine(argument);
|
||||
}
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process common arguments for all functionality
|
||||
/// </summary>
|
||||
/// <returns>True if all arguments pass, false otherwise</returns>
|
||||
private static (bool, MediaType, RedumpSystem?) ProcessCommonArguments(string[] args)
|
||||
{
|
||||
// All other use requires at least 3 arguments
|
||||
if (args.Length < 3)
|
||||
{
|
||||
DisplayHelp("Invalid number of arguments");
|
||||
return (false, MediaType.NONE, null);
|
||||
}
|
||||
|
||||
// Check the MediaType
|
||||
var mediaType = EnumConverter.ToMediaType(args[0].Trim('"'));
|
||||
if (mediaType == MediaType.NONE)
|
||||
{
|
||||
DisplayHelp($"{args[0]} is not a recognized media type");
|
||||
return (false, MediaType.NONE, null);
|
||||
}
|
||||
|
||||
// Check the RedumpSystem
|
||||
var knownSystem = Extensions.ToRedumpSystem(args[1].Trim('"'));
|
||||
if (knownSystem == null)
|
||||
{
|
||||
DisplayHelp($"{args[1]} is not a recognized system");
|
||||
return (false, MediaType.NONE, null);
|
||||
}
|
||||
|
||||
return (true, mediaType, knownSystem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process any standalone arguments for the program
|
||||
/// </summary>
|
||||
/// <returns>True if one of the arguments was processed, false otherwise</returns>
|
||||
private static bool ProcessStandaloneArguments(string[] args)
|
||||
{
|
||||
// Help options
|
||||
if (args.Length == 0 || args[0] == "-h" || args[0] == "-?")
|
||||
{
|
||||
DisplayHelp();
|
||||
return true;
|
||||
}
|
||||
|
||||
// List options
|
||||
if (args[0] == "-lm" || args[0] == "--listmedia")
|
||||
{
|
||||
Console.WriteLine("Supported Media Types:");
|
||||
foreach (string mediaType in Extensions.ListMediaTypes())
|
||||
{
|
||||
Console.WriteLine(mediaType);
|
||||
}
|
||||
Console.ReadLine();
|
||||
return true;
|
||||
}
|
||||
else if (args[0] == "-lp" || args[0] == "--listprograms")
|
||||
{
|
||||
Console.WriteLine("Supported Programs:");
|
||||
foreach (string program in EnumExtensions.ListPrograms())
|
||||
{
|
||||
Console.WriteLine(program);
|
||||
}
|
||||
Console.ReadLine();
|
||||
return true;
|
||||
}
|
||||
else if (args[0] == "-ls" || args[0] == "--listsystems")
|
||||
{
|
||||
Console.WriteLine("Supported Systems:");
|
||||
foreach (string system in Extensions.ListSystems())
|
||||
{
|
||||
Console.WriteLine(system);
|
||||
}
|
||||
Console.ReadLine();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
7
MPF.Check/launchSettings.json
Normal file
7
MPF.Check/launchSettings.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"profiles": {
|
||||
"MPF.Check": {
|
||||
"commandName": "Project"
|
||||
}
|
||||
}
|
||||
}
|
||||
4
MPF.Core/AssemblyInfo.cs
Normal file
4
MPF.Core/AssemblyInfo.cs
Normal file
@@ -0,0 +1,4 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
// Anything marked as internal can be used by the test methods
|
||||
[assembly: InternalsVisibleTo("MPF.Test")]
|
||||
381
MPF.Core/Converters/EnumConverter.cs
Normal file
381
MPF.Core/Converters/EnumConverter.cs
Normal file
@@ -0,0 +1,381 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
#if NETFRAMEWORK
|
||||
using IMAPI2;
|
||||
#endif
|
||||
using MPF.Core.Data;
|
||||
using SabreTools.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 NETFRAMEWORK
|
||||
/// <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(SabreTools.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.DiscImageCreator:
|
||||
return "DiscImageCreator";
|
||||
case InternalProgram.Redumper:
|
||||
return "redumper";
|
||||
|
||||
#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 "rd":
|
||||
case "redumper":
|
||||
return InternalProgram.Redumper;
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
121
MPF.Core/Data/Constants.cs
Normal file
121
MPF.Core/Data/Constants.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using SabreTools.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> HDDVD { 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.NintendoGameCubeGameDisc:
|
||||
case MediaType.NintendoWiiOpticalDisc:
|
||||
return DVD;
|
||||
case MediaType.HDDVD:
|
||||
return HDDVD;
|
||||
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 DumpingProgramField = "Dumping Program";
|
||||
public const string DumpingDateField = "Date";
|
||||
public const string DumpingDriveManufacturer = "Manufacturer";
|
||||
public const string DumpingDriveModel = "Model";
|
||||
public const string DumpingDriveFirmware = "Firmware";
|
||||
public const string ReportedDiscType = "Reported Disc Type";
|
||||
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 FullyMatchingIDField = "Fully Matching ID";
|
||||
public const string PartiallyMatchingIDsField = "Partially 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 XBOXSSRanges = "Security Sector Ranges";
|
||||
|
||||
// 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";
|
||||
}
|
||||
}
|
||||
650
MPF.Core/Data/Drive.cs
Normal file
650
MPF.Core/Data/Drive.cs
Normal file
@@ -0,0 +1,650 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.Management.Infrastructure;
|
||||
using Microsoft.Management.Infrastructure.Generic;
|
||||
using MPF.Core.Converters;
|
||||
using MPF.Core.Utilities;
|
||||
using SabreTools.RedumpLib.Data;
|
||||
#if NETFRAMEWORK
|
||||
using IMAPI2;
|
||||
#endif
|
||||
|
||||
namespace MPF.Core.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents information for a single drive
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// TODO: This needs to be less Windows-centric. Devices do not always have a single letter that can be used.
|
||||
/// TODO: Can the Aaru models be used instead of the ones I've created here?
|
||||
/// </remarks>
|
||||
public class Drive
|
||||
{
|
||||
#region Fields
|
||||
|
||||
/// <summary>
|
||||
/// Represents drive type
|
||||
/// </summary>
|
||||
public InternalDriveType? InternalDriveType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Drive partition format
|
||||
/// </summary>
|
||||
public string DriveFormat { get; private set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Windows drive path
|
||||
/// </summary>
|
||||
public string Name { get; private set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Represents if Windows has marked the drive as active
|
||||
/// </summary>
|
||||
public bool MarkedActive { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the total size of the drive
|
||||
/// </summary>
|
||||
public long TotalSize { get; private set; } = default;
|
||||
|
||||
/// <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; private set; } = null;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Derived Fields
|
||||
|
||||
/// <summary>
|
||||
/// Media label as read by Windows, formatted to avoid odd outputs
|
||||
/// </summary>
|
||||
public string FormattedVolumeLabel
|
||||
{
|
||||
get
|
||||
{
|
||||
string volumeLabel = Template.DiscNotDetected;
|
||||
if (this.MarkedActive)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(this.VolumeLabel))
|
||||
volumeLabel = "track";
|
||||
else
|
||||
volumeLabel = this.VolumeLabel;
|
||||
}
|
||||
|
||||
foreach (char c in Path.GetInvalidFileNameChars())
|
||||
volumeLabel = volumeLabel.Replace(c, '_');
|
||||
|
||||
return volumeLabel;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Windows drive letter
|
||||
/// </summary>
|
||||
public char Letter => this.Name == null || this.Name.Length == 0 ? '\0' : this.Name[0];
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Protected constructor
|
||||
/// </summary>
|
||||
protected Drive() { }
|
||||
|
||||
/// <summary>
|
||||
/// Create a new Drive object from a drive type and device path
|
||||
/// </summary>
|
||||
/// <param name="driveType">InternalDriveType value representing the drive type</param>
|
||||
/// <param name="devicePath">Path to the device according to the local machine</param>
|
||||
public static Drive Create(InternalDriveType? driveType, string devicePath)
|
||||
{
|
||||
// Create a new, empty drive object
|
||||
var drive = new Drive()
|
||||
{
|
||||
InternalDriveType = driveType,
|
||||
};
|
||||
|
||||
// If we have an invalid device path, return null
|
||||
if (string.IsNullOrWhiteSpace(devicePath))
|
||||
return null;
|
||||
|
||||
// Sanitize a Windows-formatted long device path
|
||||
if (devicePath.StartsWith("\\\\.\\"))
|
||||
devicePath = devicePath.Substring("\\\\.\\".Length);
|
||||
|
||||
// Create and validate the drive info object
|
||||
var driveInfo = new DriveInfo(devicePath);
|
||||
if (driveInfo == null || driveInfo == default)
|
||||
return null;
|
||||
|
||||
// Fill in the rest of the data
|
||||
drive.PopulateFromDriveInfo(driveInfo);
|
||||
|
||||
return drive;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populate all fields from a DriveInfo object
|
||||
/// </summary>
|
||||
/// <param name="driveInfo">DriveInfo object to populate from</param>
|
||||
private void PopulateFromDriveInfo(DriveInfo driveInfo)
|
||||
{
|
||||
// If we have an invalid DriveInfo, just return
|
||||
if (driveInfo == null || driveInfo == default)
|
||||
return;
|
||||
|
||||
// Populate the data fields
|
||||
this.Name = driveInfo.Name;
|
||||
this.MarkedActive = driveInfo.IsReady;
|
||||
if (this.MarkedActive)
|
||||
{
|
||||
this.DriveFormat = driveInfo.DriveFormat;
|
||||
this.TotalSize = driveInfo.TotalSize;
|
||||
this.VolumeLabel = driveInfo.VolumeLabel;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.DriveFormat = string.Empty;
|
||||
this.TotalSize = default;
|
||||
this.VolumeLabel = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
#region Public Functionality
|
||||
|
||||
/// <summary>
|
||||
/// Create a list of active drives matched to their volume labels
|
||||
/// </summary>
|
||||
/// <param name="ignoreFixedDrives">True to ignore fixed drives from population, false otherwise</param>
|
||||
/// <returns>Active drives, matched to labels, if possible</returns>
|
||||
public static List<Drive> CreateListOfDrives(bool ignoreFixedDrives)
|
||||
{
|
||||
var drives = GetDriveList(ignoreFixedDrives);
|
||||
drives = drives?.OrderBy(i => i.Letter)?.ToList();
|
||||
return drives;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current media type from drive letter
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
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 NET6_0_OR_GREATER
|
||||
else
|
||||
return GetMediaTypeFromSize();
|
||||
#endif
|
||||
|
||||
// Get the current drive information
|
||||
string deviceId = null;
|
||||
bool loaded = false;
|
||||
try
|
||||
{
|
||||
// Get the device ID first
|
||||
CimSession session = CimSession.Create(null);
|
||||
var collection = session.QueryInstances("root\\CIMV2", "WQL", $"SELECT * FROM Win32_CDROMDrive WHERE Id = '{this.Letter}:\'");
|
||||
|
||||
foreach (CimInstance instance in collection)
|
||||
{
|
||||
CimKeyedCollection<CimProperty> properties = instance.CimInstanceProperties;
|
||||
deviceId = (string)properties["DeviceID"]?.Value;
|
||||
loaded = (bool)properties["MediaLoaded"]?.Value;
|
||||
}
|
||||
|
||||
// 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");
|
||||
|
||||
#if NETFRAMEWORK
|
||||
|
||||
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);
|
||||
|
||||
#else
|
||||
|
||||
return (null, "IMAPI2 recorder not supported");
|
||||
|
||||
#endif
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (null, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <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;
|
||||
|
||||
// Check volume labels first
|
||||
RedumpSystem? systemFromLabel = GetRedumpSystemFromVolumeLabel();
|
||||
if (systemFromLabel != null)
|
||||
return systemFromLabel;
|
||||
|
||||
// Get a list of files for quicker checking
|
||||
#region Consoles
|
||||
|
||||
// Bandai Playdia Quick Interactive System
|
||||
try
|
||||
{
|
||||
List<string> files = Directory.EnumerateFiles(drivePath, "*", SearchOption.TopDirectoryOnly).ToList();
|
||||
|
||||
if (files.Any(f => f.EndsWith(".AJS", StringComparison.OrdinalIgnoreCase))
|
||||
&& files.Any(f => f.EndsWith(".GLB", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return RedumpSystem.BandaiPlaydiaQuickInteractiveSystem;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
// Mattel Fisher-Price iXL
|
||||
if (File.Exists(Path.Combine(drivePath, "iXL", "iXLUpdater.exe")))
|
||||
{
|
||||
return RedumpSystem.MattelFisherPriceiXL;
|
||||
}
|
||||
|
||||
// Microsoft Xbox 360
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(Path.Combine(drivePath, "$SystemUpdate"))
|
||||
&& Directory.EnumerateFiles(Path.Combine(drivePath, "$SystemUpdate")).Any()
|
||||
&& this.TotalSize <= 500_000_000)
|
||||
{
|
||||
return RedumpSystem.MicrosoftXbox360;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
// Microsoft Xbox One
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(Path.Combine(drivePath, "MSXC"))
|
||||
&& Directory.EnumerateFiles(Path.Combine(drivePath, "MSXC")).Any())
|
||||
{
|
||||
return RedumpSystem.MicrosoftXboxOne;
|
||||
}
|
||||
}
|
||||
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
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(Path.Combine(drivePath, "PS3_GAME"))
|
||||
|| Directory.Exists(Path.Combine(drivePath, "PS3_UPDATE"))
|
||||
|| File.Exists(Path.Combine(drivePath, "PS3_DISC.SFB")))
|
||||
{
|
||||
return RedumpSystem.SonyPlayStation3;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
// Sony PlayStation 4
|
||||
// There are more possible paths that could be checked.
|
||||
// There are some entries that can be found on most PS4 discs:
|
||||
// "/app/GAME_SERIAL/app.pkg"
|
||||
// "/bd/param.sfo"
|
||||
// "/license/rif"
|
||||
// There are also extra files that can be found on some discs:
|
||||
// "/patch/GAME_SERIAL/patch.pkg" can be found in Redump entry 66816.
|
||||
// Originally on disc as "/patch/CUSA11302/patch.pkg".
|
||||
// Is used as an on-disc update for the base game app without needing to get update from the internet.
|
||||
// "/addcont/GAME_SERIAL/CONTENT_ID/ac.pkg" can be found in Redump entry 97619.
|
||||
// Originally on disc as "/addcont/CUSA00288/FFXIVEXPS400001A/ac.pkg".
|
||||
if (File.Exists(Path.Combine(drivePath, "PS4", "UPDATE", "PS4UPDATE.PUP")))
|
||||
{
|
||||
return RedumpSystem.SonyPlayStation4;
|
||||
}
|
||||
|
||||
// V.Tech V.Flash / V.Smile Pro
|
||||
if (File.Exists(Path.Combine(drivePath, "0SYSTEM")))
|
||||
{
|
||||
return RedumpSystem.VTechVFlashVSmilePro;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Computers
|
||||
|
||||
// Sharp X68000
|
||||
if (File.Exists(Path.Combine(drivePath, "COMMAND.X")))
|
||||
{
|
||||
return RedumpSystem.SharpX68000;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Video Formats
|
||||
|
||||
// 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 and DVD-Video
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(Path.Combine(drivePath, "AUDIO_TS"))
|
||||
&& Directory.EnumerateFiles(Path.Combine(drivePath, "AUDIO_TS")).Any())
|
||||
{
|
||||
return RedumpSystem.DVDAudio;
|
||||
}
|
||||
|
||||
else if (Directory.Exists(Path.Combine(drivePath, "VIDEO_TS"))
|
||||
&& Directory.EnumerateFiles(Path.Combine(drivePath, "VIDEO_TS")).Any())
|
||||
{
|
||||
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 { }
|
||||
|
||||
// VCD
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(Path.Combine(drivePath, "VCD"))
|
||||
&& Directory.EnumerateFiles(Path.Combine(drivePath, "VCD")).Any())
|
||||
{
|
||||
return RedumpSystem.VideoCD;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
#endregion
|
||||
|
||||
// Default return
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current system from the drive volume label
|
||||
/// </summary>
|
||||
/// <returns>The system based on volume label, null if none detected</returns>
|
||||
public RedumpSystem? GetRedumpSystemFromVolumeLabel()
|
||||
{
|
||||
// If the volume label is empty, we can't do anything
|
||||
if (string.IsNullOrWhiteSpace(this.VolumeLabel))
|
||||
return null;
|
||||
|
||||
// Audio CD
|
||||
if (this.VolumeLabel.Equals("Audio CD", StringComparison.OrdinalIgnoreCase))
|
||||
return RedumpSystem.AudioCD;
|
||||
|
||||
// Microsoft Xbox
|
||||
if (this.VolumeLabel.Equals("SEP13011042", StringComparison.OrdinalIgnoreCase))
|
||||
return RedumpSystem.MicrosoftXbox;
|
||||
else if (this.VolumeLabel.Equals("SEP13011042072", StringComparison.OrdinalIgnoreCase))
|
||||
return RedumpSystem.MicrosoftXbox;
|
||||
|
||||
// Microsoft Xbox 360
|
||||
if (this.VolumeLabel.Equals("XBOX360", StringComparison.OrdinalIgnoreCase))
|
||||
return RedumpSystem.MicrosoftXbox360;
|
||||
else if (this.VolumeLabel.Equals("XGD2DVD_NTSC", StringComparison.OrdinalIgnoreCase))
|
||||
return RedumpSystem.MicrosoftXbox360;
|
||||
|
||||
// Microsoft Xbox 360 - Too overly broad even if a lot of discs use this
|
||||
//if (this.VolumeLabel.Equals("CD_ROM", StringComparison.OrdinalIgnoreCase))
|
||||
// return RedumpSystem.MicrosoftXbox360; // Also for Xbox One?
|
||||
//if (this.VolumeLabel.Equals("DVD_ROM", StringComparison.OrdinalIgnoreCase))
|
||||
// return RedumpSystem.MicrosoftXbox360;
|
||||
|
||||
// Sega Mega-CD / Sega-CD
|
||||
if (this.VolumeLabel.Equals("Sega_CD", StringComparison.OrdinalIgnoreCase))
|
||||
return RedumpSystem.SegaMegaCDSegaCD;
|
||||
|
||||
// Sony PlayStation 3
|
||||
if (this.VolumeLabel.Equals("PS3VOLUME", StringComparison.OrdinalIgnoreCase))
|
||||
return RedumpSystem.SonyPlayStation3;
|
||||
|
||||
// Sony PlayStation 4
|
||||
if (this.VolumeLabel.Equals("PS4VOLUME", StringComparison.OrdinalIgnoreCase))
|
||||
return RedumpSystem.SonyPlayStation4;
|
||||
|
||||
// Sony PlayStation 5
|
||||
if (this.VolumeLabel.Equals("PS5VOLUME", StringComparison.OrdinalIgnoreCase))
|
||||
return RedumpSystem.SonyPlayStation5;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <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.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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refresh the current drive information based on path
|
||||
/// </summary>
|
||||
public void RefreshDrive()
|
||||
{
|
||||
var driveInfo = DriveInfo.GetDrives().FirstOrDefault(d => d?.Name == this.Name);
|
||||
this.PopulateFromDriveInfo(driveInfo);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Get the media type for a device path based on size
|
||||
/// </summary>
|
||||
/// <returns>MediaType, null on error</returns>
|
||||
private (MediaType?, string) GetMediaTypeFromSize()
|
||||
{
|
||||
if (this.TotalSize >= 0 && this.TotalSize < 800_000_000 && this.DriveFormat == "CDFS")
|
||||
return (MediaType.CDROM, null);
|
||||
else if (this.TotalSize >= 400_000_000 && this.TotalSize <= 8_540_000_000 && this.DriveFormat == "UDF")
|
||||
return (MediaType.DVD, null);
|
||||
else
|
||||
return (MediaType.BluRay, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all current attached Drives
|
||||
/// </summary>
|
||||
/// <param name="ignoreFixedDrives">True to ignore fixed drives from population, false otherwise</param>
|
||||
/// <returns>List of drives, null on error</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>
|
||||
private static List<Drive> GetDriveList(bool ignoreFixedDrives)
|
||||
{
|
||||
var desiredDriveTypes = new List<DriveType>() { DriveType.CDRom };
|
||||
if (!ignoreFixedDrives)
|
||||
{
|
||||
desiredDriveTypes.Add(DriveType.Fixed);
|
||||
desiredDriveTypes.Add(DriveType.Removable);
|
||||
}
|
||||
|
||||
// TODO: Reduce reliance on `DriveInfo`
|
||||
// https://github.com/aaru-dps/Aaru/blob/5164a154e2145941472f2ee0aeb2eff3338ecbb3/Aaru.Devices/Windows/ListDevices.cs#L66
|
||||
|
||||
// Create an output drive list
|
||||
List<Drive> drives = new List<Drive>();
|
||||
|
||||
// Get all standard supported drive types
|
||||
try
|
||||
{
|
||||
drives = DriveInfo.GetDrives()
|
||||
.Where(d => desiredDriveTypes.Contains(d.DriveType))
|
||||
.Select(d => Create(EnumConverter.ToInternalDriveType(d.DriveType), d.Name))
|
||||
.ToList();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return drives;
|
||||
}
|
||||
|
||||
// Find and update all floppy drives
|
||||
try
|
||||
{
|
||||
CimSession session = CimSession.Create(null);
|
||||
var collection = session.QueryInstances("root\\CIMV2", "WQL", "SELECT * FROM Win32_LogicalDisk");
|
||||
|
||||
foreach (CimInstance instance in collection)
|
||||
{
|
||||
CimKeyedCollection<CimProperty> properties = instance.CimInstanceProperties;
|
||||
uint? mediaType = properties["MediaType"]?.Value as uint?;
|
||||
if (mediaType != null && ((mediaType > 0 && mediaType < 11) || (mediaType > 12 && mediaType < 22)))
|
||||
{
|
||||
char devId = (properties["Caption"].Value as string)[0];
|
||||
drives.ForEach(d => { if (d.Letter == devId) { d.InternalDriveType = Data.InternalDriveType.Floppy; } });
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// No-op
|
||||
}
|
||||
|
||||
return drives;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
31
MPF.Core/Data/Enumerations.cs
Normal file
31
MPF.Core/Data/Enumerations.cs
Normal 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,
|
||||
DiscImageCreator,
|
||||
Redumper,
|
||||
|
||||
// Verification support only
|
||||
CleanRip,
|
||||
DCDumper,
|
||||
UmdImageCreator,
|
||||
}
|
||||
}
|
||||
296
MPF.Core/Data/IniFile.cs
Normal file
296
MPF.Core/Data/IniFile.cs
Normal 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
|
||||
}
|
||||
}
|
||||
677
MPF.Core/Data/Options.cs
Normal file
677
MPF.Core/Data/Options.cs
Normal file
@@ -0,0 +1,677 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using MPF.Core.Converters;
|
||||
using SabreTools.RedumpLib.Data;
|
||||
|
||||
namespace MPF.Core.Data
|
||||
{
|
||||
public class Options : IDictionary<string, string>
|
||||
{
|
||||
private 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 Redumper
|
||||
/// </summary>
|
||||
public string RedumperPath
|
||||
{
|
||||
get { return GetStringSetting(_settings, "RedumperPath", "Programs\\Redumper\\redumper.exe"); }
|
||||
set { _settings["RedumperPath"] = 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>
|
||||
/// Fast update label - Skips disc checks and updates path only
|
||||
/// </summary>
|
||||
public bool FastUpdateLabel
|
||||
{
|
||||
get { return GetBooleanSetting(_settings, "FastUpdateLabel", false); }
|
||||
set { _settings["FastUpdateLabel"] = 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();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default output path for dumps
|
||||
/// </summary>
|
||||
/// <remarks>This is a hidden setting</remarks>
|
||||
public bool ShowDebugViewMenuItem
|
||||
{
|
||||
get { return GetBooleanSetting(_settings, "ShowDebugViewMenuItem", false); }
|
||||
set { _settings["ShowDebugViewMenuItem"] = value.ToString(); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Dumping Speeds
|
||||
|
||||
/// <summary>
|
||||
/// Default CD dumping speed
|
||||
/// </summary>
|
||||
public int PreferredDumpSpeedCD
|
||||
{
|
||||
get { return GetInt32Setting(_settings, "PreferredDumpSpeedCD", 24); }
|
||||
set { _settings["PreferredDumpSpeedCD"] = value.ToString(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default DVD dumping speed
|
||||
/// </summary>
|
||||
public int PreferredDumpSpeedDVD
|
||||
{
|
||||
get { return GetInt32Setting(_settings, "PreferredDumpSpeedDVD", 16); }
|
||||
set { _settings["PreferredDumpSpeedDVD"] = value.ToString(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default HD-DVD dumping speed
|
||||
/// </summary>
|
||||
public int PreferredDumpSpeedHDDVD
|
||||
{
|
||||
get { return GetInt32Setting(_settings, "PreferredDumpSpeedHDDVD", 8); }
|
||||
set { _settings["PreferredDumpSpeedHDDVD"] = value.ToString(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default BD dumping speed
|
||||
/// </summary>
|
||||
public int PreferredDumpSpeedBD
|
||||
{
|
||||
get { return GetInt32Setting(_settings, "PreferredDumpSpeedBD", 8); }
|
||||
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 multi-sector read flag by default
|
||||
/// </summary>
|
||||
public bool DICMultiSectorRead
|
||||
{
|
||||
get { return GetBooleanSetting(_settings, "DICMultiSectorRead", false); }
|
||||
set { _settings["DICMultiSectorRead"] = value.ToString(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Include a default multi-sector read value
|
||||
/// </summary>
|
||||
public int DICMultiSectorReadValue
|
||||
{
|
||||
get { return GetInt32Setting(_settings, "DICMultiSectorReadValue", 0); }
|
||||
set { _settings["DICMultiSectorReadValue"] = value.ToString(); }
|
||||
}
|
||||
|
||||
/// <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>
|
||||
/// Default number of DVD/HD-DVD/BD rereads
|
||||
/// </summary>
|
||||
public int DICDVDRereadCount
|
||||
{
|
||||
get { return GetInt32Setting(_settings, "DICDVDRereadCount", 10); }
|
||||
set { _settings["DICDVDRereadCount"] = 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 Redumper
|
||||
|
||||
/// <summary>
|
||||
/// Enable debug output while dumping by default
|
||||
/// </summary>
|
||||
public bool RedumperEnableDebug
|
||||
{
|
||||
get { return GetBooleanSetting(_settings, "RedumperEnableDebug", false); }
|
||||
set { _settings["RedumperEnableDebug"] = value.ToString(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable verbose output while dumping by default
|
||||
/// </summary>
|
||||
public bool RedumperEnableVerbose
|
||||
{
|
||||
get { return GetBooleanSetting(_settings, "RedumperEnableVerbose", false); }
|
||||
set { _settings["RedumperEnableVerbose"] = value.ToString(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default number of rereads
|
||||
/// </summary>
|
||||
public int RedumperRereadCount
|
||||
{
|
||||
get { return GetInt32Setting(_settings, "RedumperRereadCount", 20); }
|
||||
set { _settings["RedumperRereadCount"] = 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>
|
||||
/// Output all found protections to a separate file in the directory
|
||||
/// </summary>
|
||||
public bool OutputSeparateProtectionFile
|
||||
{
|
||||
get { return GetBooleanSetting(_settings, "OutputSeparateProtectionFile", true); }
|
||||
set { _settings["OutputSeparateProtectionFile"] = 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>
|
||||
/// Enable tabs in all input fields
|
||||
/// </summary>
|
||||
public bool EnableTabsInInputFields
|
||||
{
|
||||
get { return GetBooleanSetting(_settings, "EnableTabsInInputFields", false); }
|
||||
set { _settings["EnableTabsInInputFields"] = value.ToString(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Limit outputs to Redump-supported values only
|
||||
/// </summary>
|
||||
public bool EnableRedumpCompatibility
|
||||
{
|
||||
get { return GetBooleanSetting(_settings, "EnableRedumpCompatibility", true); }
|
||||
set { _settings["EnableRedumpCompatibility"] = 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>
|
||||
/// 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(); }
|
||||
}
|
||||
|
||||
#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>
|
||||
/// Constructor taking an existing Options object
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
public Options(Options source)
|
||||
{
|
||||
_settings = new Dictionary<string, string>(source._settings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set all fields from an existing Options object
|
||||
/// </summary>
|
||||
/// <param name="source"></param>
|
||||
public void SetFromExisting(Options source)
|
||||
{
|
||||
_settings = new Dictionary<string, string>(source._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
|
||||
}
|
||||
}
|
||||
75
MPF.Core/Data/ProcessingQueue.cs
Normal file
75
MPF.Core/Data/ProcessingQueue.cs
Normal 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
52
MPF.Core/Data/Result.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
180
MPF.Core/Data/XgdInfo.cs
Normal file
180
MPF.Core/Data/XgdInfo.cs
Normal file
@@ -0,0 +1,180 @@
|
||||
using SabreTools.RedumpLib.Data;
|
||||
|
||||
namespace MPF.Core.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains information specific to an XGD disc
|
||||
/// </summary>
|
||||
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 XMID/XeMID string that all other information is derived from
|
||||
/// </summary>
|
||||
public string RawXMID { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// XGD1 XMID
|
||||
/// </summary>
|
||||
public SabreTools.Models.Xbox.XMID XMID { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// XGD2/3 XeMID
|
||||
/// </summary>
|
||||
public SabreTools.Models.Xbox.XeMID XeMID { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Populate a set of XGD information from a Master ID (XMID/XeMID) string
|
||||
/// </summary>
|
||||
/// <param name="xmid">XMID/XeMID string representing the DMI information</param>
|
||||
public XgdInfo(string xmid)
|
||||
{
|
||||
this.Initialized = false;
|
||||
if (string.IsNullOrWhiteSpace(xmid))
|
||||
return;
|
||||
|
||||
this.RawXMID = xmid.TrimEnd('\0');
|
||||
if (string.IsNullOrWhiteSpace(this.RawXMID))
|
||||
return;
|
||||
|
||||
// XGD1 information is 8 characters
|
||||
if (this.RawXMID.Length == 8)
|
||||
this.Initialized = ParseXGD1XMID(this.RawXMID);
|
||||
|
||||
// XGD2/3 information is semi-variable length
|
||||
else if (this.RawXMID.Length == 13 || this.RawXMID.Length == 14 || this.RawXMID.Length == 21 || this.RawXMID.Length == 22)
|
||||
this.Initialized = ParseXGD23XeMID(this.RawXMID);
|
||||
}
|
||||
|
||||
/// <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 (XMID != null)
|
||||
return $"{XMID.PublisherIdentifier}-{XMID.GameID}";
|
||||
|
||||
// XGD2/3 uses a specific identifier
|
||||
else if (XeMID?.PlatformIdentifier == '2')
|
||||
return $"{XeMID.PublisherIdentifier}-{XeMID.PlatformIdentifier}{XeMID.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 (XMID != null)
|
||||
return $"1.{XMID.VersionNumber}";
|
||||
|
||||
// XGD2/3 uses a specific identifier
|
||||
else if (XeMID?.PlatformIdentifier == '2')
|
||||
return $"1.{XeMID.SKU}";
|
||||
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse an XGD1 XMID string
|
||||
/// </summary>
|
||||
/// <param name="rawXmid">XMID string to attempt to parse</param>
|
||||
/// <returns>True if the XMID could be parsed, false otherwise</returns>
|
||||
private bool ParseXGD1XMID(string rawXmid)
|
||||
{
|
||||
try
|
||||
{
|
||||
var xmid = new SabreTools.Serialization.Files.XMID().Deserialize(rawXmid);
|
||||
if (xmid == null)
|
||||
return false;
|
||||
|
||||
this.XMID = xmid;
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse an XGD2/3 XeMID string
|
||||
/// </summary>
|
||||
/// <param name="rawXemid">XeMID string to attempt to parse</param>
|
||||
/// <returns>True if the XeMID could be parsed, false otherwise</returns>
|
||||
private bool ParseXGD23XeMID(string rawXemid)
|
||||
{
|
||||
try
|
||||
{
|
||||
var xemid = new SabreTools.Serialization.Files.XeMID().Deserialize(rawXemid);
|
||||
if (xemid == null)
|
||||
return false;
|
||||
|
||||
this.XeMID = xemid;
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#region Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Determine the region based on the XGD serial character
|
||||
/// </summary>
|
||||
/// <param name="region">Character denoting the region</param>
|
||||
/// <returns>Region, if possible</returns>
|
||||
public static Region? GetRegion(char region)
|
||||
{
|
||||
switch (region)
|
||||
{
|
||||
case 'W': return Region.World;
|
||||
case 'A': return Region.UnitedStatesOfAmerica;
|
||||
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
176
MPF.Core/Hashing/Hasher.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
154
MPF.Core/Hashing/OptimizedCRC.cs
Normal file
154
MPF.Core/Hashing/OptimizedCRC.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
80
MPF.Core/Hashing/ThreadLoadBuffer.cs
Normal file
80
MPF.Core/Hashing/ThreadLoadBuffer.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
52
MPF.Core/MPF.Core.csproj
Normal file
52
MPF.Core/MPF.Core.csproj
Normal file
@@ -0,0 +1,52 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net48;net6.0;net7.0</TargetFrameworks>
|
||||
<RuntimeIdentifiers>win7-x64;win8-x64;win81-x64;win10-x64;linux-x64;osx-x64</RuntimeIdentifiers>
|
||||
<Authors>Matt Nadareski;ReignStumble;Jakz</Authors>
|
||||
<Copyright>Copyright (c)2019-2023</Copyright>
|
||||
<RepositoryUrl>https://github.com/SabreTools/MPF</RepositoryUrl>
|
||||
<Version>2.6.4</Version>
|
||||
<IncludeSource>true</IncludeSource>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<NrtRevisionFormat>$(Version)-{chash:8}</NrtRevisionFormat>
|
||||
<NrtResolveSimpleAttributes>true</NrtResolveSimpleAttributes>
|
||||
<NrtShowRevision>false</NrtShowRevision>
|
||||
</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>
|
||||
<PackageReference Include="Microsoft.Management.Infrastructure" Version="2.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="SabreTools.Models" Version="1.1.2" />
|
||||
<PackageReference Include="SabreTools.RedumpLib" Version="1.1.1" />
|
||||
<PackageReference Include="SabreTools.Serialization" Version="1.1.2" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0" />
|
||||
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
174
MPF.Core/Utilities/BinaryReaderExtensions.cs
Normal file
174
MPF.Core/Utilities/BinaryReaderExtensions.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
396
MPF.Core/Utilities/Chime.cs
Normal file
396
MPF.Core/Utilities/Chime.cs
Normal file
@@ -0,0 +1,396 @@
|
||||
using System;
|
||||
|
||||
namespace MPF.Core.Utilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Methods to deal with outputting tones to the PC speaker
|
||||
/// </summary>
|
||||
public class Chime
|
||||
{
|
||||
/// <summary>
|
||||
/// Standard duration to play a single tone
|
||||
/// </summary>
|
||||
private const int standardDurationMs = 200;
|
||||
|
||||
#region Octave 0
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing C(0)
|
||||
/// </summary>
|
||||
private const int noteC0 = 16; // 16.35
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing D(0)
|
||||
/// </summary>
|
||||
private const int noteD0 = 18; // 18.35
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing E(0)
|
||||
/// </summary>
|
||||
private const int noteE0 = 21; // 20.60
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing F(0)
|
||||
/// </summary>
|
||||
private const int noteF0 = 22; // 21.83
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing G(0)
|
||||
/// </summary>
|
||||
private const int noteG0 = 25; // 24.50
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing A(0)
|
||||
/// </summary>
|
||||
private const int noteA0 = 28; // 27.50
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing B(0)
|
||||
/// </summary>
|
||||
private const int noteB0 = 31; // 30.87
|
||||
|
||||
#endregion
|
||||
|
||||
#region Octave 1
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing C(1)
|
||||
/// </summary>
|
||||
private const int noteC1 = 33; // 32.70
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing D(1)
|
||||
/// </summary>
|
||||
private const int noteD1 = 37; // 36.71
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing E(1)
|
||||
/// </summary>
|
||||
private const int noteE1 = 41; // 41.20
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing F(1)
|
||||
/// </summary>
|
||||
private const int noteF1 = 44; // 43.65
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing G(1)
|
||||
/// </summary>
|
||||
private const int noteG1 = 49; // 49.00
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing A(1)
|
||||
/// </summary>
|
||||
private const int noteA1 = 55; // 55.00
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing B(1)
|
||||
/// </summary>
|
||||
private const int noteB1 = 62; // 61.74
|
||||
|
||||
#endregion
|
||||
|
||||
#region Octave 2
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing C(2)
|
||||
/// </summary>
|
||||
private const int noteC2 = 65; // 65.41
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing D(2)
|
||||
/// </summary>
|
||||
private const int noteD2 = 73; // 73.42
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing E(2)
|
||||
/// </summary>
|
||||
private const int noteE2 = 82; // 82.41
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing F(2)
|
||||
/// </summary>
|
||||
private const int noteF2 = 87; // 87.31
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing G(2)
|
||||
/// </summary>
|
||||
private const int noteG2 = 98; // 98.00
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing A(2)
|
||||
/// </summary>
|
||||
private const int noteA2 = 110; // 110.00
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing B(2)
|
||||
/// </summary>
|
||||
private const int noteB2 = 123; // 123.47
|
||||
|
||||
#endregion
|
||||
|
||||
#region Octave 3
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing C(3)
|
||||
/// </summary>
|
||||
private const int noteC3 = 131; // 130.81
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing D(3)
|
||||
/// </summary>
|
||||
private const int noteD3 = 147; // 146.83
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing E(3)
|
||||
/// </summary>
|
||||
private const int noteE3 = 165; // 164.81
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing F(3)
|
||||
/// </summary>
|
||||
private const int noteF3 = 175; // 174.61
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing G(3)
|
||||
/// </summary>
|
||||
private const int noteG3 = 196; // 196.00
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing A(3)
|
||||
/// </summary>
|
||||
private const int noteA3 = 220; // 220.00
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing B(3)
|
||||
/// </summary>
|
||||
private const int noteB3 = 247; // 246.94
|
||||
|
||||
#endregion
|
||||
|
||||
#region Octave 4
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing C(4)
|
||||
/// </summary>
|
||||
private const int noteC4 = 262; // 261.63
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing D(4)
|
||||
/// </summary>
|
||||
private const int noteD4 = 294; // 293.66
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing E(4)
|
||||
/// </summary>
|
||||
private const int noteE4 = 330; // 329.63
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing F(4)
|
||||
/// </summary>
|
||||
private const int noteF4 = 349; // 349.23
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing G(4)
|
||||
/// </summary>
|
||||
private const int noteG4 = 392; // 392.00
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing A(4)
|
||||
/// </summary>
|
||||
private const int noteA4 = 440; // 440.00
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing B(4)
|
||||
/// </summary>
|
||||
private const int noteB4 = 494; // 493.88
|
||||
|
||||
#endregion
|
||||
|
||||
#region Octave 5
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing C(5)
|
||||
/// </summary>
|
||||
private const int noteC5 = 523; // 523.25
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing D(5)
|
||||
/// </summary>
|
||||
private const int noteD5 = 587; // 587.33
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing E(5)
|
||||
/// </summary>
|
||||
private const int noteE5 = 659; // 659.25
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing F(5)
|
||||
/// </summary>
|
||||
private const int noteF5 = 698; // 698.46
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing G(5)
|
||||
/// </summary>
|
||||
private const int noteG5 = 783; // 783.99
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing A(5)
|
||||
/// </summary>
|
||||
private const int noteA5 = 880; // 880.00
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing B(5)
|
||||
/// </summary>
|
||||
private const int noteB5 = 988; // 987.77
|
||||
|
||||
#endregion
|
||||
|
||||
#region Octave 6
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing C(6)
|
||||
/// </summary>
|
||||
private const int noteC6 = 1047; // 1046.50
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing D(6)
|
||||
/// </summary>
|
||||
private const int noteD6 = 1175; // 1174.66
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing E(6)
|
||||
/// </summary>
|
||||
private const int noteE6 = 1319; // 1318.51
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing F(6)
|
||||
/// </summary>
|
||||
private const int noteF6 = 1397; // 1396.91
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing G(6)
|
||||
/// </summary>
|
||||
private const int noteG6 = 1568; // 1567.98
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing A(6)
|
||||
/// </summary>
|
||||
private const int noteA6 = 1760; // 1760.00
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing B(6)
|
||||
/// </summary>
|
||||
private const int noteB6 = 1976; // 1975.53
|
||||
|
||||
#endregion
|
||||
|
||||
#region Octave 7
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing C(7)
|
||||
/// </summary>
|
||||
private const int noteC7 = 2093; // 2093.00
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing D(7)
|
||||
/// </summary>
|
||||
private const int noteD7 = 2349; // 2349.32
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing E(7)
|
||||
/// </summary>
|
||||
private const int noteE7 = 2637; // 2637.02
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing F(7)
|
||||
/// </summary>
|
||||
private const int noteF7 = 2794; // 2793.83
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing G(7)
|
||||
/// </summary>
|
||||
private const int noteG7 = 3136; // 3135.96
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing A(7)
|
||||
/// </summary>
|
||||
private const int noteA7 = 3520; // 3520.00
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing B(7)
|
||||
/// </summary>
|
||||
private const int noteB7 = 3951; // 3951.07
|
||||
|
||||
#endregion
|
||||
|
||||
#region Octave 8
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing C(8)
|
||||
/// </summary>
|
||||
private const int noteC8 = 4186; // 4186.01
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing D(8)
|
||||
/// </summary>
|
||||
private const int noteD8 = 4699; // 4698.63
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing E(8)
|
||||
/// </summary>
|
||||
private const int noteE8 = 5274; // 5274.04
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing F(8)
|
||||
/// </summary>
|
||||
private const int noteF8 = 5588; // 5587.65
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing G(8)
|
||||
/// </summary>
|
||||
private const int noteG8 = 6272; // 6271.93
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing A(8)
|
||||
/// </summary>
|
||||
private const int noteA8 = 7040; // 7040.00
|
||||
|
||||
/// <summary>
|
||||
/// Frequency representing B(8)
|
||||
/// </summary>
|
||||
private const int noteB8 = 7902; // 7902.13
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Output a series of beeps for completion, similar to DiscImageCreator
|
||||
/// </summary>
|
||||
/// <param name="success">True if the upward series should play, false otherwise</param>
|
||||
public static void StandardCompletion(bool success)
|
||||
{
|
||||
if (success)
|
||||
{
|
||||
Console.Beep(noteC4, standardDurationMs);
|
||||
Console.Beep(noteD4, standardDurationMs);
|
||||
Console.Beep(noteE4, standardDurationMs);
|
||||
Console.Beep(noteF4, standardDurationMs);
|
||||
Console.Beep(noteG4, standardDurationMs);
|
||||
Console.Beep(noteA4, standardDurationMs);
|
||||
Console.Beep(noteB4, standardDurationMs);
|
||||
Console.Beep(noteC5, standardDurationMs);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Beep(noteC5, standardDurationMs);
|
||||
Console.Beep(noteB4, standardDurationMs);
|
||||
Console.Beep(noteA4, standardDurationMs);
|
||||
Console.Beep(noteG4, standardDurationMs);
|
||||
Console.Beep(noteF4, standardDurationMs);
|
||||
Console.Beep(noteE4, standardDurationMs);
|
||||
Console.Beep(noteD4, standardDurationMs);
|
||||
Console.Beep(noteC4, standardDurationMs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
149
MPF.Core/Utilities/EnumExtensions.cs
Normal file
149
MPF.Core/Utilities/EnumExtensions.cs
Normal file
@@ -0,0 +1,149 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MPF.Core.Converters;
|
||||
using MPF.Core.Data;
|
||||
using SabreTools.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:
|
||||
case RedumpSystem.SonyPlayStationPortable:
|
||||
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.HasbroiONEducationalGamingSystem:
|
||||
case RedumpSystem.HasbroVideoNow:
|
||||
case RedumpSystem.HasbroVideoNowColor:
|
||||
case RedumpSystem.HasbroVideoNowJr:
|
||||
case RedumpSystem.HasbroVideoNowXP:
|
||||
case RedumpSystem.PhilipsCDi:
|
||||
case RedumpSystem.PlayStationGameSharkUpdates:
|
||||
case RedumpSystem.SuperAudioCD:
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List all programs with their short usable names
|
||||
/// </summary>
|
||||
public static List<string> ListPrograms()
|
||||
{
|
||||
var programs = new List<string>();
|
||||
|
||||
foreach (var val in Enum.GetValues(typeof(InternalProgram)))
|
||||
{
|
||||
if (((InternalProgram)val) == InternalProgram.NONE)
|
||||
continue;
|
||||
|
||||
programs.Add($"{((InternalProgram?)val).LongName()}");
|
||||
}
|
||||
|
||||
return programs;
|
||||
}
|
||||
}
|
||||
}
|
||||
121
MPF.Core/Utilities/Logging.cs
Normal file
121
MPF.Core/Utilities/Logging.cs
Normal 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]}");
|
||||
}
|
||||
}
|
||||
}
|
||||
178
MPF.Core/Utilities/OptionsLoader.cs
Normal file
178
MPF.Core/Utilities/OptionsLoader.cs
Normal file
@@ -0,0 +1,178 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using MPF.Core.Converters;
|
||||
using MPF.Core.Data;
|
||||
|
||||
namespace MPF.Core.Utilities
|
||||
{
|
||||
public static class OptionsLoader
|
||||
{
|
||||
#region Arguments
|
||||
|
||||
/// <summary>
|
||||
/// Load the current set of options from application arguments
|
||||
/// </summary>
|
||||
public static (Options, string, int) LoadFromArguments(string[] args, int startIndex = 0)
|
||||
{
|
||||
// Create the output values with defaults
|
||||
var options = new Options()
|
||||
{
|
||||
RedumpUsername = null,
|
||||
RedumpPassword = null,
|
||||
InternalProgram = InternalProgram.NONE,
|
||||
OutputSubmissionJSON = false,
|
||||
CompressLogFiles = false,
|
||||
};
|
||||
|
||||
string parsedPath = null;
|
||||
|
||||
// These values require multiple parts to be active
|
||||
bool scan = false, protectFile = false;
|
||||
|
||||
// If we have no arguments, just return
|
||||
if (args == null || args.Length == 0)
|
||||
return (options, null, 0);
|
||||
|
||||
// If we have an invalid start index, just return
|
||||
if (startIndex < 0 || startIndex >= args.Length)
|
||||
return (options, null, startIndex);
|
||||
|
||||
// Loop through the arguments and parse out values
|
||||
for (; startIndex < args.Length; startIndex++)
|
||||
{
|
||||
// Redump login
|
||||
if (args[startIndex].StartsWith("-c=") || args[startIndex].StartsWith("--credentials="))
|
||||
{
|
||||
string[] credentials = args[startIndex].Split('=')[1].Split(';');
|
||||
options.RedumpUsername = credentials[0];
|
||||
options.RedumpPassword = credentials[1];
|
||||
}
|
||||
else if (args[startIndex] == "-c" || args[startIndex] == "--credentials")
|
||||
{
|
||||
options.RedumpUsername = args[startIndex + 1];
|
||||
options.RedumpPassword = args[startIndex + 2];
|
||||
startIndex += 2;
|
||||
}
|
||||
|
||||
// Use specific program
|
||||
else if (args[startIndex].StartsWith("-u=") || args[startIndex].StartsWith("--use="))
|
||||
{
|
||||
string internalProgram = args[startIndex].Split('=')[1];
|
||||
options.InternalProgram = EnumConverter.ToInternalProgram(internalProgram);
|
||||
}
|
||||
else if (args[startIndex] == "-u" || args[startIndex] == "--use")
|
||||
{
|
||||
string internalProgram = args[startIndex + 1];
|
||||
options.InternalProgram = EnumConverter.ToInternalProgram(internalProgram);
|
||||
startIndex++;
|
||||
}
|
||||
|
||||
// Use a device path for physical checks
|
||||
else if (args[startIndex].StartsWith("-p=") || args[startIndex].StartsWith("--path="))
|
||||
{
|
||||
parsedPath = args[startIndex].Split('=')[1];
|
||||
}
|
||||
else if (args[startIndex] == "-p" || args[startIndex] == "--path")
|
||||
{
|
||||
parsedPath = args[startIndex + 1];
|
||||
startIndex++;
|
||||
}
|
||||
|
||||
// Scan for protection (requires device path)
|
||||
else if (args[startIndex].Equals("-s") || args[startIndex].Equals("--scan"))
|
||||
{
|
||||
scan = true;
|
||||
}
|
||||
|
||||
// Output protection to separate file (requires scan for protection)
|
||||
else if (args[startIndex].Equals("-f") || args[startIndex].Equals("--protect-file"))
|
||||
{
|
||||
protectFile = true;
|
||||
}
|
||||
|
||||
// Output submission JSON
|
||||
else if (args[startIndex].Equals("-j") || args[startIndex].Equals("--json"))
|
||||
{
|
||||
options.OutputSubmissionJSON = true;
|
||||
}
|
||||
|
||||
// Compress log and extraneous files
|
||||
else if (args[startIndex].Equals("-z") || args[startIndex].Equals("--zip"))
|
||||
{
|
||||
options.CompressLogFiles = true;
|
||||
}
|
||||
|
||||
// Default, we fall out
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Now deal with the complex options
|
||||
options.ScanForProtection = scan && !string.IsNullOrWhiteSpace(parsedPath);
|
||||
options.OutputSeparateProtectionFile = scan && protectFile && !string.IsNullOrWhiteSpace(parsedPath);
|
||||
|
||||
return (options, parsedPath, startIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return a list of supported arguments and descriptions
|
||||
/// </summary>
|
||||
public static List<string> PrintSupportedArguments()
|
||||
{
|
||||
var supportedArguments = new List<string>();
|
||||
|
||||
supportedArguments.Add("-u, --use <program> Dumping program output type [REQUIRED]");
|
||||
supportedArguments.Add("-c, --credentials <user> <pw> Redump username and password");
|
||||
supportedArguments.Add("-p, --path <drivepath> Physical drive path for additional checks");
|
||||
supportedArguments.Add("-s, --scan Enable copy protection scan (requires --path)");
|
||||
supportedArguments.Add("-f, --protect-file Output protection to separate file (requires --scan)");
|
||||
supportedArguments.Add("-j, --json Enable submission JSON output");
|
||||
supportedArguments.Add("-z, --zip Enable log file compression");
|
||||
|
||||
return supportedArguments;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Configuration
|
||||
|
||||
/// <summary>
|
||||
/// Load the current set of options from the application configuration
|
||||
/// </summary>
|
||||
public static Options LoadFromConfig()
|
||||
{
|
||||
Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
|
||||
|
||||
var settings = configFile.AppSettings.Settings;
|
||||
var dict = new Dictionary<string, string>();
|
||||
|
||||
foreach (string key in settings.AllKeys)
|
||||
{
|
||||
dict[key] = settings[key]?.Value ?? string.Empty;
|
||||
}
|
||||
|
||||
return new Options(dict);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save the current set of options to the application configuration
|
||||
/// </summary>
|
||||
public static void SaveToConfig(Options options)
|
||||
{
|
||||
Configuration configFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
|
||||
|
||||
// Loop through all settings in Options and save them, overwriting existing settings
|
||||
foreach (var kvp in options)
|
||||
{
|
||||
configFile.AppSettings.Settings.Remove(kvp.Key);
|
||||
configFile.AppSettings.Settings.Add(kvp.Key, kvp.Value);
|
||||
}
|
||||
|
||||
configFile.Save(ConfigurationSaveMode.Modified);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
213
MPF.Core/Utilities/Tools.cs
Normal file
213
MPF.Core/Utilities/Tools.cs
Normal file
@@ -0,0 +1,213 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using MPF.Core.Data;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SabreTools.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()
|
||||
{
|
||||
try
|
||||
{
|
||||
var assemblyVersion = Attribute.GetCustomAttribute(Assembly.GetEntryAssembly(), typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute;
|
||||
return assemblyVersion.InformationalVersion;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return ex.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the latest version of MPF from GitHub and the release URL
|
||||
/// </summary>
|
||||
private static (string tag, string url) GetRemoteVersionAndUrl()
|
||||
{
|
||||
#if NETFRAMEWORK
|
||||
using (System.Net.WebClient wc = new System.Net.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);
|
||||
}
|
||||
#else
|
||||
using (System.Net.Http.HttpClient hc = new System.Net.Http.HttpClient())
|
||||
{
|
||||
// TODO: Figure out a better way than having this hardcoded...
|
||||
string url = "https://api.github.com/repos/SabreTools/MPF/releases/latest";
|
||||
var message = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, url);
|
||||
message.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0");
|
||||
string latestReleaseJsonString = hc.Send(message)?.Content?.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
var latestReleaseJson = JObject.Parse(latestReleaseJsonString);
|
||||
string latestTag = latestReleaseJson["tag_name"].ToString();
|
||||
string releaseUrl = latestReleaseJson["html_url"].ToString();
|
||||
|
||||
return (latestTag, releaseUrl);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
4
MPF.Library/AssemblyInfo.cs
Normal file
4
MPF.Library/AssemblyInfo.cs
Normal file
@@ -0,0 +1,4 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
// Anything marked as internal can be used by the test methods
|
||||
[assembly: InternalsVisibleTo("MPF.Test")]
|
||||
566
MPF.Library/DumpEnvironment.cs
Normal file
566
MPF.Library/DumpEnvironment.cs
Normal file
@@ -0,0 +1,566 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using BurnOutSharp;
|
||||
using MPF.Core.Data;
|
||||
using MPF.Core.Utilities;
|
||||
using MPF.Modules;
|
||||
using SabreTools.RedumpLib.Data;
|
||||
|
||||
namespace MPF.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the state of all settings to be used during dumping
|
||||
/// </summary>
|
||||
public class DumpEnvironment
|
||||
{
|
||||
#region Output paths
|
||||
|
||||
/// <summary>
|
||||
/// Base output file path to write files to
|
||||
/// </summary>
|
||||
public string OutputPath { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region UI information
|
||||
|
||||
/// <summary>
|
||||
/// Drive object representing the current drive
|
||||
/// </summary>
|
||||
public Drive Drive { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Currently selected system
|
||||
/// </summary>
|
||||
public RedumpSystem? System { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Currently selected media type
|
||||
/// </summary>
|
||||
public MediaType? Type { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Currently selected dumping program
|
||||
/// </summary>
|
||||
public InternalProgram InternalProgram { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Options object representing user-defined options
|
||||
/// </summary>
|
||||
public Core.Data.Options Options { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Parameters object representing what to send to the internal program
|
||||
/// </summary>
|
||||
public BaseParameters Parameters { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
/// <summary>
|
||||
/// Generic way of reporting a message
|
||||
/// </summary>
|
||||
public EventHandler<string> ReportStatus;
|
||||
|
||||
/// <summary>
|
||||
/// Queue of items that need to be logged
|
||||
/// </summary>
|
||||
private ProcessingQueue<string> outputQueue;
|
||||
|
||||
/// <summary>
|
||||
/// Event handler for data returned from a process
|
||||
/// </summary>
|
||||
private void OutputToLog(object proc, string args) => outputQueue.Enqueue(args);
|
||||
|
||||
/// <summary>
|
||||
/// Process the outputs in the queue
|
||||
/// </summary>
|
||||
private void ProcessOutputs(string nextOutput) => ReportStatus.Invoke(this, nextOutput);
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Constructor for a full DumpEnvironment object from user information
|
||||
/// </summary>
|
||||
/// <param name="options"></param>
|
||||
/// <param name="outputPath"></param>
|
||||
/// <param name="drive"></param>
|
||||
/// <param name="system"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="internalProgram"></param>
|
||||
/// <param name="parameters"></param>
|
||||
public DumpEnvironment(Core.Data.Options options,
|
||||
string outputPath,
|
||||
Drive drive,
|
||||
RedumpSystem? system,
|
||||
MediaType? type,
|
||||
InternalProgram? internalProgram,
|
||||
string parameters)
|
||||
{
|
||||
// Set options object
|
||||
this.Options = options;
|
||||
|
||||
// Output paths
|
||||
this.OutputPath = InfoTool.NormalizeOutputPaths(outputPath);
|
||||
|
||||
// UI information
|
||||
this.Drive = drive;
|
||||
this.System = system ?? options.DefaultSystem;
|
||||
this.Type = type ?? MediaType.NONE;
|
||||
this.InternalProgram = internalProgram ?? options.InternalProgram;
|
||||
|
||||
// Dumping program
|
||||
SetParameters(parameters);
|
||||
}
|
||||
|
||||
#region Public Functionality
|
||||
|
||||
/// <summary>
|
||||
/// Adjust output paths if we're using DiscImageCreator
|
||||
/// </summary>
|
||||
public void AdjustPathsForDiscImageCreator()
|
||||
{
|
||||
// Only DiscImageCreator has issues with paths
|
||||
if (this.Parameters.InternalProgram != InternalProgram.DiscImageCreator)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
// Normalize the output path
|
||||
string outputPath = InfoTool.NormalizeOutputPaths(this.OutputPath);
|
||||
|
||||
// Replace all instances in the output directory
|
||||
string outputDirectory = Path.GetDirectoryName(outputPath);
|
||||
outputDirectory = outputDirectory.Replace(".", "_");
|
||||
|
||||
// Replace all instances in the output filename
|
||||
string outputFilename = Path.GetFileNameWithoutExtension(outputPath);
|
||||
outputFilename = outputFilename.Replace(".", "_");
|
||||
|
||||
// Get the extension for recreating the path
|
||||
string outputExtension = Path.GetExtension(outputPath).TrimStart('.');
|
||||
|
||||
// Rebuild the output path
|
||||
if (!string.IsNullOrWhiteSpace(outputExtension))
|
||||
this.OutputPath = Path.Combine(outputDirectory, $"{outputFilename}.{outputExtension}");
|
||||
else
|
||||
this.OutputPath = Path.Combine(outputDirectory, outputFilename);
|
||||
|
||||
// Assign the path to the filename as well for dumping
|
||||
((Modules.DiscImageCreator.Parameters)this.Parameters).Filename = this.OutputPath;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the parameters object based on the internal program and parameters string
|
||||
/// </summary>
|
||||
/// <param name="parameters">String representation of the parameters</param>
|
||||
public void SetParameters(string parameters)
|
||||
{
|
||||
switch (this.InternalProgram)
|
||||
{
|
||||
// Dumping support
|
||||
case InternalProgram.Aaru:
|
||||
this.Parameters = new Modules.Aaru.Parameters(parameters) { ExecutablePath = Options.AaruPath };
|
||||
break;
|
||||
|
||||
case InternalProgram.DiscImageCreator:
|
||||
this.Parameters = new Modules.DiscImageCreator.Parameters(parameters) { ExecutablePath = Options.DiscImageCreatorPath };
|
||||
break;
|
||||
|
||||
case InternalProgram.Redumper:
|
||||
this.Parameters = new Modules.Redumper.Parameters(parameters) { ExecutablePath = Options.RedumperPath };
|
||||
break;
|
||||
|
||||
// Verification support only
|
||||
case InternalProgram.CleanRip:
|
||||
this.Parameters = new Modules.CleanRip.Parameters(parameters) { ExecutablePath = null };
|
||||
break;
|
||||
|
||||
case InternalProgram.DCDumper:
|
||||
this.Parameters = null; // TODO: Create correct parameter type when supported
|
||||
break;
|
||||
|
||||
case InternalProgram.UmdImageCreator:
|
||||
this.Parameters = new Modules.UmdImageCreator.Parameters(parameters) { ExecutablePath = null };
|
||||
break;
|
||||
|
||||
// This should never happen, but it needs a fallback
|
||||
default:
|
||||
this.Parameters = new Modules.DiscImageCreator.Parameters(parameters) { ExecutablePath = Options.DiscImageCreatorPath };
|
||||
break;
|
||||
}
|
||||
|
||||
// Set system and type
|
||||
this.Parameters.System = this.System;
|
||||
this.Parameters.Type = this.Type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the full parameter string for either DiscImageCreator or Aaru
|
||||
/// </summary>
|
||||
/// <param name="driveSpeed">Nullable int representing the drive speed</param>
|
||||
/// <returns>String representing the params, null on error</returns>
|
||||
public string GetFullParameters(int? driveSpeed)
|
||||
{
|
||||
// Populate with the correct params for inputs (if we're not on the default option)
|
||||
if (System != null && Type != MediaType.NONE)
|
||||
{
|
||||
// If drive letter is invalid, skip this
|
||||
if (Drive == null)
|
||||
return null;
|
||||
|
||||
// Set the proper parameters
|
||||
switch (this.InternalProgram)
|
||||
{
|
||||
case InternalProgram.Aaru:
|
||||
Parameters = new Modules.Aaru.Parameters(System, Type, Drive.Letter, this.OutputPath, driveSpeed, Options);
|
||||
break;
|
||||
|
||||
case InternalProgram.DiscImageCreator:
|
||||
Parameters = new Modules.DiscImageCreator.Parameters(System, Type, Drive.Letter, this.OutputPath, driveSpeed, Options);
|
||||
break;
|
||||
|
||||
case InternalProgram.Redumper:
|
||||
Parameters = new Modules.Redumper.Parameters(System, Type, Drive.Letter, this.OutputPath, driveSpeed, Options);
|
||||
break;
|
||||
|
||||
// This should never happen, but it needs a fallback
|
||||
default:
|
||||
Parameters = new Modules.DiscImageCreator.Parameters(System, Type, Drive.Letter, this.OutputPath, driveSpeed, Options);
|
||||
break;
|
||||
}
|
||||
|
||||
// Generate and return the param string
|
||||
return Parameters.GenerateParameters();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Dumping
|
||||
|
||||
/// <summary>
|
||||
/// Cancel an in-progress dumping process
|
||||
/// </summary>
|
||||
public void CancelDumping() => Parameters.KillInternalProgram();
|
||||
|
||||
/// <summary>
|
||||
/// Eject the disc using DiscImageCreator
|
||||
/// </summary>
|
||||
public async Task<string> EjectDisc() =>
|
||||
await RunStandaloneDiscImageCreatorCommand(Modules.DiscImageCreator.CommandStrings.Eject);
|
||||
|
||||
/// <summary>
|
||||
/// Reset the current drive using DiscImageCreator
|
||||
/// </summary>
|
||||
public async Task<string> ResetDrive() =>
|
||||
await RunStandaloneDiscImageCreatorCommand(Modules.DiscImageCreator.CommandStrings.Reset);
|
||||
|
||||
/// <summary>
|
||||
/// Execute the initial invocation of the dumping programs
|
||||
/// </summary>
|
||||
/// <param name="progress">Optional result progress callback</param>
|
||||
public async Task<Result> Run(IProgress<Result> progress = null)
|
||||
{
|
||||
// Check that we have the basics for dumping
|
||||
Result result = IsValidForDump();
|
||||
if (!result)
|
||||
return result;
|
||||
|
||||
// Invoke output processing, if needed
|
||||
if (!Options.ToolsInSeparateWindow)
|
||||
{
|
||||
outputQueue = new ProcessingQueue<string>(ProcessOutputs);
|
||||
Parameters.ReportStatus += OutputToLog;
|
||||
}
|
||||
|
||||
// Execute internal tool
|
||||
progress?.Report(Result.Success($"Executing {this.InternalProgram}... {(Options.ToolsInSeparateWindow ? "please wait!" : "see log for output!")}"));
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(this.OutputPath));
|
||||
await Task.Run(() => Parameters.ExecuteInternalProgram(Options.ToolsInSeparateWindow));
|
||||
progress?.Report(Result.Success($"{this.InternalProgram} has finished!"));
|
||||
|
||||
// Execute additional tools
|
||||
progress?.Report(Result.Success("Running any additional tools... see log for output!"));
|
||||
result = await Task.Run(() => ExecuteAdditionalTools());
|
||||
progress?.Report(result);
|
||||
|
||||
// Remove event handler if needed
|
||||
if (!Options.ToolsInSeparateWindow)
|
||||
{
|
||||
outputQueue.Dispose();
|
||||
Parameters.ReportStatus -= OutputToLog;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that the current environment has a complete dump and create submission info is possible
|
||||
/// </summary>
|
||||
/// <param name="resultProgress">Optional result progress callback</param>
|
||||
/// <param name="protectionProgress">Optional protection progress callback</param>
|
||||
/// <param name="processUserInfo">Optional user prompt to deal with submission information</param>
|
||||
/// <returns>Result instance with the outcome</returns>
|
||||
public async Task<Result> VerifyAndSaveDumpOutput(
|
||||
IProgress<Result> resultProgress = null,
|
||||
IProgress<ProtectionProgress> protectionProgress = null,
|
||||
Func<SubmissionInfo, (bool?, SubmissionInfo)> processUserInfo = null)
|
||||
{
|
||||
resultProgress?.Report(Result.Success("Gathering submission information... please wait!"));
|
||||
|
||||
// Get the output directory and filename separately
|
||||
string outputDirectory = Path.GetDirectoryName(this.OutputPath);
|
||||
string outputFilename = Path.GetFileName(this.OutputPath);
|
||||
|
||||
// Check to make sure that the output had all the correct files
|
||||
(bool foundFiles, List<string> missingFiles) = InfoTool.FoundAllFiles(outputDirectory, outputFilename, this.Parameters, false);
|
||||
if (!foundFiles)
|
||||
{
|
||||
resultProgress?.Report(Result.Failure($"There were files missing from the output:\n{string.Join("\n", missingFiles)}"));
|
||||
return Result.Failure("Error! Please check output directory as dump may be incomplete!");
|
||||
}
|
||||
|
||||
// Extract the information from the output files
|
||||
resultProgress?.Report(Result.Success("Extracting output information from output files..."));
|
||||
SubmissionInfo submissionInfo = await InfoTool.ExtractOutputInformation(
|
||||
this.OutputPath,
|
||||
this.Drive,
|
||||
this.System,
|
||||
this.Type,
|
||||
this.Options,
|
||||
this.Parameters,
|
||||
resultProgress,
|
||||
protectionProgress);
|
||||
resultProgress?.Report(Result.Success("Extracting information complete!"));
|
||||
|
||||
// Eject the disc automatically if configured to
|
||||
if (Options.EjectAfterDump == true)
|
||||
{
|
||||
resultProgress?.Report(Result.Success($"Ejecting disc in drive {Drive.Letter}"));
|
||||
await EjectDisc();
|
||||
}
|
||||
|
||||
// Reset the drive automatically if configured to
|
||||
if (this.InternalProgram == InternalProgram.DiscImageCreator && Options.DICResetDriveAfterDump)
|
||||
{
|
||||
resultProgress?.Report(Result.Success($"Resetting drive {Drive.Letter}"));
|
||||
await ResetDrive();
|
||||
}
|
||||
|
||||
// Get user-modifiable information if confugured to
|
||||
if (Options.PromptForDiscInformation && processUserInfo != null)
|
||||
{
|
||||
resultProgress?.Report(Result.Success("Waiting for additional disc information..."));
|
||||
|
||||
bool? filledInfo;
|
||||
(filledInfo, submissionInfo) = processUserInfo(submissionInfo);
|
||||
|
||||
if (filledInfo == true)
|
||||
resultProgress?.Report(Result.Success("Additional disc information added!"));
|
||||
else
|
||||
resultProgress?.Report(Result.Success("Disc information skipped!"));
|
||||
}
|
||||
|
||||
// Process special fields for site codes
|
||||
resultProgress?.Report(Result.Success("Processing site codes..."));
|
||||
InfoTool.ProcessSpecialFields(submissionInfo);
|
||||
resultProgress?.Report(Result.Success("Processing complete!"));
|
||||
|
||||
// Format the information for the text output
|
||||
resultProgress?.Report(Result.Success("Formatting information..."));
|
||||
(List<string> formattedValues, string formatResult) = InfoTool.FormatOutputData(submissionInfo, this.Options);
|
||||
if (formattedValues == null)
|
||||
resultProgress?.Report(Result.Success(formatResult));
|
||||
else
|
||||
resultProgress?.Report(Result.Failure(formatResult));
|
||||
|
||||
// Write the text output
|
||||
resultProgress?.Report(Result.Success("Writing information to !submissionInfo.txt..."));
|
||||
(bool txtSuccess, string txtResult) = InfoTool.WriteOutputData(outputDirectory, formattedValues);
|
||||
if (txtSuccess)
|
||||
resultProgress?.Report(Result.Success(txtResult));
|
||||
else
|
||||
resultProgress?.Report(Result.Failure(txtResult));
|
||||
|
||||
// Write the copy protection output
|
||||
if (Options.ScanForProtection && Options.OutputSeparateProtectionFile)
|
||||
{
|
||||
resultProgress?.Report(Result.Success("Writing protection to !protectionInfo.txt..."));
|
||||
bool scanSuccess = InfoTool.WriteProtectionData(outputDirectory, submissionInfo);
|
||||
if (scanSuccess)
|
||||
resultProgress?.Report(Result.Success("Writing complete!"));
|
||||
else
|
||||
resultProgress?.Report(Result.Failure("Writing could not complete!"));
|
||||
}
|
||||
|
||||
// Write the JSON output, if required
|
||||
if (Options.OutputSubmissionJSON)
|
||||
{
|
||||
resultProgress?.Report(Result.Success($"Writing information to !submissionInfo.json{(Options.IncludeArtifacts ? ".gz" : string.Empty)}..."));
|
||||
bool jsonSuccess = InfoTool.WriteOutputData(outputDirectory, submissionInfo, Options.IncludeArtifacts);
|
||||
if (jsonSuccess)
|
||||
resultProgress?.Report(Result.Success("Writing complete!"));
|
||||
else
|
||||
resultProgress?.Report(Result.Failure("Writing could not complete!"));
|
||||
}
|
||||
|
||||
// Compress the logs, if required
|
||||
if (Options.CompressLogFiles)
|
||||
{
|
||||
resultProgress?.Report(Result.Success("Compressing log files..."));
|
||||
(bool compressSuccess, string compressResult) = InfoTool.CompressLogFiles(outputDirectory, outputFilename, this.Parameters);
|
||||
if (compressSuccess)
|
||||
resultProgress?.Report(Result.Success(compressResult));
|
||||
else
|
||||
resultProgress?.Report(Result.Failure(compressResult));
|
||||
}
|
||||
|
||||
resultProgress?.Report(Result.Success("Submission information process complete!"));
|
||||
return Result.Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the parameters are valid
|
||||
/// </summary>
|
||||
/// <returns>True if the configuration is valid, false otherwise</returns>
|
||||
internal bool ParametersValid()
|
||||
{
|
||||
bool parametersValid = Parameters.IsValid();
|
||||
bool floppyValid = !(Drive.InternalDriveType == InternalDriveType.Floppy ^ Type == MediaType.FloppyDisk);
|
||||
|
||||
// TODO: HardDisk being in the Removable category is a hack, fix this later
|
||||
bool removableDiskValid = !((Drive.InternalDriveType == InternalDriveType.Removable || Drive.InternalDriveType == InternalDriveType.HardDisk)
|
||||
^ (Type == MediaType.CompactFlash || Type == MediaType.SDCard || Type == MediaType.FlashDrive || Type == MediaType.HardDisk));
|
||||
|
||||
return parametersValid && floppyValid && removableDiskValid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run any additional tools given a DumpEnvironment
|
||||
/// </summary>
|
||||
/// <returns>Result instance with the outcome</returns>
|
||||
private Result ExecuteAdditionalTools() => Result.Success("No external tools needed!");
|
||||
|
||||
/// <summary>
|
||||
/// Run internal program async with an input set of parameters
|
||||
/// </summary>
|
||||
/// <param name="parameters"></param>
|
||||
/// <returns>Standard output from commandline window</returns>
|
||||
private async Task<string> ExecuteInternalProgram(BaseParameters parameters)
|
||||
{
|
||||
Process childProcess;
|
||||
string output = await Task.Run(() =>
|
||||
{
|
||||
childProcess = new Process()
|
||||
{
|
||||
StartInfo = new ProcessStartInfo()
|
||||
{
|
||||
FileName = parameters.ExecutablePath,
|
||||
Arguments = parameters.GenerateParameters(),
|
||||
CreateNoWindow = true,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardInput = true,
|
||||
RedirectStandardOutput = true,
|
||||
},
|
||||
};
|
||||
childProcess.Start();
|
||||
childProcess.WaitForExit(1000);
|
||||
|
||||
// Just in case, we want to push a button 5 times to clear any errors
|
||||
for (int i = 0; i < 5; i++)
|
||||
childProcess.StandardInput.WriteLine("Y");
|
||||
|
||||
string stdout = childProcess.StandardOutput.ReadToEnd();
|
||||
childProcess.Dispose();
|
||||
return stdout;
|
||||
});
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate the current environment is ready for a dump
|
||||
/// </summary>
|
||||
/// <returns>Result instance with the outcome</returns>
|
||||
private Result IsValidForDump()
|
||||
{
|
||||
// Validate that everything is good
|
||||
if (!ParametersValid())
|
||||
return Result.Failure("Error! Current configuration is not supported!");
|
||||
|
||||
// Fix the output paths, just in case
|
||||
this.OutputPath = InfoTool.NormalizeOutputPaths(this.OutputPath);
|
||||
|
||||
// Validate that the output path isn't on the dumping drive
|
||||
if (this.OutputPath[0] == Drive.Letter)
|
||||
return Result.Failure("Error! Cannot output to same drive that is being dumped!");
|
||||
|
||||
// Validate that the required program exists
|
||||
if (!File.Exists(Parameters.ExecutablePath))
|
||||
return Result.Failure($"Error! {Parameters.ExecutablePath} does not exist!");
|
||||
|
||||
// Validate that the dumping drive doesn't contain the executable
|
||||
string fullExecutablePath = Path.GetFullPath(Parameters.ExecutablePath);
|
||||
if (fullExecutablePath[0] == Drive.Letter)
|
||||
return Result.Failure("Error! Cannot dump same drive that executable resides on!");
|
||||
|
||||
// Validate that the current configuration is supported
|
||||
return Tools.GetSupportStatus(System, Type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate that DIscImageCreator is able to be found
|
||||
/// </summary>
|
||||
/// <returns>True if DiscImageCreator is found properly, false otherwise</returns>
|
||||
private bool RequiredProgramsExist()
|
||||
{
|
||||
// Validate that the path is configured
|
||||
if (string.IsNullOrWhiteSpace(Options.DiscImageCreatorPath))
|
||||
return false;
|
||||
|
||||
// Validate that the required program exists
|
||||
if (!File.Exists(Options.DiscImageCreatorPath))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Run a standalone DiscImageCreator command
|
||||
/// </summary>
|
||||
/// <param name="command">Command string to run</param>
|
||||
/// <returns>The output of the command on success, null on error</returns>
|
||||
private async Task<string> RunStandaloneDiscImageCreatorCommand(string command)
|
||||
{
|
||||
// Validate that DiscImageCreator is all set
|
||||
if (!RequiredProgramsExist())
|
||||
return null;
|
||||
|
||||
// Validate we're not trying to eject a non-optical
|
||||
if (Drive.InternalDriveType != InternalDriveType.Optical)
|
||||
return null;
|
||||
|
||||
CancelDumping();
|
||||
|
||||
var parameters = new Modules.DiscImageCreator.Parameters(string.Empty)
|
||||
{
|
||||
BaseCommand = command,
|
||||
DriveLetter = Drive.Letter.ToString(),
|
||||
ExecutablePath = Options.DiscImageCreatorPath,
|
||||
};
|
||||
|
||||
return await ExecuteInternalProgram(parameters);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
2888
MPF.Library/InfoTool.cs
Normal file
2888
MPF.Library/InfoTool.cs
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user