// ramdisk.cpp: implementation of the CRamFolder class. // ////////////////////////////////////////////////////////////////////// #include "ramdisk.h" #include "folder.h" #include <kernel/ramdisk.h> #include <string.h> #include <stdlib.h> #define RAMDISK_ADDR 0xd0000000 class CRamFolder : public CFolder { public: CRamFolder(); virtual ~CRamFolder(); protected: virtual void ScanDir(); virtual IUnknown* DoOpen(folderitem_ext_t* buf); }; class CRamFile : public IUnknown, public IStream { public: CRamFile(void* data, ramfile_t* file); STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject); IMPLEMENT_IUNKNOWN(CFatFile); STDMETHOD_(size_t, Read) (void* pBuffer, size_t dwLength); STDMETHOD_(size_t, Write) (const void* pBuffer, size_t dwLength); STDMETHOD(SetIoMode)(dword mode); STDMETHOD(IsReady)(); STDMETHOD(Stat)(folderitem_t* buf); STDMETHOD(Seek)(THIS long offset, int origin); protected: byte* m_data; ramfile_t* m_file; dword m_pos; }; extern "C" IFolder* RamDisk_Create() { return new CRamFolder; } ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CRamFolder::CRamFolder() { } CRamFolder::~CRamFolder() { } void CRamFolder::ScanDir() { folderitem_ext_t* item; dword i; wchar_t temp[16]; ramdisk_t* header; ramfile_t* files; header = (ramdisk_t*) RAMDISK_ADDR; files = (ramfile_t*) (header + 1); for (i = 0; i < header->num_files; i++) { item = new folderitem_ext_t; memset(item, 0, sizeof(folderitem_ext_t)); item->size = sizeof(folderitem_t); mbstowcs(temp, files[i].name, countof(temp)); item->name = wcsdup(temp); item->length = files[i].length; item->attributes = ATTR_READ_ONLY; item->next = m_item_first; item->data = files + i; m_item_first = item; } } IUnknown* CRamFolder::DoOpen(folderitem_ext_t* buf) { IUnknown* file; file = CFolder::DoOpen(buf); if (file) return file; else if (buf->data) { ramfile_t* file = (ramfile_t*) buf->data; return new CRamFile((byte*) RAMDISK_ADDR + file->offset, file); } else return NULL; } CRamFile::CRamFile(void* data, ramfile_t* file) { m_file = file; m_pos = 0; m_data = (byte*) data; } HRESULT CRamFile::QueryInterface(REFIID iid, void ** ppvObject) { if (InlineIsEqualGUID(iid, IID_IUnknown) || InlineIsEqualGUID(iid, IID_IStream)) { AddRef(); *ppvObject = (IStream*) this; return S_OK; } else return E_FAIL; } size_t CRamFile::Read(void* pBuffer, size_t dwLength) { if (dwLength + m_pos > m_file->length) dwLength = m_file->length - m_pos; memcpy(pBuffer, m_data + m_pos, dwLength); m_pos += dwLength; return dwLength; } size_t CRamFile::Write(const void* pBuffer, size_t dwLength) { return 0; } HRESULT CRamFile::SetIoMode(dword mode) { return S_OK; } HRESULT CRamFile::IsReady() { return S_OK; } HRESULT CRamFile::Stat(folderitem_t* buf) { if (buf->name_max && buf->name) mbstowcs(buf->name, m_file->name, buf->name_max); buf->length = m_file->length; buf->attributes = ATTR_READ_ONLY; return S_OK; } HRESULT CRamFile::Seek(long offset, int origin) { switch (origin) { case seekSet: if (offset >= 0 && offset < (long) m_file->length) m_pos = offset; else return E_FAIL; break; case seekCur: if (m_pos + offset >= 0 && m_pos + offset < m_file->length) m_pos += offset; else return E_FAIL; break; case seekEnd: if (offset <= 0 && -offset < (long) m_file->length) m_pos = m_file->length + offset; else return E_FAIL; break; } return S_OK; }