bool CAddrDB::Read(CAddrMan& addr) { // open input file, and associate with CAutoFile FILE *file = fopen(pathAddr.string().c_str(), "rb"); CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION); if (!filein) return error("CAddrman::Read() : open failed"); // use file size to size memory buffer int fileSize = boost::filesystem::file_size(pathAddr); int dataSize = fileSize - sizeof(uint256); // Don't try to resize to a negative number if file is small if ( dataSize < 0 ) dataSize = 0; vector<unsigned char> vchData; vchData.resize(dataSize); uint256 hashIn; // read data and checksum from file try { filein.read((char *)&vchData[0], dataSize); filein >> hashIn; } catch (std::exception &e) { return error("CAddrman::Read() 2 : I/O error or stream data corrupted"); } filein.fclose(); CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION); // verify stored checksum matches input data uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end()); if (hashIn != hashTmp) return error("CAddrman::Read() : checksum mismatch; data corrupted"); unsigned char pchMsgTmp[4]; try { // de-serialize file header (pchMessageStart magic number) and ssPeers >> FLATDATA(pchMsgTmp); // verify the network matches ours if (memcmp(pchMsgTmp, pchMessageStart, sizeof(pchMsgTmp))) return error("CAddrman::Read() : invalid network magic number"); // de-serialize address data into one CAddrMan object ssPeers >> addr; } catch (std::exception &e) { return error("CAddrman::Read() : I/O error or stream data corrupted"); } return true; }
bool CAddrDB::Read(CAddrMan& addr) { // open input file, and associate with CAutoFile FILE *file = fopen(pathAddr.string().c_str(), "rb"); CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION); if(!filein) return(error("CAddrDB::Read() : fopen(%s) failed", pathAddr.string().c_str())); // use file size to size memory buffer int fileSize = GetFilesize(filein); int dataSize = fileSize - sizeof(uint256); vector<unsigned char> vchData; vchData.resize(dataSize); uint256 hashIn; // read data and checksum from file try { filein.read((char *)&vchData[0], dataSize); filein >> hashIn; } catch(std::exception &e) { return(error("CAddrDB::Read() : I/O error")); } filein.fclose(); CDataStream ssPeers(vchData, SER_DISK, CLIENT_VERSION); // verify stored checksum matches input data uint256 hashTmp = Hash(ssPeers.begin(), ssPeers.end()); if(hashIn != hashTmp) return(error("CAddrDB::Read() : checksum mismatch")); // de-serialize address data unsigned char pchMsgTmp[4]; try { ssPeers >> FLATDATA(pchMsgTmp); ssPeers >> addr; } catch(std::exception &e) { return(error("CAddrDB::Read() #2 : I/O error")); } // finally, verify the network matches ours if(memcmp(pchMsgTmp, pchMessageStart, sizeof(pchMsgTmp))) return(error("CAddrDB::Read() : invalid network magic number")); return(true); }
bool CAddrDB::Write(const CAddrMan& addr) { // Generate random temporary filename unsigned short randv = 0; RAND_bytes((unsigned char *)&randv, sizeof(randv)); std::string tmpfn = strprintf("peers.dat.%04x", randv); // serialize addresses, checksum data up to that point, then append csum CDataStream ssPeers(SER_DISK, CLIENT_VERSION); //header fix mincoin unsigned char pchMessageStart[4]; GetMessageStart(pchMessageStart,false); ssPeers << FLATDATA(pchMessageStart); ssPeers << addr; uint256 hash = Hash(ssPeers.begin(), ssPeers.end()); ssPeers << hash; // open temp output file, and associate with CAutoFile boost::filesystem::path pathTmp = GetDataDir() / tmpfn; FILE *file = fopen(pathTmp.string().c_str(), "wb"); CAutoFile fileout = CAutoFile(file, SER_DISK, CLIENT_VERSION); if (!fileout) return error("CAddrman::Write() : open failed"); // Write and commit header, data try { fileout << ssPeers; } catch (std::exception &e) { return error("CAddrman::Write() : I/O error"); } FileCommit(fileout); fileout.fclose(); // replace existing peers.dat, if any, with new peers.dat.XXXX if (!RenameOver(pathTmp, pathAddr)) return error("CAddrman::Write() : Rename-into-place failed"); return true; }
bool CRemoteCacheLink::InternalEnsurePipeOpen ( CAutoFile& hPipe , const CString& pipeName) const { if (hPipe) return true; int tryleft = 2; while (!hPipe && tryleft--) { hPipe = CreateFile( pipeName, // pipe name GENERIC_READ | // read and write access GENERIC_WRITE, 0, // no sharing NULL, // default security attributes OPEN_EXISTING, // opens existing pipe FILE_FLAG_OVERLAPPED, // default attributes NULL); // no template file if ((!hPipe) && (GetLastError() == ERROR_PIPE_BUSY)) { // TGitCache is running but is busy connecting a different client. // Do not give up immediately but wait for a few milliseconds until // the server has created the next pipe instance if (!WaitNamedPipe (pipeName, 50)) { continue; } } } if (hPipe) { // The pipe connected; change to message-read mode. DWORD dwMode; dwMode = PIPE_READMODE_MESSAGE; if(!SetNamedPipeHandleState( hPipe, // pipe handle &dwMode, // new pipe mode NULL, // don't set maximum bytes NULL)) // don't set maximum time { CTraceToOutputDebugString::Instance()(__FUNCTION__ ": SetNamedPipeHandleState failed"); hPipe.CloseHandle(); } } return hPipe; }
Value dumpbootstrap(const Array& params, bool fHelp) { if (fHelp || params.size() != 2) throw runtime_error( "dumpbootstrap \"destination\" \"blocks\"\n" "\nCreates a bootstrap format block dump of the blockchain in destination, which can be a directory or a path with filename, up to the given block number."); string strDest = params[0].get_str(); int nBlocks = params[1].get_int(); if (nBlocks < 0 || nBlocks > nBestHeight) throw runtime_error("Block number out of range."); boost::filesystem::path pathDest(strDest); if (boost::filesystem::is_directory(pathDest)) pathDest /= "bootstrap.dat"; try { FILE* file = fopen(pathDest.string().c_str(), "wb"); if (!file) throw JSONRPCError(RPC_MISC_ERROR, "Error: Could not open bootstrap file for writing."); CAutoFile fileout = CAutoFile(file, SER_DISK, CLIENT_VERSION); if (!fileout) throw JSONRPCError(RPC_MISC_ERROR, "Error: Could not open bootstrap file for writing."); for (int nHeight = 0; nHeight <= nBlocks; nHeight++) { CBlock block; CBlockIndex* pblockindex = FindBlockByHeight(nHeight); block.ReadFromDisk(pblockindex, true); fileout << FLATDATA(Params().MessageStart()) << fileout.GetSerializeSize(block) << block; } } catch(const boost::filesystem::filesystem_error &e) { throw JSONRPCError(RPC_MISC_ERROR, "Error: Bootstrap dump failed!"); } return Value::null; }
bool CAddrDB::Write(const CAddrMan& addr) { // Generate random temporary filename Генерация случайного временного файла unsigned short randv = 0; RAND_bytes((unsigned char *)&randv, sizeof(randv)); std::string tmpfn = strprintf("peers.dat.%04x", randv); // serialize addresses, checksum data up to that point, then append csum сериализации адреса, контрольная сумма данных до того момента, затем добавить CSUM CDataStream ssPeers(SER_DISK, CLIENT_VERSION); ssPeers << FLATDATA(Params().MessageStart()); ssPeers << addr; uint256 hash = Hash(ssPeers.begin(), ssPeers.end()); ssPeers << hash; // open temp output file, and associate with CAutoFile открытыть временный выходной файл и ассоциировать с CAutoFile boost::filesystem::path pathTmp = GetDataDir() / tmpfn; FILE *file = fopen(pathTmp.string().c_str(), "wb"); CAutoFile fileout = CAutoFile(file, SER_DISK, CLIENT_VERSION); if (!fileout) return error("CAddrman::Write() : open failed"); // Write and commit header, data запись и фиксация заголовка, данных try { fileout << ssPeers; } catch (std::exception &e) { return error("CAddrman::Write() : I/O error"); } FileCommit(fileout); fileout.fclose(); // replace existing peers.dat, if any, with new peers.dat.XXXX заменить существующие peers.dat, если таковые имеются, новыми peers.dat.XXXX if (!RenameOver(pathTmp, pathAddr)) return error("CAddrman::Write() : Rename-into-place failed"); return true; }
return true; } uint256 CLotData::GetClottoFileHash() { CAutoFile fileout = CAutoFile(OpenFile(0, true), SER_DISK, CLIENT_VERSION); if (!fileout) return error("CLotDB::GetClottoFileHash : open failed"); fseek(fileout, 0, SEEK_END); //move the point to the end of file long filesize = ftell(fileout); //get the file size if (filesize < 0) return error("CLotDB::GetClottoFileHash : ftell failed"); rewind(fileout); //move the point to the start of file vector<unsigned char> vchData; vchData.resize(filesize); try { fileout.read((char *) &vchData[0], filesize); } catch (std::exception &e) { return error("CLotDB::GetClottoFileHash : read failed"); } fileout.fclose();
void CDirectoryWatcher::WorkerThread() { DWORD numBytes; CDirWatchInfo * pdi = NULL; LPOVERLAPPED lpOverlapped; WCHAR buf[READ_DIR_CHANGE_BUFFER_SIZE] = {0}; WCHAR * pFound = NULL; while (m_bRunning) { CleanupWatchInfo(); if (watchedPaths.GetCount()) { // Any incoming notifications? pdi = NULL; numBytes = 0; InterlockedExchange(&m_bCleaned, FALSE); if ((!m_hCompPort) || !GetQueuedCompletionStatus(m_hCompPort, &numBytes, (PULONG_PTR) &pdi, &lpOverlapped, 600000 /*10 minutes*/)) { // No. Still trying? if (!m_bRunning) return; ATLTRACE(_T(": restarting watcher\n")); m_hCompPort.CloseHandle(); // We must sync the whole section because other threads may // receive "AddPath" calls that will delete the completion // port *while* we are adding references to it . AutoLocker lock(m_critSec); // Clear the list of watched objects and recreate that list. // This will also delete the old completion port ClearInfoMap(); CleanupWatchInfo(); for (int i=0; i<watchedPaths.GetCount(); ++i) { CTGitPath watchedPath = watchedPaths[i]; CAutoFile hDir = CreateFile(watchedPath.GetWinPath(), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, //security attributes OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | //required privileges: SE_BACKUP_NAME and SE_RESTORE_NAME. FILE_FLAG_OVERLAPPED, NULL); if (!hDir) { // this could happen if a watched folder has been removed/renamed ATLTRACE(_T("CDirectoryWatcher: CreateFile failed. Can't watch directory %s\n"), watchedPaths[i].GetWinPath()); watchedPaths.RemovePath(watchedPath); break; } DEV_BROADCAST_HANDLE NotificationFilter; SecureZeroMemory(&NotificationFilter, sizeof(NotificationFilter)); NotificationFilter.dbch_size = sizeof(DEV_BROADCAST_HANDLE); NotificationFilter.dbch_devicetype = DBT_DEVTYP_HANDLE; NotificationFilter.dbch_handle = hDir; // RegisterDeviceNotification sends a message to the UI thread: // make sure we *can* send it and that the UI thread isn't waiting on a lock int numPaths = watchedPaths.GetCount(); size_t numWatch = watchInfoMap.size(); lock.Unlock(); NotificationFilter.dbch_hdevnotify = RegisterDeviceNotification(hWnd, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE); lock.Lock(); // since we released the lock to prevent a deadlock with the UI thread, // it could happen that new paths were added to watch, or another thread // could have cleared our info map. // if that happened, we have to restart watching all paths again. if ((numPaths != watchedPaths.GetCount()) || (numWatch != watchInfoMap.size())) { ClearInfoMap(); CleanupWatchInfo(); Sleep(200); break; } CDirWatchInfo * pDirInfo = new CDirWatchInfo(hDir, watchedPath); hDir.Detach(); // the new CDirWatchInfo object owns the handle now pDirInfo->m_hDevNotify = NotificationFilter.dbch_hdevnotify; HANDLE port = CreateIoCompletionPort(pDirInfo->m_hDir, m_hCompPort, (ULONG_PTR)pDirInfo, 0); if (port == NULL) { ATLTRACE(_T("CDirectoryWatcher: CreateIoCompletionPort failed. Can't watch directory %s\n"), watchedPath.GetWinPath()); // we must close the directory handle to allow ClearInfoMap() // to close the completion port properly pDirInfo->CloseDirectoryHandle(); ClearInfoMap(); CleanupWatchInfo(); delete pDirInfo; pDirInfo = NULL; watchedPaths.RemovePath(watchedPath); break; } m_hCompPort = port; if (!ReadDirectoryChangesW(pDirInfo->m_hDir, pDirInfo->m_Buffer, READ_DIR_CHANGE_BUFFER_SIZE, TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE, &numBytes,// not used &pDirInfo->m_Overlapped, NULL)) //no completion routine! { ATLTRACE(_T("CDirectoryWatcher: ReadDirectoryChangesW failed. Can't watch directory %s\n"), watchedPath.GetWinPath()); // we must close the directory handle to allow ClearInfoMap() // to close the completion port properly pDirInfo->CloseDirectoryHandle(); ClearInfoMap(); CleanupWatchInfo(); delete pDirInfo; pDirInfo = NULL; watchedPaths.RemovePath(watchedPath); break; } ATLTRACE(_T("watching path %s\n"), pDirInfo->m_DirName.GetWinPath()); watchInfoMap[pDirInfo->m_hDir] = pDirInfo; } } else { if (!m_bRunning) return; if (watchInfoMap.empty()) continue; // NOTE: the longer this code takes to execute until ReadDirectoryChangesW // is called again, the higher the chance that we miss some // changes in the file system! if (pdi) { BOOL bRet = false; std::list<CTGitPath> notifyPaths; { AutoLocker lock(m_critSec); // in case the CDirectoryWatcher objects have been cleaned, // the m_bCleaned variable will be set to true here. If the // objects haven't been cleared, we can access them here. if (InterlockedExchange(&m_bCleaned, FALSE)) continue; if ( (!pdi->m_hDir) || watchInfoMap.empty() || (watchInfoMap.find(pdi->m_hDir) == watchInfoMap.end())) { continue; } PFILE_NOTIFY_INFORMATION pnotify = (PFILE_NOTIFY_INFORMATION)pdi->m_Buffer; DWORD nOffset = 0; do { pnotify = (PFILE_NOTIFY_INFORMATION)((LPBYTE)pnotify + nOffset); if ((ULONG_PTR)pnotify - (ULONG_PTR)pdi->m_Buffer > READ_DIR_CHANGE_BUFFER_SIZE) break; nOffset = pnotify->NextEntryOffset; if (pnotify->FileNameLength >= (READ_DIR_CHANGE_BUFFER_SIZE*sizeof(TCHAR))) continue; SecureZeroMemory(buf, READ_DIR_CHANGE_BUFFER_SIZE*sizeof(TCHAR)); _tcsncpy_s(buf, pdi->m_DirPath, _countof(buf) - 1); errno_t err = _tcsncat_s(buf + pdi->m_DirPath.GetLength(), READ_DIR_CHANGE_BUFFER_SIZE-pdi->m_DirPath.GetLength(), pnotify->FileName, min(READ_DIR_CHANGE_BUFFER_SIZE-pdi->m_DirPath.GetLength(), pnotify->FileNameLength/sizeof(TCHAR))); if (err == STRUNCATE) { continue; } buf[(pnotify->FileNameLength/sizeof(TCHAR))+pdi->m_DirPath.GetLength()] = 0; if (m_FolderCrawler) { if ((pFound = wcsstr(buf, L"\\tmp")) != NULL) { pFound += 4; if (((*pFound)=='\\')||((*pFound)=='\0')) { continue; } } if ((pFound = wcsstr(buf, L":\\RECYCLER\\")) != NULL) { if ((pFound-buf) < 5) { // a notification for the recycle bin - ignore it continue; } } if ((pFound = wcsstr(buf, L":\\$Recycle.Bin\\")) != NULL) { if ((pFound-buf) < 5) { // a notification for the recycle bin - ignore it continue; } } if (wcsstr(buf, L".tmp") != NULL) { // assume files with a .tmp extension are not versioned and interesting, // so ignore them. continue; } CTGitPath path; bool isIndex = false; if ((pFound = wcsstr(buf, L".git")) != NULL) { // omit repository data change except .git/index.lock- or .git/HEAD.lock-files if ((ULONG_PTR)pnotify - (ULONG_PTR)pdi->m_Buffer > READ_DIR_CHANGE_BUFFER_SIZE) break; path = g_AdminDirMap.GetWorkingCopy(CTGitPath(buf).GetContainingDirectory().GetWinPathString()); if ((wcsstr(pFound, L"index.lock") != NULL || wcsstr(pFound, L"HEAD.lock") != NULL) && pnotify->Action == FILE_ACTION_ADDED) { CGitStatusCache::Instance().BlockPath(path); continue; } else if (((wcsstr(pFound, L"index.lock") != NULL || wcsstr(pFound, L"HEAD.lock") != NULL) && pnotify->Action == FILE_ACTION_REMOVED) || (((wcsstr(pFound, L"index") != NULL && wcsstr(pFound, L"index.lock") == NULL) || (wcsstr(pFound, L"HEAD") != NULL && wcsstr(pFound, L"HEAD.lock") != NULL)) && pnotify->Action == FILE_ACTION_MODIFIED) || ((wcsstr(pFound, L"index.lock") == NULL || wcsstr(pFound, L"HEAD.lock") != NULL) && pnotify->Action == FILE_ACTION_RENAMED_NEW_NAME)) { isIndex = true; CGitStatusCache::Instance().BlockPath(path, 1); } else { continue; } } else path.SetFromUnknown(buf); if(!path.HasAdminDir() && !isIndex) continue; ATLTRACE(_T("change notification: %s\n"), buf); notifyPaths.push_back(path); } } while ((nOffset > 0)&&(nOffset < READ_DIR_CHANGE_BUFFER_SIZE)); // setup next notification cycle SecureZeroMemory (pdi->m_Buffer, sizeof(pdi->m_Buffer)); SecureZeroMemory (&pdi->m_Overlapped, sizeof(OVERLAPPED)); bRet = ReadDirectoryChangesW(pdi->m_hDir, pdi->m_Buffer, READ_DIR_CHANGE_BUFFER_SIZE, TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE, &numBytes,// not used &pdi->m_Overlapped, NULL); //no completion routine! } if (!notifyPaths.empty()) { for (std::list<CTGitPath>::const_iterator nit = notifyPaths.begin(); nit != notifyPaths.end(); ++nit) { m_FolderCrawler->AddPathForUpdate(*nit); } } // any clean-up to do? CleanupWatchInfo(); if (!bRet) { // Since the call to ReadDirectoryChangesW failed, just // wait a while. We don't want to have this thread // running using 100% CPU if something goes completely // wrong. Sleep(200); } } } }// if (watchedPaths.GetCount()) else Sleep(200); }// while (m_bRunning) }
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; }
DWORD WINAPI CommandWaitThread(LPVOID lpvParam) { ATLTRACE("CommandWaitThread started\n"); bool * bRun = (bool *)lpvParam; // The main loop creates an instance of the named pipe and // then waits for a client to connect to it. When the client // connects, a thread is created to handle communications // with that client, and the loop is repeated. DWORD dwThreadId; BOOL fConnected; CAutoFile hPipe; while (*bRun) { hPipe = CreateNamedPipe( GetCacheCommandPipeName(), PIPE_ACCESS_DUPLEX, // read/write access PIPE_TYPE_MESSAGE | // message type pipe PIPE_READMODE_MESSAGE | // message-read mode PIPE_WAIT, // blocking mode PIPE_UNLIMITED_INSTANCES, // max. instances BUFSIZE, // output buffer size BUFSIZE, // input buffer size NMPWAIT_USE_DEFAULT_WAIT, // client time-out NULL); // NULL DACL if (!hPipe) { //OutputDebugStringA("TSVNCache: CreatePipe failed\n"); //DebugOutputLastError(); if (*bRun) Sleep(200); continue; // never leave the thread! } // Wait for the client to connect; if it succeeds, // the function returns a nonzero value. If the function returns // zero, GetLastError returns ERROR_PIPE_CONNECTED. fConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); if (fConnected) { // Create a thread for this client. CAutoGeneralHandle hCommandThread = CreateThread( NULL, // no security attribute 0, // default stack size CommandThread, (HANDLE) hPipe, // thread parameter 0, // not suspended &dwThreadId); // returns thread ID if (!hCommandThread) { //OutputDebugStringA("TSVNCache: Could not create Command thread\n"); //DebugOutputLastError(); DisconnectNamedPipe(hPipe); hPipe.CloseHandle(); // since we're now closing this thread, we also have to close the whole application! // otherwise the thread is dead, but the app is still running, refusing new instances // but no pipe will be available anymore. PostMessage(hWnd, WM_CLOSE, 0, 0); return 1; } // detach the handle, since we passed it to the thread hPipe.Detach(); } else { // The client could not connect, so close the pipe. //OutputDebugStringA("TSVNCache: ConnectNamedPipe failed\n"); //DebugOutputLastError(); hPipe.CloseHandle(); if (*bRun) Sleep(200); continue; // don't end the thread! } } ATLTRACE("CommandWait thread exited\n"); return 0; }
bool CPicture::Load(tstring sFilePathName) { bool bResult = false; bIsIcon = false; lpIcons = NULL; //CFile PictureFile; //CFileException e; FreePictureData(); // Important - Avoid Leaks... // No-op if no file specified if (sFilePathName.empty()) return true; // Load & initialize the GDI+ library if available HMODULE hGdiPlusLib = AtlLoadSystemLibraryUsingFullPath(_T("gdiplus.dll")); if (hGdiPlusLib && GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) == Ok) { bHaveGDIPlus = true; } // Since we loaded the gdiplus.dll only to check if it's available, we // can safely free the library here again - GdiplusStartup() loaded it too // and reference counting will make sure that it stays loaded until GdiplusShutdown() // is called. FreeLibrary(hGdiPlusLib); // Attempt to load using GDI+ if available if (bHaveGDIPlus) { pBitmap = new Bitmap(sFilePathName.c_str(), FALSE); GUID guid; pBitmap->GetRawFormat(&guid); if (pBitmap->GetLastStatus() != Ok) { delete pBitmap; pBitmap = NULL; } // gdiplus only loads the first icon found in an icon file // so we have to handle icon files ourselves :( // Even though gdiplus can load icons, it can't load the new // icons from Vista - in Vista, the icon format changed slightly. // But the LoadIcon/LoadImage API still can load those icons, // at least those dimensions which are also used on pre-Vista // systems. // For that reason, we don't rely on gdiplus telling us if // the image format is "icon" or not, we also check the // file extension for ".ico". std::transform(sFilePathName.begin(), sFilePathName.end(), sFilePathName.begin(), ::tolower); bIsIcon = (guid == ImageFormatIcon) || (wcsstr(sFilePathName.c_str(), L".ico") != NULL) || (wcsstr(sFilePathName.c_str(), L".cur") != NULL); bIsTiff = (guid == ImageFormatTIFF) || (_tcsstr(sFilePathName.c_str(), _T(".tiff")) != NULL); m_Name = sFilePathName; if (bIsIcon) { // Icon file, get special treatment... if (pBitmap) { // Cleanup first... delete (pBitmap); pBitmap = NULL; bIsIcon = true; } CAutoFile hFile = CreateFile(sFilePathName.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile) { BY_HANDLE_FILE_INFORMATION fileinfo; if (GetFileInformationByHandle(hFile, &fileinfo)) { lpIcons = new BYTE[fileinfo.nFileSizeLow]; DWORD readbytes; if (ReadFile(hFile, lpIcons, fileinfo.nFileSizeLow, &readbytes, NULL)) { // we have the icon. Now gather the information we need later if (readbytes >= sizeof(ICONDIR)) { // we are going to open same file second time so we have to close the file now hFile.CloseHandle(); LPICONDIR lpIconDir = (LPICONDIR)lpIcons; if ((lpIconDir->idCount) && ((lpIconDir->idCount * sizeof(ICONDIR)) <= fileinfo.nFileSizeLow)) { try { bResult = false; nCurrentIcon = 0; hIcons = new HICON[lpIconDir->idCount]; // check that the pointers point to data that we just loaded if (((BYTE*)lpIconDir->idEntries > (BYTE*)lpIconDir) && (((BYTE*)lpIconDir->idEntries) + (lpIconDir->idCount * sizeof(ICONDIRENTRY)) < ((BYTE*)lpIconDir) + fileinfo.nFileSizeLow)) { m_Width = lpIconDir->idEntries[0].bWidth; m_Height = lpIconDir->idEntries[0].bHeight; bResult = true; for (int i=0; i<lpIconDir->idCount; ++i) { hIcons[i] = (HICON)LoadImage(NULL, sFilePathName.c_str(), IMAGE_ICON, lpIconDir->idEntries[i].bWidth, lpIconDir->idEntries[i].bHeight, LR_LOADFROMFILE); if (hIcons[i] == NULL) { // if the icon couldn't be loaded, the data is most likely corrupt delete [] lpIcons; lpIcons = NULL; bResult = false; break; } } } } catch (...) { delete [] lpIcons; lpIcons = NULL; bResult = false; } } else { delete [] lpIcons; lpIcons = NULL; bResult = false; } } else { delete [] lpIcons; lpIcons = NULL; bResult = false; } } else { delete [] lpIcons; lpIcons = NULL; } } } } else if (pBitmap) // Image loaded successfully with GDI+ { m_Height = pBitmap->GetHeight(); m_Width = pBitmap->GetWidth(); bResult = true; } // If still failed to load the file... if (!bResult) { // Attempt to load the FreeImage library as an optional DLL to support additional formats // NOTE: Currently just loading via FreeImage & using GDI+ for drawing. // It might be nice to remove this dependency in the future. HMODULE hFreeImageLib = LoadLibrary(_T("FreeImage.dll")); // FreeImage DLL functions typedef const char* (__stdcall *FreeImage_GetVersion_t)(void); typedef int (__stdcall *FreeImage_GetFileType_t)(const TCHAR *filename, int size); typedef int (__stdcall *FreeImage_GetFIFFromFilename_t)(const TCHAR *filename); typedef void* (__stdcall *FreeImage_Load_t)(int format, const TCHAR *filename, int flags); typedef void (__stdcall *FreeImage_Unload_t)(void* dib); typedef int (__stdcall *FreeImage_GetColorType_t)(void* dib); typedef unsigned (__stdcall *FreeImage_GetWidth_t)(void* dib); typedef unsigned (__stdcall *FreeImage_GetHeight_t)(void* dib); typedef void (__stdcall *FreeImage_ConvertToRawBits_t)(BYTE *bits, void *dib, int pitch, unsigned bpp, unsigned red_mask, unsigned green_mask, unsigned blue_mask, BOOL topdown); //FreeImage_GetVersion_t FreeImage_GetVersion = NULL; FreeImage_GetFileType_t FreeImage_GetFileType = NULL; FreeImage_GetFIFFromFilename_t FreeImage_GetFIFFromFilename = NULL; FreeImage_Load_t FreeImage_Load = NULL; FreeImage_Unload_t FreeImage_Unload = NULL; //FreeImage_GetColorType_t FreeImage_GetColorType = NULL; FreeImage_GetWidth_t FreeImage_GetWidth = NULL; FreeImage_GetHeight_t FreeImage_GetHeight = NULL; FreeImage_ConvertToRawBits_t FreeImage_ConvertToRawBits = NULL; if (hFreeImageLib) { bool exportsValid = true; //FreeImage_GetVersion = (FreeImage_GetVersion_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetVersion@0", valid); FreeImage_GetWidth = (FreeImage_GetWidth_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetWidth@4", exportsValid); FreeImage_GetHeight = (FreeImage_GetHeight_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetHeight@4", exportsValid); FreeImage_Unload = (FreeImage_Unload_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_Unload@4", exportsValid); FreeImage_ConvertToRawBits = (FreeImage_ConvertToRawBits_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_ConvertToRawBits@32", exportsValid); #ifdef UNICODE FreeImage_GetFileType = (FreeImage_GetFileType_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFileTypeU@8", exportsValid); FreeImage_GetFIFFromFilename = (FreeImage_GetFIFFromFilename_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFIFFromFilenameU@4", exportsValid); FreeImage_Load = (FreeImage_Load_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_LoadU@12", exportsValid); #else FreeImage_GetFileType = (FreeImage_GetFileType_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFileType@8", exportsValid); FreeImage_GetFIFFromFilename = (FreeImage_GetFIFFromFilename_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_GetFIFFromFilename@4", exportsValid); FreeImage_Load = (FreeImage_Load_t)s_GetProcAddressEx(hFreeImageLib, "_FreeImage_Load@12", exportsValid); #endif //const char* version = FreeImage_GetVersion(); // Check the DLL is using compatible exports if (exportsValid) { // Derive file type from file header. int fileType = FreeImage_GetFileType(sFilePathName.c_str(), 0); if (fileType < 0) { // No file header available, attempt to parse file name for extension. fileType = FreeImage_GetFIFFromFilename(sFilePathName.c_str()); } // If we have a valid file type if (fileType >= 0) { void* dib = FreeImage_Load(fileType, sFilePathName.c_str(), 0); if (dib) { unsigned width = FreeImage_GetWidth(dib); unsigned height = FreeImage_GetHeight(dib); // Create a GDI+ bitmap to load into... pBitmap = new Bitmap(width, height, PixelFormat32bppARGB); if (pBitmap && pBitmap->GetLastStatus() == Ok) { // Write & convert the loaded data into the GDI+ Bitmap Rect rect(0, 0, width, height); BitmapData bitmapData; if (pBitmap->LockBits(&rect, ImageLockModeWrite, PixelFormat32bppARGB, &bitmapData) == Ok) { FreeImage_ConvertToRawBits((BYTE*)bitmapData.Scan0, dib, bitmapData.Stride, 32, 0xff << RED_SHIFT, 0xff << GREEN_SHIFT, 0xff << BLUE_SHIFT, FALSE); pBitmap->UnlockBits(&bitmapData); m_Width = width; m_Height = height; bResult = true; } else // Failed to lock the destination Bitmap { delete pBitmap; pBitmap = NULL; } } else // Bitmap allocation failed { delete pBitmap; pBitmap = NULL; } FreeImage_Unload(dib); dib = NULL; } } } FreeLibrary(hFreeImageLib); hFreeImageLib = NULL; } } }
CMasternodeDB::ReadResult CMasternodeDB::Read(CMasternodeMan& mnodemanToLoad) { int64_t nStart = GetTimeMillis(); // open input file, and associate with CAutoFile FILE *file = fopen(pathMN.string().c_str(), "rb"); CAutoFile filein = CAutoFile(file, SER_DISK, CLIENT_VERSION); if (!filein) { error("%s : Failed to open file %s", __func__, pathMN.string()); return FileError; } // use file size to size memory buffer int fileSize = boost::filesystem::file_size(pathMN); int dataSize = fileSize - sizeof(uint256); // Don't try to resize to a negative number if file is small if (dataSize < 0) dataSize = 0; vector<unsigned char> vchData; vchData.resize(dataSize); uint256 hashIn; // read data and checksum from file try { filein.read((char *)&vchData[0], dataSize); filein >> hashIn; } catch (std::exception &e) { error("%s : Deserialize or I/O error - %s", __func__, e.what()); return HashReadError; } filein.fclose(); CDataStream ssMasternodes(vchData, SER_DISK, CLIENT_VERSION); // verify stored checksum matches input data uint256 hashTmp = Hash(ssMasternodes.begin(), ssMasternodes.end()); if (hashIn != hashTmp) { error("%s : Checksum mismatch, data corrupted", __func__); return IncorrectHash; } unsigned char pchMsgTmp[4]; try { // de-serialize file header (network specific magic number) and .. ssMasternodes >> FLATDATA(pchMsgTmp); // ... verify the network matches ours if (memcmp(pchMsgTmp, Params().MessageStart(), sizeof(pchMsgTmp))) { error("%s : Invalid network magic number", __func__); return IncorrectMagic; } // de-serialize address data into one CMnList object ssMasternodes >> mnodemanToLoad; } catch (std::exception &e) { mnodemanToLoad.Clear(); error("%s : Deserialize or I/O error - %s", __func__, e.what()); return IncorrectFormat; } mnodemanToLoad.CheckAndRemove(); // clean out expired LogPrintf("Loaded info from mncache.dat %dms\n", GetTimeMillis() - nStart); LogPrintf(" %s\n", mnodemanToLoad.ToString()); return Ok; }
void CPathWatcher::WorkerThread() { DWORD numBytes; CDirWatchInfo * pdi = NULL; LPOVERLAPPED lpOverlapped; WCHAR buf[MAX_PATH*4] = {0}; while (m_bRunning) { if (watchedPaths.GetCount()) { if (!GetQueuedCompletionStatus(m_hCompPort, &numBytes, (PULONG_PTR) &pdi, &lpOverlapped, INFINITE)) { // Error retrieving changes // Clear the list of watched objects and recreate that list if (!m_bRunning) return; { AutoLocker lock(m_critSec); ClearInfoMap(); } DWORD lasterr = GetLastError(); if ((m_hCompPort)&&(lasterr!=ERROR_SUCCESS)&&(lasterr!=ERROR_INVALID_HANDLE)) { m_hCompPort.CloseHandle(); } // Since we pass m_hCompPort to CreateIoCompletionPort, we // have to set this to NULL to have that API create a new // handle. m_hCompPort = NULL; for (int i=0; i<watchedPaths.GetCount(); ++i) { CAutoFile hDir = CreateFile(watchedPaths[i].GetWinPath(), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, //security attributes OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | //required privileges: SE_BACKUP_NAME and SE_RESTORE_NAME. FILE_FLAG_OVERLAPPED, NULL); if (!hDir) { // this could happen if a watched folder has been removed/renamed m_hCompPort.CloseHandle(); AutoLocker lock(m_critSec); watchedPaths.RemovePath(watchedPaths[i]); i--; if (i<0) i=0; break; } CDirWatchInfo * pDirInfo = new CDirWatchInfo(hDir, watchedPaths[i]); hDir.Detach(); // the new CDirWatchInfo object owns the handle now m_hCompPort = CreateIoCompletionPort(pDirInfo->m_hDir, m_hCompPort, (ULONG_PTR)pDirInfo, 0); if (m_hCompPort == NULL) { AutoLocker lock(m_critSec); ClearInfoMap(); delete pDirInfo; pDirInfo = NULL; watchedPaths.RemovePath(watchedPaths[i]); i--; if (i<0) i=0; break; } if (!ReadDirectoryChangesW(pDirInfo->m_hDir, pDirInfo->m_Buffer, READ_DIR_CHANGE_BUFFER_SIZE, TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE, &numBytes,// not used &pDirInfo->m_Overlapped, NULL)) //no completion routine! { AutoLocker lock(m_critSec); ClearInfoMap(); delete pDirInfo; pDirInfo = NULL; watchedPaths.RemovePath(watchedPaths[i]); i--; if (i<0) i=0; break; } AutoLocker lock(m_critSec); watchInfoMap[pDirInfo->m_hDir] = pDirInfo; ATLTRACE(_T("watching path %s\n"), pDirInfo->m_DirName.GetWinPath()); } } else { if (!m_bRunning) return; // NOTE: the longer this code takes to execute until ReadDirectoryChangesW // is called again, the higher the chance that we miss some // changes in the file system! if (pdi) { if (numBytes == 0) { goto continuewatching; } PFILE_NOTIFY_INFORMATION pnotify = (PFILE_NOTIFY_INFORMATION)pdi->m_Buffer; if ((ULONG_PTR)pnotify - (ULONG_PTR)pdi->m_Buffer > READ_DIR_CHANGE_BUFFER_SIZE) goto continuewatching; DWORD nOffset = pnotify->NextEntryOffset; do { nOffset = pnotify->NextEntryOffset; SecureZeroMemory(buf, MAX_PATH*4*sizeof(TCHAR)); _tcsncpy_s(buf, MAX_PATH*4, pdi->m_DirPath, MAX_PATH*4); errno_t err = _tcsncat_s(buf+pdi->m_DirPath.GetLength(), (MAX_PATH*4)-pdi->m_DirPath.GetLength(), pnotify->FileName, _TRUNCATE); if (err == STRUNCATE) { pnotify = (PFILE_NOTIFY_INFORMATION)((LPBYTE)pnotify + nOffset); continue; } buf[min(MAX_PATH*4-1, pdi->m_DirPath.GetLength()+(pnotify->FileNameLength/sizeof(WCHAR)))] = 0; pnotify = (PFILE_NOTIFY_INFORMATION)((LPBYTE)pnotify + nOffset); ATLTRACE(_T("change notification: %s\n"), buf); m_changedPaths.AddPath(CTGitPath(buf)); if ((ULONG_PTR)pnotify - (ULONG_PTR)pdi->m_Buffer > READ_DIR_CHANGE_BUFFER_SIZE) break; } while (nOffset); continuewatching: SecureZeroMemory(pdi->m_Buffer, sizeof(pdi->m_Buffer)); SecureZeroMemory(&pdi->m_Overlapped, sizeof(OVERLAPPED)); if (!ReadDirectoryChangesW(pdi->m_hDir, pdi->m_Buffer, READ_DIR_CHANGE_BUFFER_SIZE, TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE, &numBytes,// not used &pdi->m_Overlapped, NULL)) //no completion routine! { // Since the call to ReadDirectoryChangesW failed, just // wait a while. We don't want to have this thread // running using 100% CPU if something goes completely // wrong. Sleep(200); } } } }// if (watchedPaths.GetCount()) else Sleep(200); }// while (m_bRunning) }
BOOL CFileTextLines::Load(const CString& sFilePath, int lengthHint /* = 0*/) { m_LineEndings = EOL_AUTOLINE; m_UnicodeType = CFileTextLines::AUTOTYPE; RemoveAll(); m_endings.clear(); if(lengthHint != 0) { Reserve(lengthHint); } if (PathIsDirectory(sFilePath)) { m_sErrorString.Format(IDS_ERR_FILE_NOTAFILE, (LPCTSTR)sFilePath); return FALSE; } if (!PathFileExists(sFilePath)) { //file does not exist, so just return SUCCESS return TRUE; } CAutoFile hFile = CreateFile(sFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); if (!hFile) { SetErrorString(); return FALSE; } LARGE_INTEGER fsize; if (!GetFileSizeEx(hFile, &fsize)) { SetErrorString(); return false; } if (fsize.HighPart) { // file is way too big for us m_sErrorString.LoadString(IDS_ERR_FILE_TOOBIG); return FALSE; } // If new[] was done for type T delete[] must be called on a pointer of type T*, // otherwise the behavior is undefined. // +1 is to address possible truncation when integer division is done wchar_t* pFileBuf = new wchar_t[fsize.LowPart/sizeof(wchar_t) + 1]; DWORD dwReadBytes = 0; if (!ReadFile(hFile, pFileBuf, fsize.LowPart, &dwReadBytes, NULL)) { delete [] pFileBuf; SetErrorString(); return FALSE; } if (m_UnicodeType == CFileTextLines::AUTOTYPE) { m_UnicodeType = this->CheckUnicodeType(pFileBuf, dwReadBytes); } if (m_LineEndings == EOL_AUTOLINE) { m_LineEndings = CheckLineEndings(pFileBuf, min(10000, dwReadBytes)); } hFile.CloseHandle(); if (m_UnicodeType == CFileTextLines::BINARY) { m_sErrorString.Format(IDS_ERR_FILE_BINARY, (LPCTSTR)sFilePath); delete [] pFileBuf; return FALSE; } // we may have to convert the file content if ((m_UnicodeType == UTF8)||(m_UnicodeType == UTF8BOM)) { int ret = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)pFileBuf, dwReadBytes, NULL, 0); wchar_t * pWideBuf = new wchar_t[ret]; int ret2 = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)pFileBuf, dwReadBytes, pWideBuf, ret); if (ret2 == ret) { delete [] pFileBuf; pFileBuf = pWideBuf; dwReadBytes = ret2; } else delete [] pWideBuf; } else if (m_UnicodeType == ASCII) { int ret = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR)pFileBuf, dwReadBytes, NULL, 0); wchar_t * pWideBuf = new wchar_t[ret]; int ret2 = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (LPCSTR)pFileBuf, dwReadBytes, pWideBuf, ret); if (ret2 == ret) { delete [] pFileBuf; pFileBuf = pWideBuf; dwReadBytes = ret2; } else delete [] pWideBuf; } // fill in the lines into the array wchar_t * pTextBuf = pFileBuf; wchar_t * pLineStart = pFileBuf; if (m_UnicodeType == UNICODE_LE) { // UTF16 have two bytes per char dwReadBytes/=2; } if ((m_UnicodeType == UTF8BOM)||(m_UnicodeType == UNICODE_LE)) { // ignore the BOM ++pTextBuf; ++pLineStart; --dwReadBytes; } for (DWORD i = 0; i<dwReadBytes; ++i) { if (*pTextBuf == '\r') { if ((i + 1) < dwReadBytes) { if (*(pTextBuf+1) == '\n') { // crlf line ending CString line(pLineStart, (int)(pTextBuf-pLineStart)); Add(line, EOL_CRLF); pLineStart = pTextBuf+2; ++pTextBuf; ++i; } else { // cr line ending CString line(pLineStart, (int)(pTextBuf-pLineStart)); Add(line, EOL_CR); pLineStart =pTextBuf+1; } } } else if (*pTextBuf == '\n') { // lf line ending CString line(pLineStart, (int)(pTextBuf-pLineStart)); Add(line, EOL_LF); pLineStart =pTextBuf+1; } ++pTextBuf; } if (pLineStart < pTextBuf) { CString line(pLineStart, (int)(pTextBuf-pLineStart)); Add(line, EOL_NOENDING); m_bReturnAtEnd = false; } else m_bReturnAtEnd = true; delete [] pFileBuf; return TRUE; }