-
Notifications
You must be signed in to change notification settings - Fork 9
/
decode-gc.go
73 lines (61 loc) · 1.59 KB
/
decode-gc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package main
import (
"bytes"
"crypto/md5"
"fmt"
"io"
"os"
"reflect"
)
func decodeGameCube(r *os.File, outPath string) {
startSector := make([]byte, 0x2B8800)
_, err := io.ReadFull(r, startSector)
errorExit(err)
startBuffer := bytes.NewBuffer(startSector)
sig := startBuffer.Next(4)
id := startBuffer.Next(4)
hashValue := startBuffer.Next(16)
startBuffer.Next(6)
discNumber, err := startBuffer.ReadByte()
errorExit(err)
fmt.Println("GameCube Disc")
fmt.Printf("Signature: %s\n", string(sig))
fmt.Printf("ID: %s\n", string(id))
fmt.Printf("MD5: %x\n", hashValue)
w, err := os.Create(outPath)
errorExit(err)
defer w.Close()
bytesWritten := uint64(0)
padBlock := uint32(0)
padOffset := uint64(0)
padding := generatePaddingBlock(padBlock, id, uint32(discNumber))
transfer := make([]byte, 2048)
hash := md5.New()
fmt.Printf("Writing Disc Data.....")
for i := 0; i < 712880; i++ {
if padOffset == 0x40000 {
padBlock++
padding = generatePaddingBlock(padBlock, id, uint32(discNumber))
padOffset = 0
}
if setNextOffset(r, startBuffer) {
wrote := uint64(blockTransferWithHash(r, w, transfer, hash))
bytesWritten += wrote
padOffset += wrote
} else {
slice := padding[padOffset : padOffset+2048]
io.Copy(hash, bytes.NewBuffer(slice))
_, err = w.Write(slice)
errorExit(err)
bytesWritten += 2048
padOffset += 2048
}
}
fmt.Println("Done")
calcValue := hash.Sum(nil)
if reflect.DeepEqual(hashValue, calcValue) {
fmt.Printf("Decode OK: %x\n", hashValue)
} else {
fmt.Printf("Decode FAIL: expected: %x calculated: %x\n", hashValue, calcValue)
}
}