1
+ /*
2
+ [DRM/CDRM] Tomb Raider: Legend/Anniversary/Underworld DRM/CDRM Unpacker
3
+ Copyright (C) Gh0stBlade 2015 - gh0stblade@live[dot]co.uk
4
+
5
+ This program is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU General Public License
7
+ as published by the Free Software Foundation; either version 2
8
+ of the License, or (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program; if not, write to the Free Software
17
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
+ */
19
+
1
20
#include " DRM.h"
21
+ #include " File.h"
22
+ #include " FileExtensions.h"
23
+
24
+ #include < stdio.h>
25
+ #include < iostream>
26
+ #include < fstream>
27
+ #include < sstream>
2
28
3
29
void cDRM::LoadFromFile (char * szFilePath)
4
30
{
31
+ // Store DRM input path
32
+ this ->szFilePath = szFilePath;
33
+
34
+ // Initialise ifstream for reading in binary mode
35
+ std::ifstream ifs (this ->szFilePath , std::ios::binary);
36
+
37
+ // Read our DRM header into cDRM
38
+ this ->uiVersion = ReadUInt (ifs);
39
+ this ->uiNumSections = ReadUInt (ifs);
40
+
41
+ // If we're exceeding the max amount of sections error
42
+ if (this ->uiNumSections > DRM_MAX_SECTIONS)
43
+ {
44
+ std::cout << " Fatal Error: Number of Sections: " << this ->uiNumSections << " exceeded the limit of: " << DRM_MAX_SECTIONS << " !" << std::endl;
45
+ return ;
46
+ }
47
+
48
+ // If not enough sections
49
+ if (this ->uiNumSections <= 0 )
50
+ {
51
+ std::cout << " Fatal Error: Number of Sections <= 0 !" << std::endl;
52
+ return ;
53
+ }
54
+
55
+ // Allocate our sections
56
+ this ->pSections = new Section[this ->uiNumSections ];
57
+
58
+ // Read all the section info into mDRM
59
+ for (int i = 0 ; i != this ->uiNumSections ; i++)
60
+ {
61
+ this ->pSections [i].uiSize = ReadUInt (ifs);
62
+ this ->pSections [i].ucType = ReadUByte (ifs);
63
+ this ->pSections [i].ucUnk00 = ReadUByte (ifs);
64
+ this ->pSections [i].usUnk01 = ReadUShort (ifs);
65
+ this ->pSections [i].uiHeaderSize = ReadUInt (ifs);
66
+ this ->pSections [i].uiHash = ReadUInt (ifs);
67
+ this ->pSections [i].uiLang = ReadUInt (ifs);
68
+ }
69
+
70
+ // Close ifstream
71
+ ifs.close ();
72
+ }
73
+
74
+ void cDRM::ExtractSections ()
75
+ {
76
+ // Initialise ifstream for reading in binary mode
77
+ std::ifstream ifs (this ->szFilePath , std::ios::binary);
78
+
79
+ std::string strOutPath = std::string (this ->szFilePath );
80
+ strOutPath = strOutPath.substr (0 , strOutPath.find_last_of (" ." )) + " \\ " ;
81
+
82
+ for (int i = 0 ; i != this ->uiNumSections ; i++)
83
+ {
84
+ std::cout << " Extracting Section: " << " [ " << (i + 1 ) << " / " << this ->uiNumSections << " ]" << std::endl;
85
+
86
+ // Create Directory
87
+ CreateDirectories (strOutPath);
88
+
89
+ // Define output file path
90
+ std::stringstream strOutPath2;
91
+ strOutPath2 << strOutPath << std::hex << i << szExtensions[this ->pSections [i].ucType ];
92
+
93
+ // Skip header
94
+ bool bRealSize = false ;
95
+ if (bRealSize)
96
+ {
97
+ // Declare variables to store data
98
+ char * szSectionData = new char [this ->pSections [i].uiSize ];
99
+
100
+ // Declare output file stream
101
+ std::ofstream ofs (strOutPath2.str (), std::ios::binary);
102
+
103
+ // Skip header info
104
+ ifs.seekg (((this ->pSections [i].uiHeaderSize >> 0x8 ) * 0x8 ), SEEK_CUR);
105
+
106
+ // Read then write the section data
107
+ ifs.read (szSectionData, this ->pSections [i].uiSize );
108
+ ofs.write (szSectionData, this ->pSections [i].uiSize );
109
+
110
+ ofs.flush ();
111
+ ofs.close ();
112
+
113
+ // Clear memory
114
+ delete[] szSectionData;
115
+ }
116
+ else
117
+ {
118
+ // Declare variables to store data
119
+ char * szSectionData = new char [this ->pSections [i].uiSize + ((this ->pSections [i].uiHeaderSize >> 0x8 ) * 0x8 )];
120
+
121
+ // Declare output file stream
122
+ std::ofstream ofs (strOutPath2.str (), std::ios::binary);
123
+
124
+ // Read then write the section data
125
+ ifs.read (szSectionData, this ->pSections [i].uiSize + ((this ->pSections [i].uiHeaderSize >> 0x8 ) * 0x8 ));
126
+ ofs.write (szSectionData, this ->pSections [i].uiSize + ((this ->pSections [i].uiHeaderSize >> 0x8 ) * 0x8 ));
127
+
128
+ ofs.flush ();
129
+ ofs.close ();
130
+
131
+ // Clear memory
132
+ delete[] szSectionData;
133
+ }
134
+ }
135
+
136
+ // Print success
137
+ std::cout << " Successfully Extracted: " << " [ " << (this ->uiNumSections ) << " ] " << " section(s)!" << std::endl;
138
+ }
139
+
140
+ void cDRM::Destroy ()
141
+ {
142
+ if (this ->pSections != NULL )
143
+ delete[] this ->pSections ;
5
144
145
+ delete this ;
6
146
}
0 commit comments