Commit edbb5a89 by Csók Tamás

client: upgrades in the setup process, plus more logical layout of the code

parent 1c2901e3
...@@ -162,9 +162,9 @@ IF NOT "!output_on_screen!"=="False" ( ...@@ -162,9 +162,9 @@ IF NOT "!output_on_screen!"=="False" (
goto loop goto loop
) else ( ) else (
set test=%install_path:~0,-1% set test=%install_path:~0,-1%
call %running_directory%inPath test && (IF NOT "!output_on_screen!"=="False" (@echo %test% is already in PATH)) || (call %running_directory%addPath test & setx>nul PATH "%PATH%;%test%" & IF NOT "!output_on_screen!"=="False" ( @echo %test% set to local PATH)) call %running_directory%inPath test && (IF NOT "!output_on_screen!"=="False" (@echo %test% is already in PATH)) || (call %running_directory%addPath test & setx>nul PATH "%PATH%;%test%" /m & IF NOT "!output_on_screen!"=="False" ( @echo %test% set to PATH))
set test=%install_path%Scripts set test=%install_path%Scripts
call %running_directory%inPath test && (IF NOT "!output_on_screen!"=="False" (@echo %test% is already in PATH)) || (call %running_directory%addPath test & setx>nul PATH "%PATH%;%test%" & IF NOT "!output_on_screen!"=="False" ( @echo %test% set to local PATH)) call %running_directory%inPath test && (IF NOT "!output_on_screen!"=="False" (@echo %test% is already in PATH)) || (call %running_directory%addPath test & setx>nul PATH "%PATH%;%test%" /m & IF NOT "!output_on_screen!"=="False" ( @echo %test% set to PATH))
) )
GOTO PIP_CHECK GOTO PIP_CHECK
...@@ -195,12 +195,11 @@ IF NOT "!output_on_screen!"=="False" ( ...@@ -195,12 +195,11 @@ IF NOT "!output_on_screen!"=="False" (
) else ( ) else (
call python -m pip install --upgrade pip >nul 2>&1 call python -m pip install --upgrade pip >nul 2>&1
) )
IF "%install_selenium%"=="False" ( SET "pip_program=requirements.txt"
SET "pip_program=winshell" IF NOT "!output_on_screen!"=="False" (
) else ( @echo Installing python modules
SET "pip_program=selenium"
) )
GOTO PIP_PACKAGE_CHECK GOTO PIP_PACKAGE_INSTALL
rem Check if the PIP package is installed or not rem Check if the PIP package is installed or not
:PIP_PACKAGE_CHECK :PIP_PACKAGE_CHECK
...@@ -213,9 +212,7 @@ IF NOT "!output_on_screen!"=="False" ( ...@@ -213,9 +212,7 @@ IF NOT "!output_on_screen!"=="False" (
IF NOT "!output_on_screen!"=="False" ( IF NOT "!output_on_screen!"=="False" (
@echo %%b !pip_program! is found @echo %%b !pip_program! is found
) )
rem pywin32 cannot be installed or updated via pip GOTO CHECK_PACKAGE_LIST
if "!pip_program!"=="pywin32" goto CHECK_PACKAGE_LIST
GOTO PIP_PACKAGE_UPDATE
) )
) )
IF NOT "!output_on_screen!"=="False" ( IF NOT "!output_on_screen!"=="False" (
...@@ -223,38 +220,21 @@ IF NOT "!output_on_screen!"=="False" ( ...@@ -223,38 +220,21 @@ IF NOT "!output_on_screen!"=="False" (
) )
GOTO PIP_PACKAGE_INSTALL GOTO PIP_PACKAGE_INSTALL
rem Try to install the PIP package via PIP rem Try to install the PIP packages via PIP
:PIP_PACKAGE_INSTALL :PIP_PACKAGE_INSTALL
IF NOT "!output_on_screen!"=="False" (
@echo Installing !pip_program!
)
if "!pip_program!"=="pywin32" ( if "!pip_program!"=="pywin32" (
call python %running_directory%pywin_installer.py call python %running_directory%pywin_installer.py
) else ( ) else (
IF NOT "!output_on_screen!"=="False" ( IF NOT "!output_on_screen!"=="False" (
call python -m pip install !pip_program! call python -m pip install -r requirements.txt
) else ( ) else (
call python -m pip install !pip_program! >nul 2>&1 call python -m pip install -r requirements.txt >nul 2>&1
) )
) )
goto CHECK_PACKAGE_LIST goto CHECK_PACKAGE_LIST
rem Try to update Selenium
:PIP_PACKAGE_UPDATE
IF NOT "!output_on_screen!"=="False" (
@echo Trying to update !pip_program!
call python -m pip install --upgrade !pip_program!
) else (
call python -m pip install --upgrade !pip_program! >nul 2>&1
)
goto CHECK_PACKAGE_LIST
:CHECK_PACKAGE_LIST :CHECK_PACKAGE_LIST
if "!pip_program!"=="selenium" ( if "!pip_program!"=="requirements.txt" (
set "pip_program=winshell"
goto PIP_PACKAGE_CHECK
)
if "!pip_program!"=="winshell" (
set "pip_program=pywin32" set "pip_program=pywin32"
goto PIP_PACKAGE_CHECK goto PIP_PACKAGE_CHECK
) )
...@@ -395,7 +375,7 @@ if "!browserToUse!"=="None" ( ...@@ -395,7 +375,7 @@ if "!browserToUse!"=="None" (
call :Split "%browser_path%" test call :Split "%browser_path%" test
set myTest=!test:~0,-1! set myTest=!test:~0,-1!
rem Set that path in the PATH environment variable rem Set that path in the PATH environment variable
call %running_directory%inPath myTest && (IF NOT "!output_on_screen!"=="False" ( @echo !myTest! is already in PATH)) || (call %running_directory%addPath myTest & setx>nul PATH "%PATH%;!myTest!" & IF NOT "!output_on_screen!"=="False" ( @echo !myTest! set to local PATH) ) call %running_directory%inPath myTest && (IF NOT "!output_on_screen!"=="False" ( @echo !myTest! is already in PATH)) || (call %running_directory%addPath myTest & setx>nul PATH "%PATH%;!myTest!" /m & IF NOT "!output_on_screen!"=="False" ( @echo !myTest! set to PATH) )
:install_driver :install_driver
IF NOT "%install_selenium%"=="False" ( IF NOT "%install_selenium%"=="False" (
if NOT "!selenium_driver_name!"=="" ( if NOT "!selenium_driver_name!"=="" (
...@@ -448,7 +428,7 @@ rem Create folder if needed and set it to PATH ...@@ -448,7 +428,7 @@ rem Create folder if needed and set it to PATH
IF NOT "!output_on_screen!"=="False" ( IF NOT "!output_on_screen!"=="False" (
@echo Checking wheter ^'%install_location%^\^' exists already @echo Checking wheter ^'%install_location%^\^' exists already
) )
call %running_directory%inPath install_location && (IF NOT "!output_on_screen!"=="False" ( @echo !install_location! is already in PATH)) || (call %running_directory%addPath install_location & setx>nul PATH "%PATH%;!install_location!" & IF NOT "!output_on_screen!"=="False" ( @echo !install_location! set to local PATH)) call %running_directory%inPath install_location && (IF NOT "!output_on_screen!"=="False" ( @echo !install_location! is already in PATH)) || (call %running_directory%addPath install_location & setx>nul PATH "%PATH%;!install_location!" /m & IF NOT "!output_on_screen!"=="False" ( @echo !install_location! set to PATH))
if not exist "%install_location%\" ( if not exist "%install_location%\" (
mkdir "%install_location%" mkdir "%install_location%"
) )
...@@ -462,7 +442,7 @@ IF NOT "!output_on_screen!"=="False" ( ...@@ -462,7 +442,7 @@ IF NOT "!output_on_screen!"=="False" (
xcopy>nul "%running_directory%cloud.py" "%install_location%\" /y xcopy>nul "%running_directory%cloud.py" "%install_location%\" /y
xcopy>nul "%running_directory%cloud_connect_from_windows.py" "%install_location%\" /y xcopy>nul "%running_directory%cloud_connect_from_windows.py" "%install_location%\" /y
xcopy>nul "%running_directory%win_install.py" "%install_location%\" /y xcopy>nul "%running_directory%win_install.py" "%install_location%\" /y
xcopy>nul "%running_directory%nx_client_installer.py" "%install_location%\" /y xcopy>nul "%running_directory%windowsclasses.py" "%install_location%\" /y
xcopy>nul "%running_directory%nxkey.py" "%install_location%\" /y xcopy>nul "%running_directory%nxkey.py" "%install_location%\" /y
xcopy>nul "%running_directory%OrderedDict.py" "%install_location%\" /y xcopy>nul "%running_directory%OrderedDict.py" "%install_location%\" /y
xcopy>nul "%running_directory%cloud.ico" "%install_location%\" /y xcopy>nul "%running_directory%cloud.ico" "%install_location%\" /y
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "CIRCLE Client" #define MyAppName "CIRCLE Client"
#define MyAppProgramInfo "Visit the CIRCLE"
#define MyAppProgram "Cloud GUI.url"
#define MyAppDir "{userappdata}\CIRCLE"
#define MyAppVersion "1.0" #define MyAppVersion "1.0"
#define MyAppPublisher "BME IK, IIT, VIK" #define MyAppPublisher "BME IK, IIT, VIK"
#define MyAppURL "http://cloud.bme.hu/" #define MyAppURL "http://cloud.bme.hu/"
...@@ -79,4 +82,5 @@ Filename: "{app}\uninstall.bat"; Parameters: "True"; Flags: waituntilterminated ...@@ -79,4 +82,5 @@ Filename: "{app}\uninstall.bat"; Parameters: "True"; Flags: waituntilterminated
[Icons] [Icons]
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}" Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
Name: "{group}\{#MyAppProgramInfo}"; Filename: "{#MyAppDir}\{#MyAppProgram}"; IconFilename: "{#MyAppDir}\cloud.ico"
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
A cloudban létrehozott virtuális gépekhez történő kapcsolódást segítő Main program of the Client written for CIRCLE Cloud.
program The Client job is to help the ease of use of the cloud system.
""" """
import platform import platform
...@@ -21,22 +21,22 @@ except ImporError: ...@@ -21,22 +21,22 @@ except ImporError:
class Struct: class Struct:
""" """
Paraméterek átadására használt struktúra A struct used for parameter passing
Keyword arguments: Keyword arguments:
state -- A virtuális gép állapota, azt figyeljük, hogy fut-e state -- State of the Virtual Computer (running, etc..)
protocol -- SSH, NX és RDP lehetséges protocol -- SSH, NX and RDP possible
host -- A virtuális gép címe host -- Address of the Virtual Computer
port -- Ezen a porton csatlakozunk a virtuális géphez port -- The port where we can access the Virtual Computer
user -- Csatlakozáshoz használt név user -- Username used for the connection
password -- Csatlakozáshoz használt jelszó password -- Password used for the connection
""" """
pass pass
def parse_arguments(): def parse_arguments():
""" """
Argument parser, argparse modulon alapszik Argument parser, based on the argparse module
Keyword arguments: Keyword arguments:
@return args -- arguments given by console @return args -- arguments given by console
...@@ -53,18 +53,16 @@ def parse_arguments(): ...@@ -53,18 +53,16 @@ def parse_arguments():
"first the proper driver.", type=str, "first the proper driver.", type=str,
choices=['firefox', 'chrome', 'ie', 'opera'], choices=['firefox', 'chrome', 'ie', 'opera'],
default="firefox") default="firefox")
parser.add_argument(
"-o", "--old", help="Use old interface", action="store_true")
args = parser.parse_args() args = parser.parse_args()
return args return args
class Browser: class Browser:
""" """
Browser inicializálás Browser initialisation
Keyword arguments: Keyword arguments:
@param args -- Az args.driver paraméterrel meghatározhatjuk, @param args -- args.driver tells us which installed browser
melyik böngészőt akarjuk használni. we want to use with selenium.
""" """
def __init__(self, args): def __init__(self, args):
self.args = args self.args = args
...@@ -80,8 +78,7 @@ class Browser: ...@@ -80,8 +78,7 @@ class Browser:
def login(self): def login(self):
""" """
Címtáras beléptetés a parancssorban megadott paraméterek Eduid login based on the given console arguments
alapján
""" """
driver = self.driver driver = self.driver
args = self.args args = self.args
...@@ -95,59 +92,21 @@ class Browser: ...@@ -95,59 +92,21 @@ class Browser:
driver.find_element_by_css_selector( driver.find_element_by_css_selector(
"input[type='submit']").click() "input[type='submit']").click()
def old_main(self):
"""
A régi webes felület használata
Keyword arguments:
@return vm -- Virtuális gép csatlakozásához szükséges
paraméterek
"""
vm = Struct()
driver = self.driver
driver.maximize_window()
driver.get("https://cloud.ik.bme.hu/info/")
driver.find_element_by_css_selector("a[href*='/login/']").click()
self.login()
vm.state, vm.protocol = "", "NONE"
try:
while vm.state.upper()[:3] not in ("FUT", "RUN"):
element = WebDriverWait(driver, 7200).until(
EC.presence_of_element_located((
By.CSS_SELECTOR,
"input.hidden-password.shown[type='text']")))
vm.password = element.get_attribute("value")
vm.state = driver.find_element_by_css_selector(
"#state > div > p").text
vm.protocol = driver.find_element_by_css_selector(
"#vm-credentials > div > table > tbody > "+
"tr:nth-child(1) > td").text
vm.host,vm.port = driver.find_element_by_css_selector(
"#vm-credentials > div > table > tbody > "+
"tr:nth-child(2) > td").text.split(':')
vm.user = driver.find_element_by_css_selector(
"#vm-credentials > div > table > tbody > "+
"tr:nth-child(4) > td").text
driver.find_element_by_css_selector("a[href*='/logout/']").click()
except:
print "Browser session timed out!"
raise
return vm
def main(self): def main(self):
""" """
Az új webes felület használata Use of the https://cloud.bme.hu/
Keyword arguments: Keyword arguments:
@return vm -- Virtuális gép csatlakozásához szükséges @return vm -- Necessarily parameters to connect
paraméterek to the Virtual Machine
""" """
vm = Struct() vm = Struct()
driver = self.driver driver = self.driver
driver.maximize_window() driver.maximize_window()
driver.get("https://pc3.szgt.uni-miskolc.hu/") driver.get("https://cloud.bme.hu/")
#driver.find_element_by_css_selector("a[href*='/login/']").click() # driver.find_element_by_css_selector("a[href*='/login/']").click()
#self.login() # self.login()
vm.state, vm.protocol = "", "NONE" vm.state, vm.protocol = "", "NONE"
try: try:
while vm.state.upper()[:3] not in ("FUT", "RUN"): while vm.state.upper()[:3] not in ("FUT", "RUN"):
...@@ -157,7 +116,7 @@ class Browser: ...@@ -157,7 +116,7 @@ class Browser:
"#vm-details-pw-eye.fa.fa-eye-slash"))) "#vm-details-pw-eye.fa.fa-eye-slash")))
vm.state = driver.find_element_by_css_selector( vm.state = driver.find_element_by_css_selector(
"#vm-details-state > span").text "#vm-details-state > span").text
#cl: connection string converted to list # cl: connection string converted to list
cl = driver.find_element_by_css_selector( cl = driver.find_element_by_css_selector(
"#vm-details-connection-string").get_attribute( "#vm-details-connection-string").get_attribute(
"value").split() "value").split()
...@@ -177,14 +136,7 @@ class Browser: ...@@ -177,14 +136,7 @@ class Browser:
def main(): def main():
""" """
Főprogram Main program
Job:
beolvassuk a paramétereket
megnyitjuk a kiválasztott böngészőben a weboldalt
bejelentkezünk a címtárba
kiválasztjuk a futtatni kívánt klienst
kapcsolódunk a klienshez
""" """
try: try:
args = parse_arguments() args = parse_arguments()
...@@ -196,14 +148,8 @@ def main(): ...@@ -196,14 +148,8 @@ def main():
vm.state = "RUN" vm.state = "RUN"
else: else:
browser = Browser(args) browser = Browser(args)
try:
if args.old:
vm = browser.old_main()
else:
vm = browser.main() vm = browser.main()
browser.driver.quit() browser.driver.quit()
except:
raise
if platform.system() == "Linux": if platform.system() == "Linux":
from cloud_connect_from_linux import connect from cloud_connect_from_linux import connect
elif platform.system() == "Windows": elif platform.system() == "Windows":
......
#!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """
# Távoli klienshez csatlakozás windows OS alól Configuration of the Windows specific tools to enhance the ease of use
## of the CIRCLE cloud. Handles the auto launch and auto configuration
of these specific connectivity programs.
"""
import time import time
import os import os
...@@ -12,16 +15,19 @@ import win32crypt ...@@ -12,16 +15,19 @@ import win32crypt
import binascii import binascii
import nxkey import nxkey
##
# A távoli klienshez csatlakozás valósítja majd meg windows alól
# @param vm Paraméterek a csatlakozáshoz
# vm.protocol SSH, NX és RDP lehetséges
# vm.host A virtuális gép címe
# vm.port Ezen a porton csatlakozunk a virtuális géphez
# vm.user Csatlakozáshoz használt név
# vm.password Csatlakozáshoz használt jelszó
#
def connect(vm): def connect(vm):
"""
Handles to connection to the Virtual Machines from the local
machine
Keyword arguments:
vm.protocol -- SSH, NX and RDP possible
vm.host -- Address of the Virtual Computer
vm.port -- The port where we can access the Virtual Computer
vm.user -- Username used for the connection
vm.password -- Password used for the connection
"""
if vm.protocol == "SSH": if vm.protocol == "SSH":
arguments = "-ssh -P %s -pw %s %s@%s" % (vm.port, vm.password, vm.user, vm.host) arguments = "-ssh -P %s -pw %s %s@%s" % (vm.port, vm.password, vm.user, vm.host)
subprocess.Popen("putty.exe "+arguments, shell = True) subprocess.Popen("putty.exe "+arguments, shell = True)
...@@ -64,6 +70,7 @@ def connect(vm): ...@@ -64,6 +70,7 @@ def connect(vm):
f.close() f.close()
subprocess.Popen(config_file, shell = True) subprocess.Popen(config_file, shell = True)
NX_template = """<!DOCTYPE NXClientSettings> NX_template = """<!DOCTYPE NXClientSettings>
<NXClientSettings application="nxclient" version="1.3" > <NXClientSettings application="nxclient" version="1.3" >
<group name="General" > <group name="General" >
......
...@@ -195,12 +195,11 @@ IF NOT "!output_on_screen!"=="False" ( ...@@ -195,12 +195,11 @@ IF NOT "!output_on_screen!"=="False" (
) else ( ) else (
call python -m pip install --upgrade pip >nul 2>&1 call python -m pip install --upgrade pip >nul 2>&1
) )
IF "%install_selenium%"=="False" ( SET "pip_program=requirements.txt"
SET "pip_program=winshell" IF NOT "!output_on_screen!"=="False" (
) else ( @echo Installing python modules
SET "pip_program=selenium"
) )
GOTO PIP_PACKAGE_CHECK GOTO PIP_PACKAGE_INSTALL
rem Check if the PIP package is installed or not rem Check if the PIP package is installed or not
:PIP_PACKAGE_CHECK :PIP_PACKAGE_CHECK
...@@ -213,9 +212,7 @@ IF NOT "!output_on_screen!"=="False" ( ...@@ -213,9 +212,7 @@ IF NOT "!output_on_screen!"=="False" (
IF NOT "!output_on_screen!"=="False" ( IF NOT "!output_on_screen!"=="False" (
@echo %%b !pip_program! is found @echo %%b !pip_program! is found
) )
rem pywin32 cannot be installed or updated via pip GOTO CHECK_PACKAGE_LIST
if "!pip_program!"=="pywin32" goto CHECK_PACKAGE_LIST
GOTO PIP_PACKAGE_UPDATE
) )
) )
IF NOT "!output_on_screen!"=="False" ( IF NOT "!output_on_screen!"=="False" (
...@@ -223,38 +220,21 @@ IF NOT "!output_on_screen!"=="False" ( ...@@ -223,38 +220,21 @@ IF NOT "!output_on_screen!"=="False" (
) )
GOTO PIP_PACKAGE_INSTALL GOTO PIP_PACKAGE_INSTALL
rem Try to install the PIP package via PIP rem Try to install the PIP packages via PIP
:PIP_PACKAGE_INSTALL :PIP_PACKAGE_INSTALL
IF NOT "!output_on_screen!"=="False" (
@echo Installing !pip_program!
)
if "!pip_program!"=="pywin32" ( if "!pip_program!"=="pywin32" (
call python %running_directory%pywin_installer.py call python %running_directory%pywin_installer.py
) else ( ) else (
IF NOT "!output_on_screen!"=="False" ( IF NOT "!output_on_screen!"=="False" (
call python -m pip install !pip_program! call python -m pip install -r requirements.txt
) else ( ) else (
call python -m pip install !pip_program! >nul 2>&1 call python -m pip install -r requirements.txt >nul 2>&1
) )
) )
goto CHECK_PACKAGE_LIST goto CHECK_PACKAGE_LIST
rem Try to update Selenium
:PIP_PACKAGE_UPDATE
IF NOT "!output_on_screen!"=="False" (
@echo Trying to update !pip_program!
call python -m pip install --upgrade !pip_program!
) else (
call python -m pip install --upgrade !pip_program! >nul 2>&1
)
goto CHECK_PACKAGE_LIST
:CHECK_PACKAGE_LIST :CHECK_PACKAGE_LIST
if "!pip_program!"=="selenium" ( if "!pip_program!"=="requirements.txt" (
set "pip_program=winshell"
goto PIP_PACKAGE_CHECK
)
if "!pip_program!"=="winshell" (
set "pip_program=pywin32" set "pip_program=pywin32"
goto PIP_PACKAGE_CHECK goto PIP_PACKAGE_CHECK
) )
...@@ -462,7 +442,7 @@ IF NOT "!output_on_screen!"=="False" ( ...@@ -462,7 +442,7 @@ IF NOT "!output_on_screen!"=="False" (
xcopy>nul "%running_directory%cloud.py" "%install_location%\" /y xcopy>nul "%running_directory%cloud.py" "%install_location%\" /y
xcopy>nul "%running_directory%cloud_connect_from_windows.py" "%install_location%\" /y xcopy>nul "%running_directory%cloud_connect_from_windows.py" "%install_location%\" /y
xcopy>nul "%running_directory%win_install.py" "%install_location%\" /y xcopy>nul "%running_directory%win_install.py" "%install_location%\" /y
xcopy>nul "%running_directory%nx_client_installer.py" "%install_location%\" /y xcopy>nul "%running_directory%windowsclasses.py" "%install_location%\" /y
xcopy>nul "%running_directory%nxkey.py" "%install_location%\" /y xcopy>nul "%running_directory%nxkey.py" "%install_location%\" /y
xcopy>nul "%running_directory%OrderedDict.py" "%install_location%\" /y xcopy>nul "%running_directory%OrderedDict.py" "%install_location%\" /y
xcopy>nul "%running_directory%cloud.ico" "%install_location%\" /y xcopy>nul "%running_directory%cloud.ico" "%install_location%\" /y
......
...@@ -2,23 +2,16 @@ ...@@ -2,23 +2,16 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
NX Client for Windows installer with RegistryHandler and NX Client for Windows installer
DecideArchitecture classes.
Checks whether NX Client for Windows is installed in the system, the Checks whether NX Client for Windows is installed in the system, the
classes used for this process are used for other operations too. classes used for this process are used for other operations too.
""" """
import os import os
import sys
import argparse import argparse
import errno
import subprocess import subprocess
import time import time
from _winreg import * import windowsclasses
try:
from collections import *
except ImporError:
from OrderedDict import *
def parse_arguments(): def parse_arguments():
...@@ -29,10 +22,12 @@ def parse_arguments(): ...@@ -29,10 +22,12 @@ def parse_arguments():
@return args -- arguments given by console @return args -- arguments given by console
""" """
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
if DecideArchitecture.Is64Windows(): if windowsclasses.DecideArchitecture.Is64Windows():
local_default = DecideArchitecture.GetProgramFiles64()+"\\CIRCLE\\" local_default = (windowsclasses.DecideArchitecture.GetProgramFiles64()
+"\\CIRCLE\\")
else: else:
local_default = DecideArchitecture.GetProgramFiles32()+"\\CIRCLE\\" local_default = (windowsclasses.DecideArchitecture.GetProgramFiles32()
+"\\CIRCLE\\")
if (not os.path.exists(local_default[:-1]) if (not os.path.exists(local_default[:-1])
and os.path.exists(os.environ['APPDATA']+"\\CIRCLE")): and os.path.exists(os.environ['APPDATA']+"\\CIRCLE")):
local_default = os.environ['APPDATA']+"\\CIRCLE\\" local_default = os.environ['APPDATA']+"\\CIRCLE\\"
...@@ -40,316 +35,16 @@ def parse_arguments(): ...@@ -40,316 +35,16 @@ def parse_arguments():
"-l", "--location", "-l", "--location",
help="Location of the client files in the system", help="Location of the client files in the system",
default=local_default) default=local_default)
parser.add_argument(
"-g", "--global",
help="Whether we want to edit registry globally or just locally",
action="store_true")
parser.add_argument(
"-d", "--different",
help="Only handle the architecture specific registry area",
action="store_true")
parser.add_argument(
"-r", "--registry",
help="Which HKEY_* const registry type the program should use",
type=str, choices=['HKLM', 'HKCR', 'HKCU', 'HKU', 'HKPD', 'HKCC'],
default="HKLM")
args = parser.parse_args() args = parser.parse_args()
return args return args
class Struct:
"""
Parameter bypassing struct
"""
pass
class RegistryHandler:
"""
Registry handling class, makes registry based queries and
manipulations easier.
This class can handle WOW64 based application differently and none
differently (default)
"""
def __init__(self, args = None):
"""Initialise RegistryHandler
Keyword arguments:
@param args -- The arguments that decide how the we should
handle the registry
args.registry -- What base registry should we use
(default: HKLM)
Raises AttributeError if not supported base registry type is
given
args.different -- Whether we handle registry redirection or not
"""
if args is None:
self.args = Struct()
self.args.different = None
self.args.registry = None
else:
if not hasattr(args, 'different'):
args.different = None
if not hasattr(args, 'registry'):
args.registry = None
self.args = args
if self.args.different is None:
self.args.different = False
if self.args.registry is None or self.args.registry == "HKLM":
self.args.registry = HKEY_LOCAL_MACHINE
elif self.args.registry == "HKCR":
self.args.registry = HKEY_CLASSES_ROOT
elif self.args.registry == "HKCU":
self.args.registry = HKEY_CURRENT_USER
elif self.args.registry == "HKU":
self.args.registry = HKEY_USERS
elif self.args.registry == "HKPD":
self.args.registry = HKEY_PERFORMANCE_DATA
elif self.args.registry == "HKCC":
self.args.registry = HKEY_CURRENT_CONFIG
else:
#print "Non supported registry type"
raise AttributeError
def connect_registry(self):
"""
Getting a registry open
Keyword arguments:
@return connected_registy -- Reference to the newly opened
registry
"""
return ConnectRegistry(None,self.args.registry)
def create_registry_from_dict_chain(
self, dict_chain, both = False, architect = KEY_WOW64_64KEY,
needed_rights = KEY_ALL_ACCESS):
""""
Create registry key and value multilevel tree by chained
dictionaries.
Can raise AttributeError if the provided dict chain isn't
correct
Keyword arguments:
@param key_value_chain -- The dict chain containing all the
information
@param both -- Whether create the registry in WOW64
node too
@param architect -- The current registry view (
only change it if we want to fill the
WOW6432 registry only [both = False],
on x64 windows)
@param needed_rights -- SAM rights to access the key
"""
if both and architect is KEY_WOW64_64KEY:
self.create_registry_from_dict_chain(
dict_chain, False, KEY_WOW64_32KEY, needed_rights)
if not DecideArchitecture.Is64Windows():
architect = 0
connected_registy = self.connect_registry()
if (isinstance(dict_chain, dict)
or isinstance(dict_chain, OrderedDict)):
for key, value in dict_chain.iteritems():
if isinstance(value, dict) or isinstance(value, OrderedDict):
temp_dict = OrderedDict()
for my_key, my_value in value.iteritems():
temp_dict[key+"\\"+my_key] = my_value
self.create_registry_from_dict_chain(
temp_dict, False, architect, needed_rights)
else:
if isinstance(value, list):
if len(value)%2 != 0:
#print "Not enough member in the list"
raise AttributeError
else:
new_key = CreateKeyEx(
connected_registy, key, 0,
needed_rights | architect)
temp_dict = OrderedDict(
value[i:i+2] for i in range(
0, len(value), 2))
for my_key, my_value in temp_dict.iteritems():
if my_key == "default":
my_key = None
SetValueEx(
new_key, my_key, 0, REG_SZ, my_value)
else:
new_key = CreateKeyEx(
connected_registy, key, 0,
needed_rights | architect)
SetValueEx(new_key, None, 0, REG_SZ, value)
else:
print "The provided attribute wasn't a dictionary chain"
raise AttributeError
def get_key(self, key_name, needed_rights = KEY_ALL_ACCESS):
"""
Getting a registry value by it's key's name
Can raise KeyError if key is not found in the registry
Keyword arguments:
@param key_name -- The specific key name of which value we
are interested in
@param needed_rights -- SAM rights to access the key
@return -- [key, architect]
key -- Reference to the opened
key handler
architect -- 0 for x86
KEY_WOW64_32KEY or
KEY_WOW64_64KEY
depending where we
found the key on x64
"""
connected_registy = self.connect_registry()
architect = 0
if DecideArchitecture.Is64Windows():
architect = KEY_WOW64_64KEY
try:
key = OpenKey(connected_registy, key_name, 0,
needed_rights | architect)
except WindowsError:
if DecideArchitecture.Is64Windows() and not self.args.different:
try:
architect = KEY_WOW64_32KEY
key = OpenKey(connected_registy, key_name,
0, needed_rights | architect)
except WindowsError:
raise KeyError
else:
raise KeyError
return [key, architect]
def get_key_values(
self, key_name, subkey_list, subroutine = False,
depth = "subkeys"):
"""
Getting registry subkeys value by it's key's name and subkeys
name
Can raise LookupError exception if there are missing data
Can raise AttributeError exception if depth attribute is wrong
Keyword arguments:
@param key_name -- The specific key name of which subkey's
we are interested in
@param subkey_list -- List containing all the subkeys names
which values we are interested in
@param subroutine -- Whether suppress exception about not
having enough results or not
(default: False)
@param depth -- How depth the search should go for
[options: key, subkeys, all]
(default: subkeys)
@return results{} -- Dictionary with the subkey_name - value
combinations as keys and values
"""
if depth == "key":
int_depth = 0;
elif depth == "subkeys":
int_depth = 1;
elif depth == "all":
int_depth = 2;
else:
raise AttributeError
try:
key_and_architect = self.get_key(key_name)
key = key_and_architect[0]
architect = key_and_architect[1]
except KeyError:
#print "%s doesn't exist in the registry" % key_name
raise LookupError
#print "%s found in the registry" % key_name
results = {}
if int_depth >= 1:
for i in xrange(0, QueryInfoKey(key)[0]-1):
skey_name = EnumKey(key, i)
skey = OpenKey(key, skey_name, 0, KEY_ALL_ACCESS | architect)
if int_depth == 2 and QueryInfoKey(skey)[0] > 0:
for key, value in self.get_key_values(
skey_name, subkey_list, True, depth).iteritems():
results[key] = value
for subkey_name in subkey_list:
try:
results[subkey_name] = QueryValueEx(
skey, subkey_name)[0]
except OSError as e:
if e.errno == errno.ENOENT:
#print ("%s doesn't exist in this" % subkey_name
# " subkey")
pass
skey.Close()
if not results or len(results) != len(subkey_list):
for subkey_name in subkey_list:
try:
results[subkey_name] = QueryValueEx(key, subkey_name)[0]
except OSError as e:
pass
key.Close()
if len(results) != len(subkey_list):
#print "We are missing important variables"
raise LookupError
return results
def get_key_value(
self, key_name, subkey_name, subroutine = None, depth = None):
"""
This is a wrapper for the get_key_values to be easier to use
for single subkeys.
Getting registry subkey value by it's key's name and subkey
name
Keyword arguments:
@param key_name -- The specific key name of which subkey's
we are interested in
@param subkey_name -- The specific subkey name which value we
are interested in
@param subroutine -- can be found at: get_key_values
@param depth -- can be found at: get_key_values
@return value -- Value of the specific subkey
"""
try:
if subroutine is None:
return self.get_key_values(key_name,
[subkey_name])[subkey_name]
elif depth is None:
return self.get_key_values(key_name, [subkey_name],
subroutine)[subkey_name]
else:
return self.get_key_values(key_name, [subkey_name],
subroutine, depth)[subkey_name]
except:
raise
class DecideArchitecture:
"""
Helper class to get the true ProgramFiles directory.
This class doesn't depend on Phyton or Windows architecture.
"""
@staticmethod
def Is64Windows():
return 'PROGRAMFILES(X86)' in os.environ
@staticmethod
def GetProgramFiles32():
if DecideArchitecture.Is64Windows():
return os.environ['PROGRAMFILES(X86)']
else:
return os.environ['PROGRAMFILES']
@staticmethod
def GetProgramFiles64():
if DecideArchitecture.Is64Windows():
return os.environ['PROGRAMW6432']
else:
return None
def main(): def main():
try: try:
args = parse_arguments() args = parse_arguments()
nx_install_location = None nx_install_location = None
while nx_install_location is None: while nx_install_location is None:
print "Checking whether NX Client for Windows is installed" print "Checking whether NX Client for Windows is installed"
handler = RegistryHandler() handler = windowsclasses.RegistryHandler()
try: try:
nx_install_location = handler.get_key_value( nx_install_location = handler.get_key_value(
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"+ "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"+
...@@ -370,6 +65,5 @@ def main(): ...@@ -370,6 +65,5 @@ def main():
except: except:
pass pass
if __name__ == "__main__": if __name__ == "__main__":
main() main()
\ No newline at end of file
...@@ -8,7 +8,7 @@ Pywin32 installer for CIRCLE client application ...@@ -8,7 +8,7 @@ Pywin32 installer for CIRCLE client application
import os import os
import sys import sys
import subprocess import subprocess
from nx_client_installer import DecideArchitecture import windowsclasses
def main(): def main():
...@@ -27,7 +27,7 @@ def main(): ...@@ -27,7 +27,7 @@ def main():
else: else:
pywin32_version = str(219) pywin32_version = str(219)
if sys.hexversion < 0x02070000: if sys.hexversion < 0x02070000:
if DecideArchitecture.Is64Windows(): if windowsclasses.DecideArchitecture.Is64Windows():
subprocess.Popen( subprocess.Popen(
"%s\\x64\\pywin32-%s.win-amd64-py2.6.exe" % ( "%s\\x64\\pywin32-%s.win-amd64-py2.6.exe" % (
os.path.dirname(os.path.realpath(__file__)), os.path.dirname(os.path.realpath(__file__)),
...@@ -38,7 +38,7 @@ def main(): ...@@ -38,7 +38,7 @@ def main():
os.path.dirname(os.path.realpath(__file__)), os.path.dirname(os.path.realpath(__file__)),
pywin32_version)).wait() pywin32_version)).wait()
elif sys.hexversion < 0x02080000: elif sys.hexversion < 0x02080000:
if DecideArchitecture.Is64Windows(): if windowsclasses.DecideArchitecture.Is64Windows():
subprocess.Popen( subprocess.Popen(
"%s\\x64\\pywin32-%s.win-amd64-py2.7.exe" % ( "%s\\x64\\pywin32-%s.win-amd64-py2.7.exe" % (
os.path.dirname(os.path.realpath(__file__)), os.path.dirname(os.path.realpath(__file__)),
......
winshell==0.6
\ No newline at end of file
...@@ -9,11 +9,12 @@ import os ...@@ -9,11 +9,12 @@ import os
import argparse import argparse
import subprocess import subprocess
import pythoncom import pythoncom
import shutil
from win32com.shell import shell, shellcon from win32com.shell import shell, shellcon
from nx_client_installer import DecideArchitecture, RegistryHandler, Struct import windowsclasses
try: try:
from collections import * from collections import *
except ImporError: except ImportError:
from OrderedDict import * from OrderedDict import *
...@@ -32,10 +33,12 @@ def parse_arguments(): ...@@ -32,10 +33,12 @@ def parse_arguments():
"first the proper driver.", type=str, default="firefox", "first the proper driver.", type=str, default="firefox",
required=False, choices=['firefox', 'chrome', required=False, choices=['firefox', 'chrome',
'iexplore', 'opera']) 'iexplore', 'opera'])
if DecideArchitecture.Is64Windows(): if windowsclasses.DecideArchitecture.Is64Windows():
local_default = DecideArchitecture.GetProgramFiles64()+"\\CIRCLE\\" local_default = (windowsclasses.DecideArchitecture.GetProgramFiles64()
+"\\CIRCLE\\")
else: else:
local_default = DecideArchitecture.GetProgramFiles32()+"\\CIRCLE\\" local_default = (windowsclasses.DecideArchitecture.GetProgramFiles32()
+"\\CIRCLE\\")
if (not os.path.exists(local_default[:-1]) if (not os.path.exists(local_default[:-1])
and os.path.exists(os.environ['APPDATA']+"\\CIRCLE")): and os.path.exists(os.environ['APPDATA']+"\\CIRCLE")):
local_default = os.environ['APPDATA']+"\\CIRCLE\\" local_default = os.environ['APPDATA']+"\\CIRCLE\\"
...@@ -53,7 +56,7 @@ def parse_arguments(): ...@@ -53,7 +56,7 @@ def parse_arguments():
parser.add_argument( parser.add_argument(
"-t", "--target", "-t", "--target",
help="If this is an URL icon, where should it point", help="If this is an URL icon, where should it point",
default="https://pc3.szgt.uni-miskolc.hu/", required=False) default="https://cloud.bme.hu/", required=False)
args = parser.parse_args() args = parser.parse_args()
return args return args
...@@ -69,9 +72,9 @@ def custom_protocol_register(custom_protocol): ...@@ -69,9 +72,9 @@ def custom_protocol_register(custom_protocol):
raise AttributeError raise AttributeError
print "\t"+custom_protocol.iterkeys().next() print "\t"+custom_protocol.iterkeys().next()
try: try:
custom_arguments = Struct() custom_arguments = windowsclasses.Struct()
custom_arguments.registry = "HKCR" custom_arguments.registry = "HKCR"
handler = RegistryHandler(custom_arguments) handler = windowsclasses.RegistryHandler(custom_arguments)
handler.create_registry_from_dict_chain(custom_protocol, True) handler.create_registry_from_dict_chain(custom_protocol, True)
print "\t\tDone!" print "\t\tDone!"
except: except:
...@@ -95,9 +98,10 @@ def main(): ...@@ -95,9 +98,10 @@ def main():
pythoncom.CLSCTX_INPROC_SERVER, pythoncom.CLSCTX_INPROC_SERVER,
shell.IID_IShellLink shell.IID_IShellLink
) )
desktop_path = shell.SHGetFolderPath (0, shellcon.CSIDL_DESKTOP, 0, 0) desktop_path = shell.SHGetFolderPath (
0, shellcon.CSIDL_DESKTOP, 0, 0)
if args.remove: if args.remove:
location =os.path.join(desktop_path, "Cloud GUI") location = os.path.join(desktop_path, "Cloud GUI")
if os.path.isfile("%s%s" % (location, ".lnk")): if os.path.isfile("%s%s" % (location, ".lnk")):
os.remove("%s%s" % (location, ".lnk")) os.remove("%s%s" % (location, ".lnk"))
if os.path.isfile("%s%s" % (location, ".url")): if os.path.isfile("%s%s" % (location, ".url")):
...@@ -126,9 +130,10 @@ def main(): ...@@ -126,9 +130,10 @@ def main():
0, shellcon.CSIDL_DESKTOP, 0, 0) 0, shellcon.CSIDL_DESKTOP, 0, 0)
persist_file = shortcut.QueryInterface( persist_file = shortcut.QueryInterface(
pythoncom.IID_IPersistFile) pythoncom.IID_IPersistFile)
persist_file.Save( location = os.path.join(desktop_path, "Cloud GUI.lnk")
os.path.join(desktop_path, "Cloud GUI.lnk"), 0) persist_file.Save(location, 0)
print "Icon successfully created on desktop" print "Icon successfully created on desktop"
shutil.copy(location, args.location)
print "Creating custom URL protocol handlers" print "Creating custom URL protocol handlers"
try: try:
custom_ssh = OrderedDict( custom_ssh = OrderedDict(
......
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Place holder for all windows specific frequently used classes.
Currently here:
RegistryHandler - Registry based operations
DecideArchitecture - Accurate way to decide operating system architecture
"""
import os
import argparse
import errno
from _winreg import *
try:
from collections import *
except ImporError:
from OrderedDict import *
def parse_arguments():
"""
Argument parser, based on argparse module
Keyword arguments:
@return args -- arguments given by console
"""
parser = argparse.ArgumentParser()
parser.add_argument(
"-g", "--global",
help="Whether we want to edit registry globally or just locally",
action="store_true")
parser.add_argument(
"-d", "--different",
help="Only handle the architecture specific registry area",
action="store_true")
parser.add_argument(
"-r", "--registry",
help="Which HKEY_* const registry type the program should use",
type=str, choices=['HKLM', 'HKCR', 'HKCU', 'HKU', 'HKPD', 'HKCC'],
default="HKLM")
args = parser.parse_args()
return args
def main():
return RegistryHandler(parse_arguments())
class Struct:
"""
Parameter bypassing struct
"""
pass
class RegistryHandler:
"""
Registry handling class, makes registry based queries and
manipulations easier.
This class can handle WOW64 based application differently and none
differently (default)
"""
def __init__(self, args = None):
"""Initialise RegistryHandler
Keyword arguments:
@param args -- The arguments that decide how the we should
handle the registry
args.registry -- What base registry should we use
(default: HKLM)
Raises AttributeError if not supported base registry type is
given
args.different -- Whether we handle registry redirection or not
"""
if args is None:
self.args = Struct()
self.args.different = None
self.args.registry = None
else:
if not hasattr(args, 'different'):
args.different = None
if not hasattr(args, 'registry'):
args.registry = None
self.args = args
if self.args.different is None:
self.args.different = False
if self.args.registry is None or self.args.registry == "HKLM":
self.args.registry = HKEY_LOCAL_MACHINE
elif self.args.registry == "HKCR":
self.args.registry = HKEY_CLASSES_ROOT
elif self.args.registry == "HKCU":
self.args.registry = HKEY_CURRENT_USER
elif self.args.registry == "HKU":
self.args.registry = HKEY_USERS
elif self.args.registry == "HKPD":
self.args.registry = HKEY_PERFORMANCE_DATA
elif self.args.registry == "HKCC":
self.args.registry = HKEY_CURRENT_CONFIG
else:
#print "Non supported registry type"
raise AttributeError
def connect_registry(self):
"""
Getting a registry open
Keyword arguments:
@return connected_registy -- Reference to the newly opened
registry
"""
return ConnectRegistry(None,self.args.registry)
def create_registry_from_dict_chain(
self, dict_chain, both = False, architect = KEY_WOW64_64KEY,
needed_rights = KEY_ALL_ACCESS):
""""
Create registry key and value multilevel tree by chained
dictionaries.
Can raise AttributeError if the provided dict chain isn't
correct
Keyword arguments:
@param key_value_chain -- The dict chain containing all the
information
@param both -- Whether create the registry in WOW64
node too
@param architect -- The current registry view (
only change it if we want to fill the
WOW6432 registry only [both = False],
on x64 windows)
@param needed_rights -- SAM rights to access the key
"""
if both and architect is KEY_WOW64_64KEY:
self.create_registry_from_dict_chain(
dict_chain, False, KEY_WOW64_32KEY, needed_rights)
if not DecideArchitecture.Is64Windows():
architect = 0
connected_registy = self.connect_registry()
if (isinstance(dict_chain, dict)
or isinstance(dict_chain, OrderedDict)):
for key, value in dict_chain.iteritems():
if isinstance(value, dict) or isinstance(value, OrderedDict):
temp_dict = OrderedDict()
for my_key, my_value in value.iteritems():
temp_dict[key+"\\"+my_key] = my_value
self.create_registry_from_dict_chain(
temp_dict, False, architect, needed_rights)
else:
if isinstance(value, list):
if len(value)%2 != 0:
#print "Not enough member in the list"
raise AttributeError
else:
new_key = CreateKeyEx(
connected_registy, key, 0,
needed_rights | architect)
temp_dict = OrderedDict(
value[i:i+2] for i in range(
0, len(value), 2))
for my_key, my_value in temp_dict.iteritems():
if my_key == "default":
my_key = None
SetValueEx(
new_key, my_key, 0, REG_SZ, my_value)
else:
new_key = CreateKeyEx(
connected_registy, key, 0,
needed_rights | architect)
SetValueEx(new_key, None, 0, REG_SZ, value)
else:
print "The provided attribute wasn't a dictionary chain"
raise AttributeError
def get_key(self, key_name, needed_rights = KEY_ALL_ACCESS):
"""
Getting a registry value by it's key's name
Can raise KeyError if key is not found in the registry
Keyword arguments:
@param key_name -- The specific key name of which value we
are interested in
@param needed_rights -- SAM rights to access the key
@return -- [key, architect]
key -- Reference to the opened
key handler
architect -- 0 for x86
KEY_WOW64_32KEY or
KEY_WOW64_64KEY
depending where we
found the key on x64
"""
connected_registy = self.connect_registry()
architect = 0
if DecideArchitecture.Is64Windows():
architect = KEY_WOW64_64KEY
try:
key = OpenKey(connected_registy, key_name, 0,
needed_rights | architect)
except WindowsError:
if DecideArchitecture.Is64Windows() and not self.args.different:
try:
architect = KEY_WOW64_32KEY
key = OpenKey(connected_registy, key_name,
0, needed_rights | architect)
except WindowsError:
raise KeyError
else:
raise KeyError
return [key, architect]
def get_key_values(
self, key_name, subkey_list, subroutine = False,
depth = "subkeys"):
"""
Getting registry subkeys value by it's key's name and subkeys
name
Can raise LookupError exception if there are missing data
Can raise AttributeError exception if depth attribute is wrong
Keyword arguments:
@param key_name -- The specific key name of which subkey's
we are interested in
@param subkey_list -- List containing all the subkeys names
which values we are interested in
@param subroutine -- Whether suppress exception about not
having enough results or not
(default: False)
@param depth -- How depth the search should go for
[options: key, subkeys, all]
(default: subkeys)
@return results{} -- Dictionary with the subkey_name - value
combinations as keys and values
"""
if depth == "key":
int_depth = 0;
elif depth == "subkeys":
int_depth = 1;
elif depth == "all":
int_depth = 2;
else:
raise AttributeError
try:
key_and_architect = self.get_key(key_name)
key = key_and_architect[0]
architect = key_and_architect[1]
except KeyError:
#print "%s doesn't exist in the registry" % key_name
raise LookupError
#print "%s found in the registry" % key_name
results = {}
if int_depth >= 1:
for i in xrange(0, QueryInfoKey(key)[0]-1):
skey_name = EnumKey(key, i)
skey = OpenKey(key, skey_name, 0, KEY_ALL_ACCESS | architect)
if int_depth == 2 and QueryInfoKey(skey)[0] > 0:
for key, value in self.get_key_values(
skey_name, subkey_list, True, depth).iteritems():
results[key] = value
for subkey_name in subkey_list:
try:
results[subkey_name] = QueryValueEx(
skey, subkey_name)[0]
except OSError as e:
if e.errno == errno.ENOENT:
#print ("%s doesn't exist in this" % subkey_name
# " subkey")
pass
skey.Close()
if not results or len(results) != len(subkey_list):
for subkey_name in subkey_list:
try:
results[subkey_name] = QueryValueEx(key, subkey_name)[0]
except OSError as e:
pass
key.Close()
if len(results) != len(subkey_list):
#print "We are missing important variables"
raise LookupError
return results
def get_key_value(
self, key_name, subkey_name, subroutine = None, depth = None):
"""
This is a wrapper for the get_key_values to be easier to use
for single subkeys.
Getting registry subkey value by it's key's name and subkey
name
Keyword arguments:
@param key_name -- The specific key name of which subkey's
we are interested in
@param subkey_name -- The specific subkey name which value we
are interested in
@param subroutine -- can be found at: get_key_values
@param depth -- can be found at: get_key_values
@return value -- Value of the specific subkey
"""
try:
if subroutine is None:
return self.get_key_values(key_name,
[subkey_name])[subkey_name]
elif depth is None:
return self.get_key_values(key_name, [subkey_name],
subroutine)[subkey_name]
else:
return self.get_key_values(key_name, [subkey_name],
subroutine, depth)[subkey_name]
except:
raise
class DecideArchitecture:
"""
Helper class to get the true ProgramFiles directory.
This class doesn't depend on Phyton or Windows architecture.
"""
@staticmethod
def Is64Windows():
return 'PROGRAMFILES(X86)' in os.environ
@staticmethod
def GetProgramFiles32():
if DecideArchitecture.Is64Windows():
return os.environ['PROGRAMFILES(X86)']
else:
return os.environ['PROGRAMFILES']
@staticmethod
def GetProgramFiles64():
if DecideArchitecture.Is64Windows():
return os.environ['PROGRAMW6432']
else:
return None
\ No newline at end of file
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
A cloudban létrehozott virtuális gépekhez történő kapcsolódást segítő Main program of the Client written for CIRCLE Cloud.
program The Client job is to help the ease of use of the cloud system.
""" """
import platform import platform
...@@ -21,22 +21,22 @@ except ImporError: ...@@ -21,22 +21,22 @@ except ImporError:
class Struct: class Struct:
""" """
Paraméterek átadására használt struktúra A struct used for parameter passing
Keyword arguments: Keyword arguments:
state -- A virtuális gép állapota, azt figyeljük, hogy fut-e state -- State of the Virtual Computer (running, etc..)
protocol -- SSH, NX és RDP lehetséges protocol -- SSH, NX and RDP possible
host -- A virtuális gép címe host -- Address of the Virtual Computer
port -- Ezen a porton csatlakozunk a virtuális géphez port -- The port where we can access the Virtual Computer
user -- Csatlakozáshoz használt név user -- Username used for the connection
password -- Csatlakozáshoz használt jelszó password -- Password used for the connection
""" """
pass pass
def parse_arguments(): def parse_arguments():
""" """
Argument parser, argparse modulon alapszik Argument parser, based on the argparse module
Keyword arguments: Keyword arguments:
@return args -- arguments given by console @return args -- arguments given by console
...@@ -53,18 +53,16 @@ def parse_arguments(): ...@@ -53,18 +53,16 @@ def parse_arguments():
"first the proper driver.", type=str, "first the proper driver.", type=str,
choices=['firefox', 'chrome', 'ie', 'opera'], choices=['firefox', 'chrome', 'ie', 'opera'],
default="firefox") default="firefox")
parser.add_argument(
"-o", "--old", help="Use old interface", action="store_true")
args = parser.parse_args() args = parser.parse_args()
return args return args
class Browser: class Browser:
""" """
Browser inicializálás Browser initialisation
Keyword arguments: Keyword arguments:
@param args -- Az args.driver paraméterrel meghatározhatjuk, @param args -- args.driver tells us which installed browser
melyik böngészőt akarjuk használni. we want to use with selenium.
""" """
def __init__(self, args): def __init__(self, args):
self.args = args self.args = args
...@@ -80,8 +78,7 @@ class Browser: ...@@ -80,8 +78,7 @@ class Browser:
def login(self): def login(self):
""" """
Címtáras beléptetés a parancssorban megadott paraméterek Eduid login based on the given console arguments
alapján
""" """
driver = self.driver driver = self.driver
args = self.args args = self.args
...@@ -95,59 +92,21 @@ class Browser: ...@@ -95,59 +92,21 @@ class Browser:
driver.find_element_by_css_selector( driver.find_element_by_css_selector(
"input[type='submit']").click() "input[type='submit']").click()
def old_main(self):
"""
A régi webes felület használata
Keyword arguments:
@return vm -- Virtuális gép csatlakozásához szükséges
paraméterek
"""
vm = Struct()
driver = self.driver
driver.maximize_window()
driver.get("https://cloud.ik.bme.hu/info/")
driver.find_element_by_css_selector("a[href*='/login/']").click()
self.login()
vm.state, vm.protocol = "", "NONE"
try:
while vm.state.upper()[:3] not in ("FUT", "RUN"):
element = WebDriverWait(driver, 7200).until(
EC.presence_of_element_located((
By.CSS_SELECTOR,
"input.hidden-password.shown[type='text']")))
vm.password = element.get_attribute("value")
vm.state = driver.find_element_by_css_selector(
"#state > div > p").text
vm.protocol = driver.find_element_by_css_selector(
"#vm-credentials > div > table > tbody > "+
"tr:nth-child(1) > td").text
vm.host,vm.port = driver.find_element_by_css_selector(
"#vm-credentials > div > table > tbody > "+
"tr:nth-child(2) > td").text.split(':')
vm.user = driver.find_element_by_css_selector(
"#vm-credentials > div > table > tbody > "+
"tr:nth-child(4) > td").text
driver.find_element_by_css_selector("a[href*='/logout/']").click()
except:
print "Browser session timed out!"
raise
return vm
def main(self): def main(self):
""" """
Az új webes felület használata Use of the https://cloud.bme.hu/
Keyword arguments: Keyword arguments:
@return vm -- Virtuális gép csatlakozásához szükséges @return vm -- Necessarily parameters to connect
paraméterek to the Virtual Machine
""" """
vm = Struct() vm = Struct()
driver = self.driver driver = self.driver
driver.maximize_window() driver.maximize_window()
driver.get("https://pc3.szgt.uni-miskolc.hu/") driver.get("https://cloud.bme.hu/")
#driver.find_element_by_css_selector("a[href*='/login/']").click() # driver.find_element_by_css_selector("a[href*='/login/']").click()
#self.login() # self.login()
vm.state, vm.protocol = "", "NONE" vm.state, vm.protocol = "", "NONE"
try: try:
while vm.state.upper()[:3] not in ("FUT", "RUN"): while vm.state.upper()[:3] not in ("FUT", "RUN"):
...@@ -157,7 +116,7 @@ class Browser: ...@@ -157,7 +116,7 @@ class Browser:
"#vm-details-pw-eye.fa.fa-eye-slash"))) "#vm-details-pw-eye.fa.fa-eye-slash")))
vm.state = driver.find_element_by_css_selector( vm.state = driver.find_element_by_css_selector(
"#vm-details-state > span").text "#vm-details-state > span").text
#cl: connection string converted to list # cl: connection string converted to list
cl = driver.find_element_by_css_selector( cl = driver.find_element_by_css_selector(
"#vm-details-connection-string").get_attribute( "#vm-details-connection-string").get_attribute(
"value").split() "value").split()
...@@ -177,14 +136,7 @@ class Browser: ...@@ -177,14 +136,7 @@ class Browser:
def main(): def main():
""" """
Főprogram Main program
Job:
beolvassuk a paramétereket
megnyitjuk a kiválasztott böngészőben a weboldalt
bejelentkezünk a címtárba
kiválasztjuk a futtatni kívánt klienst
kapcsolódunk a klienshez
""" """
try: try:
args = parse_arguments() args = parse_arguments()
...@@ -196,14 +148,8 @@ def main(): ...@@ -196,14 +148,8 @@ def main():
vm.state = "RUN" vm.state = "RUN"
else: else:
browser = Browser(args) browser = Browser(args)
try:
if args.old:
vm = browser.old_main()
else:
vm = browser.main() vm = browser.main()
browser.driver.quit() browser.driver.quit()
except:
raise
if platform.system() == "Linux": if platform.system() == "Linux":
from cloud_connect_from_linux import connect from cloud_connect_from_linux import connect
elif platform.system() == "Windows": elif platform.system() == "Windows":
......
#!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
## """
# Távoli klienshez csatlakozás windows OS alól Configuration of the Windows specific tools to enhance the ease of use
## of the CIRCLE cloud. Handles the auto launch and auto configuration
of these specific connectivity programs.
"""
import time import time
import os import os
...@@ -12,16 +15,19 @@ import win32crypt ...@@ -12,16 +15,19 @@ import win32crypt
import binascii import binascii
import nxkey import nxkey
##
# A távoli klienshez csatlakozás valósítja majd meg windows alól
# @param vm Paraméterek a csatlakozáshoz
# vm.protocol SSH, NX és RDP lehetséges
# vm.host A virtuális gép címe
# vm.port Ezen a porton csatlakozunk a virtuális géphez
# vm.user Csatlakozáshoz használt név
# vm.password Csatlakozáshoz használt jelszó
#
def connect(vm): def connect(vm):
"""
Handles to connection to the Virtual Machines from the local
machine
Keyword arguments:
vm.protocol -- SSH, NX and RDP possible
vm.host -- Address of the Virtual Computer
vm.port -- The port where we can access the Virtual Computer
vm.user -- Username used for the connection
vm.password -- Password used for the connection
"""
if vm.protocol == "SSH": if vm.protocol == "SSH":
arguments = "-ssh -P %s -pw %s %s@%s" % (vm.port, vm.password, vm.user, vm.host) arguments = "-ssh -P %s -pw %s %s@%s" % (vm.port, vm.password, vm.user, vm.host)
subprocess.Popen("putty.exe "+arguments, shell = True) subprocess.Popen("putty.exe "+arguments, shell = True)
...@@ -64,6 +70,7 @@ def connect(vm): ...@@ -64,6 +70,7 @@ def connect(vm):
f.close() f.close()
subprocess.Popen(config_file, shell = True) subprocess.Popen(config_file, shell = True)
NX_template = """<!DOCTYPE NXClientSettings> NX_template = """<!DOCTYPE NXClientSettings>
<NXClientSettings application="nxclient" version="1.3" > <NXClientSettings application="nxclient" version="1.3" >
<group name="General" > <group name="General" >
......
...@@ -2,23 +2,16 @@ ...@@ -2,23 +2,16 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
NX Client for Windows installer with RegistryHandler and NX Client for Windows installer
DecideArchitecture classes.
Checks whether NX Client for Windows is installed in the system, the Checks whether NX Client for Windows is installed in the system, the
classes used for this process are used for other operations too. classes used for this process are used for other operations too.
""" """
import os import os
import sys
import argparse import argparse
import errno
import subprocess import subprocess
import time import time
from _winreg import * import windowsclasses
try:
from collections import *
except ImporError:
from OrderedDict import *
def parse_arguments(): def parse_arguments():
...@@ -29,10 +22,12 @@ def parse_arguments(): ...@@ -29,10 +22,12 @@ def parse_arguments():
@return args -- arguments given by console @return args -- arguments given by console
""" """
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
if DecideArchitecture.Is64Windows(): if windowsclasses.DecideArchitecture.Is64Windows():
local_default = DecideArchitecture.GetProgramFiles64()+"\\CIRCLE\\" local_default = (windowsclasses.DecideArchitecture.GetProgramFiles64()
+"\\CIRCLE\\")
else: else:
local_default = DecideArchitecture.GetProgramFiles32()+"\\CIRCLE\\" local_default = (windowsclasses.DecideArchitecture.GetProgramFiles32()
+"\\CIRCLE\\")
if (not os.path.exists(local_default[:-1]) if (not os.path.exists(local_default[:-1])
and os.path.exists(os.environ['APPDATA']+"\\CIRCLE")): and os.path.exists(os.environ['APPDATA']+"\\CIRCLE")):
local_default = os.environ['APPDATA']+"\\CIRCLE\\" local_default = os.environ['APPDATA']+"\\CIRCLE\\"
...@@ -40,316 +35,16 @@ def parse_arguments(): ...@@ -40,316 +35,16 @@ def parse_arguments():
"-l", "--location", "-l", "--location",
help="Location of the client files in the system", help="Location of the client files in the system",
default=local_default) default=local_default)
parser.add_argument(
"-g", "--global",
help="Whether we want to edit registry globally or just locally",
action="store_true")
parser.add_argument(
"-d", "--different",
help="Only handle the architecture specific registry area",
action="store_true")
parser.add_argument(
"-r", "--registry",
help="Which HKEY_* const registry type the program should use",
type=str, choices=['HKLM', 'HKCR', 'HKCU', 'HKU', 'HKPD', 'HKCC'],
default="HKLM")
args = parser.parse_args() args = parser.parse_args()
return args return args
class Struct:
"""
Parameter bypassing struct
"""
pass
class RegistryHandler:
"""
Registry handling class, makes registry based queries and
manipulations easier.
This class can handle WOW64 based application differently and none
differently (default)
"""
def __init__(self, args = None):
"""Initialise RegistryHandler
Keyword arguments:
@param args -- The arguments that decide how the we should
handle the registry
args.registry -- What base registry should we use
(default: HKLM)
Raises AttributeError if not supported base registry type is
given
args.different -- Whether we handle registry redirection or not
"""
if args is None:
self.args = Struct()
self.args.different = None
self.args.registry = None
else:
if not hasattr(args, 'different'):
args.different = None
if not hasattr(args, 'registry'):
args.registry = None
self.args = args
if self.args.different is None:
self.args.different = False
if self.args.registry is None or self.args.registry == "HKLM":
self.args.registry = HKEY_LOCAL_MACHINE
elif self.args.registry == "HKCR":
self.args.registry = HKEY_CLASSES_ROOT
elif self.args.registry == "HKCU":
self.args.registry = HKEY_CURRENT_USER
elif self.args.registry == "HKU":
self.args.registry = HKEY_USERS
elif self.args.registry == "HKPD":
self.args.registry = HKEY_PERFORMANCE_DATA
elif self.args.registry == "HKCC":
self.args.registry = HKEY_CURRENT_CONFIG
else:
#print "Non supported registry type"
raise AttributeError
def connect_registry(self):
"""
Getting a registry open
Keyword arguments:
@return connected_registy -- Reference to the newly opened
registry
"""
return ConnectRegistry(None,self.args.registry)
def create_registry_from_dict_chain(
self, dict_chain, both = False, architect = KEY_WOW64_64KEY,
needed_rights = KEY_ALL_ACCESS):
""""
Create registry key and value multilevel tree by chained
dictionaries.
Can raise AttributeError if the provided dict chain isn't
correct
Keyword arguments:
@param key_value_chain -- The dict chain containing all the
information
@param both -- Whether create the registry in WOW64
node too
@param architect -- The current registry view (
only change it if we want to fill the
WOW6432 registry only [both = False],
on x64 windows)
@param needed_rights -- SAM rights to access the key
"""
if both and architect is KEY_WOW64_64KEY:
self.create_registry_from_dict_chain(
dict_chain, False, KEY_WOW64_32KEY, needed_rights)
if not DecideArchitecture.Is64Windows():
architect = 0
connected_registy = self.connect_registry()
if (isinstance(dict_chain, dict)
or isinstance(dict_chain, OrderedDict)):
for key, value in dict_chain.iteritems():
if isinstance(value, dict) or isinstance(value, OrderedDict):
temp_dict = OrderedDict()
for my_key, my_value in value.iteritems():
temp_dict[key+"\\"+my_key] = my_value
self.create_registry_from_dict_chain(
temp_dict, False, architect, needed_rights)
else:
if isinstance(value, list):
if len(value)%2 != 0:
#print "Not enough member in the list"
raise AttributeError
else:
new_key = CreateKeyEx(
connected_registy, key, 0,
needed_rights | architect)
temp_dict = OrderedDict(
value[i:i+2] for i in range(
0, len(value), 2))
for my_key, my_value in temp_dict.iteritems():
if my_key == "default":
my_key = None
SetValueEx(
new_key, my_key, 0, REG_SZ, my_value)
else:
new_key = CreateKeyEx(
connected_registy, key, 0,
needed_rights | architect)
SetValueEx(new_key, None, 0, REG_SZ, value)
else:
print "The provided attribute wasn't a dictionary chain"
raise AttributeError
def get_key(self, key_name, needed_rights = KEY_ALL_ACCESS):
"""
Getting a registry value by it's key's name
Can raise KeyError if key is not found in the registry
Keyword arguments:
@param key_name -- The specific key name of which value we
are interested in
@param needed_rights -- SAM rights to access the key
@return -- [key, architect]
key -- Reference to the opened
key handler
architect -- 0 for x86
KEY_WOW64_32KEY or
KEY_WOW64_64KEY
depending where we
found the key on x64
"""
connected_registy = self.connect_registry()
architect = 0
if DecideArchitecture.Is64Windows():
architect = KEY_WOW64_64KEY
try:
key = OpenKey(connected_registy, key_name, 0,
needed_rights | architect)
except WindowsError:
if DecideArchitecture.Is64Windows() and not self.args.different:
try:
architect = KEY_WOW64_32KEY
key = OpenKey(connected_registy, key_name,
0, needed_rights | architect)
except WindowsError:
raise KeyError
else:
raise KeyError
return [key, architect]
def get_key_values(
self, key_name, subkey_list, subroutine = False,
depth = "subkeys"):
"""
Getting registry subkeys value by it's key's name and subkeys
name
Can raise LookupError exception if there are missing data
Can raise AttributeError exception if depth attribute is wrong
Keyword arguments:
@param key_name -- The specific key name of which subkey's
we are interested in
@param subkey_list -- List containing all the subkeys names
which values we are interested in
@param subroutine -- Whether suppress exception about not
having enough results or not
(default: False)
@param depth -- How depth the search should go for
[options: key, subkeys, all]
(default: subkeys)
@return results{} -- Dictionary with the subkey_name - value
combinations as keys and values
"""
if depth == "key":
int_depth = 0;
elif depth == "subkeys":
int_depth = 1;
elif depth == "all":
int_depth = 2;
else:
raise AttributeError
try:
key_and_architect = self.get_key(key_name)
key = key_and_architect[0]
architect = key_and_architect[1]
except KeyError:
#print "%s doesn't exist in the registry" % key_name
raise LookupError
#print "%s found in the registry" % key_name
results = {}
if int_depth >= 1:
for i in xrange(0, QueryInfoKey(key)[0]-1):
skey_name = EnumKey(key, i)
skey = OpenKey(key, skey_name, 0, KEY_ALL_ACCESS | architect)
if int_depth == 2 and QueryInfoKey(skey)[0] > 0:
for key, value in self.get_key_values(
skey_name, subkey_list, True, depth).iteritems():
results[key] = value
for subkey_name in subkey_list:
try:
results[subkey_name] = QueryValueEx(
skey, subkey_name)[0]
except OSError as e:
if e.errno == errno.ENOENT:
#print ("%s doesn't exist in this" % subkey_name
# " subkey")
pass
skey.Close()
if not results or len(results) != len(subkey_list):
for subkey_name in subkey_list:
try:
results[subkey_name] = QueryValueEx(key, subkey_name)[0]
except OSError as e:
pass
key.Close()
if len(results) != len(subkey_list):
#print "We are missing important variables"
raise LookupError
return results
def get_key_value(
self, key_name, subkey_name, subroutine = None, depth = None):
"""
This is a wrapper for the get_key_values to be easier to use
for single subkeys.
Getting registry subkey value by it's key's name and subkey
name
Keyword arguments:
@param key_name -- The specific key name of which subkey's
we are interested in
@param subkey_name -- The specific subkey name which value we
are interested in
@param subroutine -- can be found at: get_key_values
@param depth -- can be found at: get_key_values
@return value -- Value of the specific subkey
"""
try:
if subroutine is None:
return self.get_key_values(key_name,
[subkey_name])[subkey_name]
elif depth is None:
return self.get_key_values(key_name, [subkey_name],
subroutine)[subkey_name]
else:
return self.get_key_values(key_name, [subkey_name],
subroutine, depth)[subkey_name]
except:
raise
class DecideArchitecture:
"""
Helper class to get the true ProgramFiles directory.
This class doesn't depend on Phyton or Windows architecture.
"""
@staticmethod
def Is64Windows():
return 'PROGRAMFILES(X86)' in os.environ
@staticmethod
def GetProgramFiles32():
if DecideArchitecture.Is64Windows():
return os.environ['PROGRAMFILES(X86)']
else:
return os.environ['PROGRAMFILES']
@staticmethod
def GetProgramFiles64():
if DecideArchitecture.Is64Windows():
return os.environ['PROGRAMW6432']
else:
return None
def main(): def main():
try: try:
args = parse_arguments() args = parse_arguments()
nx_install_location = None nx_install_location = None
while nx_install_location is None: while nx_install_location is None:
print "Checking whether NX Client for Windows is installed" print "Checking whether NX Client for Windows is installed"
handler = RegistryHandler() handler = windowsclasses.RegistryHandler()
try: try:
nx_install_location = handler.get_key_value( nx_install_location = handler.get_key_value(
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"+ "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"+
...@@ -370,6 +65,5 @@ def main(): ...@@ -370,6 +65,5 @@ def main():
except: except:
pass pass
if __name__ == "__main__": if __name__ == "__main__":
main() main()
\ No newline at end of file
...@@ -8,7 +8,7 @@ Pywin32 installer for CIRCLE client application ...@@ -8,7 +8,7 @@ Pywin32 installer for CIRCLE client application
import os import os
import sys import sys
import subprocess import subprocess
from nx_client_installer import DecideArchitecture import windowsclasses
def main(): def main():
...@@ -27,7 +27,7 @@ def main(): ...@@ -27,7 +27,7 @@ def main():
else: else:
pywin32_version = str(219) pywin32_version = str(219)
if sys.hexversion < 0x02070000: if sys.hexversion < 0x02070000:
if DecideArchitecture.Is64Windows(): if windowsclasses.DecideArchitecture.Is64Windows():
subprocess.Popen( subprocess.Popen(
"%s\\x64\\pywin32-%s.win-amd64-py2.6.exe" % ( "%s\\x64\\pywin32-%s.win-amd64-py2.6.exe" % (
os.path.dirname(os.path.realpath(__file__)), os.path.dirname(os.path.realpath(__file__)),
...@@ -38,7 +38,7 @@ def main(): ...@@ -38,7 +38,7 @@ def main():
os.path.dirname(os.path.realpath(__file__)), os.path.dirname(os.path.realpath(__file__)),
pywin32_version)).wait() pywin32_version)).wait()
elif sys.hexversion < 0x02080000: elif sys.hexversion < 0x02080000:
if DecideArchitecture.Is64Windows(): if windowsclasses.DecideArchitecture.Is64Windows():
subprocess.Popen( subprocess.Popen(
"%s\\x64\\pywin32-%s.win-amd64-py2.7.exe" % ( "%s\\x64\\pywin32-%s.win-amd64-py2.7.exe" % (
os.path.dirname(os.path.realpath(__file__)), os.path.dirname(os.path.realpath(__file__)),
......
...@@ -9,11 +9,12 @@ import os ...@@ -9,11 +9,12 @@ import os
import argparse import argparse
import subprocess import subprocess
import pythoncom import pythoncom
import shutil
from win32com.shell import shell, shellcon from win32com.shell import shell, shellcon
from nx_client_installer import DecideArchitecture, RegistryHandler, Struct import windowsclasses
try: try:
from collections import * from collections import *
except ImporError: except ImportError:
from OrderedDict import * from OrderedDict import *
...@@ -32,10 +33,12 @@ def parse_arguments(): ...@@ -32,10 +33,12 @@ def parse_arguments():
"first the proper driver.", type=str, default="firefox", "first the proper driver.", type=str, default="firefox",
required=False, choices=['firefox', 'chrome', required=False, choices=['firefox', 'chrome',
'iexplore', 'opera']) 'iexplore', 'opera'])
if DecideArchitecture.Is64Windows(): if windowsclasses.DecideArchitecture.Is64Windows():
local_default = DecideArchitecture.GetProgramFiles64()+"\\CIRCLE\\" local_default = (windowsclasses.DecideArchitecture.GetProgramFiles64()
+"\\CIRCLE\\")
else: else:
local_default = DecideArchitecture.GetProgramFiles32()+"\\CIRCLE\\" local_default = (windowsclasses.DecideArchitecture.GetProgramFiles32()
+"\\CIRCLE\\")
if (not os.path.exists(local_default[:-1]) if (not os.path.exists(local_default[:-1])
and os.path.exists(os.environ['APPDATA']+"\\CIRCLE")): and os.path.exists(os.environ['APPDATA']+"\\CIRCLE")):
local_default = os.environ['APPDATA']+"\\CIRCLE\\" local_default = os.environ['APPDATA']+"\\CIRCLE\\"
...@@ -53,7 +56,7 @@ def parse_arguments(): ...@@ -53,7 +56,7 @@ def parse_arguments():
parser.add_argument( parser.add_argument(
"-t", "--target", "-t", "--target",
help="If this is an URL icon, where should it point", help="If this is an URL icon, where should it point",
default="https://pc3.szgt.uni-miskolc.hu/", required=False) default="https://cloud.bme.hu/", required=False)
args = parser.parse_args() args = parser.parse_args()
return args return args
...@@ -69,9 +72,9 @@ def custom_protocol_register(custom_protocol): ...@@ -69,9 +72,9 @@ def custom_protocol_register(custom_protocol):
raise AttributeError raise AttributeError
print "\t"+custom_protocol.iterkeys().next() print "\t"+custom_protocol.iterkeys().next()
try: try:
custom_arguments = Struct() custom_arguments = windowsclasses.Struct()
custom_arguments.registry = "HKCR" custom_arguments.registry = "HKCR"
handler = RegistryHandler(custom_arguments) handler = windowsclasses.RegistryHandler(custom_arguments)
handler.create_registry_from_dict_chain(custom_protocol, True) handler.create_registry_from_dict_chain(custom_protocol, True)
print "\t\tDone!" print "\t\tDone!"
except: except:
...@@ -95,9 +98,10 @@ def main(): ...@@ -95,9 +98,10 @@ def main():
pythoncom.CLSCTX_INPROC_SERVER, pythoncom.CLSCTX_INPROC_SERVER,
shell.IID_IShellLink shell.IID_IShellLink
) )
desktop_path = shell.SHGetFolderPath (0, shellcon.CSIDL_DESKTOP, 0, 0) desktop_path = shell.SHGetFolderPath (
0, shellcon.CSIDL_DESKTOP, 0, 0)
if args.remove: if args.remove:
location =os.path.join(desktop_path, "Cloud GUI") location = os.path.join(desktop_path, "Cloud GUI")
if os.path.isfile("%s%s" % (location, ".lnk")): if os.path.isfile("%s%s" % (location, ".lnk")):
os.remove("%s%s" % (location, ".lnk")) os.remove("%s%s" % (location, ".lnk"))
if os.path.isfile("%s%s" % (location, ".url")): if os.path.isfile("%s%s" % (location, ".url")):
...@@ -126,9 +130,10 @@ def main(): ...@@ -126,9 +130,10 @@ def main():
0, shellcon.CSIDL_DESKTOP, 0, 0) 0, shellcon.CSIDL_DESKTOP, 0, 0)
persist_file = shortcut.QueryInterface( persist_file = shortcut.QueryInterface(
pythoncom.IID_IPersistFile) pythoncom.IID_IPersistFile)
persist_file.Save( location = os.path.join(desktop_path, "Cloud GUI.lnk")
os.path.join(desktop_path, "Cloud GUI.lnk"), 0) persist_file.Save(location, 0)
print "Icon successfully created on desktop" print "Icon successfully created on desktop"
shutil.copy(location, args.location)
print "Creating custom URL protocol handlers" print "Creating custom URL protocol handlers"
try: try:
custom_ssh = OrderedDict( custom_ssh = OrderedDict(
......
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Place holder for all windows specific frequently used classes.
Currently here:
RegistryHandler - Registry based operations
DecideArchitecture - Accurate way to decide operating system architecture
"""
import os
import argparse
import errno
from _winreg import *
try:
from collections import *
except ImporError:
from OrderedDict import *
def parse_arguments():
"""
Argument parser, based on argparse module
Keyword arguments:
@return args -- arguments given by console
"""
parser = argparse.ArgumentParser()
parser.add_argument(
"-g", "--global",
help="Whether we want to edit registry globally or just locally",
action="store_true")
parser.add_argument(
"-d", "--different",
help="Only handle the architecture specific registry area",
action="store_true")
parser.add_argument(
"-r", "--registry",
help="Which HKEY_* const registry type the program should use",
type=str, choices=['HKLM', 'HKCR', 'HKCU', 'HKU', 'HKPD', 'HKCC'],
default="HKLM")
args = parser.parse_args()
return args
def main():
return RegistryHandler(parse_arguments())
class Struct:
"""
Parameter bypassing struct
"""
pass
class RegistryHandler:
"""
Registry handling class, makes registry based queries and
manipulations easier.
This class can handle WOW64 based application differently and none
differently (default)
"""
def __init__(self, args = None):
"""Initialise RegistryHandler
Keyword arguments:
@param args -- The arguments that decide how the we should
handle the registry
args.registry -- What base registry should we use
(default: HKLM)
Raises AttributeError if not supported base registry type is
given
args.different -- Whether we handle registry redirection or not
"""
if args is None:
self.args = Struct()
self.args.different = None
self.args.registry = None
else:
if not hasattr(args, 'different'):
args.different = None
if not hasattr(args, 'registry'):
args.registry = None
self.args = args
if self.args.different is None:
self.args.different = False
if self.args.registry is None or self.args.registry == "HKLM":
self.args.registry = HKEY_LOCAL_MACHINE
elif self.args.registry == "HKCR":
self.args.registry = HKEY_CLASSES_ROOT
elif self.args.registry == "HKCU":
self.args.registry = HKEY_CURRENT_USER
elif self.args.registry == "HKU":
self.args.registry = HKEY_USERS
elif self.args.registry == "HKPD":
self.args.registry = HKEY_PERFORMANCE_DATA
elif self.args.registry == "HKCC":
self.args.registry = HKEY_CURRENT_CONFIG
else:
#print "Non supported registry type"
raise AttributeError
def connect_registry(self):
"""
Getting a registry open
Keyword arguments:
@return connected_registy -- Reference to the newly opened
registry
"""
return ConnectRegistry(None,self.args.registry)
def create_registry_from_dict_chain(
self, dict_chain, both = False, architect = KEY_WOW64_64KEY,
needed_rights = KEY_ALL_ACCESS):
""""
Create registry key and value multilevel tree by chained
dictionaries.
Can raise AttributeError if the provided dict chain isn't
correct
Keyword arguments:
@param key_value_chain -- The dict chain containing all the
information
@param both -- Whether create the registry in WOW64
node too
@param architect -- The current registry view (
only change it if we want to fill the
WOW6432 registry only [both = False],
on x64 windows)
@param needed_rights -- SAM rights to access the key
"""
if both and architect is KEY_WOW64_64KEY:
self.create_registry_from_dict_chain(
dict_chain, False, KEY_WOW64_32KEY, needed_rights)
if not DecideArchitecture.Is64Windows():
architect = 0
connected_registy = self.connect_registry()
if (isinstance(dict_chain, dict)
or isinstance(dict_chain, OrderedDict)):
for key, value in dict_chain.iteritems():
if isinstance(value, dict) or isinstance(value, OrderedDict):
temp_dict = OrderedDict()
for my_key, my_value in value.iteritems():
temp_dict[key+"\\"+my_key] = my_value
self.create_registry_from_dict_chain(
temp_dict, False, architect, needed_rights)
else:
if isinstance(value, list):
if len(value)%2 != 0:
#print "Not enough member in the list"
raise AttributeError
else:
new_key = CreateKeyEx(
connected_registy, key, 0,
needed_rights | architect)
temp_dict = OrderedDict(
value[i:i+2] for i in range(
0, len(value), 2))
for my_key, my_value in temp_dict.iteritems():
if my_key == "default":
my_key = None
SetValueEx(
new_key, my_key, 0, REG_SZ, my_value)
else:
new_key = CreateKeyEx(
connected_registy, key, 0,
needed_rights | architect)
SetValueEx(new_key, None, 0, REG_SZ, value)
else:
print "The provided attribute wasn't a dictionary chain"
raise AttributeError
def get_key(self, key_name, needed_rights = KEY_ALL_ACCESS):
"""
Getting a registry value by it's key's name
Can raise KeyError if key is not found in the registry
Keyword arguments:
@param key_name -- The specific key name of which value we
are interested in
@param needed_rights -- SAM rights to access the key
@return -- [key, architect]
key -- Reference to the opened
key handler
architect -- 0 for x86
KEY_WOW64_32KEY or
KEY_WOW64_64KEY
depending where we
found the key on x64
"""
connected_registy = self.connect_registry()
architect = 0
if DecideArchitecture.Is64Windows():
architect = KEY_WOW64_64KEY
try:
key = OpenKey(connected_registy, key_name, 0,
needed_rights | architect)
except WindowsError:
if DecideArchitecture.Is64Windows() and not self.args.different:
try:
architect = KEY_WOW64_32KEY
key = OpenKey(connected_registy, key_name,
0, needed_rights | architect)
except WindowsError:
raise KeyError
else:
raise KeyError
return [key, architect]
def get_key_values(
self, key_name, subkey_list, subroutine = False,
depth = "subkeys"):
"""
Getting registry subkeys value by it's key's name and subkeys
name
Can raise LookupError exception if there are missing data
Can raise AttributeError exception if depth attribute is wrong
Keyword arguments:
@param key_name -- The specific key name of which subkey's
we are interested in
@param subkey_list -- List containing all the subkeys names
which values we are interested in
@param subroutine -- Whether suppress exception about not
having enough results or not
(default: False)
@param depth -- How depth the search should go for
[options: key, subkeys, all]
(default: subkeys)
@return results{} -- Dictionary with the subkey_name - value
combinations as keys and values
"""
if depth == "key":
int_depth = 0;
elif depth == "subkeys":
int_depth = 1;
elif depth == "all":
int_depth = 2;
else:
raise AttributeError
try:
key_and_architect = self.get_key(key_name)
key = key_and_architect[0]
architect = key_and_architect[1]
except KeyError:
#print "%s doesn't exist in the registry" % key_name
raise LookupError
#print "%s found in the registry" % key_name
results = {}
if int_depth >= 1:
for i in xrange(0, QueryInfoKey(key)[0]-1):
skey_name = EnumKey(key, i)
skey = OpenKey(key, skey_name, 0, KEY_ALL_ACCESS | architect)
if int_depth == 2 and QueryInfoKey(skey)[0] > 0:
for key, value in self.get_key_values(
skey_name, subkey_list, True, depth).iteritems():
results[key] = value
for subkey_name in subkey_list:
try:
results[subkey_name] = QueryValueEx(
skey, subkey_name)[0]
except OSError as e:
if e.errno == errno.ENOENT:
#print ("%s doesn't exist in this" % subkey_name
# " subkey")
pass
skey.Close()
if not results or len(results) != len(subkey_list):
for subkey_name in subkey_list:
try:
results[subkey_name] = QueryValueEx(key, subkey_name)[0]
except OSError as e:
pass
key.Close()
if len(results) != len(subkey_list):
#print "We are missing important variables"
raise LookupError
return results
def get_key_value(
self, key_name, subkey_name, subroutine = None, depth = None):
"""
This is a wrapper for the get_key_values to be easier to use
for single subkeys.
Getting registry subkey value by it's key's name and subkey
name
Keyword arguments:
@param key_name -- The specific key name of which subkey's
we are interested in
@param subkey_name -- The specific subkey name which value we
are interested in
@param subroutine -- can be found at: get_key_values
@param depth -- can be found at: get_key_values
@return value -- Value of the specific subkey
"""
try:
if subroutine is None:
return self.get_key_values(key_name,
[subkey_name])[subkey_name]
elif depth is None:
return self.get_key_values(key_name, [subkey_name],
subroutine)[subkey_name]
else:
return self.get_key_values(key_name, [subkey_name],
subroutine, depth)[subkey_name]
except:
raise
class DecideArchitecture:
"""
Helper class to get the true ProgramFiles directory.
This class doesn't depend on Phyton or Windows architecture.
"""
@staticmethod
def Is64Windows():
return 'PROGRAMFILES(X86)' in os.environ
@staticmethod
def GetProgramFiles32():
if DecideArchitecture.Is64Windows():
return os.environ['PROGRAMFILES(X86)']
else:
return os.environ['PROGRAMFILES']
@staticmethod
def GetProgramFiles64():
if DecideArchitecture.Is64Windows():
return os.environ['PROGRAMW6432']
else:
return None
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment