metrics.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /** (c) Nullsoft, Inc. C O N F I D E N T I A L
  2. ** Filename:
  3. ** Project:
  4. ** Description:
  5. ** Author:
  6. ** Created:
  7. **/
  8. #include "Main.h"
  9. #include <windows.h>
  10. #include "../nu/AutoUrl.h"
  11. #include <io.h>
  12. char metric_plugin_list[512] = {0};
  13. typedef struct
  14. {
  15. char country[64];
  16. char email[128];
  17. char objects[256];
  18. unsigned char sendemail;
  19. unsigned char sex; //1=m, 2=f, otherwise undefined
  20. unsigned char agegroup; // 1=under 13, 2=13-18, 3=18-24, 4=25-34, 5=35-44, 6=45-54, 7=55+
  21. unsigned char pad[1];
  22. } reg_data;
  23. void makeurlcodes(char *in, char *out)
  24. {
  25. char *i=in,*p=out;
  26. while (i && *i)
  27. {
  28. int v=*((unsigned char *)i++);
  29. if (IsCharAlpha(v) || (v>='0' && v <='9') || v == ' ' || v == '.' || v == '-' || v == '_') *p++ = v;
  30. else
  31. {
  32. int a,b;
  33. *p++ = '%';
  34. a=v>>4;
  35. b=v&15;
  36. a += '0';
  37. if (a > '9') a += 'A'-'9'-1;
  38. b += '0';
  39. if (b > '9') b += 'A'-'9'-1;
  40. *p++ = a;
  41. *p++ = b;
  42. }
  43. }
  44. if (p) *p=0;
  45. }
  46. static int in_objlist(char *objlist, char *obj)
  47. {
  48. char *b=objlist-1;
  49. while ((b=strstr(b+1,obj)))
  50. {
  51. if (b==objlist||b[-1]==':')
  52. {
  53. if (b[lstrlenA(obj)]==':' || !b[lstrlenA(obj)])
  54. return 1;
  55. }
  56. }
  57. return 0;
  58. }
  59. /* benski> this could be made faster using StringCchCatEx, but this isn't called enough to warrant
  60. spending the time right this instant */
  61. static void diff_objs(char *oldobj, char *newobj, char out[512])
  62. {
  63. char *n=newobj;
  64. *out=0;
  65. while (n && *n)
  66. {
  67. char buf[128],*b=buf;
  68. while (n && *n && *n != ':') *b++=*n++;
  69. if (n && *n) n++;
  70. *b++=0;
  71. if (!in_objlist(oldobj,buf))
  72. {
  73. if (!*out) StringCchCatA(out, 512, ":");
  74. StringCchCatA(out, 512, buf);
  75. }
  76. }
  77. n=oldobj;
  78. while (n && *n)
  79. {
  80. char buf[128],*b=buf;
  81. while (n && *n && *n != ':') *b++=*n++;
  82. if (n && *n) n++;
  83. *b++=0;
  84. if (!in_objlist(newobj,buf))
  85. {
  86. if (!*out) StringCchCatA(out, 512, ":");
  87. StringCchCatA(out, 512, "-");
  88. StringCchCatA(out, 512, buf);
  89. }
  90. }
  91. }
  92. static void get_objlist(char l[256])
  93. {
  94. char browserbrand[128]="";
  95. GetPrivateProfileStringA("winamp","browserbrand","",browserbrand+1,sizeof(browserbrand)-1,INI_FILEA);
  96. if (browserbrand[1])
  97. browserbrand[0]='.';
  98. else browserbrand[0]=0;
  99. StringCchPrintfA(l, 256, "wa%s%s%s",app_version,browserbrand,metric_plugin_list);
  100. }
  101. #define METRICS_EMAIL 0x0001
  102. #define METRICS_COUNTRY 0x0002
  103. #define METRICS_ANNOUNCEMENTS 0x0003
  104. #define METRICS_GENDER 0x0004
  105. INT GetMetricsValueW(const char *data, const char *pszType, void *pDest, int cbDest)
  106. {
  107. reg_data *prd = (reg_data*)data;
  108. char *str = NULL;
  109. unsigned char *val = NULL;
  110. if (!prd || !pszType || !pDest) return 0;
  111. if (IS_INTRESOURCE(pszType))
  112. {
  113. switch(((INT)(INT_PTR)pszType))
  114. {
  115. case METRICS_EMAIL: str = prd->email; break;
  116. case METRICS_COUNTRY: str = prd->country; break;
  117. case METRICS_ANNOUNCEMENTS: val = &prd->sendemail; break;
  118. case METRICS_GENDER: val = &prd->sex; break;
  119. }
  120. }
  121. if (str) return MultiByteToWideChar(CP_ACP, 0, str, -1, (wchar_t*)pDest, cbDest/sizeof(wchar_t));
  122. if (val)
  123. {
  124. ZeroMemory(pDest, cbDest);
  125. *((unsigned char*)pDest) = *val;
  126. return sizeof(*val);
  127. }
  128. return 0;
  129. }
  130. BOOL SetMetricsValueW(const char *data, const char *pszType, const void *pVal, int cbVal)
  131. {
  132. reg_data *prd = (reg_data*)data;
  133. char *str = NULL;
  134. unsigned char *val = NULL;
  135. int maxLen;
  136. if (!prd || !pszType) return FALSE;
  137. maxLen = 1;
  138. if (IS_INTRESOURCE(pszType))
  139. {
  140. switch(((INT)(INT_PTR)pszType))
  141. {
  142. case METRICS_EMAIL: str = prd->email; maxLen = sizeof(prd->email)/sizeof(char); break;
  143. case METRICS_COUNTRY: str = prd->country; maxLen = sizeof(prd->country)/sizeof(char); break;
  144. case METRICS_ANNOUNCEMENTS: val = &prd->sendemail; break;
  145. case METRICS_GENDER: val = &prd->sex; break;
  146. }
  147. }
  148. if (str)
  149. {
  150. int len;
  151. const wchar_t *val = (const wchar_t*)pVal;
  152. if (!*val) { *str = 0x00; return TRUE; }
  153. len = WideCharToMultiByte(CP_ACP, 0, val, (-1 == cbVal) ? -1 : cbVal/sizeof(wchar_t), str, maxLen, NULL, NULL);
  154. if (len && len < maxLen) str[len] = 0x00;
  155. return (len);
  156. }
  157. if (val)
  158. {
  159. *val = *((unsigned char*)pVal);
  160. return TRUE;
  161. }
  162. return FALSE;
  163. }
  164. INT GetMetricsSize(const char *data)
  165. {
  166. reg_data *prd = (reg_data*)data;
  167. if (!prd || (!*prd->email && !*prd->country && !prd->sex && !prd->agegroup && !prd->sendemail)) return 0;
  168. return sizeof(reg_data);
  169. }
  170. BOOL SendMetrics(const char *data, HWND hwndParent)
  171. {
  172. BOOL result;
  173. reg_data *prd = (reg_data*)data;
  174. char buf1[512] = {0}, buf2[512] = {0}, _old_obj[256] = {0};
  175. char urlbuf[8192] = {0};
  176. size_t urlsize = sizeof(urlbuf)/sizeof(*urlbuf);
  177. char *url = urlbuf;
  178. int is_upgrade=!GetPrivateProfileIntW(L"WinampReg",L"IsFirstInst",0,INI_FILE);
  179. if (!prd) return 0;
  180. // fucko: set is_upgrade
  181. StringCchCopyExA(url,urlsize,"http://client.winamp.com/update/do_im.php?", &url, &urlsize, 0);
  182. makeurlcodes(prd->country,buf1);
  183. stats_getuidstr(buf2);
  184. StringCchPrintfExA(url, urlsize, &url, &urlsize, 0, "ID=%s&ZIP=%s",buf2,buf1);
  185. makeurlcodes(prd->email,buf1);
  186. StringCchPrintfExA(url, urlsize, &url, &urlsize, 0, "&EMAIL=%s&ML=%c" /*"&AGE=%d" */ "&SEX=%c&ISUP=%d",buf1,prd->sendemail?'y':'n',
  187. // prd->agegroup,
  188. prd->sex==1 ? 'M' : (prd->sex==2 ? 'F' : 'N' ),
  189. is_upgrade);
  190. CopyMemory(_old_obj, prd->objects, sizeof(_old_obj));
  191. get_objlist(prd->objects);
  192. diff_objs(_old_obj,prd->objects,buf1);
  193. makeurlcodes(buf1,buf2);
  194. StringCchPrintfExA(url, urlsize, &url, &urlsize, 0,"&OBJS=%s",buf2);
  195. StringCchPrintfExA(url, urlsize, &url, &urlsize, 0,"&SKIN=%s",(char *)AutoUrl(config_skin));
  196. wchar_t mlfilename[MAX_PATH] = {0};
  197. PathCombineW(mlfilename, PLUGINDIR, L"gen_ml.dll");
  198. StringCchPrintfExA(url, urlsize, &url, &urlsize, 0,"&MLIB=%d",!_waccess(mlfilename, 0));
  199. StringCchPrintfExA(url, urlsize, &url, &urlsize, 0,"&V=%s",app_version);
  200. DeleteFileW(TEMP_FILE);
  201. result = !httpRetrieveFileW(hwndParent, urlbuf, TEMP_FILE, getStringW(IDS_INST_SENDINGIN,NULL,0));
  202. if (result) WritePrivateProfileStringW(L"WinampReg", L"IsFirstInst", L"0", INI_FILE);
  203. return result;
  204. }