Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve get_lib_version, use as check #415

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 10 additions & 19 deletions lib/inputstreamhelper/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
set_setting, set_setting_bool, textviewer, translate_path, yesno_dialog)
from .utils import arch, http_download, remove_tree, run_cmd, store, system_os, temp_path, unzip
from .widevine.arm import install_widevine_arm, unmount
from .widevine.widevine import (backup_path, has_widevinecdm, ia_cdm_path, install_cdm_from_backup, latest_widevine_version,
from .widevine.widevine import (backup_path, has_widevinecdm, get_lib_version, ia_cdm_path, install_cdm_from_backup, latest_widevine_version,
load_widevine_config, missing_widevine_libs, widevine_config_path, widevine_eula, widevinecdm_path)
from .unicodes import compat_path

Expand Down Expand Up @@ -96,18 +96,6 @@ def _inputstream_version(self):
from .unicodes import to_unicode
return to_unicode(addon.getAddonInfo('version'))

@staticmethod
def _get_lib_version(path):
if not path or not exists(path):
return '(Not found)'
import re
with open(compat_path(path), 'rb') as library:
match = re.search(br'[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+', library.read())
if not match:
return '(Undetected)'
from .unicodes import to_unicode
return to_unicode(match.group(0))

def _has_inputstream(self):
"""Checks if selected InputStream add-on is installed."""
data = jsonrpc(method='Addons.GetAddonDetails', params=dict(addonid=self.inputstream_addon))
Expand Down Expand Up @@ -195,7 +183,9 @@ def install_and_finish(self, progress, version):
"""Installs the cdm from backup and runs checks"""

progress.update(97, message=localize(30049)) # Installing Widevine CDM
install_cdm_from_backup(version)
if not install_cdm_from_backup(version):
progress.close()
return False

progress.update(98, message=localize(30050)) # Finishing
if has_widevinecdm():
Expand Down Expand Up @@ -432,7 +422,7 @@ def info_dialog(self):
wv_updated = strftime('%Y-%m-%d %H:%M', localtime(get_setting_float('last_modified', 0.0)))
else:
wv_updated = 'Never'
text += localize(30821, version=self._get_lib_version(widevinecdm_path()), date=wv_updated) + '\n'
text += localize(30821, version=get_lib_version(widevinecdm_path()), date=wv_updated) + '\n'
if arch() in ('arm', 'arm64'): # Chrome OS version
wv_cfg = load_widevine_config()
if wv_cfg:
Expand All @@ -451,7 +441,8 @@ def info_dialog(self):
log(2, '\n{info}'.format(info=kodi_to_ascii(text)))
textviewer(localize(30901), text)

def rollback_libwv(self):
@staticmethod
def rollback_libwv():
"""Rollback lib to a version specified by the user"""
bpath = backup_path()
versions = listdir(bpath)
Expand All @@ -470,7 +461,7 @@ def rollback_libwv(self):
show_versions = []

for version in versions:
lib_version = self._get_lib_version(os.path.join(bpath, version, config.WIDEVINE_CDM_FILENAME[system_os()]))
lib_version = get_lib_version(os.path.join(bpath, version, config.WIDEVINE_CDM_FILENAME[system_os()]))
show_versions.append('{} ({})'.format(lib_version, version))

if not show_versions:
Expand All @@ -480,7 +471,7 @@ def rollback_libwv(self):
version = select_dialog(localize(30057), show_versions)
if version != -1:
log(0, 'Rollback to version {version}', version=versions[version])
install_cdm_from_backup(versions[version])
notification(localize(30037), localize(30051)) # Success! Widevine successfully installed.
if install_cdm_from_backup(versions[version]):
notification(localize(30037), localize(30051)) # Success! Widevine successfully installed.

return
31 changes: 29 additions & 2 deletions lib/inputstreamhelper/widevine/widevine.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,23 @@

def install_cdm_from_backup(version):
"""Copies files from specified backup version to cdm dir"""
filenames = listdir(os.path.join(backup_path(), version))
backup_dir = os.path.join(backup_path(), version)

if not get_lib_version(os.path.join(backup_dir, config.WIDEVINE_CDM_FILENAME[system_os()])):
log(4, 'lib version check failed! Aborting installation.')
ok_dialog(localize(30004), localize(30005)) # Error during install, please report
return False
filenames = listdir(backup_dir)

for filename in filenames:
backup_fpath = os.path.join(backup_path(), version, filename)
backup_fpath = os.path.join(backup_dir, filename)
install_fpath = os.path.join(ia_cdm_path(), filename)
hardlink(backup_fpath, install_fpath)

log(0, 'Installed CDM version {version} from backup', version=version)
set_setting('last_modified', time())
remove_old_backups(backup_path())
return True


def widevine_eula():
Expand Down Expand Up @@ -118,6 +125,26 @@ def ia_cdm_path():
return cdm_path


def get_lib_version(path):
"""
Determines version of the Widevine library using the python ctypes module.
Returns empty string if not possible, which might indicate a problematic file/arch mismatch, so this can be used as a check.
"""
from ctypes import CDLL, c_char_p
from _ctypes import dlclose

lib_version = ''
try:
lib = CDLL(compat_path(path))
lib.GetCdmVersion.restype = c_char_p
lib_version = to_unicode(lib.GetCdmVersion())
dlclose(lib._handle) # pylint: disable=protected-access
except (OSError, AttributeError) as exc:
log(4, 'Failed to determine lib version: ' + str(exc))

return lib_version


def missing_widevine_libs():
"""Parses ldd output of libwidevinecdm.so and displays dialog if any depending libraries are missing."""
if system_os() != 'Linux': # this should only be needed for linux
Expand Down
8 changes: 4 additions & 4 deletions tests/xbmcvfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,11 @@ def rmdir(path):
def translatePath(path):
"""A stub implementation of the xbmc translatePath() function"""
if path.startswith('special://home'):
return path.replace('special://home', os.path.join(os.getcwd(), 'tests/'))
return path.replace('special://home', os.path.join(os.getcwd(), 'tests'))
if path.startswith('special://masterprofile'):
return path.replace('special://masterprofile', os.path.join(os.getcwd(), 'tests/userdata/'))
return path.replace('special://masterprofile', os.path.join(os.getcwd(), 'tests/userdata'))
if path.startswith('special://profile'):
return path.replace('special://profile', os.path.join(os.getcwd(), 'tests/userdata/'))
return path.replace('special://profile', os.path.join(os.getcwd(), 'tests/userdata'))
if path.startswith('special://userdata'):
return path.replace('special://userdata', os.path.join(os.getcwd(), 'tests/userdata/'))
return path.replace('special://userdata', os.path.join(os.getcwd(), 'tests/userdata'))
return path