Exemplo n.º 1
0
def rmdirRecursiveWindows(dir):
    """Windows-specific version of rmdirRecursive that handles
    path lengths longer than MAX_PATH.
    """

    dir = os.path.realpath(dir)
    # Make sure directory is writable
    SetFileAttributesW('\\\\?\\' + dir, FILE_ATTRIBUTE_NORMAL)

    for ffrec in FindFiles('\\\\?\\' + dir + '\\*.*'):
        file_attr = ffrec[0]
        name = ffrec[8]
        if name == '.' or name == '..':
            continue
        full_name = os.path.join(dir, name)

        if file_attr & FILE_ATTRIBUTE_DIRECTORY:
            rmdirRecursiveWindows(full_name)
        else:
            SetFileAttributesW('\\\\?\\' + full_name, FILE_ATTRIBUTE_NORMAL)
            DeleteFile('\\\\?\\' + full_name)
    RemoveDirectory('\\\\?\\' + dir)
Exemplo n.º 2
0
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