diff options
author | Lars Op den Kamp <lars@opdenkamp.eu> | 2010-10-16 15:07:20 +0200 |
---|---|---|
committer | Lars Op den Kamp <lars@opdenkamp.eu> | 2011-01-04 12:19:41 +0100 |
commit | 2c81a1063d956cbe49b3460076b1ce3ef6505518 (patch) | |
tree | d220a48c74ef86d608bc40d432ce96f046504899 /addons/library.xbmc.addon | |
parent | 07db21c48d60933b45c702d333572ed8f4629fdc (diff) |
merge pvr-testing2 svn rev 32591 into trunk
Diffstat (limited to 'addons/library.xbmc.addon')
-rw-r--r-- | addons/library.xbmc.addon/dlfcn-win32.cpp | 263 | ||||
-rw-r--r-- | addons/library.xbmc.addon/dlfcn-win32.h | 46 | ||||
-rw-r--r-- | addons/library.xbmc.addon/libXBMC_addon.h | 150 |
3 files changed, 459 insertions, 0 deletions
diff --git a/addons/library.xbmc.addon/dlfcn-win32.cpp b/addons/library.xbmc.addon/dlfcn-win32.cpp new file mode 100644 index 0000000000..a6cf2c28ff --- /dev/null +++ b/addons/library.xbmc.addon/dlfcn-win32.cpp @@ -0,0 +1,263 @@ +/*
+ * dlfcn-win32
+ * Copyright (c) 2007 Ramiro Polla
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <windows.h>
+#include <stdio.h>
+
+#include "dlfcn-win32.h"
+
+/* Note:
+ * MSDN says these functions are not thread-safe. We make no efforts to have
+ * any kind of thread safety.
+ */
+
+/* I have no special reason to have set MAX_GLOBAL_OBJECTS to this value. Any
+ * comments are welcome.
+ */
+#define MAX_OBJECTS 255
+
+static HMODULE global_objects[MAX_OBJECTS];
+
+/* This function adds an object to the list of global objects.
+ * The implementation is very simple and slow.
+ * TODO: should failing this function be enough to fail the call to dlopen( )?
+ */
+static void global_object_add( HMODULE hModule )
+{
+ int i;
+
+ for( i = 0 ; i < MAX_OBJECTS ; i++ )
+ {
+ if( !global_objects[i] )
+ {
+ global_objects[i] = hModule;
+ break;
+ }
+ }
+}
+
+static void global_object_rem( HMODULE hModule )
+{
+ int i;
+
+ for( i = 0 ; i < MAX_OBJECTS ; i++ )
+ {
+ if( global_objects[i] == hModule )
+ {
+ global_objects[i] = 0;
+ break;
+ }
+ }
+}
+
+/* Argument to last function. Used in dlerror( ) */
+static char last_name[MAX_PATH];
+
+static int copy_string( char *dest, int dest_size, const char *src )
+{
+ int i = 0;
+
+ if( src && dest )
+ {
+ for( i = 0 ; i < dest_size-1 ; i++ )
+ {
+ if( !src[i] )
+ break;
+ else
+ dest[i] = src[i];
+ }
+ }
+ dest[i] = '\0';
+
+ return i;
+}
+
+void *dlopen( const char *file, int mode )
+{
+ HMODULE hModule;
+ UINT uMode;
+
+ /* Do not let Windows display the critical-error-handler message box */
+ uMode = SetErrorMode( SEM_FAILCRITICALERRORS );
+
+ if( file == 0 )
+ {
+ /* Save NULL pointer for error message */
+ _snprintf_s( last_name, MAX_PATH, MAX_PATH, "0x%p", file );
+
+ /* POSIX says that if the value of file is 0, a handle on a global
+ * symbol object must be provided. That object must be able to access
+ * all symbols from the original program file, and any objects loaded
+ * with the RTLD_GLOBAL flag.
+ * The return value from GetModuleHandle( ) allows us to retrieve
+ * symbols only from the original program file. For objects loaded with
+ * the RTLD_GLOBAL flag, we create our own list later on.
+ */
+ hModule = GetModuleHandle( NULL );
+ }
+ else
+ {
+ char lpFileName[MAX_PATH];
+ int i;
+
+ /* MSDN says backslashes *must* be used instead of forward slashes. */
+ for( i = 0 ; i < sizeof(lpFileName)-1 ; i++ )
+ {
+ if( !file[i] )
+ break;
+ else if( file[i] == '/' )
+ lpFileName[i] = '\\';
+ else
+ lpFileName[i] = file[i];
+ }
+ lpFileName[i] = '\0';
+
+ /* Save file name for error message */
+ copy_string( last_name, sizeof(last_name), lpFileName );
+
+ /* POSIX says the search path is implementation-defined.
+ * LOAD_WITH_ALTERED_SEARCH_PATH is used to make it behave more closely
+ * to UNIX's search paths (start with system folders instead of current
+ * folder).
+ */
+ hModule = LoadLibraryEx( (LPSTR) lpFileName, NULL,
+ LOAD_WITH_ALTERED_SEARCH_PATH );
+ /* If the object was loaded with RTLD_GLOBAL, add it to list of global
+ * objects, so that its symbols may be retrieved even if the handle for
+ * the original program file is passed. POSIX says that if the same
+ * file is specified in multiple invocations, and any of them are
+ * RTLD_GLOBAL, even if any further invocations use RTLD_LOCAL, the
+ * symbols will remain global.
+ */
+
+ if( hModule && (mode & RTLD_GLOBAL) )
+ global_object_add( hModule );
+ }
+
+ /* Return to previous state of the error-mode bit flags. */
+ SetErrorMode( uMode );
+
+ return (void *) hModule;
+}
+
+int dlclose( void *handle )
+{
+ HMODULE hModule = (HMODULE) handle;
+ BOOL ret;
+
+ /* Save handle for error message */
+ _snprintf_s( last_name, MAX_PATH, MAX_PATH, "0x%p", handle );
+
+ ret = FreeLibrary( hModule );
+
+ /* If the object was loaded with RTLD_GLOBAL, remove it from list of global
+ * objects.
+ */
+ if( ret )
+ global_object_rem( hModule );
+
+ /* dlclose's return value in inverted in relation to FreeLibrary's. */
+ ret = !ret;
+
+ return (int) ret;
+}
+
+void *dlsym( void *handle, const char *name )
+{
+ FARPROC symbol;
+ HMODULE myhandle = (HMODULE) handle;
+
+ /* Save symbol name for error message */
+ copy_string( last_name, sizeof(last_name), name );
+
+ symbol = GetProcAddress( myhandle, name );
+#if 0
+ if( symbol == NULL )
+ {
+ HMODULE hModule;
+
+ /* If the handle for the original program file is passed, also search
+ * in all globally loaded objects.
+ */
+
+ hModule = GetModuleHandle( NULL );
+
+ if( hModule == handle )
+ {
+ int i;
+
+ for( i = 0 ; i < MAX_OBJECTS ; i++ )
+ {
+ if( global_objects[i] != 0 )
+ {
+ symbol = GetProcAddress( global_objects[i], name );
+ if( symbol != NULL )
+ break;
+ }
+ }
+ }
+
+
+ CloseHandle( hModule );
+ }
+#endif
+ return (void*) symbol;
+}
+
+char *dlerror( void )
+{
+ DWORD dwMessageId;
+ /* POSIX says this function doesn't have to be thread-safe, so we use one
+ * static buffer.
+ * MSDN says the buffer cannot be larger than 64K bytes, so we set it to
+ * the limit.
+ */
+ static char lpBuffer[65535];
+ DWORD ret;
+
+ dwMessageId = GetLastError( );
+
+ if( dwMessageId == 0 )
+ return NULL;
+
+ /* Format error message to:
+ * "<argument to function that failed>": <Windows localized error message>
+ */
+ ret = copy_string( lpBuffer, sizeof(lpBuffer), "\"" );
+ ret += copy_string( lpBuffer+ret, sizeof(lpBuffer)-ret, last_name );
+ ret += copy_string( lpBuffer+ret, sizeof(lpBuffer)-ret, "\": " );
+ ret += FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwMessageId,
+ MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
+ lpBuffer+ret, sizeof(lpBuffer)-ret, NULL );
+
+ if( ret > 1 )
+ {
+ /* POSIX says the string must not have trailing <newline> */
+ if( lpBuffer[ret-2] == '\r' && lpBuffer[ret-1] == '\n' )
+ lpBuffer[ret-2] = '\0';
+ }
+
+ /* POSIX says that invoking dlerror( ) a second time, immediately following
+ * a prior invocation, shall result in NULL being returned.
+ */
+ SetLastError(0);
+
+ return lpBuffer;
+}
+
diff --git a/addons/library.xbmc.addon/dlfcn-win32.h b/addons/library.xbmc.addon/dlfcn-win32.h new file mode 100644 index 0000000000..f906343a96 --- /dev/null +++ b/addons/library.xbmc.addon/dlfcn-win32.h @@ -0,0 +1,46 @@ +#pragma once
+/*
+ * dlfcn-win32
+ * Copyright (c) 2007 Ramiro Polla
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef DLFCN_H
+#define DLFCN_H
+
+/* POSIX says these are implementation-defined.
+ * To simplify use with Windows API, we treat them the same way.
+ */
+
+#define RTLD_LAZY 0
+#define RTLD_NOW 0
+
+#define RTLD_GLOBAL (1 << 1)
+#define RTLD_LOCAL (1 << 2)
+
+/* These two were added in The Open Group Base Specifications Issue 6.
+ * Note: All other RTLD_* flags in any dlfcn.h are not standard compliant.
+ */
+
+#define RTLD_DEFAULT 0
+#define RTLD_NEXT 0
+
+void *dlopen ( const char *file, int mode );
+int dlclose( void *handle );
+void *dlsym ( void *handle, const char *name );
+char *dlerror( void );
+
+#endif /* DLFCN-WIN32_H */
diff --git a/addons/library.xbmc.addon/libXBMC_addon.h b/addons/library.xbmc.addon/libXBMC_addon.h new file mode 100644 index 0000000000..7af0d1cf7d --- /dev/null +++ b/addons/library.xbmc.addon/libXBMC_addon.h @@ -0,0 +1,150 @@ +#pragma once +/* + * Copyright (C) 2005-2010 Team XBMC + * http://www.xbmc.org + * + * 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, 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 XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include <string> +#include <vector> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +#ifndef _LINUX +#include "dlfcn-win32.h" +#define ADDON_DLL "\\library.xbmc.addon\\libXBMC_addon.dll" +#else +#include <dlfcn.h> +#if defined(__APPLE__) +#if defined(__POWERPC__) +#define ADDON_DLL "/library.xbmc.addon/libXBMC_addon-powerpc-osx.so" +#else +#define ADDON_DLL "/library.xbmc.addon/libXBMC_addon-x86-osx.so" +#endif +#elif defined(__x86_64__) +#define ADDON_DLL "/library.xbmc.addon/libXBMC_addon-x86_64-linux.so" +#elif defined(_POWERPC) +#define ADDON_DLL "/library.xbmc.addon/libXBMC_addon-powerpc-linux.so" +#elif defined(_POWERPC64) +#define ADDON_DLL "/library.xbmc.addon/libXBMC_addon-powerpc64-linux.so" +#else /* !__x86_64__ && !__powerpc__ */ +#define ADDON_DLL "/library.xbmc.addon/libXBMC_addon-i486-linux.so" +#endif /* __x86_64__ */ +#endif /* _LINUX */ + +typedef enum addon_log { + LOG_DEBUG, + LOG_INFO, + LOG_NOTICE, + LOG_ERROR +} addon_log_t; + +typedef enum queue_msg { + QUEUE_INFO, + QUEUE_WARNING, + QUEUE_ERROR +} queue_msg_t; + +class cHelper_libXBMC_addon +{ +public: + cHelper_libXBMC_addon() + { + m_libXBMC_addon = NULL; + m_Handle = NULL; + } + + ~cHelper_libXBMC_addon() + { + if (m_libXBMC_addon) + { + XBMC_unregister_me(); + dlclose(m_libXBMC_addon); + } + } + + bool RegisterMe(void *Handle) + { + m_Handle = Handle; + + std::string libBasePath; + libBasePath = ((cb_array*)m_Handle)->libPath; + libBasePath += ADDON_DLL; + + m_libXBMC_addon = dlopen(libBasePath.c_str(), RTLD_LAZY); + if (m_libXBMC_addon == NULL) + { + fprintf(stderr, "Unable to load %s\n", dlerror()); + return false; + } + + XBMC_register_me = (int (*)(void *HANDLE)) + dlsym(m_libXBMC_addon, "XBMC_register_me"); + if (XBMC_register_me == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + XBMC_unregister_me = (void (*)()) + dlsym(m_libXBMC_addon, "XBMC_unregister_me"); + if (XBMC_unregister_me == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + Log = (void (*)(const addon_log_t loglevel, const char *format, ... )) + dlsym(m_libXBMC_addon, "XBMC_log"); + if (Log == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GetSetting = (bool (*)(std::string settingName, void *settingValue)) + dlsym(m_libXBMC_addon, "XBMC_get_setting"); + if (GetSetting == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + QueueNotification = (void (*)(const queue_msg_t loglevel, const char *format, ... )) + dlsym(m_libXBMC_addon, "XBMC_queue_notification"); + if (QueueNotification == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + UnknownToUTF8 = (void (*)(std::string &str)) + dlsym(m_libXBMC_addon, "XBMC_unknown_to_utf8"); + if (UnknownToUTF8 == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GetLocalizedString = (std::string (*)(int dwCode)) + dlsym(m_libXBMC_addon, "XBMC_get_localized_string"); + if (GetLocalizedString == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + GetDVDMenuLanguage = (std::string (*)()) + dlsym(m_libXBMC_addon, "XBMC_get_dvd_menu_language"); + if (GetDVDMenuLanguage == NULL) { fprintf(stderr, "Unable to assign function %s\n", dlerror()); return false; } + + return XBMC_register_me(m_Handle) > 0; + } + + void (*Log)(const addon_log_t loglevel, const char *format, ... ); + bool (*GetSetting)(std::string settingName, void *settingValue); + void (*QueueNotification)(const queue_msg_t type, const char *format, ... ); + void (*UnknownToUTF8)(std::string &str); + std::string (*GetLocalizedString)(int dwCode); + std::string (*GetDVDMenuLanguage)(); + +protected: + int (*XBMC_register_me)(void *HANDLE); + void (*XBMC_unregister_me)(); + +private: + void *m_libXBMC_addon; + void *m_Handle; + struct cb_array + { + const char* libPath; + }; +}; |