def get_file_basic_info(file_name, file_handle): file_attributes = GetFileAttributesW(file_name) file_size = GetFileSize(file_handle) logging.debug("Compressed: %r", bool(file_attributes & FILE_ATTRIBUTE_COMPRESSED)) logging.debug("Encrypted: %r", bool(file_attributes & FILE_ATTRIBUTE_ENCRYPTED)) logging.debug("Sparse: %r", bool(file_attributes & FILE_ATTRIBUTE_SPARSE_FILE)) return file_size, bool(file_attributes & (FILE_ATTRIBUTE_COMPRESSED | FILE_ATTRIBUTE_ENCRYPTED | FILE_ATTRIBUTE_SPARSE_FILE))
def get_file_basic_info(file_name, file_handle): file_attributes = GetFileAttributesW(file_name) file_size = GetFileSize(file_handle) is_compressed = bool(file_attributes & FILE_ATTRIBUTE_COMPRESSED) is_encrypted = bool(file_attributes & FILE_ATTRIBUTE_ENCRYPTED) is_sparse = bool(file_attributes & FILE_ATTRIBUTE_SPARSE_FILE) is_special = is_compressed | is_encrypted | is_sparse if is_special: logger.debug('{}: {} {} {}'.format( file_name, 'compressed' if is_compressed else '', 'encrypted' if is_encrypted else '', 'sparse' if is_sparse else '')) return file_size, is_special
def isSysOrHide(system, filename, filepath): ''' '判断当前系统下,文件是否为系统文件或隐藏文件 '参数:system :系统代号,1 表示 windows 系统, 2 表示 linux系统 ' filename:文件名 '若文件是系统文件或是隐藏文件,则返回True,否则返回False ''' if system == 1: file_flag = GetFileAttributesW(filepath) is_hidden = file_flag & FILE_ATTRIBUTE_HIDDEN is_system = file_flag & FILE_ATTRIBUTE_SYSTEM if is_hidden == 2 or is_system == 4: return True else: return False elif system == 2: if filename.startswith('.'): return True else: return False
def file_wipe(file_name): # add \\?\ if it does not exist to support Unicode and long paths file_name = extended_path(file_name) check_os() win_version, _ = determine_win_version() volume = volume_from_file(file_name) volume_info = get_volume_information(volume) cluster_size = (volume_info.sectors_per_cluster * volume_info.bytes_per_sector) file_handle = open_file(file_name) file_size, is_special = get_file_basic_info(file_name, file_handle) orig_extents = get_extents(file_handle) if is_special: bridged_extents = [ x for x in logical_ranges_to_extents( get_extents(file_handle, False), True) ] CloseHandle(file_handle) #logger.debug('Original extents: {}'.format(orig_extents)) volume_handle = obtain_readwrite(volume) attrs = GetFileAttributesW(file_name) if attrs & FILE_ATTRIBUTE_READONLY: # Remove read-only attribute to avoid "access denied" in CreateFileW(). SetFileAttributesW(file_name, attrs & ~FILE_ATTRIBUTE_READONLY) file_handle = open_file(file_name, GENERIC_READ | GENERIC_WRITE) if not is_special: # Direct overwrite when it's a regular file. #logger.info("Attempting direct file wipe.") wipe_file_direct(file_handle, orig_extents, cluster_size, file_size) new_extents = get_extents(file_handle) CloseHandle(file_handle) #logger.debug('New extents: {}'.format(new_extents)) if orig_extents == new_extents: clean_up(None, volume_handle, None) return # Expectation was that extents should be identical and file is wiped. # If OS didn't give that to us, continue below and use defrag wipe. # Any extent within new_extents has now been wiped by above. # It can be subtracted from the orig_extents list, and now we will # just clean up anything not yet overwritten. orig_extents = extents_a_minus_b(orig_extents, new_extents) else: # File needs special treatment. We can't just do a basic overwrite. # First we will truncate it. Then chase down the freed clusters to # wipe them, now that they are no longer part of the file. truncate_file(file_handle) CloseHandle(file_handle) # Poll to confirm that our clusters were freed. poll_clusters_freed(volume_handle, volume_info.total_clusters, orig_extents) # Chase down all the freed clusters we can, and wipe them. #logger.debug("Attempting defrag file wipe.") # Put the temp file in the same folder as the target wipe file. # Should be able to write this path if user can write the wipe file. tmp_file_path = os.path.dirname(file_name) + os.sep + tmp_file_name if is_special: orig_extents = choose_if_bridged(volume_handle, volume_info.total_clusters, orig_extents, bridged_extents) for lcn_start, lcn_end in orig_extents: result = wipe_extent_by_defrag(volume_handle, lcn_start, lcn_end, cluster_size, volume_info.total_clusters, tmp_file_path) # Clean up. clean_up(None, volume_handle, tmp_file_path) return