Skip to content

Add GUI support for selecting files to collect/upload#238

Merged
Miauwkeru merged 11 commits into
fox-it:mainfrom
raverburg:feature/collect_files_gui
May 6, 2026
Merged

Add GUI support for selecting files to collect/upload#238
Miauwkeru merged 11 commits into
fox-it:mainfrom
raverburg:feature/collect_files_gui

Conversation

@raverburg
Copy link
Copy Markdown
Contributor

This update adds functionality to the GUI that allows users to select specific files for collection and/or upload. Selected files are passed to the existing logic used by acquire, allowing users to either collect them during acquisition or upload them independently.

Notes:
We use a custom version of acquire internally that looks for a config.json file in the same directory instead of using config.py

Comment thread acquire/gui/base.py Outdated
Comment thread acquire/gui/base.py Outdated
Comment thread acquire/gui/win32.py Outdated
def choose_folder(self) -> None:
if self._closed:
return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed there is empty space here, most of the style/lint issues can be fixed by running tox run -e fix and then you can check it with tox run -e lint

Comment thread acquire/gui/win32.py
Comment on lines +537 to 540
self.choose_files()
elif lParam == self.start_button:
user32.EnableWindow(self.start_button, False)
user32.EnableWindow(self.choose_folder_button, False)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.choose_files()
elif lParam == self.start_button:
user32.EnableWindow(self.start_button, False)
user32.EnableWindow(self.choose_folder_button, False)
self.choose_files()
elif lParam == self.start_button:
user32.EnableWindow(self.start_button, False)
user32.EnableWindow(self.choose_folder_button, False)
user32.EnableWindow(self.choose_files_button, False)

Comment thread acquire/gui/win32.py Outdated
user32.SetWindowTextA(self.choose_files_button, b"Clear file(s)")
user32.EnableWindow(self.start_button, True)
else:
print("User cancelled file selection")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically it could also be because the filename(s) exceeded the 4096 wchar buffer. Is there a way to distinguish between those errors? And then, show it to the user if it isn't a cancelled operation?

Comment thread acquire/gui/win32.py Outdated
("lStructSize", w.DWORD),
("hwndOwner", w.HWND),
("hInstance", w.HINSTANCE),
("lpstrFilter", w.LPWSTR),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
("lpstrFilter", w.LPWSTR),
("lpstrFilter", w.LPCWSTR),

Comment thread acquire/gui/win32.py Outdated
("lpstrDefExt", w.LPWSTR),
("lCustData", w.LPARAM),
("lpfnHook", w.LPVOID),
("lpTemplateName", w.LPWSTR),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
("lpTemplateName", w.LPWSTR),
("lpTemplateName", w.LPCSTR),

Comment thread acquire/gui/win32.py Outdated
Comment on lines +162 to +163
("lpstrInitialDir", w.LPWSTR),
("lpstrTitle", w.LPWSTR),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
("lpstrInitialDir", w.LPWSTR),
("lpstrTitle", w.LPWSTR),
("lpstrInitialDir", w.LPCWSTR),
("lpstrTitle", w.LPCWSTR),

Comment thread acquire/gui/win32.py Outdated
get_last_error,
sizeof,
string_at,
wstring_at
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently unused

@raverburg
Copy link
Copy Markdown
Contributor Author

Hi! Sorry for the long wait. I only remembered this PR was still open when I ran into the same issue again: there's no easy way for clients to upload investigation material (without 3rd party tools), which is exactly what acquire GUI aims to fix.

I've addressed your feedback:

  • Correct ctypes pointer types on OPENFILENAME fields
  • Declare argtypes/restype for CommDlgExtendedError
  • Fix nMaxFile to use character count instead of byte size
  • Surface FNERR_BUFFERTOOSMALL error via MessageBox
  • Disable "Choose files" button once acquisition starts
  • Update wait_for_start return type to reflect list[str] for files

Copy link
Copy Markdown
Contributor

@Miauwkeru Miauwkeru left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If acquire output folder is selected, it might be good to disable the
"select file(s) to collect" chooser.
As currently you can select both where the upload part will get ignored. Looking just at the GUI you would not expect that to happen

