diff options
Diffstat (limited to 'Src/omBrowser/storageDwnld.cpp')
-rw-r--r-- | Src/omBrowser/storageDwnld.cpp | 395 |
1 files changed, 395 insertions, 0 deletions
diff --git a/Src/omBrowser/storageDwnld.cpp b/Src/omBrowser/storageDwnld.cpp new file mode 100644 index 00000000..6f501781 --- /dev/null +++ b/Src/omBrowser/storageDwnld.cpp @@ -0,0 +1,395 @@ +#include "main.h" +#include "./storageDwnld.h" +#include "./ifc_omwebstorage.h" +#include "./ifc_wasabihelper.h" +#include "./ifc_omservicehost.h" +#include "..\Components\wac_network\wac_network_http_receiver_api.h" + +OmStorageDwnld::OmStorageDwnld(api_downloadManager *downloadManager, BOOL enableCompression) + : ref(1), userCallback(NULL), userData(NULL), completed(NULL), flags(0), + opState(stateInitializing), resultCode(api_downloadManager::TICK_SUCCESS), + cookie(NULL), manager(downloadManager), serviceHost(NULL) +{ + if (NULL != manager) + manager->AddRef(); + + if (FALSE != enableCompression) + flags |= flagEnableCompression; + + InitializeCriticalSection(&lock); +} + +OmStorageDwnld::~OmStorageDwnld() +{ + EnterCriticalSection(&lock); + + if (NULL != manager) + { + if (NULL != cookie) + { + manager->ReleaseDownload(cookie); + cookie = NULL; + } + + manager->Release(); + manager = NULL; + } + + if (NULL != completed) + { + CloseHandle(completed); + completed = NULL; + } + + if (NULL != serviceHost) + { + serviceHost->Release(); + serviceHost = NULL; + } + + LeaveCriticalSection(&lock); + + DeleteCriticalSection(&lock); +} + +HRESULT OmStorageDwnld::CreateInstance(api_downloadManager *downloadManager, BOOL enableCompression, OmStorageDwnld **instance) +{ + if (NULL == instance) return E_POINTER; + + *instance = NULL; + if (NULL == downloadManager) + return E_INVALIDARG; + + *instance = new OmStorageDwnld(downloadManager, enableCompression); + if (NULL == *instance) return E_OUTOFMEMORY; + + return S_OK; +} + +size_t OmStorageDwnld::AddRef() +{ + return InterlockedIncrement((LONG*)&ref); +} + +size_t OmStorageDwnld::Release() +{ + if (0 == ref) + return ref; + + LONG r = InterlockedDecrement((LONG*)&ref); + if (0 == r) + delete(this); + + return r; +} + +int OmStorageDwnld::QueryInterface(GUID interface_guid, void **object) +{ + if (NULL == object) return E_POINTER; + + if (IsEqualIID(interface_guid, IFC_OmStorageAsync)) + *object = static_cast<ifc_omstorageasync*>(this); + else + { + *object = NULL; + return E_NOINTERFACE; + } + + if (NULL == *object) + return E_UNEXPECTED; + + AddRef(); + return S_OK; +} + +HRESULT OmStorageDwnld::GetState(UINT *state) +{ + if (NULL == state) + return E_POINTER; + + EnterCriticalSection(&lock); + *state = opState; + LeaveCriticalSection(&lock); + + return S_OK; +} + +HRESULT OmStorageDwnld::GetWaitHandle(HANDLE *handle) +{ + if (NULL == handle) + return E_POINTER; + + HRESULT hr = S_OK; + + EnterCriticalSection(&lock); + + if (NULL == completed) + { + completed = CreateEvent(NULL, TRUE, FALSE, NULL); + if (NULL == completed) + { + *handle = NULL; + DWORD error = GetLastError(); + hr = HRESULT_FROM_WIN32(error); + } + } + + if (SUCCEEDED(hr) && FALSE == DuplicateHandle(GetCurrentProcess(), completed, + GetCurrentProcess(), handle, 0, FALSE, DUPLICATE_SAME_ACCESS)) + { + *handle = NULL; + DWORD error = GetLastError(); + hr = HRESULT_FROM_WIN32(error); + } + + LeaveCriticalSection(&lock); + return hr; +} + +HRESULT OmStorageDwnld::GetData(void **data) +{ + if (NULL == data) + return E_POINTER; + + EnterCriticalSection(&lock); + *data = userData; + LeaveCriticalSection(&lock); + + return S_OK; +} + +HRESULT OmStorageDwnld::GetCallback(AsyncCallback *callback) +{ + if (NULL == callback) + return E_POINTER; + + EnterCriticalSection(&lock); + *callback = userCallback; + LeaveCriticalSection(&lock); + + return S_OK; +} + +void OmStorageDwnld::OnInit(DownloadToken token) +{ + EnterCriticalSection(&lock); + + AddRef(); + cookie = token; + opState = stateConnecting; + + if (NULL != manager) + { + manager->RetainDownload(cookie); + + if (0 != (flagEnableCompression & flags)) + { + api_httpreceiver *receiver = manager->GetReceiver(token); + if (NULL != receiver) + receiver->AllowCompression(); + } + } + + LeaveCriticalSection(&lock); +} + +void OmStorageDwnld::OnConnect(DownloadToken token) +{ + EnterCriticalSection(&lock); + opState = stateReceiving; + LeaveCriticalSection(&lock); +} + +void OmStorageDwnld::OnTick(DownloadToken token) +{ + EnterCriticalSection(&lock); + + if (stateConnecting == opState) + opState = stateReceiving; + + LeaveCriticalSection(&lock); +} + +void OmStorageDwnld::OnFinish(DownloadToken token) +{ + DownloadCompleted(api_downloadManager::TICK_SUCCESS); +} + +void OmStorageDwnld::OnError(DownloadToken token, int errorCode) +{ + DownloadCompleted(errorCode); +} + +void OmStorageDwnld::OnCancel(DownloadToken token) +{ + DownloadCompleted(api_downloadManager::TICK_NODATA); +} + +void OmStorageDwnld::DownloadCompleted( INT errorCode ) +{ + EnterCriticalSection( &lock ); + + resultCode = errorCode; + opState = stateCompleted; + HANDLE event = completed; + + LeaveCriticalSection( &lock ); + + if ( NULL != event ) + { + SetEvent( event ); + } + + EnterCriticalSection( &lock ); + AsyncCallback cb = userCallback; + LeaveCriticalSection( &lock ); + + if ( NULL != cb ) + { + cb( this ); + } + + Release(); +} + +HRESULT OmStorageDwnld::SetData(void *data) +{ + EnterCriticalSection(&lock); + userData = data; + LeaveCriticalSection(&lock); + + return S_OK; +} + +HRESULT OmStorageDwnld::SetCallback(AsyncCallback callback) +{ + EnterCriticalSection(&lock); + userCallback = callback; + LeaveCriticalSection(&lock); + + return S_OK; +} + +HRESULT OmStorageDwnld::GetResultCode() +{ + EnterCriticalSection(&lock); + + HRESULT hr; + if (NULL == cookie || NULL == manager) + { + hr = E_UNEXPECTED; + } + else + { + switch(resultCode) + { + case api_downloadManager::TICK_SUCCESS: hr = E_DWNLD_OK; break; + case api_downloadManager::TICK_FAILURE: hr = (0 != (flagUserAbort & flags)) ? E_DWNLD_ABORT : E_DWNLD_FAIL; break; + case api_downloadManager::TICK_TIMEOUT: hr = E_DWNLD_TIMEOUT; break; + case api_downloadManager::TICK_CANT_CONNECT: hr = E_DWNLD_CANT_CONNECT; break; + case api_downloadManager::TICK_WRITE_ERROR: hr = E_DWNLD_WRITE_ERROR; break; + default: hr = E_DWNLD_BUSY; break; + } + } + + LeaveCriticalSection(&lock); + + return hr; +} + +HRESULT OmStorageDwnld::GetBuffer(void **buffer, size_t *bufferSize) +{ + if (NULL == buffer) return E_POINTER; + + EnterCriticalSection(&lock); + + HRESULT hr = GetResultCode(); + if (SUCCEEDED(hr) && 0 != manager->GetBuffer(cookie, buffer, bufferSize)) + hr = E_DWNLD_FAIL; + + LeaveCriticalSection(&lock); + + if (FAILED(hr)) + { + *buffer = NULL; + *bufferSize = 0; + } + + return hr; +} + +HRESULT OmStorageDwnld::RequestAbort(BOOL fDrop) +{ + EnterCriticalSection(&lock); + if (FALSE != fDrop) + { + userData = NULL; + userCallback = NULL; + } + + if (NULL != cookie && NULL != manager) + { + opState = stateAborting; + flags |= flagUserAbort; + manager->CancelDownload(cookie); + } + + LeaveCriticalSection(&lock); + + return S_OK; +} + +HRESULT OmStorageDwnld::SetServiceHost(ifc_omservicehost *host) +{ + EnterCriticalSection(&lock); + + if (NULL != serviceHost) + serviceHost->Release(); + + serviceHost = host; + if (NULL != serviceHost) + serviceHost->AddRef(); + + LeaveCriticalSection(&lock); + + return S_OK; +} + +HRESULT OmStorageDwnld::GetServiceHost(ifc_omservicehost **host) +{ + if (NULL == host) + return E_POINTER; + + EnterCriticalSection(&lock); + + *host = serviceHost; + if (NULL != serviceHost) + serviceHost->AddRef(); + + LeaveCriticalSection(&lock); + + return S_OK; +} + +#define CBCLASS OmStorageDwnld +START_MULTIPATCH; + START_PATCH(MPIID_OMSTORAGEASYNC) + M_CB(MPIID_OMSTORAGEASYNC, ifc_omstorageasync, ADDREF, AddRef); + M_CB(MPIID_OMSTORAGEASYNC, ifc_omstorageasync, RELEASE, Release); + M_CB(MPIID_OMSTORAGEASYNC, ifc_omstorageasync, QUERYINTERFACE, QueryInterface); + M_CB(MPIID_OMSTORAGEASYNC, ifc_omstorageasync, API_GETSTATE, GetState); + M_CB(MPIID_OMSTORAGEASYNC, ifc_omstorageasync, API_GETWAITHANDLE, GetWaitHandle); + M_CB(MPIID_OMSTORAGEASYNC, ifc_omstorageasync, API_GETDATA, GetData); + NEXT_PATCH(MPIID_DOWNLOADCALLBACK) + M_CB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, ADDREF, AddRef); + M_CB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, RELEASE, Release); + M_CB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, QUERYINTERFACE, QueryInterface); + M_VCB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, IFC_DOWNLOADMANAGERCALLBACK_ONFINISH, OnFinish); + M_VCB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, IFC_DOWNLOADMANAGERCALLBACK_ONTICK, OnTick); + M_VCB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, IFC_DOWNLOADMANAGERCALLBACK_ONERROR, OnError); + M_VCB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, IFC_DOWNLOADMANAGERCALLBACK_ONCANCEL, OnCancel); + M_VCB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, IFC_DOWNLOADMANAGERCALLBACK_ONCONNECT, OnConnect); + M_VCB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, IFC_DOWNLOADMANAGERCALLBACK_ONINIT, OnInit); + END_PATCH +END_MULTIPATCH; +#undef CBCLASS
\ No newline at end of file |