common.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. #include "./common.h"
  2. #include "./api__ml_online.h"
  3. #include "./main.h"
  4. #include "../winamp/wa_ipc.h"
  5. #include <strsafe.h>
  6. LPWSTR Plugin_MallocString(size_t cchLen)
  7. {
  8. return (LPWSTR)calloc(cchLen, sizeof(WCHAR));
  9. }
  10. void Plugin_FreeString(LPWSTR pszString)
  11. {
  12. if (NULL != pszString)
  13. {
  14. free(pszString);
  15. pszString = NULL;
  16. }
  17. }
  18. LPWSTR Plugin_ReAllocString(LPWSTR pszString, size_t cchLen)
  19. {
  20. return (LPWSTR)realloc(pszString, sizeof(WCHAR) * cchLen);
  21. }
  22. LPWSTR Plugin_CopyString(LPCWSTR pszSource)
  23. {
  24. if (NULL == pszSource)
  25. return NULL;
  26. INT cchSource = lstrlenW(pszSource) + 1;
  27. LPWSTR copy = Plugin_MallocString(cchSource);
  28. if (NULL != copy)
  29. {
  30. CopyMemory(copy, pszSource, sizeof(WCHAR) * cchSource);
  31. }
  32. return copy;
  33. }
  34. LPSTR Plugin_MallocAnsiString(size_t cchLen)
  35. {
  36. return (LPSTR)calloc(cchLen, sizeof(CHAR));
  37. }
  38. LPSTR Plugin_CopyAnsiString(LPCSTR pszSource)
  39. {
  40. if (NULL == pszSource)
  41. return NULL;
  42. INT cchSource = lstrlenA(pszSource) + 1;
  43. LPSTR copy = Plugin_MallocAnsiString(cchSource);
  44. if (NULL != copy)
  45. {
  46. CopyMemory(copy, pszSource, sizeof(CHAR) * cchSource);
  47. }
  48. return copy;
  49. }
  50. void Plugin_FreeAnsiString(LPSTR pszString)
  51. {
  52. Plugin_FreeString((LPWSTR)pszString);
  53. }
  54. LPSTR Plugin_WideCharToMultiByte(UINT codePage, DWORD dwFlags, LPCWSTR lpWideCharStr, INT cchWideChar, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar)
  55. {
  56. INT cchBuffer = WideCharToMultiByte(codePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar);
  57. if (0 == cchBuffer) return NULL;
  58. LPSTR buffer = Plugin_MallocAnsiString(cchBuffer);
  59. if (NULL == buffer) return NULL;
  60. if (0 == WideCharToMultiByte(codePage, dwFlags, lpWideCharStr, cchWideChar, buffer, cchBuffer, lpDefaultChar, lpUsedDefaultChar))
  61. {
  62. Plugin_FreeAnsiString(buffer);
  63. return NULL;
  64. }
  65. return buffer;
  66. }
  67. LPWSTR Plugin_MultiByteToWideChar(UINT codePage, DWORD dwFlags, LPCSTR lpMultiByteStr, INT cbMultiByte)
  68. {
  69. if (NULL == lpMultiByteStr) return NULL;
  70. INT cchBuffer = MultiByteToWideChar(codePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0);
  71. if (NULL == cchBuffer) return NULL;
  72. if (cbMultiByte > 0) cchBuffer++;
  73. LPWSTR buffer = Plugin_MallocString(cchBuffer);
  74. if (NULL == buffer) return NULL;
  75. if (0 == MultiByteToWideChar(codePage, dwFlags, lpMultiByteStr, cbMultiByte, buffer, cchBuffer))
  76. {
  77. Plugin_FreeString(buffer);
  78. return NULL;
  79. }
  80. if (cbMultiByte > 0)
  81. {
  82. buffer[cchBuffer - 1] = L'\0';
  83. }
  84. return buffer;
  85. }
  86. LPWSTR Plugin_DuplicateResString(LPCWSTR pszResource)
  87. {
  88. return (IS_INTRESOURCE(pszResource)) ?
  89. (LPWSTR)pszResource :
  90. Plugin_CopyString(pszResource);
  91. }
  92. void Plugin_FreeResString(LPWSTR pszResource)
  93. {
  94. if (!IS_INTRESOURCE(pszResource))
  95. Plugin_FreeString(pszResource);
  96. }
  97. HRESULT Plugin_CopyResString(LPWSTR pszBuffer, INT cchBufferMax, LPCWSTR pszString)
  98. {
  99. if (NULL == pszBuffer)
  100. return E_INVALIDARG;
  101. HRESULT hr = S_OK;
  102. if (NULL == pszString)
  103. {
  104. pszBuffer[0] = L'\0';
  105. }
  106. else if (IS_INTRESOURCE(pszString))
  107. {
  108. if (NULL == WASABI_API_LNG)
  109. hr = E_FAIL;
  110. else
  111. WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)pszString, pszBuffer, cchBufferMax);
  112. }
  113. else
  114. {
  115. hr = StringCchCopy(pszBuffer, cchBufferMax, pszString);
  116. }
  117. return hr;
  118. }
  119. void Plugin_SafeRelease(IUnknown *pUnk)
  120. {
  121. if (NULL != pUnk)
  122. pUnk->Release();
  123. }
  124. HRESULT Plugin_MakeResourcePath(LPWSTR pszBuffer, INT cchBufferMax, LPCWSTR pszType, LPCWSTR pszName, UINT flags)
  125. {
  126. HINSTANCE hInstance = WASABI_API_LNG_HINST;
  127. if (NULL == hInstance || NULL == FindResource(hInstance, pszName, pszType))
  128. hInstance = Plugin_GetInstance();
  129. if (NULL == OMUTILITY)
  130. return E_UNEXPECTED;
  131. return OMUTILITY->MakeResourcePath(pszBuffer, cchBufferMax, hInstance, pszType, pszName, flags);
  132. }
  133. HWND Plugin_GetDialogOwner(void)
  134. {
  135. HWND hOwner= Plugin_GetLibrary();
  136. if (NULL == hOwner || FALSE == IsWindowVisible(hOwner) ||
  137. FALSE == IsWindowEnabled(hOwner))
  138. {
  139. hOwner = Plugin_GetWinamp();
  140. if (NULL != hOwner)
  141. {
  142. HWND hDlgParent = (HWND)SENDWAIPC(hOwner, IPC_GETDIALOGBOXPARENT, 0L);
  143. if (NULL != hDlgParent)
  144. hOwner = hDlgParent;
  145. }
  146. }
  147. return hOwner;
  148. }
  149. HRESULT Plugin_AppendFileFilter(LPTSTR pszBuffer, size_t cchBufferMax, LPCTSTR pName, LPCTSTR pFilter, LPTSTR *ppBufferOut, size_t *pRemaining, BOOL bShowFilter)
  150. {
  151. HRESULT hr;
  152. LPTSTR pCursor = pszBuffer;
  153. if (NULL != ppBufferOut)
  154. *ppBufferOut = pszBuffer;
  155. if (NULL != pRemaining)
  156. *pRemaining = cchBufferMax;
  157. if (NULL == pszBuffer || NULL == pName || NULL == pFilter)
  158. return E_INVALIDARG;
  159. pszBuffer[0] = TEXT('\0');
  160. hr = StringCchCopyEx(pCursor, cchBufferMax, pName, &pCursor, &cchBufferMax,
  161. STRSAFE_IGNORE_NULLS | STRSAFE_NULL_ON_FAILURE);
  162. if (bShowFilter && SUCCEEDED(hr))
  163. {
  164. LPTSTR p = pCursor;
  165. hr = StringCchPrintfEx(pCursor, cchBufferMax, &pCursor, &cchBufferMax,
  166. STRSAFE_IGNORE_NULLS | STRSAFE_NULL_ON_FAILURE, TEXT(" (%s)"), pFilter);
  167. if (SUCCEEDED(hr) && p != pCursor)
  168. CharLowerBuff(p, (INT)(INT_PTR)(pCursor - p));
  169. }
  170. if (SUCCEEDED(hr))
  171. {
  172. pCursor++;
  173. cchBufferMax--;
  174. hr = StringCchCopyEx(pCursor, cchBufferMax, pFilter, &pCursor, &cchBufferMax,
  175. STRSAFE_IGNORE_NULLS | STRSAFE_NULL_ON_FAILURE);
  176. }
  177. if (cchBufferMax < 1)
  178. hr = STRSAFE_E_INSUFFICIENT_BUFFER;
  179. pCursor++;
  180. cchBufferMax--;
  181. if (SUCCEEDED(hr))
  182. {
  183. pCursor[0] = TEXT('\0');
  184. if (NULL != ppBufferOut)
  185. *ppBufferOut = pCursor;
  186. if (NULL != pRemaining)
  187. *pRemaining = cchBufferMax;
  188. }
  189. else
  190. {
  191. pszBuffer[0] = TEXT('\0');
  192. pszBuffer[1] = TEXT('\0');
  193. }
  194. return hr;
  195. }
  196. HRESULT Plugin_BuildActionUrl(LPWSTR *ppStringOut, LPCWSTR pszAction, UINT *pServiceUid, size_t cchServiceUid)
  197. {
  198. if (NULL == ppStringOut)
  199. return E_POINTER;
  200. *ppStringOut = NULL;
  201. if (NULL == pszAction || L'\0' == *pszAction ||
  202. NULL == pServiceUid || 0 == cchServiceUid)
  203. {
  204. return E_INVALIDARG;
  205. }
  206. const WCHAR szPrefix[] = L"http://services.winamp.com/svc/action?action=%s\0";
  207. const WCHAR szService[] = L"&svc_id=%u\0";
  208. const WCHAR szClient[] = L"&unique_id=%s\0";
  209. size_t cchBuffer = ARRAYSIZE(szPrefix) + ARRAYSIZE(szService) + ARRAYSIZE(szClient);
  210. cchBuffer += lstrlen(pszAction);
  211. cchBuffer += (cchServiceUid * 11);
  212. cchBuffer += 32; // unique id
  213. LPWSTR buffer = Plugin_MallocString(cchBuffer);
  214. if (NULL == buffer)
  215. return E_OUTOFMEMORY;
  216. HRESULT hr;
  217. LPWSTR cursor = buffer;
  218. size_t remaining = cchBuffer;
  219. hr = StringCchPrintfEx(cursor, remaining, &cursor, &remaining, STRSAFE_NULL_ON_FAILURE,
  220. szPrefix, pszAction);
  221. for (size_t i = 0; i < cchServiceUid && SUCCEEDED(hr); i++)
  222. {
  223. hr = StringCchPrintfEx(cursor, remaining, &cursor, &remaining, STRSAFE_NULL_ON_FAILURE,
  224. ((0 == i) ? szService : L",%u"), pServiceUid[i]);
  225. }
  226. if (SUCCEEDED(hr))
  227. {
  228. WCHAR szTemp[128] = {0};
  229. hr = OMBROWSERMNGR->GetClientId(szTemp, ARRAYSIZE(szTemp));
  230. if (SUCCEEDED(hr))
  231. {
  232. hr = StringCchPrintfEx(cursor, remaining, &cursor, &remaining, STRSAFE_NULL_ON_FAILURE, szClient, szTemp);
  233. }
  234. }
  235. if (FAILED(hr))
  236. {
  237. Plugin_FreeString(buffer);
  238. hr = E_FAIL;
  239. }
  240. else
  241. {
  242. *ppStringOut = buffer;
  243. }
  244. return hr;
  245. }
  246. INT Plugin_ParseKeywords(LPCWSTR input, INT cchInput, WCHAR separator, BOOL eatSpace, KWPARSERPROC callback, ULONG_PTR user)
  247. {
  248. if (NULL == input)
  249. return 0;
  250. if (cchInput < 0)
  251. cchInput = lstrlen(input);
  252. if (cchInput <= 0)
  253. return 0;
  254. LPCWSTR end = (input + cchInput);
  255. if(eatSpace)
  256. while(input < end && L' ' == *input) input++;
  257. if (L'\0' == *input)
  258. return 0;
  259. INT found = 0;
  260. for (;;)
  261. {
  262. LPCWSTR pBlock = input;
  263. while(input <= end && separator != *input) input++;
  264. LPCWSTR last = (input - 1);
  265. if (eatSpace)
  266. while(last >= pBlock && L' ' == *last) last--;
  267. if (last >= pBlock)
  268. {
  269. UINT code = callback(pBlock, (INT)(INT_PTR)(last - pBlock) + 1, user);
  270. if (KWPARSER_FOUND & code) found++;
  271. if (KWPARSER_ABORT == (0x01 & code))
  272. return found;
  273. }
  274. if (input >= end || L'\0' == *input)
  275. return found;
  276. input++;
  277. if(eatSpace)
  278. while(input < end && L' ' == *input) input++;
  279. }
  280. return found;
  281. }
  282. INT Plugin_MessageBox(LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
  283. {
  284. HWND hHost, hLibrary = Plugin_GetLibrary();
  285. if (NULL != hLibrary && FALSE != IsWindowVisible(hLibrary))
  286. {
  287. hHost = (HWND)SENDMLIPC(hLibrary, ML_IPC_GETCURRENTVIEW, 0);
  288. if (NULL == hHost || FALSE == IsWindowVisible(hHost))
  289. hHost = hLibrary;
  290. }
  291. else
  292. hHost = Plugin_GetDialogOwner();
  293. if(IS_INTRESOURCE(lpText) && NULL != lpText)
  294. {
  295. WCHAR szText[2048] = {0};
  296. lpText = WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)lpText, szText, ARRAYSIZE(szText));
  297. }
  298. if(IS_INTRESOURCE(lpCaption) && NULL != lpCaption)
  299. {
  300. WCHAR szCaption[128] = {0};
  301. lpCaption = WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)lpCaption, szCaption, ARRAYSIZE(szCaption));
  302. }
  303. return MessageBox(hHost, lpText, lpCaption, uType);
  304. }