aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Library/ml_online/common.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Library/ml_online/common.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/Plugins/Library/ml_online/common.cpp')
-rw-r--r--Src/Plugins/Library/ml_online/common.cpp374
1 files changed, 374 insertions, 0 deletions
diff --git a/Src/Plugins/Library/ml_online/common.cpp b/Src/Plugins/Library/ml_online/common.cpp
new file mode 100644
index 00000000..f3d88809
--- /dev/null
+++ b/Src/Plugins/Library/ml_online/common.cpp
@@ -0,0 +1,374 @@
+#include "./common.h"
+#include "./api__ml_online.h"
+#include "./main.h"
+
+#include "../winamp/wa_ipc.h"
+
+#include <strsafe.h>
+
+LPWSTR Plugin_MallocString(size_t cchLen)
+{
+ return (LPWSTR)calloc(cchLen, sizeof(WCHAR));
+}
+
+void Plugin_FreeString(LPWSTR pszString)
+{
+ if (NULL != pszString)
+ {
+ free(pszString);
+ pszString = NULL;
+ }
+}
+
+LPWSTR Plugin_ReAllocString(LPWSTR pszString, size_t cchLen)
+{
+ return (LPWSTR)realloc(pszString, sizeof(WCHAR) * cchLen);
+}
+
+LPWSTR Plugin_CopyString(LPCWSTR pszSource)
+{
+ if (NULL == pszSource)
+ return NULL;
+
+ INT cchSource = lstrlenW(pszSource) + 1;
+
+ LPWSTR copy = Plugin_MallocString(cchSource);
+ if (NULL != copy)
+ {
+ CopyMemory(copy, pszSource, sizeof(WCHAR) * cchSource);
+ }
+ return copy;
+}
+
+LPSTR Plugin_MallocAnsiString(size_t cchLen)
+{
+ return (LPSTR)calloc(cchLen, sizeof(CHAR));
+}
+
+LPSTR Plugin_CopyAnsiString(LPCSTR pszSource)
+{
+ if (NULL == pszSource)
+ return NULL;
+
+ INT cchSource = lstrlenA(pszSource) + 1;
+
+ LPSTR copy = Plugin_MallocAnsiString(cchSource);
+ if (NULL != copy)
+ {
+ CopyMemory(copy, pszSource, sizeof(CHAR) * cchSource);
+ }
+ return copy;
+
+}
+void Plugin_FreeAnsiString(LPSTR pszString)
+{
+ Plugin_FreeString((LPWSTR)pszString);
+}
+
+LPSTR Plugin_WideCharToMultiByte(UINT codePage, DWORD dwFlags, LPCWSTR lpWideCharStr, INT cchWideChar, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar)
+{
+ INT cchBuffer = WideCharToMultiByte(codePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar);
+ if (0 == cchBuffer) return NULL;
+
+ LPSTR buffer = Plugin_MallocAnsiString(cchBuffer);
+ if (NULL == buffer) return NULL;
+
+ if (0 == WideCharToMultiByte(codePage, dwFlags, lpWideCharStr, cchWideChar, buffer, cchBuffer, lpDefaultChar, lpUsedDefaultChar))
+ {
+ Plugin_FreeAnsiString(buffer);
+ return NULL;
+ }
+ return buffer;
+}
+
+LPWSTR Plugin_MultiByteToWideChar(UINT codePage, DWORD dwFlags, LPCSTR lpMultiByteStr, INT cbMultiByte)
+{
+ if (NULL == lpMultiByteStr) return NULL;
+ INT cchBuffer = MultiByteToWideChar(codePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0);
+ if (NULL == cchBuffer) return NULL;
+
+ if (cbMultiByte > 0) cchBuffer++;
+
+ LPWSTR buffer = Plugin_MallocString(cchBuffer);
+ if (NULL == buffer) return NULL;
+
+ if (0 == MultiByteToWideChar(codePage, dwFlags, lpMultiByteStr, cbMultiByte, buffer, cchBuffer))
+ {
+ Plugin_FreeString(buffer);
+ return NULL;
+ }
+
+ if (cbMultiByte > 0)
+ {
+ buffer[cchBuffer - 1] = L'\0';
+ }
+ return buffer;
+}
+
+LPWSTR Plugin_DuplicateResString(LPCWSTR pszResource)
+{
+ return (IS_INTRESOURCE(pszResource)) ?
+ (LPWSTR)pszResource :
+ Plugin_CopyString(pszResource);
+}
+
+void Plugin_FreeResString(LPWSTR pszResource)
+{
+ if (!IS_INTRESOURCE(pszResource))
+ Plugin_FreeString(pszResource);
+}
+
+HRESULT Plugin_CopyResString(LPWSTR pszBuffer, INT cchBufferMax, LPCWSTR pszString)
+{
+ if (NULL == pszBuffer)
+ return E_INVALIDARG;
+
+ HRESULT hr = S_OK;
+
+ if (NULL == pszString)
+ {
+ pszBuffer[0] = L'\0';
+ }
+ else if (IS_INTRESOURCE(pszString))
+ {
+ if (NULL == WASABI_API_LNG)
+ hr = E_FAIL;
+ else
+ WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)pszString, pszBuffer, cchBufferMax);
+ }
+ else
+ {
+ hr = StringCchCopy(pszBuffer, cchBufferMax, pszString);
+ }
+ return hr;
+}
+
+void Plugin_SafeRelease(IUnknown *pUnk)
+{
+ if (NULL != pUnk)
+ pUnk->Release();
+}
+
+HRESULT Plugin_MakeResourcePath(LPWSTR pszBuffer, INT cchBufferMax, LPCWSTR pszType, LPCWSTR pszName, UINT flags)
+{
+ HINSTANCE hInstance = WASABI_API_LNG_HINST;
+ if (NULL == hInstance || NULL == FindResource(hInstance, pszName, pszType))
+ hInstance = Plugin_GetInstance();
+
+ if (NULL == OMUTILITY)
+ return E_UNEXPECTED;
+
+ return OMUTILITY->MakeResourcePath(pszBuffer, cchBufferMax, hInstance, pszType, pszName, flags);
+}
+
+HWND Plugin_GetDialogOwner(void)
+{
+ HWND hOwner= Plugin_GetLibrary();
+ if (NULL == hOwner || FALSE == IsWindowVisible(hOwner) ||
+ FALSE == IsWindowEnabled(hOwner))
+ {
+ hOwner = Plugin_GetWinamp();
+ if (NULL != hOwner)
+ {
+ HWND hDlgParent = (HWND)SENDWAIPC(hOwner, IPC_GETDIALOGBOXPARENT, 0L);
+ if (NULL != hDlgParent)
+ hOwner = hDlgParent;
+ }
+ }
+ return hOwner;
+}
+
+HRESULT Plugin_AppendFileFilter(LPTSTR pszBuffer, size_t cchBufferMax, LPCTSTR pName, LPCTSTR pFilter, LPTSTR *ppBufferOut, size_t *pRemaining, BOOL bShowFilter)
+{
+ HRESULT hr;
+
+ LPTSTR pCursor = pszBuffer;
+
+ if (NULL != ppBufferOut)
+ *ppBufferOut = pszBuffer;
+
+ if (NULL != pRemaining)
+ *pRemaining = cchBufferMax;
+
+ if (NULL == pszBuffer || NULL == pName || NULL == pFilter)
+ return E_INVALIDARG;
+
+ pszBuffer[0] = TEXT('\0');
+
+ hr = StringCchCopyEx(pCursor, cchBufferMax, pName, &pCursor, &cchBufferMax,
+ STRSAFE_IGNORE_NULLS | STRSAFE_NULL_ON_FAILURE);
+ if (bShowFilter && SUCCEEDED(hr))
+ {
+ LPTSTR p = pCursor;
+ hr = StringCchPrintfEx(pCursor, cchBufferMax, &pCursor, &cchBufferMax,
+ STRSAFE_IGNORE_NULLS | STRSAFE_NULL_ON_FAILURE, TEXT(" (%s)"), pFilter);
+ if (SUCCEEDED(hr) && p != pCursor)
+ CharLowerBuff(p, (INT)(INT_PTR)(pCursor - p));
+ }
+ if (SUCCEEDED(hr))
+ {
+ pCursor++;
+ cchBufferMax--;
+ hr = StringCchCopyEx(pCursor, cchBufferMax, pFilter, &pCursor, &cchBufferMax,
+ STRSAFE_IGNORE_NULLS | STRSAFE_NULL_ON_FAILURE);
+ }
+
+ if (cchBufferMax < 1)
+ hr = STRSAFE_E_INSUFFICIENT_BUFFER;
+
+ pCursor++;
+ cchBufferMax--;
+
+ if (SUCCEEDED(hr))
+ {
+ pCursor[0] = TEXT('\0');
+ if (NULL != ppBufferOut)
+ *ppBufferOut = pCursor;
+ if (NULL != pRemaining)
+ *pRemaining = cchBufferMax;
+ }
+ else
+ {
+ pszBuffer[0] = TEXT('\0');
+ pszBuffer[1] = TEXT('\0');
+ }
+
+ return hr;
+}
+
+HRESULT Plugin_BuildActionUrl(LPWSTR *ppStringOut, LPCWSTR pszAction, UINT *pServiceUid, size_t cchServiceUid)
+{
+ if (NULL == ppStringOut)
+ return E_POINTER;
+
+ *ppStringOut = NULL;
+
+ if (NULL == pszAction || L'\0' == *pszAction ||
+ NULL == pServiceUid || 0 == cchServiceUid)
+ {
+ return E_INVALIDARG;
+ }
+
+ const WCHAR szPrefix[] = L"http://services.winamp.com/svc/action?action=%s\0";
+ const WCHAR szService[] = L"&svc_id=%u\0";
+ const WCHAR szClient[] = L"&unique_id=%s\0";
+
+ size_t cchBuffer = ARRAYSIZE(szPrefix) + ARRAYSIZE(szService) + ARRAYSIZE(szClient);
+ cchBuffer += lstrlen(pszAction);
+ cchBuffer += (cchServiceUid * 11);
+ cchBuffer += 32; // unique id
+
+ LPWSTR buffer = Plugin_MallocString(cchBuffer);
+ if (NULL == buffer)
+ return E_OUTOFMEMORY;
+
+ HRESULT hr;
+ LPWSTR cursor = buffer;
+ size_t remaining = cchBuffer;
+
+
+ hr = StringCchPrintfEx(cursor, remaining, &cursor, &remaining, STRSAFE_NULL_ON_FAILURE,
+ szPrefix, pszAction);
+
+ for (size_t i = 0; i < cchServiceUid && SUCCEEDED(hr); i++)
+ {
+ hr = StringCchPrintfEx(cursor, remaining, &cursor, &remaining, STRSAFE_NULL_ON_FAILURE,
+ ((0 == i) ? szService : L",%u"), pServiceUid[i]);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ WCHAR szTemp[128] = {0};
+ hr = OMBROWSERMNGR->GetClientId(szTemp, ARRAYSIZE(szTemp));
+ if (SUCCEEDED(hr))
+ {
+ hr = StringCchPrintfEx(cursor, remaining, &cursor, &remaining, STRSAFE_NULL_ON_FAILURE, szClient, szTemp);
+ }
+ }
+
+ if (FAILED(hr))
+ {
+ Plugin_FreeString(buffer);
+ hr = E_FAIL;
+ }
+ else
+ {
+ *ppStringOut = buffer;
+ }
+ return hr;
+}
+
+INT Plugin_ParseKeywords(LPCWSTR input, INT cchInput, WCHAR separator, BOOL eatSpace, KWPARSERPROC callback, ULONG_PTR user)
+{
+ if (NULL == input)
+ return 0;
+
+ if (cchInput < 0)
+ cchInput = lstrlen(input);
+
+ if (cchInput <= 0)
+ return 0;
+
+ LPCWSTR end = (input + cchInput);
+
+ if(eatSpace)
+ while(input < end && L' ' == *input) input++;
+
+ if (L'\0' == *input)
+ return 0;
+
+ INT found = 0;
+
+ for (;;)
+ {
+ LPCWSTR pBlock = input;
+ while(input <= end && separator != *input) input++;
+ LPCWSTR last = (input - 1);
+ if (eatSpace)
+ while(last >= pBlock && L' ' == *last) last--;
+
+ if (last >= pBlock)
+ {
+ UINT code = callback(pBlock, (INT)(INT_PTR)(last - pBlock) + 1, user);
+ if (KWPARSER_FOUND & code) found++;
+ if (KWPARSER_ABORT == (0x01 & code))
+ return found;
+ }
+
+ if (input >= end || L'\0' == *input)
+ return found;
+
+ input++;
+ if(eatSpace)
+ while(input < end && L' ' == *input) input++;
+ }
+
+ return found;
+}
+
+INT Plugin_MessageBox(LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
+{
+ HWND hHost, hLibrary = Plugin_GetLibrary();
+ if (NULL != hLibrary && FALSE != IsWindowVisible(hLibrary))
+ {
+ hHost = (HWND)SENDMLIPC(hLibrary, ML_IPC_GETCURRENTVIEW, 0);
+ if (NULL == hHost || FALSE == IsWindowVisible(hHost))
+ hHost = hLibrary;
+ }
+ else
+ hHost = Plugin_GetDialogOwner();
+
+ if(IS_INTRESOURCE(lpText) && NULL != lpText)
+ {
+ WCHAR szText[2048] = {0};
+ lpText = WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)lpText, szText, ARRAYSIZE(szText));
+ }
+
+ if(IS_INTRESOURCE(lpCaption) && NULL != lpCaption)
+ {
+ WCHAR szCaption[128] = {0};
+ lpCaption = WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)lpCaption, szCaption, ARRAYSIZE(szCaption));
+ }
+
+ return MessageBox(hHost, lpText, lpCaption, uType);
+} \ No newline at end of file