Skip to content

Commit 1a6c96a

Browse files
committed
v2024.11.20
1 parent 0617e42 commit 1a6c96a

File tree

5 files changed

+77
-36
lines changed

5 files changed

+77
-36
lines changed
2.21 KB
Loading

OneDriveExplorer/Images/splashv.png

370 Bytes
Loading

OneDriveExplorer/OneDriveExplorer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# OneDriveExplorer
2-
# Copyright (C) 2022
2+
# Copyright (C) 2024
33
#
44
# This file is part of OneDriveExplorer
55
#
@@ -51,7 +51,7 @@
5151
)
5252

5353
__author__ = "Brian Maloney"
54-
__version__ = "2024.11.12"
54+
__version__ = "2024.11.20"
5555
__email__ = "[email protected]"
5656
rbin = []
5757
DATParser = dat_parser.DATParser()

OneDriveExplorer/OneDriveExplorer_GUI.py

Lines changed: 67 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# OneDriveExplorer
2-
# Copyright (C) 2022
2+
# Copyright (C) 2024
33
#
44
# This file is part of OneDriveExplorer
55
#
@@ -29,6 +29,7 @@
2929
import re
3030
import base64
3131
import json
32+
import psutil
3233
import ctypes
3334
import webbrowser
3435
import argparse
@@ -103,7 +104,7 @@
103104
)
104105

105106
__author__ = "Brian Maloney"
106-
__version__ = "2024.11.12"
107+
__version__ = "2024.11.20"
107108
__email__ = "[email protected]"
108109
rbin = []
109110
user_logs = {}
@@ -123,6 +124,7 @@
123124
dfs_to_concat = []
124125
folder_type = []
125126
dragging_sash = False
127+
sync_message = None
126128
df_GraphMetadata_Records = pd.DataFrame(columns=['fileName', 'resourceID', 'graphMetadataJSON', 'spoCompositeID',
127129
'createdBy', 'modifiedBy', 'filePolicies', 'fileExtension', 'lastWriteCount'])
128130

@@ -232,23 +234,32 @@ def create_widgets(self):
232234
self.win.bind('<Configure>', self.sync_windows)
233235

234236
def btn1(self):
237+
parent = psutil.Process(os.getpid())
238+
for child in parent.children(recursive=True):
239+
child.kill()
240+
self.win.destroy()
235241
sys.exit()
236242

237243
def btn2(self):
238244
self.root.unbind("<Configure>")
245+
if sync_message:
246+
sync_message.bind_events()
239247
self.win.destroy()
240248

241249
def __callback(self):
242250
return
243251

244252
def sync_windows(self, event=None):
245-
x = self.root.winfo_x()
246-
qw = self.win.winfo_width()
247-
y = self.root.winfo_y()
248-
qh = self.win.winfo_height()
249-
w = self.root.winfo_width()
250-
h = self.root.winfo_height()
251-
self.win.geometry("+%d+%d" % (x + w/2 - qw/2, y + h/2 - qh/2))
253+
try:
254+
x = self.root.winfo_x()
255+
qw = self.win.winfo_width()
256+
y = self.root.winfo_y()
257+
qh = self.win.winfo_height()
258+
w = self.root.winfo_width()
259+
h = self.root.winfo_height()
260+
self.win.geometry("+%d+%d" % (x + w/2 - qw/2, y + h/2 - qh/2))
261+
except Exception:
262+
pass
252263

253264

254265
class Preferences:
@@ -437,7 +448,7 @@ def __init__(self, root, sql=False):
437448
self.sql = sql
438449
self.win = tk.Toplevel(self.root)
439450
self.win.wm_transient(self.root)
440-
self.win.title("Load User Hive")
451+
self.win.title("Load User Hive - NTUSER.DAT")
441452
self.win.iconbitmap(application_path + '/Images/titles/question.ico')
442453
self.win.grab_set()
443454
self.win.focus_force()
@@ -456,9 +467,9 @@ def __init__(self, root, sql=False):
456467
self.inner_frame.grid(row=0, column=0, padx=5, pady=5)
457468
self.button_frame.grid(row=2, column=0, columnspan=3)
458469

