1
0

utility.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. #include "main.h"
  2. #include "./utility.h"
  3. #include "./cacheManager.h"
  4. #include "./mlNavigationHelper.h"
  5. #include "./graphicsObject.h"
  6. #include "./storageHelper.h"
  7. #include "./wasabiHelper.h"
  8. #define LISTENER_CLASS L"Nullsoft_OmBrowserListener"
  9. #define LWM_FIRST (WM_USER + 11)
  10. #define LWM_INVOKECALLBACK (LWM_FIRST + 0)
  11. #define ICBP_TYPE_DISPPARAM2 0x0001
  12. struct INVOKECALLBACKPARAM
  13. {
  14. INVOKECALLBACKPARAM() : type(0), callback(NULL) {}
  15. UINT type;
  16. void *callback;
  17. };
  18. struct ICBP_DISPPARAM2
  19. {
  20. ICBP_DISPPARAM2() : object(NULL), param1(0), param2(0) {}
  21. INVOKECALLBACKPARAM header;
  22. Dispatchable *object;
  23. ULONG_PTR param1;
  24. ULONG_PTR param2;
  25. };
  26. static void CALLBACK InvokeCallback_MarshallingApc(ULONG_PTR data)
  27. {
  28. INVOKECALLBACKPARAM *icbp = (INVOKECALLBACKPARAM*)data;
  29. if (NULL == icbp) return;
  30. switch(icbp->type)
  31. {
  32. case ICBP_TYPE_DISPPARAM2:
  33. if (NULL != icbp->callback)
  34. {
  35. ICBP_DISPPARAM2 *p = (ICBP_DISPPARAM2*)icbp;
  36. ((ifc_omutility::ThreadCallback2)icbp->callback)(p->object, p->param1, p->param2);
  37. if (NULL != p->object) p->object->Release();
  38. }
  39. break;
  40. }
  41. free(icbp);
  42. }
  43. static LRESULT WINAPI Listener_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  44. {
  45. switch(uMsg)
  46. {
  47. case LWM_INVOKECALLBACK:
  48. if (NULL != lParam)
  49. ((ifc_omutility::ThreadCallback)lParam)((ULONG_PTR)wParam);
  50. return TRUE;
  51. }
  52. return DefWindowProc(hwnd, uMsg, wParam, lParam);
  53. }
  54. OmUtility::OmUtility()
  55. : ref(1), cacheManager(NULL), navigationHelper(NULL), graphicsObject(NULL),
  56. storageHelper(NULL), hListener(NULL)
  57. {
  58. WNDCLASS listenerClass = {0};
  59. if (0 == GetClassInfo(Plugin_GetInstance(), LISTENER_CLASS, &listenerClass))
  60. {
  61. ZeroMemory(&listenerClass, sizeof(listenerClass));
  62. listenerClass.hInstance = Plugin_GetInstance();
  63. listenerClass.lpfnWndProc = Listener_WindowProc;
  64. listenerClass.lpszClassName =LISTENER_CLASS;
  65. listenerClass.style = 0;
  66. RegisterClassW(&listenerClass);
  67. }
  68. hListener = CreateWindow(LISTENER_CLASS, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, Plugin_GetInstance(), NULL);
  69. }
  70. OmUtility::~OmUtility()
  71. {
  72. if (NULL != navigationHelper)
  73. navigationHelper->Release();
  74. if (NULL != cacheManager)
  75. cacheManager->Release();
  76. if (NULL != graphicsObject)
  77. graphicsObject->Release();
  78. if (NULL != hListener)
  79. DestroyWindow(hListener);
  80. if (NULL != storageHelper)
  81. storageHelper->Release();
  82. }
  83. OmUtility *OmUtility::CreateInstance()
  84. {
  85. return new OmUtility();
  86. }
  87. size_t OmUtility::AddRef()
  88. {
  89. return InterlockedIncrement((LONG*)&ref);
  90. }
  91. size_t OmUtility::Release()
  92. {
  93. if (0 == ref)
  94. return ref;
  95. LONG r = InterlockedDecrement((LONG*)&ref);
  96. if (0 == r)
  97. delete(this);
  98. return r;
  99. }
  100. int OmUtility::QueryInterface(GUID interface_guid, void **object)
  101. {
  102. if (NULL == object) return E_POINTER;
  103. if (IsEqualIID(interface_guid, IFC_OmUtility))
  104. *object = static_cast<ifc_omutility*>(this);
  105. else
  106. {
  107. *object = NULL;
  108. return E_NOINTERFACE;
  109. }
  110. if (NULL == *object)
  111. return E_UNEXPECTED;
  112. AddRef();
  113. return S_OK;
  114. }
  115. HRESULT OmUtility::EnsurePathExist(LPCWSTR pszDirectory)
  116. {
  117. return Plugin_EnsurePathExist(pszDirectory);
  118. }
  119. HRESULT OmUtility::MakeResourcePath(LPWSTR pszBuffer, UINT cchBufferMax, HINSTANCE hInstance, LPCWSTR pszType, LPCWSTR pszName, UINT uFlags)
  120. {
  121. return Plugin_MakeResourcePath(pszBuffer, cchBufferMax, hInstance, pszType, pszName, uFlags);
  122. }
  123. HRESULT OmUtility::GetCacheManager(ifc_omcachemanager **managerOut)
  124. {
  125. if (NULL == managerOut)
  126. return E_POINTER;
  127. if (NULL == cacheManager)
  128. {
  129. HRESULT hr = CacheManager::CreateInstance(&cacheManager);
  130. if (FAILED(hr))
  131. {
  132. *managerOut = NULL;
  133. return hr;
  134. }
  135. }
  136. cacheManager->AddRef();
  137. *managerOut = cacheManager;
  138. return S_OK;
  139. }
  140. HRESULT OmUtility::GetMlNavigationHelper(HWND hLibrary, ifc_mlnavigationhelper **helper)
  141. {
  142. if (NULL == helper)
  143. return E_POINTER;
  144. if (NULL == hLibrary)
  145. {
  146. *helper = NULL;
  147. return E_INVALIDARG;
  148. }
  149. if (NULL == navigationHelper)
  150. {
  151. HRESULT hr;
  152. ifc_omcachemanager *cache = NULL;
  153. if (FAILED(GetCacheManager(&cache)))
  154. {
  155. hr = E_FAIL;
  156. cache = NULL;
  157. }
  158. else
  159. {
  160. hr = MlNavigationHelper::CreateInstance(hLibrary, cache, &navigationHelper);
  161. }
  162. if (NULL != cache)
  163. cache->Release();
  164. if (FAILED(hr))
  165. {
  166. *helper = NULL;
  167. return hr;
  168. }
  169. }
  170. else
  171. {
  172. if (hLibrary != navigationHelper->GetLibrary())
  173. return E_UNEXPECTED;
  174. }
  175. navigationHelper->AddRef();
  176. *helper = navigationHelper;
  177. return S_OK;
  178. }
  179. HRESULT OmUtility::QueryImageLoader(HINSTANCE hInstance, LPCWSTR pszName, BOOL fPremultiply, ifc_omimageloader **imageLoader)
  180. {
  181. return Plugin_QueryImageLoader(hInstance, pszName, fPremultiply, imageLoader);
  182. }
  183. HRESULT OmUtility::GetGraphics(ifc_omgraphics **graphics)
  184. {
  185. if (NULL == graphics)
  186. return E_POINTER;
  187. if (NULL == graphicsObject)
  188. {
  189. HRESULT hr = GraphicsObject::CreateInstance(&graphicsObject);
  190. if (FAILED(hr)) return hr;
  191. }
  192. graphicsObject->AddRef();
  193. *graphics = graphicsObject;
  194. return S_OK;
  195. }
  196. HRESULT OmUtility::PostMainThreadCallback(ThreadCallback callback, ULONG_PTR data)
  197. {
  198. if (NULL == callback)
  199. return E_INVALIDARG;
  200. if (NULL != hListener &&
  201. FALSE != PostMessage(hListener, LWM_INVOKECALLBACK, (WPARAM)data, (LPARAM)callback))
  202. {
  203. return S_OK;
  204. }
  205. ifc_wasabihelper *wasabi = NULL;
  206. HRESULT hr = Plugin_GetWasabiHelper(&wasabi);
  207. if (SUCCEEDED(hr) && wasabi != NULL)
  208. {
  209. api_application *application = NULL;
  210. hr = wasabi->GetApplicationApi(&application);
  211. if (SUCCEEDED(hr) && application != NULL)
  212. {
  213. HANDLE hThread = application->main_getMainThreadHandle();
  214. if (NULL == hThread)
  215. hr = E_FAIL;
  216. else
  217. {
  218. DWORD r = QueueUserAPC((PAPCFUNC)callback, hThread, data);
  219. if (0 == r)
  220. {
  221. r = GetLastError();
  222. hr = HRESULT_FROM_WIN32(r);
  223. }
  224. }
  225. application->Release();
  226. }
  227. wasabi->Release();
  228. }
  229. return hr;
  230. }
  231. HRESULT OmUtility::PostMainThreadCallback2(ThreadCallback2 callback, Dispatchable *object, ULONG_PTR param1, ULONG_PTR param2)
  232. {
  233. if (NULL == callback || NULL == object)
  234. return E_INVALIDARG;
  235. ICBP_DISPPARAM2 *data = (ICBP_DISPPARAM2*)calloc(1, sizeof(ICBP_DISPPARAM2));
  236. if (NULL == data) return E_OUTOFMEMORY;
  237. data->header.type = ICBP_TYPE_DISPPARAM2;
  238. data->header.callback = callback;
  239. data->object = object;
  240. if (NULL != data->object)
  241. data->object->AddRef();
  242. data->param1 = param1;
  243. data->param2 = param2;
  244. HRESULT hr = PostMainThreadCallback(InvokeCallback_MarshallingApc, (ULONG_PTR)data);
  245. if (FAILED(hr))
  246. {
  247. if (NULL != data->object)
  248. data->object->Release();
  249. free(data);
  250. }
  251. return hr;
  252. }
  253. HRESULT OmUtility::GetStorageHelper(ifc_omstoragehelper **helper)
  254. {
  255. if (NULL == helper)
  256. return E_POINTER;
  257. if (NULL == storageHelper)
  258. {
  259. HRESULT hr = StorageHelper::CreateInstance(&storageHelper);
  260. if (FAILED(hr))
  261. {
  262. *helper = NULL;
  263. return hr;
  264. }
  265. }
  266. *helper = storageHelper;
  267. storageHelper->AddRef();
  268. return S_OK;
  269. }
  270. #define CBCLASS OmUtility
  271. START_DISPATCH;
  272. CB(ADDREF, AddRef)
  273. CB(RELEASE, Release)
  274. CB(QUERYINTERFACE, QueryInterface)
  275. CB(API_ENSUREPATHEXIST, EnsurePathExist)
  276. CB(API_MAKERESPATH, MakeResourcePath)
  277. CB(API_GETCACHEMANAGER, GetCacheManager)
  278. CB(API_GETMLNAVIGATIONHELPER, GetMlNavigationHelper)
  279. CB(API_QUERYIMAGELOADER, QueryImageLoader)
  280. CB(API_GETGRAPHICS, GetGraphics)
  281. CB(API_POSTMAINTHREADCALLBACK, PostMainThreadCallback)
  282. CB(API_POSTMAINTHREADCALLBACK2, PostMainThreadCallback2)
  283. CB(API_GETSTORAGEHELPER, GetStorageHelper)
  284. END_DISPATCH;
  285. #undef CBCLASS