Comment thread acquire/gui/base.py Outdated
def wait_for_start(self, args: Namespace) -> tuple[str, bool, bool]:
return args.output, args.auto_upload, False
def wait_for_start(self, args: Namespace) -> tuple[str, list[str], bool, bool]:
return args.output, None, args.auto_upload, False
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return args.output, None, args.auto_upload, False
return args.output, [], args.auto_upload, False

Either an empty list or change the typehint that you know you could get a None value

Comment thread acquire/gui/win32.py Outdated
error_code = comdlg32.CommDlgExtendedError()
if error_code == FNERR_BUFFERTOOSMALL:
user32.MessageBoxA(
self.hwnd, b"Too many or too long file names selected. Please select fewer files.", b"Acquire", 0
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.hwnd, b"Too many or too long file names selected. Please select fewer files.", b"Acquire", 0
self.hwnd, b"The combined filename length exceeded the expected size. Please select fewer files.", b"Acquire", 0

This reads better to me, but feel free to add some suggestions

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No I agree

@raverburg raverburg force-pushed the feature/collect_files_gui branch from 86ae76a to e7db77c Compare April 29, 2026 14:33
Comment thread acquire/gui/win32.py Outdated
ofn.nMaxFile = buffer_size
ofn.lpstrFilter = "All Files\0*.*\0Text Files\0*.txt\0\0"
ofn.nFilterIndex = 1
ofn.Flags = 0x00002000 | 0x00080000 | 0x00000200
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a comment with what these magic numbers actually mean?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed I was using a wrong flag so I corrected this and changed the numbers with named constants

Comment thread acquire/gui/win32.py Outdated
Co-authored-by: Miauwkeru <Miauwkeru@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@Miauwkeru Miauwkeru left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency :P

Comment thread acquire/gui/win32.py Outdated


comdlg32 = WinDLL("comdlg32", use_last_error=True)
comdlg32.GetOpenFileNameW.argtypes = (POINTER(OPENFILENAME),)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
comdlg32.GetOpenFileNameW.argtypes = (POINTER(OPENFILENAME),)
comdlg32.GetOpenFileNameW.argtypes = (POINTER(OPENFILENAMEW),)

Comment thread acquire/gui/win32.py Outdated
Comment on lines +389 to +390
ofn = OPENFILENAME()
ofn.lStructSize = sizeof(OPENFILENAME)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ofn = OPENFILENAME()
ofn.lStructSize = sizeof(OPENFILENAME)
ofn = OPENFILENAMEW()
ofn.lStructSize = sizeof(OPENFILENAMEW)

@raverburg raverburg force-pushed the feature/collect_files_gui branch from ec8f8ab to 35b7016 Compare May 6, 2026 10:05
@Miauwkeru
Copy link
Copy Markdown
Contributor

I reordered some function definitions so its a bit more visually distinct what belongs together. This was some general cleanup that wasn't related to the PR, so I did it myself. I will now do some final checks!

@codecov
Copy link
Copy Markdown

codecov Bot commented May 6, 2026

Codecov Report

❌ Patch coverage is 2.67857% with 109 lines in your changes missing coverage. Please review.
✅ Project coverage is 43.74%. Comparing base (2956b06) to head (de024d7).

Files with missing lines Patch % Lines
acquire/gui/win32.py 0.00% 98 Missing ⚠️
acquire/acquire.py 0.00% 9 Missing ⚠️
acquire/gui/base.py 60.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #238      +/-   ##
==========================================
- Coverage   44.75%   43.74%   -1.01%     
==========================================
  Files          26       26              
  Lines        3546     3630      +84     
==========================================
+ Hits         1587     1588       +1     
- Misses       1959     2042      +83     
Flag Coverage Δ
unittests 43.74% <2.67%> (-1.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Miauwkeru Miauwkeru merged commit 4ace12e into fox-it:main May 6, 2026
19 of 23 checks passed
@raverburg
Copy link
Copy Markdown
Contributor Author

Great! Thank you for everything @Miauwkeru 😄

@Miauwkeru
Copy link
Copy Markdown
Contributor

no problem @raverburg :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add GUI support for selecting files to collect/upload

2 participants