459-
self.label_i = ttk.Label(self.inner_frame, image=question_img)
470+
self.label_i = ttk.Label(self.inner_frame, image=reg_img)
460471
self.label = ttk.Label(self.inner_frame,
461-
text="User's registry hive allows the mount points of the SyncEngines to be resolved.\n\nDo you want to provide a registry hive?\n")
472+
text="User's registry hive (NTUSER.DAT) allows the mount points of the SyncEngines to be resolved.\n\nDo you want to provide a registry hive?\n")
462473

463474
self.label_l = ttk.Label(self.inner_frame, text="Note:")
464475

@@ -475,7 +486,7 @@ def __init__(self, root, sql=False):
475486
takefocus=False,
476487
command=self.close_hive)
477488

478-
self.label_i.grid(row=0, column=0, rowspan=2, sticky='n')
489+
self.label_i.grid(row=0, column=0, rowspan=2, padx=(0, 5), sticky='n')
479490
self.label.grid(row=0, column=1, columnspan=2, pady=(5, 0), sticky='w')
480491
self.label_l.grid(row=1, column=1, sticky='nw')
481492
self.label_r.grid(row=1, column=2, padx=5, sticky='w')
@@ -496,8 +507,8 @@ def close_hive(self):
496507
def get_hive(self):
497508
global reghive
498509
reghive = filedialog.askopenfilename(initialdir="/",
499-
title="Open",
500-
filetypes=(("Load user hive",
510+
title="Open User Registry Hive",
511+
filetypes=(("NTUSER.DAT",
501512
"*.dat"),))
502513
if reghive:
503514
self.win.destroy()
@@ -1320,13 +1331,24 @@ def create_widgets(self):
13201331
def bind_events(self):
13211332
self.root.bind('<Configure>', self.sync_windows)
13221333
self.win.bind('<Configure>', self.sync_windows)
1334+
self.root.bind("<Map>", self.bring_window_back)
1335+
1336+
def bring_window_back(self, e):
1337+
self.win.attributes('-topmost', 1)
1338+
self.win.attributes('-topmost', 0)
13231339

13241340
def sync_windows(self, event=None):
1341+
on_top = self.root.tk.eval('wm stackorder '+str(self.win)+' isabove '+str(self.root))
1342+
if on_top == '0':
1343+
self.bring_window_back(event)
1344+
13251345
if 'thread_load' in str(threading.enumerate()) and len(threading.enumerate()) <= 4:
13261346
self.root.unbind("<Configure>")
1347+
self.root.unbind("<Map>")
13271348
self.win.destroy()
13281349
if len(threading.enumerate()) <= 3:
13291350
self.root.unbind("<Configure>")
1351+
self.root.unbind("<Map>")
13301352
self.win.destroy()
13311353
try:
13321354
x = self.root.winfo_x()
@@ -1341,6 +1363,7 @@ def sync_windows(self, event=None):
13411363

13421364
def close_sync(self):
13431365
self.root.unbind("<Configure>")
1366+
self.root.unbind("<Map>")
13441367
self.win.destroy()
13451368

13461369
def __callback(self):
@@ -1596,7 +1619,7 @@ def do_popup(self, event):
15961619
popup.add_command(label="Remove OneDrive Folder",
15971620
image=self.rof_img,
15981621
compound='left',
1599-
command=lambda: [self.thread_del_folder(curItem), SyncMessage(root)])
1622+
command=lambda: self.thread_del_folder(curItem))
16001623
popup.add_separator()
16011624

16021625
if image[0] != str(del_img):
@@ -1689,8 +1712,10 @@ def copy_name(self, values):
16891712
self.root.clipboard_append(name_item.split("Name: ")[1])
16901713

16911714
def thread_del_folder(self, iid):
1715+
global sync_message
16921716
message.unbind('<Double-Button-1>', bind_id)
16931717
value_label['text'] = ''
1718+
sync_message = SyncMessage(root)
16941719
t1 = threading.Thread(target=self.del_folder, args=(iid,), daemon=True)
16951720
t1.start()
16961721
root.after(200, check_if_ready, t1, "df")
@@ -3373,6 +3398,7 @@ def fixed_map(option):
33733398

33743399

33753400
def search(item=''):
3401+
root.update()
33763402
query = search_entry.get()
33773403
if len(query) == 0:
33783404
return
@@ -3447,6 +3473,7 @@ def clear_search():
34473473

34483474

34493475
def delete_item_and_descendants(tree, item=''):
3476+
root.update()
34503477
children = tree.get_children(item)
34513478
for child in children:
34523479
if child in file_items:
@@ -3748,17 +3775,20 @@ def live_system(menu):
37483775
pb.stop()
37493776
odl = parse_odl(logs[0], key, pb, value_label, gui=True)
37503777
tb = ttk.Frame()
3751-
pt = pandastablepatch.MyTable(tb,
3752-
dataframe=odl,
3753-
maxcellwidth=900,
3754-
showtoolbar=False,
3755-
showstatusbar=False,
3756-
enable_menus=True,
3757-
editable=False)
3758-
tv_frame.add(tb, text=f'{key} Logs ')
3759-
pt.adjustColumnWidths()
3760-
pt.show()
3761-
user_logs.setdefault(f'{key}_logs.csv', pt)
3778+
3779+
if not odl.empty:
3780+
pt = pandastablepatch.MyTable(tb,
3781+
dataframe=odl,
3782+
maxcellwidth=900,
3783+
showtoolbar=False,
3784+
showstatusbar=False,
3785+
enable_menus=True,
3786+
editable=False)
3787+
tv_frame.add(tb, text=f'{key} Logs ')
3788+
pt.adjustColumnWidths()
3789+
pt.show()
3790+
user_logs.setdefault(f'{key}_logs.csv', pt)
3791+
37623792
if menu_data['odl_save'] is True:
37633793
value_label['text'] = f"Saving {key}_logs.csv. Please wait...."
37643794
pb.configure(mode='indeterminate')
@@ -3798,7 +3828,7 @@ def open_dat(menu):
37983828
global reghive
37993829
global recbin
38003830
filename = filedialog.askopenfilename(initialdir="/",
3801-
title="Open",
3831+
title="Open <UserCid>.dat",
38023832
filetypes=(("OneDrive dat file",
38033833
"*.dat *.dat.previous"),
38043834
))
@@ -3896,7 +3926,7 @@ def odl(folder_name, csv=False):
38963926
breadcrumb.disable_crumbs()
38973927
file_manager.tv2.delete(*file_manager.tv2.get_children())
38983928
file_manager.tv3.delete(*file_manager.tv3.get_children())
3899-
key_find = re.compile(r'Users/(?P<user>.*)?/AppData')
3929+
key_find = re.compile(r'Users/(?P<user>[^/]+)/AppData')
39003930
pb.stop()
39013931
start = time.time()
39023932

@@ -3944,7 +3974,7 @@ def odl(folder_name, csv=False):
39443974
if len(key) == 0:
39453975
key = 'ODL'
39463976
else:
3947-
key = key[0]
3977+
key = key[-1]
39483978
odl = parse_odl(folder_name, key, pb, value_label, gui=True)
39493979

39503980
tb = ttk.Frame()
@@ -4473,6 +4503,7 @@ def sync():
44734503

44744504
def check_if_ready(thread, t_string):
44754505
global cstruct_df
4506+
global sync_message
44764507
if thread.is_alive():
44774508
# not ready yet, run the check again soon
44784509
root.after(200, check_if_ready, thread, t_string)
@@ -4483,6 +4514,7 @@ def check_if_ready(thread, t_string):
44834514
if t_string == "s":
44844515
cstruct_df = load_cparser(args.cstructs)
44854516
if t_string == "tca" or t_string == "df":
4517+
sync_message = None
44864518
widgets_normal()
44874519
if t_string == "lp":
44884520
root.event_generate("<Configure>")
@@ -4499,7 +4531,9 @@ def thread_search():
44994531

45004532

45014533
def thread_clear_all():
4534+
global sync_message
45024535
message.unbind('<Double-Button-1>', bind_id)
4536+
sync_message = SyncMessage(root)
45034537
t1 = threading.Thread(target=clear_all, daemon=True)
45044538
t1.start()
45054539
root.after(200, check_if_ready, t1, "tca")
@@ -4723,7 +4757,7 @@ def stop_drag(event):
47234757
error_img = ImageTk.PhotoImage(Image.open(application_path + '/Images/gui/error.png')) # ExportResult
47244758
asc_img = ImageTk.PhotoImage(Image.open(application_path + '/Images/gui/table_sort_asc.png')) # pandastable
47254759
desc_img = ImageTk.PhotoImage(Image.open(application_path + '/Images/gui/table_sort_desc.png')) # pandastable
4726-
question_img = ImageTk.PhotoImage(Image.open(application_path + '/Images/gui/question.png')) # hive
4760+
reg_img = ImageTk.PhotoImage(Image.open(application_path + '/Images/gui/registry.png')) # hive
47274761
trash_img = ImageTk.PhotoImage(Image.open(application_path + '/Images/gui/trashcan.png')) # recbin
47284762
ode_img = ImageTk.PhotoImage(Image.open(application_path + '/Images/gui/ode.png')) # about
47294763
meta_img = ImageTk.PhotoImage(Image.open(application_path + '/Images/gui/tools.png')) # about
@@ -5052,7 +5086,7 @@ def stop_drag(event):
50525086
odsmenu.add_command(label="Import CSV", image=csv_img, compound='left',
50535087
command=lambda: import_csv(odsmenu))
50545088
odsmenu.add_command(label="Unload all files", image=uaf_img, compound='left',
5055-
command=lambda: [thread_clear_all(), SyncMessage(root)], accelerator="Alt+0")
5089+
command=lambda: thread_clear_all(), accelerator="Alt+0")
50565090
odsmenu.entryconfig("Unload all files", state='disable')
50575091

50585092
odlmenu.add_command(label="Load ODL logs", image=folderop_img, compound='left',
@@ -5070,7 +5104,7 @@ def stop_drag(event):
50705104
projmenu.add_command(label="SaveAs", image=saveas_img, compound='left',
50715105
command=lambda: saveAs_proj())
50725106
projmenu.add_command(label="Unload", image=ual_img, compound='left',
5073-
command=lambda: [thread_clear_all(), del_logs(), SyncMessage(root)])
5107+
command=lambda: [thread_clear_all(), del_logs()])
50745108
projmenu.entryconfig("Save", state='disable')
50755109
root.unbind('<Alt-s>')
50765110
projmenu.entryconfig("SaveAs", state='disable')

OneDriveExplorer/ode/parsers/odl.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,10 @@ def process_odl(filename, map):
584584
odl['Code_File'] = data.code_file_name.decode('utf8')
585585
odl['Flags'] = data.flags
586586
odl['Function'] = data.code_function_name.decode('utf8')
587-
odl['Context_Data'] = extract_context_data(data_block.context_data) if data_block.context_data else ''
587+
if hasattr(data_block, 'context_data') and data_block.context_data:
588+
odl['Context_Data'] = extract_context_data(data_block.context_data)
589+
#cstruct.dumpstruct(data_block)
590+
#odl['Context_Data'] = extract_context_data(data_block.context_data) if data_block.context_data else ''
588591
odl['Description'] = description
589592
odl['Params'] = params
590593
odl_rows.append(odl)
@@ -629,6 +632,10 @@ def parse_odl(rootDir, key='', pb=False, value_label=False, gui=False):
629632

630633
total = len(filenames)
631634
count = 0
635+
636+
if total == 0:
637+
return df
638+
632639
if gui:
633640
pb.configure(mode='determinate')
634641
for filename in filenames:

0 commit comments

Comments
 (0)