atomicshop 2.15.13__py3-none-any.whl → 2.16.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of atomicshop might be problematic. Click here for more details.

Files changed (66) hide show
  1. atomicshop/__init__.py +1 -1
  2. atomicshop/a_installs/ubuntu/pycharm.py +7 -0
  3. atomicshop/a_installs/win/pycharm.py +2 -2
  4. atomicshop/{addons/mains/install_wsl_ubuntu_lts_admin.py → a_installs/win/wsl_ubuntu_lts.py} +1 -0
  5. atomicshop/{addons/mains → a_mains}/FACT/update_extract.py +3 -2
  6. atomicshop/a_mains/dns_gateway_setting.py +11 -0
  7. atomicshop/basics/booleans.py +14 -5
  8. atomicshop/dns.py +104 -0
  9. atomicshop/file_io/docxs.py +8 -0
  10. atomicshop/file_io/tomls.py +133 -0
  11. atomicshop/filesystem.py +5 -4
  12. atomicshop/get_process_list.py +3 -3
  13. atomicshop/mitm/config_static.py +195 -0
  14. atomicshop/mitm/config_toml_editor.py +55 -0
  15. atomicshop/mitm/connection_thread_worker.py +54 -90
  16. atomicshop/mitm/import_config.py +148 -139
  17. atomicshop/mitm/initialize_engines.py +7 -2
  18. atomicshop/mitm/initialize_mitm_server.py +162 -107
  19. atomicshop/mitm/shared_functions.py +0 -1
  20. atomicshop/mitm/statistic_analyzer.py +13 -1
  21. atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py +54 -14
  22. atomicshop/permissions/__init__.py +0 -0
  23. atomicshop/permissions/permissions.py +22 -0
  24. atomicshop/{permissions.py → permissions/ubuntu_permissions.py} +4 -54
  25. atomicshop/permissions/win_permissions.py +33 -0
  26. atomicshop/script_as_string_processor.py +5 -1
  27. atomicshop/wrappers/cryptographyw.py +3 -3
  28. atomicshop/wrappers/dockerw/install_docker.py +6 -5
  29. atomicshop/wrappers/elasticsearchw/install_elastic.py +2 -1
  30. atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py +5 -4
  31. atomicshop/wrappers/mongodbw/install_mongodb.py +2 -1
  32. atomicshop/wrappers/msiw.py +2 -3
  33. atomicshop/wrappers/psutilw/networks.py +25 -1
  34. atomicshop/wrappers/pycharmw/__init__.py +0 -0
  35. atomicshop/wrappers/pycharmw/ubuntu.py +38 -0
  36. atomicshop/wrappers/{pycharmw.py → pycharmw/win.py} +2 -2
  37. atomicshop/wrappers/pywin32w/wmis/__init__.py +0 -0
  38. atomicshop/wrappers/pywin32w/wmis/helpers.py +127 -0
  39. atomicshop/wrappers/pywin32w/wmis/win32networkadapter.py +167 -0
  40. atomicshop/wrappers/socketw/accepter.py +8 -8
  41. atomicshop/wrappers/socketw/base.py +13 -0
  42. atomicshop/wrappers/socketw/certificator.py +202 -149
  43. atomicshop/wrappers/socketw/creator.py +15 -35
  44. atomicshop/wrappers/socketw/dns_server.py +155 -102
  45. atomicshop/wrappers/socketw/exception_wrapper.py +8 -27
  46. atomicshop/wrappers/socketw/get_process.py +115 -95
  47. atomicshop/wrappers/socketw/sni.py +298 -164
  48. atomicshop/wrappers/socketw/socket_client.py +5 -12
  49. atomicshop/wrappers/socketw/socket_server_tester.py +1 -1
  50. atomicshop/wrappers/socketw/socket_wrapper.py +328 -72
  51. atomicshop/wrappers/socketw/statistics_csv.py +94 -16
  52. atomicshop/wrappers/ubuntu_terminal.py +6 -6
  53. atomicshop/wrappers/wslw.py +1 -0
  54. {atomicshop-2.15.13.dist-info → atomicshop-2.16.1.dist-info}/METADATA +1 -1
  55. {atomicshop-2.15.13.dist-info → atomicshop-2.16.1.dist-info}/RECORD +63 -54
  56. atomicshop/addons/mains/__pycache__/install_fibratus_windows.cpython-312.pyc +0 -0
  57. atomicshop/addons/mains/__pycache__/msi_unpacker.cpython-312.pyc +0 -0
  58. atomicshop/mitm/config_editor.py +0 -37
  59. /atomicshop/{addons/mains/install_docker_rootless_ubuntu.py → a_installs/ubuntu/docker_rootless.py} +0 -0
  60. /atomicshop/{addons/mains/install_docker_ubuntu_main_sudo.py → a_installs/ubuntu/docker_sudo.py} +0 -0
  61. /atomicshop/{addons/mains/install_elastic_search_and_kibana_ubuntu.py → a_installs/ubuntu/elastic_search_and_kibana.py} +0 -0
  62. /atomicshop/{addons/mains → a_mains}/FACT/factw_fact_extractor_docker_image_main_sudo.py +0 -0
  63. /atomicshop/wrappers/pywin32w/{wmi_win32process.py → wmis/win32process.py} +0 -0
  64. {atomicshop-2.15.13.dist-info → atomicshop-2.16.1.dist-info}/LICENSE.txt +0 -0
  65. {atomicshop-2.15.13.dist-info → atomicshop-2.16.1.dist-info}/WHEEL +0 -0
  66. {atomicshop-2.15.13.dist-info → atomicshop-2.16.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,22 @@
1
+ import os
2
+ import ctypes
3
+
4
+
5
+ def is_admin() -> bool:
6
+ """
7
+ Function checks on Windows or POSIX OSes if the script is executed under Administrative Privileges.
8
+ :return: True / False.
9
+ """
10
+
11
+ if os.name == 'nt':
12
+ if ctypes.windll.shell32.IsUserAnAdmin() == 0:
13
+ result = False
14
+ else:
15
+ result = True
16
+ else:
17
+ if 'SUDO_USER' in os.environ and os.geteuid() == 0:
18
+ result = True
19
+ else:
20
+ result = False
21
+
22
+ return result
@@ -1,6 +1,5 @@
1
1
  import os
2
2
  import stat
3
- import ctypes
4
3
  import contextlib
5
4
  import subprocess
6
5
 
@@ -9,27 +8,7 @@ if os.name == 'posix':
9
8
  import pwd
10
9
 
11
10
 
12
- def is_admin() -> bool:
13
- """
14
- Function checks on Windows or POSIX OSes if the script is executed under Administrative Privileges.
15
- :return: True / False.
16
- """
17
-
18
- if os.name == 'nt':
19
- if ctypes.windll.shell32.IsUserAnAdmin() == 0:
20
- result = False
21
- else:
22
- result = True
23
- else:
24
- if 'SUDO_USER' in os.environ and os.geteuid() == 0:
25
- result = True
26
- else:
27
- result = False
28
-
29
- return result
30
-
31
-
32
- def get_ubuntu_sudo_executer_username() -> str:
11
+ def get_sudo_executer_username() -> str:
33
12
  """
34
13
  Function gets the username of the user who executed the script with sudo.
35
14
  :return: str, username.
@@ -41,7 +20,7 @@ def get_ubuntu_sudo_executer_username() -> str:
41
20
  return ''
42
21
 
43
22
 
44
- def set_executable_permission(file_path: str):
23
+ def set_executable(file_path: str):
45
24
  """
46
25
  Function sets the executable permission on a file.
47
26
  Equivalent to: chmod +x <file_path>
@@ -54,7 +33,7 @@ def set_executable_permission(file_path: str):
54
33
  os.chmod(file_path, os.stat(file_path).st_mode | stat.S_IXUSR)
55
34
 
56
35
 
57
- def change_file_owner_ubuntu(file_path: str, username: str):
36
+ def change_file_owner(file_path: str, username: str):
58
37
  """
59
38
  Function changes the owner of the file to the specified user.
60
39
  :param file_path: str, path to the file.
@@ -66,7 +45,7 @@ def change_file_owner_ubuntu(file_path: str, username: str):
66
45
  os.chown(file_path, uid, -1)
67
46
 
68
47
 
69
- def is_executable_permission(file_path: str) -> bool:
48
+ def is_executable(file_path: str) -> bool:
70
49
  """
71
50
  Function checks if the file has the executable permission.
72
51
  Equivalent to: stat -c "%a %n" <file_path>
@@ -120,32 +99,3 @@ def expand_user_path(user_name, path):
120
99
  pwnam = pwd.getpwnam(user_name)
121
100
  home_dir = pwnam.pw_dir
122
101
  return path.replace("~", home_dir)
123
-
124
-
125
- def unblock_file_windows(file_path):
126
- """
127
- Unblock a file on Windows. This is used to unblock files downloaded from the internet.
128
- When you Right-click then navigate to Properties, you will see the Unblock checkbox.
129
- :param file_path:
130
- :return:
131
- """
132
- try:
133
- subprocess.run(["powershell", "-Command", f"Unblock-File -Path '{file_path}'"], check=True)
134
- print(f"Successfully unblocked the file: {file_path}")
135
- except subprocess.CalledProcessError as e:
136
- print(f"Failed to unblock the file: {file_path}\nError: {e}")
137
-
138
-
139
- def get_command_to_run_as_admin_windows(command: str) -> str:
140
- """
141
- Function returns the command to run a command as administrator on Windows.
142
- :param command: str, command to run.
143
- :return: str, command to run as administrator.
144
- """
145
-
146
- executable = command.split()[0]
147
- command = (
148
- f"powershell -Command "
149
- f"\"Start-Process {executable} -ArgumentList '{' '.join(command.split()[1:])}' -Verb RunAs\"")
150
-
151
- return command
@@ -0,0 +1,33 @@
1
+ import subprocess
2
+
3
+
4
+ def unblock_file_windows(file_path):
5
+ """
6
+ Unblock a file on Windows. This is used to unblock files downloaded from the internet.
7
+ When you Right-click then navigate to Properties, you will see the Unblock checkbox.
8
+ :param file_path:
9
+ :return:
10
+ """
11
+ try:
12
+ subprocess.run(["powershell", "-Command", f"Unblock-File -Path '{file_path}'"], check=True)
13
+ print(f"Successfully unblocked the file: {file_path}")
14
+ except subprocess.CalledProcessError as e:
15
+ print(f"Failed to unblock the file: {file_path}\nError: {e}")
16
+
17
+
18
+ def get_command_to_run_as_admin_windows(command: str) -> str:
19
+ """
20
+ Function returns the command to run a command as administrator on Windows.
21
+ NOTE: When you run something this way, the parent will be the powershell.exe process.
22
+ If you need a status result directly of the executed command, you need to use subprocess.run() instead.
23
+
24
+ :param command: str, command to run.
25
+ :return: str, command to run as administrator.
26
+ """
27
+
28
+ executable = command.split()[0]
29
+ command = (
30
+ f"powershell -Command "
31
+ f"\"Start-Process {executable} -ArgumentList '{' '.join(command.split()[1:])}' -Verb RunAs\"")
32
+
33
+ return command
@@ -1,6 +1,7 @@
1
1
  """Loading resources using stdlib importlib.resources APIs (Python 3.7+)
2
2
  https://docs.python.org/3/library/importlib.html#module-importlib.resources"""
3
3
  import importlib.resources
4
+ from typing import Literal
4
5
 
5
6
  from .print_api import print_api
6
7
 
@@ -13,7 +14,10 @@ class ScriptAsStringProcessor:
13
14
  self.exchange_input_variable_string: str = "exchange_input_variable"
14
15
  self.script_string: str = str()
15
16
 
16
- def read_script_to_string(self, script_file_name: str):
17
+ def read_script_to_string(
18
+ self,
19
+ script_file_name: Literal['process_from_port', 'process_from_ipv4']
20
+ ):
17
21
  self.script_string = importlib.resources.read_text(
18
22
  f'{__package__}.{self.resources_directory_name}',
19
23
  f'{script_file_name}.py')
@@ -80,7 +80,7 @@ def convert_pem_to_x509_object(certificate: Union[str, bytes]) -> x509.Certifica
80
80
  return x509.load_pem_x509_certificate(certificate)
81
81
 
82
82
 
83
- def convert_der_to_x509_object(certificate: bytes):
83
+ def convert_der_to_x509_object(certificate: bytes) -> x509.Certificate:
84
84
  """Convert DER certificate from socket to x509 object.
85
85
 
86
86
  :param certificate: bytes, certificate to convert.
@@ -151,8 +151,8 @@ def copy_extensions_from_old_cert_to_new_cert(
151
151
  builder = x509.CertificateBuilder()
152
152
  builder = builder.subject_name(certificate.subject)
153
153
  builder = builder.issuer_name(certificate.issuer)
154
- builder = builder.not_valid_before(certificate.not_valid_before)
155
- builder = builder.not_valid_after(certificate.not_valid_after)
154
+ builder = builder.not_valid_before(certificate.not_valid_before_utc)
155
+ builder = builder.not_valid_after(certificate.not_valid_after_utc)
156
156
  builder = builder.serial_number(certificate.serial_number)
157
157
 
158
158
  # We're using the new private key that we will sign with the new certificate later.
@@ -2,7 +2,8 @@ import sys
2
2
  import subprocess
3
3
  import getpass
4
4
 
5
- from ... import process, filesystem, permissions
5
+ from ... import process, filesystem
6
+ from ...permissions import permissions, ubuntu_permissions
6
7
  from ...print_api import print_api
7
8
  from .. import ubuntu_terminal
8
9
 
@@ -38,7 +39,7 @@ def add_current_user_to_docker_group(print_kwargs: dict = None):
38
39
  :return:
39
40
  """
40
41
  # Check if current user that executed the script is a sudo user. If not, use the current user.
41
- sudo_executer_username: str = permissions.get_ubuntu_sudo_executer_username()
42
+ sudo_executer_username: str = ubuntu_permissions.get_sudo_executer_username()
42
43
  if sudo_executer_username:
43
44
  current_user = sudo_executer_username
44
45
  else:
@@ -145,7 +146,7 @@ def install_docker_ubuntu(
145
146
  ubuntu_terminal.update_system_packages()
146
147
  ubuntu_terminal.install_packages(['uidmap'])
147
148
 
148
- with permissions.temporary_regular_permissions():
149
+ with ubuntu_permissions.temporary_regular_permissions():
149
150
  # After 'get-docker.sh' execution, we will install docker in rootless mode.
150
151
  # process.execute_script('dockerd-rootless-setuptool.sh install', shell=True, as_regular_user=True)
151
152
  process.execute_script(
@@ -164,13 +165,13 @@ def install_docker_ubuntu(
164
165
  process.execute_script(docker_enable_command, shell=True, executable=None)
165
166
 
166
167
  print_api('Executing "loginctl enable-linger" to enable Docker to run when the user is not logged in...')
167
- non_sudo_executer = permissions.get_ubuntu_sudo_executer_username()
168
+ non_sudo_executer = ubuntu_permissions.get_sudo_executer_username()
168
169
  # Enable lingering so Docker runs when the user is not logged in
169
170
  process.execute_script(f'sudo loginctl enable-linger {non_sudo_executer}', shell=True)
170
171
 
171
172
  print_api('Adding $HOME/bin to your PATH...')
172
173
  # Add $HOME/bin to your PATH if it's not already there.
173
- with permissions.temporary_regular_permissions():
174
+ with ubuntu_permissions.temporary_regular_permissions():
174
175
  ubuntu_terminal.add_path_to_bashrc(as_regular_user=True)
175
176
 
176
177
  # Add appropriate permissions to the docker socket, so the user can run docker commands without sudo in python.
@@ -1,7 +1,8 @@
1
1
  import sys
2
2
 
3
3
  from ...print_api import print_api
4
- from ... import process, permissions
4
+ from ... import process
5
+ from ...permissions import permissions
5
6
  from .. import ubuntu_terminal
6
7
  from . import config_basic, infrastructure
7
8
 
@@ -2,7 +2,8 @@ import sys
2
2
  import subprocess
3
3
  from pathlib import Path
4
4
 
5
- from .... import permissions, filesystem
5
+ from .... import filesystem
6
+ from ....permissions import ubuntu_permissions
6
7
  from ....archiver import zips
7
8
  from ....print_api import print_api
8
9
  from ... import githubw, pipw, ubuntu_terminal
@@ -42,7 +43,7 @@ def install_before_restart(
42
43
  # sys.exit(1)
43
44
 
44
45
  # # Install docker in rootless mode.
45
- # with permissions.temporary_regular_permissions():
46
+ # with ubuntu_permissions.temporary_regular_permissions():
46
47
  # install_docker.install_docker_ubuntu(
47
48
  # use_docker_installer=True, rootless=True, add_current_user_to_docker_group_bool=False)
48
49
 
@@ -59,7 +60,7 @@ def install_before_restart(
59
60
  filesystem.remove_directory(installation_directory)
60
61
 
61
62
  # Since you run the script with sudo, we need to change the permissions to the current user.
62
- # with permissions.temporary_regular_permissions():
63
+ # with ubuntu_permissions.temporary_regular_permissions():
63
64
  # Create the FACT_core directory.
64
65
  filesystem.create_directory(installation_directory)
65
66
 
@@ -78,7 +79,7 @@ def install_before_restart(
78
79
  remove_first_directory=True, **(print_kwargs or {}))
79
80
 
80
81
  # Set the executable permission on the pre-installation file.
81
- permissions.set_executable_permission(fact_core_pre_install_file_path)
82
+ ubuntu_permissions.set_executable(fact_core_pre_install_file_path)
82
83
 
83
84
  if use_built_in_fact_installer:
84
85
  # Run the shell script
@@ -4,7 +4,8 @@ from typing import Union
4
4
  import argparse
5
5
  import subprocess
6
6
 
7
- from ... import urls, web, permissions
7
+ from ... import urls, web
8
+ from ...permissions import permissions
8
9
  from ...print_api import print_api
9
10
  from .. import msiw
10
11
  from . import infrastructure
@@ -1,8 +1,7 @@
1
1
  import subprocess
2
- import sys
3
2
 
4
3
  from ..print_api import print_api
5
- from .. import permissions
4
+ from ..permissions import permissions
6
5
  from ..import get_process_list
7
6
  from .psutilw import processes
8
7
 
@@ -124,7 +123,7 @@ def install_msi(
124
123
  command = f"{command} {additional_args}"
125
124
 
126
125
  # if as_admin:
127
- # command = permissions.get_command_to_run_as_admin_windows(command)
126
+ # command = win_permissions.get_command_to_run_as_admin_windows(command)
128
127
 
129
128
  # Run the command
130
129
  result = subprocess.run(command, capture_output=True, text=True)
@@ -1,5 +1,6 @@
1
1
  from typing import Union
2
2
  import shlex
3
+ import socket
3
4
 
4
5
  import psutil
5
6
 
@@ -14,7 +15,10 @@ def get_process_using_port(port: int) -> Union[dict, None]:
14
15
  try:
15
16
  connections = proc.connections(kind='inet')
16
17
  for conn in connections:
17
- if conn.laddr.port == port:
18
+ # if conn.laddr.port == port:
19
+ # Status LISTEN is for TCP sockets and NONE is for UDP sockets.
20
+ # Sometimes after socket close, the port will be in TIME_WAIT state.
21
+ if conn.laddr.port == port and (conn.status == 'LISTEN' or conn.status == 'NONE'):
18
22
  cmdline = proc.info['cmdline']
19
23
  if not cmdline:
20
24
  cmdline = '<EMPTY: TRY RUNNING AS ADMIN>'
@@ -43,3 +47,23 @@ def get_processes_using_port_list(ports: list) -> Union[dict, None]:
43
47
  port_process_map[port] = process_info
44
48
 
45
49
  return port_process_map
50
+
51
+
52
+ def get_default_connection_name() -> Union[dict, None]:
53
+ """
54
+ Function to get the default network interface.
55
+ :return: dict[interface_name: details] or None.
56
+ """
57
+ # Get all interfaces.
58
+ interfaces: dict = psutil.net_if_addrs()
59
+ default_ip_address: str = socket.gethostbyname(socket.gethostname())
60
+
61
+ for interface, details in interfaces.items():
62
+ for address in details:
63
+ # Check if the address is an IPv4 address (AF_INET) and not a loopback (127.0.0.1)
64
+ if address.family == socket.AF_INET and not address.address.startswith('127.'):
65
+ # Check if the address is the default IP address.
66
+ if address.address == default_ip_address:
67
+ return {interface: details}
68
+
69
+ return None
File without changes
@@ -0,0 +1,38 @@
1
+ import argparse
2
+
3
+ from ... import process
4
+ from ...print_api import print_api
5
+
6
+
7
+ def parse_args():
8
+ """
9
+ Parse command line arguments.
10
+
11
+ :return: Parsed arguments.
12
+ """
13
+ parser = argparse.ArgumentParser(description='Install PyCharm Community Edition.')
14
+ parser.add_argument('--install', action='store_true', help='Install PyCharm Community Edition with snapd.')
15
+ parser.add_argument('--enable_sudo_execution', action='store_true',
16
+ help='There is a problem when trying to run snapd installed Pycharm as sudo, need to enable '
17
+ 'this.')
18
+
19
+ return parser.parse_args()
20
+
21
+
22
+ def install_main():
23
+ """
24
+ Main function to install the latest PyCharm Community Edition.
25
+
26
+ Usage:
27
+ python -m atomicshop.a_installs.ubuntu.pycharm
28
+ """
29
+
30
+ args = parse_args()
31
+
32
+ if args.install:
33
+ process.execute_script('sudo snap install pycharm-community --classic', shell=True)
34
+
35
+ if args.enable_sudo_execution:
36
+ process.execute_script('xhost +SI:localuser:root', shell=True)
37
+ print_api('Run the following command to start PyCharm as root: [sudo snap run pycharm-community]', color='blue')
38
+ return 0
@@ -2,8 +2,8 @@ import requests
2
2
  from bs4 import BeautifulSoup
3
3
  import subprocess
4
4
 
5
- from .. import web, filesystem
6
- from ..print_api import print_api
5
+ from ... import web, filesystem
6
+ from ...print_api import print_api
7
7
 
8
8
 
9
9
  # URL to the PyCharm Community Edition download page
File without changes
@@ -0,0 +1,127 @@
1
+ import win32com.client
2
+
3
+
4
+ class WmiMethodExecutionError(Exception):
5
+ pass
6
+
7
+
8
+ class WmiMethodParameterError(Exception):
9
+ pass
10
+
11
+
12
+ class EmptyValue:
13
+ pass
14
+
15
+
16
+ def get_method(
17
+ wmi_object: win32com.client.CDispatch,
18
+ method_name: str
19
+ ):
20
+ """
21
+ Get the WMI method.
22
+
23
+ :param wmi_object: WMI object.
24
+ :param method_name: str, name of the method.
25
+ :return: WMI method object.
26
+ """
27
+
28
+ return wmi_object.Methods_(method_name)
29
+
30
+
31
+ def get_method_parameter_instance(
32
+ method: win32com.client.CDispatch
33
+ ):
34
+ """
35
+ Get the WMI method parameter.
36
+
37
+ :param method: WMI method object.
38
+ :return: WMI method parameter object.
39
+ """
40
+
41
+ return method.inParameters.SpawnInstance_()
42
+
43
+
44
+ def call_method(
45
+ wmi_object: win32com.client.CDispatch,
46
+ method_name: str,
47
+ value: any = EmptyValue
48
+ ):
49
+ """
50
+ Call the WMI method.
51
+
52
+ :param wmi_object: WMI object.
53
+ :param method_name: str, name of the method.
54
+ :param value: any, value to pass to the method.
55
+ Methods can receive a None value if they don't require any parameters.
56
+ If the method doesn't require any parameters, leave it as 'EmptyValue' class.
57
+ :return: WMI method object.
58
+ """
59
+
60
+ # Get the method instance out of the WMI object.
61
+ method = get_method(wmi_object, method_name)
62
+
63
+ # Check if the method requires any parameters.
64
+ if not method.InParameters and not isinstance(value, EmptyValue):
65
+ raise WmiMethodParameterError(f"Method '{method_name}' doesn't require any parameters.\nValue: {value}")
66
+ elif method.InParameters and isinstance(value, EmptyValue):
67
+ raise WmiMethodParameterError(f"Method '{method_name}' requires parameters.\nValue: {value}")
68
+
69
+ # If value was passed for the method to set.
70
+ if not isinstance(value, EmptyValue):
71
+ # Get the input parameters names that a method requires.
72
+ # The names are stored in a list of tuples where the first element is the name of the parameter and the second
73
+ # element is a boolean that indicates if the parameter is an array.
74
+ input_parameters_names = [
75
+ (input_parameter.Name, input_parameter.IsArray) for input_parameter in method.InParameters.Properties_]
76
+
77
+ # Check if the value and the input parameter is a list.
78
+ if not (isinstance(value, list) or value is None) and input_parameters_names[0][1]:
79
+ raise WmiMethodParameterError(f"Parameter '{input_parameters_names[0][0]}' must be a list.\nValue: {value}")
80
+ elif (isinstance(value, list) or value is None) and not input_parameters_names[0][1]:
81
+ raise WmiMethodParameterError(f"Parameter '{input_parameters_names[0][0]}' "
82
+ f"must be a single value.\nValue: {value}")
83
+
84
+ # Get generic parameter instance.
85
+ parameter_instance = get_method_parameter_instance(method)
86
+ # Set the attribute of the parameter name instance that we retrieved from above to the value.
87
+ # At this point only been using one parameter for a method, so maybe need to refactor this part if needed
88
+ # in the future for more than one parameter.
89
+ setattr(parameter_instance, input_parameters_names[0][0], value)
90
+
91
+ # Execute the method with the parameter instance.
92
+ result = wmi_object.ExecMethod_(method_name, parameter_instance)
93
+ else:
94
+ # Execute the method without any parameters.
95
+ result = wmi_object.ExecMethod_(method_name)
96
+
97
+ # Getting Result.
98
+ # Get the output parameters names that a method returns.
99
+ if method.OutParameters:
100
+ out_properties_names = [
101
+ (out_property.Name, out_property.IsArray) for out_property in method.OutParameters.Properties_]
102
+ else:
103
+ out_properties_names = []
104
+
105
+ # Get the results for each parameter the method returns.
106
+ results = []
107
+ for name, is_array in out_properties_names:
108
+ value = result.Properties_(name).Value
109
+ if is_array:
110
+ results.append(list(value or []))
111
+ else:
112
+ results.append(value)
113
+
114
+ # Check if the method executed successfully.
115
+ for result in results:
116
+ if result != 0:
117
+ raise WmiMethodExecutionError(f"Failed to execute method '{method_name}' with error code: {result}")
118
+
119
+
120
+ """
121
+ # Setting SeDebugPrivilege
122
+ import win32security, ntsecuritycon, win32con, win32api
123
+ privs = ((win32security.LookupPrivilegeValue('',ntsecuritycon.SE_DEBUG_NAME), win32con.SE_PRIVILEGE_ENABLED),)
124
+ hToken = win32security.OpenProcessToken(win32api.GetCurrentProcess(), win32security.TOKEN_ALL_ACCESS)
125
+ win32security.AdjustTokenPrivileges(hToken, False, privs)
126
+ win32api.CloseHandle(hToken)
127
+ """