1
0

Main.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. #include "main.h"
  2. #include "../nu/AutoWide.h"
  3. #define LANG_STATIC_BUFFER_SIZE 1024
  4. extern "C" void ResolveEnvironmentVariables2(wchar_t *string, wchar_t *destString, size_t stringSize);
  5. static UINT WM_TASKBARCREATED;
  6. // winamp2/5
  7. wchar_t ini_file[MAX_PATH] = {0},
  8. wa2ConfigDir[MAX_PATH] = {0},
  9. winampClassName[MAX_PATH] = {0},
  10. winampaLngPath[MAX_PATH] = {0},
  11. icon_tmp[MAX_PATH] = {0},
  12. winamp_exe_file[MAX_PATH] = {0},
  13. bm_file[MAX_PATH] = {0};
  14. static HWND hwndWinamp;
  15. static HINSTANCE g_hInstance, winampaLng, nativeLng;
  16. static HICON m_icon;
  17. typedef HRESULT(WINAPI *CHANGEWINDOWMESSAGEFILTER)(UINT message, DWORD dwFlag);
  18. static CHANGEWINDOWMESSAGEFILTER changeWMFilter;
  19. int config_iconidx = -1, config_systray_icon = 1;
  20. static wchar_t ini_sec[] = L"WinampAgent";
  21. int ReadStr(HANDLE hFile, char *str, int len)
  22. {
  23. while (1)
  24. {
  25. DWORD l = 0;
  26. ReadFile(hFile, str, 1, &l, 0);
  27. if (l != 1 || *str == '\r' || *str == '\n')
  28. {
  29. DWORD t = 0;
  30. ReadFile(hFile, str, 1, &t, 0);
  31. *str = 0;
  32. return (l == 1);
  33. }
  34. str++;
  35. if (--len < 1)
  36. {
  37. *str = 0;
  38. return 1;
  39. }
  40. }
  41. }
  42. static BOOL LoadWMFilter(void){
  43. if (!changeWMFilter){
  44. changeWMFilter = (CHANGEWINDOWMESSAGEFILTER)GetProcAddress(GetModuleHandle(L"USER32"), "ChangeWindowMessageFilter");
  45. }
  46. return (!!changeWMFilter);
  47. }
  48. void LoadWinampaLng(void){
  49. winampaLng = LoadLibraryExW(winampaLngPath, NULL, LOAD_LIBRARY_AS_DATAFILE);
  50. }
  51. void UnloadWinampaLng(void){
  52. if(winampaLng){
  53. FreeLibrary(winampaLng);
  54. winampaLng = 0;
  55. }
  56. }
  57. wchar_t* GetStringW(UINT uID)
  58. {
  59. static wchar_t *buf;
  60. if (!buf)
  61. buf = (wchar_t *)GlobalAlloc(LPTR,(LANG_STATIC_BUFFER_SIZE*sizeof(buf[0])));
  62. if (!LoadStringW(winampaLng, uID, buf, LANG_STATIC_BUFFER_SIZE))
  63. {
  64. if (winampaLng == nativeLng || !LoadStringW(nativeLng, uID, buf, LANG_STATIC_BUFFER_SIZE))
  65. {
  66. lstrcpynW(buf, L"Error loading string", LANG_STATIC_BUFFER_SIZE);
  67. }
  68. }
  69. return buf;
  70. }
  71. // about the most reliable way i can find to get the Winamp window as it could
  72. // have been started with the /CLASS= parameter which then means it won't be
  73. // 'Winamp v1.x' so instead go for a fixed child window which will always be
  74. // there (and deals with other apps who create a 'fake' Winamp window (like AIMP)
  75. // and there are two versions to cope with classic or modern skins being used.
  76. BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
  77. {
  78. wchar_t name[24] = {0};
  79. GetClassNameW(hwnd, name, 24);
  80. // this check will only work for classic skins
  81. if (!lstrcmpiW(name, L"Winamp PE"))
  82. {
  83. HWND child = GetWindow(GetWindow(hwnd, GW_CHILD), GW_CHILD);
  84. GetClassNameW(child, name, 24);
  85. // this check improves reliability of this check against players
  86. // like KMPlayer which also create a fake playlist editor window
  87. if (!lstrcmpiW(name, L"WinampVis") || lstrcmpiW(name, L"TSkinPanel"))
  88. {
  89. hwndWinamp = GetWindow(hwnd, GW_OWNER);
  90. return FALSE;
  91. }
  92. }
  93. // this check will only work for modern skins
  94. else if (!lstrcmpiW(name, L"BaseWindow_RootWnd"))
  95. {
  96. HWND child = GetWindow(GetWindow(hwnd,GW_CHILD),GW_CHILD);
  97. GetClassNameW(child, name, 24);
  98. if (!lstrcmpiW(name, L"Winamp PE") ||
  99. !lstrcmpiW(name, L"Winamp Gen"))
  100. {
  101. hwndWinamp = GetWindow(hwnd,GW_OWNER);
  102. return FALSE;
  103. }
  104. }
  105. // and then we just try what we can (default and
  106. // taking into account where possible /CLASS use
  107. else if (!lstrcmpiW(name, L"Winamp v1.x") ||
  108. !lstrcmpiW(name, winampClassName))
  109. {
  110. HWND child = GetWindow(hwnd,GW_CHILD);
  111. GetClassNameW(child, name, 24);
  112. if (!lstrcmpiW(name, L"WinampVis"))
  113. {
  114. hwndWinamp = hwnd;
  115. return FALSE;
  116. }
  117. }
  118. return TRUE;
  119. }
  120. HWND GetWinampHWND(void)
  121. {
  122. // incase things changed since last time, always re-check
  123. hwndWinamp = 0;
  124. EnumWindows(EnumWindowsProc, 0);
  125. return hwndWinamp;
  126. }
  127. LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  128. {
  129. int force_icon = 0;
  130. if (WM_TASKBARCREATED && uMsg == WM_TASKBARCREATED)
  131. {
  132. uMsg = WM_USER + 1;
  133. force_icon = 1;
  134. }
  135. switch (uMsg)
  136. {
  137. case WM_CREATE:
  138. SendMessage(hwnd, WM_USER + 1, 0, 0);
  139. return TRUE;
  140. case WM_USER + 1:
  141. {
  142. int iconidx;
  143. int isintray;
  144. config_systray_icon = ini_file[0] ? GetPrivateProfileIntW(ini_sec, L"is_intray", 1, ini_file) : 0;
  145. iconidx = ini_file[0] ? GetPrivateProfileIntW(L"Winamp", L"sticon", 0, ini_file) : 0;
  146. isintray = !!systray_isintray();
  147. if ((isintray && (force_icon || iconidx != config_iconidx)) ||
  148. isintray != (config_systray_icon))
  149. {
  150. HICON m_oldicon = m_icon;
  151. m_icon = 0;
  152. if (config_systray_icon)
  153. {
  154. if (iconidx != 0)
  155. {
  156. HMODULE h = LoadLibraryExW(winamp_exe_file, NULL, LOAD_LIBRARY_AS_DATAFILE);
  157. if (h)
  158. {
  159. int geticonid(int x); // in winampicon.cpp
  160. int icon_to_use = geticonid(iconidx);
  161. if(icon_to_use != -666)
  162. {
  163. m_icon = (HICON)LoadImage(h,MAKEINTRESOURCE(icon_to_use),IMAGE_ICON,16,16,0);
  164. }
  165. else
  166. {
  167. if(PathFileExistsW(icon_tmp))
  168. {
  169. m_icon = (HICON)LoadImageW(0,icon_tmp,IMAGE_ICON,16,16,LR_LOADFROMFILE);
  170. }
  171. }
  172. FreeLibrary(h);
  173. }
  174. }
  175. if (!m_icon) m_icon = (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 16, 16, 0);
  176. if (isintray) systray_mod(hwnd, m_icon, 0);
  177. systray_add(hwnd, m_icon, GetStringW(IDS_WINAMP_AGENT));
  178. }
  179. else systray_del(hwnd);
  180. if (m_oldicon) DestroyIcon(m_oldicon);
  181. }
  182. config_iconidx = iconidx;
  183. }
  184. return 0;
  185. case WM_CLOSE:
  186. DestroyWindow(hwnd);
  187. return 0;
  188. case WM_ENDSESSION: // JF JAN01001 added
  189. if (wParam)
  190. {
  191. ExitProcess(0);
  192. return 0;
  193. }
  194. break;
  195. case WM_USER + 8:
  196. if (LOWORD(lParam) == WM_MOUSEMOVE)
  197. {
  198. static DWORD last_t;
  199. if (GetTickCount() - last_t > 250)
  200. {
  201. last_t = GetTickCount();
  202. HWND hwnd2 = GetWinampHWND();
  203. if (IsWindow(hwnd2))
  204. {
  205. wchar_t buf[128] = {0};
  206. GetWindowTextW(hwnd2, buf, 128);
  207. systray_mod(hwnd, 0, buf);
  208. }
  209. else
  210. {
  211. systray_mod(hwnd, 0, GetStringW(IDS_WINAMP_AGENT));
  212. }
  213. }
  214. }
  215. else if (LOWORD(lParam) == WM_LBUTTONUP ||
  216. LOWORD(lParam) == WM_LBUTTONDBLCLK)
  217. {
  218. if(!(GetAsyncKeyState(VK_SHIFT)&0x8000))
  219. {
  220. HWND hwnd2 = GetWinampHWND();
  221. if (IsWindow(hwnd2))
  222. {
  223. if (LOWORD(lParam) == WM_LBUTTONDBLCLK)
  224. {
  225. ShowWindow(hwnd2, SW_RESTORE);
  226. }
  227. SetForegroundWindow(hwnd2);
  228. SendMessage(hwnd2, WM_USER + 1, 0, WM_LBUTTONUP);
  229. }
  230. else
  231. {
  232. ShellExecuteW(NULL, L"open", winamp_exe_file, L"", L".", SW_SHOW);
  233. }
  234. }
  235. else
  236. {
  237. SendMessage(hwnd, WM_CLOSE, 0, 0);
  238. }
  239. }
  240. else if (LOWORD(lParam) == WM_RBUTTONUP)
  241. {
  242. HWND hwnd2 = GetWinampHWND();
  243. if (IsWindow(hwnd2) && !(GetAsyncKeyState(VK_CONTROL)&0x8000))
  244. {
  245. SetForegroundWindow(hwnd2);
  246. SendMessage(hwnd2, WM_USER + 1, 0, WM_RBUTTONUP);
  247. }
  248. else
  249. {
  250. HMENU hMenu = CreatePopupMenu();
  251. MENUITEMINFOW i = {0};
  252. // for bookmarks menu
  253. int num_bookmarks = 0;
  254. // for audio cd entries
  255. wchar_t g_audiocdletter[4] = {0};
  256. int g_audiocdletters = 0;
  257. int drivemask = 0;
  258. DWORD drives = GetLogicalDrives();
  259. char fn[1024] = {0};
  260. char ft[1024] = {0};
  261. POINT p = {0};
  262. GetCursorPos(&p);
  263. i.cbSize = sizeof(i);
  264. i.fMask = MIIM_TYPE | MIIM_DATA | MIIM_ID;
  265. i.fType = MFT_STRING;
  266. i.wID = 1;
  267. i.dwTypeData = GetStringW(IDS_OPEN_WINAMP);
  268. i.cch = lstrlenW((wchar_t*)i.dwTypeData);
  269. InsertMenuItemW(hMenu, 0, TRUE, &i);
  270. i.wID = 0;
  271. i.fType = MFT_SEPARATOR;
  272. InsertMenuItemW(hMenu, 1, TRUE, &i);
  273. i.fMask = MIIM_TYPE | MIIM_DATA | MIIM_ID;
  274. i.fType = MFT_STRING;
  275. i.wID = 2;
  276. i.dwTypeData = GetStringW(IDS_DISABLE_WINAMP_AGENT);
  277. i.cch = lstrlenW((wchar_t*)i.dwTypeData);
  278. InsertMenuItemW(hMenu, 2, TRUE, &i);
  279. i.wID = 3;
  280. i.dwTypeData = GetStringW(IDS_CLOSE_WINAMP_AGENT);
  281. i.cch = lstrlenW((wchar_t*)i.dwTypeData);
  282. InsertMenuItemW(hMenu, 3, TRUE, &i);
  283. SetMenuDefaultItem(hMenu,!(GetAsyncKeyState(VK_SHIFT)&0x8000)?0:3,1);
  284. i.wID = 0;
  285. i.fType = MFT_SEPARATOR;
  286. InsertMenuItemW(hMenu, 4, TRUE, &i);
  287. i.wID = 10;
  288. for (drivemask = 0; drivemask < 32; drivemask++)
  289. {
  290. if (drives&(1 << drivemask))
  291. {
  292. wchar_t str[256] = {0};
  293. StringCchPrintfW(str, 256, L"%c:\\", 'A' + drivemask);
  294. if (GetDriveTypeW(str) == DRIVE_CDROM)
  295. {
  296. int old_error_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
  297. DWORD system_flags = 0, max_file_len = 0;
  298. wchar_t drives[4] = {L" :\\"}, c = L'A' + drivemask, vol_buf[40] = {0}, empty[64] = {0};
  299. drives[0] = g_audiocdletter[g_audiocdletters] = c;
  300. GetVolumeInformationW(drives,vol_buf,sizeof(vol_buf),0,&max_file_len,&system_flags,0,0);
  301. SetErrorMode(old_error_mode);
  302. lstrcpynW(empty,GetStringW(IDS_EMPTY),64);
  303. StringCchPrintfW(str, 256, GetStringW(IDS_AUDIO_CD),c,(vol_buf[0]?vol_buf:empty));
  304. i.fType = MFT_STRING;
  305. i.dwTypeData = str;
  306. i.cch = (UINT)wcslen(str);
  307. InsertMenuItemW(hMenu, 5 + g_audiocdletters, TRUE, &i);
  308. i.wID++;
  309. g_audiocdletters++;
  310. if (g_audiocdletters == 4) break;
  311. }
  312. }
  313. }
  314. if(g_audiocdletters)
  315. {
  316. i.wID = 0;
  317. i.fType = MFT_SEPARATOR;
  318. InsertMenuItemW(hMenu, 5 + g_audiocdletters, TRUE, &i);
  319. }
  320. i.fType = MFT_STRING;
  321. i.dwTypeData = GetStringW(IDS_BOOKMARKS);
  322. i.cch = lstrlenW((wchar_t*)i.dwTypeData);
  323. HMENU sm = i.hSubMenu = CreatePopupMenu();
  324. i.fMask |= MIIM_SUBMENU;
  325. i.wID = 0;
  326. InsertMenuItemW(hMenu, 6 + g_audiocdletters, TRUE, &i);
  327. // have to keep this ansi since winamp.bm doesn't support unicode
  328. HANDLE hFile = CreateFileW(bm_file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  329. if (hFile != INVALID_HANDLE_VALUE)
  330. {
  331. MENUITEMINFOW ib = {0};
  332. ib.cbSize = sizeof(ib);
  333. ib.fMask = MIIM_TYPE | MIIM_DATA | MIIM_ID;
  334. ib.fType = MFT_STRING;
  335. i.wID = ib.wID = 20;
  336. while (1)
  337. {
  338. if (!ReadStr(hFile, fn, MAX_PATH)) break;
  339. if (!ReadStr(hFile, ft, 2048)) break;
  340. ib.dwTypeData = AutoWideDup(ft, CP_UTF8);
  341. ib.cch = lstrlenW(ib.dwTypeData);
  342. InsertMenuItemW(sm, num_bookmarks, TRUE, &ib);
  343. ib.wID++;
  344. i.wID++;
  345. num_bookmarks++;
  346. }
  347. }
  348. if(i.wID == 20 || !i.wID)
  349. {
  350. i.fMask = MIIM_TYPE | MIIM_DATA | MIIM_ID;
  351. i.fType = MFT_STRING;
  352. i.dwTypeData = GetStringW(IDS_NO_BOOKMARKS_FOUND);
  353. i.cch = lstrlenW((wchar_t*)i.dwTypeData);
  354. InsertMenuItemW(sm, num_bookmarks, TRUE, &i);
  355. EnableMenuItem(sm, i.wID, MF_BYCOMMAND | MF_GRAYED);
  356. }
  357. SetForegroundWindow(hwnd);
  358. int x = TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_RIGHTBUTTON | TPM_LEFTBUTTON | TPM_NONOTIFY, p.x, p.y, 0, hwnd, NULL);
  359. if (x == 1)
  360. {
  361. HWND hwnd2 = GetWinampHWND();
  362. if (IsWindow(hwnd2))
  363. {
  364. SetForegroundWindow(hwnd2);
  365. SendMessage(hwnd2, WM_USER + 1, 0, WM_LBUTTONUP);
  366. }
  367. else
  368. {
  369. ShellExecuteW(NULL, L"open", winamp_exe_file, L"", L".", SW_SHOW);
  370. }
  371. }
  372. else if (x == 2 || x == 3)
  373. {
  374. if (x == 2) // disable
  375. {
  376. HKEY key;
  377. if (RegOpenKeyW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", &key) == ERROR_SUCCESS)
  378. {
  379. RegDeleteValueW(key, L"WinampAgent");
  380. RegCloseKey(key);
  381. }
  382. }
  383. SendMessage(hwnd, WM_CLOSE, 0, 0);
  384. }
  385. else if(x >= 10 && x < 10 + g_audiocdletters)
  386. {
  387. wchar_t ftW[1024] = {0};
  388. StringCchPrintfW(ftW, 1024, L"\"cda://%c\"", g_audiocdletter[x - 10]);
  389. ShellExecuteW(NULL, L"open", winamp_exe_file, ftW, L".", SW_SHOW);
  390. }
  391. else if (x >= 20 && x < 20 + num_bookmarks && hFile != INVALID_HANDLE_VALUE)
  392. {
  393. int r = 0;
  394. x -= 20;
  395. SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
  396. for (; r <= x; r ++)
  397. {
  398. if (!ReadStr(hFile, fn, MAX_PATH)) break;
  399. if (!ReadStr(hFile, ft, 2048)) break;
  400. }
  401. if (r == (x + 1))
  402. {
  403. wchar_t ftW[1024] = {0};
  404. StringCchPrintfW(ftW, 1024, L"\"%s\"", AutoWide(fn, CP_UTF8));
  405. ShellExecuteW(NULL, L"open", winamp_exe_file, ftW, L".", SW_SHOW);
  406. }
  407. }
  408. DestroyMenu(hMenu);
  409. if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
  410. }
  411. }
  412. return 0;
  413. case WM_USER + 16:
  414. // do this on load/unload requests just incase something went wrong
  415. UnloadWinampaLng();
  416. if(!wParam) LoadWinampaLng();
  417. return 0;
  418. case WM_DESTROY:
  419. if (systray_isintray()) systray_del(hwnd);
  420. PostQuitMessage(0);
  421. return 0;
  422. }
  423. return DefWindowProc(hwnd, uMsg, wParam, lParam);
  424. }
  425. static wchar_t szClassName[] = L"WinampAgentMain";
  426. static wchar_t szErrorTitle[] = L"Winamp Agent Error";
  427. void queryPath(wchar_t *out, wchar_t *in, int out_len)
  428. {
  429. wchar_t buf[MAX_PATH] = {0};
  430. HKEY key = 0;
  431. if (RegOpenKeyW(HKEY_CLASSES_ROOT, in, &key) == ERROR_SUCCESS)
  432. {
  433. DWORD s = sizeof(buf);
  434. if (RegQueryValueExW(key, NULL, 0, NULL, (LPBYTE)buf, &s) == ERROR_SUCCESS)
  435. {
  436. if (buf[0] == L'\"')
  437. {
  438. wchar_t *p = buf + 1;
  439. while (p && *p != L'\"' && *p) p=CharNextW(p);
  440. if (p && *p) *p = 0;
  441. while (p > buf && *p != L'\\') p = CharPrevW(buf,p);
  442. if (p && *p) *p = 0;
  443. lstrcpynW(out, buf + 1, out_len);
  444. }
  445. else
  446. {
  447. wchar_t *p = buf;
  448. while (p && *p) p=CharNextW(p);
  449. while (p > buf && *p != L'\\') p = CharPrevW(buf,p);
  450. if (p && *p) *p = 0;
  451. lstrcpynW(out, buf, out_len);
  452. }
  453. }
  454. RegCloseKey(key);
  455. }
  456. }
  457. void BuildDirectories()
  458. {
  459. // get ini_file from reg
  460. wchar_t winamp2Folder[MAX_PATH] = {0};
  461. // attempt to get the winamp folder from the play then the enqueue and then just revert to current folder (wa2/5)
  462. queryPath(winamp2Folder, L"Winamp.File\\shell\\play\\command", MAX_PATH);
  463. if(!winamp2Folder[0]) queryPath(winamp2Folder, L"Winamp.File\\shell\\enqueue\\command", MAX_PATH);
  464. if(!winamp2Folder[0])
  465. {
  466. wchar_t buf[MAX_PATH] = {0}, *p = buf;
  467. GetModuleFileNameW(GetModuleHandleW(NULL), buf, sizeof(buf));
  468. while (p && *p) p=CharNextW(p);
  469. while (p > buf && *p != L'\\') p=CharPrevW(buf,p);
  470. if (p && *p) *p = 0;
  471. lstrcpynW(winamp2Folder, buf, sizeof(winamp2Folder));
  472. }
  473. if (winamp2Folder[0]) // wa2/5
  474. {
  475. wchar_t pathsIni[MAX_PATH] = {0};
  476. wchar_t iniFileName[MAX_PATH] = {0};
  477. wchar_t profileString[MAX_PATH] = {0};
  478. StringCchPrintfW(pathsIni, MAX_PATH, L"%s\\paths.ini", winamp2Folder);
  479. GetPrivateProfileStringW(L"Winamp", L"inidir", L"", profileString, MAX_PATH, pathsIni);
  480. if (profileString[0])
  481. ResolveEnvironmentVariables2(profileString, wa2ConfigDir, MAX_PATH);
  482. else
  483. lstrcpynW(wa2ConfigDir, winamp2Folder, MAX_PATH);
  484. GetPrivateProfileStringW(L"Winamp", L"class", L"", profileString, MAX_PATH, pathsIni);
  485. if (profileString[0])
  486. ResolveEnvironmentVariables2(profileString, winampClassName, MAX_PATH);
  487. GetPrivateProfileStringW(L"Winamp", L"inifile", L"", profileString, MAX_PATH, pathsIni);
  488. if (profileString[0])
  489. ResolveEnvironmentVariables2(profileString, iniFileName, MAX_PATH);
  490. else
  491. lstrcpynW(iniFileName, L"winamp.ini", MAX_PATH);
  492. StringCchPrintfW(ini_file, MAX_PATH, L"%s\\%s", wa2ConfigDir, iniFileName);
  493. // winamp.exe should extract this out for us when a new wlz is loaded so we
  494. // don't have to bloat up winampa - just have to deal with wlz changes instead
  495. StringCchPrintfW(winampaLngPath, MAX_PATH, L"%s\\winampa.lng", wa2ConfigDir);
  496. StringCchPrintfW(icon_tmp, MAX_PATH, L"%s\\winamp.ico", wa2ConfigDir);
  497. StringCchPrintfW(winamp_exe_file, MAX_PATH, L"%s\\winamp.exe", winamp2Folder);
  498. StringCchPrintfW(bm_file, MAX_PATH, L"%s\\winamp.bm8", wa2ConfigDir);
  499. // just make sure if a winamp.bm8 doesn't exist then
  500. // go make one from winamp.bm - implemented for 5.58+
  501. if(!PathFileExistsW(bm_file))
  502. {
  503. wchar_t tmp[MAX_PATH] = {0};
  504. StringCchPrintfW(tmp, MAX_PATH, L"%s\\winamp.bm", wa2ConfigDir);
  505. CopyFileW(tmp,bm_file,FALSE);
  506. }
  507. }
  508. if (!winampClassName[0])
  509. lstrcpynW(winampClassName, L"Winamp v1.x", MAX_PATH);
  510. }
  511. int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  512. {
  513. MSG msg = {0};
  514. static WNDCLASSW wc;
  515. if (FindWindowW(szClassName, NULL))
  516. {
  517. ExitProcess(0);
  518. }
  519. WM_TASKBARCREATED = RegisterWindowMessageW(L"TaskbarCreated");
  520. // add in a UIPI filter so we can get required notifications from winamp.exe such
  521. // as when we're started from an elevation request e.g. via prefs dialog options.
  522. if (LoadWMFilter()){
  523. changeWMFilter(WM_USER+1, 1/*MSGFLT_ADD*/);
  524. changeWMFilter(WM_USER+16, 1/*MSGFLT_ADD*/);
  525. }
  526. wc.lpfnWndProc = WndProc;
  527. g_hInstance = wc.hInstance = GetModuleHandleW(NULL);
  528. wc.lpszClassName = szClassName;
  529. BuildDirectories();
  530. // attempt to load winampa.lng if present (if extracted from the current wlz if there is one)
  531. nativeLng = hInstance;
  532. LoadWinampaLng();
  533. if (!RegisterClassW(&wc))
  534. {
  535. MessageBoxW(NULL, L"Cannot register window class!", szErrorTitle, MB_OK | MB_ICONSTOP);
  536. return 0;
  537. }
  538. if (!(CreateWindowExW(WS_EX_TOPMOST | WS_EX_TOOLWINDOW, szClassName, L"", 0,
  539. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  540. NULL, NULL, g_hInstance, NULL)))
  541. {
  542. MessageBoxW(NULL, L"Cannot create window!", szErrorTitle, MB_OK | MB_ICONSTOP);
  543. return 0;
  544. }
  545. while (GetMessageW(&msg, NULL, 0, 0))
  546. {
  547. DispatchMessageW(&msg);
  548. } // while(GetMessage...
  549. UnloadWinampaLng();
  550. ExitProcess(0);
  551. return 0;
  552. }
  553. #ifdef DO_LOG
  554. void do_log_print(char *p)
  555. {
  556. HANDLE h = CreateFile("C:\\winampa.log", GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL);
  557. if (h != INVALID_HANDLE_VALUE)
  558. {
  559. DWORD l = 0;
  560. SetFilePointer(h, 0, NULL, FILE_END);
  561. WriteFile(h, p, lstrlen(p), &l, NULL);
  562. CloseHandle(h);
  563. }
  564. }
  565. #endif