00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "StdAfx.h"
00024 #include "AsyncReader.h"
00025 #include <afxsock.h>
00026 #include <afxinet.h>
00027 #include "..\..\..\DSUtil\DSUtil.h"
00028
00029
00030
00031
00032
00033 CAsyncFileReader::CAsyncFileReader(CString fn, HRESULT& hr)
00034 : CUnknown(NAME("CAsyncFileReader"), NULL, &hr)
00035 , m_len(-1)
00036 , m_hBreakEvent(NULL)
00037 , m_lOsError(0)
00038 {
00039 hr = Open(fn, modeRead|shareDenyWrite|typeBinary|osSequentialScan) ? S_OK : E_FAIL;
00040 if(SUCCEEDED(hr)) m_len = GetLength();
00041 }
00042
00043 STDMETHODIMP CAsyncFileReader::NonDelegatingQueryInterface(REFIID riid, void** ppv)
00044 {
00045 CheckPointer(ppv, E_POINTER);
00046
00047 return
00048 QI(IAsyncReader)
00049 QI(ISyncReader)
00050 QI(IFileHandle)
00051 __super::NonDelegatingQueryInterface(riid, ppv);
00052 }
00053
00054
00055
00056 STDMETHODIMP CAsyncFileReader::SyncRead(LONGLONG llPosition, LONG lLength, BYTE* pBuffer)
00057 {
00058 do
00059 {
00060 try
00061 {
00062 if(llPosition+lLength > GetLength()) return E_FAIL;
00063 if(llPosition != Seek(llPosition, begin)) return E_FAIL;
00064 if((UINT)lLength < Read(pBuffer, lLength)) return E_FAIL;
00065
00066 #ifdef DEBUG
00067 static __int64 s_total = 0, s_laststoppos = 0;
00068 s_total += lLength;
00069 if(s_laststoppos > llPosition)
00070 TRACE(_T("[%I64d - %I64d] %d (%I64d)\n"), llPosition, llPosition + lLength, lLength, s_total);
00071 s_laststoppos = llPosition + lLength;
00072 #endif
00073
00074 return S_OK;
00075 }
00076 catch(CFileException* e)
00077 {
00078 m_lOsError = e->m_lOsError;
00079 e->Delete();
00080 Sleep(1);
00081 CString fn = m_strFileName;
00082 try {Close();} catch(CFileException* e) {e->Delete();}
00083 try {Open(fn, modeRead|shareDenyWrite|typeBinary|osSequentialScan);} catch(CFileException* e) {e->Delete();}
00084 m_strFileName = fn;
00085 }
00086 }
00087 while(m_hBreakEvent && WaitForSingleObject(m_hBreakEvent, 0) == WAIT_TIMEOUT);
00088
00089 return E_FAIL;
00090 }
00091
00092 STDMETHODIMP CAsyncFileReader::Length(LONGLONG* pTotal, LONGLONG* pAvailable)
00093 {
00094 LONGLONG len = m_len >= 0 ? m_len : GetLength();
00095 if(pTotal) *pTotal = len;
00096 if(pAvailable) *pAvailable = len;
00097 return S_OK;
00098 }
00099
00100
00101
00102 STDMETHODIMP_(HANDLE) CAsyncFileReader::GetFileHandle()
00103 {
00104 return m_hFile;
00105 }
00106
00107
00108
00109
00110
00111 CAsyncUrlReader::CAsyncUrlReader(CString url, HRESULT& hr)
00112 : CAsyncFileReader(url, hr)
00113 {
00114 if(SUCCEEDED(hr)) return;
00115
00116 m_url = url;
00117
00118 if(CAMThread::Create())
00119 CallWorker(CMD_INIT);
00120
00121 hr = Open(m_fn, modeRead|shareDenyRead|typeBinary|osSequentialScan) ? S_OK : E_FAIL;
00122 m_len = -1;
00123 }
00124
00125 CAsyncUrlReader::~CAsyncUrlReader()
00126 {
00127 if(ThreadExists())
00128 CallWorker(CMD_EXIT);
00129
00130 if(!m_fn.IsEmpty())
00131 {
00132 CFile::Close();
00133 DeleteFile(m_fn);
00134 }
00135 }
00136
00137
00138
00139 STDMETHODIMP CAsyncUrlReader::Length(LONGLONG* pTotal, LONGLONG* pAvailable)
00140 {
00141 if(pTotal) *pTotal = 0;
00142 return __super::Length(NULL, pAvailable);
00143 }
00144
00145
00146
00147 DWORD CAsyncUrlReader::ThreadProc()
00148 {
00149 AfxSocketInit(NULL);
00150
00151 DWORD cmd = GetRequest();
00152 if(cmd != CMD_INIT) {Reply(E_FAIL); return E_FAIL;}
00153
00154 try
00155 {
00156 CInternetSession is;
00157 CAutoPtr<CStdioFile> fin(is.OpenURL(m_url, 1, INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_EXISTING_CONNECT|INTERNET_FLAG_NO_CACHE_WRITE));
00158
00159 TCHAR path[MAX_PATH], fn[MAX_PATH];
00160 CFile fout;
00161 if(GetTempPath(MAX_PATH, path) && GetTempFileName(path, _T("mpc_http"), 0, fn)
00162 && fout.Open(fn, modeCreate|modeWrite|shareDenyWrite|typeBinary))
00163 {
00164 m_fn = fn;
00165
00166 char buff[1024];
00167 int len = fin->Read(buff, sizeof(buff));
00168 if(len > 0) fout.Write(buff, len);
00169
00170 Reply(S_OK);
00171
00172 while(!CheckRequest(&cmd))
00173 {
00174 int len = fin->Read(buff, sizeof(buff));
00175 if(len > 0) fout.Write(buff, len);
00176 }
00177 }
00178 else
00179 {
00180 Reply(E_FAIL);
00181 }
00182
00183 fin->Close();
00184 }
00185 catch(CInternetException* ie)
00186 {
00187 ie->Delete();
00188 Reply(E_FAIL);
00189 }
00190
00191
00192
00193 cmd = GetRequest();
00194 ASSERT(cmd == CMD_EXIT);
00195 Reply(S_OK);
00196
00197
00198
00199 m_hThread = NULL;
00200
00201 return S_OK;
00202 }