// grepWin - regex search and replace for Windows // Copyright (C) 2007-2008, 2010-2022 - Stefan Kueng // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software Foundation, // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // #include "stdafx.h" #include "strsafe.h" #include "resource.h" #include "SearchDlg.h" #include "AboutDlg.h" #include "CmdLineParser.h" #include "Registry.h" #include "Language.h" #include "StringUtils.h" #include "PathUtils.h" #pragma warning(push) #pragma warning(disable : 4458) // declaration of 'xxx' hides class member #include #include "WinUser.h" #pragma warning(pop) // Global Variables: HINSTANCE g_hInst; // current instance HICON g_hDlgIcon128; bool bPortable = false; CSimpleIni g_iniFile; std::wstring g_iniPath; HANDLE hInitProtection = nullptr; ULONGLONG g_startTime = GetTickCount64(); UINT GREPWIN_STARTUPMSG = RegisterWindowMessage(L"grepWinNP3_StartupMessage"); static std::wstring SanitizeSearchPaths(const std::wstring& searchpath) { std::vector container; stringtok(container, searchpath, true); std::wstring sResult; for (auto path : container) { if (!sResult.empty()) sResult += L"|"; size_t endPos = path.find_last_not_of(L" \"\t"); if (std::wstring::npos != endPos) { path = path.substr(0, endPos + 1); } size_t startPos = path.find_first_not_of(L" \"\t"); if ((startPos > 0) && (std::wstring::npos != startPos)) { path = path.substr(startPos); } sResult += CPathUtils::GetLongPathname(path); } return sResult; } static void RegisterContextMenu(bool bAdd) { if (bAdd) { std::wstring sIconPath = CStringUtils::Format(L"%s,-%d", CPathUtils::GetLongPathname(CPathUtils::GetModulePath()).c_str(), IDI_GREPWIN); std::wstring sExePath = CStringUtils::Format(L"%s /searchpath:\"%%1\"", CPathUtils::GetLongPathname(CPathUtils::GetModulePath()).c_str()); SHSetValue(HKEY_CURRENT_USER, L"Software\\Classes\\Directory\\shell\\grepWinNP3", nullptr, REG_SZ, L"Search with grepWinNP3\0", sizeof(L"Search with grepWinNP3\0")); SHSetValue(HKEY_CURRENT_USER, L"Software\\Classes\\Directory\\shell\\grepWinNP3", L"Icon", REG_SZ, sIconPath.c_str(), static_cast((sIconPath.size() + 1) * sizeof(WCHAR))); SHSetValue(HKEY_CURRENT_USER, L"Software\\Classes\\Directory\\shell\\grepWinNP3\\Command", nullptr, REG_SZ, sExePath.c_str(), static_cast((sExePath.size() + 1) * sizeof(WCHAR))); SHSetValue(HKEY_CURRENT_USER, L"Software\\Classes\\Directory\\Background\\shell\\grepWinNP3", nullptr, REG_SZ, L"Search with grepWinNP3", sizeof(L"Search with grepWinNP3") + 2); SHSetValue(HKEY_CURRENT_USER, L"Software\\Classes\\Directory\\Background\\shell\\grepWinNP3", L"Icon", REG_SZ, sIconPath.c_str(), static_cast((sIconPath.size() + 1) * sizeof(WCHAR))); SHSetValue(HKEY_CURRENT_USER, L"Software\\Classes\\Folder\\shell\\grepWinNP3", nullptr, REG_SZ, L"Search with grepWinNP3", sizeof(L"Search with grepWinNP3") + 2); SHSetValue(HKEY_CURRENT_USER, L"Software\\Classes\\Folder\\shell\\grepWinNP3", L"Icon", REG_SZ, sIconPath.c_str(), static_cast((sIconPath.size() + 1) * sizeof(WCHAR))); SHSetValue(HKEY_CURRENT_USER, L"Software\\Classes\\Folder\\shell\\grepWinNP3\\Command", nullptr, REG_SZ, sExePath.c_str(), static_cast((sExePath.size() + 1) * sizeof(WCHAR))); SHSetValue(HKEY_CURRENT_USER, L"Software\\Classes\\Drive\\shell\\grepWinNP3", nullptr, REG_SZ, L"Search with grepWinNP3", sizeof(L"Search with grepWinNP3") + 2); SHSetValue(HKEY_CURRENT_USER, L"Software\\Classes\\Drive\\shell\\grepWinNP3", L"Icon", REG_SZ, sIconPath.c_str(), static_cast((sIconPath.size() + 1) * sizeof(WCHAR))); SHSetValue(HKEY_CURRENT_USER, L"Software\\Classes\\Drive\\shell\\grepWinNP3\\Command", nullptr, REG_SZ, sExePath.c_str(), static_cast((sExePath.size() + 1) * sizeof(WCHAR))); SHSetValue(HKEY_CURRENT_USER, L"Software\\Classes\\*\\shell\\grepWinNP3", nullptr, REG_SZ, L"Search with grepWinNP3", sizeof(L"Search with grepWinNP3") + 2); SHSetValue(HKEY_CURRENT_USER, L"Software\\Classes\\*\\shell\\grepWinNP3", L"Icon", REG_SZ, sIconPath.c_str(), static_cast((sIconPath.size() + 1) * sizeof(WCHAR))); SHSetValue(HKEY_CURRENT_USER, L"Software\\Classes\\*\\shell\\grepWinNP3\\Command", nullptr, REG_SZ, sExePath.c_str(), static_cast((sExePath.size() + 1) * sizeof(WCHAR))); SHSetValue(HKEY_CURRENT_USER, L"Software\\Classes\\*\\shell\\grepWinNP3", L"MultiSelectModel", REG_SZ, L"Player\0", sizeof(L"Player\0")); sExePath = CStringUtils::Format(L"%s /searchpath:\"%%V\"", CPathUtils::GetLongPathname(CPathUtils::GetModulePath()).c_str()); SHSetValue(HKEY_CURRENT_USER, L"Software\\Classes\\Directory\\Background\\shell\\grepWinNP3\\Command", nullptr, REG_SZ, sExePath.c_str(), static_cast((sExePath.size() + 1) * sizeof(WCHAR))); } else { SHDeleteKey(HKEY_CURRENT_USER, L"Software\\Classes\\Directory\\shell\\grepWinNP3"); SHDeleteKey(HKEY_CURRENT_USER, L"Software\\Classes\\Directory\\Background\\shell\\grepWinNP3"); SHDeleteKey(HKEY_CURRENT_USER, L"Software\\Classes\\Folder\\shell\\grepWinNP3"); SHDeleteKey(HKEY_CURRENT_USER, L"Software\\Classes\\Drive\\shell\\grepWinNP3"); SHDeleteKey(HKEY_CURRENT_USER, L"Software\\Classes\\*\\shell\\grepWinNP3"); } } BOOL CALLBACK windowEnumerator(__in HWND hwnd, __in LPARAM lParam) { HWND* pWnd = reinterpret_cast(lParam); WCHAR buf[MAX_PATH] = {0}; GetWindowText(hwnd, buf, _countof(buf)); if (_wcsnicmp(buf, L"grepwinnp3 :", 12) == 0) { *pWnd = hwnd; if (SendMessage(hwnd, GREPWIN_STARTUPMSG, 1, 0)) { // grepWin instance started moments ago, so use this one return FALSE; } } return TRUE; } int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); UNREFERENCED_PARAMETER(nCmdShow); // uncomment the following lines for low-memory tests. // note: process needs to run elevated for this to work. // //auto job = CreateJobObject(NULL, NULL); //JOBOBJECT_EXTENDED_LIMIT_INFORMATION joblimit = { 0 }; //joblimit.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_WORKINGSET; //joblimit.JobMemoryLimit = 30 * 1024 * 1024; //joblimit.ProcessMemoryLimit = 30 * 1024 * 1024; //joblimit.PeakProcessMemoryUsed = 30 * 1024 * 1024; //joblimit.BasicLimitInformation.MaximumWorkingSetSize = 30 * 1024 * 1024; //joblimit.BasicLimitInformation.MinimumWorkingSetSize = 30 * 1024; //SetInformationJobObject(job, JobObjectExtendedLimitInformation, &joblimit, sizeof(joblimit)); //AssignProcessToJobObject(job, GetCurrentProcess()); SetDllDirectory(L""); // if multiple items are selected in explorer and grepWin is started for all of them, // explorer starts multiple grepWin instances at once. In case there's already a grepWin instance // running, sleep for a while to give that instance time to fully initialize HANDLE hReloadProtection = ::CreateMutex(nullptr, FALSE, L"{6473AA76-0EAE-4C96-8C99-AFDFEFFE42B5}"); bool alreadyRunning = false; if ((!hReloadProtection) || (GetLastError() == ERROR_ALREADY_EXISTS)) { // An instance of grepWin is already running alreadyRunning = true; } hInitProtection = ::CreateMutex(nullptr, FALSE, L"{6473AA76-0EAE-4C96-8C99-AFDFEFFE42B6}"); bool initInProgress = false; if ((!hInitProtection) || (GetLastError() == ERROR_ALREADY_EXISTS)) { // An instance of grepWin is initializing initInProgress = true; } g_hInst = hInstance; ::OleInitialize(nullptr); ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); // we need some of the common controls INITCOMMONCONTROLSEX icEx; icEx.dwSize = sizeof(INITCOMMONCONTROLSEX); icEx.dwICC = ICC_LINK_CLASS | ICC_LISTVIEW_CLASSES | ICC_PAGESCROLLER_CLASS | ICC_PROGRESS_CLASS | ICC_STANDARD_CLASSES | ICC_TAB_CLASSES | ICC_TREEVIEW_CLASSES | ICC_UPDOWN_CLASS | ICC_USEREX_CLASSES | ICC_WIN95_CLASSES; InitCommonControlsEx(&icEx); g_hDlgIcon128 = NULL; LoadIconWithScaleDown(hInstance, MAKEINTRESOURCE(IDI_GREPWIN), 128, 128, &g_hDlgIcon128); HMODULE hRichEdt = LoadLibrary(L"Riched20.dll"); CCmdLineParser parser(lpCmdLine); //MessageBox(NULL, L"", L"", MB_OK); if (parser.HasKey(L"register")) { RegisterContextMenu(true); return FALSE; } if ((parser.HasKey(L"unregister")) || (parser.HasKey(L"deregister"))) { RegisterContextMenu(false); return FALSE; } bool bQuit = false; HWND hWnd = nullptr; int timeout = 20; // find already running grepWin windows if (alreadyRunning && !parser.HasKey(L"new")) { do { if (EnumWindows(windowEnumerator, reinterpret_cast(&hWnd)) != FALSE) { // long running grepWin Window found: // if a grepWin process is currently initializing, // wait a while and enumerate again while (initInProgress) { CloseHandle(hInitProtection); Sleep(100); initInProgress = false; hInitProtection = ::CreateMutex(nullptr, FALSE, L"{6473AA76-0EAE-4C96-8C99-AFDFEFFE42B6}"); if ((!hInitProtection) || (GetLastError() == ERROR_ALREADY_EXISTS)) { // An instance of grepWin is still initializing initInProgress = true; } } hWnd = nullptr; EnumWindows(windowEnumerator, reinterpret_cast(&hWnd)); } if (alreadyRunning && (hWnd == nullptr)) Sleep(100); timeout--; } while ((hWnd == nullptr) && alreadyRunning && timeout); } auto moduleName = CPathUtils::GetFileName(CPathUtils::GetModulePath(nullptr)); bPortable = ((wcsstr(moduleName.c_str(), L"portable")) || (parser.HasKey(L"portable")) || (wcsstr(moduleName.c_str(), L"NP3"))); g_iniPath = CPathUtils::GetModuleDir(nullptr); g_iniPath += L"\\grepwinNP3.ini"; if (parser.HasVal(L"inipath")) { g_iniPath = parser.GetVal(L"inipath"); bPortable = true; } if (bPortable) { if (PathIsRelative(g_iniPath.c_str())) { WCHAR absPath[MAX_PATH] = {L'\0'}; StringCchCopy(absPath, MAX_PATH, CPathUtils::GetModuleDir(nullptr).c_str()); PathAppend(absPath, g_iniPath.c_str()); g_iniPath = absPath; } g_iniFile.SetUnicode(); g_iniFile.SetMultiLine(); g_iniFile.SetSpaces(false); g_iniFile.LoadFile(g_iniPath.c_str()); } if (hWnd) { bool bOnlyOne = bPortable ? g_iniFile.GetBoolValue(L"global", L"onlyone", L"false") : !!DWORD(CRegStdDWORD(L"Software\\grepWinNP3\\onlyone", 0)); bool bCopyData = false; if (SendMessage(hWnd, GREPWIN_STARTUPMSG, 1, 0)) // check if grepWin was started moments ago { SendMessage(hWnd, GREPWIN_STARTUPMSG, 0, 0); // reset the timer bCopyData = true; bQuit = true; } else if (bOnlyOne) { bCopyData = true; bQuit = true; } if (bCopyData) { // grepWin was started just moments ago: // add the new path to the existing search path in that grepWin instance std::wstring searchfor = parser.HasVal(L"searchfor") ? parser.GetVal(L"searchfor") : (bPortable ? g_iniFile.GetValue(L"global", L"searchfor", L"") : L""); std::wstring sPath = parser.HasVal(L"searchpath") ? parser.GetVal(L"searchpath") : (bPortable ? g_iniFile.GetValue(L"global", L"searchpath", L"") : L""); SearchReplace(sPath, L"/", L"\\"); sPath = SanitizeSearchPaths(sPath); CopyData_t data2copy = {0}; StringCchCopyW(data2copy.searchFor, _countof(data2copy.searchFor), searchfor.c_str()); StringCchCopyW(data2copy.searchPath, _countof(data2copy.searchPath), sPath.c_str()); COPYDATASTRUCT copyData = {0}; copyData.lpData = static_cast(const_cast(sPath.c_str())); copyData.cbData = static_cast(sPath.size()) * sizeof(wchar_t); SendMessage(hWnd, WM_COPYDATA, 0, reinterpret_cast(©Data)); SetForegroundWindow(hWnd); //set the window to front bQuit = true; } else if (bOnlyOne) { std::wstring sPath = parser.HasVal(L"searchpath") ? parser.GetVal(L"searchpath") : L""; SearchReplace(sPath, L"/", L"\\"); sPath = SanitizeSearchPaths(sPath); COPYDATASTRUCT copyData = {0}; copyData.lpData = static_cast(const_cast(sPath.c_str())); copyData.cbData = static_cast(sPath.size()) * sizeof(wchar_t); SendMessage(hWnd, WM_COPYDATA, 1, reinterpret_cast(©Data)); SetForegroundWindow(hWnd); // set the window to front bQuit = true; } } int ret = 0; if (!bQuit) { Gdiplus::GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; // Initialize GDI+. Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr); if (bPortable) { std::wstring languagefile = g_iniFile.GetValue(L"global", L"languagefile", L""); if (PathIsRelative(languagefile.c_str())) { TCHAR wchAppPath[MAX_PATH] = {L'\0'}; GetModuleFileName(nullptr, wchAppPath, MAX_PATH); PathRemoveFileSpec(wchAppPath); PathAppend(wchAppPath, languagefile.c_str()); TCHAR wchLngPath[MAX_PATH] = {L'\0'}; PathCanonicalize(wchLngPath, wchAppPath); CLanguage::Instance().LoadFile(wchLngPath); } else CLanguage::Instance().LoadFile(languagefile); } else CLanguage::Instance().LoadFile(std::wstring(CRegStdString(L"Software\\grepWinNP3\\languagefile"))); if (parser.HasKey(L"about")||parser.HasKey(L"?")||parser.HasKey(L"help")) { if (hInitProtection) CloseHandle(hInitProtection); CAboutDlg aboutDlg(nullptr); ret = static_cast(aboutDlg.DoModal(hInstance, IDD_ABOUT, nullptr, NULL)); } else { CSearchDlg searchDlg(nullptr); if (parser.HasVal(L"searchini")) { std::wstring iniPath = parser.GetVal(L"searchini"); CSimpleIni searchIni; searchIni.SetUnicode(true); searchIni.LoadFile(iniPath.c_str()); std::wstring section; if (parser.HasVal(L"name")) section = parser.GetVal(L"name"); if (searchIni.GetValue(section.c_str(), L"searchpath")) { std::wstring sPath = searchIni.GetValue(section.c_str(), L"searchpath"); sPath = SanitizeSearchPaths(sPath); searchDlg.SetSearchPath(sPath); } if (searchIni.GetValue(section.c_str(), L"searchfor")) searchDlg.SetSearchString(searchIni.GetValue(section.c_str(), L"searchfor")); if (searchIni.GetValue(section.c_str(), L"filemaskregex")) searchDlg.SetFileMask(searchIni.GetValue(section.c_str(), L"filemaskregex"), true); if (searchIni.GetValue(section.c_str(), L"filemask")) searchDlg.SetFileMask(searchIni.GetValue(section.c_str(), L"filemask"), false); if (searchIni.GetValue(section.c_str(), L"direxcluderegex")) searchDlg.SetDirExcludeRegexMask(searchIni.GetValue(section.c_str(), L"direxcluderegex")); else if (searchIni.GetValue(section.c_str(), L"filemaskexclude")) searchDlg.SetDirExcludeRegexMask(searchIni.GetValue(section.c_str(), L"filemaskexclude")); if (searchIni.GetValue(section.c_str(), L"replacewith")) searchDlg.SetReplaceWith(searchIni.GetValue(section.c_str(), L"replacewith")); if (searchIni.GetValue(section.c_str(), L"preset")) searchDlg.SetPreset(searchIni.GetValue(section.c_str(), L"preset")); if (searchIni.GetValue(section.c_str(), L"i")) searchDlg.SetCaseSensitive(_wcsicmp(searchIni.GetValue(section.c_str(), L"i"), L"yes") != 0); if (searchIni.GetValue(section.c_str(), L"n")) searchDlg.SetMatchesNewline(_wcsicmp(searchIni.GetValue(section.c_str(), L"n"), L"yes") == 0); if (searchIni.GetValue(section.c_str(), L"k")) searchDlg.SetCreateBackups(_wcsicmp(searchIni.GetValue(section.c_str(), L"k"), L"yes") == 0); if (searchIni.GetValue(section.c_str(), L"keepfiledate")) searchDlg.SetKeepFileDate(_wcsicmp(searchIni.GetValue(section.c_str(), L"keepfiledate"), L"yes") == 0); if (searchIni.GetValue(section.c_str(), L"wholewords")) searchDlg.SetWholeWords(_wcsicmp(searchIni.GetValue(section.c_str(), L"wholewords"), L"yes") == 0); if (searchIni.GetValue(section.c_str(), L"utf8")) searchDlg.SetUTF8(_wcsicmp(searchIni.GetValue(section.c_str(), L"utf8"), L"yes") == 0); if (searchIni.GetValue(section.c_str(), L"binary")) searchDlg.SetBinary(_wcsicmp(searchIni.GetValue(section.c_str(), L"binary"), L"yes") == 0); if (searchIni.GetValue(section.c_str(), L"size")) { int cmp = 0; if (searchIni.GetValue(section.c_str(), L"sizecmp")) cmp = _wtoi(searchIni.GetValue(section.c_str(), L"sizecmp")); searchDlg.SetSize(_wtoi(searchIni.GetValue(section.c_str(), L"size")), cmp); } if (searchIni.GetValue(section.c_str(), L"s")) searchDlg.SetIncludeSystem(_wcsicmp(searchIni.GetValue(section.c_str(), L"s"), L"yes") == 0); if (searchIni.GetValue(section.c_str(), L"h")) searchDlg.SetIncludeHidden(_wcsicmp(searchIni.GetValue(section.c_str(), L"h"), L"yes") == 0); if (searchIni.GetValue(section.c_str(), L"u")) searchDlg.SetIncludeSubfolders(_wcsicmp(searchIni.GetValue(section.c_str(), L"u"), L"yes") == 0); if (searchIni.GetValue(section.c_str(), L"l")) searchDlg.SetIncludeSymLinks(_wcsicmp(searchIni.GetValue(section.c_str(), L"l"), L"yes") == 0); if (searchIni.GetValue(section.c_str(), L"b")) searchDlg.SetIncludeBinary(_wcsicmp(searchIni.GetValue(section.c_str(), L"b"), L"yes") == 0); if (searchIni.GetValue(section.c_str(), L"regex")) searchDlg.SetUseRegex(_wcsicmp(searchIni.GetValue(section.c_str(), L"regex"), L"yes") == 0); else if (searchIni.GetValue(section.c_str(), L"searchfor")) searchDlg.SetUseRegex(true); if (searchIni.GetValue(section.c_str(), L"execute") || searchIni.GetValue(section.c_str(), L"executesearch")) searchDlg.SetExecute(ExecuteAction::Search); if (searchIni.GetValue(section.c_str(), L"executereplace")) searchDlg.SetExecute(ExecuteAction::Replace); if (searchIni.GetValue(section.c_str(), L"executecapture")) searchDlg.SetExecute(ExecuteAction::Capture); if (searchIni.GetValue(section.c_str(), L"closedialog")) searchDlg.SetEndDialog(); if (searchIni.GetValue(section.c_str(), L"content")) searchDlg.SetShowContent(); if (searchIni.GetValue(section.c_str(), L"datelimit") && searchIni.GetValue(section.c_str(), L"date1")) { FILETIME date1 = {0}; FILETIME date2 = {0}; int year = 0; int month = 0; int day = 0; auto sDate1 = searchIni.GetValue(section.c_str(), L"date1"); swscanf_s(sDate1, L"%4d:%2d:%2d", &year, &month, &day); SYSTEMTIME sysTime = {0}; sysTime.wYear = static_cast(year); sysTime.wMonth = static_cast(month); sysTime.wDay = static_cast(day); SystemTimeToFileTime(&sysTime, &date1); if (searchIni.GetValue(section.c_str(), L"date2")) { auto sDate2 = searchIni.GetValue(section.c_str(), L"date2"); swscanf_s(sDate2, L"%4d:%2d:%2d", &year, &month, &day); sysTime.wYear = static_cast(year); sysTime.wMonth = static_cast(month); sysTime.wDay = static_cast(day); SystemTimeToFileTime(&sysTime, &date2); } searchDlg.SetDateLimit(_wtoi(searchIni.GetValue(section.c_str(), L"datelimit")), date1, date2); } } if (parser.HasKey(L"searchpath")) { std::wstring sPath = parser.HasVal(L"searchpath") ? parser.GetVal(L"searchpath") : (bPortable ? g_iniFile.GetValue(L"global", L"searchpath", L"") : L""); sPath = SanitizeSearchPaths(sPath); searchDlg.SetSearchPath(sPath); } if (parser.HasKey(L"searchfor")) searchDlg.SetSearchString(parser.GetVal(L"searchfor") ? parser.GetVal(L"searchfor") : (bPortable ? g_iniFile.GetValue(L"global", L"searchfor", L"") : L"")); if (parser.HasKey(L"filemaskregex")) searchDlg.SetFileMask(parser.GetVal(L"filemaskregex") ? parser.GetVal(L"filemaskregex") : L"", true); if (parser.HasKey(L"filemask")) searchDlg.SetFileMask(parser.GetVal(L"filemask") ? parser.GetVal(L"filemask") : L"", false); if (parser.HasKey(L"direxcluderegex")) searchDlg.SetDirExcludeRegexMask(parser.GetVal(L"direxcluderegex") ? parser.GetVal(L"direxcluderegex") : L""); else if (parser.HasKey(L"filemaskexclude")) searchDlg.SetDirExcludeRegexMask(parser.GetVal(L"filemaskexclude") ? parser.GetVal(L"filemaskexclude") : L""); if (parser.HasKey(L"replacewith")) searchDlg.SetReplaceWith(parser.GetVal(L"replacewith") ? parser.GetVal(L"replacewith") : L""); if (parser.HasVal(L"preset")) searchDlg.SetPreset(parser.GetVal(L"preset")); if (parser.HasVal(L"i")) searchDlg.SetCaseSensitive(_wcsicmp(parser.GetVal(L"i"), L"yes")!=0); if (parser.HasVal(L"n")) searchDlg.SetMatchesNewline(_wcsicmp(parser.GetVal(L"n"), L"yes")==0); if (parser.HasVal(L"k")) searchDlg.SetCreateBackups(_wcsicmp(parser.GetVal(L"k"), L"yes") == 0); if (parser.HasVal(L"keepfiledate")) searchDlg.SetKeepFileDate(_wcsicmp(parser.GetVal(L"keepfiledate"), L"yes") == 0); if (parser.HasVal(L"wholewords")) searchDlg.SetWholeWords(_wcsicmp(parser.GetVal(L"wholewords"), L"yes") == 0); else if (parser.HasKey(L"wholewords")) searchDlg.SetWholeWords(true); if (parser.HasVal(L"utf8")) searchDlg.SetUTF8(_wcsicmp(parser.GetVal(L"utf8"), L"yes")==0); if (parser.HasVal(L"binary")) searchDlg.SetBinary(_wcsicmp(parser.GetVal(L"binary"), L"yes") == 0); if (parser.HasVal(L"size")) { int cmp = 0; if (parser.HasVal(L"sizecmp")) cmp = parser.GetLongVal(L"sizecmp"); searchDlg.SetSize(parser.GetLongVal(L"size"), cmp); } if (parser.HasVal(L"s")) searchDlg.SetIncludeSystem(_wcsicmp(parser.GetVal(L"s"), L"yes") == 0); if (parser.HasVal(L"h")) searchDlg.SetIncludeHidden(_wcsicmp(parser.GetVal(L"h"), L"yes") == 0); if (parser.HasVal(L"u")) searchDlg.SetIncludeSubfolders(_wcsicmp(parser.GetVal(L"u"), L"yes") == 0); if (parser.HasVal(L"l")) searchDlg.SetIncludeSymLinks(_wcsicmp(parser.GetVal(L"l"), L"yes") == 0); if (parser.HasVal(L"b")) searchDlg.SetIncludeBinary(_wcsicmp(parser.GetVal(L"b"), L"yes") == 0); if (parser.HasVal(L"regex")) searchDlg.SetUseRegex(_wcsicmp(parser.GetVal(L"regex"), L"yes") == 0); else if(parser.HasVal(L"searchfor")) searchDlg.SetUseRegex(true); if (parser.HasKey(L"execute") || parser.HasKey(L"executesearch")) searchDlg.SetExecute(ExecuteAction::Search); if (parser.HasKey(L"executereplace")) searchDlg.SetExecute(ExecuteAction::Replace); if (parser.HasKey(L"executecapture")) searchDlg.SetExecute(ExecuteAction::Capture); if (parser.HasKey(L"closedialog")) searchDlg.SetEndDialog(); if (parser.HasKey(L"content")) searchDlg.SetShowContent(); if (parser.HasVal(L"datelimit") && parser.HasVal(L"date1")) { FILETIME date1 = { 0 }; FILETIME date2 = { 0 }; int year = 0; int month = 0; int day = 0; auto sDate1 = parser.GetVal(L"date1"); swscanf_s(sDate1, L"%4d:%2d:%2d", &year, &month, &day); SYSTEMTIME sysTime = {0}; sysTime.wYear = static_cast(year); sysTime.wMonth = static_cast(month); sysTime.wDay = static_cast(day); SystemTimeToFileTime(&sysTime, &date1); if (parser.HasVal(L"date2")) { auto sDate2 = parser.GetVal(L"date2"); swscanf_s(sDate2, L"%4d:%2d:%2d", &year, &month, &day); sysTime.wYear = static_cast(year); sysTime.wMonth = static_cast(month); sysTime.wDay = static_cast(day); SystemTimeToFileTime(&sysTime, &date2); } searchDlg.SetDateLimit(parser.GetLongVal(L"datelimit"), date1, date2); } if (!parser.HasKey(L"searchpath")) { auto cmdLineSize = wcslen(lpCmdLine); auto cmdLinePath = std::make_unique(cmdLineSize + 1); wcscpy_s(cmdLinePath.get(), cmdLineSize + 1, lpCmdLine); PathUnquoteSpaces(cmdLinePath.get()); if (PathFileExists(cmdLinePath.get())) { std::wstring sPath = cmdLinePath.get(); sPath = SanitizeSearchPaths(sPath); searchDlg.SetSearchPath(sPath); } } if (parser.HasKey(L"nosavesettings")) searchDlg.SetNoSaveSettings(true); SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); ret = static_cast(searchDlg.DoModal(hInstance, IDD_SEARCHDLG, nullptr, IDR_SEARCHDLG)); } if (bPortable) { g_iniFile.SaveFile(g_iniPath.c_str(), true); } Gdiplus::GdiplusShutdown(gdiplusToken); } ::CoUninitialize(); ::OleUninitialize(); FreeLibrary(hRichEdt); CloseHandle(hReloadProtection); return ret; }