123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- #include "main.h"
- #include "navigation.h"
- #include "servicehelper.h"
- #include "handler.h"
- #include "ifc_omservice.h"
- #include "../Agave/URIHandler/svc_urihandler.h"
- #include <api/service/waservicefactory.h>
- #include "api.h"
- #include <shlwapi.h>
- static uint8_t quickhex(wchar_t c)
- {
- int hexvalue = c;
- if (hexvalue & 0x10)
- hexvalue &= ~0x30;
- else
- {
- hexvalue &= 0xF;
- hexvalue += 9;
- }
- return hexvalue;
- }
- static uint8_t DecodeEscape(const wchar_t *&str)
- {
- uint8_t a = quickhex(*++str);
- uint8_t b = quickhex(*++str);
- str++;
- return a * 16 + b;
- }
- static void DecodeEscapedUTF8(wchar_t *&output, const wchar_t *&input)
- {
- uint8_t utf8_data[1024] = {0}; // hopefully big enough!!
- int num_utf8_words=0;
- bool error=false;
- while (input && *input == '%' && num_utf8_words < sizeof(utf8_data))
- {
- if (iswxdigit(input[1]) && iswxdigit(input[2]))
- {
- utf8_data[num_utf8_words++]=DecodeEscape(input);
- }
- else if (input[1] == '%')
- {
- input+=2;
- utf8_data[num_utf8_words++]='%';
- }
- else
- {
- error = true;
- break;
- }
- }
- int len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)utf8_data, num_utf8_words, 0, 0);
- MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)utf8_data, num_utf8_words, output, len);
- output += len;
- if (error)
- {
- *output++ = *input++;
- }
- }
- static void UrlDecode(const wchar_t *input, wchar_t *output, size_t len)
- {
- const wchar_t *stop = output+len-4; // give ourself a cushion large enough to hold a full UTF-16 sequence
- const wchar_t *itr = input;
- while (itr && *itr)
- {
- if (output >= stop)
- {
- *output=0;
- return;
- }
- switch (*itr)
- {
- case '%':
- DecodeEscapedUTF8(output, itr);
- break;
- case '&':
- *output = 0;
- return;
- default:
- *output++ = *itr++;
- break;
- }
- }
- *output = 0;
- }
- // first parameter has param name either null or = terminated, second is null terminated
- static bool ParamCompare(const wchar_t *url_param, const wchar_t *param_name)
- {
- while (url_param && *url_param && *param_name && *url_param!=L'=')
- {
- if (*url_param++ != *param_name++)
- return false;
- }
- return true;
- }
- static bool get_request_parm(const wchar_t *params, const wchar_t *param_name, wchar_t *value, size_t value_len)
- {
- const wchar_t *t=params;
- while (t && *t && *t != L'?') // find start of parameters
- t++;
-
- while (t && *t)
- {
- t++; // skip ? or &
- if (ParamCompare(t, param_name))
- {
- while (t && *t && *t != L'=' && *t != '&') // find start of value
- t++;
- switch(*t)
- {
- case L'=':
- UrlDecode(++t, value, value_len);
- return true;
- case 0:
- case L'&': // no value
- *value=0;
- return true;
- default: // shouldn't get here
- return false;
- }
- }
- while (t && *t && *t != L'&') // find next parameter
- t++;
- }
- return false;
- }
- int OnlineServicesURIHandler::ProcessFilename(const wchar_t *filename)
- {
- if (HANDLED != IsMine(filename))
- return NOT_HANDLED;
- UINT serviceId = 0;
- wchar_t szBuffer[512]=L"";
- if (get_request_parm(filename, L"id", szBuffer, ARRAYSIZE(szBuffer)) &&
- L'\0' != szBuffer[0])
- {
- if (FALSE == StrToIntEx(szBuffer, STIF_SUPPORT_HEX, (INT*)&serviceId))
- serviceId = 0;
- }
- ServiceHelper_ShowService(serviceId, SHOWMODE_ENSUREVISIBLE);
- return HANDLED_EXCLUSIVE;
- }
- int OnlineServicesURIHandler::IsMine(const wchar_t *filename)
- {
- if (!_wcsnicmp(filename, L"winamp://Online Services", 24) || !_wcsnicmp(filename, L"winamp://Online%20Services", 26))
- return HANDLED;
- else
- return NOT_HANDLED;
- }
- #define CBCLASS OnlineServicesURIHandler
- START_DISPATCH;
- CB(PROCESSFILENAME, ProcessFilename);
- CB(ISMINE, IsMine);
- END_DISPATCH;
- #undef CBCLASS
|