diff --git a/.gitignore b/.gitignore index b7a283c..5bbe957 100755 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,4 @@ plugins_install/ peasoup_executable*/ -/programs/Makefile* \ No newline at end of file +/programs/Makefile* diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..cba3133 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "qtbase"] + path = qtbase + url = https://code.qt.io/qt/qtbase.git + branch = v6.9.0 \ No newline at end of file diff --git a/README.md b/README.md index 22502b0..0f94e30 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,13 @@ ## DLL methods - [x] `GetOpenFileNameA` +- [ ] `IFileOpenDialog` - [x] `QFileDialog::getOpenFileName` - [ ] `QFileDialog::getOpenFileNames` - [ ] `QFileDialog::getOpenFileUrl` - [ ] `QFileDialog::getOpenFileUrls` - [ ] `QFileDialog::getOpenFileContent` - [ ] `wxFileDialog` -- [ ] `IFileOpenDialog` ## Build scripts @@ -29,8 +29,8 @@ programs/build.bat drrun -c ..\..\clients\CustomClient\build\Debug\CustomClient.dll -c C:\Users\vboxuser\git\winafl\build64\bin\Release\winafl.dll -debug -target_offset 0x8530 -fuzz_iterations 1 -nargs 2 -target_module .\GetOpenFileNameA.exe -- .\GetOpenFileNameA.exe ``` -### `\QT_getOpenFileName.exe` +### `QT_getOpenFileName.exe` ```bash drrun -c ..\..\clients\CustomClient\build\Debug\CustomClient.dll -c C:\Users\vboxuser\git\winafl\build64\bin\Release\winafl.dll -debug -target_offset 0x1320 -fuzz_iterations 1 -nargs 2 -target_module .\QT_getOpenFileName.exe -- .\QT_getOpenFileName.exe -``` \ No newline at end of file +``` diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt new file mode 100644 index 0000000..ace1cce --- /dev/null +++ b/client/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.7) + +project(CustomClient) + +find_package(DynamoRIO REQUIRED) + +add_library(CustomClient SHARED "${CMAKE_CURRENT_SOURCE_DIR}/src/client.c") + +add_definitions(-DCC_QTLIB_DLL_PATH="${CMAKE_CURRENT_SOURCE_DIR}/lib/build/release/CC_QTLib.dll") + +target_include_directories(CustomClient PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/lib") +target_link_directories(CustomClient PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/lib/build/release") + +target_link_libraries(CustomClient drwrap drmgr CC_QTLib) + +configure_DynamoRIO_client(CustomClient) diff --git a/client/build.bat b/client/build.bat new file mode 100755 index 0000000..c493f5a --- /dev/null +++ b/client/build.bat @@ -0,0 +1,18 @@ +@echo off +setlocal +set "ERRLEVEL=" + +pushd "%~dp0" + +cd lib +if not exist "build" mkdir build +cd build +..\..\..\qtbase\bin\qmake.exe ..\CC_QTLib.pro +nmake + +popd + +if not exist "build" mkdir build +cd build +cmake -DDynamoRIO_DIR=C:\Users\vboxuser\DynamoRIO-Windows\cmake .. +cmake --build . diff --git a/client/lib/CC_QTLib.cpp b/client/lib/CC_QTLib.cpp new file mode 100644 index 0000000..474b783 --- /dev/null +++ b/client/lib/CC_QTLib.cpp @@ -0,0 +1,53 @@ +#include + +#include +#include +#include + +extern "C" Q_DECL_EXPORT void CC_QString_insert(QString **ptr, const char *str) { + *ptr = new QString(str); +} + +extern "C" Q_DECL_EXPORT QString *CC_QString_create(const char *str) { + return new QString(str); +} + +extern "C" Q_DECL_EXPORT void CC_QString_destroy(QString *str) { + delete str; +} + +extern "C" Q_DECL_EXPORT void CC_QUrl_insert(QUrl **ptr, const char *str) { + *ptr = new QUrl(str); +} + +extern "C" Q_DECL_EXPORT QUrl *CC_QUrl_create(const char *str) { + return new QUrl(str); +} + +extern "C" Q_DECL_EXPORT void CC_QUrl_destroy(QUrl *str) { + delete str; +} + +extern "C" Q_DECL_EXPORT QList *CC_QStringList_create() { + return new QList(); +} + +extern "C" Q_DECL_EXPORT void CC_QStringList_destroy(QList *lst) { + delete lst; +} + +extern "C" Q_DECL_EXPORT void CC_QStringList_append(QList *lst, QString *el) { + lst->append(*el); +} + +extern "C" Q_DECL_EXPORT QList *CC_QUrlList_create() { + return new QList(); +} + +extern "C" Q_DECL_EXPORT void CC_QUrlList_destroy(QList *lst) { + delete lst; +} + +extern "C" Q_DECL_EXPORT void CC_QUrlList_append(QList *lst, QUrl *el) { + lst->append(*el); +} diff --git a/client/lib/CC_QTLib.h b/client/lib/CC_QTLib.h new file mode 100644 index 0000000..0f8f8b1 --- /dev/null +++ b/client/lib/CC_QTLib.h @@ -0,0 +1,85 @@ +#pragma once + +void CC_QString_insert(void *ptr, const char *str); +void *CC_QString_create(const char *str); +void CC_QString_destroy(void *str); + +// QUrl +void CC_QUrl_insert(void *ptr, const char *str); +void *CC_QUrl_create(const char *str); +void CC_QUrl_destroy(void *str); + +// QStringList +void *CC_QStringList_create(); +void CC_QStringList_destroy(void *lst); +void CC_QStringList_append(void *lst, void *el); + +// QUrlList +void *CC_QUrlList_create(const char *str); +void CC_QUrlList_destroy(void *lst); +void CC_QUrlList_append(void *lst, void *el); + +/* +// QString +void (*CC_QString_insert)(void *ptr, const char *str); +void *(*CC_QString_create)(const char *str); +void (*CC_QString_destroy)(void *str); + +// QUrl +void (*CC_QUrl_insert)(void *ptr, const char *str); +void *(*CC_QUrl_create)(const char *str); +void (*CC_QUrl_destroy)(void *str); + +// QStringList +void *(*CC_QStringList_create)(); +void (*CC_QStringList_destroy)(void *lst); +void (*CC_QStringList_append)(void *lst, void *el); + +// QUrlList +void *(*CC_QUrlList_create)(const char *str); +void (*CC_QUrlList_destroy)(void *lst); +void (*CC_QUrlList_append)(void *lst, void *el); + +inline void CC_QTLib_load() { +#ifndef CC_QTLIB_DLL_PATH +#error "CC_QTLIB_DLL_PATH not defined" +#else + + HMODULE hDLL; + + // hDLL = LoadLibrary("C:\\Qt\\6.9.0\\msvc2022_64\\bin\\Qt6Core.dll"); + // if (!hDLL) { + // dr_printf("failed to load %s\n", "C:\\Qt\\6.9.0\\msvc2022_64\\bin\\Qt6Core.dll"); + // exit(1); + // } + + hDLL = LoadLibrary(CC_QTLIB_DLL_PATH); + if (!hDLL) { + dr_printf("failed to load %s\n", CC_QTLIB_DLL_PATH); + exit(1); + } + + #define CC_QTLIB_LOAD(name) name = GetProcAddress(hDLL, #name); + + CC_QTLIB_LOAD(CC_QString_insert); + CC_QTLIB_LOAD(CC_QString_create); + CC_QTLIB_LOAD(CC_QString_destroy); + + CC_QTLIB_LOAD(CC_QUrl_insert); + CC_QTLIB_LOAD(CC_QUrl_create); + CC_QTLIB_LOAD(CC_QUrl_destroy); + + CC_QTLIB_LOAD(CC_QStringList_create); + CC_QTLIB_LOAD(CC_QStringList_destroy); + CC_QTLIB_LOAD(CC_QStringList_append); + + CC_QTLIB_LOAD(CC_QUrlList_create); + CC_QTLIB_LOAD(CC_QUrlList_destroy); + CC_QTLIB_LOAD(CC_QUrlList_append); + + dr_printf("%s loaded!\n", CC_QTLIB_DLL_PATH); + +#endif + +} +*/ diff --git a/client/lib/CC_QTLib.pro b/client/lib/CC_QTLib.pro new file mode 100644 index 0000000..ca59a9c --- /dev/null +++ b/client/lib/CC_QTLib.pro @@ -0,0 +1,5 @@ +QT += core widgets +TEMPLATE = lib +TARGET = CC_QTLib +SOURCES += CC_QTLib.cpp +CONFIG += staticlib diff --git a/clients/CustomClient/client.c b/client/src/client.c similarity index 63% rename from clients/CustomClient/client.c rename to client/src/client.c index 5cff7f8..dc33abc 100644 --- a/clients/CustomClient/client.c +++ b/client/src/client.c @@ -4,17 +4,28 @@ #include "dr_ir_opcodes_x86.h" #include "dr_ir_macros_x86.h" +#include "CC_QTLib.h" + #include #include #include #include +#include char *CUSTOM_FILE = "C:\\Users\\vboxuser\\Downloads\\spoofed_number.txt"; static app_pc pc_GetOpenFileNameA = NULL; -static app_pc pc_QString_QString = NULL; +void (*QString_const)(void *, char *) = NULL; +void (*QArray_allocate)(void *, int64_t, int64_t, int64_t, int64_t) = NULL; +static app_pc pc_QUrl_const = NULL; +static app_pc pc_QList_const = NULL; + static app_pc pc_QFileDialog_getOpenFileName = NULL; +static app_pc pc_QFileDialog_getOpenFileNames = NULL; +static app_pc pc_QFileDialog_getOpenFileUrl = NULL; +static app_pc pc_QFileDialog_getOpenFileUrls = NULL; +static app_pc pc_QFileDialog_getOpenFileContent = NULL; static void intercept_GetOpenFileNameA() { void *drcontext = dr_get_current_drcontext(); @@ -35,15 +46,30 @@ static void intercept_GetOpenFileNameA() { static void intercept_QFileDialog_getOpenFileName() { void *drcontext = dr_get_current_drcontext(); + dr_printf("intercept_QFileDialog_getOpenFileName\n"); + + dr_mcontext_t mcontext = { sizeof(mcontext), DR_MC_ALL }; + dr_get_mcontext(drcontext, &mcontext); + + CC_QString_insert((void *)mcontext.rcx, CUSTOM_FILE); +} + +static void intercept_QFileDialog_getOpenFileNames() { + void *drcontext = dr_get_current_drcontext(); + dr_mcontext_t mcontext = { sizeof(mcontext), DR_MC_ALL }; dr_get_mcontext(drcontext, &mcontext); // make use of QString constructor to construct return value - void *QString = (void *)mcontext.rcx; - void(*QString_QString)(void *, char *) = (void(*)(void *, char *))pc_QString_QString; - QString_QString(QString, CUSTOM_FILE); + // void *QArray = (void *)mcontext.rcx; + + // char QString[24]; + // QString_const(QString, CUSTOM_FILE); + + // QArray_allocate(QArray, 0x18, 8, 1, 1); } + static void event_exit(void) { } @@ -55,12 +81,17 @@ static void event_module_load(void *drcontext, const module_data_t *mod, bool lo } if (strstr(lowerpath, "qt6core.dll")) { - pc_QString_QString = (app_pc)dr_get_proc_address(mod->handle, "??0QString@@QEAA@PEBD@Z"); - // if (pc_QString_QString) dr_printf("Found QString::QString at %p\n", pc_QString_QString); + QString_const = (app_pc)dr_get_proc_address(mod->handle, "??0QString@@QEAA@PEBD@Z"); + QArray_allocate = (app_pc)dr_get_proc_address(mod->handle, "?allocate@QArrayData@@SAPEAXPEAPEAU1@_J11W4AllocationOption@1@@Z"); + // pc_QStringList_const = (app_pc)dr_get_proc_address(mod->handle, "??0QString@@QEAA@PEBD@Z"); + // if (pc_QString_const) dr_printf("Found QString::QString at %p\n", pc_QString_const); } - if (strstr(lowerpath, "qt6widgets.dll")) { pc_QFileDialog_getOpenFileName = (app_pc)dr_get_proc_address(mod->handle, "?getOpenFileName@QFileDialog@@SA?AVQString@@PEAVQWidget@@AEBV2@11PEAV2@V?$QFlags@W4Option@QFileDialog@@@@@Z"); + pc_QFileDialog_getOpenFileNames = (app_pc)dr_get_proc_address(mod->handle, "?getOpenFileNames@QFileDialog@@SA?AV?$QList@VQString@@@@PEAVQWidget@@AEBVQString@@11PEAV4@V?$QFlags@W4Option@QFileDialog@@@@@Z"); + pc_QFileDialog_getOpenFileUrl = (app_pc)dr_get_proc_address(mod->handle, "?getOpenFileUrl@QFileDialog@@SA?AVQUrl@@PEAVQWidget@@AEBVQString@@AEBV2@1PEAV4@V?$QFlags@W4Option@QFileDialog@@@@AEBV?$QList@VQString@@@@@Z"); + pc_QFileDialog_getOpenFileUrls = (app_pc)dr_get_proc_address(mod->handle, "?getOpenFileUrls@QFileDialog@@SA?AV?$QList@VQUrl@@@@PEAVQWidget@@AEBVQString@@AEBVQUrl@@1PEAV4@V?$QFlags@W4Option@QFileDialog@@@@AEBV?$QList@VQString@@@@@Z"); + pc_QFileDialog_getOpenFileContent = (app_pc)dr_get_proc_address(mod->handle, "?getOpenFileContent@QFileDialog@@SAXAEBVQString@@AEBV?$function@$$A6AXAEBVQString@@AEBVQByteArray@@@Z@std@@PEAVQWidget@@@Z"); // if (pc_QFileDialog_getOpenFileName) dr_printf("Found QFileDialog::getOpenFileName at %p\n", pc_QFileDialog_getOpenFileName); } @@ -108,7 +139,7 @@ static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t instr = next; } - + return DR_EMIT_DEFAULT; } @@ -117,5 +148,6 @@ DR_EXPORT void dr_client_main(client_id_t id, int argc, const char *argv[]) { dr_register_exit_event(event_exit); dr_register_module_load_event(event_module_load); dr_register_bb_event(event_basic_block); -} + // CC_QTLib_load(); +} diff --git a/clients/CustomClient/CMakeLists.txt b/clients/CustomClient/CMakeLists.txt deleted file mode 100644 index e76191a..0000000 --- a/clients/CustomClient/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -cmake_minimum_required(VERSION 3.7) -project(CustomClient) - -find_package(DynamoRIO REQUIRED) -add_library(CustomClient SHARED client.c) -target_link_libraries(CustomClient drwrap drmgr) -configure_DynamoRIO_client(CustomClient) diff --git a/clients/build_all.ps1 b/clients/build_all.ps1 deleted file mode 100755 index e8cc20b..0000000 --- a/clients/build_all.ps1 +++ /dev/null @@ -1,17 +0,0 @@ -$CWD = (pwd).Path - -$DIR = $PSScriptRoot -cd $DIR - -Get-ChildItem -Directory | % { - $clientDir = "$DIR\$_" - $buildDir = "$DIR\$_\build" - - $$ = New-Item -ItemType Directory -Force $buildDir - cd $buildDir - - cmake -DDynamoRIO_DIR=C:\Users\vboxuser\DynamoRIO-Windows\cmake .. - cmake --build . -} - -cd $CWD diff --git a/programs/build.bat b/programs/build.bat index 55db7db..ac1802c 100644 --- a/programs/build.bat +++ b/programs/build.bat @@ -2,5 +2,22 @@ cl /Fe:compiled\Foo.exe source\Foo.c /Zi /Od /link /MACHINE:X64 cl /Fe:compiled\GetOpenFileNameA.exe comdlg32.lib source\GetOpenFileNameA.c /Zi /Od /link /MACHINE:X64 +cl /Fe:compiled\IFileDialog.exe uuid.lib ole32.lib source\IFileDialog.c /Zi /Od /link /MACHINE:X64 + +qmake source\QT_getOpenFileContent.pro +nmake + qmake source\QT_getOpenFileName.pro nmake + +qmake source\QT_getOpenFileNames.pro +nmake + +qmake source\QT_getOpenFileUrl.pro +nmake + +qmake source\QT_getOpenFileUrls.pro +nmake + +qmake source\QT_TestLib.pro +nmake -f Makefile.Debug diff --git a/programs/compiled/Foo.exe b/programs/compiled/Foo.exe index 87b4950..84dc300 100644 Binary files a/programs/compiled/Foo.exe and b/programs/compiled/Foo.exe differ diff --git a/programs/compiled/GetOpenFileNameA.exe b/programs/compiled/GetOpenFileNameA.exe index 8201c8d..a2eadc4 100644 Binary files a/programs/compiled/GetOpenFileNameA.exe and b/programs/compiled/GetOpenFileNameA.exe differ diff --git a/programs/compiled/IFileDialog.exe b/programs/compiled/IFileDialog.exe new file mode 100644 index 0000000..62e52c7 Binary files /dev/null and b/programs/compiled/IFileDialog.exe differ diff --git a/programs/compiled/QT_TestLib.exe b/programs/compiled/QT_TestLib.exe new file mode 100644 index 0000000..49d8c06 Binary files /dev/null and b/programs/compiled/QT_TestLib.exe differ diff --git a/programs/compiled/QT_getOpenFileContent.exe b/programs/compiled/QT_getOpenFileContent.exe new file mode 100644 index 0000000..1fda529 Binary files /dev/null and b/programs/compiled/QT_getOpenFileContent.exe differ diff --git a/programs/compiled/QT_getOpenFileName.exe b/programs/compiled/QT_getOpenFileName.exe index c352bcd..870758f 100644 Binary files a/programs/compiled/QT_getOpenFileName.exe and b/programs/compiled/QT_getOpenFileName.exe differ diff --git a/programs/compiled/QT_getOpenFileNames.exe b/programs/compiled/QT_getOpenFileNames.exe new file mode 100644 index 0000000..6e8b15c Binary files /dev/null and b/programs/compiled/QT_getOpenFileNames.exe differ diff --git a/programs/compiled/QT_getOpenFileUrl.exe b/programs/compiled/QT_getOpenFileUrl.exe new file mode 100644 index 0000000..8659993 Binary files /dev/null and b/programs/compiled/QT_getOpenFileUrl.exe differ diff --git a/programs/compiled/QT_getOpenFileUrls.exe b/programs/compiled/QT_getOpenFileUrls.exe new file mode 100644 index 0000000..cd46915 Binary files /dev/null and b/programs/compiled/QT_getOpenFileUrls.exe differ diff --git a/programs/source/IFileDialog.c b/programs/source/IFileDialog.c new file mode 100644 index 0000000..079ffb0 --- /dev/null +++ b/programs/source/IFileDialog.c @@ -0,0 +1,81 @@ +#include +#include // Required for IFileDialog and related interfaces +#include +#include + +int main() { + HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + if (FAILED(hr)) { + fprintf(stderr, "CoInitializeEx failed: 0x%lx\n", hr); + exit(1); + } + + char file[MAX_PATH] = {0}; + IFileOpenDialog *pFileOpen = NULL; + IShellItem *pItem = NULL; + PWSTR pszFilePath = NULL; + + hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_ALL, + &IID_IFileOpenDialog, (void**)&pFileOpen); + + if (SUCCEEDED(hr)) { + COMDLG_FILTERSPEC rgSpec[] = {{L"All Files", L"*.*"}}; + pFileOpen->lpVtbl->SetFileTypes(pFileOpen, ARRAYSIZE(rgSpec), rgSpec); + + pFileOpen->lpVtbl->SetTitle(pFileOpen, L"Select File"); + + DWORD dwFlags; + pFileOpen->lpVtbl->GetOptions(pFileOpen, &dwFlags); + pFileOpen->lpVtbl->SetOptions(pFileOpen, dwFlags | FOS_FILEMUSTEXIST | FOS_PATHMUSTEXIST); + + hr = pFileOpen->lpVtbl->Show(pFileOpen, NULL); + + if (SUCCEEDED(hr)) { + hr = pFileOpen->lpVtbl->GetResult(pFileOpen, &pItem); + + if (SUCCEEDED(hr)) { + hr = pItem->lpVtbl->GetDisplayName(pItem, SIGDN_FILESYSPATH, &pszFilePath); + + if (SUCCEEDED(hr)) { + wcstombs(file, pszFilePath, MAX_PATH); + } + } + } + } + + // Clean up COM objects and memory. + if (pszFilePath) { + CoTaskMemFree(pszFilePath); + } + if (pItem) { + pItem->lpVtbl->Release(pItem); + } + if (pFileOpen) { + pFileOpen->lpVtbl->Release(pFileOpen); + } + CoUninitialize(); + + // Check if a file was successfully selected. + if (FAILED(hr) || file[0] == '\0') { + puts("File selection cancelled or failed."); + exit(1); + } + + FILE *f = fopen(file, "r"); + if (!f) { + perror("fopen(...)"); + exit(1); + } + + long input; + if (fscanf(f, "%ld", &input) != 1) { + puts("fscanf(...) failed to scan input number"); + fclose(f); + exit(1); + } + + printf("%ld\n", 2 * input); + + fclose(f); + return 0; +} \ No newline at end of file diff --git a/programs/source/QT_TestLib.cpp b/programs/source/QT_TestLib.cpp new file mode 100644 index 0000000..b3f6280 --- /dev/null +++ b/programs/source/QT_TestLib.cpp @@ -0,0 +1,35 @@ +#include +#include +#include +#include + +void test_QList_QUrl0() { + QUrl fooUrl("asdf"); + QList fooList({fooUrl}); +} + +void test_QList_QUrl1() { + QUrl fooUrl("asdf"); + QList fooList; + fooList.append(fooUrl); +} + +void test_QStringList0() { + QString fooStr("Foo"); + QStringList fooList(fooStr); +} + +void test_QStringList1() { + QString fooStr("Foo"); + QStringList fooList({fooStr}); +} + +void test_QStringList2() { + QString fooStr("Foo"); + QStringList fooList; + fooList.append(fooStr); +} + +int main() { + return 0; +} diff --git a/programs/source/QT_TestLib.pro b/programs/source/QT_TestLib.pro new file mode 100644 index 0000000..2985432 --- /dev/null +++ b/programs/source/QT_TestLib.pro @@ -0,0 +1,5 @@ +QT += core widgets +CONFIG += console +SOURCES += QT_TestLib.cpp +TARGET = QT_TestLib +DESTDIR = compiled diff --git a/programs/source/QT_getOpenFileContent.cpp b/programs/source/QT_getOpenFileContent.cpp new file mode 100644 index 0000000..ccdb171 --- /dev/null +++ b/programs/source/QT_getOpenFileContent.cpp @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include // Still needed for parsing the content +#include +#include + +int main(int argc, char *argv[]) { + QApplication app(argc, argv); + + QSemaphore sem(1); + sem.acquire(); + + int returnCode = -1; + + auto fileContentReady = [&returnCode, &sem](const QString &fileName, const QByteArray &fileContent) { + if (fileName.isEmpty() || !QFile(fileName).exists()) { + std::cerr << "Failed to open file" << std::endl; + returnCode = 1; + sem.release(); + return; + } + + QString contentStr(fileContent); + QTextStream in(&contentStr); + QString line = in.readLine(); + + bool ok; + int number = line.toInt(&ok); + if (!ok) { + std::cerr << "Failed to read integer from file content" << std::endl; + returnCode = 1; + sem.release(); + return; + } + + std::cout << number * 2 << std::endl; + returnCode = 0; + sem.release(); + }; + + QFileDialog::getOpenFileContent("All Files (*.*)", fileContentReady); + + QThread *thread = QThread::create([&sem, &returnCode] () { + sem.acquire(); + if (returnCode == -1) { + std::cerr << "Failed to open file dialog" << std::endl; + return 1; + } + + return returnCode; + }); + thread->start(); + + // TODO: currently does not work +} \ No newline at end of file diff --git a/programs/source/QT_getOpenFileContent.pro b/programs/source/QT_getOpenFileContent.pro new file mode 100644 index 0000000..583684b --- /dev/null +++ b/programs/source/QT_getOpenFileContent.pro @@ -0,0 +1,5 @@ +QT += core widgets +CONFIG += console +SOURCES += QT_getOpenFileContent.cpp +TARGET = QT_getOpenFileContent +DESTDIR = compiled diff --git a/programs/source/QT_getOpenFileName.cpp b/programs/source/QT_getOpenFileName.cpp index a150652..ac3ac03 100644 --- a/programs/source/QT_getOpenFileName.cpp +++ b/programs/source/QT_getOpenFileName.cpp @@ -9,10 +9,10 @@ int main(int argc, char *argv[]) { QApplication app(argc, argv); QString fileName = QFileDialog::getOpenFileName(nullptr, "Select File", "", "All Files (*.*)"); - if (fileName.isEmpty()) return 0; + if (fileName.isEmpty()) return 1; QFile file(fileName); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + if (!file.exists() || !file.open(QIODevice::ReadOnly | QIODevice::Text)) { std::cerr << "Failed to open file" << std::endl; return 1; } diff --git a/programs/source/QT_getOpenFileNames.cpp b/programs/source/QT_getOpenFileNames.cpp new file mode 100644 index 0000000..e022bb4 --- /dev/null +++ b/programs/source/QT_getOpenFileNames.cpp @@ -0,0 +1,32 @@ +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + QApplication app(argc, argv); + + QStringList fileNames = QFileDialog::getOpenFileNames(nullptr, "Select File", "", "All Files (*.*)"); + if (fileNames.isEmpty()) return 1; + + QFile file(fileNames.first()); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + std::cerr << "Failed to open file" << std::endl; + return 1; + } + + QTextStream in(&file); + QString line = in.readLine(); + bool ok; + int number = line.toInt(&ok); + + if (!ok) { + std::cerr << "Failed to read integer from file" << std::endl; + return 1; + } + + std::cout << number * 2 << std::endl; + return 0; +} diff --git a/programs/source/QT_getOpenFileNames.pro b/programs/source/QT_getOpenFileNames.pro new file mode 100644 index 0000000..4e96cf4 --- /dev/null +++ b/programs/source/QT_getOpenFileNames.pro @@ -0,0 +1,5 @@ +QT += core widgets +CONFIG += console +SOURCES += QT_getOpenFileNames.cpp +TARGET = QT_getOpenFileNames +DESTDIR = compiled \ No newline at end of file diff --git a/programs/source/QT_getOpenFileUrl.cpp b/programs/source/QT_getOpenFileUrl.cpp new file mode 100644 index 0000000..d9a7825 --- /dev/null +++ b/programs/source/QT_getOpenFileUrl.cpp @@ -0,0 +1,32 @@ +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + QApplication app(argc, argv); + + QUrl url = QFileDialog::getOpenFileUrl(nullptr, "Select File", QUrl(), "All Files (*.*)"); + if (!url.isValid() || !url.isLocalFile()) return 1; + + QFile file(url.toLocalFile()); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + std::cerr << "Failed to open file" << std::endl; + return 1; + } + + QTextStream in(&file); + QString line = in.readLine(); + bool ok; + int number = line.toInt(&ok); + + if (!ok) { + std::cerr << "Failed to read integer from file" << std::endl; + return 1; + } + + std::cout << number * 2 << std::endl; + return 0; +} diff --git a/programs/source/QT_getOpenFileUrl.pro b/programs/source/QT_getOpenFileUrl.pro new file mode 100644 index 0000000..4a9796b --- /dev/null +++ b/programs/source/QT_getOpenFileUrl.pro @@ -0,0 +1,5 @@ +QT += core widgets +CONFIG += console +SOURCES += QT_getOpenFileUrl.cpp +TARGET = QT_getOpenFileUrl +DESTDIR = compiled diff --git a/programs/source/QT_getOpenFileUrls.cpp b/programs/source/QT_getOpenFileUrls.cpp new file mode 100644 index 0000000..6d7cb6f --- /dev/null +++ b/programs/source/QT_getOpenFileUrls.cpp @@ -0,0 +1,35 @@ +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + QApplication app(argc, argv); + + QList urls = QFileDialog::getOpenFileUrls(nullptr, "Select File", QUrl(), "All Files (*.*)"); + if (urls.empty()) return 1; + + QUrl url = urls.first(); + if (!url.isValid() || !url.isLocalFile()) return 1; + + QFile file(url.toLocalFile()); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + std::cerr << "Failed to open file" << std::endl; + return 1; + } + + QTextStream in(&file); + QString line = in.readLine(); + bool ok; + int number = line.toInt(&ok); + + if (!ok) { + std::cerr << "Failed to read integer from file" << std::endl; + return 1; + } + + std::cout << number * 2 << std::endl; + return 0; +} diff --git a/programs/source/QT_getOpenFileUrls.pro b/programs/source/QT_getOpenFileUrls.pro new file mode 100644 index 0000000..85020f7 --- /dev/null +++ b/programs/source/QT_getOpenFileUrls.pro @@ -0,0 +1,5 @@ +QT += core widgets +CONFIG += console +SOURCES += QT_getOpenFileUrls.cpp +TARGET = QT_getOpenFileUrls +DESTDIR = compiled diff --git a/qtbase b/qtbase new file mode 160000 index 0000000..2598674 --- /dev/null +++ b/qtbase @@ -0,0 +1 @@ +Subproject commit 25986746947798e1a22d0830d3bcb11a55fcd3ae diff --git a/setup.bat b/setup.bat new file mode 100644 index 0000000..4f0b687 --- /dev/null +++ b/setup.bat @@ -0,0 +1,64 @@ +@echo off + +if not exist "qtbase" git submodule update --init + +cd qtbase +.\configure.bat ^ + -platform win32-msvc ^ + -prefix .\build ^ + -opensource ^ + -static ^ + -release ^ + -confirm-license ^ + -no-openssl ^ + -no-ssl ^ + -no-opengl ^ + -skip qtcharts ^ + -skip qtwebengine ^ + -skip qtconnectivity ^ + -skip qttools ^ + -skip qtlottie ^ + -skip qtimageformats ^ + -skip qtdeclarative ^ + -skip qtsvg ^ + -skip qtwayland ^ + -nomake examples ^ + -nomake tests ^ + -optimize-size ^ + -skip qdoc ^ + -skip qtactiveqt ^ + -skip qtcharts ^ + -skip qtcoap ^ + -skip qtdatavis3d ^ + -skip qtfeedback ^ + -skip qtgamepad ^ + -skip qtgraphicaleffects ^ + -skip qtgrpc ^ + -skip qthttpserver ^ + -skip qtlocation ^ + -skip qtlottie ^ + -skip qtmultimedia ^ + -skip qtnetworkauth ^ + -skip qtpim ^ + -skip qtpositioning ^ + -skip qtquick3d ^ + -skip qtremoteobjects ^ + -skip qtscxml ^ + -skip qtsensors ^ + -skip qtserialbus ^ + -skip qtserialport ^ + -skip qtspeech ^ + -skip qtsvg ^ + -skip qttools ^ + -skip qttranslations ^ + -skip qtvirtualkeyboard ^ + -skip qtwebchannel ^ + -skip qtwebengine ^ + -skip qtwebsockets ^ + -skip qtwebview ^ + -skip qtx11extras ^ + -skip qtxmlpatterns +#.\configure.bat -release -platform win32-msvc -prefix .\build -opensource -confirm-license -nomake tests -nomake examples + +cmake --build . --parallel +cmake --install .