268 lines
8.0 KiB
Python
268 lines
8.0 KiB
Python
|
# Copyright 2017 Cloudbase Solutions Srl
|
||
|
# All Rights Reserved.
|
||
|
#
|
||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||
|
# not use this file except in compliance with the License. You may obtain
|
||
|
# a copy of the License at
|
||
|
#
|
||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||
|
#
|
||
|
# Unless required by applicable law or agreed to in writing, software
|
||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||
|
# License for the specific language governing permissions and limitations
|
||
|
# under the License.
|
||
|
|
||
|
import ctypes
|
||
|
|
||
|
from os_win.utils.winapi import constants as w_const
|
||
|
from os_win.utils.winapi import wintypes
|
||
|
|
||
|
lib_handle = None
|
||
|
|
||
|
ISCSI_SECURITY_FLAGS = ctypes.c_uint64
|
||
|
ISCSI_LOGIN_FLAGS = ctypes.c_uint32
|
||
|
ISCSI_LOGIN_OPTIONS_INFO_SPECIFIED = ctypes.c_uint32
|
||
|
ISCSI_AUTH_TYPES = wintypes.UINT
|
||
|
ISCSI_DIGEST_TYPES = wintypes.UINT
|
||
|
DEVICE_TYPE = wintypes.ULONG
|
||
|
|
||
|
|
||
|
class ISCSI_TARGET_PORTAL(ctypes.Structure):
|
||
|
_fields_ = [
|
||
|
('SymbolicName', wintypes.WCHAR * w_const.MAX_ISCSI_PORTAL_NAME_LEN),
|
||
|
('Address', wintypes.WCHAR * w_const.MAX_ISCSI_PORTAL_ADDRESS_LEN),
|
||
|
('Socket', wintypes.USHORT)
|
||
|
]
|
||
|
|
||
|
|
||
|
PISCSI_TARGET_PORTAL = ctypes.POINTER(ISCSI_TARGET_PORTAL)
|
||
|
|
||
|
|
||
|
class ISCSI_LOGIN_OPTIONS(ctypes.Structure):
|
||
|
_fields_ = [
|
||
|
('Version', wintypes.ULONG),
|
||
|
('InformationSpecified', ISCSI_LOGIN_OPTIONS_INFO_SPECIFIED),
|
||
|
('LoginFlags', ISCSI_LOGIN_FLAGS),
|
||
|
('AuthType', ISCSI_AUTH_TYPES),
|
||
|
('HeaderDigest', ISCSI_DIGEST_TYPES),
|
||
|
('DataDigest', ISCSI_DIGEST_TYPES),
|
||
|
('MaximumConnections', wintypes.ULONG),
|
||
|
('DefaultTime2Wait', wintypes.ULONG),
|
||
|
('DefaultTime2Retain', wintypes.ULONG),
|
||
|
('UsernameLength', wintypes.ULONG),
|
||
|
('PasswordLength', wintypes.ULONG),
|
||
|
('Username', wintypes.PSTR),
|
||
|
('Password', wintypes.PSTR)
|
||
|
]
|
||
|
|
||
|
|
||
|
PISCSI_LOGIN_OPTIONS = ctypes.POINTER(ISCSI_LOGIN_OPTIONS)
|
||
|
|
||
|
|
||
|
class SCSI_LUN_LIST(ctypes.Structure):
|
||
|
_fields_ = [
|
||
|
('OSLUN', wintypes.ULONG),
|
||
|
('TargetLUN', wintypes.ULONGLONG)
|
||
|
]
|
||
|
|
||
|
|
||
|
PSCSI_LUN_LIST = ctypes.POINTER(SCSI_LUN_LIST)
|
||
|
|
||
|
|
||
|
class ISCSI_UNIQUE_SESSION_ID(ctypes.Structure):
|
||
|
_fields_ = [
|
||
|
('AdapterUnique', wintypes.ULONGLONG),
|
||
|
('AdapterSpecific', wintypes.ULONGLONG)
|
||
|
]
|
||
|
|
||
|
|
||
|
PISCSI_UNIQUE_SESSION_ID = ctypes.POINTER(ISCSI_UNIQUE_SESSION_ID)
|
||
|
|
||
|
|
||
|
class ISCSI_UNIQUE_CONNECTION_ID(ISCSI_UNIQUE_SESSION_ID):
|
||
|
pass
|
||
|
|
||
|
|
||
|
PISCSI_UNIQUE_CONNECTION_ID = ctypes.POINTER(ISCSI_UNIQUE_CONNECTION_ID)
|
||
|
|
||
|
|
||
|
class ISCSI_TARGET_MAPPING(ctypes.Structure):
|
||
|
_fields_ = [
|
||
|
('InitiatorName', wintypes.WCHAR * w_const.MAX_ISCSI_HBANAME_LEN),
|
||
|
('TargetName', wintypes.WCHAR * (w_const.MAX_ISCSI_NAME_LEN + 1)),
|
||
|
('OSDeviceName', wintypes.WCHAR * w_const.MAX_PATH),
|
||
|
('SessionId', ISCSI_UNIQUE_SESSION_ID),
|
||
|
('OSBusNumber', wintypes.ULONG),
|
||
|
('OSTargetNumber', wintypes.ULONG),
|
||
|
('LUNCount', wintypes.ULONG),
|
||
|
('LUNList', PSCSI_LUN_LIST)
|
||
|
]
|
||
|
|
||
|
|
||
|
PISCSI_TARGET_MAPPING = ctypes.POINTER(ISCSI_TARGET_MAPPING)
|
||
|
|
||
|
|
||
|
class PERSISTENT_ISCSI_LOGIN_INFO(ctypes.Structure):
|
||
|
_fields_ = [
|
||
|
('TargetName', wintypes.WCHAR * (w_const.MAX_ISCSI_NAME_LEN + 1)),
|
||
|
('IsInformationalSession', wintypes.BOOLEAN),
|
||
|
('InitiatorInstance', wintypes.WCHAR * w_const.MAX_ISCSI_HBANAME_LEN),
|
||
|
('InitiatorPortNumber', wintypes.ULONG),
|
||
|
('TargetPortal', ISCSI_TARGET_PORTAL),
|
||
|
('SecurityFlags', ISCSI_SECURITY_FLAGS),
|
||
|
('Mappings', PISCSI_TARGET_MAPPING),
|
||
|
('LoginOptions', ISCSI_LOGIN_OPTIONS)
|
||
|
]
|
||
|
|
||
|
|
||
|
PPERSISTENT_ISCSI_LOGIN_INFO = ctypes.POINTER(PERSISTENT_ISCSI_LOGIN_INFO)
|
||
|
|
||
|
|
||
|
class ISCSI_CONNECTION_INFO(ctypes.Structure):
|
||
|
_fields_ = [
|
||
|
('ConnectionId', ISCSI_UNIQUE_CONNECTION_ID),
|
||
|
('InitiatorAddress', wintypes.PWSTR),
|
||
|
('TargetAddress', wintypes.PWSTR),
|
||
|
('InitiatorSocket', wintypes.USHORT),
|
||
|
('TargetSocket', wintypes.USHORT),
|
||
|
('CID', ctypes.c_ubyte * 2)
|
||
|
]
|
||
|
|
||
|
|
||
|
PISCSI_CONNECTION_INFO = ctypes.POINTER(ISCSI_CONNECTION_INFO)
|
||
|
|
||
|
|
||
|
class ISCSI_SESSION_INFO(ctypes.Structure):
|
||
|
_fields_ = [
|
||
|
('SessionId', ISCSI_UNIQUE_SESSION_ID),
|
||
|
('InitiatorName', wintypes.PWSTR),
|
||
|
('TargetName', wintypes.PWSTR),
|
||
|
('TargetNodeName', wintypes.PWSTR),
|
||
|
('ISID', ctypes.c_ubyte * 6),
|
||
|
('TSID', ctypes.c_ubyte * 2),
|
||
|
('ConnectionCount', wintypes.ULONG),
|
||
|
('Connections', PISCSI_CONNECTION_INFO)
|
||
|
]
|
||
|
|
||
|
|
||
|
PISCSI_SESSION_INFO = ctypes.POINTER(ISCSI_SESSION_INFO)
|
||
|
|
||
|
|
||
|
class SCSI_ADDRESS(ctypes.Structure):
|
||
|
_fields_ = [
|
||
|
('Length', wintypes.ULONG),
|
||
|
('PortNumber', ctypes.c_ubyte),
|
||
|
('PathId', ctypes.c_ubyte),
|
||
|
('TargetId', ctypes.c_ubyte),
|
||
|
('Lun', ctypes.c_ubyte)
|
||
|
]
|
||
|
|
||
|
|
||
|
class STORAGE_DEVICE_NUMBER(ctypes.Structure):
|
||
|
_fields_ = [
|
||
|
('DeviceType', DEVICE_TYPE),
|
||
|
('DeviceNumber', wintypes.DWORD),
|
||
|
('PartitionNumber', wintypes.DWORD)
|
||
|
]
|
||
|
|
||
|
|
||
|
class ISCSI_DEVICE_ON_SESSION(ctypes.Structure):
|
||
|
_fields_ = [
|
||
|
('InitiatorName', wintypes.WCHAR * w_const.MAX_ISCSI_HBANAME_LEN),
|
||
|
('TargetName', wintypes.WCHAR * (w_const.MAX_ISCSI_NAME_LEN + 1)),
|
||
|
('ScsiAddress', SCSI_ADDRESS),
|
||
|
('DeviceInterfaceType', wintypes.GUID),
|
||
|
('DeviceInterfaceName', wintypes.WCHAR * w_const.MAX_PATH),
|
||
|
('LegacyName', wintypes.WCHAR * w_const.MAX_PATH),
|
||
|
('StorageDeviceNumber', STORAGE_DEVICE_NUMBER),
|
||
|
('DeviceInstance', wintypes.ULONG)
|
||
|
]
|
||
|
|
||
|
|
||
|
PISCSI_DEVICE_ON_SESSION = ctypes.POINTER(ISCSI_DEVICE_ON_SESSION)
|
||
|
|
||
|
|
||
|
def register():
|
||
|
global lib_handle
|
||
|
lib_handle = ctypes.windll.iscsidsc
|
||
|
|
||
|
lib_handle.AddIScsiStaticTargetW.argtypes = [
|
||
|
wintypes.PWSTR,
|
||
|
wintypes.PWSTR,
|
||
|
wintypes.ULONG,
|
||
|
wintypes.BOOLEAN,
|
||
|
PISCSI_TARGET_MAPPING,
|
||
|
PISCSI_LOGIN_OPTIONS,
|
||
|
wintypes.LPVOID # unused
|
||
|
]
|
||
|
lib_handle.AddIScsiStaticTargetW.restype = wintypes.ULONG
|
||
|
|
||
|
lib_handle.GetDevicesForIScsiSessionW.argtypes = [
|
||
|
PISCSI_UNIQUE_SESSION_ID,
|
||
|
wintypes.PULONG,
|
||
|
PISCSI_DEVICE_ON_SESSION
|
||
|
]
|
||
|
lib_handle.GetDevicesForIScsiSessionW.restype = wintypes.ULONG
|
||
|
|
||
|
lib_handle.GetIScsiInitiatorNodeNameW.argtypes = [wintypes.PWCHAR]
|
||
|
lib_handle.GetIScsiInitiatorNodeNameW.restype = wintypes.ULONG
|
||
|
|
||
|
lib_handle.GetIScsiSessionListW.argtypes = [
|
||
|
wintypes.PULONG,
|
||
|
wintypes.PULONG,
|
||
|
PISCSI_SESSION_INFO
|
||
|
]
|
||
|
lib_handle.GetIScsiSessionListW.restype = wintypes.ULONG
|
||
|
|
||
|
lib_handle.LoginIScsiTargetW.argtypes = [
|
||
|
wintypes.PWSTR,
|
||
|
wintypes.BOOLEAN,
|
||
|
wintypes.PWSTR,
|
||
|
wintypes.ULONG,
|
||
|
PISCSI_TARGET_PORTAL,
|
||
|
ISCSI_SECURITY_FLAGS,
|
||
|
PISCSI_TARGET_MAPPING,
|
||
|
PISCSI_LOGIN_OPTIONS,
|
||
|
wintypes.ULONG,
|
||
|
wintypes.PCHAR,
|
||
|
wintypes.BOOLEAN,
|
||
|
PISCSI_UNIQUE_SESSION_ID,
|
||
|
PISCSI_UNIQUE_CONNECTION_ID
|
||
|
]
|
||
|
lib_handle.LoginIScsiTargetW.restype = wintypes.ULONG
|
||
|
|
||
|
lib_handle.LogoutIScsiTarget.argtypes = [PISCSI_UNIQUE_SESSION_ID]
|
||
|
lib_handle.LogoutIScsiTarget.restype = wintypes.ULONG
|
||
|
|
||
|
lib_handle.RemoveIScsiPersistentTargetW.argtypes = [
|
||
|
wintypes.PWSTR,
|
||
|
wintypes.ULONG,
|
||
|
wintypes.PWSTR,
|
||
|
PISCSI_TARGET_PORTAL
|
||
|
]
|
||
|
lib_handle.RemoveIScsiPersistentTargetW.restype = wintypes.ULONG
|
||
|
|
||
|
lib_handle.RemoveIScsiStaticTargetW.argtypes = [wintypes.PWSTR]
|
||
|
lib_handle.RemoveIScsiStaticTargetW.restype = wintypes.ULONG
|
||
|
|
||
|
lib_handle.ReportIScsiInitiatorListW.argtypes = [
|
||
|
wintypes.PULONG,
|
||
|
wintypes.PWCHAR
|
||
|
]
|
||
|
lib_handle.ReportIScsiInitiatorListW.restype = wintypes.ULONG
|
||
|
|
||
|
lib_handle.ReportIScsiPersistentLoginsW.argtypes = [
|
||
|
wintypes.PULONG,
|
||
|
PPERSISTENT_ISCSI_LOGIN_INFO,
|
||
|
wintypes.PULONG
|
||
|
]
|
||
|
lib_handle.ReportIScsiPersistentLoginsW.restype = wintypes.ULONG
|
||
|
|
||
|
lib_handle.ReportIScsiTargetsW.argtypes = [
|
||
|
wintypes.BOOLEAN,
|
||
|
wintypes.PULONG,
|
||
|
wintypes.PWCHAR
|
||
|
]
|
||
|
lib_handle.ReportIScsiTargetsW.restype = wintypes.ULONG
|