#include "precomp.h"
#include "RFSHELL.h"
#include "IFilesystem.h"
#include "reiserfs.h"
class ReiserFS_FSWrapper : public IFilesystem
{
public:
ReiserFS_FSWrapper();
virtual ~ReiserFS_FSWrapper();
virtual void AddRef();
virtual void Release();
virtual HANDLE WINAPI OpenFile(LPCTSTR szFilename) const;
virtual void WINAPI ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD NumberOfBytesToRead, DWORD& NumberOfBytesRead) const;
virtual void WINAPI CloseFile(HANDLE hFile) const;
virtual HANDLE WINAPI FindFirstFile(LPCTSTR szPath) const;
virtual BOOL WINAPI FindNextFile(HANDLE hFind, UNIX_FILEINFO& FileInfo) const;
virtual void WINAPI CloseFind(HANDLE hFind) const;
virtual DWORD WINAPI GetVersion() const;
virtual BOOL WINAPI CopyFile(LPCTSTR szPath, ICreateFileInfo* lpContext ) const;
ReiserFsPartition m_Partition;
ULONG m_ulRefCount;
};
ReiserFS_FSWrapper::ReiserFS_FSWrapper()
{
m_ulRefCount = 1;
}
void ReiserFS_FSWrapper::AddRef()
{
m_ulRefCount++;
}
void ReiserFS_FSWrapper::Release()
{
if(m_ulRefCount)
{
m_ulRefCount--;
}
if(!m_ulRefCount)
{
delete this;
}
}
ReiserFS_FSWrapper::~ReiserFS_FSWrapper()
{
}
class RFSFileInfo : public ICreateFileInfo
{
public:
RFSFileInfo();
virtual ~RFSFileInfo();
virtual BOOL SetFileSize( INT64 Size );
virtual void Write( LPBYTE lpbData, DWORD dwSize );
DWORD m_dwSize;
DWORD m_dwUsed;
DWORD m_dwReadPos;
LPBYTE m_lpbMemory;
};
RFSFileInfo::RFSFileInfo()
{
m_dwSize = 0;
m_dwReadPos = 0;
m_dwUsed = 0;
m_lpbMemory = 0;
}
RFSFileInfo::~RFSFileInfo()
{
delete m_lpbMemory;
}
BOOL RFSFileInfo::SetFileSize( INT64 Size )
{
m_lpbMemory = 0;
if( (Size < 0) || (Size >= 0x7FFFFFFF) )
return FALSE;
m_dwSize = (DWORD) Size;
m_lpbMemory = new BYTE[m_dwSize];
return (m_lpbMemory != 0);
}
void RFSFileInfo::Write( LPBYTE lpbData, DWORD dwSize )
{
if( m_lpbMemory )
{
DWORD dwBytesToWrite = dwSize;
if( dwBytesToWrite + m_dwUsed > m_dwSize )
dwBytesToWrite = m_dwSize - m_dwUsed;
CopyMemory( m_lpbMemory + m_dwUsed, lpbData, dwBytesToWrite );
m_dwUsed += dwBytesToWrite;
}
}
HANDLE ReiserFS_FSWrapper::OpenFile(LPCTSTR szFilename) const
{
RFSFileInfo* fi = new RFSFileInfo;
ReiserFsPartition* p = (ReiserFsPartition*) &m_Partition;
if( p->GetFileEx(szFilename, fi) )
{
return (HANDLE) fi;
}
return INVALID_HANDLE_VALUE;
}
DWORD WINAPI ReiserFS_FSWrapper::GetVersion() const
{
return RFSHELL_API_VERSION;
}
BOOL WINAPI ReiserFS_FSWrapper::CopyFile(LPCTSTR szPath, ICreateFileInfo* cfi ) const
{
ReiserFsPartition* p = (ReiserFsPartition*) &m_Partition;
return p->GetFileEx(szPath, cfi);
}
void ReiserFS_FSWrapper::ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD NumberOfBytesToRead, DWORD& NumberOfBytesRead) const
{
RFSFileInfo* fi = (RFSFileInfo*) hFile;
NumberOfBytesRead = NumberOfBytesToRead;
if( fi->m_dwReadPos + NumberOfBytesRead > fi->m_dwSize )
NumberOfBytesRead = fi->m_dwSize - fi->m_dwReadPos;
if( NumberOfBytesRead )
{
CopyMemory( (LPBYTE) lpBuffer, fi->m_lpbMemory + fi->m_dwReadPos, NumberOfBytesRead );
fi->m_dwReadPos += NumberOfBytesRead;
}
}
void ReiserFS_FSWrapper::CloseFile(HANDLE hFile) const
{
RFSFileInfo* fi = (RFSFileInfo*) hFile;
delete fi;
}
HANDLE ReiserFS_FSWrapper::FindFirstFile(LPCTSTR szPath) const
{
PList* files = new PList;
if( !files )
return INVALID_HANDLE_VALUE;
// CONST SUCKS.
ReiserFsPartition* p = (ReiserFsPartition*) &m_Partition;
if( p->ListDir(files,szPath) )
{
return (HANDLE) files;
}
else
{
delete files;
return INVALID_HANDLE_VALUE;
}
}
BOOL ReiserFS_FSWrapper::FindNextFile(HANDLE hFind, UNIX_FILEINFO& FileInfo) const
{
PList* p = (PList*) hFind;
ReiserFsFileInfo* pFI = (ReiserFsFileInfo*) p->m_pHead;
if( pFI )
{
FileInfo.i_mode = pFI->m_stat.sd_mode;
FileInfo.i_uid = (__u16) pFI->m_stat.sd_uid;
FileInfo.i_gid = (__u16) pFI->m_stat.sd_gid;
FileInfo.i_size = (__u64) pFI->m_stat.sd_size;
FileInfo.i_atime = pFI->m_stat.sd_atime;
FileInfo.i_ctime = pFI->m_stat.sd_ctime;
FileInfo.i_mtime = pFI->m_stat.sd_mtime;
strncpy( FileInfo.szFileName, pFI->m_strName, UNIX_FILENAME_LENGTH );
p->Delete(pFI);
return TRUE;
}
else
{
return FALSE;
}
}
void ReiserFS_FSWrapper::CloseFind(HANDLE hFind) const
{
PList* p = (PList*) hFind;
delete p;
}
extern "C" {
void WINAPI FS_Autodetect( LPFNFoundPartition lpCallback, LPVOID lpContext )
{
ReiserFsPartition partition;
partition.Autodetect(60, lpCallback, lpContext);
}
IFilesystem* WINAPI FS_CreateInstance( LPCSTR lpszName )
{
// invalid name
if( strncmp( lpszName, "/dev/hd", 7 ) )
return 0;
lpszName += 7;
int iDrive = lpszName[0] - 'a';
int iPartition = strtol(lpszName+1,0,10);
ReiserFS_FSWrapper* instance = new ReiserFS_FSWrapper;
if( !instance )
return NULL;
if( !instance->m_Partition.Open(iDrive, iPartition) )
return NULL;
return instance;
}
}
syntax highlighted by Code2HTML, v. 0.9.1