diff options
author | Alex Bennee <alex@bennee.com> | 2010-07-14 15:57:06 +0100 |
---|---|---|
committer | Alex Bennee <alex@bennee.com> | 2010-07-14 15:57:06 +0100 |
commit | ba15707b292d827bdce732e7713b26fae3f75c74 (patch) | |
tree | 8159d5daa4588ade1e71b9cb8541d6438c6b80c6 /src/win32 |
EasyTag 2.1.1
Diffstat (limited to 'src/win32')
-rwxr-xr-x | src/win32/easytag.rc | 4 | ||||
-rwxr-xr-x | src/win32/resource.h | 1 | ||||
-rwxr-xr-x | src/win32/win32dep.c | 493 | ||||
-rwxr-xr-x | src/win32/win32dep.h | 84 | ||||
-rwxr-xr-x | src/win32/win_easytag.c | 557 |
5 files changed, 1139 insertions, 0 deletions
diff --git a/src/win32/easytag.rc b/src/win32/easytag.rc new file mode 100755 index 0000000..cd8fd58 --- /dev/null +++ b/src/win32/easytag.rc @@ -0,0 +1,4 @@ +#include "resource.h" + +EASYTAG_ICON ICON "../pixmaps/easytag.ico" + diff --git a/src/win32/resource.h b/src/win32/resource.h new file mode 100755 index 0000000..4cd30ad --- /dev/null +++ b/src/win32/resource.h @@ -0,0 +1 @@ +#define EASYTAG_ICON 109 diff --git a/src/win32/win32dep.c b/src/win32/win32dep.c new file mode 100755 index 0000000..a644adc --- /dev/null +++ b/src/win32/win32dep.c @@ -0,0 +1,493 @@ +/* + * easytag + * + * File: win32dep.c + * Date: June, 2002 + * Description: Windows dependant code for Easytag + * this code if largely taken from win32 gaim + * + * Copyright (C) 2002-2003, Herman Bloggs <hermanator12002@yahoo.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include <windows.h> +#include <io.h> +#include <stdlib.h> +#include <stdio.h> +#include <winuser.h> +#include <shlobj.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/timeb.h> + +#include <gtk/gtk.h> +#include <glib.h> +#if GLIB_CHECK_VERSION(2,6,0) +# include <glib/gstdio.h> +#else +# define g_fopen fopen +# define g_unlink unlink +#endif +#include <gdk/gdkwin32.h> + +#include "resource.h" +//#include "../log.h" + +#include <libintl.h> + +#include "win32dep.h" + +/* + * DEFINES & MACROS + */ +#define _(x) gettext(x) + + +/* + * DATA STRUCTS + */ + +/* For shfolder.dll */ +typedef HRESULT (CALLBACK* LPFNSHGETFOLDERPATHA)(HWND, int, HANDLE, DWORD, LPSTR); +typedef HRESULT (CALLBACK* LPFNSHGETFOLDERPATHW)(HWND, int, HANDLE, DWORD, LPWSTR); + +typedef enum +{ + SHGFP_TYPE_CURRENT = 0, // current value for user, verify it exists + SHGFP_TYPE_DEFAULT = 1, // default value, may not exist +} SHGFP_TYPE; + +/* + * LOCALS + */ +static char app_data_dir[MAX_PATH + 1] = "C:"; +static char install_dir[MAXPATHLEN]; +static char locale_dir[MAXPATHLEN]; + +static void str_replace_char (gchar *str, gchar in_char, gchar out_char); + +/* + * GLOBALS + */ +HINSTANCE ET_exe_hInstance = 0; +HINSTANCE ET_dll_hInstance = 0; + +/* + * PROTOS + */ +LPFNSHGETFOLDERPATHA MySHGetFolderPathA = NULL; +LPFNSHGETFOLDERPATHW MySHGetFolderPathW = NULL; + +FARPROC ET_Win32_Find_And_Loadproc (char*, char*); +char* ET_Win32_Data_Dir (void); + + +/* + * PUBLIC CODE + */ + +HINSTANCE ET_Win32_Hinstance (void) +{ + return ET_exe_hInstance; +} + +/* Escape windows dir separators. This is needed when paths are saved, + and on being read back have their '\' chars used as an escape char. + Returns an allocated string which needs to be freed. +*/ +char* ET_Win32_Escape_Dirsep (char* filename ) +{ + int sepcount=0; + char* ret=NULL; + int cnt=0; + + ret = filename; + while(*ret) + { + if(*ret == '\\') + sepcount++; + ret++; + } + ret = g_malloc0(strlen(filename) + sepcount + 1); + while(*filename) + { + ret[cnt] = *filename; + if(*filename == '\\') + ret[++cnt] = '\\'; + filename++; + cnt++; + } + ret[cnt] = '\0'; + return ret; +} + +/* this is used by libmp4v2 : what is it doing here you think ? well...search! */ +int gettimeofday (struct timeval *t, void *foo) +{ + struct _timeb temp; + + if (t != 0) { + _ftime(&temp); + t->tv_sec = temp.time; /* seconds since 1-1-1970 */ + t->tv_usec = temp.millitm * 1000; /* microseconds */ + } + return (0); +} + + +/* emulate the unix function */ +int mkstemp (char *template) +{ + int fd = -1; + + char *str = mktemp(template); + if(str != NULL) + { + fd = open(str, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + } + + return fd; +} + +/* Determine whether the specified dll contains the specified procedure. + If so, load it (if not already loaded). */ +FARPROC ET_Win32_Find_And_Loadproc ( char* dllname, char* procedure ) +{ + HMODULE hmod; + int did_load=0; + FARPROC proc = 0; + + if(!(hmod=GetModuleHandle(dllname))) + { + //Log_Print(_("DLL '%s' not found. Try loading it..."), dllname); + g_printf(_("DLL '%s' not found. Try loading it..."), dllname); + g_print("\n"); + if(!(hmod = LoadLibrary(dllname))) + { + //Log_Print(_("DLL '%s' could not be loaded"), dllname); + g_print(_("DLL '%s' could not be loaded"), dllname); + g_print("\n"); + return NULL; + } + else + did_load = TRUE; + } + + if((proc=GetProcAddress(hmod, procedure))) + { + //Log_Print(_("This version of '%s' contains '%s'"), dllname, procedure); + g_print(_("This version of '%s' contains '%s'"), dllname, procedure); + g_print("\n"); + return proc; + } + else + { + //Log_Print(_("Function '%s' not found in dll '%s'"), procedure, dllname); + g_print(_("Function '%s' not found in dll '%s'"), procedure, dllname); + g_print("\n"); + if(did_load) + { + /* unload dll */ + FreeLibrary(hmod); + } + return NULL; + } +} + +/* Determine Easytag Paths during Runtime */ + +char* ET_Win32_Install_Dir (void) +{ + HMODULE hmod; + char* buf; + + hmod = GetModuleHandle(NULL); + if ( hmod == 0 ) + { + buf = g_win32_error_message( GetLastError() ); + //Log_Print("GetModuleHandle error: %s\n", buf); + g_print("GetModuleHandle error: %s\n", buf); + g_free(buf); + return NULL; + } + if (GetModuleFileName( hmod, (char*)&install_dir, MAXPATHLEN ) == 0) + { + buf = g_win32_error_message( GetLastError() ); + //Log_Print("GetModuleFileName error: %s\n", buf); + g_print("GetModuleFileName error: %s\n", buf); + g_free(buf); + return NULL; + } + buf = g_path_get_dirname( install_dir ); + strcpy( (char*)&install_dir, buf ); + g_free( buf ); + + return (char*)&install_dir; +} + + +char* ET_Win32_Locale_Dir (void) +{ + strcpy(locale_dir, ET_Win32_Install_Dir()); + g_strlcat(locale_dir, G_DIR_SEPARATOR_S "locale", sizeof(locale_dir)); + return (char*)&locale_dir; +} + +char* ET_Win32_Data_Dir (void) +{ + return (char*)&app_data_dir; +} + + +/* Miscellaneous */ + +gboolean ET_Win32_Read_Reg_String (HKEY key, char* sub_key, char* val_name, LPBYTE data, LPDWORD data_len) +{ + HKEY hkey; + gboolean ret = FALSE; + + if(ERROR_SUCCESS == RegOpenKeyEx(key, sub_key, 0, KEY_QUERY_VALUE, &hkey)) + { + if (ERROR_SUCCESS == RegQueryValueEx(hkey, val_name, 0, NULL, data, data_len)) + ret = TRUE; + RegCloseKey(key); + } + return ret; +} + +/* find a default player executable */ +char* ET_Win32_Get_Audio_File_Player (void) +{ + DWORD len = 256; + char key_value[256]; + + char *player; + + if(ET_Win32_Read_Reg_String(HKEY_CURRENT_USER, "Software\\foobar2000", "InstallDir", key_value, &len)) + { + player = g_strconcat(key_value, "\\foobar2000.exe", NULL); + } + else if(ET_Win32_Read_Reg_String(HKEY_CURRENT_USER, "Software\\Winamp", "", key_value, &len)) + { + player = g_strconcat(key_value, "\\winamp.exe", NULL); + } + else + { + player = g_strdup(""); + } + + //Log_Print(_("Audio player: '%s'"), player); + g_print(_("Audio player: '%s'"), player); + g_print("\n"); + + return player; +} + + +void ET_Win32_Notify_Uri (const char *uri) +{ + SHELLEXECUTEINFO sinfo; + + memset(&sinfo, 0, sizeof(sinfo)); + sinfo.cbSize = sizeof(sinfo); + sinfo.fMask = SEE_MASK_CLASSNAME; + sinfo.lpVerb = "open"; + sinfo.lpFile = uri; + sinfo.nShow = SW_SHOWNORMAL; + sinfo.lpClass = "http"; + + /* We'll allow whatever URI schemes are supported by the + default http browser. + */ + if(!ShellExecuteEx(&sinfo)) + //Log_Print("Error opening URI: %s error: %d\n", uri, (int)sinfo.hInstApp); + g_print("Error opening URI: %s error: %d\n", uri, (int)sinfo.hInstApp); +} + + + +void str_replace_char (gchar *str, gchar in_char, gchar out_char) +{ + while(*str) + { + if(*str == in_char) + *str = out_char; + str++; + } +} + + + +/* Remove trailing '/' if any */ +void ET_Win32_Path_Remove_Trailing_Slash (gchar *path) +{ + int path_len = strlen(path); + + if(path_len > 3 && path[path_len - 1] == '/') + { + path[path_len - 1] = '\0'; + } +} + +/* Remove trailing '\' if any, but not when 'C:\' */ +void ET_Win32_Path_Remove_Trailing_Backslash (gchar *path) +{ + int path_len = strlen(path); + + if(path_len > 3 && path[path_len - 1] == '\\') + { + path[path_len - 1] = '\0'; + } +} + +void ET_Win32_Path_Replace_Backslashes (gchar *path) +{ + str_replace_char(path, '\\', '/'); +} + +void ET_Win32_Path_Replace_Slashes (gchar *path) +{ + str_replace_char(path, '/', '\\'); +} + +void ET_Win32_Init (HINSTANCE hint) +{ + WORD wVersionRequested; + WSADATA wsaData; + char *newenv; + + ET_exe_hInstance = hint; + + /* Winsock init */ + wVersionRequested = MAKEWORD( 2, 2 ); + WSAStartup( wVersionRequested, &wsaData ); + + /* Confirm that the winsock DLL supports 2.2 */ + /* Note that if the DLL supports versions greater than + 2.2 in addition to 2.2, it will still return 2.2 in + wVersion since that is the version we requested. */ + if ( LOBYTE( wsaData.wVersion ) != 2 + || HIBYTE( wsaData.wVersion ) != 2 ) + { + g_print("Could not find a usable WinSock DLL. Oh well.\n"); + WSACleanup(); + } + + /* Set app data dir, used by easytag_home_dir */ + newenv = (char*)g_getenv("EASYTAGHOME"); + if(!newenv) + { +#if GLIB_CHECK_VERSION(2,6,0) + if ((MySHGetFolderPathW = (LPFNSHGETFOLDERPATHW) ET_Win32_Find_And_Loadproc("shfolder.dll", "SHGetFolderPathW"))) + { + wchar_t utf_16_dir[MAX_PATH +1]; + char *temp; + MySHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, + SHGFP_TYPE_CURRENT, utf_16_dir); + temp = g_utf16_to_utf8(utf_16_dir, -1, NULL, NULL, NULL); + g_strlcpy(app_data_dir, temp, sizeof(app_data_dir)); + g_free(temp); + } else if ((MySHGetFolderPathA = (LPFNSHGETFOLDERPATHA) ET_Win32_Find_And_Loadproc("shfolder.dll", "SHGetFolderPathA"))) + { + char locale_dir[MAX_PATH + 1]; + char *temp; + MySHGetFolderPathA(NULL, CSIDL_APPDATA, NULL, + SHGFP_TYPE_CURRENT, locale_dir); + temp = g_locale_to_utf8(locale_dir, -1, NULL, NULL, NULL); + g_strlcpy(app_data_dir, temp, sizeof(app_data_dir)); + g_free(temp); + } +#else + if ((MySHGetFolderPathA = (LPFNSHGETFOLDERPATHA) ET_Win32_Find_And_Loadproc("shfolder.dll", "SHGetFolderPathA"))) + { + MySHGetFolderPathA(NULL, CSIDL_APPDATA, NULL, + SHGFP_TYPE_CURRENT, app_data_dir); + } +#endif + else + { + strcpy(app_data_dir, "C:"); + } + } + else + { + g_strlcpy(app_data_dir, newenv, sizeof(app_data_dir)); + } + + //ET_Win32_Path_Replace_Backslashes(app_data_dir); + + //Log_Print(_("EasyTAG settings dir: '%s'"), app_data_dir); + g_print(_("EasyTAG settings dir: '%s'"), app_data_dir); + g_print("\n"); + + newenv = g_strdup_printf("HOME=%s", app_data_dir); + + if (putenv(newenv)<0) + g_print("putenv failed\n"); + g_free(newenv); + +} + +/* Windows Cleanup */ + +void ET_Win32_Cleanup (void) +{ + /* winsock cleanup */ + WSACleanup(); +} + +/* DLL initializer */ +BOOL WINAPI DllMain ( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) +{ + ET_dll_hInstance = hinstDLL; + return TRUE; +} + + +/* + * Copyright (C) 2002 Manuel Novoa III + * Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#include <string.h> +#include <ctype.h> + +char *strcasestr(const char *s1, const char *s2) +{ + register const char *s = s1; + register const char *p = s2; + + do { + if (!*p) { + return (char *) s1;; + } + if ((*p == *s) + || (tolower(*((unsigned char *)p)) == tolower(*((unsigned char *)s))) + ) { + ++p; + ++s; + } else { + p = s2; + if (!*s) { + return NULL; + } + s = ++s1; + } + } while (1); +}
\ No newline at end of file diff --git a/src/win32/win32dep.h b/src/win32/win32dep.h new file mode 100755 index 0000000..7e5e1ae --- /dev/null +++ b/src/win32/win32dep.h @@ -0,0 +1,84 @@ +/* + * easytag + * + * File: win32dep.h + * + * Copyright (C) 2002-2003, Herman Bloggs <hermanator12002@yahoo.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef _WIN32DEP_H_ +#define _WIN32DEP_H_ + + +#include <winsock2.h> +#include <process.h> +#include <gtk/gtk.h> +#include <gdk/gdkevents.h> + +#define lstat stat +#define mkdir(a,b) mkdir(a) +#define chown(a,b,c) +#define chmod(a,b) + +//#define strcasestr(haystack, needle) strstr(haystack, needle) +char *strcasestr(const char *s1, const char *s2); + + + +/* + * PROTOS + */ + +/** + ** win32dep.c + **/ +/* Windows helper functions */ +extern int mkstemp(char *template); + +extern HINSTANCE ET_Win32_Hinstance (void); +extern gboolean ET_Win32_Read_Reg_String (HKEY key, char* sub_key, char* val_name, LPBYTE data, LPDWORD data_len); +extern char* ET_Win32_Escape_Dirsep (char*); + +/* Determine ET paths */ +extern char* ET_Win32_Install_Dir (void); +extern char* ET_Win32_Locale_Dir (void); +extern char* ET_Win32_Data_Dir (void); + +/* Misc */ +extern char * ET_Win32_Get_Audio_File_Player (void); +extern void ET_Win32_Notify_Uri (const char *uri); + +/* init / cleanup */ +extern void ET_Win32_Init (HINSTANCE); +extern void ET_Win32_Cleanup (void); + +extern void ET_Win32_Path_Remove_Trailing_Slash (gchar *path); +extern void ET_Win32_Path_Remove_Trailing_Backslash (gchar *path); +extern void ET_Win32_Path_Replace_Backslashes (gchar *path); +extern void ET_Win32_Path_Replace_Slashes (gchar *path); + +/* + * MACROS + */ + +/* + * ET specific + */ +#define DATADIR ET_Win32_Install_Dir() +#define LOCALE ET_Win32_Locale_Dir() + +#endif /* _WIN32DEP_H_ */ diff --git a/src/win32/win_easytag.c b/src/win32/win_easytag.c new file mode 100755 index 0000000..cd6628d --- /dev/null +++ b/src/win32/win_easytag.c @@ -0,0 +1,557 @@ +/* + * Code taken from GAIM 2.0.0b5 + * + */ +/* + * win_easytag.c + * + * Date: June, 2002 + * Description: Entry point for win32 easytag, and various win32 dependant + * routines. + * + * EasyTAG is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x501 +#endif +#include <windows.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#define WIN32_PROXY_REGKEY "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" + +/* These will hopefully be in the win32api next time it is updated - at which point, we'll remove them */ +#ifndef LANG_PERSIAN +#define LANG_PERSIAN 0x29 +#endif +#ifndef LANG_BOSNIAN +#define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN 0x05 +#define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC 0x08 +#endif +#ifndef SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN +#define SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN 0x04 +#endif +#ifndef LANG_XHOSA +#define LANG_XHOSA 0x34 +#endif + + +typedef int (CALLBACK* LPFNEASYTAGMAIN)(HINSTANCE, int, char**); +typedef void (CALLBACK* LPFNSETDLLDIRECTORY)(LPCTSTR); +typedef BOOL (CALLBACK* LPFNATTACHCONSOLE)(DWORD); + +/* + * PROTOTYPES + */ +static LPFNEASYTAGMAIN easytag_main = NULL; +static LPFNSETDLLDIRECTORY MySetDllDirectory = NULL; + + +static const char *get_win32_error_message(DWORD err) { + static char err_msg[512]; + + FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &err_msg, sizeof(err_msg), NULL); + + return err_msg; +} + +static BOOL read_reg_string(HKEY key, char* sub_key, char* val_name, LPBYTE data, LPDWORD data_len) { + HKEY hkey; + BOOL ret = FALSE; + LONG retv; + + if (ERROR_SUCCESS == (retv = RegOpenKeyEx(key, sub_key, 0, + KEY_QUERY_VALUE, &hkey))) { + if (ERROR_SUCCESS == (retv = RegQueryValueEx(hkey, val_name, + NULL, NULL, data, data_len))) + ret = TRUE; + else { + const char *err_msg = get_win32_error_message(retv); + + printf("Could not read reg key '%s' subkey '%s' value: '%s'. Message: (%ld) %s\n", + ((key == HKEY_LOCAL_MACHINE) ? "HKLM" : + (key == HKEY_CURRENT_USER) ? "HKCU" : + "???"), + sub_key, val_name, retv, err_msg); + } + RegCloseKey(hkey); + } + else { + TCHAR szBuf[80]; + + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, retv, 0, + (LPTSTR) &szBuf, sizeof(szBuf), NULL); + printf("Could not open reg subkey: '%s'. Error: (%ld) %s\n", + sub_key, retv, szBuf); + } + + return ret; +} + +static void dll_prep() { + char path[MAX_PATH + 1]; + HMODULE hmod; + HKEY hkey; + char gtkpath[MAX_PATH + 1]; + DWORD plen; + + plen = sizeof(gtkpath); + hkey = HKEY_CURRENT_USER; + if (!read_reg_string(hkey, "SOFTWARE\\GTK\\2.0", "Path", + (LPBYTE) >kpath, &plen)) { + hkey = HKEY_LOCAL_MACHINE; + if (!read_reg_string(hkey, "SOFTWARE\\GTK\\2.0", "Path", + (LPBYTE) >kpath, &plen)) { + printf("GTK+ Path Registry Key not found. " + "Assuming GTK+ is in the PATH.\n"); + return; + } + } + + /* this value is replaced during a successful RegQueryValueEx() */ + plen = sizeof(path); + /* Determine GTK+ dll path .. */ + if (!read_reg_string(hkey, "SOFTWARE\\GTK\\2.0", "DllPath", + (LPBYTE) &path, &plen)) { + strcpy(path, gtkpath); + strcat(path, "\\bin"); + } + + printf("GTK+ path found: %s\n", path); + + if ((hmod = GetModuleHandle("kernel32.dll"))) { + MySetDllDirectory = (LPFNSETDLLDIRECTORY) GetProcAddress( + hmod, "SetDllDirectoryA"); + if (!MySetDllDirectory) + printf("SetDllDirectory not supported\n"); + } else + printf("Error getting kernel32.dll module handle\n"); + + /* For Windows XP SP1+ / Server 2003 we use SetDllDirectory to avoid dll hell */ + if (MySetDllDirectory) { + printf("Using SetDllDirectory\n"); + MySetDllDirectory(path); + } + + /* For the rest, we set the current directory and make sure + * SafeDllSearch is set to 0 where needed. */ + else { + OSVERSIONINFO osinfo; + + printf("Setting current directory to GTK+ dll directory\n"); + SetCurrentDirectory(path); + /* For Windows 2000 (SP3+) / WinXP (No SP): + * If SafeDllSearchMode is set to 1, Windows system directories are + * searched for dlls before the current directory. Therefore we set it + * to 0. + */ + osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osinfo); + if ((osinfo.dwMajorVersion == 5 && + osinfo.dwMinorVersion == 0 && + strcmp(osinfo.szCSDVersion, "Service Pack 3") >= 0) || + (osinfo.dwMajorVersion == 5 && + osinfo.dwMinorVersion == 1 && + strcmp(osinfo.szCSDVersion, "") >= 0) + ) { + DWORD regval = 1; + DWORD reglen = sizeof(DWORD); + + printf("Using Win2k (SP3+) / WinXP (No SP)... Checking SafeDllSearch\n"); + read_reg_string(HKEY_LOCAL_MACHINE, + "System\\CurrentControlSet\\Control\\Session Manager", + "SafeDllSearchMode", + (LPBYTE) ®val, + ®len); + + if (regval != 0) { + printf("Trying to set SafeDllSearchMode to 0\n"); + regval = 0; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, + "System\\CurrentControlSet\\Control\\Session Manager", + 0, KEY_SET_VALUE, &hkey + ) == ERROR_SUCCESS) { + if (RegSetValueEx(hkey, + "SafeDllSearchMode", 0, + REG_DWORD, (LPBYTE) ®val, + sizeof(DWORD) + ) != ERROR_SUCCESS) + printf("Error writing SafeDllSearchMode. Error: %u\n", + (UINT) GetLastError()); + RegCloseKey(hkey); + } else + printf("Error opening Session Manager key for writing. Error: %u\n", + (UINT) GetLastError()); + } else + printf("SafeDllSearchMode is set to 0\n"); + }/*end else*/ + } +} + +static char* lcid_to_posix(LCID lcid) { + char *posix = NULL; + int lang_id = PRIMARYLANGID(lcid); + int sub_id = SUBLANGID(lcid); + + switch (lang_id) { + case LANG_ARABIC: posix = "ar"; break; + case LANG_AZERI: posix = "az"; break; + case LANG_BENGALI: posix = "bn"; break; + case LANG_BULGARIAN: posix = "bg"; break; + case LANG_CATALAN: posix = "ca"; break; + case LANG_CHINESE: + switch (sub_id) { + case SUBLANG_CHINESE_SIMPLIFIED: + posix = "zh_CN"; break; + case SUBLANG_CHINESE_TRADITIONAL: + posix = "zh_TW"; break; + default: + posix = "zh"; break; + } + break; + case LANG_CZECH: posix = "cs"; break; + case LANG_DANISH: posix = "da"; break; + case LANG_ESTONIAN: posix = "et"; break; + case LANG_PERSIAN: posix = "fa"; break; + case LANG_GERMAN: posix = "de"; break; + case LANG_GREEK: posix = "el"; break; + case LANG_ENGLISH: + switch (sub_id) { + case SUBLANG_ENGLISH_UK: + posix = "en_GB"; break; + case SUBLANG_ENGLISH_AUS: + posix = "en_AU"; break; + case SUBLANG_ENGLISH_CAN: + posix = "en_CA"; break; + default: + posix = "en"; break; + } + break; + case LANG_SPANISH: posix = "es"; break; + case LANG_BASQUE: posix = "eu"; break; + case LANG_FINNISH: posix = "fi"; break; + case LANG_FRENCH: posix = "fr"; break; + case LANG_GALICIAN: posix = "gl"; break; + case LANG_GUJARATI: posix = "gu"; break; + case LANG_HEBREW: posix = "he"; break; + case LANG_HINDI: posix = "hi"; break; + case LANG_HUNGARIAN: posix = "hu"; break; + case LANG_ICELANDIC: break; + case LANG_ITALIAN: posix = "it"; break; + case LANG_JAPANESE: posix = "ja"; break; + case LANG_GEORGIAN: posix = "ka"; break; + case LANG_KOREAN: posix = "ko"; break; + case LANG_LITHUANIAN: posix = "lt"; break; + case LANG_MACEDONIAN: posix = "mk"; break; + case LANG_DUTCH: posix = "nl"; break; + case LANG_NEPALI: posix = "ne"; break; + case LANG_NORWEGIAN: + switch (sub_id) { + case SUBLANG_NORWEGIAN_BOKMAL: + posix = "nb"; break; + case SUBLANG_NORWEGIAN_NYNORSK: + posix = "nn"; break; + } + break; + case LANG_PUNJABI: posix = "pa"; break; + case LANG_POLISH: posix = "pl"; break; + case LANG_PORTUGUESE: + switch (sub_id) { + case SUBLANG_PORTUGUESE_BRAZILIAN: + posix = "pt_BR"; break; + default: + posix = "pt"; break; + } + break; + case LANG_ROMANIAN: posix = "ro"; break; + case LANG_RUSSIAN: posix = "ru"; break; + /* LANG_CROATIAN == LANG_SERBIAN == LANG_BOSNIAN */ + case LANG_SERBIAN: + switch (sub_id) { + case SUBLANG_SERBIAN_LATIN: + posix = "sr@Latn"; break; + case SUBLANG_SERBIAN_CYRILLIC: + posix = "sr"; break; + case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC: + case SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN: + posix = "bs"; break; + case SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN: + posix = "hr"; break; + } + break; + case LANG_SLOVAK: posix = "sk"; break; + case LANG_SLOVENIAN: posix = "sl"; break; + case LANG_ALBANIAN: posix = "sq"; break; + case LANG_SWEDISH: posix = "sv"; break; + case LANG_TAMIL: posix = "ta"; break; + case LANG_TELUGU: posix = "te"; break; + case LANG_THAI: posix = "th"; break; + case LANG_TURKISH: posix = "tr"; break; + case LANG_UKRAINIAN: posix = "uk"; break; + case LANG_VIETNAMESE: posix = "vi"; break; + case LANG_XHOSA: posix = "xh"; break; + case LANG_URDU: break; + case LANG_INDONESIAN: break; + case LANG_BELARUSIAN: break; + case LANG_LATVIAN: break; + case LANG_ARMENIAN: break; + case LANG_AFRIKAANS: break; + case LANG_FAEROESE: break; + case LANG_MALAY: break; + case LANG_KAZAK: break; + case LANG_KYRGYZ: break; + case LANG_SWAHILI: break; + case LANG_UZBEK: break; + case LANG_TATAR: break; + case LANG_ORIYA: break; + case LANG_KANNADA: break; + case LANG_MALAYALAM: break; + case LANG_ASSAMESE: break; + case LANG_MARATHI: break; + case LANG_SANSKRIT: break; + case LANG_MONGOLIAN: break; + case LANG_KONKANI: break; + case LANG_MANIPURI: break; + case LANG_SINDHI: break; + case LANG_SYRIAC: break; + case LANG_KASHMIRI: break; + case LANG_DIVEHI: break; + } + + /* Deal with exceptions */ + if (posix == NULL) { + switch (lcid) { + case 0x0455: posix = "my_MM"; break; /* Myanmar (Burmese) */ + case 9999: posix = "ku"; break; /* Kurdish (from NSIS) */ + } + } + + return posix; +} + +/* Determine and set Eastytag locale as follows (in order of priority): + - Check EASYTAGLANG env var + - Check NSIS Installer Language reg value + - Use default user locale +*/ +static const char *get_locale() { + const char *locale = NULL; + LCID lcid; + char data[10]; + DWORD datalen = 10; + + /* Check if user set EASYTAGLANG env var */ + if ((locale = getenv("EASYTAGLANG"))) { + printf("Variable EASYTAGLANG defined: '%s'\n",locale); + return locale; + }else + printf("Variable EASYTAGLANG not defined\n"); + + if (read_reg_string(HKEY_CURRENT_USER, "SOFTWARE\\easytag", + "Installer Language", (LPBYTE) &data, &datalen)) { + if ((locale = lcid_to_posix(atoi(data)))) + return locale; + } + + lcid = GetUserDefaultLCID(); + if ((locale = lcid_to_posix(lcid))) + return locale; + + return "en"; +} + +static void set_locale() { + const char *locale = NULL; + char envstr[25]; + + locale = get_locale(); + + snprintf(envstr, 25, "LANG=%s", locale); + printf("Setting locale: %s\n", envstr); + putenv(envstr); +} + +#if 0 +#define WM_FOCUS_REQUEST (WM_APP + 13) + +static BOOL set_running() { + HANDLE h; + + if ((h = CreateMutex(NULL, FALSE, "easytag_is_running"))) { + if (GetLastError() == ERROR_ALREADY_EXISTS) { + HWND msg_win; + + if((msg_win = FindWindow(TEXT("WineasytagMsgWinCls"), NULL))) + if(SendMessage(msg_win, WM_FOCUS_REQUEST, (WPARAM) NULL, (LPARAM) NULL)) + return FALSE; + + /* If we get here, the focus request wasn't successful */ + + MessageBox(NULL, + "An instance of EasyTAG is already running", + NULL, MB_OK | MB_TOPMOST); + + return FALSE; + } + } + return TRUE; +} +#endif + +static void set_proxy() { + DWORD regval = 1; + DWORD reglen = sizeof(DWORD); + + /* If the proxy server environment variables are already set, + * we shouldn't override them */ + if (getenv("HTTP_PROXY") || getenv("http_proxy") || getenv("HTTPPROXY")) + return; + + if (read_reg_string(HKEY_CURRENT_USER, WIN32_PROXY_REGKEY, + "ProxyEnable", + (LPBYTE) ®val, ®len) && (regval & 1)) { + char proxy_server[2048]; + char *c = NULL; + reglen = sizeof(proxy_server); + + if (!read_reg_string(HKEY_CURRENT_USER, WIN32_PROXY_REGKEY, + "ProxyServer", (LPBYTE) &proxy_server, ®len)) + return; + + if ((reglen > strlen("http=")) + && (c = strstr(proxy_server, "http="))) { + char *d; + c += strlen("http="); + d = strchr(c, ';'); + if (d) { + *d = '\0'; + } + /* c now points the proxy server (and port) */ + } + + if (c) { + const char envstr_prefix[] = "HTTP_PROXY=http://"; + char envstr[sizeof(envstr_prefix) + strlen(c) + 1]; + snprintf(envstr, sizeof(envstr), "%s%s", + envstr_prefix, c); + printf("Setting HTTP Proxy: %s\n", envstr); + putenv(envstr); + } + } + +} + +#ifdef __GNUC__ +# ifndef _stdcall +# define _stdcall __attribute__((stdcall)) +# endif +#endif + +int _stdcall +WinMain (struct HINSTANCE__ *hInstance, struct HINSTANCE__ *hPrevInstance, + char *lpszCmdLine, int nCmdShow) { + char errbuf[512]; + HMODULE hmod; + + /* If debug or help or version flag used, create console for output */ + if (strstr(lpszCmdLine, "-d") || strstr(lpszCmdLine, "-h") || strstr(lpszCmdLine, "-v")) { + /* If stdout hasn't been redirected to a file, alloc a console + * (_istty() doesn't work for stuff using the GUI subsystem) */ + if (_fileno(stdout) == -1) { + LPFNATTACHCONSOLE MyAttachConsole = NULL; + if ((hmod = GetModuleHandle("kernel32.dll"))) { + MyAttachConsole = + (LPFNATTACHCONSOLE) + GetProcAddress(hmod, "AttachConsole"); + } + if ((MyAttachConsole && MyAttachConsole(ATTACH_PARENT_PROCESS)) + || AllocConsole()) { + freopen("CONOUT$", "w", stdout); + freopen("CONOUT$", "w", stderr); + } + } + } +#if 0 + /* Load exception handler if we have it */ + if (GetModuleFileName(NULL, gaimdir, MAX_PATH) != 0) { + char *tmp = gaimdir; + char *prev = NULL; + + while ((tmp = strchr(tmp, '\\'))) { + prev = tmp; + tmp++; + } + + if (prev) { + prev[0] = '\0'; + strcat(gaimdir, "\\exchndl.dll"); + if (LoadLibrary(gaimdir)) + printf("Loaded exchndl.dll\n"); + } + } else { + DWORD dw = GetLastError(); + const char *err_msg = get_win32_error_message(dw); + snprintf(errbuf, 512, + "Error getting module filename. Error: (%u) %s", + (UINT) dw, err_msg); + printf(errbuf); + MessageBox(NULL, errbuf, NULL, MB_OK | MB_TOPMOST); + } +#endif + + dll_prep(); + + set_locale(); + /* If help or version flag used, do not check Mutex */ + //if (!strstr(lpszCmdLine, "-h") && !strstr(lpszCmdLine, "-v")) + // if (!getenv("GAIM_MULTI_INST") && !wgaim_set_running()) + // return 0; + + set_proxy(); + + /* Now we are ready for EasyTag .. */ + if ((hmod = LoadLibrary("easytag.dll"))) { + easytag_main = (LPFNEASYTAGMAIN) GetProcAddress(hmod, "easytag_main"); + } + + if (!easytag_main) { + DWORD dw = GetLastError(); + BOOL mod_not_found = (dw == ERROR_MOD_NOT_FOUND || dw == ERROR_DLL_NOT_FOUND); + const char *err_msg = get_win32_error_message(dw); + + snprintf(errbuf, 512, "Error loading 'easytag.dll'. Error: (%u) %s%s%s", + (UINT) dw, err_msg, + mod_not_found ? "\n" : "", + mod_not_found ? "This probably means that GTK+ can't be found." : ""); + printf(errbuf); + MessageBox(NULL, errbuf, TEXT("Error"), MB_OK | MB_TOPMOST); + + return 0; + } + + return easytag_main (hInstance, __argc, __argv); +} |