예제 #1
0
def local_path_for_entry(entry):
    if app.EntryIsDrive(entry):
        return app.EntryGetName(entry)[0]
    parent = app.EntryGetParent(entry)
    if parent:
        return local_path_for_entry(parent) + u"\\" + app.EntryGetName(entry)
    else:
        return u""
예제 #2
0
 def _do_save_as():
     global progress_dlg_cancel
     progress_dlg_cancel = False
     ff = app.GetFocusedFile()
     if ff:
         file_name = app.SaveDlgQuery(app.EntryGetName(ff))
         if not file_name:
             return
         file_name = os.path.abspath(file_name)
         if file_name[:2].upper() == app.EntryGetPath(ff)[:2].upper():
             if app.ShowYesNoDlg(
                     u"It is not safe to recover the file to destination you specified, recovered files can be corrupted. Do you want to proceed anyway?"
             ) == 7:
                 return
         if file_name:
             BULK = 256 * 1024
             app.ShowProgressDlg(
                 u"Copy...",
                 u"Copy file " + app.EntryGetName(ff) + u" to " + file_name)
             entry = ff
             target_path = file_name
             try:
                 volume = app.VolumeForEntry(entry)
                 mft_ref = app.EntryGetMFTRef(entry)
                 if volume and mft_ref >= 0:
                     file = volume.open_file(mft_ref)
                     total_size = reduce(lambda x, y: y.size + x,
                                         file.data_streams.values(), 0L)
                     processed_size = 0L
                     for data_stream_name, data_stream in file.data_streams.items(
                     ):
                         is_alter_stream = len(data_stream_name) > 0
                         file_name = target_path
                         if data_stream_name:
                             file_name += u"_" + data_stream_name
                         f = open(file_name, "wb")
                         pos = 0L
                         count = data_stream.size
                         while count > 0:
                             if progress_dlg_cancel:
                                 raise Exception(STR_USER_CANCELLED)
                             C = BULK
                             if C > count:
                                 C = count
                             data = data_stream.read_data(pos, C)
                             pos += C
                             count -= C
                             processed_size += C
                             f.write(data)
                             perc = int(pos * 100.0 / data_stream.size)
                             app.NotifyProgressDlg(perc)
                         f.close()
             except:
                 traceback.print_exc()
             app.HideProgressDlg()
예제 #3
0
def path_upto_parent(entry, parent_id):
    parent = app.EntryGetParent(entry)
    if parent and app.EntryGetID(parent) != parent_id:
        pp = path_upto_parent(parent, parent_id)
        if pp:
            return pp + u"\\" + app.EntryGetName(entry)
        else:
            return app.EntryGetName(entry)
    elif parent:
        if not app.EntryIsDrive(entry):
            return app.EntryGetName(entry)
        else:
            return app.EntryGetName(entry)[0]
    else:
        return u""
예제 #4
0
 def _validate_entry(entry):
     name = app.EntryGetName(entry)
     if not case_sensitive:
         name = name.upper()
     for mask in masks:
         if mask == "*.*":
             mask = "*"
         if not app.FileNameMatches(name, unicode(mask)):
             continue
         if not ((search_files and app.EntryIsFile(entry)) or
                 (search_folders and app.EntryIsDirectory(entry))):
             continue
         if not (
             (search_deleted and app.EntryIsDeleted(entry)) or
             (search_non_deleted and not app.EntryIsDeleted(entry))):
             continue
         if use_modify_filter:
             MD = app.EntryGetModifyDate(entry)
             if not ((MD >= modify_from) and (MD < modify_to + 1)):
                 continue
         if use_create_filter:
             CD = app.EntryGetCreateDate(entry)
             if not ((CD >= created_from) and (CD < created_to + 1)):
                 continue
         if size_from is not None and app.EntryIsFile(entry):
             if not (app.EntryGetDataSize(entry) >= size_from):
                 continue
         if size_to is not None and app.EntryIsFile(entry):
             if not (app.EntryGetDataSize(entry) <= size_to):
                 continue
         mft_ref = app.EntryGetMFTRef(entry)
         if not _entries.has_key(mft_ref):
             app.AddSearchResult(entry)
             _entries[mft_ref] = entry
         break
