#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; } }