storageDwnld.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. #include "main.h"
  2. #include "./storageDwnld.h"
  3. #include "./ifc_omwebstorage.h"
  4. #include "./ifc_wasabihelper.h"
  5. #include "./ifc_omservicehost.h"
  6. #include "..\Components\wac_network\wac_network_http_receiver_api.h"
  7. OmStorageDwnld::OmStorageDwnld(api_downloadManager *downloadManager, BOOL enableCompression)
  8. : ref(1), userCallback(NULL), userData(NULL), completed(NULL), flags(0),
  9. opState(stateInitializing), resultCode(api_downloadManager::TICK_SUCCESS),
  10. cookie(NULL), manager(downloadManager), serviceHost(NULL)
  11. {
  12. if (NULL != manager)
  13. manager->AddRef();
  14. if (FALSE != enableCompression)
  15. flags |= flagEnableCompression;
  16. InitializeCriticalSection(&lock);
  17. }
  18. OmStorageDwnld::~OmStorageDwnld()
  19. {
  20. EnterCriticalSection(&lock);
  21. if (NULL != manager)
  22. {
  23. if (NULL != cookie)
  24. {
  25. manager->ReleaseDownload(cookie);
  26. cookie = NULL;
  27. }
  28. manager->Release();
  29. manager = NULL;
  30. }
  31. if (NULL != completed)
  32. {
  33. CloseHandle(completed);
  34. completed = NULL;
  35. }
  36. if (NULL != serviceHost)
  37. {
  38. serviceHost->Release();
  39. serviceHost = NULL;
  40. }
  41. LeaveCriticalSection(&lock);
  42. DeleteCriticalSection(&lock);
  43. }
  44. HRESULT OmStorageDwnld::CreateInstance(api_downloadManager *downloadManager, BOOL enableCompression, OmStorageDwnld **instance)
  45. {
  46. if (NULL == instance) return E_POINTER;
  47. *instance = NULL;
  48. if (NULL == downloadManager)
  49. return E_INVALIDARG;
  50. *instance = new OmStorageDwnld(downloadManager, enableCompression);
  51. if (NULL == *instance) return E_OUTOFMEMORY;
  52. return S_OK;
  53. }
  54. size_t OmStorageDwnld::AddRef()
  55. {
  56. return InterlockedIncrement((LONG*)&ref);
  57. }
  58. size_t OmStorageDwnld::Release()
  59. {
  60. if (0 == ref)
  61. return ref;
  62. LONG r = InterlockedDecrement((LONG*)&ref);
  63. if (0 == r)
  64. delete(this);
  65. return r;
  66. }
  67. int OmStorageDwnld::QueryInterface(GUID interface_guid, void **object)
  68. {
  69. if (NULL == object) return E_POINTER;
  70. if (IsEqualIID(interface_guid, IFC_OmStorageAsync))
  71. *object = static_cast<ifc_omstorageasync*>(this);
  72. else
  73. {
  74. *object = NULL;
  75. return E_NOINTERFACE;
  76. }
  77. if (NULL == *object)
  78. return E_UNEXPECTED;
  79. AddRef();
  80. return S_OK;
  81. }
  82. HRESULT OmStorageDwnld::GetState(UINT *state)
  83. {
  84. if (NULL == state)
  85. return E_POINTER;
  86. EnterCriticalSection(&lock);
  87. *state = opState;
  88. LeaveCriticalSection(&lock);
  89. return S_OK;
  90. }
  91. HRESULT OmStorageDwnld::GetWaitHandle(HANDLE *handle)
  92. {
  93. if (NULL == handle)
  94. return E_POINTER;
  95. HRESULT hr = S_OK;
  96. EnterCriticalSection(&lock);
  97. if (NULL == completed)
  98. {
  99. completed = CreateEvent(NULL, TRUE, FALSE, NULL);
  100. if (NULL == completed)
  101. {
  102. *handle = NULL;
  103. DWORD error = GetLastError();
  104. hr = HRESULT_FROM_WIN32(error);
  105. }
  106. }
  107. if (SUCCEEDED(hr) && FALSE == DuplicateHandle(GetCurrentProcess(), completed,
  108. GetCurrentProcess(), handle, 0, FALSE, DUPLICATE_SAME_ACCESS))
  109. {
  110. *handle = NULL;
  111. DWORD error = GetLastError();
  112. hr = HRESULT_FROM_WIN32(error);
  113. }
  114. LeaveCriticalSection(&lock);
  115. return hr;
  116. }
  117. HRESULT OmStorageDwnld::GetData(void **data)
  118. {
  119. if (NULL == data)
  120. return E_POINTER;
  121. EnterCriticalSection(&lock);
  122. *data = userData;
  123. LeaveCriticalSection(&lock);
  124. return S_OK;
  125. }
  126. HRESULT OmStorageDwnld::GetCallback(AsyncCallback *callback)
  127. {
  128. if (NULL == callback)
  129. return E_POINTER;
  130. EnterCriticalSection(&lock);
  131. *callback = userCallback;
  132. LeaveCriticalSection(&lock);
  133. return S_OK;
  134. }
  135. void OmStorageDwnld::OnInit(DownloadToken token)
  136. {
  137. EnterCriticalSection(&lock);
  138. AddRef();
  139. cookie = token;
  140. opState = stateConnecting;
  141. if (NULL != manager)
  142. {
  143. manager->RetainDownload(cookie);
  144. if (0 != (flagEnableCompression & flags))
  145. {
  146. api_httpreceiver *receiver = manager->GetReceiver(token);
  147. if (NULL != receiver)
  148. receiver->AllowCompression();
  149. }
  150. }
  151. LeaveCriticalSection(&lock);
  152. }
  153. void OmStorageDwnld::OnConnect(DownloadToken token)
  154. {
  155. EnterCriticalSection(&lock);
  156. opState = stateReceiving;
  157. LeaveCriticalSection(&lock);
  158. }
  159. void OmStorageDwnld::OnTick(DownloadToken token)
  160. {
  161. EnterCriticalSection(&lock);
  162. if (stateConnecting == opState)
  163. opState = stateReceiving;
  164. LeaveCriticalSection(&lock);
  165. }
  166. void OmStorageDwnld::OnFinish(DownloadToken token)
  167. {
  168. DownloadCompleted(api_downloadManager::TICK_SUCCESS);
  169. }
  170. void OmStorageDwnld::OnError(DownloadToken token, int errorCode)
  171. {
  172. DownloadCompleted(errorCode);
  173. }
  174. void OmStorageDwnld::OnCancel(DownloadToken token)
  175. {
  176. DownloadCompleted(api_downloadManager::TICK_NODATA);
  177. }
  178. void OmStorageDwnld::DownloadCompleted( INT errorCode )
  179. {
  180. EnterCriticalSection( &lock );
  181. resultCode = errorCode;
  182. opState = stateCompleted;
  183. HANDLE event = completed;
  184. LeaveCriticalSection( &lock );
  185. if ( NULL != event )
  186. {
  187. SetEvent( event );
  188. }
  189. EnterCriticalSection( &lock );
  190. AsyncCallback cb = userCallback;
  191. LeaveCriticalSection( &lock );
  192. if ( NULL != cb )
  193. {
  194. cb( this );
  195. }
  196. Release();
  197. }
  198. HRESULT OmStorageDwnld::SetData(void *data)
  199. {
  200. EnterCriticalSection(&lock);
  201. userData = data;
  202. LeaveCriticalSection(&lock);
  203. return S_OK;
  204. }
  205. HRESULT OmStorageDwnld::SetCallback(AsyncCallback callback)
  206. {
  207. EnterCriticalSection(&lock);
  208. userCallback = callback;
  209. LeaveCriticalSection(&lock);
  210. return S_OK;
  211. }
  212. HRESULT OmStorageDwnld::GetResultCode()
  213. {
  214. EnterCriticalSection(&lock);
  215. HRESULT hr;
  216. if (NULL == cookie || NULL == manager)
  217. {
  218. hr = E_UNEXPECTED;
  219. }
  220. else
  221. {
  222. switch(resultCode)
  223. {
  224. case api_downloadManager::TICK_SUCCESS: hr = E_DWNLD_OK; break;
  225. case api_downloadManager::TICK_FAILURE: hr = (0 != (flagUserAbort & flags)) ? E_DWNLD_ABORT : E_DWNLD_FAIL; break;
  226. case api_downloadManager::TICK_TIMEOUT: hr = E_DWNLD_TIMEOUT; break;
  227. case api_downloadManager::TICK_CANT_CONNECT: hr = E_DWNLD_CANT_CONNECT; break;
  228. case api_downloadManager::TICK_WRITE_ERROR: hr = E_DWNLD_WRITE_ERROR; break;
  229. default: hr = E_DWNLD_BUSY; break;
  230. }
  231. }
  232. LeaveCriticalSection(&lock);
  233. return hr;
  234. }
  235. HRESULT OmStorageDwnld::GetBuffer(void **buffer, size_t *bufferSize)
  236. {
  237. if (NULL == buffer) return E_POINTER;
  238. EnterCriticalSection(&lock);
  239. HRESULT hr = GetResultCode();
  240. if (SUCCEEDED(hr) && 0 != manager->GetBuffer(cookie, buffer, bufferSize))
  241. hr = E_DWNLD_FAIL;
  242. LeaveCriticalSection(&lock);
  243. if (FAILED(hr))
  244. {
  245. *buffer = NULL;
  246. *bufferSize = 0;
  247. }
  248. return hr;
  249. }
  250. HRESULT OmStorageDwnld::RequestAbort(BOOL fDrop)
  251. {
  252. EnterCriticalSection(&lock);
  253. if (FALSE != fDrop)
  254. {
  255. userData = NULL;
  256. userCallback = NULL;
  257. }
  258. if (NULL != cookie && NULL != manager)
  259. {
  260. opState = stateAborting;
  261. flags |= flagUserAbort;
  262. manager->CancelDownload(cookie);
  263. }
  264. LeaveCriticalSection(&lock);
  265. return S_OK;
  266. }
  267. HRESULT OmStorageDwnld::SetServiceHost(ifc_omservicehost *host)
  268. {
  269. EnterCriticalSection(&lock);
  270. if (NULL != serviceHost)
  271. serviceHost->Release();
  272. serviceHost = host;
  273. if (NULL != serviceHost)
  274. serviceHost->AddRef();
  275. LeaveCriticalSection(&lock);
  276. return S_OK;
  277. }
  278. HRESULT OmStorageDwnld::GetServiceHost(ifc_omservicehost **host)
  279. {
  280. if (NULL == host)
  281. return E_POINTER;
  282. EnterCriticalSection(&lock);
  283. *host = serviceHost;
  284. if (NULL != serviceHost)
  285. serviceHost->AddRef();
  286. LeaveCriticalSection(&lock);
  287. return S_OK;
  288. }
  289. #define CBCLASS OmStorageDwnld
  290. START_MULTIPATCH;
  291. START_PATCH(MPIID_OMSTORAGEASYNC)
  292. M_CB(MPIID_OMSTORAGEASYNC, ifc_omstorageasync, ADDREF, AddRef);
  293. M_CB(MPIID_OMSTORAGEASYNC, ifc_omstorageasync, RELEASE, Release);
  294. M_CB(MPIID_OMSTORAGEASYNC, ifc_omstorageasync, QUERYINTERFACE, QueryInterface);
  295. M_CB(MPIID_OMSTORAGEASYNC, ifc_omstorageasync, API_GETSTATE, GetState);
  296. M_CB(MPIID_OMSTORAGEASYNC, ifc_omstorageasync, API_GETWAITHANDLE, GetWaitHandle);
  297. M_CB(MPIID_OMSTORAGEASYNC, ifc_omstorageasync, API_GETDATA, GetData);
  298. NEXT_PATCH(MPIID_DOWNLOADCALLBACK)
  299. M_CB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, ADDREF, AddRef);
  300. M_CB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, RELEASE, Release);
  301. M_CB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, QUERYINTERFACE, QueryInterface);
  302. M_VCB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, IFC_DOWNLOADMANAGERCALLBACK_ONFINISH, OnFinish);
  303. M_VCB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, IFC_DOWNLOADMANAGERCALLBACK_ONTICK, OnTick);
  304. M_VCB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, IFC_DOWNLOADMANAGERCALLBACK_ONERROR, OnError);
  305. M_VCB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, IFC_DOWNLOADMANAGERCALLBACK_ONCANCEL, OnCancel);
  306. M_VCB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, IFC_DOWNLOADMANAGERCALLBACK_ONCONNECT, OnConnect);
  307. M_VCB(MPIID_DOWNLOADCALLBACK, ifc_downloadManagerCallback, IFC_DOWNLOADMANAGERCALLBACK_ONINIT, OnInit);
  308. END_PATCH
  309. END_MULTIPATCH;
  310. #undef CBCLASS