예제 #5
0
    def recovery():
        global RecoveryRunning, total_files, processed_files
        RecoveryRunning = True
        try:
            app.RecoveryPanelInit()
            rparams = app.GetRecoveryParams()
            recover_folder_structure = rparams['recover_folder_structure']
            dst_folder = rparams["recovery_folder"]
            if not os.path.exists(dst_folder):
                try:
                    os.makedirs(dst_folder)
                except:
                    S = STR_CANNOT_CREATE_FOLDER + dst_folder
                    app.ShowMessageModal(S)
                    raise Exception(S)
            c = dst_folder[-1]
            if c != "\\" and c != "/":
                dst_folder += "\\"

            _drv = os.path.abspath(dst_folder)[:2]

            emit(rmtMessage, STR_START_RECOVERY_TO + dst_folder)
            emit(rmtMessage, STR_GEN_FILE_LIST)
            entries = get_checked_entries()
            files = filter(lambda entry: app.EntryIsFile(entry), entries)
            mcpid = get_minimal_common_parent_id(files)

            total_files = len(files)
            total_size = reduce(lambda x, y: app.EntryGetDataSize(y) + x,
                                files, 0L)
            emit(
                rmtMessage, STR_FILE_LIST_GENERATED %
                (len(entries), total_files, total_size))
            context = RecoveryContext()
            context.total_files = total_files
            context.total_size = total_size
            thread.start_new_thread(report_thread, (context, ))

            for fe in entries:
                if app.EntryGetPath(fe)[:2].upper() == _drv.upper():
                    if app.ShowYesNoDlg(
                            u"It is not safe to recover some files into the folder you specified, recovered files can be corrupted. Do you want to proceed anyway?"
                    ) == 7:
                        raise Exception(STR_USER_CANCELLED)
                    else:
                        break

            if len(entries) > 0:
                del entries[0]  # remove .root. node from top
                for entry in files:
                    if not RecoveryRunning:
                        break
                    full_path = None
                    if recover_folder_structure:
                        full_path = dst_folder + path_upto_parent(entry, mcpid)
                    else:
                        full_path = dst_folder + app.EntryGetName(entry)
                    print "UPTO PATH: ", path_upto_parent(entry, mcpid)
                    dirs = u"\\".join(full_path.split(u"\\")[:-1])
                    if not os.path.exists(dirs):
                        print "Create dirs: ", dirs
                        os.makedirs(dirs)
                    copy_file(entry, full_path, context, rparams)
        finally:
            RecoveryRunning = False
