aboutsummaryrefslogtreecommitdiff
path: root/Src/omBrowser/storageDwnld.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/omBrowser/storageDwnld.cpp')
-rw-r--r--Src/omBrowser/storageDwnld.cpp395
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