def get_physical_path(self): buf = ctypes.create_unicode_buffer(1024) bufLen = wintypes.DWORD(ctypes.sizeof(buf)) ret_val = virtdisk.GetVirtualDiskPhysicalPath(self._handle, ctypes.byref(bufLen), buf) if ret_val: raise exception.WindowsCloudbaseInitException( "Cannot get virtual disk physical path: %r", ret_val) return buf.value
def open(self): handle = kernel32.CreateFileW(ctypes.c_wchar_p(self._path), self.GENERIC_READ, self.FILE_SHARE_READ, 0, self.OPEN_EXISTING, self.FILE_ATTRIBUTE_READONLY, 0) if handle == self.INVALID_HANDLE_VALUE: raise exception.WindowsCloudbaseInitException( 'Cannot open file: %r') self._handle = handle self._sector_size, self._disk_size, self.fixed =\ self._get_geometry()
def _get_layout(self): layout = Win32_DRIVE_LAYOUT_INFORMATION_EX() bytes_returned = wintypes.DWORD() ret_val = kernel32.DeviceIoControl( self._handle, winioctlcon.IOCTL_DISK_GET_DRIVE_LAYOUT_EX, 0, 0, ctypes.byref(layout), ctypes.sizeof(layout), ctypes.byref(bytes_returned), 0) if not ret_val: raise exception.WindowsCloudbaseInitException( "Cannot get disk layout: %r") return layout
def create_user_logon_session(self, username, password, domain='.', load_profile=True): token = wintypes.HANDLE() ret_val = advapi32.LogonUserW(six.text_type(username), six.text_type(domain), six.text_type(password), 2, 0, ctypes.byref(token)) if not ret_val: raise exception.WindowsCloudbaseInitException( "User logon failed: %r") if load_profile: pi = Win32_PROFILEINFO() pi.dwSize = ctypes.sizeof(Win32_PROFILEINFO) pi.lpUserName = six.text_type(username) ret_val = userenv.LoadUserProfileW(token, ctypes.byref(pi)) if not ret_val: kernel32.CloseHandle(token) raise exception.WindowsCloudbaseInitException( "Cannot load user profile: %r") return token
def get_current_user(self): """Get the user account name from the underlying instance.""" buf_len = wintypes.ULONG(512) buf = ctypes.create_unicode_buffer(512) ret_val = secur32.GetUserNameExW( self.EXTENDED_NAME_FORMAT_SAM_COMPATIBLE, buf, ctypes.byref(buf_len)) if not ret_val: raise exception.WindowsCloudbaseInitException( "GetUserNameExW failed: %r") return buf.value.split("\\")
def _get_user_sid_and_domain(self, username): sid = ctypes.create_string_buffer(1024) cbSid = wintypes.DWORD(ctypes.sizeof(sid)) domainName = ctypes.create_unicode_buffer(1024) cchReferencedDomainName = wintypes.DWORD( ctypes.sizeof(domainName) / ctypes.sizeof(wintypes.WCHAR)) sidNameUse = wintypes.DWORD() ret_val = advapi32.LookupAccountNameW( 0, six.text_type(username), sid, ctypes.byref(cbSid), domainName, ctypes.byref(cchReferencedDomainName), ctypes.byref(sidNameUse)) if not ret_val: raise exception.WindowsCloudbaseInitException( "Cannot get user SID: %r") return (sid, domainName.value)
def _get_geometry(self): """Get details about the disk size bounds.""" geom = Win32_DiskGeometry() bytes_returned = wintypes.DWORD() ret_val = kernel32.DeviceIoControl( self._handle, winioctlcon.IOCTL_DISK_GET_DRIVE_GEOMETRY, 0, 0, ctypes.byref(geom), ctypes.sizeof(geom), ctypes.byref(bytes_returned), 0) if not ret_val: raise exception.WindowsCloudbaseInitException( "Cannot get disk geometry: %r") _sector_size = geom.BytesPerSector _disk_size = (geom.Cylinders * geom.TracksPerCylinder * geom.SectorsPerTrack * geom.BytesPerSector) fixed = geom.MediaType == Win32_DiskGeometry.FixedMedia return _sector_size, _disk_size, fixed
def get_geometry(self): if not self._geom: geom = Win32_DiskGeometry() bytes_returned = wintypes.DWORD() ret_val = kernel32.DeviceIoControl( self._handle, self.IOCTL_DISK_GET_DRIVE_GEOMETRY, 0, 0, ctypes.byref(geom), ctypes.sizeof(geom), ctypes.byref(bytes_returned), 0) if not ret_val: raise exception.WindowsCloudbaseInitException( "Cannot get disk geometry: %r") self._geom = geom return self._geom
def open(self): access = self.GENERIC_READ share_mode = self.FILE_SHARE_READ if self._allow_write: access |= self.GENERIC_WRITE share_mode |= self.FILE_SHARE_WRITE attributes = 0 else: attributes = self.FILE_ATTRIBUTE_READONLY handle = kernel32.CreateFileW(ctypes.c_wchar_p(self._path), access, share_mode, 0, self.OPEN_EXISTING, attributes, 0) if handle == self.INVALID_HANDLE_VALUE: raise exception.WindowsCloudbaseInitException( 'Cannot open file: %r') self._handle = handle self._sector_size, self._disk_size, self.fixed =\ self._get_geometry()
def open(self): if self._handle: self.close() self._load_virtdisk_dll() vst = Win32_VIRTUAL_STORAGE_TYPE() vst.DeviceId = self.VIRTUAL_STORAGE_TYPE_DEVICE_ISO vst.VendorId = get_WIN32_VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT() handle = wintypes.HANDLE() ret_val = virtdisk.OpenVirtualDisk( ctypes.byref(vst), ctypes.c_wchar_p(self._path), self.VIRTUAL_DISK_ACCESS_ATTACH_RO | self.VIRTUAL_DISK_ACCESS_READ, self.OPEN_VIRTUAL_DISK_FLAG_NONE, 0, ctypes.byref(handle)) if ret_val: raise exception.WindowsCloudbaseInitException( "Cannot open virtual disk: %r", ret_val) self._handle = handle
def _test_windows_exception(self, mock_format_error, mock_get_last_error, message="Test %r", description="test", error_code=None): mock_format_error.return_value = description mock_get_last_error.return_value = mock.sentinel.error_code with self.assertRaises(exception.CloudbaseInitException) as cm: raise exception.WindowsCloudbaseInitException(message, error_code) if error_code is None: mock_get_last_error.assert_called_once_with() error_code = mock.sentinel.error_code try: expected = message % description except TypeError: expected = message mock_format_error.assert_called_once_with(error_code) self.assertEqual(expected, str(cm.exception))
def get_physical_disks(self): physical_disks = [] disk_guid = GUID_DEVINTERFACE_DISK handle_disks = setupapi.SetupDiGetClassDevsW( ctypes.byref(disk_guid), None, None, self.DIGCF_PRESENT | self.DIGCF_DEVICEINTERFACE) if handle_disks == self.INVALID_HANDLE_VALUE: raise exception.CloudbaseInitException( "SetupDiGetClassDevs failed") try: did = Win32_SP_DEVICE_INTERFACE_DATA() did.cbSize = ctypes.sizeof(Win32_SP_DEVICE_INTERFACE_DATA) index = 0 while setupapi.SetupDiEnumDeviceInterfaces(handle_disks, None, ctypes.byref(disk_guid), index, ctypes.byref(did)): index += 1 handle_disk = self.INVALID_HANDLE_VALUE required_size = wintypes.DWORD() if not setupapi.SetupDiGetDeviceInterfaceDetailW( handle_disks, ctypes.byref(did), None, 0, ctypes.byref(required_size), None): if (kernel32.GetLastError() != self.ERROR_INSUFFICIENT_BUFFER): raise exception.WindowsCloudbaseInitException( "SetupDiGetDeviceInterfaceDetailW failed: %r") pdidd = ctypes.cast( msvcrt.malloc(ctypes.c_size_t(required_size.value)), ctypes.POINTER(Win32_SP_DEVICE_INTERFACE_DETAIL_DATA_W)) try: pdidd.contents.cbSize = ctypes.sizeof( Win32_SP_DEVICE_INTERFACE_DETAIL_DATA_W) if not self._is_64bit_arch(): # NOTE(cpoieana): For some reason, on x86 platforms # the alignment or content of the struct # is not taken into consideration. pdidd.contents.cbSize = 6 if not setupapi.SetupDiGetDeviceInterfaceDetailW( handle_disks, ctypes.byref(did), pdidd, required_size, None, None): raise exception.WindowsCloudbaseInitException( "SetupDiGetDeviceInterfaceDetailW failed: %r") device_path = ctypes.cast(pdidd.contents.DevicePath, wintypes.LPWSTR).value handle_disk = kernel32.CreateFileW(device_path, 0, self.FILE_SHARE_READ, None, self.OPEN_EXISTING, 0, 0) if handle_disk == self.INVALID_HANDLE_VALUE: raise exception.CloudbaseInitException( 'CreateFileW failed') sdn = Win32_STORAGE_DEVICE_NUMBER() b = wintypes.DWORD() if not kernel32.DeviceIoControl( handle_disk, self.IOCTL_STORAGE_GET_DEVICE_NUMBER, None, 0, ctypes.byref(sdn), ctypes.sizeof(sdn), ctypes.byref(b), None): raise exception.WindowsCloudbaseInitException( 'DeviceIoControl failed: %r') physical_disks.append(r"\\.\PHYSICALDRIVE%d" % sdn.DeviceNumber) finally: msvcrt.free(pdidd) if handle_disk != self.INVALID_HANDLE_VALUE: kernel32.CloseHandle(handle_disk) finally: setupapi.SetupDiDestroyDeviceInfoList(handle_disks) return physical_disks
def detach(self): ret_val = virtdisk.DetachVirtualDisk( self._handle, self.DETACH_VIRTUAL_DISK_FLAG_NONE, 0) if ret_val: raise exception.WindowsCloudbaseInitException( "Cannot detach virtual disk: %r", ret_val)
def attach(self): ret_val = virtdisk.AttachVirtualDisk( self._handle, 0, self.ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY, 0, 0, 0) if ret_val: raise exception.WindowsCloudbaseInitException( "Cannot attach virtual disk: %r", ret_val)