Skip to content
Permalink
Browse files

Fix ISO handling

* Return the expected output for listFiles

* Do not do the file size sanity check

* Properly return the contents of iso files

* Fix file list on multisector directories
  Was losing the first file of each sector after the first because the loop
  condition was skipping it after the continue.
  • Loading branch information...
TheCycoONE committed May 1, 2019
1 parent 46c58e3 commit 464ada256566ba9e3f72a5dd5967307cd037fe72
Showing with 47 additions and 21 deletions.
  1. +7 −0 CorsixTH/Lua/app.lua
  2. +14 −4 CorsixTH/Lua/filesystem.lua
  3. +25 −16 CorsixTH/Src/iso_fs.cpp
  4. +1 −1 CorsixTH/Src/iso_fs.h
@@ -1249,7 +1249,13 @@ function App:checkInstallFolder()
-- Do a few more checks to make sure that commonly corrupted files are OK.
local corrupt = {}

-- Check for file corruption for local files.
-- No check is done if the game is loaded from an ISO
local function check_corrupt(path, correct_size)
if self.fs.provider then
return true
end

local real_path = self.fs:getFilePath(path)
-- If the file exists but is smaller than usual it is probably corrupt
if real_path then
@@ -1318,6 +1324,7 @@ function App:readDataFile(dir, filename)
if filename == nil then
dir, filename = "Data", dir
end

local data = assert(self.fs:readContents(dir .. pathsep .. filename))
if data:sub(1, 3) == "RNC" then
data = assert(rnc.decompress(data))
@@ -99,8 +99,20 @@ function FileSystem:listFiles(virtual_path, ...)
return self.files
end

local function getFullPath(virtual_path, ...)
if ... then
virtual_path = table.concat({virtual_path, ...}, pathsep)
end
return virtual_path
end

function FileSystem:readContents(virtual_path, ...)
local file, err = self:getFilePath(virtual_path, ...)
virtual_path = getFullPath(virtual_path, ...)
if self.provider then
return self.provider:readContents(virtual_path)
end

local file, err = self:getFilePath(virtual_path)
if not file then
return file, err
end
@@ -114,9 +126,7 @@ function FileSystem:readContents(virtual_path, ...)
end

function FileSystem:getFilePath(virtual_path, ...)
if ... then
virtual_path = table.concat({virtual_path, ...}, pathsep)
end
virtual_path = getFullPath(virtual_path, ...)
if self.provider then
return self.provider:readContents(virtual_path)
elseif not self.sub_dirs then
@@ -285,15 +285,16 @@ void iso_filesystem::build_file_lookup_table(uint32_t iSector, int iDirEntsSize,
delete[] pBuffer;
return;
}

uint8_t *pDirEnt = pBuffer;
for(; iDirEntsSize > 0; iDirEntsSize -= *pDirEnt, pDirEnt += *pDirEnt)
for(;;)
{
// There is zero padding so that no record spans multiple sectors.
if(*pDirEnt == 0)
{
--iDirEntsSize, ++pDirEnt;
continue;
while (*pDirEnt == 0 && iDirEntsSize > 0) {
--iDirEntsSize;
++pDirEnt;
}
if (iDirEntsSize <= 0) { break; }

uint32_t iDataSector = read_native_int<uint32_t>(pDirEnt + file_sector_offset);
uint32_t iDataLength = read_native_int<uint32_t>(pDirEnt + file_data_length_offset);
@@ -333,6 +334,9 @@ void iso_filesystem::build_file_lookup_table(uint32_t iSector, int iDirEntsSize,
sPath = nullptr;
}
delete[] sPath;

iDirEntsSize -= *pDirEnt;
pDirEnt += *pDirEnt;
}
delete[] pBuffer;

@@ -359,26 +363,31 @@ iso_filesystem::file_metadata* iso_filesystem::allocate_file_record()
}

void iso_filesystem::visit_directory_files(const char* sPath,
void (*fnCallback)(void*, const char*),
void (*fnCallback)(void*, const char*, const char*),
void* pCallbackData) const
{
size_t iLen = std::strlen(sPath) + 1;
std::vector<char> sNormedPath(iLen);
for(size_t i = 0; i < iLen; ++i)
for (size_t i = 0; i < iLen; ++i)
sNormedPath[i] = normalise(sPath[i]);

// Inefficient (better would be to binary search for first and last files
// which begin with sPath), but who cares - this isn't called often
for(size_t i = 0; i < file_count; ++i)
for (size_t i = 0; i < file_count; ++i)
{
const char *sName = files[i].path;
if(std::strlen(sName) >= iLen && std::memcmp(sNormedPath.data(), sName, iLen - 1) == 0)
if (std::strlen(sName) >= iLen && std::memcmp(sNormedPath.data(), sName, iLen - 1) == 0)
{
sName += iLen - 1;
if(*sName == path_seperator)
if (*sName == path_seperator) {
++sName;
if(std::strchr(sName, path_seperator) == nullptr)
fnCallback(pCallbackData, sName);
}
if (std::strchr(sName, path_seperator) == nullptr) {
std::string file_path(sPath);
file_path.push_back(path_seperator);
file_path.append(sName);
fnCallback(pCallbackData, sName, file_path.c_str());
}
}
}
}
@@ -503,7 +512,7 @@ int l_isofs_set_path_separator(lua_State *L)
int l_isofs_set_root(lua_State *L)
{
iso_filesystem *pSelf = luaT_testuserdata<iso_filesystem>(L);
FILE *fIso = *luaT_testuserdata<FILE*>(L, 2);
FILE *fIso = *luaT_testuserdata<FILE*>(L, 2, false);
if(pSelf->initialise(fIso))
{
lua_pushvalue(L, 2);
@@ -541,11 +550,11 @@ int l_isofs_read_contents(lua_State *L)
return 1;
}

void l_isofs_list_files_callback(void *p, const char* s)
void l_isofs_list_files_callback(void *p, const char* name, const char* path)
{
lua_State *L = reinterpret_cast<lua_State*>(p);
lua_pushstring(L, s);
lua_pushboolean(L, 1);
lua_pushstring(L, name);
lua_pushstring(L, path);
lua_settable(L, 3);
}

@@ -75,7 +75,7 @@ class iso_filesystem
\param pCallbackData Opaque value to be called to fnCallback.
*/
void visit_directory_files(const char* sPath,
void (*fnCallback)(void*, const char*),
void (*fnCallback)(void*, const char*, const char*),
void* pCallbackData) const;

//! Test if a file handle from findFile() is good or is invalid

0 comments on commit 464ada2

Please sign in to comment.
You can’t perform that action at this time.