# -*- coding: utf-8 -*- # # gPodder - A media aggregator and podcast client # Copyright (c) 2005-2018 The gPodder Team # Copyright (c) 2018 Eric Le Lay # # gPodder is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # gPodder is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import ctypes from ctypes import HRESULT, Structure, byref, c_ulonglong from ctypes.wintypes import (BOOL, BYTE, DWORD, HANDLE, LPCWSTR, PULARGE_INTEGER, WORD) from uuid import UUID from win32ctypes.core.ctypes._util import check_zero, function_factory # Use a local copy of dlls. kernel32 = ctypes.WinDLL('kernel32') shell32 = ctypes.WinDLL('shell32') ole32 = ctypes.WinDLL('ole32') # https://msdn.microsoft.com/en-us/library/windows/desktop/aa373931%28v=vs.85%29.aspx class GUID(ctypes.Structure): _fields_ = [ ("Data1", DWORD), ("Data2", WORD), ("Data3", WORD), ("Data4", BYTE * 8), ] def __init__(self, uuidstr=None): uuid = UUID(uuidstr) Structure.__init__(self) self.Data1, self.Data2, self.Data3, self.Data4[0], self.Data4[1], rest = uuid.fields for i in range(2, 8): self.Data4[i] = rest >> (8 - i - 1) * 8 & 0xff REFKNOWNFOLDERID = ctypes.POINTER(GUID) S_OK = HRESULT(0).value CoTaskMemFree = function_factory( ole32.CoTaskMemFree, [ctypes.c_void_p], None) _BaseGetDiskFreeSpaceEx = function_factory( kernel32.GetDiskFreeSpaceExW, [LPCWSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER], BOOL, check_zero) _BaseGetFileAttributes = function_factory( kernel32.GetFileAttributesW, [LPCWSTR], DWORD) _BaseSHGetKnownFolderPath = function_factory( shell32.SHGetKnownFolderPath, [REFKNOWNFOLDERID, DWORD, HANDLE, ctypes.POINTER(ctypes.c_wchar_p)], HRESULT) def GetDiskFreeSpaceEx(lpDirectoryName): lp_dirname = LPCWSTR(lpDirectoryName) lpFreeBytesAvailable = c_ulonglong(0) lpTotalNumberOfBytes = c_ulonglong(0) lpTotalNumberOfFreeBytes = c_ulonglong(0) _BaseGetDiskFreeSpaceEx(lp_dirname, byref(lpFreeBytesAvailable), byref(lpTotalNumberOfBytes), byref(lpTotalNumberOfFreeBytes)) freeBytesAvailable = lpFreeBytesAvailable.value totalNumberOfBytes = lpTotalNumberOfBytes.value totalNumberOfFreeBytes = lpTotalNumberOfFreeBytes.value return (freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes) def GetFileAttributes(lpFileName): lp_filename = LPCWSTR(lpFileName) return _BaseGetFileAttributes(lp_filename) def SHGetKnownFolderPath(rfid, dwFlags): out_buf = ctypes.c_wchar_p() try: ret = _BaseSHGetKnownFolderPath(byref(rfid), dwFlags, None, byref(out_buf)) except WindowsError: return None if ret != S_OK: return None res = out_buf.value CoTaskMemFree(out_buf) return res # https://msdn.microsoft.com/en-us/library/dd378447(v=vs.85).aspx class KNOWN_FOLDER_FLAG: KF_FLAG_DEFAULT = 0x00000000 KF_FLAG_SIMPLE_IDLIST = 0x00000100 KF_FLAG_NOT_PARENT_RELATIVE = 0x00000200 KF_FLAG_DEFAULT_PATH = 0x00000400 KF_FLAG_INIT = 0x00000800 KF_FLAG_NO_ALIAS = 0x00001000 KF_FLAG_DONT_UNEXPAND = 0x00002000 KF_FLAG_DONT_VERIFY = 0x00004000 KF_FLAG_CREATE = 0x00008000 KF_FLAG_NO_PACKAGE_REDIRECTION = 0x00010000 KF_FLAG_NO_APPCONTAINER_REDIRECTION = 0x00010000 KF_FLAG_FORCE_PACKAGE_REDIRECTION = 0x00020000 KF_FLAG_FORCE_APPCONTAINER_REDIRECTION = 0x00020000 KF_FLAG_RETURN_FILTER_REDIRECTION_TARGET = 0x00040000 KF_FLAG_FORCE_APP_DATA_REDIRECTION = 0x00080000 KF_FLAG_ALIAS_ONLY = 0x80000000 # https://msdn.microsoft.com/en-us/library/dd378457(v=vs.85).aspx class KNOWNFOLDERID: FOLDERID_Documents = GUID("{FDD39AD0-238F-46AF-ADB4-6C85480369C7}") def get_documents_folder(): flags = KNOWN_FOLDER_FLAG.KF_FLAG_DEFAULT | \ KNOWN_FOLDER_FLAG.KF_FLAG_DONT_UNEXPAND | \ KNOWN_FOLDER_FLAG.KF_FLAG_CREATE | \ KNOWN_FOLDER_FLAG.KF_FLAG_DONT_VERIFY return SHGetKnownFolderPath(KNOWNFOLDERID.FOLDERID_Documents, flags) def get_reg_current_user_string_value(subkey, value_name): import winreg try: my_key = winreg.OpenKeyEx(winreg.HKEY_CURRENT_USER, subkey) except FileNotFoundError: return None try: value, type_ = winreg.QueryValueEx(my_key, value_name) if type_ == winreg.REG_SZ: return value else: raise WindowsError("Unexpected type for value %s in registry: %i" % (valueName, type_)) except FileNotFoundError: return None