예제 #6
0
 def copy_file(entry, target_path, context, rparams):
     global RecoverySkip
     recover_all_data_strems = rparams['recover_all_data_strems']
     delete_unsuccessful = rparams['delete_unsuccessful']
     naming = rparams['naming']
     unchecking = rparams['unchecking']
     context.current_file_progress = 0
     RecoverySkip = False
     BULK = 256 * 1024
     processed_size = 0L
     total_size = 0L
     file_name = None
     has_errors = False
     f = None
     try:
         volume = app.VolumeForEntry(entry)
         mft_ref = app.EntryGetMFTRef(entry)
         if volume and mft_ref >= 0:
             file = volume.open_file(mft_ref)
             if len(file.data_streams) > 1:
                 emit(
                     rmtMessage, STR_KNOWN_DATA_STREAMS +
                     unicode(str(file.data_streams.keys())))
             total_size = reduce(lambda x, y: y.size + x,
                                 file.data_streams.values(), 0L)
             for data_stream_name, data_stream in file.data_streams.items():
                 is_alter_stream = len(data_stream_name) > 0
                 if is_alter_stream and not recover_all_data_strems:
                     continue
                 if data_stream_name:
                     context.current_file_name = app.EntryGetName(
                         entry) + u" stream: " + data_stream_name
                 else:
                     context.current_file_name = app.EntryGetName(entry)
                 file_name = target_path
                 if data_stream_name:
                     file_name += u"_" + data_stream_name
                 if os.path.exists(file_name):
                     if naming == 0:
                         file_name = generate_autoname(file_name)
                     elif naming == 1:
                         file_name = app.SaveDlgQuery(file_name)
                         if not file_name:
                             raise Exception(STR_USER_SKIPPED)
                     elif naming == 2:
                         continue
                 f = open(file_name, "wb")
                 pos = 0L
                 count = data_stream.size
                 while count > 0:
                     if not RecoveryRunning:
                         raise Exception(STR_USER_CANCELLED)
                     if RecoverySkip:
                         if not is_alter_stream:
                             context.processed_size += count
                         raise Exception(STR_USER_SKIPPED)
                     C = BULK
                     if C > count:
                         C = count
                     try:
                         data = data_stream.read_data(pos, C)
                         pos += C
                         count -= C
                         processed_size += C
                         context.current_file_progress = int(
                             processed_size * 100.0 / total_size)
                         f.write(data)
                     finally:
                         if not is_alter_stream:
                             context.processed_size += C
                 f.close()
                 f = None
                 if is_alter_stream:
                     emit(
                         rmtSuccess,
                         u"Recovered ok - " + app.EntryGetPath(entry) +
                         u" stream " + data_stream_name)
                 else:
                     emit(rmtSuccess,
                          u"Recovered ok - " + app.EntryGetPath(entry))
         else:
             raise Exception(STR_CANNOT_OPEN_FILE % (mft_ref, str(volume)))
     except Exception, Value:
         has_errors = True
         emit(rmtError, STR_ERROR_ON % (target_path, str(Value)))
         if f:
             f.close()
         if file_name and delete_unsuccessful:
             try:
                 os.remove(file_name)
             except Exception, Value:
                 pass
예제 #7
0
def real_path_for_entry(entry):
    parent = app.EntryGetParent(entry)
    if parent:
        return real_path_for_entry(parent) + u"\\" + app.EntryGetName(entry)
    else:
        return u""
예제 #8
0
 def __on_search_init_error(ExceptionValue):
     search_finished.set()
     app.ShowMessageModal(STR_NON_NTFS_DRIVE %
                          (app.EntryGetName(search_start_entry), ))
