pureikyubu/Docs/RE/dvdfs.txt
ogamespec 7dc8b1166f DVDConvertPathToEntrynum reversing
- Fixed MountSdk userOffset address (not to be erased by Arena clear)
2020-04-01 02:25:46 +03:00

208 lines
4.9 KiB
Text

typedef struct
{
union
{
struct {
u8 isDir; // 1, if directory
u8 nameOffsetHi;
u16 nameOffsetLo;
};
uint32 nameOffsetDirFlag;
};
union
{
struct // root entry
{
u32 reservedZero;
s32 entryNum;
};
struct // file
{
s32 fileOffset;
s32 fileLength;
};
struct // directory
{
s32 parentOffset; // previous
s32 nextOffset; // next
};
};
} DVDFileEntry;
struct DVDFileInfo
{
DVDCommandBlock cb;
u32 startAddr; // disk address of file
u32 length; // file size in bytes
DVDCallback callback;
};
struct DVDCommandBlock
{
DVDCommandBlock* next;
DVDCommandBlock* prev;
u32 command;
s32 state;
u32 offset;
u32 length;
void* addr;
u32 currTransferSize;
u32 transferredSize;
DVDDiskID* id;
DVDCBCallback callback;
void* userData;
};
OSBootInfo * BootInfo; // OS boot info
DVDFileEntry * FstStart; // begin of fs entries
s32 MaxEntryNum; // entries count
char * FstStringStart; // begin of file strings
s32 currentDirectory; // current directory entry
void __DVDFSInit(void)
{
BootInfo = (OSBootInfo *)OSPhysicalToCached(0);
FstStart = BootInfo->FSTLocation;
if(FstStart)
{
MaxEntryNum = FstStart[0].entryNum;
FstStringStart = (char *)(&FstStart[MaxEntryNum]);
}
}
BOOL DVDOpen(char* fileName, DVDFileInfo* fileInfo)
{
if(fileName == NULL)
OSHalt("DVDOpen(): null pointer is specified to file name\n");
if(fileInfo == NULL)
OSHalt("DVDOpen(): null pointer is specified to file info address\n");
s32 entrynum = DVDConvertPathToEntrynum(fileName);
if(entrynum < 0)
{
char currentDir[128];
DVDGetCurrentDir(currentDir, sizeof(currentDir));
OSReport( "Warning: DVDOpen(): file '%s' was not found under %s.\n",
fileName,
currentDir );
return FALSE;
}
DVDFileEntry * entry = &FstStart[entrynum];
if( entry->isDir )
{
OSReport( "DVDOpen(): directory '%s' is specified as a filename\n",
fileName );
return FALSE;
}
// save file information
fileInfo->startAddr = entry->fileOffset;
fileInfo->length = entry->fileLength;
// reset callback
fileInfo->callback = NULL;
fileInfo->cb.state = DVD_STATE_END;
return TRUE;
}
/// NOT COMPLETE !!!!!!!!!!!!!!!!!!!!!
s32 DVDConvertPathToEntrynum(char * pathPtr)
{
char * origPathPtr = pathPtr, *ptr;
r31 = ^^^^^^^^^^^ r22 = r3
if(pathPtr == NULL)
DBHalt("DVDConvertPathToEntrynum(): null pointer is specified\n");
// get current dirent (set in DVDChangeDir)
s32 dirLookAt = currentDirectory;
// path is empty - ""
if(pathPtr[0] == '\0') return 0;
// alg is pretty simple, just read if's (its almost like usual language)
while(pathPtr[0] != '\0')
{
// absolute path started "/"
if(pathPtr[0] == '/')
{
dirLookAt = 0;
pathPtr++;
continue;
}
// walk directory
// ../, ./, . (path "." mean root entry), .. (".." mean parent dirent)
if(pathPtr[0] == '.')
{
if(pathPtr[1] == '.')
{
if(pathPtr[2] == '/')
{
dirLookAt = FstStart[dirLookAt].parentOffset;
pathPtr += 3;
continue;
}
if(pathPtr[2] == '\0')
{
return FstStart[dirLookAt].parentOffset;
}
}
if(pathPtr[1] == '/')
{
pathPtr += 2;
continue;
}
if(pathPtr[1] == '\0')
{
return 0;
}
}
// check old 8.3 name convention, if flag disabled
if(__DVDLongFileNameFlag == FALSE)
{
r26 = 0
r27 = 0
ptr = pathPtr
if(ptr[0] != '\0')
{
if(ptr[0] == '/')
{
}
}
}
else
{
ptr = pathPtr;
// find end of directory name
while(ptr[0] != '/' && ptr[0]) ptr++;
}
}
}