int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){ //load ini file //printf("Loading config file\n"); CSimpleIni ini; ini.SetUnicode(); ini.LoadFile("config/jar-launcher.ini"); //load keys //printf("Loading keys\n"); const char* jar = ini.GetValue("Launcher", "jar", "xls2csv.jar"); const char* mem_min = ini.GetValue("Launcher", "jvm_memory_min", "256m"); const char* mem_max = ini.GetValue("Launcher", "jvm_memory_max", "512m"); //put together command string char* command = new char[256]; int command_length = sprintf( command, "java -Xms%s -Xmx%s -jar %s", mem_min, mem_max, jar); assert( command_length > 0 ); //setup call STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); //make call //printf("Launching %s\n", jar); //execl( command, NULL); //int result = system(command); CreateProcess( NULL, // No module name (use command line) command,// Command line NULL, // Process handle not inheritable NULL, // Thread handle not inheritable FALSE, // Set handle inheritance to FALSE CREATE_NO_WINDOW, // No creation flags NULL, // Use parent's environment block NULL, // Use parent's starting directory &si, // Pointer to STARTUPINFO structure &pi); //clean up CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); delete[] command; return 0;}
bool SyncCommand::Execute() { bool bRet = false; CRegString rSyncPath(L"Software\\TortoiseSVN\\SyncPath"); CTSVNPath syncPath = CTSVNPath(CString(rSyncPath)); CTSVNPath syncFolder = syncPath; CRegDWORD regCount(L"Software\\TortoiseSVN\\SyncCounter"); CRegDWORD regSyncAuth(L"Software\\TortoiseSVN\\SyncAuth"); bool bSyncAuth = DWORD(regSyncAuth) != 0; if (!cmdLinePath.IsEmpty()) syncPath = cmdLinePath; if (syncPath.IsEmpty() && !parser.HasKey(L"askforpath")) { return false; } syncPath.AppendPathString(L"tsvnsync.tsex"); BOOL bWithLocals = FALSE; if (parser.HasKey(L"askforpath")) { // ask for the path first, then for the password // this is used for a manual import/export CString path; bool bGotPath = FileOpenSave(path, bWithLocals, !!parser.HasKey(L"load"), GetExplorerHWND()); if (bGotPath) { syncPath = CTSVNPath(path); if (!parser.HasKey(L"load") && syncPath.GetFileExtension().IsEmpty()) syncPath.AppendRawString(L".tsex"); } else return false; } CSimpleIni iniFile; iniFile.SetMultiLine(true); SVNAuthData authData; CAutoRegKey hMainKey; RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\TortoiseSVN", 0, KEY_READ, hMainKey.GetPointer()); FILETIME filetime = { 0 }; RegQueryInfoKey(hMainKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &filetime); bool bCloudIsNewer = false; if (!parser.HasKey(L"save")) { // open the file in read mode CAutoFile hFile = CreateFile(syncPath.GetWinPathString(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile.IsValid()) { // load the file LARGE_INTEGER fsize = { 0 }; if (GetFileSizeEx(hFile, &fsize)) { auto filebuf = std::make_unique<char[]>(DWORD(fsize.QuadPart)); DWORD bytesread = 0; if (ReadFile(hFile, filebuf.get(), DWORD(fsize.QuadPart), &bytesread, NULL)) { // decrypt the file contents std::string encrypted; if (bytesread > 0) encrypted = std::string(filebuf.get(), bytesread); CRegString regPW(L"Software\\TortoiseSVN\\SyncPW"); CString password; if (parser.HasKey(L"askforpath") && parser.HasKey(L"load")) { INT_PTR dlgret = 0; bool bPasswordMatches = true; do { bPasswordMatches = true; CPasswordDlg passDlg(CWnd::FromHandle(GetExplorerHWND())); passDlg.m_bForSave = !!parser.HasKey(L"save"); dlgret = passDlg.DoModal(); password = passDlg.m_sPW1; if ((dlgret == IDOK) && (parser.HasKey(L"load"))) { std::string passworda = CUnicodeUtils::StdGetUTF8((LPCWSTR)password); std::string decrypted = CStringUtils::Decrypt(encrypted, passworda); if ((decrypted.size() < 3) || (decrypted.substr(0, 3) != "***")) { bPasswordMatches = false; } } } while ((dlgret == IDOK) && !bPasswordMatches); if (dlgret != IDOK) return false; } else { auto passwordbuf = CStringUtils::Decrypt(CString(regPW)); if (passwordbuf.get()) { password = passwordbuf.get(); } else { // password does not match or it couldn't be read from // the registry! // TaskDialog(GetExplorerHWND(), AfxGetResourceHandle(), MAKEINTRESOURCE(IDS_APPNAME), MAKEINTRESOURCE(IDS_ERR_ERROROCCURED), MAKEINTRESOURCE(IDS_SYNC_WRONGPASSWORD), TDCBF_OK_BUTTON, TD_ERROR_ICON, NULL); CString sCmd = L" /command:settings /page:21"; CAppUtils::RunTortoiseProc(sCmd); return false; } } std::string passworda = CUnicodeUtils::StdGetUTF8((LPCWSTR)password); std::string decrypted = CStringUtils::Decrypt(encrypted, passworda); if (decrypted.size() >= 3) { if (decrypted.substr(0, 3) == "***") { decrypted = decrypted.substr(3); // pass the decrypted data to the ini file iniFile.LoadFile(decrypted.c_str(), decrypted.size()); int inicount = _wtoi(iniFile.GetValue(L"sync", L"synccounter", L"")); if (inicount != 0) { if (int(DWORD(regCount)) < inicount) { bCloudIsNewer = true; regCount = inicount; } } // load the auth data, but do not overwrite already stored auth data! if (bSyncAuth) authData.ImportAuthData(syncFolder.GetWinPathString(), password); } else { CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error decrypting, password may be wrong\n"); return false; } } } } } else { CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error opening file %s, Error %u\n", syncPath.GetWinPath(), GetLastError()); auto lasterr = GetLastError(); if ((lasterr != ERROR_FILE_NOT_FOUND) && (lasterr != ERROR_PATH_NOT_FOUND)) return false; } } if (parser.HasKey(L"load")) bCloudIsNewer = true; if (parser.HasKey(L"save")) bCloudIsNewer = false; bool bHaveChanges = false; if (bWithLocals || parser.HasKey(L"local")) { // remove all blocks that are allowed for local exports for (const auto& allow : regBlockLocalArray) { regBlockArray.erase(std::remove(regBlockArray.begin(), regBlockArray.end(), allow), regBlockArray.end()); } } // go through all registry values and update either the registry // or the ini file, depending on which is newer for (const auto& regname : regUseArray) { bool bChanges = HandleRegistryKey(regname, iniFile, bCloudIsNewer); bHaveChanges = bHaveChanges || bChanges; } if (bWithLocals || parser.HasKey(L"local")) { for (const auto& regname : regUseLocalArray) { bool bChanges = HandleRegistryKey(regname, iniFile, bCloudIsNewer); bHaveChanges = bHaveChanges || bChanges; } } if (bCloudIsNewer) { CString regpath = L"Software\\"; CSimpleIni::TNamesDepend keys; iniFile.GetAllKeys(L"registry_dword", keys); for (const auto& k : keys) { CRegDWORD reg(regpath + k); reg = _wtol(iniFile.GetValue(L"registry_dword", k, L"")); } keys.clear(); iniFile.GetAllKeys(L"registry_qword", keys); for (const auto& k : keys) { CRegQWORD reg(regpath + k); reg = _wtoi64(iniFile.GetValue(L"registry_qword", k, L"")); } keys.clear(); iniFile.GetAllKeys(L"registry_string", keys); for (const auto& k : keys) { CRegString reg(regpath + k); reg = CString(iniFile.GetValue(L"registry_string", k, L"")); } } { // sync project monitor settings CString sDataFilePath = CPathUtils::GetAppDataDirectory(); sDataFilePath += L"\\MonitoringData.ini"; CSimpleIni monitorIni; monitorIni.SetMultiLine(true); if (bCloudIsNewer) { CSimpleIni origMonitorIni; origMonitorIni.SetMultiLine(true); origMonitorIni.LoadFile(sDataFilePath); CSimpleIni::TNamesDepend keys; iniFile.GetAllKeys(L"ini_monitor", keys); for (const auto& k : keys) { CString sKey = k; CString sSection = sKey.Left(sKey.Find('.')); sKey = sKey.Mid(sKey.Find('.') + 1); if (sKey.CompareNoCase(L"name") == 0) { // make sure the non-synced values are still used monitorIni.SetValue(sSection, L"lastchecked", origMonitorIni.GetValue(sSection, L"lastchecked", L"0")); monitorIni.SetValue(sSection, L"lastcheckedrobots", origMonitorIni.GetValue(sSection, L"lastcheckedrobots", L"0")); monitorIni.SetValue(sSection, L"lastHEAD", origMonitorIni.GetValue(sSection, L"lastHEAD", L"0")); monitorIni.SetValue(sSection, L"UnreadItems", origMonitorIni.GetValue(sSection, L"UnreadItems", L"0")); monitorIni.SetValue(sSection, L"unreadFirst", origMonitorIni.GetValue(sSection, L"unreadFirst", L"0")); monitorIni.SetValue(sSection, L"WCPathOrUrl", origMonitorIni.GetValue(sSection, L"WCPathOrUrl", L"")); } CString sValue = CString(iniFile.GetValue(L"ini_monitor", k, L"")); if ((sKey.Compare(L"username") == 0) || (sKey.Compare(L"password") == 0)) { sValue = CStringUtils::Encrypt(sValue); } monitorIni.SetValue(sSection, sKey, sValue); } FILE * pFile = NULL; errno_t err = 0; int retrycount = 5; CString sTempfile = CTempFiles::Instance().GetTempFilePathString(); do { err = _tfopen_s(&pFile, sTempfile, L"wb"); if ((err == 0) && pFile) { monitorIni.SaveFile(pFile); err = fclose(pFile); } if (err) { CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error saving %s, retrycount %d\n", (LPCWSTR)sTempfile, retrycount); Sleep(500); } } while (err && retrycount--); if (err == 0) { if (!CopyFile(sTempfile, sDataFilePath, FALSE)) CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error copying %s to %s, Error %u\n", (LPCWSTR)sTempfile, (LPCWSTR)sDataFilePath, GetLastError()); else { // now send a message to a possible running monitor to force it // to reload the ini file. Otherwise it would overwrite the ini // file without using the synced data! HWND hWnd = FindWindow(NULL, CString(MAKEINTRESOURCE(IDS_MONITOR_DLGTITLE))); if (hWnd) { UINT TSVN_COMMITMONITOR_RELOADINI = RegisterWindowMessage(L"TSVNCommitMonitor_ReloadIni"); PostMessage(hWnd, TSVN_COMMITMONITOR_RELOADINI, 0, 0); } } } } else { CSimpleIni::TNamesDepend mitems; if (PathFileExists(sDataFilePath)) { int retrycount = 5; SI_Error err = SI_OK; do { err = monitorIni.LoadFile(sDataFilePath); if (err == SI_FILE) { CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error loading %s, retrycount %d\n", (LPCWSTR)sDataFilePath, retrycount); Sleep(500); } } while ((err == SI_FILE) && retrycount--); if (err == SI_FILE) { return false; } monitorIni.GetAllSections(mitems); } for (const auto& mitem : mitems) { CString sSection = mitem; CString Name = monitorIni.GetValue(mitem, L"Name", L""); if (!Name.IsEmpty()) { CString newval = monitorIni.GetValue(mitem, L"WCPathOrUrl", L""); iniFile.SetValue(L"ini_monitor", sSection + L".Name", Name); CString oldval = iniFile.GetValue(L"ini_monitor", sSection + L".WCPathOrUrl", L""); bHaveChanges |= ((newval != oldval) && (!oldval.IsEmpty())); // only save monitored working copies if local settings are included, or // if the monitored path is an url. // Don't save paths to working copies for non-local stores if (bWithLocals || newval.IsEmpty() || !PathIsDirectory(newval)) iniFile.SetValue(L"ini_monitor", sSection + L".WCPathOrUrl", newval); newval = monitorIni.GetValue(mitem, L"interval", L"5"); oldval = iniFile.GetValue(L"ini_monitor", sSection + L".interval", L"0"); bHaveChanges |= newval != oldval; iniFile.SetValue(L"ini_monitor", sSection + L".interval", newval); newval = monitorIni.GetValue(mitem, L"minminutesinterval", L"0"); oldval = iniFile.GetValue(L"ini_monitor", sSection + L".minminutesinterval", L"0"); bHaveChanges |= newval != oldval; iniFile.SetValue(L"ini_monitor", sSection + L".minminutesinterval", newval); newval = CStringUtils::Decrypt(monitorIni.GetValue(mitem, L"username", L"")).get(); oldval = iniFile.GetValue(L"ini_monitor", sSection + L".username", L""); bHaveChanges |= newval != oldval; iniFile.SetValue(L"ini_monitor", sSection + L".username", newval); newval = CStringUtils::Decrypt(monitorIni.GetValue(mitem, L"password", L"")).get(); oldval = iniFile.GetValue(L"ini_monitor", sSection + L".password", L""); bHaveChanges |= newval != oldval; iniFile.SetValue(L"ini_monitor", sSection + L".password", newval); newval = monitorIni.GetValue(mitem, L"MsgRegex", L""); oldval = iniFile.GetValue(L"ini_monitor", sSection + L".MsgRegex", L""); bHaveChanges |= newval != oldval; iniFile.SetValue(L"ini_monitor", sSection + L".MsgRegex", newval); newval = monitorIni.GetValue(mitem, L"ignoreauthors", L""); oldval = iniFile.GetValue(L"ini_monitor", sSection + L".ignoreauthors", L""); bHaveChanges |= newval != oldval; iniFile.SetValue(L"ini_monitor", sSection + L".ignoreauthors", newval); newval = monitorIni.GetValue(mitem, L"parentTreePath", L""); oldval = iniFile.GetValue(L"ini_monitor", sSection + L".parentTreePath", L""); bHaveChanges |= newval != oldval; iniFile.SetValue(L"ini_monitor", sSection + L".parentTreePath", newval); newval = monitorIni.GetValue(mitem, L"uuid", L""); oldval = iniFile.GetValue(L"ini_monitor", sSection + L".uuid", L""); bHaveChanges |= newval != oldval; iniFile.SetValue(L"ini_monitor", sSection + L".uuid", newval); newval = monitorIni.GetValue(mitem, L"root", L""); oldval = iniFile.GetValue(L"ini_monitor", sSection + L".root", L""); bHaveChanges |= newval != oldval; iniFile.SetValue(L"ini_monitor", sSection + L".root", newval); ProjectProperties ProjProps; ProjProps.LoadFromIni(monitorIni, sSection); ProjProps.SaveToIni(iniFile, L"ini_monitor", sSection + L".pp_"); } else if (sSection.CompareNoCase(L"global") == 0) { CString newval = monitorIni.GetValue(mitem, L"PlaySound", L"1"); CString oldval = iniFile.GetValue(L"ini_monitor", sSection + L".PlaySound", L"1"); bHaveChanges |= newval != oldval; iniFile.SetValue(L"ini_monitor", sSection + L".PlaySound", newval); newval = monitorIni.GetValue(mitem, L"ShowNotifications", L"1"); oldval = iniFile.GetValue(L"ini_monitor", sSection + L".ShowNotifications", L"1"); bHaveChanges |= newval != oldval; iniFile.SetValue(L"ini_monitor", sSection + L".ShowNotifications", newval); } } } } { // sync TortoiseMerge regex filters CSimpleIni regexIni; regexIni.SetMultiLine(true); CString sDataFilePath = CPathUtils::GetAppDataDirectory(); sDataFilePath += L"\\regexfilters.ini"; if (bCloudIsNewer) { CSimpleIni origRegexIni; if (PathFileExists(sDataFilePath)) { int retrycount = 5; SI_Error err = SI_OK; do { err = origRegexIni.LoadFile(sDataFilePath); if (err == SI_FILE) { CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error loading %s, retrycount %d\n", (LPCWSTR)sDataFilePath, retrycount); Sleep(500); } } while ((err == SI_FILE) && retrycount--); if (err == SI_FILE) { return false; } } CSimpleIni::TNamesDepend keys; iniFile.GetAllKeys(L"ini_tmergeregex", keys); for (const auto& k : keys) { CString sKey = k; CString sSection = sKey.Left(sKey.Find('.')); sKey = sKey.Mid(sKey.Find('.') + 1); CString sValue = CString(iniFile.GetValue(L"ini_tmergeregex", k, L"")); regexIni.SetValue(sSection, sKey, sValue); } FILE * pFile = NULL; errno_t err = 0; int retrycount = 5; CString sTempfile = CTempFiles::Instance().GetTempFilePathString(); do { err = _tfopen_s(&pFile, sTempfile, L"wb"); if ((err == 0) && pFile) { regexIni.SaveFile(pFile); err = fclose(pFile); } if (err) { CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error saving %s, retrycount %d\n", (LPCWSTR)sTempfile, retrycount); Sleep(500); } } while (err && retrycount--); if (err == 0) { if (!CopyFile(sTempfile, sDataFilePath, FALSE)) CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error copying %s to %s, Error: %u\n", (LPCWSTR)sTempfile, (LPCWSTR)sDataFilePath, GetLastError()); } } else { if (PathFileExists(sDataFilePath)) { int retrycount = 5; SI_Error err = SI_OK; do { err = regexIni.LoadFile(sDataFilePath); if (err == SI_FILE) { CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error loading %s, retrycount %d\n", (LPCWSTR)sDataFilePath, retrycount); Sleep(500); } } while ((err == SI_FILE) && retrycount--); if (err == SI_FILE) { return false; } } CSimpleIni::TNamesDepend mitems; regexIni.GetAllSections(mitems); for (const auto& mitem : mitems) { CString sSection = mitem; CString newval = regexIni.GetValue(mitem, L"regex", L""); CString oldval = iniFile.GetValue(L"ini_tmergeregex", sSection + L".regex", L""); bHaveChanges |= newval != oldval; iniFile.SetValue(L"ini_tmergeregex", sSection + L".regex", newval); newval = regexIni.GetValue(mitem, L"replace", L"5"); oldval = iniFile.GetValue(L"ini_tmergeregex", sSection + L".replace", L"0"); bHaveChanges |= newval != oldval; iniFile.SetValue(L"ini_tmergeregex", sSection + L".replace", newval); } } } if (bHaveChanges) { iniFile.SetValue(L"sync", L"version", TSVN_SYNC_VERSION_STR); DWORD count = regCount; ++count; regCount = count; CString tmp; tmp.Format(L"%lu", count); iniFile.SetValue(L"sync", L"synccounter", tmp); // save the ini file std::string iniData; iniFile.SaveString(iniData); iniData = "***" + iniData; // encrypt the string CString password; if (parser.HasKey(L"askforpath")) { CPasswordDlg passDlg(CWnd::FromHandle(GetExplorerHWND())); passDlg.m_bForSave = true; if (passDlg.DoModal() != IDOK) return false; password = passDlg.m_sPW1; } else { CRegString regPW(L"Software\\TortoiseSVN\\SyncPW"); auto passwordbuf = CStringUtils::Decrypt(CString(regPW)); if (passwordbuf.get()) { password = passwordbuf.get(); } } std::string passworda = CUnicodeUtils::StdGetUTF8((LPCWSTR)password); std::string encrypted = CStringUtils::Encrypt(iniData, passworda); CPathUtils::MakeSureDirectoryPathExists(syncPath.GetContainingDirectory().GetWinPathString()); CString sTempfile = CTempFiles::Instance().GetTempFilePathString(); CAutoFile hFile = CreateFile(sTempfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile.IsValid()) { DWORD written = 0; if (WriteFile(hFile, encrypted.c_str(), DWORD(encrypted.size()), &written, NULL)) { if (hFile.CloseHandle()) { if (!CopyFile(sTempfile, syncPath.GetWinPath(), FALSE)) { CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error copying %s to %s, Error: %u\n", (LPCWSTR)sTempfile, syncPath.GetWinPath(), GetLastError()); } else bRet = true; } else CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error closing file %s, Error: %u\n", (LPCWSTR)sTempfile, GetLastError()); } else CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error writing to file %s, Error: %u\n", (LPCWSTR)sTempfile, GetLastError()); } else CTraceToOutputDebugString::Instance()(_T(__FUNCTION__) L": Error creating file %s for writing, Error: %u\n", (LPCWSTR)sTempfile, GetLastError()); if (bSyncAuth) { // now save all auth data CPathUtils::MakeSureDirectoryPathExists(syncFolder.GetWinPathString() + L"\\auth"); CPathUtils::MakeSureDirectoryPathExists(syncFolder.GetWinPathString() + L"\\auth\\svn.simple"); CPathUtils::MakeSureDirectoryPathExists(syncFolder.GetWinPathString() + L"\\auth\\svn.ssl.client-passphrase"); CPathUtils::MakeSureDirectoryPathExists(syncFolder.GetWinPathString() + L"\\auth\\svn.ssl.server"); CPathUtils::MakeSureDirectoryPathExists(syncFolder.GetWinPathString() + L"\\auth\\svn.username"); authData.ExportAuthData(syncFolder.GetWinPathString(), password); } } return bRet; }
bool SyncCommand::HandleRegistryKey(const CString& regname, CSimpleIni& iniFile, bool bCloudIsNewer) { CAutoRegKey hKey; CAutoRegKey hKeyKey; DWORD regtype = 0; DWORD regsize = 0; CString sKeyPath = L"Software"; CString sValuePath = regname; CString sIniKeyName = regname; CString sRegname = regname; CString sValue; bool bHaveChanges = false; if (regname.Find('\\') >= 0) { // handle values in sub-keys sKeyPath = L"Software\\" + regname.Left(regname.ReverseFind('\\')); sValuePath = regname.Mid(regname.ReverseFind('\\') + 1); } if (RegOpenKeyEx(HKEY_CURRENT_USER, sKeyPath, 0, KEY_READ, hKey.GetPointer()) == ERROR_SUCCESS) { bool bEnum = false; bool bEnumKeys = false; int index = 0; int keyindex = 0; // an asterisk means: use all values inside the specified key if (sValuePath == L"*") bEnum = true; if (sValuePath == L"**") { bEnumKeys = true; bEnum = true; RegOpenKeyEx(HKEY_CURRENT_USER, sKeyPath, 0, KEY_READ, hKeyKey.GetPointer()); } do { if (bEnumKeys) { bEnum = true; index = 0; wchar_t cKeyName[MAX_PATH] = { 0 }; DWORD cLen = _countof(cKeyName); if (RegEnumKeyEx(hKeyKey, keyindex, cKeyName, &cLen, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) { bEnumKeys = false; break; } ++keyindex; sKeyPath = L"Software\\" + regname.Left(regname.ReverseFind('\\')) + L"\\" + cKeyName + L"\\"; sRegname = regname.Left(regname.ReverseFind('\\')) + L"\\" + cKeyName + L"\\"; hKey.CloseHandle(); if (RegOpenKeyEx(HKEY_CURRENT_USER, sKeyPath, 0, KEY_READ, hKey.GetPointer()) != ERROR_SUCCESS) { bEnumKeys = false; break; } } do { if (bEnum) { // start enumerating all values wchar_t cValueName[MAX_PATH] = { 0 }; DWORD cLen = _countof(cValueName); if (RegEnumValue(hKey, index, cValueName, &cLen, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) { bEnum = false; break; } ++index; sValuePath = cValueName; CString sValueLower = sValuePath; sValueLower.MakeLower(); bool bIgnore = false; for (const auto& ignore : regBlockArray) { if (wcswildcmp(ignore, sValueLower)) { bIgnore = true; break; } } if (bIgnore) continue; sIniKeyName = sRegname.Left(sRegname.ReverseFind('\\')); if (sIniKeyName.IsEmpty()) sIniKeyName = sValuePath; else sIniKeyName += L"\\" + sValuePath; } if (RegQueryValueEx(hKey, sValuePath, NULL, ®type, NULL, ®size) == ERROR_SUCCESS) { if (regtype != 0) { auto regbuf = std::make_unique<BYTE[]>(regsize); if (RegQueryValueEx(hKey, sValuePath, NULL, ®type, regbuf.get(), ®size) == ERROR_SUCCESS) { switch (regtype) { case REG_DWORD: { DWORD value = *(DWORD*)regbuf.get(); sValue = iniFile.GetValue(L"registry_dword", sIniKeyName); DWORD nValue = DWORD(_wtol(sValue)); if (nValue != value) { if (bCloudIsNewer) { RegSetValueEx(hKey, sValuePath, NULL, regtype, (BYTE *)&nValue, sizeof(nValue)); } else { bHaveChanges = true; sValue.Format(L"%lu", value); iniFile.SetValue(L"registry_dword", sIniKeyName, sValue); } } if (bCloudIsNewer) iniFile.Delete(L"registry_dword", sIniKeyName); } break; case REG_QWORD: { QWORD value = *(QWORD*)regbuf.get(); sValue = iniFile.GetValue(L"registry_qword", sIniKeyName); QWORD nValue = QWORD(_wtoi64(sValue)); if (nValue != value) { if (bCloudIsNewer) { RegSetValueEx(hKey, sValuePath, NULL, regtype, (BYTE *)&nValue, sizeof(nValue)); } else { bHaveChanges = true; sValue.Format(L"%I64d", value); iniFile.SetValue(L"registry_qword", sIniKeyName, sValue); } } if (bCloudIsNewer) iniFile.Delete(L"registry_qword", sIniKeyName); } break; case REG_EXPAND_SZ: case REG_MULTI_SZ: case REG_SZ: { sValue = (LPCWSTR)regbuf.get(); CString iniValue = iniFile.GetValue(L"registry_string", sIniKeyName); if (iniValue != sValue) { if (bCloudIsNewer) { RegSetValueEx(hKey, sValuePath, NULL, regtype, (BYTE *)(LPCWSTR)iniValue, (iniValue.GetLength() + 1)*sizeof(WCHAR)); } else { bHaveChanges = true; iniFile.SetValue(L"registry_string", sIniKeyName, sValue); } } if (bCloudIsNewer) iniFile.Delete(L"registry_string", sIniKeyName); } break; } } } } } while (bEnum); } while (bEnumKeys); } return bHaveChanges; }
void DoIniTest() { CSimpleIni sini; sini.WriteBoolean("test", "bool", true); bool bValue = sini.GetBoolean("test", "bool", false); VERIFY(bValue == true); int iValue; iValue = sini.GetInt("test", "not-existing", 20); VERIFY(iValue == 20); sini.WriteInt("test", "int", -100); iValue = sini.GetInt("test", "int", 0); VERIFY(iValue == -100); sini.WriteInt("test", "int", 1); bValue = sini.GetBoolean("test", "int", false); VERIFY(bValue == true); sini.WriteInt("test", "int", 0); bValue = sini.GetBoolean("test", "int", true); VERIFY(bValue == false); std::string strValue = sini.GetString("test", "not-existing", ""); VERIFY(strValue == ""); strValue = sini.GetString("test", "not-existing", "abc"); VERIFY(strValue == "abc"); sini.WriteString("test", "str", "test-string"); strValue = sini.GetString("test", "str", ""); VERIFY(strValue == "test-string"); }
int APIENTRY _tWinMain(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(NULL, 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; } g_hInst = hInstance; ::OleInitialize(NULL); ::CoInitializeEx(NULL, 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); HMODULE hRichEdt = LoadLibrary(_T("Riched20.dll")); CCmdLineParser parser(lpCmdLine); 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 = NULL; int timeout = 20; do { EnumWindows(windowenumerator, (LPARAM)&hWnd); if (alreadyRunning && (hWnd == NULL)) Sleep(100); timeout--; } while ((hWnd == NULL) && alreadyRunning && timeout); auto modulename = CPathUtils::GetFileName(CPathUtils::GetModulePath(0)); bPortable = ((_tcsstr(modulename.c_str(), _T("portable"))) || (parser.HasKey(_T("portable")))); std::wstring iniPath = CPathUtils::GetModuleDir(0); iniPath += L"\\grepwin.ini"; if (parser.HasVal(L"inipath")) iniPath = parser.GetVal(L"inipath"); if (bPortable) g_iniFile.LoadFile(iniPath.c_str()); if (hWnd) { bool bOnlyOne = !!DWORD(CRegStdDWORD(_T("Software\\grepWin\\onlyone"), 0)); if (bPortable) bOnlyOne = !!_wtoi(g_iniFile.GetValue(L"global", L"onlyone", L"0")); UINT GREPWIN_STARTUPMSG = RegisterWindowMessage(_T("grepWin_StartupMessage")); if (SendMessage(hWnd, GREPWIN_STARTUPMSG, 0, 0)) // send the new path { std::wstring spath = parser.GetVal(_T("searchpath")); SearchReplace(spath, L"/", L"\\"); spath = SanitizeSearchPaths(spath); COPYDATASTRUCT CopyData = {0}; CopyData.lpData = (LPVOID)spath.c_str(); CopyData.cbData = (DWORD)spath.size()*sizeof(wchar_t); SendMessage(hWnd, WM_COPYDATA, 0, (LPARAM)&CopyData); SetForegroundWindow(hWnd); //set the window to front bQuit = true; } else if (bOnlyOne) { std::wstring spath = parser.HasVal(L"searchpath") ? parser.GetVal(_T("searchpath")) : L""; SearchReplace(spath, L"/", L"\\"); spath = SanitizeSearchPaths(spath); COPYDATASTRUCT CopyData = { 0 }; CopyData.lpData = (LPVOID)spath.c_str(); CopyData.cbData = (DWORD)spath.size()*sizeof(wchar_t); SendMessage(hWnd, WM_COPYDATA, 1, (LPARAM)&CopyData); SetForegroundWindow(hWnd); //set the window to front bQuit = true; } } int ret = 0; if (!bQuit) { CLanguage::Instance().LoadFile(bPortable ? g_iniFile.GetValue(L"global", L"languagefile", L"") : std::wstring(CRegStdString(L"Software\\grepWin\\languagefile"))); if (parser.HasKey(_T("about"))||parser.HasKey(_T("?"))||parser.HasKey(_T("help"))) { CAboutDlg aboutDlg(NULL); ret= (int)aboutDlg.DoModal(hInstance, IDD_ABOUT, NULL, NULL); } else { CSearchDlg searchDlg(NULL); if (parser.HasVal(_T("searchpath"))) { std::wstring spath = parser.GetVal(L"searchpath"); spath = SanitizeSearchPaths(spath); searchDlg.SetSearchPath(spath); } if (parser.HasVal(_T("searchfor"))) searchDlg.SetSearchString(parser.GetVal(_T("searchfor"))); if (parser.HasVal(_T("filemaskregex"))) searchDlg.SetFileMask(parser.GetVal(_T("filemaskregex")), true); if (parser.HasVal(_T("filemask"))) searchDlg.SetFileMask(parser.GetVal(_T("filemask")), false); if (parser.HasVal(_T("filemaskexclude"))) searchDlg.SetExcludeFileMask(parser.GetVal(_T("filemaskexclude"))); if (parser.HasVal(_T("replacewith"))) searchDlg.SetReplaceWith(parser.GetVal(_T("replacewith"))); if (parser.HasVal(_T("i"))) searchDlg.SetCaseSensitive(_tcsicmp(parser.GetVal(_T("i")), _T("yes"))!=0); if (parser.HasVal(_T("n"))) searchDlg.SetMatchesNewline(_tcsicmp(parser.GetVal(_T("n")), _T("yes"))==0); if (parser.HasVal(_T("k"))) searchDlg.SetCreateBackups(_tcsicmp(parser.GetVal(_T("k")), _T("yes"))==0); if (parser.HasVal(_T("utf8"))) searchDlg.SetUTF8(_tcsicmp(parser.GetVal(_T("utf8")), _T("yes"))==0); if (parser.HasVal(_T("size"))) { int cmp = 0; if (parser.HasVal(_T("sizecmp"))) cmp = parser.GetLongVal(_T("sizecmp")); searchDlg.SetSize(parser.GetLongVal(_T("size")), cmp); } if (parser.HasVal(_T("s"))) searchDlg.SetIncludeSystem(_tcsicmp(parser.GetVal(_T("s")), _T("yes"))==0); if (parser.HasVal(_T("h"))) searchDlg.SetIncludeHidden(_tcsicmp(parser.GetVal(_T("h")), _T("yes"))==0); if (parser.HasVal(_T("u"))) searchDlg.SetIncludeSubfolders(_tcsicmp(parser.GetVal(_T("u")), _T("yes"))==0); if (parser.HasVal(_T("b"))) searchDlg.SetIncludeBinary(_tcsicmp(parser.GetVal(_T("b")), _T("yes"))==0); if (parser.HasVal(_T("regex"))) searchDlg.SetUseRegex(_tcsicmp(parser.GetVal(_T("regex")), _T("yes")) == 0); else if(parser.HasVal(_T("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"closedialog")) searchDlg.SetEndDialog(); ret = (int)searchDlg.DoModal(hInstance, IDD_SEARCHDLG, NULL, IDR_SEARCHDLG); } if (bPortable) { FILE * pFile = NULL; _tfopen_s(&pFile, iniPath.c_str(), _T("wb")); g_iniFile.SaveFile(pFile); fclose(pFile); } } ::CoUninitialize(); ::OleUninitialize(); FreeLibrary(hRichEdt); CloseHandle(hReloadProtection); return ret; }