aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/win32/win32dep.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/win32/win32dep.c')
-rwxr-xr-xsrc/win32/win32dep.c493
1 files changed, 493 insertions, 0 deletions
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