Initial commit: Complete open-source Decal rebuild
All 5 phases of the open-source Decal rebuild: Phase 1: 14 decompiled .NET projects (Interop.*, Adapter, FileService, DecalUtil) Phase 2: 10 native DLLs rewritten as C# COM servers with matching GUIDs - DecalDat, DHS, SpellFilter, DecalInput, DecalNet, DecalFilters - Decal.Core, DecalControls, DecalRender, D3DService Phase 3: C++ shims for Inject.DLL (D3D9 hooking) and LauncherHook.DLL Phase 4: DenAgent WinForms tray application Phase 5: WiX installer and build script 25 C# projects building with 0 errors. Native C++ projects require VS 2022 + Windows SDK (x86). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
commit
d1442e3747
1382 changed files with 170725 additions and 0 deletions
164
Native/DecalDat/DatFile.cpp
Normal file
164
Native/DecalDat/DatFile.cpp
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
// ACFile.cpp
|
||||
// Implementation of class cACFile
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "DatFile.h"
|
||||
|
||||
#define AC_NUMFILELOC 0x03E
|
||||
#define AC_ROOTDIRPTRLOC 0x148
|
||||
|
||||
#define new DEBUG_NEW
|
||||
|
||||
cDatFile::cFile::cFile( cDatFile *pSource, BYTE *pFirstSector, DWORD dwSize )
|
||||
: m_pFirstSector( pFirstSector ),
|
||||
m_pCurrentSector( pFirstSector ),
|
||||
m_pCurrentByte( pFirstSector + sizeof( DWORD ) ),
|
||||
m_dwSize( dwSize ),
|
||||
m_dwOffset( 0 ),
|
||||
m_pSource( pSource )
|
||||
{
|
||||
}
|
||||
|
||||
void cDatFile::cFile::reset()
|
||||
{
|
||||
m_pCurrentSector = m_pFirstSector;
|
||||
m_pCurrentByte = m_pFirstSector + sizeof( DWORD );
|
||||
m_dwOffset = 0;
|
||||
}
|
||||
|
||||
DWORD cDatFile::cFile::read( BYTE *pbBuffer, DWORD dwSize )
|
||||
{
|
||||
// Check if we can fit
|
||||
if( dwSize + m_dwOffset > m_dwSize )
|
||||
dwSize = m_dwSize - m_dwOffset;
|
||||
|
||||
DWORD dwRemaining = dwSize;
|
||||
while( dwRemaining > 0 )
|
||||
{
|
||||
if( ( m_pCurrentByte + dwRemaining ) > m_pCurrentSector + m_pSource->m_dwSectorSize )
|
||||
{
|
||||
// We are reading over a sector boundary, read what we've got and reset for the next sector
|
||||
DWORD dwSection = ( m_pCurrentSector + m_pSource->m_dwSectorSize ) - m_pCurrentByte;
|
||||
|
||||
::memcpy( pbBuffer, m_pCurrentByte, dwSection );
|
||||
m_pCurrentSector = m_pSource->m_pData + *reinterpret_cast< DWORD * >( m_pCurrentSector );
|
||||
m_pCurrentByte = m_pCurrentSector + sizeof( DWORD );
|
||||
|
||||
dwRemaining -= dwSection;
|
||||
pbBuffer += dwSection;
|
||||
}
|
||||
else
|
||||
{
|
||||
::memcpy( pbBuffer, m_pCurrentByte, dwRemaining );
|
||||
m_pCurrentByte += dwRemaining;
|
||||
dwRemaining = 0;
|
||||
}
|
||||
}
|
||||
|
||||
m_dwOffset += dwSize;
|
||||
return dwSize;
|
||||
}
|
||||
|
||||
DWORD cDatFile::cFile::skip( DWORD dwSize )
|
||||
{
|
||||
// Check if we can fit
|
||||
if( dwSize + m_dwOffset > m_dwSize )
|
||||
dwSize = m_dwSize - m_dwOffset;
|
||||
|
||||
DWORD dwRemaining = dwSize;
|
||||
while( dwRemaining > 0 )
|
||||
{
|
||||
if( ( m_pCurrentByte + dwRemaining ) > m_pCurrentSector + m_pSource->m_dwSectorSize )
|
||||
{
|
||||
// We are reading over a sector boundary, read what we've got and reset for the next sector
|
||||
DWORD dwSection = ( m_pCurrentSector + m_pSource->m_dwSectorSize ) - m_pCurrentByte;
|
||||
|
||||
m_pCurrentSector = m_pSource->m_pData + *reinterpret_cast< DWORD * >( m_pCurrentSector );
|
||||
m_pCurrentByte = m_pCurrentSector + sizeof( DWORD );
|
||||
|
||||
dwRemaining -= dwSection;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pCurrentByte += dwRemaining;
|
||||
dwRemaining = 0;
|
||||
}
|
||||
}
|
||||
|
||||
m_dwOffset += dwSize;
|
||||
return dwSize;
|
||||
}
|
||||
|
||||
cDatFile::cDatFile( LPCTSTR szFilename, DWORD dwSectorSize )
|
||||
: m_hFile( NULL ),
|
||||
m_hMapping( NULL ),
|
||||
m_pData( NULL ),
|
||||
m_dwSectorSize( dwSectorSize )
|
||||
{
|
||||
m_hFile = ::CreateFile( szFilename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL );
|
||||
|
||||
if( m_hFile == INVALID_HANDLE_VALUE )
|
||||
throw std::exception();
|
||||
|
||||
// Proceed to create the file mapping
|
||||
m_hMapping = ::CreateFileMapping( m_hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL );
|
||||
if( m_hMapping == NULL )
|
||||
{
|
||||
::CloseHandle( m_hFile );
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
m_pData = reinterpret_cast< BYTE * >( ::MapViewOfFileEx( m_hMapping, FILE_MAP_READ, 0, 0, 0, NULL ) );
|
||||
|
||||
if( m_pData == NULL )
|
||||
{
|
||||
::CloseHandle( m_hMapping );
|
||||
::CloseHandle( m_hFile );
|
||||
throw std::exception();
|
||||
}
|
||||
}
|
||||
|
||||
cDatFile::~cDatFile()
|
||||
{
|
||||
::UnmapViewOfFile( m_pData );
|
||||
::CloseHandle( m_hMapping );
|
||||
::CloseHandle( m_hFile );
|
||||
}
|
||||
|
||||
cDatFile::cFile cDatFile::getFile( DWORD dwFileNumber )
|
||||
{
|
||||
cDirectory dir;
|
||||
|
||||
// Search for our golden file
|
||||
for ( DWORD dwDirStart = *reinterpret_cast< DWORD * >( m_pData + AC_ROOTDIRPTRLOC ); dwDirStart != 0; )
|
||||
{
|
||||
cFile dir_entry( this, m_pData + dwDirStart, sizeof( cDirectory ) );
|
||||
dir_entry.read( reinterpret_cast< BYTE * >( &dir ), sizeof( cDirectory ) );
|
||||
|
||||
// Now, the files are located like triplets, so copy the triplets
|
||||
cFileEntry *pEntry = dir.m_files,
|
||||
*pEndEntry = pEntry + dir.m_dwFiles;
|
||||
|
||||
for( cFileEntry *pIter = pEntry; pIter != pEndEntry && pIter->m_dwID < dwFileNumber; ++ pIter );
|
||||
|
||||
// We either got an exact match - or we attempt to further narrow down the file
|
||||
if( pIter != pEndEntry )
|
||||
{
|
||||
// We found some sort of match
|
||||
if( pIter->m_dwID == dwFileNumber )
|
||||
// This is an exact match hooray
|
||||
return cFile( this, m_pData + pIter->m_dwOffset, pIter->m_dwSize );
|
||||
}
|
||||
|
||||
// We have an inexact match, but now we attempt to recurse
|
||||
if( dir.m_subdirs[ 0 ] == 0 )
|
||||
// If the first entry in the directory is 0, there are no
|
||||
// helpers - we lose, it's not here
|
||||
break;
|
||||
|
||||
dwDirStart = dir.m_subdirs[ pIter - pEntry ];
|
||||
}
|
||||
|
||||
// If we get here, the file wasn't found - sniff
|
||||
throw std::exception();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue