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""
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()
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""
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 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
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
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""
def __on_search_init_error(ExceptionValue): search_finished.set() app.ShowMessageModal(STR_NON_NTFS_DRIVE % (app.EntryGetName(search_start_entry), ))
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()
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)