main.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. #include "./main.h"
  2. #include "./component.h"
  3. #include "../nu/htmlcontainer2.h"
  4. #include "./ifc_wasabihelper.h"
  5. #include "./ifc_skinhelper.h"
  6. #include "./ifc_skinnedbrowser.h"
  7. #include "./pngLoader.h"
  8. #include "./ifc_omservicehost.h"
  9. #include <shlwapi.h>
  10. #include <strsafe.h>
  11. static HINSTANCE pluginInstance = NULL;
  12. static OmBrowserComponent component;
  13. LPWSTR Plugin_MallocString(size_t cchLen)
  14. {
  15. return (LPWSTR)calloc(cchLen, sizeof(WCHAR));
  16. }
  17. void Plugin_FreeString(LPWSTR pszString)
  18. {
  19. if (NULL != pszString)
  20. {
  21. free(pszString);
  22. }
  23. }
  24. LPWSTR Plugin_ReAllocString(LPWSTR pszString, size_t cchLen)
  25. {
  26. return (LPWSTR)realloc(pszString, sizeof(WCHAR) * cchLen);
  27. }
  28. LPWSTR Plugin_CopyString(LPCWSTR pszSource)
  29. {
  30. if (NULL == pszSource)
  31. return NULL;
  32. INT cchSource = lstrlenW(pszSource) + 1;
  33. LPWSTR copy = Plugin_MallocString(cchSource);
  34. if (NULL != copy)
  35. {
  36. CopyMemory(copy, pszSource, sizeof(WCHAR) * cchSource);
  37. }
  38. return copy;
  39. }
  40. LPSTR Plugin_MallocAnsiString(size_t cchLen)
  41. {
  42. return (LPSTR)calloc(cchLen, sizeof(CHAR));
  43. }
  44. LPSTR Plugin_CopyAnsiString(LPCSTR pszSource)
  45. {
  46. if (NULL == pszSource)
  47. return NULL;
  48. INT cchSource = lstrlenA(pszSource) + 1;
  49. LPSTR copy = Plugin_MallocAnsiString(cchSource);
  50. if (NULL != copy)
  51. {
  52. CopyMemory(copy, pszSource, sizeof(CHAR) * cchSource);
  53. }
  54. return copy;
  55. }
  56. void Plugin_FreeAnsiString(LPSTR pszString)
  57. {
  58. Plugin_FreeString((LPWSTR)pszString);
  59. }
  60. LPWSTR Plugin_DuplicateResString(LPCWSTR pszResource)
  61. {
  62. return (IS_INTRESOURCE(pszResource)) ?
  63. (LPWSTR)pszResource :
  64. Plugin_CopyString(pszResource);
  65. }
  66. void Plugin_FreeResString(LPWSTR pszResource)
  67. {
  68. if (!IS_INTRESOURCE(pszResource))
  69. Plugin_FreeString(pszResource);
  70. }
  71. HRESULT Plugin_CopyResString(LPWSTR pszBuffer, INT cchBufferMax, LPCWSTR pszString)
  72. {
  73. if (NULL == pszBuffer)
  74. return E_INVALIDARG;
  75. HRESULT hr = S_OK;
  76. if (NULL == pszString)
  77. {
  78. pszBuffer[0] = L'\0';
  79. }
  80. else if (IS_INTRESOURCE(pszString))
  81. {
  82. Plugin_LoadString((INT)(INT_PTR)pszString, pszBuffer, cchBufferMax);
  83. }
  84. else
  85. {
  86. hr = StringCchCopy(pszBuffer, cchBufferMax, pszString);
  87. }
  88. return hr;
  89. }
  90. LPSTR Plugin_WideCharToMultiByte(UINT codePage, DWORD dwFlags, LPCWSTR lpWideCharStr, INT cchWideChar, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar)
  91. {
  92. INT cchBuffer = WideCharToMultiByte(codePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar);
  93. if (0 == cchBuffer) return NULL;
  94. LPSTR buffer = Plugin_MallocAnsiString(cchBuffer);
  95. if (NULL == buffer) return NULL;
  96. if (0 == WideCharToMultiByte(codePage, dwFlags, lpWideCharStr, cchWideChar, buffer, cchBuffer, lpDefaultChar, lpUsedDefaultChar))
  97. {
  98. Plugin_FreeAnsiString(buffer);
  99. return NULL;
  100. }
  101. return buffer;
  102. }
  103. LPWSTR Plugin_MultiByteToWideChar(UINT codePage, DWORD dwFlags, LPCSTR lpMultiByteStr, INT cbMultiByte)
  104. {
  105. if (NULL == lpMultiByteStr) return NULL;
  106. INT cchBuffer = MultiByteToWideChar(codePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0);
  107. if (NULL == cchBuffer) return NULL;
  108. if (cbMultiByte > 0) cchBuffer++;
  109. LPWSTR buffer = Plugin_MallocString(cchBuffer);
  110. if (NULL == buffer) return NULL;
  111. if (0 == MultiByteToWideChar(codePage, dwFlags, lpMultiByteStr, cbMultiByte, buffer, cchBuffer))
  112. {
  113. Plugin_FreeString(buffer);
  114. return NULL;
  115. }
  116. if (cbMultiByte > 0)
  117. {
  118. buffer[cchBuffer - 1] = L'\0';
  119. }
  120. return buffer;
  121. }
  122. HRESULT Plugin_Initialize(HWND hwndWinamp)
  123. {
  124. return component.InitializeComponent(hwndWinamp);
  125. }
  126. HRESULT Plugin_GetWasabiHelper(ifc_wasabihelper **wasabiHelper)
  127. {
  128. return component.GetWasabiHelper(wasabiHelper);
  129. }
  130. HRESULT Plugin_GetSkinHelper(ifc_skinhelper **skinHelper)
  131. {
  132. return component.GetSkinHelper(skinHelper);
  133. }
  134. HRESULT Plugin_GetBrowserSkin(ifc_skinnedbrowser **skinnedBrowser)
  135. {
  136. ifc_skinhelper *skin = NULL;
  137. HRESULT hr = Plugin_GetSkinHelper(&skin);
  138. if (FAILED(hr) || skin == NULL) return hr;
  139. hr = skin->QueryInterface(IFC_SkinnedBrowser, (void**)skinnedBrowser);
  140. skin->Release();
  141. return hr;
  142. }
  143. HRESULT Plugin_GetWinampWnd(HWND *hwndWinamp)
  144. {
  145. return component.GetWinampWnd(hwndWinamp);
  146. }
  147. HRESULT Plugin_RegisterWinampHook(ifc_winamphook *hook, UINT *cookieOut)
  148. {
  149. return component.RegisterWinampHook(hook, cookieOut);
  150. }
  151. HRESULT Plugin_UnregisterWinampHook(UINT cookie)
  152. {
  153. return component.UnregisterWinampHook(cookie);
  154. }
  155. HINSTANCE Plugin_GetInstance()
  156. {
  157. return pluginInstance;
  158. }
  159. HINSTANCE Plugin_GetLangInstance()
  160. {
  161. ifc_wasabihelper *wasabi = NULL;
  162. if (FAILED(component.GetWasabiHelper(&wasabi)) || wasabi == NULL) return NULL;
  163. HINSTANCE langModule = NULL;
  164. if (FAILED(wasabi->GetLanguageModule(&langModule)))
  165. langModule = NULL;
  166. wasabi->Release();
  167. return langModule;
  168. }
  169. HRESULT Plugin_FormatUuidString(UUID &uid, LPWSTR pszBuffer, size_t cchBufferMax)
  170. {
  171. if (NULL == pszBuffer || cchBufferMax < 1)
  172. return E_INVALIDARG;
  173. pszBuffer[0] = L'\0';
  174. RPC_WSTR pszUid;
  175. if (RPC_S_OK != UuidToString(&uid, &pszUid))
  176. {
  177. DWORD errorCode = GetLastError();
  178. return HRESULT_FROM_WIN32(errorCode);
  179. }
  180. UINT cchLen = lstrlen((LPCWSTR)pszUid);
  181. UINT s = 0, d = 0;
  182. for (; s < cchLen && d < cchBufferMax; s++)
  183. {
  184. if (pszUid[s] >= L'a' && pszUid[s] <= L'f')
  185. {
  186. pszBuffer[d++] = (0xDF & pszUid[s]);
  187. }
  188. else if (pszUid[s] >= L'0' && pszUid[s] <= L'9')
  189. {
  190. pszBuffer[d++] = pszUid[s];
  191. }
  192. }
  193. if (d > cchBufferMax)
  194. d = 0;
  195. pszBuffer[d] = L'\0';
  196. RpcStringFree(&pszUid);
  197. return (L'\0' != pszBuffer[0]) ? S_OK : E_FAIL;
  198. }
  199. static HINSTANCE Plugin_GetLangHelper(api_language **langManager)
  200. {
  201. ifc_wasabihelper *wasabi = NULL;
  202. if (FAILED(component.GetWasabiHelper(&wasabi)) || wasabi == NULL)
  203. {
  204. *langManager = NULL;
  205. return NULL;
  206. }
  207. if (FAILED(wasabi->GetLanguageManager(langManager)))
  208. *langManager = NULL;
  209. HINSTANCE langModule = NULL;
  210. if (FAILED(wasabi->GetLanguageModule(&langModule)))
  211. langModule = NULL;
  212. wasabi->Release();
  213. return langModule;
  214. }
  215. const wchar_t* Plugin_LoadString(UINT id, wchar_t *buffer, int bufferMax)
  216. {
  217. const wchar_t* r = 0;
  218. api_language *lang = NULL;
  219. HINSTANCE langModule = Plugin_GetLangHelper(&lang);
  220. if (NULL != lang)
  221. {
  222. r = lang->GetStringW(langModule, Plugin_GetInstance(), id, buffer, bufferMax);
  223. lang->Release();
  224. }
  225. return r;
  226. }
  227. const char* Plugin_LoadStringAnsi(UINT id, char *buffer, int bufferMax)
  228. {
  229. const char* r = 0;
  230. api_language *lang = NULL;
  231. HINSTANCE langModule = Plugin_GetLangHelper(&lang);
  232. if (NULL != lang)
  233. {
  234. r = lang->GetString(langModule, Plugin_GetInstance(), id, buffer, bufferMax);
  235. lang->Release();
  236. }
  237. return r;
  238. }
  239. HWND Plugin_CreateDialogParam(const wchar_t *templateName, HWND parent, DLGPROC proc, LPARAM param)
  240. {
  241. HWND r = 0;
  242. api_language *lang = NULL;
  243. HINSTANCE langModule = Plugin_GetLangHelper(&lang);
  244. if (NULL != lang)
  245. {
  246. r = lang->CreateLDialogParamW(langModule, Plugin_GetInstance(), (INT)(INT_PTR)templateName, parent, proc, param);
  247. lang->Release();
  248. }
  249. return r;
  250. }
  251. INT_PTR Plugin_DialogBoxParam(const wchar_t *templateName, HWND parent, DLGPROC proc, LPARAM param)
  252. {
  253. INT_PTR r = -1;
  254. api_language *lang = NULL;
  255. HINSTANCE langModule = Plugin_GetLangHelper(&lang);
  256. if (NULL != lang)
  257. {
  258. r = lang->LDialogBoxParamW(langModule, Plugin_GetInstance(), (INT)(INT_PTR)templateName, parent, proc, param);
  259. lang->Release();
  260. }
  261. return r;
  262. }
  263. HMENU Plugin_LoadMenu(const wchar_t *menuName)
  264. {
  265. HMENU r = NULL;
  266. api_language *lang = NULL;
  267. HINSTANCE langModule = Plugin_GetLangHelper(&lang);
  268. if (NULL != lang)
  269. {
  270. r = lang->LoadLMenuW(langModule, Plugin_GetInstance(), (INT)(INT_PTR)menuName);
  271. lang->Release();
  272. }
  273. return r;
  274. }
  275. void *Plugin_LoadResource(const wchar_t *resourceType, const wchar_t *resourceName, unsigned long *size)
  276. {
  277. void *r = NULL;
  278. api_language *lang = NULL;
  279. HINSTANCE langModule = Plugin_GetLangHelper(&lang);
  280. if (NULL != lang)
  281. {
  282. r = lang->LoadResourceFromFileW(langModule, Plugin_GetInstance(), resourceType, resourceName, size);
  283. lang->Release();
  284. }
  285. return r;
  286. }
  287. HACCEL Plugin_LoadAccelerators(const wchar_t *tableName)
  288. {
  289. HACCEL r = NULL;
  290. api_language *lang = NULL;
  291. HINSTANCE langModule = Plugin_GetLangHelper(&lang);
  292. if (NULL != lang)
  293. {
  294. r = lang->LoadAcceleratorsW(langModule, Plugin_GetInstance(), tableName);
  295. lang->Release();
  296. }
  297. return r;
  298. }
  299. HRESULT Plugin_QueryImageLoader(HINSTANCE hInstance, LPCWSTR pszName, BOOL fPremultiply, ifc_omimageloader **imageLoader)
  300. {
  301. if (NULL == imageLoader) return E_POINTER;
  302. *imageLoader = NULL;
  303. if (NULL == pszName) return E_INVALIDARG;
  304. return PngLoader::CreateInstance(hInstance, pszName, fPremultiply, imageLoader);
  305. }
  306. size_t Plugin_TlsAlloc(void)
  307. {
  308. size_t index = TLS_OUT_OF_INDEXES;
  309. ifc_wasabihelper *wasabi = NULL;
  310. if (SUCCEEDED(component.GetWasabiHelper(&wasabi)) && wasabi != NULL)
  311. {
  312. api_application *app = NULL;
  313. if (SUCCEEDED(wasabi->GetApplicationApi(&app)) && app != NULL)
  314. {
  315. index = app->AllocateThreadStorage();
  316. app->Release();
  317. }
  318. }
  319. return index;
  320. }
  321. BOOL Plugin_TlsFree(size_t index)
  322. {
  323. return FALSE;
  324. }
  325. void *Plugin_TlsGetValue(size_t index)
  326. {
  327. void *result = NULL;
  328. ifc_wasabihelper *wasabi = NULL;
  329. if (SUCCEEDED(component.GetWasabiHelper(&wasabi)) && wasabi != NULL)
  330. {
  331. api_application *app = NULL;
  332. if (SUCCEEDED(wasabi->GetApplicationApi(&app)) && app != NULL)
  333. {
  334. result = app->GetThreadStorage(index);
  335. app->Release();
  336. }
  337. }
  338. return result;
  339. }
  340. BOOL Plugin_TlsSetValue(size_t index, void* value)
  341. {
  342. BOOL result = FALSE;
  343. ifc_wasabihelper *wasabi = NULL;
  344. if (SUCCEEDED(component.GetWasabiHelper(&wasabi)) && wasabi != NULL)
  345. {
  346. api_application *app = NULL;
  347. if (SUCCEEDED(wasabi->GetApplicationApi(&app)) && app != NULL)
  348. {
  349. app->SetThreadStorage(index, value);
  350. app->Release();
  351. result = TRUE;
  352. }
  353. }
  354. return result;
  355. }
  356. void Plugin_RegisterUnloadCallback(PLUGINUNLOADCALLBACK callback)
  357. {
  358. component.RegisterUnloadCallback(callback);
  359. }
  360. HRESULT Plugin_GetBrowserClass(LPCWSTR pszName, ifc_ombrowserclass **instance)
  361. {
  362. return component.GetBrowserClass(pszName, instance);
  363. }
  364. HRESULT Plugin_UnregisterBrowserClass(LPCWSTR pszName)
  365. {
  366. return component.UnregisterBrowserClass(pszName);
  367. }
  368. HRESULT Plugin_EnsurePathExist(LPCWSTR pszDirectory)
  369. {
  370. DWORD ec = ERROR_SUCCESS;
  371. UINT errorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
  372. if (0 == CreateDirectory(pszDirectory, NULL))
  373. {
  374. ec = GetLastError();
  375. if (ERROR_PATH_NOT_FOUND == ec)
  376. {
  377. LPCWSTR pszBlock = pszDirectory;
  378. WCHAR szBuffer[MAX_PATH] = {0};
  379. LPCTSTR pszCursor = PathFindNextComponent(pszBlock);
  380. ec = (pszCursor == pszBlock || S_OK != StringCchCopyN(szBuffer, ARRAYSIZE(szBuffer), pszBlock, (pszCursor - pszBlock))) ?
  381. ERROR_INVALID_NAME : ERROR_SUCCESS;
  382. pszBlock = pszCursor;
  383. while (ERROR_SUCCESS == ec && NULL != (pszCursor = PathFindNextComponent(pszBlock)))
  384. {
  385. if (pszCursor == pszBlock || S_OK != StringCchCatN(szBuffer, ARRAYSIZE(szBuffer), pszBlock, (pszCursor - pszBlock)))
  386. ec = ERROR_INVALID_NAME;
  387. if (ERROR_SUCCESS == ec && !CreateDirectory(szBuffer, NULL))
  388. {
  389. ec = GetLastError();
  390. if (ERROR_ALREADY_EXISTS == ec) ec = ERROR_SUCCESS;
  391. }
  392. pszBlock = pszCursor;
  393. }
  394. }
  395. if (ERROR_ALREADY_EXISTS == ec)
  396. ec = ERROR_SUCCESS;
  397. }
  398. SetErrorMode(errorMode);
  399. SetLastError(ec);
  400. return HRESULT_FROM_WIN32(ec);
  401. }
  402. HRESULT Plugin_MakeResourcePath(LPWSTR pszBuffer, UINT cchBufferMax, HINSTANCE hInstance, LPCWSTR pszType, LPCWSTR pszName, UINT uFlags)
  403. {
  404. if (NULL == pszBuffer) return E_INVALIDARG;
  405. if (NULL == hInstance || NULL == pszName)
  406. {
  407. pszBuffer[0] = L'\0';
  408. return E_INVALIDARG;
  409. }
  410. LPWSTR cursor = pszBuffer;
  411. size_t remaining = cchBufferMax;
  412. HRESULT hr = StringCchCopyEx(cursor, remaining, L"res://", &cursor, &remaining, 0);
  413. if (SUCCEEDED(hr))
  414. {
  415. DWORD cchPath = GetModuleFileName(hInstance, cursor, (DWORD)remaining);
  416. if (0 == cchPath)
  417. {
  418. DWORD errorCode = GetLastError();
  419. hr = HRESULT_FROM_WIN32(errorCode);
  420. }
  421. else
  422. {
  423. if (0 != (RESPATH_COMPACT & uFlags))
  424. {
  425. ifc_wasabihelper *wasabi = NULL;
  426. if (SUCCEEDED(Plugin_GetWasabiHelper(&wasabi)) && wasabi != NULL)
  427. {
  428. api_application *application = NULL;
  429. if (SUCCEEDED(wasabi->GetApplicationApi(&application)) && application != NULL)
  430. {
  431. WCHAR szPlugin[MAX_PATH] = {0};
  432. HINSTANCE hWinamp = application->main_gethInstance();
  433. if (NULL != hWinamp && 0 != GetModuleFileName(hWinamp, szPlugin, ARRAYSIZE(szPlugin)))
  434. {
  435. PathRemoveFileSpec(szPlugin);
  436. INT cchCommon = PathCommonPrefix(cursor, szPlugin, NULL);
  437. // prevents messing things up if on same drive and that's all that matches
  438. if (cchCommon > 3)
  439. {
  440. cchCommon++;
  441. cchPath -= cchCommon;
  442. MoveMemory(cursor, cursor + cchCommon, cchPath * sizeof(WCHAR));
  443. cursor[cchPath] = L'\0';
  444. }
  445. }
  446. application->Release();
  447. }
  448. wasabi->Release();
  449. }
  450. }
  451. remaining -= cchPath;
  452. cursor += cchPath;
  453. }
  454. LPCWSTR pszTemplate = NULL;
  455. if (SUCCEEDED(hr) && NULL != pszType)
  456. {
  457. if (IS_INTRESOURCE(pszType))
  458. {
  459. pszTemplate = (0 != (RESPATH_TARGETIE & uFlags)) ? L"/%d" : L"/#%d";
  460. hr = StringCchPrintfEx(cursor, remaining, &cursor, &remaining, 0, pszTemplate, pszType);
  461. }
  462. else if (L'\0' != *pszType)
  463. {
  464. hr = StringCchPrintfEx(cursor, remaining, &cursor, &remaining, 0, L"/%s", pszType);
  465. }
  466. }
  467. if (SUCCEEDED(hr))
  468. {
  469. if (IS_INTRESOURCE(pszName))
  470. pszTemplate = (0 != (RESPATH_TARGETIE & uFlags)) ? L"/%d" : L"/#%d";
  471. else
  472. pszTemplate = L"/%s";
  473. hr = StringCchPrintfEx(cursor, remaining, &cursor, &remaining, 0, pszTemplate, pszName);
  474. }
  475. }
  476. if (FAILED(hr))
  477. pszBuffer[0] = L'\0';
  478. return hr;
  479. }
  480. HRESULT Plugin_ResolveRelativePath(LPCWSTR pszPath, ifc_omservicehost *host, LPWSTR pszBuffer, UINT cchBufferMax)
  481. {
  482. if (NULL == pszBuffer)
  483. return E_POINTER;
  484. HRESULT hr = S_OK;
  485. if (NULL != pszPath && L'\0' == *pszPath)
  486. pszPath = NULL;
  487. if (NULL != pszPath && FALSE == PathIsRelative(pszPath))
  488. {
  489. hr = StringCchCopy(pszBuffer, cchBufferMax, pszPath);
  490. return (FAILED(hr)) ? hr : S_FALSE;
  491. }
  492. WCHAR szBase[MAX_PATH] = {0};
  493. if (NULL == host || FAILED(host->GetBasePath(NULL, szBase, ARRAYSIZE(szBase))))
  494. szBase[0]= L'\0';
  495. if (L'\0' == szBase[0] || PathIsRelative(szBase))
  496. {
  497. ifc_wasabihelper *wasabi = NULL;
  498. if (SUCCEEDED(Plugin_GetWasabiHelper(&wasabi)) && wasabi != NULL)
  499. {
  500. api_application *application = NULL;
  501. if (SUCCEEDED(wasabi->GetApplicationApi(&application)) && application != NULL)
  502. {
  503. LPCWSTR pszUser = application->path_getUserSettingsPath();
  504. if (NULL != pszUser && L'\0' != *pszUser)
  505. {
  506. if (L'\0' != szBase[0])
  507. hr = StringCchCopy(pszBuffer, cchBufferMax, szBase);
  508. if (SUCCEEDED(hr))
  509. {
  510. hr = StringCchCopy(szBase, ARRAYSIZE(szBase), pszUser);
  511. if (SUCCEEDED(hr) && L'\0' != *pszBuffer && FALSE == PathAppend(szBase, pszBuffer))
  512. hr = E_OUTOFMEMORY;
  513. }
  514. }
  515. application->Release();
  516. }
  517. wasabi->Release();
  518. }
  519. }
  520. if (SUCCEEDED(hr) && NULL != pszPath)
  521. {
  522. if (L'\0' == szBase[0])
  523. hr = StringCchCopy(szBase, ARRAYSIZE(szBase), pszPath);
  524. else if (FALSE == PathAppend(szBase, pszPath))
  525. hr = E_OUTOFMEMORY;
  526. }
  527. if (SUCCEEDED(hr) && 0 == PathCanonicalize(pszBuffer, szBase))
  528. hr = E_OUTOFMEMORY;
  529. return hr;
  530. }
  531. BOOL Plugin_IsDirectMouseWheelMessage(const UINT uMsg)
  532. {
  533. static UINT WINAMP_WM_DIRECT_MOUSE_WHEEL = WM_NULL;
  534. if (WM_NULL == WINAMP_WM_DIRECT_MOUSE_WHEEL)
  535. {
  536. WINAMP_WM_DIRECT_MOUSE_WHEEL = RegisterWindowMessageW(L"WINAMP_WM_DIRECT_MOUSE_WHEEL");
  537. if (WM_NULL == WINAMP_WM_DIRECT_MOUSE_WHEEL)
  538. return FALSE;
  539. }
  540. return (WINAMP_WM_DIRECT_MOUSE_WHEEL == uMsg);
  541. }
  542. extern "C" __declspec(dllexport) ifc_wa5component *GetWinamp5SystemComponent()
  543. {
  544. return &component;
  545. }
  546. BOOL APIENTRY DllMain(HANDLE hModule, DWORD uReason, void *reserved)
  547. {
  548. switch(uReason)
  549. {
  550. case DLL_PROCESS_ATTACH:
  551. pluginInstance = (HINSTANCE)hModule;
  552. HTMLContainer2_Initialize();
  553. break;
  554. case DLL_PROCESS_DETACH:
  555. HTMLContainer2_Uninitialize();
  556. break;
  557. }
  558. return TRUE;
  559. }