예제 #9
0
    def _do_search(search_start_entry):
        global SearchActive, FoundResults
        print "Search start..."
        SearchActive = True
        search_params = app.GetSearchParams()
        masks = map(lambda x: x.strip(), search_params["masks"].split(","))
        case_sensitive = search_params['case_sensitive']
        search_folders = search_params['search_folders']
        search_files = search_params['search_files']
        search_deleted = search_params['deleted_entries']
        search_non_deleted = search_params['non_deleted_entries']
        use_modify_filter = search_params['use_modify_filter']
        modify_from = None
        modify_to = None
        if use_modify_filter:
            modify_from = search_params['modify_from']
            modify_to = search_params['modify_to']
        use_create_filter = search_params['use_create_filter']
        created_from = None
        created_to = None
        if use_create_filter:
            created_from = search_params['created_from']
            created_to = search_params['created_to']
        if not case_sensitive:
            masks = map(lambda mask: mask.upper(), masks)
        size_from = search_params.get("size_from", None)
        if size_from:
            a, b = tuple(filter(lambda x: x != '', size_from.split(" ")))
            size_from = long(a)
            if b == "KB":
                size_from *= 1024L
            elif b == "MB":
                size_from *= 1024L * 1024L
            elif b == "GB":
                size_from *= 1024L * 1024L * 1024L
        size_to = search_params.get("size_to", None)
        if size_to:
            a, b = tuple(filter(lambda x: x != '', size_to.split(" ")))
            size_to = long(a)
            if b == "KB":
                size_to *= 1024L
            elif b == "MB":
                size_to *= 1024L * 1024L
            elif b == "GB":
                size_to *= 1024L * 1024L * 1024L

        _entries = {}

        def _validate_entry(entry):
            name = app.EntryGetName(entry)
            if not case_sensitive:
                name = name.upper()
            for mask in masks:
                if mask == "*.*":
                    mask = "*"
                if not app.FileNameMatches(name, unicode(mask)):
                    continue
                if not ((search_files and app.EntryIsFile(entry)) or
                        (search_folders and app.EntryIsDirectory(entry))):
                    continue
                if not (
                    (search_deleted and app.EntryIsDeleted(entry)) or
                    (search_non_deleted and not app.EntryIsDeleted(entry))):
                    continue
                if use_modify_filter:
                    MD = app.EntryGetModifyDate(entry)
                    if not ((MD >= modify_from) and (MD < modify_to + 1)):
                        continue
                if use_create_filter:
                    CD = app.EntryGetCreateDate(entry)
                    if not ((CD >= created_from) and (CD < created_to + 1)):
                        continue
                if size_from is not None and app.EntryIsFile(entry):
                    if not (app.EntryGetDataSize(entry) >= size_from):
                        continue
                if size_to is not None and app.EntryIsFile(entry):
                    if not (app.EntryGetDataSize(entry) <= size_to):
                        continue
                mft_ref = app.EntryGetMFTRef(entry)
                if not _entries.has_key(mft_ref):
                    app.AddSearchResult(entry)
                    _entries[mft_ref] = entry
                break

        def _caption_thread(evt):
            while True:
                for i in xrange(6):
                    evt.wait(0.5)
                    if evt.isSet():
                        return
                    app.SetSearchCaption(u"Searching " + u"." * i)

        skip_unk_entry = False

        def _search_from(entry):
            while entry and SearchActive:
                _validate_entry(entry)
                if app.EntryIsContainer(entry):
                    if skip_unk_entry and app.EntryIsDirectory(
                            entry) and app.EntryGetMFTRef(entry) == -7:
                        entry = app.EntryGetNext(entry)
                        continue
                    _search_from(app.EntryGetFirstChild(entry))
                entry = app.EntryGetNext(entry)

        def _recurse_search(entry):
            if entry:
                _validate_entry(entry)
                _search_from(app.EntryGetFirstChild(entry))

        search_finished = threading.Event()

        def __on_search_init_error(ExceptionValue):
            search_finished.set()
            app.ShowMessageModal(STR_NON_NTFS_DRIVE %
                                 (app.EntryGetName(search_start_entry), ))

        entry_name = app.EntryGetName(search_start_entry)
        search_lock.acquire()
        if app.EntryIsDriveNotScanned(
                search_start_entry):  # start scan if needed
            scanner = CNTFSVisualScanner(search_start_entry)
            scanner.on_drive_open_error = __on_search_init_error
            scanner.on_volume_open_error = __on_search_init_error
            scanner.run()
        search_lock.release()
        scanner = ScanMgr.find_scanner_for_drive(entry_name)
        thread.start_new_thread(_caption_thread, (search_finished, ))
        if scanner is None:  # this drive is not scanned now
            _recurse_search(search_start_entry)
            search_finished.set()
        else:
            skip_unk_entry = True
            _recurse_search(search_start_entry)
            skip_unk_entry = False
            CSearchScanMixin.attach_mixin(scanner, _validate_entry,
                                          search_finished, _search_from)
            scanner.unlock()
            search_finished.wait()
            _recurse_search(scanner.unk_folder)

        print "\n\nFOUND: ", app.GetSearchResultCount()
        FoundResults += app.GetSearchResultCount()
예제 #10
0
 def __init__(self, volume_entry):
     self.__volume_entry = volume_entry
     drive_name = app.EntryGetName(volume_entry)
     device_name = u"\\\\.\\%s" % drive_name
     self.__unk_folder = None
     CNTFSBaseScanner.__init__(self, drive_name, device_name)