Skip to content

Commit 1540d41

Browse files
committed
[Add] Support for Loading and Unpacking TR7 DRMs
1 parent daeaa96 commit 1540d41

12 files changed

+608
-82
lines changed

DRM/DRM.cpp

+140
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,146 @@
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+
120
#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>
228

329
void cDRM::LoadFromFile(char* szFilePath)
430
{
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;
5144

145+
delete this;
6146
}

DRM/DRM.h

+27
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,43 @@
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+
120
#ifndef DRM_H
221
#define DRM_H
322

423
//Includes
524

25+
//Definitions
26+
#define DRM_MAX_SECTIONS (16777215)
27+
628
//Classes
729
class cDRM
830
{
931
class Section;
1032

1133
public:
1234
void LoadFromFile(char* szFilePath);
35+
void ExtractSections();
36+
void Destroy();
1337

1438
private:
39+
char* szFilePath;
40+
1541
unsigned int uiVersion;
1642

1743
#if TR8
@@ -30,6 +56,7 @@ class cDRM::Section
3056
{
3157
enum Types;
3258

59+
public:
3360
unsigned int uiSize;
3461
unsigned char ucType;
3562
unsigned char ucUnk00;

DRM/DRM.rc

4.55 KB
Binary file not shown.

0 commit comments

Comments
 (0)