AmigaFileStream.h
上传用户:hy_wanghao
上传日期:2007-01-08
资源大小:279k
文件大小:5k
源码类别:

Shell编程

开发平台:

Visual C++

  1. #if !defined(AFX_AMIGAFILESTREAM_H__20001229_27CD_6704_50F9_0080AD509054__INCLUDED_)
  2. #define AFX_AMIGAFILESTREAM_H__20001229_27CD_6704_50F9_0080AD509054__INCLUDED_
  3. #if _MSC_VER > 1000
  4. #pragma once
  5. #endif // _MSC_VER > 1000
  6. /////////////////////////////////////////////////////////////////////////////
  7. // CAmigaFileStream
  8. // This IStream implementation wraps a file from the Amiga device.
  9. // It is used to pass files onto the clipboard.
  10. // Only the basic methods need implementation because the Shell
  11. // doesn't use much of the IStream functionality.
  12. class CAmigaFileStream : 
  13.    public CComObjectRootEx<CComSingleThreadModel>, 
  14.    public IStream
  15. {
  16. public:
  17. BEGIN_COM_MAP(CAmigaFileStream)
  18.    COM_INTERFACE_ENTRY(IStream)
  19.    COM_INTERFACE_ENTRY(ISequentialStream)
  20. END_COM_MAP()
  21.    CAdfDevice m_dev;
  22.    CAdfVolume m_vol;
  23.    CAdfFile m_file;
  24.    HRESULT _Init(LPCITEMIDLIST pidlDevPath, LPCTSTR pstrPath, LPCTSTR pstrFileName)
  25.    {
  26.       ATLASSERT(pidlDevPath);
  27.       ATLASSERT(pstrPath);
  28.       ATLASSERT(pstrFileName);
  29.       HRESULT Hr;
  30.       CShellPidlPath sDevPath(pidlDevPath);
  31.       HR( ::OpenAmigaDevice(sDevPath, TRUE, NULL, m_dev, m_vol) );
  32.       if( m_vol.ChangeDirectory(pstrPath)==FALSE ) return E_FAIL;
  33.       if( m_vol.GetFile( pstrFileName, _T("r"), m_file )==FALSE ) return E_FAIL;
  34.       return S_OK;
  35.    }
  36.    STDMETHOD(Read)(LPVOID pv, ULONG cb, ULONG *pcbRead)
  37.    {
  38.       if( pcbRead!=NULL ) *pcbRead = 0;
  39.       if( !m_file.IsOpen() ) return E_FAIL;
  40.       if( m_file.Eof() ) return S_FALSE;
  41.       if( m_file.GetSize()==0 ) return S_FALSE;
  42.       ULONG act = m_file.Read(pv, cb);
  43.       if( pcbRead!=NULL ) *pcbRead = act;
  44.       return act>0 ? S_OK : S_FALSE;
  45.    }
  46.    STDMETHOD(Write)(LPCVOID /*pv*/, ULONG /*cb*/, ULONG *pcbWritten)
  47.    {
  48.       if( pcbWritten!=NULL ) *pcbWritten = 0;
  49.       ATLTRACENOTIMPL(_T("CAmigaFileStream::Write"));
  50.    }
  51.    STDMETHOD(Seek)(LARGE_INTEGER dlibMove,
  52.       DWORD dwOrigin,
  53.       ULARGE_INTEGER *plibNewPosition)
  54.    {
  55.       ATLTRACE(_T("CAmigaFileStream::Seekn"));
  56.       switch( dwOrigin ) {
  57.       case STREAM_SEEK_SET:
  58.          m_file.Seek(dlibMove.LowPart);
  59.          break;
  60.       case STREAM_SEEK_CUR:
  61.          m_file.Seek(m_file.GetPos()+dlibMove.LowPart);
  62.          break;
  63.       case STREAM_SEEK_END:
  64.          m_file.Seek(m_file.GetSize()-dlibMove.LowPart);
  65.          break;
  66.       }
  67.       if( plibNewPosition!=NULL ) plibNewPosition->QuadPart = m_file.GetPos();
  68.       return S_OK;
  69.    }
  70.    STDMETHOD(SetSize)(ULARGE_INTEGER /*libNewSize*/)
  71.    {
  72.       ATLTRACENOTIMPL(_T("CAmigaFileStream::SetSize"));
  73.    }
  74.    // Apparently the Shell calls this because it needs
  75.    // to marshal the IStream between two Explorer processes.
  76.    STDMETHOD(CopyTo)( 
  77.       IStream *pstm,
  78.       ULARGE_INTEGER cb,
  79.       ULARGE_INTEGER *pcbRead,
  80.       ULARGE_INTEGER *pcbWritten)
  81.    {
  82.       ATLTRACE(_T("CAmigaFileStream::CopyTon"));
  83.       ATLASSERT(pstm);
  84.       const int COPYBUFFERSIZE = 400;
  85.       HRESULT Hr;
  86.       ULARGE_INTEGER size = { 0 };
  87.       if( pcbRead!=NULL ) pcbRead->QuadPart = 0;
  88.       if( pcbWritten!=NULL ) pcbWritten->QuadPart = 0;
  89.       while( cb.QuadPart>0 ) {
  90.          BYTE buf[COPYBUFFERSIZE];
  91.          DWORD dwRead;
  92.          HR( Read(buf, COPYBUFFERSIZE, &dwRead) );
  93.          if( Hr==S_FALSE ) break; // No more to read! Stop!
  94.          DWORD dwWritten;
  95.          HR( pstm->Write(buf, dwRead, &dwWritten) );
  96.          ATLASSERT(dwRead==dwWritten); // BUG: Don't assume this
  97.          cb.QuadPart -= dwWritten;
  98.          size.QuadPart += dwWritten;
  99.       }
  100.       if( pcbRead!=NULL ) pcbRead->QuadPart = size.QuadPart;
  101.       if( pcbWritten!=NULL ) pcbWritten->QuadPart = size.QuadPart;
  102.       return S_OK;
  103.    }
  104.    STDMETHOD(Commit)(DWORD /*grfCommitFlags*/)
  105.    {
  106.       ATLTRACENOTIMPL(_T("CAmigaFileStream::Commit"));
  107.    }
  108.    STDMETHOD(Revert)(void)
  109.    {
  110.       ATLTRACENOTIMPL(_T("CAmigaFileStream::Revert"));
  111.    }
  112.    STDMETHOD(LockRegion)(
  113.       ULARGE_INTEGER /*libOffset*/,
  114.       ULARGE_INTEGER /*cb*/,
  115.       DWORD /*dwLockType*/)
  116.    {
  117.       ATLTRACENOTIMPL(_T("CAmigaFileStream::LockRegion"));
  118.    }
  119.    STDMETHOD(UnlockRegion)( 
  120.       ULARGE_INTEGER /*libOffset*/,
  121.       ULARGE_INTEGER /*cb*/,
  122.       DWORD /*dwLockType*/)
  123.    {
  124.       ATLTRACENOTIMPL(_T("CAmigaFileStream::UnlockRegion"));
  125.    }
  126.    STDMETHOD(Stat)(STATSTG* /*pstatstg*/, DWORD /*grfStatFlag*/)
  127.    {
  128.       ATLTRACENOTIMPL(_T("CAmigaFileStream::Stat"));
  129.    }
  130.    STDMETHOD(Clone)(IStream** /*ppstm*/)
  131.    {
  132.       ATLTRACENOTIMPL(_T("CAmigaFileStream::Clone"));
  133.    }
  134. };
  135. #endif // !defined(AFX_AMIGAFILESTREAM_H__20001229_27CD_6704_50F9_0080AD509054__INCLUDED_)