handler.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #include "main.h"
  2. #include "navigation.h"
  3. #include "servicehelper.h"
  4. #include "handler.h"
  5. #include "ifc_omservice.h"
  6. #include "../Agave/URIHandler/svc_urihandler.h"
  7. #include <api/service/waservicefactory.h>
  8. #include "api.h"
  9. #include <shlwapi.h>
  10. static uint8_t quickhex(wchar_t c)
  11. {
  12. int hexvalue = c;
  13. if (hexvalue & 0x10)
  14. hexvalue &= ~0x30;
  15. else
  16. {
  17. hexvalue &= 0xF;
  18. hexvalue += 9;
  19. }
  20. return hexvalue;
  21. }
  22. static uint8_t DecodeEscape(const wchar_t *&str)
  23. {
  24. uint8_t a = quickhex(*++str);
  25. uint8_t b = quickhex(*++str);
  26. str++;
  27. return a * 16 + b;
  28. }
  29. static void DecodeEscapedUTF8(wchar_t *&output, const wchar_t *&input)
  30. {
  31. uint8_t utf8_data[1024] = {0}; // hopefully big enough!!
  32. int num_utf8_words=0;
  33. bool error=false;
  34. while (input && *input == '%' && num_utf8_words < sizeof(utf8_data))
  35. {
  36. if (iswxdigit(input[1]) && iswxdigit(input[2]))
  37. {
  38. utf8_data[num_utf8_words++]=DecodeEscape(input);
  39. }
  40. else if (input[1] == '%')
  41. {
  42. input+=2;
  43. utf8_data[num_utf8_words++]='%';
  44. }
  45. else
  46. {
  47. error = true;
  48. break;
  49. }
  50. }
  51. int len = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)utf8_data, num_utf8_words, 0, 0);
  52. MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)utf8_data, num_utf8_words, output, len);
  53. output += len;
  54. if (error)
  55. {
  56. *output++ = *input++;
  57. }
  58. }
  59. static void UrlDecode(const wchar_t *input, wchar_t *output, size_t len)
  60. {
  61. const wchar_t *stop = output+len-4; // give ourself a cushion large enough to hold a full UTF-16 sequence
  62. const wchar_t *itr = input;
  63. while (itr && *itr)
  64. {
  65. if (output >= stop)
  66. {
  67. *output=0;
  68. return;
  69. }
  70. switch (*itr)
  71. {
  72. case '%':
  73. DecodeEscapedUTF8(output, itr);
  74. break;
  75. case '&':
  76. *output = 0;
  77. return;
  78. default:
  79. *output++ = *itr++;
  80. break;
  81. }
  82. }
  83. *output = 0;
  84. }
  85. // first parameter has param name either null or = terminated, second is null terminated
  86. static bool ParamCompare(const wchar_t *url_param, const wchar_t *param_name)
  87. {
  88. while (url_param && *url_param && *param_name && *url_param!=L'=')
  89. {
  90. if (*url_param++ != *param_name++)
  91. return false;
  92. }
  93. return true;
  94. }
  95. static bool get_request_parm(const wchar_t *params, const wchar_t *param_name, wchar_t *value, size_t value_len)
  96. {
  97. const wchar_t *t=params;
  98. while (t && *t && *t != L'?') // find start of parameters
  99. t++;
  100. while (t && *t)
  101. {
  102. t++; // skip ? or &
  103. if (ParamCompare(t, param_name))
  104. {
  105. while (t && *t && *t != L'=' && *t != '&') // find start of value
  106. t++;
  107. switch(*t)
  108. {
  109. case L'=':
  110. UrlDecode(++t, value, value_len);
  111. return true;
  112. case 0:
  113. case L'&': // no value
  114. *value=0;
  115. return true;
  116. default: // shouldn't get here
  117. return false;
  118. }
  119. }
  120. while (t && *t && *t != L'&') // find next parameter
  121. t++;
  122. }
  123. return false;
  124. }
  125. int OnlineServicesURIHandler::ProcessFilename(const wchar_t *filename)
  126. {
  127. if (HANDLED != IsMine(filename))
  128. return NOT_HANDLED;
  129. UINT serviceId = 0;
  130. wchar_t szBuffer[512]=L"";
  131. if (get_request_parm(filename, L"id", szBuffer, ARRAYSIZE(szBuffer)) &&
  132. L'\0' != szBuffer[0])
  133. {
  134. if (FALSE == StrToIntEx(szBuffer, STIF_SUPPORT_HEX, (INT*)&serviceId))
  135. serviceId = 0;
  136. }
  137. ServiceHelper_ShowService(serviceId, SHOWMODE_ENSUREVISIBLE);
  138. return HANDLED_EXCLUSIVE;
  139. }
  140. int OnlineServicesURIHandler::IsMine(const wchar_t *filename)
  141. {
  142. if (!_wcsnicmp(filename, L"winamp://Online Services", 24) || !_wcsnicmp(filename, L"winamp://Online%20Services", 26))
  143. return HANDLED;
  144. else
  145. return NOT_HANDLED;
  146. }
  147. #define CBCLASS OnlineServicesURIHandler
  148. START_DISPATCH;
  149. CB(PROCESSFILENAME, ProcessFilename);
  150. CB(ISMINE, IsMine);
  151. END_DISPATCH;
  152. #undef CBCLASS