From ef58358852caa28ec0dd778e8d6f1b383716be44 Mon Sep 17 00:00:00 2001 From: irwir Date: Fri, 18 Aug 2023 18:09:21 +0300 Subject: [PATCH] Using I/O completion ports for disk operations Improve handling of UNC paths Minor GUI enhancements --- mbedtls/include/mbedtls/threading_alt.h | 17 + srchybrid/3DPreviewControl.h | 1 - srchybrid/AICHSyncThread.cpp | 39 +- srchybrid/AICHSyncThread.h | 2 +- srchybrid/AbstractFile.cpp | 32 +- srchybrid/AbstractFile.h | 62 +- srchybrid/AddFriend.cpp | 14 +- srchybrid/AddFriend.h | 2 +- srchybrid/AddSourceDlg.cpp | 17 +- srchybrid/AddSourceDlg.h | 4 +- srchybrid/ArchivePreviewDlg.cpp | 90 +- srchybrid/ArchivePreviewDlg.h | 3 +- srchybrid/ArchiveRecovery.cpp | 317 +- srchybrid/ArchiveRecovery.h | 23 +- srchybrid/AsyncProxySocketLayer.cpp | 22 +- srchybrid/AsyncProxySocketLayer.h | 2 +- srchybrid/AsyncSocketEx.cpp | 130 +- srchybrid/AsyncSocketEx.h | 7 +- srchybrid/AsyncSocketExLayer.cpp | 8 +- srchybrid/AsyncSocketExLayer.h | 2 +- srchybrid/BarShader.cpp | 14 +- srchybrid/BarShader.h | 13 +- srchybrid/BaseClient.cpp | 224 +- srchybrid/BuddyButton.cpp | 4 +- srchybrid/ButtonsTabCtrl.cpp | 2 +- srchybrid/ButtonsTabCtrl.h | 1 - srchybrid/CaptchaGenerator.cpp | 13 +- srchybrid/CaptchaGenerator.h | 2 +- srchybrid/CatDialog.cpp | 39 +- srchybrid/CatDialog.h | 4 +- srchybrid/ChatSelector.cpp | 42 +- srchybrid/ChatSelector.h | 5 +- srchybrid/ChatWnd.cpp | 32 +- srchybrid/ChatWnd.h | 2 +- srchybrid/ClientCredits.cpp | 159 +- srchybrid/ClientCredits.h | 30 +- srchybrid/ClientDetailDialog.cpp | 5 +- srchybrid/ClientDetailDialog.h | 4 +- srchybrid/ClientList.cpp | 195 +- srchybrid/ClientList.h | 27 +- srchybrid/ClientListCtrl.cpp | 187 +- srchybrid/ClientListCtrl.h | 4 +- srchybrid/ClientStateDefs.h | 4 +- srchybrid/ClientUDPSocket.cpp | 221 +- srchybrid/ClientUDPSocket.h | 6 +- srchybrid/ClientVersionInfo.h | 68 +- srchybrid/ClosableTabCtrl.cpp | 2 +- srchybrid/ClosableTabCtrl.h | 1 - srchybrid/Collection.cpp | 214 +- srchybrid/Collection.h | 22 +- srchybrid/CollectionCreateDialog.cpp | 55 +- srchybrid/CollectionCreateDialog.h | 2 +- srchybrid/CollectionFile.cpp | 16 +- srchybrid/CollectionFile.h | 7 +- srchybrid/CollectionListCtrl.cpp | 28 +- srchybrid/CollectionListCtrl.h | 4 +- srchybrid/CollectionViewDialog.cpp | 44 +- srchybrid/CollectionViewDialog.h | 4 +- srchybrid/ColorButton.cpp | 13 +- srchybrid/ColorButton.h | 6 +- srchybrid/ColourPopup.cpp | 18 +- srchybrid/ComboBoxEx2.cpp | 2 +- srchybrid/ComboBoxEx2.h | 1 - srchybrid/CommentDialog.cpp | 4 +- srchybrid/CommentDialog.h | 1 - srchybrid/CommentDialogLst.cpp | 11 +- srchybrid/CommentDialogLst.h | 1 - srchybrid/CommentListCtrl.cpp | 33 +- srchybrid/CommentListCtrl.h | 3 +- srchybrid/CorruptionBlackBox.cpp | 321 +- srchybrid/CorruptionBlackBox.h | 4 +- srchybrid/CreditsDlg.cpp | 2 +- srchybrid/CreditsThread.cpp | 40 +- srchybrid/CreditsThread.h | 2 - srchybrid/CustomAutoComplete.cpp | 103 +- srchybrid/CustomAutoComplete.h | 11 +- srchybrid/DeadSourceList.cpp | 117 +- srchybrid/DeadSourceList.h | 38 +- srchybrid/DebugHelpers.h | 6 +- srchybrid/Debug_FileSize.h | 6 +- srchybrid/DialogMinTrayBtn.cpp | 36 +- srchybrid/DialogMinTrayBtn.h | 4 +- srchybrid/DirectDownloadDlg.cpp | 23 +- srchybrid/DirectDownloadDlg.h | 2 +- srchybrid/DirectoryTreeCtrl.cpp | 186 +- srchybrid/DirectoryTreeCtrl.h | 18 +- srchybrid/DownloadClient.cpp | 918 +++-- srchybrid/DownloadClientsCtrl.cpp | 227 +- srchybrid/DownloadClientsCtrl.h | 4 +- srchybrid/DownloadListCtrl.cpp | 631 ++-- srchybrid/DownloadListCtrl.h | 10 +- srchybrid/DownloadQueue.cpp | 444 ++- srchybrid/DownloadQueue.h | 49 +- srchybrid/Drawgdix.h | 6 +- srchybrid/DropDownButton.cpp | 6 +- srchybrid/DropDownButton.h | 3 +- srchybrid/DropTarget.cpp | 74 +- srchybrid/ED2KLink.cpp | 261 +- srchybrid/ED2kLinkDlg.cpp | 2 +- srchybrid/ED2kLinkDlg.h | 3 +- srchybrid/EMSocket.cpp | 293 +- srchybrid/EMSocket.h | 6 +- srchybrid/EditDelayed.cpp | 59 +- srchybrid/EditDelayed.h | 4 +- srchybrid/EditX.cpp | 2 +- srchybrid/Emule.cpp | 260 +- srchybrid/Emule.h | 7 +- srchybrid/EmuleDlg.cpp | 359 +- srchybrid/EmuleDlg.h | 18 +- srchybrid/EnBitmap.cpp | 82 +- srchybrid/EnBitmap.h | 1 - srchybrid/EncryptedDatagramSocket.cpp | 46 +- srchybrid/EncryptedDatagramSocket.h | 4 +- srchybrid/EncryptedStreamSocket.cpp | 17 +- srchybrid/EncryptedStreamSocket.h | 6 +- srchybrid/Exceptions.h | 2 +- srchybrid/ExitBox.cpp | 2 +- srchybrid/ExitBox.h | 3 +- srchybrid/FileDetailDialog.cpp | 4 +- srchybrid/FileDetailDialog.h | 3 +- srchybrid/FileDetailDialogInfo.cpp | 46 +- srchybrid/FileDetailDialogInfo.h | 1 - srchybrid/FileDetailDialogName.cpp | 43 +- srchybrid/FileDetailDialogName.h | 1 - srchybrid/FileDetailDlgStatistics.cpp | 5 +- srchybrid/FileDetailDlgStatistics.h | 3 +- srchybrid/FileIdentifier.cpp | 123 +- srchybrid/FileIdentifier.h | 21 +- srchybrid/FileInfoDialog.cpp | 809 ++--- srchybrid/FileInfoDialog.h | 8 +- srchybrid/FirewallOpener.cpp | 7 +- srchybrid/FirewallOpener.h | 2 +- srchybrid/Flex.skl | 4 +- srchybrid/FrameGrabThread.cpp | 97 +- srchybrid/FrameGrabThread.h | 6 +- srchybrid/Friend.cpp | 45 +- srchybrid/Friend.h | 29 +- srchybrid/FriendList.cpp | 19 +- srchybrid/FriendList.h | 4 +- srchybrid/FriendListCtrl.cpp | 40 +- srchybrid/FriendListCtrl.h | 3 +- srchybrid/GDIThread.cpp | 2 +- srchybrid/GZipFile.cpp | 12 +- srchybrid/GZipFile.h | 2 +- srchybrid/GradientStatic.cpp | 10 +- srchybrid/HTRichEditCtrl.cpp | 69 +- srchybrid/HTRichEditCtrl.h | 6 +- srchybrid/HttpClientReqSocket.cpp | 35 +- srchybrid/HttpClientReqSocket.h | 5 +- srchybrid/HttpDownloadDlg.cpp | 22 +- srchybrid/I18n.cpp | 144 +- srchybrid/IESecurity.cpp | 50 +- srchybrid/IESecurity.h | 2 + srchybrid/IPFilter.cpp | 64 +- srchybrid/IPFilter.h | 14 +- srchybrid/IPFilterDlg.cpp | 47 +- srchybrid/IconStatic.cpp | 2 +- srchybrid/Ini2.cpp | 58 +- srchybrid/Ini2.h | 44 +- srchybrid/InputBox.cpp | 2 +- srchybrid/InputBox.h | 2 +- srchybrid/IrcChannelListCtrl.cpp | 66 +- srchybrid/IrcChannelListCtrl.h | 2 +- srchybrid/IrcChannelTabCtrl.cpp | 89 +- srchybrid/IrcChannelTabCtrl.h | 2 +- srchybrid/IrcMain.cpp | 147 +- srchybrid/IrcMain.h | 2 +- srchybrid/IrcNickListCtrl.cpp | 41 +- srchybrid/IrcNickListCtrl.h | 4 +- srchybrid/IrcSocket.cpp | 12 +- srchybrid/IrcSocket.h | 2 +- srchybrid/IrcWnd.cpp | 78 +- srchybrid/IrcWnd.h | 18 +- srchybrid/KadContactHistogramCtrl.cpp | 12 +- srchybrid/KadContactHistogramCtrl.h | 1 - srchybrid/KadContactListCtrl.cpp | 68 +- srchybrid/KadContactListCtrl.h | 3 +- srchybrid/KadLookupGraph.cpp | 70 +- srchybrid/KadLookupGraph.h | 2 +- srchybrid/KadSearchListCtrl.cpp | 94 +- srchybrid/KadSearchListCtrl.h | 3 +- srchybrid/KademliaWnd.cpp | 35 +- srchybrid/KnownFile.cpp | 359 +- srchybrid/KnownFile.h | 19 +- srchybrid/KnownFileList.cpp | 134 +- srchybrid/KnownFileList.h | 6 +- srchybrid/LastCommonRouteFinder.cpp | 493 ++- srchybrid/LastCommonRouteFinder.h | 49 +- srchybrid/LayeredWindowHelperST.cpp | 44 +- srchybrid/LayeredWindowHelperST.h | 12 +- srchybrid/ListBoxST.cpp | 8 +- srchybrid/ListBoxST.h | 3 +- srchybrid/ListCtrlItemWalk.h | 2 +- srchybrid/ListCtrlX.cpp | 35 +- srchybrid/ListCtrlX.h | 1 - srchybrid/ListViewSearchDlg.cpp | 4 +- srchybrid/ListViewWalkerPropertySheet.cpp | 4 +- srchybrid/ListenSocket.cpp | 2967 ++++++++--------- srchybrid/ListenSocket.h | 4 +- srchybrid/Log.cpp | 10 +- srchybrid/MapKey.h | 12 +- srchybrid/Mdump.cpp | 130 +- srchybrid/MediaInfo.cpp | 658 ++-- srchybrid/MediaInfo.h | 2 +- srchybrid/MetaDataDlg.cpp | 60 +- srchybrid/MetaDataDlg.h | 4 +- srchybrid/MeterIcon.cpp | 2 +- srchybrid/MiniMule.cpp | 105 +- srchybrid/MiniMule.h | 2 +- srchybrid/MuleListCtrl.cpp | 190 +- srchybrid/MuleListCtrl.h | 40 +- srchybrid/MuleStatusBarCtrl.cpp | 6 +- srchybrid/MuleStatusBarCtrl.h | 1 - srchybrid/MuleSystrayDlg.cpp | 13 +- srchybrid/MuleToolBarCtrl.cpp | 86 +- srchybrid/NetworkInfoDlg.cpp | 25 +- srchybrid/NetworkInfoDlg.h | 1 - srchybrid/OScopeCtrl.cpp | 178 +- srchybrid/OScopeCtrl.h | 2 +- srchybrid/Opcodes.h | 12 +- srchybrid/OtherFunctions.cpp | 565 ++-- srchybrid/OtherFunctions.h | 69 +- srchybrid/PPgConnection.cpp | 17 +- srchybrid/PPgConnection.h | 1 - srchybrid/PPgDebug.cpp | 2 +- srchybrid/PPgDebug.h | 1 - srchybrid/PPgDirectories.cpp | 107 +- srchybrid/PPgDirectories.h | 5 +- srchybrid/PPgDisplay.cpp | 2 +- srchybrid/PPgDisplay.h | 1 - srchybrid/PPgFiles.cpp | 6 +- srchybrid/PPgFiles.h | 1 - srchybrid/PPgGeneral.cpp | 47 +- srchybrid/PPgGeneral.h | 1 - srchybrid/PPgIRC.cpp | 2 +- srchybrid/PPgIRC.h | 1 - srchybrid/PPgMessages.cpp | 2 +- srchybrid/PPgMessages.h | 3 +- srchybrid/PPgNotify.cpp | 6 +- srchybrid/PPgNotify.h | 1 - srchybrid/PPgProxy.cpp | 4 +- srchybrid/PPgProxy.h | 1 - srchybrid/PPgScheduler.cpp | 8 +- srchybrid/PPgScheduler.h | 1 - srchybrid/PPgSecurity.cpp | 35 +- srchybrid/PPgSecurity.h | 1 - srchybrid/PPgServer.cpp | 2 +- srchybrid/PPgServer.h | 1 - srchybrid/PPgStats.cpp | 6 +- srchybrid/PPgStats.h | 1 - srchybrid/PPgTweaks.cpp | 16 +- srchybrid/PPgTweaks.h | 1 - srchybrid/PPgWebServer.cpp | 20 +- srchybrid/PPgWebServer.h | 1 - srchybrid/PShtWiz1.cpp | 15 +- srchybrid/Packets.cpp | 154 +- srchybrid/Packets.h | 17 +- srchybrid/Parser.cpp | 10 +- srchybrid/Parser.y | 8 +- srchybrid/PartFile.cpp | 1910 ++++++----- srchybrid/PartFile.h | 77 +- srchybrid/PartFileConvert.cpp | 163 +- srchybrid/PartFileConvert.h | 12 +- srchybrid/PartFileWriteThread.cpp | 231 ++ srchybrid/PartFileWriteThread.h | 68 + srchybrid/PeerCacheClient.cpp | 55 +- srchybrid/PeerCacheFinder.cpp | 45 +- srchybrid/PeerCacheFinder.h | 16 +- srchybrid/PeerCacheSocket.h | 2 +- srchybrid/PerfLog.cpp | 12 +- srchybrid/Pinger.cpp | 324 +- srchybrid/Pinger.h | 98 +- srchybrid/Preferences.cpp | 534 ++- srchybrid/Preferences.h | 85 +- srchybrid/PreferencesDlg.cpp | 6 +- srchybrid/PreferencesDlg.h | 1 - srchybrid/Preview.cpp | 107 +- srchybrid/Preview.h | 6 +- srchybrid/PreviewDlg.cpp | 17 +- srchybrid/PreviewDlg.h | 2 +- srchybrid/ProgressCtrlX.cpp | 5 +- srchybrid/ProgressCtrlX.h | 5 +- srchybrid/Quantize.cpp | 183 +- srchybrid/Quantize.h | 27 +- srchybrid/QueueListCtrl.cpp | 202 +- srchybrid/QueueListCtrl.h | 4 +- srchybrid/RARFile.cpp | 2 +- srchybrid/RARFile.h | 12 +- srchybrid/Resource.h | 9 +- srchybrid/RichEditCtrlX.cpp | 8 +- srchybrid/RichEditCtrlX.h | 1 - srchybrid/RichEditStream.cpp | 2 +- srchybrid/RichEditStream.h | 1 - srchybrid/SHA.cpp | 2 +- srchybrid/SHAHashSet.cpp | 168 +- srchybrid/SHAHashSet.h | 26 +- srchybrid/SMTPdialog.cpp | 4 +- srchybrid/SafeFile.cpp | 46 +- srchybrid/SafeFile.h | 18 +- srchybrid/Scanner.cpp | 50 +- srchybrid/Scanner.l | 37 +- srchybrid/Scheduler.cpp | 10 +- srchybrid/Scheduler.h | 4 +- srchybrid/SearchDlg.cpp | 57 +- srchybrid/SearchDlg.h | 9 +- srchybrid/SearchExpr.h | 27 +- srchybrid/SearchFile.cpp | 22 +- srchybrid/SearchFile.h | 12 +- srchybrid/SearchList.cpp | 324 +- srchybrid/SearchList.h | 43 +- srchybrid/SearchListCtrl.cpp | 574 ++-- srchybrid/SearchListCtrl.h | 35 +- srchybrid/SearchParams.h | 36 +- srchybrid/SearchParamsWnd.cpp | 204 +- srchybrid/SearchParamsWnd.h | 3 + srchybrid/SearchResultsWnd.cpp | 329 +- srchybrid/SearchResultsWnd.h | 32 +- srchybrid/SecRunAsUser.cpp | 76 +- srchybrid/SecRunAsUser.h | 6 +- srchybrid/SendMail.cpp | 38 +- srchybrid/Server.cpp | 6 +- srchybrid/Server.h | 6 +- srchybrid/ServerConnect.cpp | 126 +- srchybrid/ServerConnect.h | 8 +- srchybrid/ServerList.cpp | 84 +- srchybrid/ServerList.h | 2 +- srchybrid/ServerListCtrl.cpp | 416 +-- srchybrid/ServerListCtrl.h | 17 +- srchybrid/ServerSocket.cpp | 24 +- srchybrid/ServerSocket.h | 2 +- srchybrid/ServerWnd.cpp | 41 +- srchybrid/ServerWnd.h | 2 +- srchybrid/ShareableFile.cpp | 14 +- srchybrid/ShareableFile.h | 5 +- srchybrid/SharedDirsTreeCtrl.cpp | 385 +-- srchybrid/SharedDirsTreeCtrl.h | 7 +- srchybrid/SharedFileList.cpp | 637 ++-- srchybrid/SharedFileList.h | 33 +- srchybrid/SharedFilesCtrl.cpp | 530 ++- srchybrid/SharedFilesCtrl.h | 4 +- srchybrid/SharedFilesWnd.cpp | 65 +- srchybrid/SharedFilesWnd.h | 3 +- srchybrid/SmileySelector.cpp | 2 +- srchybrid/SmileySelector.h | 3 +- srchybrid/SplashScreen.cpp | 6 +- srchybrid/SplitterControl.cpp | 4 +- srchybrid/SplitterControl.h | 3 +- srchybrid/StatisticFile.cpp | 6 +- srchybrid/StatisticFile.h | 2 +- srchybrid/Statistics.cpp | 136 +- srchybrid/Statistics.h | 48 +- srchybrid/StatisticsDlg.cpp | 1619 +++++---- srchybrid/StatisticsDlg.h | 6 +- srchybrid/StatisticsTree.cpp | 62 +- srchybrid/Stdafx.h | 60 +- srchybrid/StringConversion.cpp | 2 +- srchybrid/StringConversion.h | 2 +- srchybrid/TLSthreading.h | 2 +- srchybrid/TabCtrl.cpp | 26 +- srchybrid/TaskbarNotifier.cpp | 10 +- srchybrid/TextToSpeech.cpp | 6 +- srchybrid/TextToSpeech.h | 2 +- srchybrid/TimeTick.cpp | 24 +- srchybrid/TimeTick.h | 1 - srchybrid/TitleMenu.cpp | 44 +- srchybrid/ToolBarCtrlX.cpp | 41 +- srchybrid/ToolBarCtrlX.h | 5 +- srchybrid/ToolTipCtrlX.cpp | 8 +- srchybrid/ToolTipCtrlX.h | 3 +- srchybrid/ToolbarWnd.cpp | 115 +- srchybrid/ToolbarWnd.h | 12 +- srchybrid/TransferDlg.cpp | 57 +- srchybrid/TransferDlg.h | 21 +- srchybrid/TransferWnd.cpp | 572 ++-- srchybrid/TransferWnd.h | 27 +- srchybrid/TrayDialog.cpp | 60 +- srchybrid/TrayDialog.h | 16 +- srchybrid/TrayMenuBtn.cpp | 6 +- srchybrid/TreeOptionsCtrl.cpp | 91 +- srchybrid/TreeOptionsCtrl.h | 16 +- srchybrid/TreeOptionsCtrlEx.cpp | 18 +- srchybrid/TreeOptionsCtrlEx.h | 5 +- srchybrid/TreePropSheet.cpp | 95 +- srchybrid/TreePropSheet.h | 36 +- srchybrid/TreePropSheetPgFrameDef.cpp | 2 +- srchybrid/UDPSocket.cpp | 51 +- srchybrid/UDPSocket.h | 2 +- srchybrid/UPnPImpl.cpp | 2 +- srchybrid/UPnPImpl.h | 2 +- srchybrid/UPnPImplMiniLib.cpp | 12 +- srchybrid/UPnPImplMiniLib.h | 2 +- srchybrid/UPnPImplWinServ.cpp | 250 +- srchybrid/UPnPImplWinServ.h | 31 +- srchybrid/UPnPImplWrapper.cpp | 4 +- srchybrid/UPnPImplWrapper.h | 2 +- srchybrid/URLClient.cpp | 40 +- srchybrid/URLClient.h | 3 +- srchybrid/UpdownClient.h | 147 +- srchybrid/UploadBandwidthThrottler.cpp | 308 +- srchybrid/UploadBandwidthThrottler.h | 10 +- srchybrid/UploadClient.cpp | 247 +- srchybrid/UploadDiskIOThread.cpp | 663 ++-- srchybrid/UploadDiskIOThread.h | 82 +- srchybrid/UploadListCtrl.cpp | 200 +- srchybrid/UploadListCtrl.h | 9 +- srchybrid/UploadQueue.cpp | 164 +- srchybrid/UploadQueue.h | 9 +- srchybrid/UserMsgs.h | 20 +- srchybrid/Version.cpp | 2 +- srchybrid/Version.h | 15 +- srchybrid/WebServer.cpp | 572 ++-- srchybrid/WebServer.h | 17 +- srchybrid/WebSocket.cpp | 36 +- srchybrid/WebSocket.h | 6 +- srchybrid/Wizard.cpp | 162 +- srchybrid/Wizard.h | 3 - srchybrid/ZIPFile.cpp | 29 +- srchybrid/emule.rc | 76 +- srchybrid/emule.sln | 2 +- srchybrid/emule.vcxproj | 62 +- srchybrid/emule_site_config.h | 15 +- srchybrid/kademlia/io/BufferedFileIO.cpp | 4 +- srchybrid/kademlia/io/BufferedFileIO.h | 4 +- srchybrid/kademlia/io/ByteIO.cpp | 4 +- srchybrid/kademlia/io/ByteIO.h | 4 +- srchybrid/kademlia/io/DataIO.cpp | 167 +- srchybrid/kademlia/io/DataIO.h | 14 +- srchybrid/kademlia/io/FileIO.cpp | 4 +- srchybrid/kademlia/io/FileIO.h | 4 +- srchybrid/kademlia/io/IOException.cpp | 6 +- srchybrid/kademlia/io/IOException.h | 4 +- srchybrid/kademlia/kademlia/Defines.h | 4 +- srchybrid/kademlia/kademlia/Entry.cpp | 82 +- srchybrid/kademlia/kademlia/Entry.h | 6 +- srchybrid/kademlia/kademlia/Error.h | 4 +- srchybrid/kademlia/kademlia/Indexed.cpp | 161 +- srchybrid/kademlia/kademlia/Indexed.h | 2 +- srchybrid/kademlia/kademlia/Kademlia.cpp | 26 +- srchybrid/kademlia/kademlia/Kademlia.h | 4 +- srchybrid/kademlia/kademlia/Prefs.cpp | 30 +- srchybrid/kademlia/kademlia/Prefs.h | 16 +- srchybrid/kademlia/kademlia/Search.cpp | 492 ++- srchybrid/kademlia/kademlia/Search.h | 89 +- srchybrid/kademlia/kademlia/SearchManager.cpp | 120 +- srchybrid/kademlia/kademlia/SearchManager.h | 16 +- srchybrid/kademlia/kademlia/Tag.h | 70 +- .../kademlia/kademlia/UDPFirewallTester.cpp | 16 +- .../kademlia/kademlia/UDPFirewallTester.h | 6 +- .../kademlia/net/KademliaUDPListener.cpp | 270 +- srchybrid/kademlia/net/KademliaUDPListener.h | 8 +- srchybrid/kademlia/net/PacketTracking.cpp | 162 +- srchybrid/kademlia/net/PacketTracking.h | 22 +- srchybrid/kademlia/routing/Contact.cpp | 36 +- srchybrid/kademlia/routing/Contact.h | 18 +- srchybrid/kademlia/routing/Maps.h | 12 +- srchybrid/kademlia/routing/RoutingBin.cpp | 126 +- srchybrid/kademlia/routing/RoutingBin.h | 8 +- srchybrid/kademlia/routing/RoutingZone.cpp | 172 +- srchybrid/kademlia/routing/RoutingZone.h | 14 +- srchybrid/kademlia/utils/KadClientSearcher.h | 7 +- srchybrid/kademlia/utils/KadUDPKey.h | 2 +- srchybrid/kademlia/utils/LookupHistory.cpp | 18 +- srchybrid/kademlia/utils/LookupHistory.h | 8 +- srchybrid/kademlia/utils/MiscUtils.cpp | 10 +- srchybrid/kademlia/utils/MiscUtils.h | 8 +- srchybrid/kademlia/utils/ThreadName.cpp | 4 +- srchybrid/kademlia/utils/ThreadName.h | 4 +- srchybrid/kademlia/utils/UInt128.cpp | 31 +- srchybrid/kademlia/utils/UInt128.h | 8 +- srchybrid/lang/ar_AE.rc | 6 +- srchybrid/lang/ar_AE.vcxproj | 62 +- srchybrid/lang/ba_BA.rc | 4 +- srchybrid/lang/ba_BA.vcxproj | 62 +- srchybrid/lang/bg_BG.rc | 4 +- srchybrid/lang/bg_BG.vcxproj | 62 +- srchybrid/lang/ca_ES.rc | 4 +- srchybrid/lang/ca_ES.vcxproj | 62 +- srchybrid/lang/cz_CZ.rc | 4 +- srchybrid/lang/cz_CZ.vcxproj | 62 +- srchybrid/lang/da_DK.rc | 4 +- srchybrid/lang/da_DK.vcxproj | 62 +- srchybrid/lang/de_DE.rc | 4 +- srchybrid/lang/de_DE.vcxproj | 62 +- srchybrid/lang/el_GR.rc | 4 +- srchybrid/lang/el_GR.vcxproj | 62 +- srchybrid/lang/es_AS.rc | 4 +- srchybrid/lang/es_AS.vcxproj | 62 +- srchybrid/lang/es_ES_T.rc | 4 +- srchybrid/lang/es_ES_T.vcxproj | 62 +- srchybrid/lang/et_EE.rc | 4 +- srchybrid/lang/et_EE.vcxproj | 62 +- srchybrid/lang/fa_IR.rc | 4 +- srchybrid/lang/fa_IR.vcxproj | 62 +- srchybrid/lang/fi_FI.rc | 4 +- srchybrid/lang/fi_FI.vcxproj | 62 +- srchybrid/lang/fr_BR.rc | 6 +- srchybrid/lang/fr_BR.vcxproj | 62 +- srchybrid/lang/fr_FR.rc | 4 +- srchybrid/lang/fr_FR.vcxproj | 62 +- srchybrid/lang/gl_ES.rc | 4 +- srchybrid/lang/gl_ES.vcxproj | 62 +- srchybrid/lang/he_IL.rc | 4 +- srchybrid/lang/he_IL.vcxproj | 62 +- srchybrid/lang/hu_HU.rc | 4 +- srchybrid/lang/hu_HU.vcxproj | 62 +- srchybrid/lang/it_IT.rc | 4 +- srchybrid/lang/it_IT.vcxproj | 62 +- srchybrid/lang/jp_JP.rc | 4 +- srchybrid/lang/jp_JP.vcxproj | 62 +- srchybrid/lang/ko_KR.rc | 4 +- srchybrid/lang/ko_KR.vcxproj | 62 +- srchybrid/lang/lang.rc2 | 2 +- srchybrid/lang/lang.sln | 187 +- srchybrid/lang/lt_LT.rc | 4 +- srchybrid/lang/lt_LT.vcxproj | 62 +- srchybrid/lang/lv_LV.rc | 8 +- srchybrid/lang/lv_LV.vcxproj | 62 +- srchybrid/lang/mt_MT.rc | 4 +- srchybrid/lang/mt_MT.vcxproj | 62 +- srchybrid/lang/nb_NO.rc | 4 +- srchybrid/lang/nb_NO.vcxproj | 62 +- srchybrid/lang/nl_NL.rc | 4 +- srchybrid/lang/nl_NL.vcxproj | 62 +- srchybrid/lang/nn_NO.rc | 4 +- srchybrid/lang/nn_NO.vcxproj | 62 +- srchybrid/lang/pl_PL.rc | 4 +- srchybrid/lang/pl_PL.vcxproj | 62 +- srchybrid/lang/pt_BR.rc | 4 +- srchybrid/lang/pt_BR.vcxproj | 62 +- srchybrid/lang/pt_PT.rc | 4 +- srchybrid/lang/pt_PT.vcxproj | 62 +- srchybrid/lang/ro_RO.rc | 4 +- srchybrid/lang/ro_RO.vcxproj | 62 +- srchybrid/lang/ru_RU.rc | 4 +- srchybrid/lang/ru_RU.vcxproj | 62 +- srchybrid/lang/sl_SI.rc | 4 +- srchybrid/lang/sl_SI.vcxproj | 61 +- srchybrid/lang/sq_AL.rc | 4 +- srchybrid/lang/sq_AL.vcxproj | 61 +- srchybrid/lang/sv_SE.rc | 4 +- srchybrid/lang/sv_SE.vcxproj | 61 +- srchybrid/lang/tr_TR.rc | 4 +- srchybrid/lang/tr_TR.vcxproj | 62 +- srchybrid/lang/ua_UA.rc | 4 +- srchybrid/lang/ua_UA.vcxproj | 62 +- srchybrid/lang/ug_CN.rc | 8 +- srchybrid/lang/ug_CN.vcxproj | 61 +- srchybrid/lang/va_ES.rc | 4 +- srchybrid/lang/va_ES.vcxproj | 61 +- srchybrid/lang/va_ES_RACV.rc | 4 +- srchybrid/lang/va_ES_RACV.vcxproj | 61 +- srchybrid/lang/vi_VN.rc | 4 +- srchybrid/lang/vi_VN.vcxproj | 61 +- srchybrid/lang/zh_CN.rc | 4 +- srchybrid/lang/zh_CN.vcxproj | 61 +- srchybrid/lang/zh_TW.rc | 4 +- srchybrid/lang/zh_TW.vcxproj | 61 +- srchybrid/res/MiniMule.htm | 4 +- srchybrid/res/Mule_Vista.ico | Bin 51918 -> 27086 bytes srchybrid/res/emule.rc2 | 2 +- srchybrid/res/emuleWin32.manifest | 6 +- srchybrid/res/emulex64.manifest | 8 +- 562 files changed, 16870 insertions(+), 20679 deletions(-) create mode 100644 srchybrid/PartFileWriteThread.cpp create mode 100644 srchybrid/PartFileWriteThread.h diff --git a/mbedtls/include/mbedtls/threading_alt.h b/mbedtls/include/mbedtls/threading_alt.h index 820ee0af..b602dbe6 100644 --- a/mbedtls/include/mbedtls/threading_alt.h +++ b/mbedtls/include/mbedtls/threading_alt.h @@ -1,3 +1,20 @@ +//this file is part of eMule +//Copyright (C)2017-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) +// +//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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + #pragma once #ifdef _MSC_VER #include diff --git a/srchybrid/3DPreviewControl.h b/srchybrid/3DPreviewControl.h index 8bda7e9e..df6ea1ec 100644 --- a/srchybrid/3DPreviewControl.h +++ b/srchybrid/3DPreviewControl.h @@ -10,7 +10,6 @@ class C3DPreviewControl : public CStatic public: C3DPreviewControl(); - virtual ~C3DPreviewControl() = default; protected: DECLARE_MESSAGE_MAP() diff --git a/srchybrid/AICHSyncThread.cpp b/srchybrid/AICHSyncThread.cpp index bddb94dd..774bb145 100644 --- a/srchybrid/AICHSyncThread.cpp +++ b/srchybrid/AICHSyncThread.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -56,7 +56,6 @@ int CAICHSyncThread::Run() const CString &fullpath(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + KNOWN2_MET_FILENAME); CSafeFile file; - uint32 nLastVerifiedPos = 0; // we need to keep a lock on this file while the thread is running CSingleLock lockKnown2Met(&CAICHRecoveryHashSet::m_mutKnown2File, TRUE); @@ -73,17 +72,18 @@ int CAICHSyncThread::Run() } return 0; } + uint32 nLastVerifiedPos = 0; try { if (file.GetLength() >= 1) { uint8 header = file.ReadUInt8(); if (header != KNOWN2_MET_VERSION) AfxThrowFileException(CFileException::endOfFile, 0, file.GetFileName()); - //setvbuf(file.m_pStream, NULL, _IOFBF, 16384); + //::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); ULONGLONG nExistingSize = file.GetLength(); while (file.GetPosition() < nExistingSize) { aKnown2HashesFilePos.Add(file.GetPosition()); - aKnown2Hashes.Add(CAICHHash(&file)); + aKnown2Hashes.Add(CAICHHash(file)); uint32 nHashCount = file.ReadUInt32(); if (file.GetPosition() + nHashCount * (ULONGLONG)CAICHHash::GetHashSize() > nExistingSize) AfxThrowFileException(CFileException::endOfFile, 0, file.GetFileName()); @@ -116,12 +116,12 @@ int CAICHSyncThread::Run() return 0; } - // now we check that all files which are in the shared file list have a corresponding hash in out list + // now we check that all files which are in the shared file list have a corresponding hash in the out list // those who don't are added to the hashing list CList liUsedHashes; - CSingleLock sharelock(&theApp.sharedfiles->m_mutWriteList, TRUE); - bool bDbgMsgCreatingPartHashes = true; + + CSingleLock sharelock(&theApp.sharedfiles->m_mutWriteList, TRUE); for (POSITION pos = BEFORE_START_POSITION; pos != NULL;) { if (theApp.IsClosing()) // in case of shutdown while still hashing return 0; @@ -184,10 +184,10 @@ int CAICHSyncThread::Run() uint32 nPurgeBecauseOld = 0; uint32 nPurgeDups = 0; static const CAICHHash empty; //zero AICH hash - while (file.GetPosition() < nExistingSize) { - ULONGLONG nCurrentHashsetPos = file.GetPosition(); + ULONGLONG nCurrentHashsetPos; + while ((nCurrentHashsetPos = file.GetPosition()) < nExistingSize) { ULONGLONG posTmp = 0; //position of an old duplicate hash - CAICHHash aichHash(&file); + CAICHHash aichHash(file); uint32 nHashCount = file.ReadUInt32(); if (file.GetPosition() + nHashCount * (ULONGLONG)CAICHHash::GetHashSize() > nExistingSize) AfxThrowFileException(CFileException::endOfFile, 0, file.GetFileName()); @@ -251,12 +251,12 @@ int CAICHSyncThread::Run() } } else { // remember (/index) all hashes which are stored in the file for faster checking later on - for (INT_PTR i = 0; !theApp.IsClosing() && i < aKnown2Hashes.GetCount(); ++i) + for (INT_PTR i = 0; i < aKnown2Hashes.GetCount() && !theApp.IsClosing(); ++i) CAICHRecoveryHashSet::AddStoredAICHHash(aKnown2Hashes[i], aKnown2HashesFilePos[i]); } #ifdef _DEBUG - for (POSITION pos = liUsedHashes.GetHeadPosition(); !theApp.IsClosing() && pos != NULL;) { + for (POSITION pos = liUsedHashes.GetHeadPosition(); pos != NULL && !theApp.IsClosing();) { CKnownFile *pFile = theApp.sharedfiles->GetFileByAICH(liUsedHashes.GetNext(pos)); if (pFile == NULL) { ASSERT(0); @@ -278,7 +278,7 @@ int CAICHSyncThread::Run() if (!m_liToHash.IsEmpty()) { theApp.QueueLogLine(true, GetResString(IDS_AICH_SYNCTOTAL), m_liToHash.GetCount()); theApp.emuledlg->sharedfileswnd->sharedfilesctrl.SetAICHHashing(m_liToHash.GetCount()); - // let first all normal hashing be done before starting out sync hashing + // first let all normal hashing be done before starting out sync hashing CSingleLock sLock1(&theApp.hashing_mut); // only one file hash at a time while (theApp.sharedfiles->GetHashingCount() != 0) { if (theApp.IsClosing()) @@ -319,11 +319,12 @@ bool CAICHSyncThread::ConvertToKnown2ToKnown264(CSafeFile *pTargetFile) // changing hashcount from uint16 to uint32 // there still exists a lock on known2_64.met and it should be not opened at this point - CString oldfullpath(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + OLD_KNOWN2_MET_FILENAME); - CString newfullpath(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + KNOWN2_MET_FILENAME); + const CString &sConfDir(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); + const CString &oldfullpath(sConfDir + OLD_KNOWN2_MET_FILENAME); + const CString &newfullpath(sConfDir + KNOWN2_MET_FILENAME); - if (PathFileExists(newfullpath) || !PathFileExists(oldfullpath)) - // only continue if the old file does and the new file does not exists + // continue only if the old file does exist, and the new file does not + if (::PathFileExists(newfullpath) || !::PathFileExists(oldfullpath)) return false; CSafeFile oldfile; @@ -336,7 +337,7 @@ bool CAICHSyncThread::ConvertToKnown2ToKnown264(CSafeFile *pTargetFile) strError.AppendFormat(_T(" - %s"), szError); LogError(LOG_STATUSBAR, _T("%s"), (LPCTSTR)strError); } - // else -> known2.met also doesn't exists, so nothing to convert + // known2.met also doesn't exist, so nothing to convert return false; } @@ -356,7 +357,7 @@ bool CAICHSyncThread::ConvertToKnown2ToKnown264(CSafeFile *pTargetFile) try { pTargetFile->WriteUInt8(KNOWN2_MET_VERSION); while (oldfile.GetPosition() < oldfile.GetLength()) { - CAICHHash aichHash(&oldfile); + CAICHHash aichHash(oldfile); uint32 nHashCount = oldfile.ReadUInt16(); if (oldfile.GetPosition() + nHashCount * (ULONGLONG)CAICHHash::GetHashSize() > oldfile.GetLength()) AfxThrowFileException(CFileException::endOfFile, 0, oldfile.GetFileName()); diff --git a/srchybrid/AICHSyncThread.h b/srchybrid/AICHSyncThread.h index c4ce0554..b4317886 100644 --- a/srchybrid/AICHSyncThread.h +++ b/srchybrid/AICHSyncThread.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/AbstractFile.cpp b/srchybrid/AbstractFile.cpp index d07a022f..043eb57e 100644 --- a/srchybrid/AbstractFile.cpp +++ b/srchybrid/AbstractFile.cpp @@ -1,6 +1,6 @@ // parts of this file are based on work from pan One (http://home-3.tiscali.nl/~meost/pms/) //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -39,8 +39,8 @@ CAbstractFile::CAbstractFile() : m_nFileSize(0ull) , m_FileIdentifier(m_nFileSize) , m_uRating() - , m_bCommentLoaded() , m_uUserRating() + , m_bCommentLoaded() , m_bHasComment() , m_bKadCommentSearchRunning() { @@ -51,12 +51,12 @@ CAbstractFile::CAbstractFile(const CAbstractFile *pAbstractFile) , m_FileIdentifier(pAbstractFile->m_FileIdentifier, m_nFileSize) , m_strFileName(pAbstractFile->m_strFileName) , m_strComment(pAbstractFile->m_strComment) + , m_strFileType(pAbstractFile->m_strFileType) , m_uRating(pAbstractFile->m_uRating) - , m_bCommentLoaded(pAbstractFile->m_bCommentLoaded) , m_uUserRating(pAbstractFile->m_uUserRating) + , m_bCommentLoaded(pAbstractFile->m_bCommentLoaded) , m_bHasComment(pAbstractFile->m_bHasComment) , m_bKadCommentSearchRunning(pAbstractFile->m_bKadCommentSearchRunning) - , m_strFileType(pAbstractFile->m_strFileType) { const CTypedPtrList &list = pAbstractFile->getNotes(); @@ -77,16 +77,16 @@ CAbstractFile::~CAbstractFile() void CAbstractFile::AssertValid() const { CObject::AssertValid(); - (void)m_strFileName; + m_taglist.AssertValid(); (void)m_FileIdentifier; (void)m_nFileSize; + (void)m_strFileName; (void)m_strComment; - (void)m_uRating; (void)m_strFileType; + (void)m_uRating; (void)m_uUserRating; CHECK_BOOL(m_bHasComment); CHECK_BOOL(m_bCommentLoaded); - m_taglist.AssertValid(); } void CAbstractFile::Dump(CDumpContext &dc) const @@ -95,16 +95,16 @@ void CAbstractFile::Dump(CDumpContext &dc) const } #endif -bool CAbstractFile::AddNote(Kademlia::CEntry *pEntry) +bool CAbstractFile::AddNote(const Kademlia::CEntry &cEntry) { - for (POSITION pos = m_kadNotes.GetHeadPosition(); pos != NULL; ) { + for (POSITION pos = m_kadNotes.GetHeadPosition(); pos != NULL;) { const Kademlia::CEntry *entry = m_kadNotes.GetNext(pos); - if (entry->m_uSourceID == pEntry->m_uSourceID) { - ASSERT(entry != pEntry); + if (entry->m_uSourceID == cEntry.m_uSourceID) { + ASSERT(entry != &cEntry); return false; } } - m_kadNotes.AddHead(pEntry); + m_kadNotes.AddHead(const_cast(cEntry).Copy()); UpdateFileRatingCommentAvail(); return true; } @@ -149,12 +149,12 @@ void CAbstractFile::AddTagUnique(CTag *pTag) for (INT_PTR i = m_taglist.GetCount(); --i >= 0;) { const CTag *pCurTag = m_taglist[i]; if (( (pCurTag->GetNameID() != 0 && pCurTag->GetNameID() == pTag->GetNameID()) - || (pCurTag->GetName()[0] && pTag->GetName()[0] && CmpED2KTagName(pCurTag->GetName(), pTag->GetName()) == 0) + || (pCurTag->HasName() && pTag->HasName() && CmpED2KTagName(pCurTag->GetName(), pTag->GetName()) == 0) ) && pCurTag->GetType() == pTag->GetType()) { delete pCurTag; - m_taglist.SetAt(i, pTag); + m_taglist[i] = pTag; return; } } @@ -418,13 +418,11 @@ void CAbstractFile::RefilterKadNotes(bool bUpdate) CString CAbstractFile::GetED2kLink(bool bHashset, bool bHTML, bool bHostname, bool bSource, uint32 dwSourceIP) const { CString strLink; - strLink.Format(_T("ed2k://|file|%s|%I64u|%s|") + strLink.Format(&_T(" 0 && GetFileIdentifierC().HasExpectedMD4HashCount()) { strLink += _T("p="); for (UINT j = 0; j < GetFileIdentifierC().GetAvailableMD4PartHashCount(); ++j) { diff --git a/srchybrid/AbstractFile.h b/srchybrid/AbstractFile.h index c054768b..4f7f9aa6 100644 --- a/srchybrid/AbstractFile.h +++ b/srchybrid/AbstractFile.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -71,31 +71,31 @@ class CAbstractFile: public CObject CString GetED2kLink(bool bHashset = false, bool bHTML = false, bool bHostname = false, bool bSource = false, uint32 dwSourceIP = 0) const; - EMFileSize GetFileSize() const { return m_nFileSize; } - virtual void SetFileSize(EMFileSize nFileSize) { m_nFileSize = nFileSize; } - bool IsLargeFile() const { return (uint64)m_nFileSize > OLD_MAX_EMULE_FILE_SIZE; } + EMFileSize GetFileSize() const { return m_nFileSize; } + virtual void SetFileSize(EMFileSize nFileSize) { m_nFileSize = nFileSize; } + bool IsLargeFile() const { return (uint64)m_nFileSize > OLD_MAX_EMULE_FILE_SIZE; } - uint32 GetIntTagValue(uint8 tagname) const; - uint32 GetIntTagValue(LPCSTR tagname) const; - bool GetIntTagValue(uint8 tagname, uint32 &ruValue) const; - uint64 GetInt64TagValue(uint8 tagname) const; - uint64 GetInt64TagValue(LPCSTR tagname) const; - bool GetInt64TagValue(uint8 tagname, uint64 &ruValue) const; - void SetIntTagValue(uint8 tagname, uint32 uValue); - void SetInt64TagValue(uint8 tagname, uint64 uValue); + uint32 GetIntTagValue(uint8 tagname) const; + uint32 GetIntTagValue(LPCSTR tagname) const; + bool GetIntTagValue(uint8 tagname, uint32 &ruValue) const; + uint64 GetInt64TagValue(uint8 tagname) const; + uint64 GetInt64TagValue(LPCSTR tagname) const; + bool GetInt64TagValue(uint8 tagname, uint64 &ruValue) const; + void SetIntTagValue(uint8 tagname, uint32 uValue); + void SetInt64TagValue(uint8 tagname, uint64 uValue); const CString& GetStrTagValue(uint8 tagname) const; const CString& GetStrTagValue(LPCSTR tagname) const; - void SetStrTagValue(uint8 tagname, LPCTSTR); - CTag* GetTag(uint8 tagname, uint8 tagtype) const; - CTag* GetTag(LPCSTR tagname, uint8 tagtype) const; - CTag* GetTag(uint8 tagname) const; - CTag* GetTag(LPCSTR tagname) const; + void SetStrTagValue(uint8 tagname, LPCTSTR); + CTag* GetTag(uint8 tagname, uint8 tagtype) const; + CTag* GetTag(LPCSTR tagname, uint8 tagtype) const; + CTag* GetTag(uint8 tagname) const; + CTag* GetTag(LPCSTR tagname) const; const CArray& GetTags() const { return m_taglist; } - void AddTagUnique(CTag *pTag); - void DeleteTag(uint8 tagname); - void DeleteTag(CTag *pTag); - void ClearTags(); - void CopyTags(const CArray &tags); + void AddTagUnique(CTag *pTag); + void DeleteTag(uint8 tagname); + void DeleteTag(CTag *pTag); + void ClearTags(); + void CopyTags(const CArray &tags); virtual bool IsPartFile() const { return false; } bool HasComment() const { return m_bHasComment; } @@ -107,9 +107,9 @@ class CAbstractFile: public CObject const CString &GetFileComment(); UINT GetFileRating(); void LoadComment(); - virtual void UpdateFileRatingCommentAvail(bool bForceUpdate = false) = 0; + virtual void UpdateFileRatingCommentAvail(bool bForceUpdate = false) = 0; - bool AddNote(Kademlia::CEntry *pEntry); + bool AddNote(const Kademlia::CEntry &cEntry); void RefilterKadNotes(bool bUpdate = true); const CKadEntryPtrList& getNotes() const { return m_kadNotes; } @@ -123,16 +123,16 @@ class CAbstractFile: public CObject #endif protected: - EMFileSize m_nFileSize; + CArray m_taglist; + CKadEntryPtrList m_kadNotes; + EMFileSize m_nFileSize; //must be before m_FileIdentifier due to initialisation list order CFileIdentifier m_FileIdentifier; - CString m_strFileName; - CString m_strComment; + CString m_strFileName; + CString m_strComment; + CString m_strFileType; UINT m_uRating; - bool m_bCommentLoaded; UINT m_uUserRating; + bool m_bCommentLoaded; bool m_bHasComment; bool m_bKadCommentSearchRunning; - CString m_strFileType; - CArray m_taglist; - CKadEntryPtrList m_kadNotes; }; \ No newline at end of file diff --git a/srchybrid/AddFriend.cpp b/srchybrid/AddFriend.cpp index 06d5ddd0..22ed5528 100644 --- a/srchybrid/AddFriend.cpp +++ b/srchybrid/AddFriend.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -16,11 +16,10 @@ //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "stdafx.h" #include "emule.h" -#include "AddFriend.h" -#include "Friend.h" #include "otherfunctions.h" -#include "FriendList.h" #include "Preferences.h" +#include "AddFriend.h" +#include "FriendList.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -114,14 +113,14 @@ void CAddFriend::OnAddBtn() CString strBuff; uint32 ip; GetDlgItemText(IDC_IP, strBuff); - UINT u1, u2, u3, u4, uPort = 0; + UINT u1, u2, u3, u4, uPort; if (_stscanf(strBuff, _T("%u.%u.%u.%u:%u"), &u1, &u2, &u3, &u4, &uPort) != 5 || u1 > 255 || u2 > 255 || u3 > 255 || u4 > 255 || uPort > 65535) { - uPort = 0; if (_stscanf(strBuff, _T("%u.%u.%u.%u"), &u1, &u2, &u3, &u4) != 4 || u1 > 255 || u2 > 255 || u3 > 255 || u4 > 255) { LocMessageBox(IDS_ERR_NOVALIDFRIENDINFO, MB_OK, 0); GetDlgItem(IDC_IP)->SetFocus(); return; } + uPort = 0; } in_addr iaFriend; iaFriend.S_un.S_un_b.s_b1 = (UCHAR)u1; @@ -141,7 +140,8 @@ void CAddFriend::OnAddBtn() CString strUserName; GetDlgItemText(IDC_USERNAME, strUserName); - strUserName = strUserName.Trim().Left(thePrefs.GetMaxUserNickLength()); + if (strUserName.Trim().GetLength() > thePrefs.GetMaxUserNickLength()) + strUserName.Truncate(thePrefs.GetMaxUserNickLength()); // why did we offer an edit control for entering the userhash but did not store it? ; diff --git a/srchybrid/AddFriend.h b/srchybrid/AddFriend.h index 22e23b18..eb88c4e1 100644 --- a/srchybrid/AddFriend.h +++ b/srchybrid/AddFriend.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/AddSourceDlg.cpp b/srchybrid/AddSourceDlg.cpp index e06691ed..cfecc29a 100644 --- a/srchybrid/AddSourceDlg.cpp +++ b/srchybrid/AddSourceDlg.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -18,7 +18,6 @@ #include "emule.h" #include "AddSourceDlg.h" #include "PartFile.h" -#include "OtherFunctions.h" #include "UpDownClient.h" #include "DownloadQueue.h" #include @@ -91,7 +90,7 @@ BOOL CAddSourceDlg::OnInitDialog() void CAddSourceDlg::OnBnClickedRadio1() { - m_nSourceType = 0; + m_nSourceType = 0; //source client GetDlgItem(IDC_EDIT2)->EnableWindow(true); GetDlgItem(IDC_EDIT3)->EnableWindow(true); GetDlgItem(IDC_EDIT10)->EnableWindow(false); @@ -100,7 +99,7 @@ void CAddSourceDlg::OnBnClickedRadio1() void CAddSourceDlg::OnBnClickedRadio4() { - m_nSourceType = 1; + m_nSourceType = 1; //URL GetDlgItem(IDC_EDIT2)->EnableWindow(false); GetDlgItem(IDC_EDIT3)->EnableWindow(false); GetDlgItem(IDC_EDIT10)->EnableWindow(true); @@ -113,7 +112,7 @@ void CAddSourceDlg::OnBnClickedButton1() return; switch (m_nSourceType) { - case 0: + case 0: //source client { CString sip; GetDlgItemText(IDC_EDIT2, sip); @@ -124,10 +123,10 @@ void CAddSourceDlg::OnBnClickedButton1() uint16 port; int iColon = sip.Find(_T(':')); if (iColon >= 0) { - port = (uint16)_tstoi(sip.Mid(iColon + 1)); + port = (uint16)_tstoi(CPTR(sip, iColon + 1)); sip.Truncate(iColon); } else { - BOOL bTranslated = FALSE; + BOOL bTranslated; port = (uint16)GetDlgItemInt(IDC_EDIT3, &bTranslated, FALSE); if (!bTranslated) return; @@ -140,8 +139,8 @@ void CAddSourceDlg::OnBnClickedButton1() theApp.downloadqueue->CheckAndAddSource(m_pFile, toadd); } } - return; - case 1: + break; + case 1: //URL { CString strURL; if (GetDlgItemText(IDC_EDIT10, strURL)) { diff --git a/srchybrid/AddSourceDlg.h b/srchybrid/AddSourceDlg.h index 67ea8240..3f88f8f3 100644 --- a/srchybrid/AddSourceDlg.h +++ b/srchybrid/AddSourceDlg.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -17,7 +17,6 @@ #pragma once #include "ResizableLib/ResizableDialog.h" -#include "otherfunctions.h" class CPartFile; @@ -34,7 +33,6 @@ class CAddSourceDlg : public CResizableDialog public: explicit CAddSourceDlg(CWnd *pParent = NULL); // standard constructor - virtual ~CAddSourceDlg() = default; void SetFile(CPartFile *pFile); diff --git a/srchybrid/ArchivePreviewDlg.cpp b/srchybrid/ArchivePreviewDlg.cpp index 7a0b4012..b3a00fe2 100644 --- a/srchybrid/ArchivePreviewDlg.cpp +++ b/srchybrid/ArchivePreviewDlg.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -43,7 +43,7 @@ class EncodeFileName public: EncodeFileName(); //int Encode(char *Name, wchar_t *NameW, byte *EncName); - void Decode(char *Name, byte *EncName, int EncSize, wchar_t *NameW, int MaxDecSize); + void Decode(const char* const Name, byte *EncName, int EncSize, wchar_t *NameW, int MaxDecSize); }; EncodeFileName::EncodeFileName() @@ -54,7 +54,7 @@ EncodeFileName::EncodeFileName() { } -void EncodeFileName::Decode(char *Name, byte *EncName, int EncSize, wchar_t *NameW, int MaxDecSize) +void EncodeFileName::Decode(const char* const Name, byte *EncName, int EncSize, wchar_t *NameW, int MaxDecSize) { int EncPos = 0, DecPos = 0; byte HighByte = EncName[EncPos++]; @@ -211,7 +211,7 @@ BOOL CArchivePreviewDlg::OnInitDialog() // To support full sorting of the archive entries list we'd need a separate list which // is holding the unified archive entries for all different supported archive formats so // that the ListView's sortproc can get valid 'lParam' values which are pointing to those - // entries. This could be done, but for now we just let the default ListView sort + // entries. This could be done, but for now we just let the default ListView's // functionality sort the archive entries by filename (the content of the first column). ASSERT(m_ContentList.GetStyle() & LVS_SORTASCENDING); ASSERT(m_ContentList.GetStyle() & LVS_SHAREIMAGELISTS); @@ -348,20 +348,21 @@ int CArchivePreviewDlg::ShowAceResults(int succ, archiveScannerThreadParams_s *t bool statusEncrypted = false; UINT uArchiveFileEntries = 0; - CString temp; UINT uid = tp->ai->ACEdir->IsEmpty() ? IDS_ARCPREV_INSUFFDATA : tp->file->IsPartFile() ? IDS_ARCPREV_LISTMAYBEINCOMPL : 0; + CString temp; temp.Format(_T("%s %s"), (LPCTSTR)GetResString(IDS_ARCPARSED), uid ? (LPCTSTR)GetResString(uid) : _T("")); SetDlgItemText(IDC_INFO_STATUS, temp); if (!tp->ai->ACEdir->IsEmpty()) { m_ContentList.SetRedraw(FALSE); - for (POSITION pos = tp->ai->ACEdir->GetHeadPosition(); pos != NULL;) { + for (POSITION pos = tp->ai->ACEdir->GetHeadPosition(); tp->m_bIsValid && pos != NULL;) { const ACE_BlockFile *block = tp->ai->ACEdir->GetNext(pos); int uSubId = 1; - bool bCompleteEntry = !tp->file->IsPartFile() || static_cast(tp->file)->IsComplete(block->data_offset, block->data_offset + block->PACK_SIZE, true); + bool bCompleteEntry = !tp->file->IsPartFile() + || static_cast(tp->file)->IsCompleteBDSafe(block->data_offset, block->data_offset + block->PACK_SIZE); bool bIsDirectory = ((block->FILE_ATTRIBS & FILE_ATTRIBUTE_DIRECTORY) != 0); if (!bIsDirectory) ++uArchiveFileEntries; @@ -385,12 +386,11 @@ int CArchivePreviewDlg::ShowAceResults(int succ, archiveScannerThreadParams_s *t } // attribs - temp.Empty(); - if (block->HEAD_FLAGS & 0x4000) { statusEncrypted = true; - temp += _T('P'); - } + temp = _T("P"); + } else + temp.Empty(); if (bIsDirectory) { if (!temp.IsEmpty()) @@ -426,10 +426,7 @@ int CArchivePreviewDlg::ShowAceResults(int succ, archiveScannerThreadParams_s *t // compression level if (!temp.IsEmpty()) temp += _T(", "); - if ((BYTE)block->TECHINFO == 0) - temp += _T("L0"); - else - temp.AppendFormat(_T("L%i"), (BYTE)(block->TECHINFO >> 8)); + temp.AppendFormat(_T("L%i"), (BYTE)(block->TECHINFO >> 8)); m_ContentList.SetItemText(iItem, uSubId++, temp); } @@ -510,22 +507,22 @@ int CArchivePreviewDlg::ShowISOResults(int succ, archiveScannerThreadParams_s *t // file contents into list DWORD filecount = 0; - CString temp; UINT uid = tp->ai->ISOdir->IsEmpty() ? IDS_ARCPREV_INSUFFDATA : tp->file->IsPartFile() ? IDS_ARCPREV_LISTMAYBEINCOMPL : 0; + CString temp; temp.Format(_T("%s %s"), (LPCTSTR)GetResString(IDS_ARCPARSED), uid ? (LPCTSTR)GetResString(uid) : _T("")); SetDlgItemText(IDC_INFO_STATUS, temp); m_ContentList.SetRedraw(FALSE); - for (POSITION pos = tp->ai->ISOdir->GetHeadPosition(); pos != NULL;) { + for (POSITION pos = tp->ai->ISOdir->GetHeadPosition(); tp->m_bIsValid && pos != NULL;) { ISO_FileFolderEntry *file = tp->ai->ISOdir->GetNext(pos); - bool bCompleteEntry = !tp->file->IsPartFile() || static_cast(tp->file)->IsComplete( - LODWORD(file->sector1OfExtension) * (uint64)tp->ai->isoInfos.secSize - , (LODWORD(file->sector1OfExtension) * (uint64)tp->ai->isoInfos.secSize) + file->dataSize - , true); + bool bCompleteEntry = !tp->file->IsPartFile() + || static_cast(tp->file)->IsCompleteBDSafe( + LODWORD(file->sector1OfExtension) * (uint64)tp->ai->isoInfos.secSize + , (LODWORD(file->sector1OfExtension) * (uint64)tp->ai->isoInfos.secSize) + file->dataSize); temp = CString(file->name); // remove separator extensions @@ -538,12 +535,12 @@ int CArchivePreviewDlg::ShowISOResults(int succ, archiveScannerThreadParams_s *t , INT_MAX, temp, 0, 0, iSystemImage, static_cast(!bCompleteEntry)); // attribs - temp.Empty(); //is directory? if (file->fileFlags & ISO_DIRECTORY) - temp += _T('D'); + temp = _T("D"); else { + temp.Empty(); ++filecount; // size @@ -650,16 +647,17 @@ int CArchivePreviewDlg::ShowRarResults(int succ, archiveScannerThreadParams_s *t if (!tp->ai->RARdir->IsEmpty()) { char buf[MAX_PATH + MAX_PATH * 2]; - // This file could be a self extracting RAR archive. Now that we eventually have read something + // This file could be a self-extracting RAR archive. Now that we eventually have read something // RAR-like from that file, we can set the 'verified' file type. tp->file->SetVerifiedFileType(ARCHIVE_RAR); m_ContentList.SetRedraw(FALSE); - for (POSITION pos = tp->ai->RARdir->GetHeadPosition(); pos != NULL;) { + for (POSITION pos = tp->ai->RARdir->GetHeadPosition(); tp->m_bIsValid && pos != NULL;) { RAR_BlockFile *block = tp->ai->RARdir->GetNext(pos); int uSubId = 1; - bool bCompleteEntry = !tp->file->IsPartFile() || static_cast(tp->file)->IsComplete(block->offsetData, block->offsetData + block->dataLength, true); + bool bCompleteEntry = !tp->file->IsPartFile() + || static_cast(tp->file)->IsCompleteBDSafe(block->offsetData, block->offsetData + block->dataLength); bool bIsDirectory = (block->HEAD_FLAGS & 0xE0) == 0xE0; uArchiveFileEntries += static_cast(!bIsDirectory); @@ -697,12 +695,11 @@ int CArchivePreviewDlg::ShowRarResults(int succ, archiveScannerThreadParams_s *t uSubId += 2; // attribs - temp.Empty(); - if (block->HEAD_FLAGS & 0x04) { statusEncrypted = true; - temp += _T('P'); - } + temp = _T("P"); + } else + temp.Empty(); //is directory? if (bIsDirectory) { @@ -766,7 +763,7 @@ int CArchivePreviewDlg::ShowRarResults(int succ, archiveScannerThreadParams_s *t // general info / archive attribs CString status; if (statusEncrypted) - status += GetResString(IDS_PASSWPROT); + status = GetResString(IDS_PASSWPROT); if (tp->ai->rarFlags & 0x0008) { if (!status.IsEmpty()) @@ -811,7 +808,6 @@ int CArchivePreviewDlg::ShowZipResults(int succ, archiveScannerThreadParams_s *t // file contents into list CString temp; - if (tp->ai->bZipCentralDir) temp = GetResString(IDS_ARCPREV_DIRSUCCREAD); else { @@ -825,7 +821,7 @@ int CArchivePreviewDlg::ShowZipResults(int succ, archiveScannerThreadParams_s *t bool statusEncrypted = false; if (!tp->ai->centralDirectoryEntries->IsEmpty()) { m_ContentList.SetRedraw(FALSE); - for (POSITION pos = tp->ai->centralDirectoryEntries->GetHeadPosition(); pos != NULL;) { + for (POSITION pos = tp->ai->centralDirectoryEntries->GetHeadPosition(); tp->m_bIsValid && pos != NULL;) { ZIP_CentralDirectory *cdEntry = tp->ai->centralDirectoryEntries->GetNext(pos); int uSubId = 1; @@ -833,12 +829,12 @@ int CArchivePreviewDlg::ShowZipResults(int succ, archiveScannerThreadParams_s *t bool bCompleteEntry = true; if (tp->file->IsPartFile()) { const CPartFile *pf = static_cast(tp->file); - UINT64 dataoffset = cdEntry->relativeOffsetOfLocalHeader + uint64 dataoffset = cdEntry->relativeOffsetOfLocalHeader + sizeof(ZIP_Entry) - (3 * sizeof(BYTE*)) + cdEntry->lenComment + cdEntry->lenFilename + cdEntry->lenExtraField; - bCompleteEntry = pf->IsComplete(dataoffset, dataoffset + cdEntry->lenCompressed, true); + bCompleteEntry = pf->IsCompleteBDSafe(dataoffset, dataoffset + cdEntry->lenCompressed); } // Is directory? @@ -849,7 +845,7 @@ int CArchivePreviewDlg::ShowZipResults(int succ, archiveScannerThreadParams_s *t // file/folder name CStringA strBuffA((char*)cdEntry->filename, cdEntry->lenFilename); - temp = CString(strBuffA); + temp = (CString)strBuffA; int iSystemImage = bIsDirectory ? theApp.GetFileTypeSystemImageIdx(_T("\\"), 1) : theApp.GetFileTypeSystemImageIdx(temp, temp.GetLength()); int iItem = m_ContentList.InsertItem(LVIF_TEXT | LVIF_PARAM | (iSystemImage > 0 ? LVIF_IMAGE : 0) , INT_MAX, temp, 0, 0, iSystemImage, static_cast(!bCompleteEntry)); @@ -865,11 +861,11 @@ int CArchivePreviewDlg::ShowZipResults(int succ, archiveScannerThreadParams_s *t uSubId += 2; // attribs - temp.Empty(); if (cdEntry->generalPurposeFlag & 0x01 || cdEntry->generalPurposeFlag & 0x40) { statusEncrypted = true; - temp += _T('P'); - } + temp = _T("P"); + } else + temp.Empty(); if (bIsDirectory) { if (!temp.IsEmpty()) @@ -896,11 +892,11 @@ int CArchivePreviewDlg::ShowZipResults(int succ, archiveScannerThreadParams_s *t m_ContentList.SetItemText(iItem, uSubId++, lm.Format(thePrefs.GetDateTimeFormat4Log())); // comment - temp.Empty(); if (cdEntry->lenComment) { strBuffA.SetString((char*)cdEntry->comment, cdEntry->lenComment); - temp = CString(strBuffA); - } + temp = (CString)strBuffA; + } else + temp.Empty(); m_ContentList.SetItemText(iItem, uSubId++, temp); @@ -934,8 +930,6 @@ static void FreeMemory(void *arg) { archiveScannerThreadParams_s *tp = static_cast(arg); - while (!tp->filled->IsEmpty()) - delete tp->filled->RemoveHead(); delete tp->filled; tp->filled = NULL; @@ -1038,9 +1032,9 @@ void CArchivePreviewDlg::UpdateArchiveDisplay(bool doscan) archiveinfo_s *ai = new archiveinfo_s; // get filled area list - CTypedPtrList *filled = new CTypedPtrList; + CArray *filled = new CArray; if (pFile->IsPartFile()) { - static_cast(pFile)->GetFilledList(filled); + static_cast(pFile)->GetFilledArray(*filled); if (filled->IsEmpty()) { SetDlgItemText(IDC_INFO_STATUS, GetResString(IDS_ARCPREV_INSUFFDATA)); delete filled; @@ -1048,7 +1042,7 @@ void CArchivePreviewDlg::UpdateArchiveDisplay(bool doscan) return; } } else - filled->AddTail(new Gap_Struct{ 0, (uint64)pFile->GetFileSize() }); + filled->Add(Gap_Struct{ 0, (uint64)pFile->GetFileSize() }); SetDlgItemText(IDC_INFO_STATUS, GetResString(IDS_ARCPREV_PLEASEWAIT)); @@ -1136,7 +1130,7 @@ LRESULT CArchivePreviewDlg::ShowScanResults(WPARAM wParam, LPARAM lParam) m_progressbar.SetPos(0); if (ret == -1) SetDlgItemText(IDC_INFO_STATUS, GetResString(IDS_IMP_ERR_IO)); - else if (tp->m_bIsValid) { + else { //if (tp->m_bIsValid) { // hide two unused columns for ISO and unhide for other types if (tp->type != IMAGE_ISO) { diff --git a/srchybrid/ArchivePreviewDlg.h b/srchybrid/ArchivePreviewDlg.h index 2757d8c6..d4a6f618 100644 --- a/srchybrid/ArchivePreviewDlg.h +++ b/srchybrid/ArchivePreviewDlg.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -38,7 +38,6 @@ class CArchivePreviewDlg : public CResizablePage CShareableFile *m_pFile; //archive contents was displayed for this file public: CArchivePreviewDlg(); - virtual ~CArchivePreviewDlg() = default; virtual BOOL OnInitDialog(); void SetFiles(const CSimpleArray *paFiles) { m_paFiles = paFiles; m_bDataChanged = true; } diff --git a/srchybrid/ArchiveRecovery.cpp b/srchybrid/ArchiveRecovery.cpp index 9289c6ae..e07cc4f7 100644 --- a/srchybrid/ArchiveRecovery.cpp +++ b/srchybrid/ArchiveRecovery.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -65,16 +65,13 @@ void CArchiveRecovery::recover(CPartFile *partFile, bool preview, bool bCreatePa AddLogLine(true, _T("%s \"%s\""), (LPCTSTR)GetResString(IDS_ATTEMPTING_RECOVERY), (LPCTSTR)partFile->GetFileName()); // Get the current filled list for this file - CTypedPtrList *filled = new CTypedPtrList; - partFile->GetFilledList(filled); + CArray *filled = new CArray; + partFile->GetFilledArray(*filled); #ifdef _DEBUG - { - int i = 0; - TRACE("%s: filled\n", __FUNCTION__); - for (POSITION pos = filled->GetHeadPosition(); pos != NULL;) { - const Gap_Struct *gap = filled->GetNext(pos); - TRACE("%3u: %10u %10u (%u)\n", i++, gap->start, gap->end, gap->end - gap->start + 1); - } + TRACE("%s: filled\n", __FUNCTION__); + for (INT_PTR i = 0; i < filled->GetCount(); ++i) { + const Gap_Struct &gap = (*filled)[i]; + TRACE("%3u: %10u %10u (%u)\n", i, gap.start, gap.end, gap.end - gap.start + 1); } #endif @@ -110,10 +107,10 @@ UINT AFX_CDECL CArchiveRecovery::run(LPVOID lpParam) return 0; } -bool CArchiveRecovery::performRecovery(CPartFile *partFile, CTypedPtrList *filled +bool CArchiveRecovery::performRecovery(CPartFile *partFile, CArray *paFilled , bool preview, bool bCreatePartFileCopy) { - if (filled->IsEmpty()) + if (paFilled->IsEmpty()) return false; bool success = false; @@ -122,8 +119,8 @@ bool CArchiveRecovery::performRecovery(CPartFile *partFile, CTypedPtrListGetTempPath(), (LPCTSTR)partFile->GetFileName().Left(5)); - if (!CopyPartFile(partFile, filled, tempFileName)) + tempFileName.Format(_T("%s%s-rec.tmp"), (LPCTSTR)partFile->GetTmpPath(), (LPCTSTR)partFile->GetFileName().Left(5)); + if (!partFile->CopyPartFile(*paFilled, tempFileName)) return false; // Open temp file for reading @@ -153,20 +150,20 @@ bool CArchiveRecovery::performRecovery(CPartFile *partFile, CTypedPtrListGetTempPath(), (LPCTSTR)partFile->GetFileName().Left(5), ext); + outputFileName.Format(_T("%s%s-rec%s"), (LPCTSTR)partFile->GetTmpPath(), (LPCTSTR)partFile->GetFileName().Left(5), ext); CFile output; ULONGLONG ulTempFileSize = 0; if (output.Open(outputFileName, CFile::modeWrite | CFile::shareDenyWrite | CFile::modeCreate)) { // Process the output file switch (myAtype) { case ARCHIVE_ZIP: - success = recoverZip(&temp, &output, NULL, filled, (temp.GetLength() == partFile->GetFileSize())); + success = recoverZip(&temp, &output, NULL, paFilled, (temp.GetLength() == partFile->GetFileSize())); break; case ARCHIVE_RAR: - success = recoverRar(&temp, &output, NULL, filled); + success = recoverRar(&temp, &output, NULL, paFilled); break; case ARCHIVE_ACE: - success = recoverAce(&temp, &output, NULL, filled); + success = recoverAce(&temp, &output, NULL, paFilled); } ulTempFileSize = output.GetLength(); // Close output @@ -210,7 +207,7 @@ bool CArchiveRecovery::performRecovery(CPartFile *partFile, CTypedPtrList *filled, bool fullSize) + , CArray *paFilled, bool fullSize) { bool retVal = false; INT_PTR fileCount = 0; @@ -222,8 +219,8 @@ bool CArchiveRecovery::recoverZip(CFile *zipInput, CFile *zipOutput, archiveScan else centralDirectoryEntries = aitp->ai->centralDirectoryEntries; - // If the central directory is intact this is simple - if (fullSize && readZipCentralDirectory(zipInput, centralDirectoryEntries, filled)) { + // This is simple if the central directory is intact + if (fullSize && readZipCentralDirectory(zipInput, centralDirectoryEntries, paFilled)) { if (centralDirectoryEntries->IsEmpty()) goto done; @@ -241,8 +238,8 @@ bool CArchiveRecovery::recoverZip(CFile *zipInput, CFile *zipOutput, archiveScan bool deleteCD = false; POSITION del = pos; ZIP_CentralDirectory *cdEntry = centralDirectoryEntries->GetNext(pos); - uint32 lenEntry = sizeof(ZIP_Entry) + cdEntry->lenFilename + cdEntry->lenExtraField + cdEntry->lenCompressed; - if (IsFilled(cdEntry->relativeOffsetOfLocalHeader, (uint64)cdEntry->relativeOffsetOfLocalHeader + lenEntry, filled)) { + uint32 lenEntry = (uint32)(sizeof(ZIP_Entry) + cdEntry->lenFilename + cdEntry->lenExtraField + cdEntry->lenCompressed); + if (IsFilled(cdEntry->relativeOffsetOfLocalHeader, (uint64)cdEntry->relativeOffsetOfLocalHeader + lenEntry, paFilled)) { zipInput->Seek(cdEntry->relativeOffsetOfLocalHeader, CFile::begin); // Update offset cdEntry->relativeOffsetOfLocalHeader = (uint32)zipOutput->GetPosition(); @@ -263,23 +260,23 @@ bool CArchiveRecovery::recoverZip(CFile *zipInput, CFile *zipOutput, archiveScan // Have to scan the file the hard way zipInput->SeekToBegin(); // Loop through filled areas of the file looking for entries - for (POSITION pos = filled->GetHeadPosition(); pos != NULL;) { - const Gap_Struct *fill = filled->GetNext(pos); + for (INT_PTR i = 0; i < paFilled->GetCount(); ++i) { + const Gap_Struct &fill = (*paFilled)[i]; const ULONGLONG filePos = zipInput->GetPosition(); // The file may have been positioned to the next entry in ScanForMarker() or processZipEntry() - if (filePos > fill->end) + if (filePos > fill.end) continue; - if (filePos < fill->start) - zipInput->Seek(fill->start, CFile::begin); + if (filePos < fill.start) + zipInput->Seek(fill.start, CFile::begin); - // If there is any problem, then don't bother checking the rest of this part + // If there is any problem, don't bother checking the rest of this area do { if (aitp && !aitp->m_bIsValid) return 0; // Scan for entry marker within this filled area - } while (scanForZipMarker(zipInput, aitp, ZIP_LOCAL_HEADER_MAGIC, fill->end - zipInput->GetPosition() + 1) - && zipInput->GetPosition() <= fill->end - && processZipEntry(zipInput, zipOutput, (uint32)(fill->end - zipInput->GetPosition() + 1), centralDirectoryEntries)); + } while (scanForZipMarker(zipInput, aitp, ZIP_LOCAL_HEADER_MAGIC, fill.end - zipInput->GetPosition() + 1) + && zipInput->GetPosition() <= fill.end + && processZipEntry(zipInput, zipOutput, (uint32)(fill.end - zipInput->GetPosition() + 1), centralDirectoryEntries)); } if (!zipOutput) { retVal = !centralDirectoryEntries->IsEmpty(); @@ -332,8 +329,8 @@ bool CArchiveRecovery::recoverZip(CFile *zipInput, CFile *zipOutput, archiveScan writeUInt32(zipOutput, ZIP_END_CD_MAGIC); writeUInt16(zipOutput, 0); // Number of this disk writeUInt16(zipOutput, 0); // Disk number where the central directory starts - writeUInt16(zipOutput, (uint16)fileCount); //Number of central directory records on this disk - writeUInt16(zipOutput, (uint16)fileCount); //Total number of central directory records + writeUInt16(zipOutput, (uint16)fileCount); //Number of central directory records on this disk + writeUInt16(zipOutput, (uint16)fileCount); //Total number of central directory records writeUInt32(zipOutput, (uint32)(endOffset - startOffset)); writeUInt32(zipOutput, (uint32)startOffset); writeUInt16(zipOutput, (uint16)strlen(ZIP_COMMENT)); @@ -354,7 +351,7 @@ bool CArchiveRecovery::recoverZip(CFile *zipInput, CFile *zipOutput, archiveScan return retVal; } -bool CArchiveRecovery::readZipCentralDirectory(CFile *zipInput, CTypedPtrList *centralDirectoryEntries, CTypedPtrList *filled) +bool CArchiveRecovery::readZipCentralDirectory(CFile *zipInput, CTypedPtrList *centralDirectoryEntries, CArray *filled) { try { // Ideally this zip file will not have a comment and the End-CD will be easy to find @@ -432,7 +429,7 @@ bool CArchiveRecovery::processZipEntry(CFile *zipInput, CFile *zipOutput, uint32 // Entry format : // 4 2 bytes Version needed to extract - // 6 2 bytes General purpose bit flag + // 6 2 bytes General purpose bit flags // 8 2 bytes Compression method // 10 2 bytes Last mod file time // 12 2 bytes Last mod file date @@ -445,28 +442,22 @@ bool CArchiveRecovery::processZipEntry(CFile *zipInput, CFile *zipOutput, uint32 // (e)bytes Extra field // (n)bytes Compressed data - // Read header - if (readUInt32(zipInput) != ZIP_LOCAL_HEADER_MAGIC) + ZIP_Entry entry; + UINT uReadLen = (UINT)((byte*)&entry.filename - (byte*)&entry); + if (zipInput->Read(&entry, uReadLen) != uReadLen + || entry.header != ZIP_LOCAL_HEADER_MAGIC + || !entry.crc32 //may be 0 if (generalPurposeFlag & 8) + || !entry.lenCompressed //same + || !entry.lenUncompressed //same + || !entry.lenFilename + || entry.lenFilename > MAX_PATH) // Possibly corrupt, don't allocate lots of memory + { return false; - - ZIP_Entry entry = {}; - entry.versionToExtract = readUInt16(zipInput); - entry.generalPurposeFlag = readUInt16(zipInput); - entry.compressionMethod = readUInt16(zipInput); - entry.lastModFileTime = readUInt16(zipInput); - entry.lastModFileDate = readUInt16(zipInput); - entry.crc32 = readUInt32(zipInput); - entry.lenCompressed = readUInt32(zipInput); - entry.lenUncompressed = readUInt32(zipInput); - entry.lenFilename = readUInt16(zipInput); - entry.lenExtraField = readUInt16(zipInput); + } // Do some quick checks at this stage that data is looking OK // if ((entry.crc32 == 0) && (entry.lenCompressed == 0) && (entry.lenUncompressed == 0) && (entry.lenFilename > 0)) // ; // this is a directory entry -// else - if ((entry.crc32 == 0) || (entry.lenCompressed == 0) || (entry.lenUncompressed == 0) || (entry.lenFilename == 0)) - return false; // Is this entry complete if (entry.lenFilename + entry.lenExtraField + (zipOutput ? entry.lenCompressed : 0) > available - 26) { @@ -476,8 +467,6 @@ bool CArchiveRecovery::processZipEntry(CFile *zipInput, CFile *zipOutput, uint32 } // Filename - if (entry.lenFilename > MAX_PATH) - return false; // Possibly corrupt, don't allocate lots of memory entry.filename = new BYTE[entry.lenFilename]; if (zipInput->Read(entry.filename, entry.lenFilename) != entry.lenFilename) { delete[] entry.filename; @@ -492,17 +481,7 @@ bool CArchiveRecovery::processZipEntry(CFile *zipInput, CFile *zipOutput, uint32 if (zipOutput) { // Output - writeUInt32(zipOutput, ZIP_LOCAL_HEADER_MAGIC); - writeUInt16(zipOutput, entry.versionToExtract); - writeUInt16(zipOutput, entry.generalPurposeFlag); - writeUInt16(zipOutput, entry.compressionMethod); - writeUInt16(zipOutput, entry.lastModFileTime); - writeUInt16(zipOutput, entry.lastModFileDate); - writeUInt32(zipOutput, entry.crc32); - writeUInt32(zipOutput, entry.lenCompressed); - writeUInt32(zipOutput, entry.lenUncompressed); - writeUInt16(zipOutput, entry.lenFilename); - writeUInt16(zipOutput, entry.lenExtraField); + zipOutput->Write(&entry, uReadLen); zipOutput->Write(entry.filename, entry.lenFilename); if (entry.lenExtraField > 0) zipOutput->Write(entry.extraField, entry.lenExtraField); @@ -541,15 +520,15 @@ bool CArchiveRecovery::processZipEntry(CFile *zipInput, CFile *zipOutput, uint32 cdEntry->relativeOffsetOfLocalHeader = (uint32)startOffset; cdEntry->filename = entry.filename; - if (entry.lenExtraField > 0) - cdEntry->extraField = entry.extraField; + cdEntry->extraField = (entry.lenExtraField > 0) ? entry.extraField : NULL; cdEntry->lenComment = 0; if (zipOutput != NULL) { cdEntry->lenComment = static_cast(strlen(ZIP_COMMENT)); cdEntry->comment = new BYTE[cdEntry->lenComment]; memcpy(cdEntry->comment, ZIP_COMMENT, cdEntry->lenComment); - } + } else + cdEntry->comment = NULL; centralDirectoryEntries->AddTail(cdEntry); } else { @@ -578,58 +557,12 @@ bool CArchiveRecovery::processZipEntry(CFile *zipInput, CFile *zipOutput, uint32 void CArchiveRecovery::DeleteMemory(ThreadParam *tp) { - while (!tp->filled->IsEmpty()) - delete tp->filled->RemoveHead(); delete tp->filled; delete tp; } -bool CArchiveRecovery::CopyPartFile(CPartFile *partFile, CTypedPtrList *filled, const CString &tempFileName) -{ - try { - CFile srcFile; - if (!srcFile.Open(partFile->GetFilePath(), CFile::modeRead | CFile::shareDenyNone)) - return false; - - // Open destination file and set length to the last filled end position - CFile destFile; - destFile.Open(tempFileName, CFile::modeWrite | CFile::shareDenyWrite | CFile::modeCreate); - Gap_Struct *fill = filled->GetTail(); - destFile.SetLength(fill->end); - - // Loop through the filled areas and copy data - partFile->m_bPreviewing = true; - for (POSITION pos = filled->GetHeadPosition(); pos != NULL;) { - fill = filled->GetNext(pos); - uint32 copied = 0; - srcFile.Seek(fill->start, CFile::begin); - destFile.Seek(fill->start, CFile::begin); - uint32 read; - BYTE buffer[4096]; - while ((read = srcFile.Read(buffer, sizeof buffer)) > 0) { - destFile.Write(buffer, read); - copied += read; - // Stop when finished filling (don't worry about extra) - if (fill->start + copied >= fill->end) - break; - } - } - destFile.Close(); - srcFile.Close(); - partFile->m_bPreviewing = false; - - return true; - } catch (CFileException *error) { - error->Delete(); - } catch (...) { - ASSERT(0); - } - - return false; -} - bool CArchiveRecovery::recoverRar(CFile *rarInput, CFile *rarOutput, archiveScannerThreadParams_s *aitp - , CTypedPtrList *filled) + , CArray *paFilled) { bool retVal = false; INT_PTR fileCount = 0; @@ -710,19 +643,19 @@ bool CArchiveRecovery::recoverRar(CFile *rarInput, CFile *rarOutput, archiveScan rarOutput->Write(start1, sizeof(start1)); // loop through the filled blocks - for (POSITION pos = filled->GetHeadPosition(); pos != NULL;) { - const Gap_Struct *fill = filled->GetNext(pos); - - rarInput->Seek(fill->start, CFile::begin); + const INT_PTR iLast = paFilled->GetCount() - 1; + for (INT_PTR i = 0; i <= iLast; ++i) { + const Gap_Struct &fill = (*paFilled)[i]; + rarInput->Seek(fill.start, CFile::begin); - while ((block = scanForRarFileHeader(rarInput, aitp, (fill->end - rarInput->GetPosition()))) != NULL) { + while ((block = scanForRarFileHeader(rarInput, aitp, (fill.end - rarInput->GetPosition()))) != NULL) { if (aitp) { aitp->ai->RARdir->AddTail(block); if (!aitp->m_bIsValid) return false; } - if (rarOutput != NULL && IsFilled(block->offsetData, block->offsetData + block->dataLength, filled)) { + if (rarOutput != NULL && IsFilled(block->offsetData, block->offsetData + block->dataLength, paFilled)) { // Don't include directories in file count if ((block->HEAD_FLAGS & 0xE0) != 0xE0) ++fileCount; @@ -736,7 +669,7 @@ bool CArchiveRecovery::recoverRar(CFile *rarInput, CFile *rarOutput, archiveScan delete block; block = NULL; } - if (rarInput->GetPosition() >= fill->end) + if (rarInput->GetPosition() >= fill.end) break; } } @@ -757,13 +690,14 @@ bool CArchiveRecovery::recoverRar(CFile *rarInput, CFile *rarOutput, archiveScan return retVal; } -bool CArchiveRecovery::IsFilled(uint64 start, uint64 end, CTypedPtrList *filled) +bool CArchiveRecovery::IsFilled(uint64 start, uint64 end, CArray *filled) { - for (POSITION pos = filled->GetHeadPosition(); pos != NULL;) { - const Gap_Struct *fill = filled->GetNext(pos); - if (fill->start > start) + const INT_PTR iLast = filled->GetCount() - 1; + for (INT_PTR i = 0; i <= iLast; ++i) { + const Gap_Struct &fill = (*filled)[i]; + if (fill.start > start) break; - if (fill->end >= end) + if (fill.end >= end) return true; } return false; @@ -774,32 +708,28 @@ bool CArchiveRecovery::IsFilled(uint64 start, uint64 end, CTypedPtrListGetPosition(); BYTE chunk[TESTCHUNKSIZE]; - int lenChunk = (int)sizeof(chunk); - BYTE *foundPos = NULL; - int pos = 0; - while ((available > 0) && ((lenChunk = input->Read(chunk, lenChunk)) > 0)) { + while (available > 0) { + INT_PTR lenChunk = input->Read(chunk, (UINT)(min(available, TESTCHUNKSIZE))); + if (lenChunk <= 0) + break; available -= lenChunk; - foundPos = chunk; - // Move back one, will be incremented in loop - --foundPos; - while (foundPos != NULL) { + for (BYTE *foundPos = chunk; foundPos != NULL; ++foundPos) { if (aitp && !aitp->m_bIsValid) return false; // Find first matching byte - foundPos = (BYTE*)memchr(foundPos + 1, (marker & 0xFF), (lenChunk - (foundPos + 1 - (&chunk[0])))); + foundPos = (BYTE*)memchr(foundPos, marker & 0xFF, lenChunk - (foundPos - chunk)); if (foundPos == NULL) break; // Test for end of buffer - pos = (int)(foundPos - chunk); - if ((pos + 3) > lenChunk) { - // Re-read buffer starting from found first byte position - input->Seek((LONGLONG)pos - lenChunk, CFile::current); - available += lenChunk - pos; + INT_PTR pos = foundPos - &chunk[lenChunk]; //offset from the current file position + if (pos + 3 > 0) { + // Re-read buffer starting from position of the found first byte + input->Seek(pos, CFile::current); + available += -pos; break; } @@ -807,9 +737,9 @@ bool CArchiveRecovery::scanForZipMarker(CFile *input, archiveScannerThreadParams ProcessProgress(aitp, input->GetPosition()); // Check for other bytes - if (*(uint32*)&chunk[pos] == marker) { + if (*(uint32*)foundPos == marker) { // Found it - input->Seek((LONGLONG)pos - lenChunk, CFile::current); + input->Seek(pos, CFile::current); return true; } } @@ -838,20 +768,16 @@ RAR_BlockFile* CArchiveRecovery::scanForRarFileHeader(CFile *input, archiveScann break; available -= lenChunk; - BYTE *foundPos = chunk; - - // Move back one, will be incremented in loop - --foundPos; - while (foundPos != NULL) { + for (BYTE *foundPos = chunk; foundPos != NULL; ++foundPos) { if (aitp && !aitp->m_bIsValid) return 0; // Find rar head block marker - foundPos = (BYTE*)memchr(foundPos + 1, RAR_HEAD_FILE, (lenChunk - (foundPos + 1 - (&chunk[0])))); + foundPos = (BYTE*)memchr(foundPos, RAR_HEAD_FILE, lenChunk - (foundPos - chunk)); if (foundPos == NULL) break; - ULONGLONG chunkOffset = foundPos - (&chunk[0]); + ULONGLONG chunkOffset = foundPos - chunk; ULONGLONG foundOffset = chunkstart + chunkOffset; if (aitp) @@ -932,7 +858,7 @@ RAR_BlockFile* CArchiveRecovery::scanForRarFileHeader(CFile *input, archiveScann uLong crc = crc32(0, checkCRC, sizeof *hdr); crc = crc32(crc, fileName, lenFileName); if (checkCRCsize > sizeof *hdr) - crc = crc32(crc, &checkCRC[sizeof *hdr], (checkCRCsize - sizeof *hdr)); + crc = crc32(crc, &checkCRC[sizeof *hdr], (uInt)(checkCRCsize - sizeof *hdr)); if ((uint16)crc == headCRC) { // Found valid crc, build block and return // Note that it may still be invalid data, so more checks should be performed @@ -1125,7 +1051,7 @@ ULONG getcrc(ULONG crc, UCHAR *addr, INT len) } bool CArchiveRecovery::recoverAce(CFile *aceInput, CFile *aceOutput, archiveScannerThreadParams_s *aitp - , CTypedPtrList *filled) + , CArray *paFilled) { make_crctable(); ACE_ARCHIVEHEADER *acehdr = NULL; @@ -1134,14 +1060,15 @@ bool CArchiveRecovery::recoverAce(CFile *aceInput, CFile *aceOutput, archiveScan try { UINT64 filesearchstart = 0; // Try to get file header and main header - if (IsFilled(0, 32, filled)) { + if (IsFilled(0, 32, paFilled)) { static const char ACE_ID[] = {0x2A, 0x2A, 0x41, 0x43, 0x45, 0x2A, 0x2A}; acehdr = new ACE_ARCHIVEHEADER; UINT hdrread = aceInput->Read((void*)acehdr, sizeof(ACE_ARCHIVEHEADER) - (3 * sizeof(char*)) - sizeof(uint16)); - if (memcmp(acehdr->HEAD_SIGN, ACE_ID, sizeof ACE_ID) != 0 || acehdr->HEAD_TYPE != 0 - || !IsFilled(0, acehdr->HEAD_SIZE, filled)) + if (memcmp(acehdr->HEAD_SIGN, ACE_ID, sizeof ACE_ID) != 0 + || acehdr->HEAD_TYPE != 0 + || !IsFilled(0, acehdr->HEAD_SIZE, paFilled)) { delete acehdr; acehdr = NULL; @@ -1199,14 +1126,16 @@ bool CArchiveRecovery::recoverAce(CFile *aceInput, CFile *aceOutput, archiveScan acehdr = NULL; } - // loop filled blocks - for (POSITION pos = filled->GetHeadPosition(); pos != NULL;) { - const Gap_Struct *fill = filled->GetNext(pos); + // loop on filled blocks + const INT_PTR iLast = paFilled->GetCount() - 1; + for (INT_PTR i = 0; i <= iLast; ++i) { + const Gap_Struct &fill = (*paFilled)[i]; - filesearchstart = (filesearchstart < fill->start) ? fill->start : filesearchstart; + if (filesearchstart < fill.start) + filesearchstart = fill.start; aceInput->Seek(filesearchstart, CFile::begin); - while ((block = scanForAceFileHeader(aceInput, aitp, (fill->end - filesearchstart))) != NULL) { + while ((block = scanForAceFileHeader(aceInput, aitp, (fill.end - filesearchstart))) != NULL) { if (aitp) { if (!aitp->m_bIsValid) return false; @@ -1214,7 +1143,7 @@ bool CArchiveRecovery::recoverAce(CFile *aceInput, CFile *aceOutput, archiveScan aitp->ai->ACEdir->AddTail(block); } - if (aceOutput != NULL && IsFilled(block->data_offset, block->data_offset + block->PACK_SIZE, filled)) { + if (aceOutput != NULL && IsFilled(block->data_offset, block->data_offset + block->PACK_SIZE, paFilled)) { // Don't include directories in file count //if ((block->HEAD_FLAGS & 0xE0) != 0xE0) // ++fileCount; @@ -1227,7 +1156,7 @@ bool CArchiveRecovery::recoverAce(CFile *aceInput, CFile *aceOutput, archiveScan block = NULL; } - if (aceInput->GetPosition() >= fill->end) + if (aceInput->GetPosition() >= fill.end) break; } } @@ -1257,20 +1186,17 @@ ACE_BlockFile* CArchiveRecovery::scanForAceFileHeader(CFile *input, archiveScann break; available -= lenChunk; - BYTE *foundPos = &chunk[0]; - // Move back one, will be incremented in loop - --foundPos; - while (foundPos != NULL) { + for (BYTE *foundPos = chunk; foundPos != NULL; ++foundPos) { if (aitp && !aitp->m_bIsValid) return NULL; // Find rar head block marker - foundPos = (BYTE*)memchr(foundPos + 1, 0x01, (lenChunk - (foundPos + 1 - (&chunk[0])))); + foundPos = (BYTE*)memchr(foundPos, 0x01, lenChunk - (foundPos - chunk)); if (foundPos == NULL) break; - ULONGLONG chunkOffset = foundPos - (&chunk[0]); + ULONGLONG chunkOffset = foundPos - chunk; ULONGLONG foundOffset = chunkstart + chunkOffset; if (chunkOffset < 4) @@ -1305,10 +1231,10 @@ ACE_BlockFile* CArchiveRecovery::scanForAceFileHeader(CFile *input, archiveScann newblock->HEAD_SIZE = headSize; memcpy(&newblock->HEAD_TYPE, mempos, (char*)&newblock->COMM_SIZE - (char*)&newblock->HEAD_TYPE); -// sizeof(ACE_BlockFile) - 4 - (2*sizeof(newblock->COMMENT)) - sizeof(newblock->COMM_SIZE) - sizeof(newblock->data_offset) ); + //sizeof(ACE_BlockFile) - 4 - (2 * sizeof(newblock->COMMENT)) - sizeof(newblock->COMM_SIZE) - sizeof(newblock->data_offset) ); mempos += (char*)&newblock->COMM_SIZE - (char*)&newblock->HEAD_TYPE; -// mempos += sizeof(ACE_BlockFile)-sizeof(newblock->HEAD_CRC)-sizeof(newblock->HEAD_SIZE) - (2*sizeof(newblock->COMMENT)) - sizeof(newblock->COMM_SIZE) - sizeof(newblock->data_offset); + //mempos += sizeof(ACE_BlockFile)-sizeof(newblock->HEAD_CRC)-sizeof(newblock->HEAD_SIZE) - (2 * sizeof(newblock->COMMENT)) - sizeof(newblock->COMM_SIZE) - sizeof(newblock->data_offset); // basic checks if (newblock->HEAD_SIZE < newblock->FNAME_SIZE) { @@ -1326,7 +1252,7 @@ ACE_BlockFile* CArchiveRecovery::scanForAceFileHeader(CFile *input, archiveScann mempos += newblock->FNAME_SIZE; } - //int blockleft = newblock->HEAD_SIZE - newblock->FNAME_SIZE - (sizeof(ACE_BlockFile)- (3*sizeof(uint16)) - sizeof(newblock->data_offset) - 2*sizeof(char*)); + //int blockleft = newblock->HEAD_SIZE - newblock->FNAME_SIZE - (sizeof(ACE_BlockFile)- (3 * sizeof(uint16)) - sizeof(newblock->data_offset) - 2 * sizeof(char*)); if (mempos < blockmem + newblock->HEAD_SIZE) { memcpy(&newblock->COMM_SIZE, mempos, sizeof newblock->COMM_SIZE); @@ -1402,8 +1328,6 @@ void CArchiveRecovery::writeAceBlock(CFile *input, CFile *output, ACE_BlockFile { ULONGLONG offsetStart = output->GetPosition(); try { -// block->data_offset = offsetStart; - writeUInt16(output, block->HEAD_CRC); writeUInt16(output, block->HEAD_SIZE); output->Write(&block->HEAD_TYPE, 1); @@ -1423,16 +1347,15 @@ void CArchiveRecovery::writeAceBlock(CFile *input, CFile *output, ACE_BlockFile output->Write(block->COMMENT, block->COMM_SIZE); } - // skip unknown data between header and compressed data - if ever existed... + // skip unknown data between header and compressed data - if any exists... // Now copy compressed data from input file uint32 lenToCopy = block->PACK_SIZE; if (lenToCopy > 0) { input->Seek(block->data_offset, CFile::begin); - BYTE chunk[4096]; for (uint32 written = 0; written < lenToCopy;) { - uint32 lenChunk = min(lenToCopy - written, sizeof chunk); - lenChunk = input->Read(chunk, lenChunk); + BYTE chunk[4096]; + uint32 lenChunk = input->Read(chunk, min(lenToCopy - written, sizeof chunk)); if (lenChunk == 0) break; output->Write(chunk, lenChunk); @@ -1515,36 +1438,34 @@ void CArchiveRecovery::ISOReadDirectory(archiveScannerThreadParams_s *aitp, UINT continue; } - if (aitp->ai->isoInfos.iJolietUnicode) //convert UTF-16BE to UTF-16LE + CString pathNew(currentDirName); + // make filename from Unicode (UTF-16BE) or ASCII + if (aitp->ai->isoInfos.iJolietUnicode) { + //convert UTF-16BE to UTF-16LE for (unsigned int i = 0; i < file->nameLen / sizeof(uint16); ++i) file->name[i] = _byteswap_ushort(file->name[i]); - - // make filename CString from ASCII or Unicode - const CString &filename(aitp->ai->isoInfos.iJolietUnicode ? CString(file->name) : CString((char*)file->name)); + pathNew += file->name; + } else + pathNew += CString((char*)file->name); free(file->name); - if (file->fileFlags & ISO_DIRECTORY) { - // store dir entry - CString pathNew; - pathNew.Format(_T("%s%s\\"), (LPCTSTR)currentDirName, (LPCTSTR)filename); - file->name = _tcsdup(pathNew); - aitp->ai->ISOdir->AddTail(file); + if (file->fileFlags & ISO_DIRECTORY) + slosh(pathNew); //make this a directory path + // store the entry + file->name = _tcsdup(pathNew); + aitp->ai->ISOdir->AddTail(file); - // read subdirectory recursively + if (file->fileFlags & ISO_DIRECTORY) { + // read subdirectories recursively LONGLONG curpos = isoInput->GetPosition(); ISOReadDirectory(aitp, LODWORD(file->sector1OfExtension), isoInput, pathNew); isoInput->Seek(curpos, FILE_BEGIN); - } else { - // store file entry - const CString &fullpath(currentDirName + filename); - file->name = _tcsdup(fullpath); - aitp->ai->ISOdir->AddTail(file); } } } bool CArchiveRecovery::recoverISO(CFile *isoInput, CFile *isoOutput, archiveScannerThreadParams_s *aitp - , CTypedPtrList *filled) + , CArray *paFilled) { if (isoOutput) return false; @@ -1554,7 +1475,7 @@ bool CArchiveRecovery::recoverISO(CFile *isoInput, CFile *isoOutput, archiveScan uint64 nextstart = 16 * SECSIZE; // do we have the primary volume descriptor? - if (!IsFilled(nextstart, nextstart + SECSIZE, filled)) + if (!IsFilled(nextstart, nextstart + SECSIZE, paFilled)) return false; ISO_PVD_s pvd, svd, tempSec; @@ -1616,7 +1537,7 @@ bool CArchiveRecovery::recoverISO(CFile *isoInput, CFile *isoOutput, archiveScan iUdfDetectState += 2; // remember Terminating Extended Area Descriptor (TEA) received } - } while (IsFilled(nextstart, nextstart + SECSIZE, filled)); + } while (IsFilled(nextstart, nextstart + SECSIZE, paFilled)); if (iUdfDetectState == 4) aitp->ai->isoInfos.type |= ISOtype_UDF_nsr02; diff --git a/srchybrid/ArchiveRecovery.h b/srchybrid/ArchiveRecovery.h index 48ab9dc3..52927e74 100644 --- a/srchybrid/ArchiveRecovery.h +++ b/srchybrid/ArchiveRecovery.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -193,7 +193,7 @@ static unsigned char sig_udf_bea[5] = {0x42, 0x45, 0x41, 0x30, 0x31}; // "BEA01 static unsigned char sig_udf_nsr2[5] = {0x4e, 0x53, 0x52, 0x30, 0x32}; // "NSR02" static unsigned char sig_udf_nsr3[5] = {0x4e, 0x53, 0x52, 0x30, 0x33}; // "NSR03" static unsigned char sig_tea[5] = {0x54, 0x45, 0x41, 0x30, 0x31}; // "TEA01" -static const unsigned char sElToritoID[] = "EL TORITO SPECIFICATION"; +static unsigned char sElToritoID[] = "EL TORITO SPECIFICATION"; enum ISO_ImageType { @@ -348,7 +348,7 @@ struct ISOInfos_s struct ThreadParam { CPartFile *partFile; - CTypedPtrList *filled; + CArray *filled; bool preview; bool bCreatePartFileCopy; }; @@ -384,7 +384,7 @@ struct archiveScannerThreadParams_s { CShareableFile *file; archiveinfo_s *ai; - CTypedPtrList *filled; + CArray *filled; int type; HWND ownerHwnd; HWND progressHwnd; @@ -396,20 +396,20 @@ class CArchiveRecovery { public: static void recover(CPartFile *partFile, bool preview = false, bool bCreatePartFileCopy = true); - static bool recoverZip(CFile *zipInput, CFile *zipOutput, archiveScannerThreadParams_s *aitp, CTypedPtrList *filled, bool fullSize); - static bool recoverRar(CFile *rarInput, CFile *rarOutput, archiveScannerThreadParams_s *aitp, CTypedPtrList *filled); - static bool recoverAce(CFile *aceInput, CFile *aceOutput, archiveScannerThreadParams_s *aitp, CTypedPtrList *filled); - static bool recoverISO(CFile *isoInput, CFile *isoOutput, archiveScannerThreadParams_s *aitp, CTypedPtrList *filled); + static bool recoverZip(CFile *zipInput, CFile *zipOutput, archiveScannerThreadParams_s *aitp, CArray *paFilled, bool fullSize); + static bool recoverRar(CFile *rarInput, CFile *rarOutput, archiveScannerThreadParams_s *aitp, CArray *paFilled); + static bool recoverAce(CFile *aceInput, CFile *aceOutput, archiveScannerThreadParams_s *aitp, CArray *paFilled); + static bool recoverISO(CFile *isoInput, CFile *isoOutput, archiveScannerThreadParams_s *aitp, CArray *paFilled); private: CArchiveRecovery(); // Just use static recover method static UINT AFX_CDECL run(LPVOID lpParam); - static bool performRecovery(CPartFile *partFile, CTypedPtrList *filled, bool preview, bool bCreatePartFileCopy = true); + static bool performRecovery(CPartFile *partFile, CArray *paFilled, bool preview, bool bCreatePartFileCopy = true); static bool scanForZipMarker(CFile *input, archiveScannerThreadParams_s *aitp, uint32 marker, ULONGLONG available); static bool processZipEntry(CFile *zipInput, CFile *zipOutput, uint32 available, CTypedPtrList *centralDirectoryEntries); - static bool readZipCentralDirectory(CFile *zipInput, CTypedPtrList *centralDirectoryEntries, CTypedPtrList *filled); + static bool readZipCentralDirectory(CFile *zipInput, CTypedPtrList *centralDirectoryEntries, CArray *filled); static RAR_BlockFile* scanForRarFileHeader(CFile *input, archiveScannerThreadParams_s *aitp, ULONGLONG available); static bool validateRarFileBlock(RAR_BlockFile *block); @@ -419,9 +419,8 @@ class CArchiveRecovery static void writeAceBlock(CFile *input, CFile *output, ACE_BlockFile *block); static void writeAceHeader(CFile *output, ACE_ARCHIVEHEADER *hdr); - static bool CopyPartFile(CPartFile *partFile, CTypedPtrList *filled, const CString &tempFileName); static void DeleteMemory(ThreadParam *tp); - static bool IsFilled(uint64 start, uint64 end, CTypedPtrList *filled); + static bool IsFilled(uint64 start, uint64 end, CArray *filled); static void ISOReadDirectory(archiveScannerThreadParams_s *aitp, UINT32 startSec, CFile *isoInput, const CString ¤tDirName); diff --git a/srchybrid/AsyncProxySocketLayer.cpp b/srchybrid/AsyncProxySocketLayer.cpp index dbbde56d..80713ef8 100644 --- a/srchybrid/AsyncProxySocketLayer.cpp +++ b/srchybrid/AsyncProxySocketLayer.cpp @@ -293,7 +293,7 @@ void CAsyncProxySocketLayer::OnReceive(int nErrorCode) if (m_nRecvBufferPos == 8) { TRACE(_T("SOCKS4 response: VN=%u CD=%u DSTPORT=%u DSTIP=%s\n"), (BYTE)m_pRecvBuffer[0], (BYTE)m_pRecvBuffer[1], ntohs(*(u_short*)&m_pRecvBuffer[2]), (LPCTSTR)ipstr(*(u_long*)&m_pRecvBuffer[4])); if (m_pRecvBuffer[0] != 0 || m_pRecvBuffer[1] != 90) { - DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, (LPSTR)(LPCSTR)GetSocks4Error(m_pRecvBuffer[0], m_pRecvBuffer[1])); + DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, const_cast((LPCSTR)GetSocks4Error(m_pRecvBuffer[0], m_pRecvBuffer[1]))); TriggerEvent((m_nProxyOpID == PROXYOP_CONNECT) ? FD_CONNECT : FD_ACCEPT, WSAECONNABORTED, TRUE); Reset(); ClearBuffer(); @@ -377,7 +377,7 @@ void CAsyncProxySocketLayer::OnReceive(int nErrorCode) if (m_nRecvBufferPos == 2) { TRACE(_T("SOCKS5 response: VER=%u METHOD=%u\n"), (BYTE)m_pRecvBuffer[0], (BYTE)m_pRecvBuffer[1]); if (m_pRecvBuffer[0] != 5) { - DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, (LPSTR)(LPCSTR)GetSocks5Error(m_pRecvBuffer[1])); + DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, const_cast((LPCSTR)GetSocks5Error(m_pRecvBuffer[1]))); TriggerEvent((m_nProxyOpID == PROXYOP_CONNECT) ? FD_CONNECT : FD_ACCEPT, WSAECONNABORTED, TRUE); Reset(); ClearBuffer(); @@ -416,13 +416,13 @@ void CAsyncProxySocketLayer::OnReceive(int nErrorCode) // PASSWD field that follows. The PASSWD field contains the password // association with the given UNAME. - const CStringA &sAsciiUser((CStringA)m_ProxyData.pProxyUser); - const CStringA &sAsciiPass((CStringA)m_ProxyData.pProxyPass); + const CStringA sAsciiUser(m_ProxyData.pProxyUser); + const CStringA sAsciiPass(m_ProxyData.pProxyPass); int nLenUser = sAsciiUser.GetLength(); int nLenPass = sAsciiPass.GetLength(); ASSERT(nLenUser <= 255); ASSERT(nLenPass <= 255); - unsigned char *buffer = new unsigned char[3 + nLenUser + nLenPass]; + unsigned char *buffer = new unsigned char[3 + (size_t)nLenUser + nLenPass]; buffer[0] = 1; buffer[1] = static_cast(nLenUser); if (nLenUser) @@ -450,7 +450,7 @@ void CAsyncProxySocketLayer::OnReceive(int nErrorCode) //Send connection request const CStringA sAsciiHost(m_pProxyPeerHost); size_t nlen = sAsciiHost.GetLength(); - char *command = new char[10 + nlen + 1](); + char *command = new char[10 + nlen + 1]{}; command[0] = 5; command[1] = static_cast(m_nProxyOpID); //command[2]=0; @@ -509,7 +509,7 @@ void CAsyncProxySocketLayer::OnReceive(int nErrorCode) } const CStringA sAsciiHost(m_pProxyPeerHost); size_t nlen = sAsciiHost.GetLength(); - char *command = new char[10 + nlen + 1](); + char *command = new char[10 + nlen + 1]{}; command[0] = 5; command[1] = static_cast(m_nProxyOpID); //command[2]=0; @@ -618,7 +618,7 @@ void CAsyncProxySocketLayer::OnReceive(int nErrorCode) TRACE(_T("SOCKS5 response: VER=%u REP=%u RSV=%u ATYP=%u BND.ADDR=%s BND.PORT=%u\n"), (BYTE)m_pRecvBuffer[0], (BYTE)m_pRecvBuffer[1], (BYTE)m_pRecvBuffer[2], (BYTE)m_pRecvBuffer[3], (LPCTSTR)ipstr(*(u_long*)&m_pRecvBuffer[4]), ntohs(*(u_short*)&m_pRecvBuffer[8])); if (m_nRecvBufferPos == 10) { if (m_pRecvBuffer[1] != 0) { - DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, (LPSTR)(LPCSTR)GetSocks5Error(m_pRecvBuffer[1])); + DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, const_cast((LPCSTR)GetSocks5Error(m_pRecvBuffer[1]))); if (m_nProxyOpID == PROXYOP_CONNECT) TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE); else { @@ -681,7 +681,7 @@ void CAsyncProxySocketLayer::OnReceive(int nErrorCode) char *pos2 = strchr(m_pStrBuffer, ' '); if (!pos2 || pos2[1] != '2' || pos2 > pos) { CStringA serr(m_pStrBuffer, (int)(pos - m_pStrBuffer)); - DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, (LPSTR)(LPCSTR)serr); + DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, const_cast((LPCSTR)serr)); Reset(); ClearBuffer(); TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE); @@ -814,8 +814,8 @@ void CAsyncProxySocketLayer::OnConnect(int nErrorCode) const CStringA sAscii(m_pProxyPeerHost); ASSERT(!sAscii.IsEmpty()); - size_t nLen1 = sAscii.GetLength() + 1; - char *command = new char[9 + nLen1](); + size_t nLen1 = (size_t)sAscii.GetLength() + 1; + char *command = new char[9 + nLen1]{}; int nBufLen = 9; command[0] = 4; command[1] = static_cast(m_nProxyOpID); //CONNECT or BIND request diff --git a/srchybrid/AsyncProxySocketLayer.h b/srchybrid/AsyncProxySocketLayer.h index 17951905..2c8f3396 100644 --- a/srchybrid/AsyncProxySocketLayer.h +++ b/srchybrid/AsyncProxySocketLayer.h @@ -189,7 +189,7 @@ class CAsyncProxySocketLayer : public CAsyncSocketExLayer CString m_pProxyPeerHost;//The host connected to }; -//Errorcodes +//Error codes #define PROXYERROR_NOERROR 0 #define PROXYERROR_NOCONN 1 //Can't connect to proxy server, use GetLastError for more information #define PROXYERROR_REQUESTFAILED 2 //Request failed, can't send data diff --git a/srchybrid/AsyncSocketEx.cpp b/srchybrid/AsyncSocketEx.cpp index e74b3a61..e1cefca8 100644 --- a/srchybrid/AsyncSocketEx.cpp +++ b/srchybrid/AsyncSocketEx.cpp @@ -89,19 +89,19 @@ class CAsyncSocketExHelperWindow { static LPCTSTR const sHelperWnd = _T("CAsyncSocketEx Helper Window"); //Initialize data - m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[m_nWindowDataSize](); //Reserve space for 512 active sockets + m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[m_nWindowDataSize]{}; //Reserve space for 512 active sockets //Create window - WNDCLASSEX wndclass = {}; + WNDCLASSEX wndclass{}; wndclass.cbSize = (UINT)sizeof wndclass; wndclass.lpfnWndProc = WindowProc; - wndclass.hInstance = GetModuleHandle(NULL); + wndclass.hInstance = ::GetModuleHandle(NULL); wndclass.lpszClassName = sHelperWnd; ::RegisterClassEx(&wndclass); //Starting from Win2000, system supports message-only windows that are not visible, //have no z-order, cannot be enumerated, and do not receive broadcast messages. - m_hWnd = ::CreateWindow(sHelperWnd, sHelperWnd, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, ::GetModuleHandle(0)); + m_hWnd = ::CreateWindow(sHelperWnd, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL,0); if (m_hWnd) ::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG_PTR)this); else @@ -136,7 +136,7 @@ class CAsyncSocketExHelperWindow if (!m_nWindowDataSize) { ASSERT(!m_nSocketCount); m_nWindowDataSize = 512; - m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[512](); //Reserve space for 512 active sockets + m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[512]{}; //Reserve space for 512 active sockets } if (nSocketIndex >= 0) { @@ -144,7 +144,7 @@ class CAsyncSocketExHelperWindow ASSERT(m_nWindowDataSize > nSocketIndex); ASSERT(m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket == pSocket); ASSERT(m_nSocketCount); - return TRUE; //m_pAsyncSocketExWindowData != NULL; + return m_pAsyncSocketExWindowData != NULL; } //Increase socket storage if too small @@ -178,49 +178,47 @@ class CAsyncSocketExHelperWindow } //Removes a socket from the socket storage - BOOL RemoveSocket(CAsyncSocketEx *pSocket, int &nSocketIndex) + BOOL RemoveSocket(const CAsyncSocketEx *pSocket, int &nSocketIndex) { if (!pSocket) { ASSERT(0); return FALSE; } - if (nSocketIndex < 0) - return TRUE; - - // Remove additional messages from queue - MSG msg; - while (PeekMessage(&msg, m_hWnd, WM_SOCKETEX_NOTIFY + nSocketIndex, WM_SOCKETEX_NOTIFY + nSocketIndex, PM_REMOVE)); - - ASSERT(m_pAsyncSocketExWindowData); - ASSERT(m_nWindowDataSize > 0); - ASSERT(m_nSocketCount > 0); - ASSERT(m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket == pSocket); - m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket = NULL; - nSocketIndex = -1; - --m_nSocketCount; + if (nSocketIndex >= 0) { + // Remove additional messages from queue + MSG msg; + while (::PeekMessage(&msg, m_hWnd, WM_SOCKETEX_NOTIFY + nSocketIndex, WM_SOCKETEX_NOTIFY + nSocketIndex, PM_REMOVE)); + ASSERT(m_pAsyncSocketExWindowData); + ASSERT(m_nWindowDataSize > 0); + ASSERT(m_nSocketCount > 0); + ASSERT(m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket == pSocket); + m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket = NULL; + nSocketIndex = -1; + --m_nSocketCount; + } return TRUE; } - void RemoveLayers(CAsyncSocketEx *pOrigSocket) + void RemoveLayers(const CAsyncSocketEx *pOrigSocket) { // Remove all layer messages from old socket - std::list msgList; - MSG msg; - while (PeekMessage(&msg, m_hWnd, WM_SOCKETEX_TRIGGER, WM_SOCKETEX_TRIGGER, PM_REMOVE)) { + std::vector msgList; + + for (MSG msg; ::PeekMessage(&msg, m_hWnd, WM_SOCKETEX_TRIGGER, WM_SOCKETEX_TRIGGER, PM_REMOVE);) { //Verify parameters, lookup socket and notification message if (msg.wParam >= static_cast(m_nWindowDataSize)) //Index is within socket storage continue; CAsyncSocketEx *pSocket = m_pAsyncSocketExWindowData[msg.wParam].m_pSocket; CAsyncSocketExLayer::t_LayerNotifyMsg *pMsg = reinterpret_cast(msg.lParam); - if (!pMsg || !pSocket || pSocket == pOrigSocket || pSocket->m_SocketData.hSocket != pMsg->hSocket) + if (!pMsg || !pSocket || pSocket->m_SocketData.hSocket == INVALID_SOCKET || pSocket == pOrigSocket || pSocket->m_SocketData.hSocket != pMsg->hSocket) delete pMsg; else msgList.push_back(msg); } - for (std::list::const_iterator iter = msgList.begin(); iter != msgList.end(); ++iter) + for (std::vector::const_iterator iter = msgList.begin(); iter != msgList.end(); ++iter) if (!::PostMessage(m_hWnd, iter->message, iter->wParam, iter->lParam)) delete reinterpret_cast(iter->lParam); } @@ -305,10 +303,8 @@ class CAsyncSocketExHelperWindow #ifndef NOSOCKETSTATES // netfinity: Check that socket is still valid. It might have got deleted. - if (!nErrorCode && pWnd->m_pAsyncSocketExWindowData && pSocket == pWnd->m_pAsyncSocketExWindowData[message - WM_SOCKETEX_NOTIFY].m_pSocket) { - if ((pSocket->m_nPendingEvents & FD_READ) && pSocket->GetState() == connected) - pSocket->OnReceive(0); - if ((pSocket->m_nPendingEvents & FD_FORCEREAD) && pSocket->GetState() == connected) + if (!nErrorCode && pWnd->m_pAsyncSocketExWindowData && pSocket == pWnd->m_pAsyncSocketExWindowData[message - WM_SOCKETEX_NOTIFY].m_pSocket) { + if ((pSocket->m_nPendingEvents & (FD_READ | FD_FORCEREAD)) && pSocket->GetState() == connected) pSocket->OnReceive(0); if ((pSocket->m_nPendingEvents & FD_WRITE) && pSocket->GetState() == connected) pSocket->OnSend(0); @@ -498,7 +494,7 @@ class CAsyncSocketExHelperWindow if (pWnd->m_pThreadData->layerCloseNotify.empty()) ::KillTimer(hWnd, 1); if (socket) - ::PostMessage(hWnd, socket->m_SocketData.nSocketIndex + WM_SOCKETEX_NOTIFY, socket->m_SocketData.hSocket, FD_CLOSE); + ::PostMessage(hWnd, WM_SOCKETEX_NOTIFY + socket->m_SocketData.nSocketIndex, socket->m_SocketData.hSocket, FD_CLOSE); } return 0; case WM_SOCKETEX_GETHOST: //WSAAsyncGetHostByName reply @@ -559,7 +555,7 @@ class CAsyncSocketExHelperWindow return 0; // Process pending callbacks - std::list tmp; + std::vector tmp; tmp.swap(pSocket->m_pendingCallbacks); pSocket->OnLayerCallback(tmp); } @@ -662,7 +658,7 @@ bool CAsyncSocketEx::Create(UINT nSocketPort /*=0*/, int nSocketType /*=SOCK_STR if (m_pFirstLayer) { m_lEvent = lEvent; - if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex + WM_SOCKETEX_NOTIFY, FD_DEFAULT)) { + if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), WM_SOCKETEX_NOTIFY + m_SocketData.nSocketIndex, FD_DEFAULT)) { Close(); return false; } @@ -829,8 +825,16 @@ bool CAsyncSocketEx::InitAsyncSocketExInstance() if (!m_pLocalAsyncSocketExThreadData) { // Get thread specific data if (!thread_local_data) { - thread_local_data = new t_AsyncSocketExThreadData(); - thread_local_data->m_pHelperWindow = new CAsyncSocketExHelperWindow(thread_local_data); + try { + thread_local_data = new t_AsyncSocketExThreadData{}; + thread_local_data->m_pHelperWindow = new CAsyncSocketExHelperWindow(thread_local_data); + } catch (...) { + if (thread_local_data) { + delete thread_local_data; + thread_local_data = NULL; + } + return false; + } } m_pLocalAsyncSocketExThreadData = thread_local_data; ++m_pLocalAsyncSocketExThreadData->nInstanceCount; @@ -844,13 +848,13 @@ void CAsyncSocketEx::FreeAsyncSocketExInstance() if (!m_pLocalAsyncSocketExThreadData) return; - for (std::list::const_iterator iter = m_pLocalAsyncSocketExThreadData->layerCloseNotify.begin(); iter != m_pLocalAsyncSocketExThreadData->layerCloseNotify.end(); ++iter) - if (*iter == this) { - m_pLocalAsyncSocketExThreadData->layerCloseNotify.erase(iter); - if (m_pLocalAsyncSocketExThreadData->layerCloseNotify.empty()) - ::KillTimer(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd(), 1); - break; - } + std::list &socks = m_pLocalAsyncSocketExThreadData->layerCloseNotify; + std::list::const_iterator iter = std::find(socks.begin(), socks.end(), this); + if (iter != socks.end()) { + socks.erase(iter); + if (socks.empty()) + ::KillTimer(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd(), 1); + } if (!--m_pLocalAsyncSocketExThreadData->nInstanceCount) { m_pLocalAsyncSocketExThreadData = NULL; @@ -1061,7 +1065,7 @@ BOOL CAsyncSocketEx::Attach(SOCKET hSocket, long lEvent /*= FD_DEFAULT*/) if (m_pFirstLayer) { m_lEvent = lEvent; - return !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex + WM_SOCKETEX_NOTIFY, FD_DEFAULT); + return !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), WM_SOCKETEX_NOTIFY + m_SocketData.nSocketIndex, FD_DEFAULT); } return AsyncSelect(lEvent); } @@ -1074,7 +1078,7 @@ BOOL CAsyncSocketEx::AsyncSelect(long lEvent /*= FD_DEFAULT*/) return TRUE; if (m_SocketData.hSocket == INVALID_SOCKET && m_SocketData.nFamily == AF_UNSPEC) return TRUE; - return !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex + WM_SOCKETEX_NOTIFY, lEvent); + return !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), WM_SOCKETEX_NOTIFY + m_SocketData.nSocketIndex, lEvent); } BOOL CAsyncSocketEx::Listen(int nConnectionBacklog /*=5*/) @@ -1139,7 +1143,7 @@ BOOL CAsyncSocketEx::TriggerEvent(long lEvent) delete pMsg; return res; } - return ::PostMessage(GetHelperWindowHandle(), m_SocketData.nSocketIndex + WM_SOCKETEX_NOTIFY, m_SocketData.hSocket, WSAGETSELECTEVENT(lEvent)); + return ::PostMessage(GetHelperWindowHandle(), WM_SOCKETEX_NOTIFY + m_SocketData.nSocketIndex, m_SocketData.hSocket, WSAGETSELECTEVENT(lEvent)); } SOCKET CAsyncSocketEx::GetSocketHandle() @@ -1149,9 +1153,7 @@ SOCKET CAsyncSocketEx::GetSocketHandle() HWND CAsyncSocketEx::GetHelperWindowHandle() { - if (!m_pLocalAsyncSocketExThreadData) - return 0; - if (!m_pLocalAsyncSocketExThreadData->m_pHelperWindow) + if (!m_pLocalAsyncSocketExThreadData || !m_pLocalAsyncSocketExThreadData->m_pHelperWindow) return 0; return m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd(); } @@ -1171,7 +1173,7 @@ BOOL CAsyncSocketEx::AddLayer(CAsyncSocketExLayer *pLayer) m_pLastLayer = m_pFirstLayer; return m_SocketData.hSocket == INVALID_SOCKET - || !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex + WM_SOCKETEX_NOTIFY, FD_DEFAULT); + || !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), WM_SOCKETEX_NOTIFY + m_SocketData.nSocketIndex, FD_DEFAULT); } void CAsyncSocketEx::RemoveAllLayers() @@ -1185,11 +1187,11 @@ void CAsyncSocketEx::RemoveAllLayers() m_pLocalAsyncSocketExThreadData->m_pHelperWindow->RemoveLayers(this); } -int CAsyncSocketEx::OnLayerCallback(std::list &callbacks) +int CAsyncSocketEx::OnLayerCallback(std::vector &callbacks) { while (!callbacks.empty()) { - delete[] callbacks.begin()->str; - callbacks.pop_front(); + delete[] callbacks.back().str; + callbacks.pop_back(); } return 0; } @@ -1253,7 +1255,7 @@ bool CAsyncSocketEx::TryNextProtocol() AttachHandle(); if (AsyncSelect(m_lEvent)) - if (!m_pFirstLayer || !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex + WM_SOCKETEX_NOTIFY, FD_DEFAULT)) + if (!m_pFirstLayer || !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), WM_SOCKETEX_NOTIFY + m_SocketData.nSocketIndex, FD_DEFAULT)) if (Bind(m_nSocketPort, m_sSocketAddress)) { ret = Connect(m_SocketData.nextAddr->ai_addr, (int)m_SocketData.nextAddr->ai_addrlen); if (ret || GetLastError() == WSAEWOULDBLOCK) @@ -1285,14 +1287,13 @@ void CAsyncSocketEx::AddCallbackNotification(const t_callbackMsg &msg) void CAsyncSocketEx::ResendCloseNotify() { - for (std::list::const_iterator iter = m_pLocalAsyncSocketExThreadData->layerCloseNotify.begin(); iter != m_pLocalAsyncSocketExThreadData->layerCloseNotify.end(); ++iter) - if (*iter == this) - return; - - m_pLocalAsyncSocketExThreadData->layerCloseNotify.push_back(this); - if (m_pLocalAsyncSocketExThreadData->layerCloseNotify.size() == 1) - ::SetTimer(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd(), 1, 10, NULL); - + std::list &socks = m_pLocalAsyncSocketExThreadData->layerCloseNotify; + std::list::const_iterator iter = std::find(socks.begin(), socks.end(), this); + if (iter == socks.end()) { + m_pLocalAsyncSocketExThreadData->layerCloseNotify.push_back(this); + if (m_pLocalAsyncSocketExThreadData->layerCloseNotify.size() == 1) + ::SetTimer(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd(), 1, 10, NULL); + } } #ifdef _DEBUG void CAsyncSocketEx::AssertValid() const @@ -1306,9 +1307,8 @@ void CAsyncSocketEx::AssertValid() const (void)m_nAsyncGetHostByNamePort; (void)m_nSocketPort; (void)m_pendingCallbacks; - - CHECK_PTR(m_pFirstLayer); - CHECK_PTR(m_pLastLayer); + (void)m_pFirstLayer; + (void)m_pLastLayer; } #endif diff --git a/srchybrid/AsyncSocketEx.h b/srchybrid/AsyncSocketEx.h index cf550fcc..2511db8d 100644 --- a/srchybrid/AsyncSocketEx.h +++ b/srchybrid/AsyncSocketEx.h @@ -72,6 +72,7 @@ to tim.kosse@filezilla-project.org #define FD_DEFAULT (FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE) #include +#include #define _afxSockThreadState AfxGetModuleThreadState() #define _AFX_SOCK_THREAD_STATE AFX_MODULE_THREAD_STATE @@ -236,7 +237,7 @@ class CAsyncSocketEx : public CObject //Returns the handle of the socket. SOCKET GetSocketHandle(); - //Trigers an event on the socket + //Triggers an event on the socket // Any combination of FD_READ, FD_WRITE, FD_CLOSE, FD_ACCEPT, FD_CONNECT and FD_FORCEREAD is valid for lEvent. BOOL TriggerEvent(long lEvent); @@ -313,14 +314,14 @@ class CAsyncSocketEx : public CObject CAsyncSocketExLayer *m_pLastLayer; //Called by the layers to notify application of some events - virtual int OnLayerCallback(std::list &callbacks); + virtual int OnLayerCallback(std::vector &callbacks); // Used by Bind with AF_UNSPEC sockets UINT m_nSocketPort; CString m_sSocketAddress; // Pending callbacks - std::list m_pendingCallbacks; + std::vector m_pendingCallbacks; }; #define LAYERCALLBACK_STATECHANGE 0 diff --git a/srchybrid/AsyncSocketExLayer.cpp b/srchybrid/AsyncSocketExLayer.cpp index b9225d9b..2cc6fafa 100644 --- a/srchybrid/AsyncSocketExLayer.cpp +++ b/srchybrid/AsyncSocketExLayer.cpp @@ -312,7 +312,7 @@ bool CAsyncSocketExLayer::ConnectNext(const CString &sHostAddress, UINT nHostPor m_pOwnerSocket->m_SocketData.hSocket = hSocket; m_pOwnerSocket->AttachHandle(); if (!m_pOwnerSocket->AsyncSelect(m_lEvent) - || (m_pOwnerSocket->m_pFirstLayer && WSAAsyncSelect(m_pOwnerSocket->m_SocketData.hSocket, m_pOwnerSocket->GetHelperWindowHandle(), m_pOwnerSocket->m_SocketData.nSocketIndex + WM_SOCKETEX_NOTIFY, FD_DEFAULT))) + || (m_pOwnerSocket->m_pFirstLayer && WSAAsyncSelect(m_pOwnerSocket->m_SocketData.hSocket, m_pOwnerSocket->GetHelperWindowHandle(), WM_SOCKETEX_NOTIFY + m_pOwnerSocket->m_SocketData.nSocketIndex, FD_DEFAULT))) { m_pOwnerSocket->Close(); continue; @@ -603,7 +603,7 @@ bool CAsyncSocketExLayer::CreateNext(UINT nSocketPort, int nSocketType, long lEv m_pOwnerSocket->Close(); return false; } - if (m_pOwnerSocket->m_pFirstLayer && WSAAsyncSelect(m_pOwnerSocket->m_SocketData.hSocket, m_pOwnerSocket->GetHelperWindowHandle(), m_pOwnerSocket->m_SocketData.nSocketIndex + WM_SOCKETEX_NOTIFY, FD_DEFAULT)) { + if (m_pOwnerSocket->m_pFirstLayer && WSAAsyncSelect(m_pOwnerSocket->m_SocketData.hSocket, m_pOwnerSocket->GetHelperWindowHandle(), WM_SOCKETEX_NOTIFY + m_pOwnerSocket->m_SocketData.nSocketIndex, FD_DEFAULT)) { m_pOwnerSocket->Close(); return false; } @@ -624,7 +624,7 @@ bool CAsyncSocketExLayer::CreateNext(UINT nSocketPort, int nSocketType, long lEv return ret; } -int CAsyncSocketExLayer::DoLayerCallback(int nType, WPARAM wParam, LPARAM lParam, char *str /*=NULL*/) +int CAsyncSocketExLayer::DoLayerCallback(int nType, WPARAM wParam, LPARAM lParam, const char* const str /*=NULL*/) { if (m_pOwnerSocket) { int nError = WSAGetLastError(); @@ -748,7 +748,7 @@ bool CAsyncSocketExLayer::TryNextProtocol() m_pOwnerSocket->AttachHandle(); if (m_pOwnerSocket->AsyncSelect(m_lEvent)) - if (!m_pOwnerSocket->m_pFirstLayer || !WSAAsyncSelect(m_pOwnerSocket->m_SocketData.hSocket, m_pOwnerSocket->GetHelperWindowHandle(), m_pOwnerSocket->m_SocketData.nSocketIndex + WM_SOCKETEX_NOTIFY, FD_DEFAULT)) { + if (!m_pOwnerSocket->m_pFirstLayer || !WSAAsyncSelect(m_pOwnerSocket->m_SocketData.hSocket, m_pOwnerSocket->GetHelperWindowHandle(), WM_SOCKETEX_NOTIFY + m_pOwnerSocket->m_SocketData.nSocketIndex, FD_DEFAULT)) { m_pOwnerSocket->m_SocketData.nFamily = m_nFamily = (ADDRESS_FAMILY)m_nextAddr->ai_family; if (m_pOwnerSocket->Bind(m_nSocketPort, m_sSocketAddress)) { ret = !connect(m_pOwnerSocket->GetSocketHandle(), m_nextAddr->ai_addr, (int)m_nextAddr->ai_addrlen) || WSAGetLastError() == WSAEWOULDBLOCK; diff --git a/srchybrid/AsyncSocketExLayer.h b/srchybrid/AsyncSocketExLayer.h index f20deb81..6c45433b 100644 --- a/srchybrid/AsyncSocketExLayer.h +++ b/srchybrid/AsyncSocketExLayer.h @@ -121,7 +121,7 @@ class CAsyncSocketExLayer CAsyncSocketEx *m_pOwnerSocket; //Calls OnLayerCallback on owner socket - int DoLayerCallback(int nType, WPARAM wParam, LPARAM lParam, char *str = NULL); + int DoLayerCallback(int nType, WPARAM wParam, LPARAM lParam, const char* const str = NULL); int GetLayerState() const; BOOL TriggerEvent(long lEvent, int nErrorCode, BOOL bPassThrough = FALSE); diff --git a/srchybrid/BarShader.cpp b/srchybrid/BarShader.cpp index a557f26f..f1409f07 100644 --- a/srchybrid/BarShader.cpp +++ b/srchybrid/BarShader.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -31,7 +31,7 @@ static char THIS_FILE[] = __FILE__; CBarShader::CBarShader(uint32 height, uint32 width) : m_dPixelsPerByte() , m_dBytesPerPixel() - , m_uFileSize(EMFileSize(1ull)) + , m_uFileSize(1ull) , m_iWidth(width) , m_iHeight(height) , m_bIsPreview() @@ -68,7 +68,7 @@ void CBarShader::BuildModifiers() int depth = (7 - m_used3dlevel); int count = HALF(m_iHeight); double piOverDepth = M_PI / depth; - double base = piOverDepth * ((depth / 2.0) - 1); + double base = piOverDepth * (depth / 2.0 - 1); double increment = piOverDepth / (count - 1); m_Modifiers = new float[count]; @@ -102,6 +102,12 @@ void CBarShader::SetHeight(int height) } } +void CBarShader::SetRect(const CRect & rect) +{ + SetWidth(rect.Width()); + SetHeight(rect.Height()); +} + void CBarShader::FillRange(uint64 start, uint64 end, COLORREF color) { if (end > (uint64)m_uFileSize) @@ -185,7 +191,7 @@ void CBarShader::Draw(CDC *dc, int iLeft, int iTop, bool bFlat) } while (pos != NULL); // SLUGFILLER: speedBarShader rectSpan.left = rectSpan.right; - rectSpan.right++; + ++rectSpan.right; if (g_bLowColorDesktop) FillBarRect(dc, &rectSpan, color, bFlat); else diff --git a/srchybrid/BarShader.h b/srchybrid/BarShader.h index adcb54e3..2d7c409c 100644 --- a/srchybrid/BarShader.h +++ b/srchybrid/BarShader.h @@ -12,17 +12,14 @@ class CBarShader //set the height of the bar void SetHeight(int height); + //set the width of the bar + void SetRect(const CRect &rect); + //returns the width of the bar - int GetWidth() const - { - return m_iWidth; - } + int GetWidth() const { return m_iWidth; } //returns the height of the bar - int GetHeight() const - { - return m_iHeight; - } + int GetHeight() const { return m_iHeight; } //call this to blank the shader without changing file size void Reset(); diff --git a/srchybrid/BaseClient.cpp b/srchybrid/BaseClient.cpp index e58e5964..0912a9e0 100644 --- a/srchybrid/BaseClient.cpp +++ b/srchybrid/BaseClient.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -25,7 +25,6 @@ #include "PartFile.h" #include "ListenSocket.h" #include "PeerCacheSocket.h" -#include "Friend.h" #include "Packets.h" #include "Opcodes.h" #include "SafeFile.h" @@ -33,6 +32,7 @@ #include "Server.h" #include "ClientCredits.h" #include "IPFilter.h" +#include "Friend.h" #include "Statistics.h" #include "ServerConnect.h" #include "DownloadQueue.h" @@ -237,7 +237,7 @@ void CUpDownClient::Init() m_lastRefreshedDLDisplay = 0; m_lastRefreshedULDisplay = ::GetTickCount(); - m_random_update_wait = (uint32)(rand() / (RAND_MAX / SEC2MS(1))); + m_random_update_wait = (DWORD)(rand() % SEC2MS(1)); m_fHashsetRequestingMD4 = 0; m_fSharedDirectories = 0; @@ -314,16 +314,7 @@ CUpDownClient::~CUpDownClient() while (!m_RequestedFiles_list.IsEmpty()) delete m_RequestedFiles_list.RemoveHead(); - while (!m_PendingBlocks_list.IsEmpty()) { - Pending_Block_Struct *pending = m_PendingBlocks_list.RemoveHead(); - delete pending->block; - // Not always allocated - if (pending->zStream) { - inflateEnd(pending->zStream); - delete pending->zStream; - } - delete pending; - } + ClearDownloadBlockRequests(); while (!m_WaitingPackets_list.IsEmpty()) delete m_WaitingPackets_list.RemoveHead(); @@ -374,18 +365,18 @@ bool CUpDownClient::ProcessHelloPacket(const uchar *pachPacket, uint32 nSize) data.ReadUInt8(); // read size of userhash // reset all client's properties; a client may not send a particular emule tag any longer ClearHelloProperties(); - return ProcessHelloTypePacket(&data); + return ProcessHelloTypePacket(data); } bool CUpDownClient::ProcessHelloAnswer(const uchar *pachPacket, uint32 nSize) { CSafeMemFile data(pachPacket, nSize); - bool bIsMule = ProcessHelloTypePacket(&data); + bool bIsMule = ProcessHelloTypePacket(data); m_bHelloAnswerPending = false; return bIsMule; } -bool CUpDownClient::ProcessHelloTypePacket(CSafeMemFile *data) +bool CUpDownClient::ProcessHelloTypePacket(CSafeMemFile &data) { bool bDbgInfo = thePrefs.GetUseDebugDevice(); m_strHelloInfo.Empty(); @@ -395,19 +386,19 @@ bool CUpDownClient::ProcessHelloTypePacket(CSafeMemFile *data) m_fNoViewSharedFiles = 0; m_bUnicodeSupport = false; - data->ReadHash16(m_achUserHash); + data.ReadHash16(m_achUserHash); if (bDbgInfo) m_strHelloInfo.AppendFormat(_T("Hash=%s (%s)"), (LPCTSTR)md4str(m_achUserHash), DbgGetHashTypeString(m_achUserHash)); - m_nUserIDHybrid = data->ReadUInt32(); + m_nUserIDHybrid = data.ReadUInt32(); if (bDbgInfo) m_strHelloInfo.AppendFormat(_T(" UserID=%u (%s)"), m_nUserIDHybrid, (LPCTSTR)ipstr(m_nUserIDHybrid)); - uint16 nUserPort = data->ReadUInt16(); // hmm clientport is sent twice - why? + uint16 nUserPort = data.ReadUInt16(); // hmm clientport is sent twice - why? if (bDbgInfo) m_strHelloInfo.AppendFormat(_T(" Port=%u"), nUserPort); DWORD dwEmuleTags = 0; bool bPrTag = false; - uint32 tagcount = data->ReadUInt32(); + uint32 tagcount = data.ReadUInt32(); if (bDbgInfo) m_strHelloInfo.AppendFormat(_T(" Tags=%u"), tagcount); for (uint32 i = 0; i < tagcount; ++i) { @@ -574,8 +565,8 @@ bool CUpDownClient::ProcessHelloTypePacket(CSafeMemFile *data) m_strHelloInfo.AppendFormat(_T("\n ***UnkType=%s"), (LPCTSTR)temptag.GetFullInfo()); break; default: - // Since eDonkeyHybrid 1.3 is no longer sending the additional Int32 at the end of the Hello packet, - // we use the "pr=1" tag to determine them. + // Since eDonkeyHybrid 1.3 is no longer sending the additional Int32 at the end of + // the Hello packet, we use the "pr=1" tag to determine them. if (temptag.GetName() && temptag.GetName()[0] == 'p' && temptag.GetName()[1] == 'r') bPrTag = true; @@ -584,8 +575,8 @@ bool CUpDownClient::ProcessHelloTypePacket(CSafeMemFile *data) } } m_nUserPort = nUserPort; - m_dwServerIP = data->ReadUInt32(); - m_nServerPort = data->ReadUInt16(); + m_dwServerIP = data.ReadUInt32(); + m_nServerPort = data.ReadUInt16(); if (bDbgInfo) m_strHelloInfo.AppendFormat(_T("\n Server=%s:%u"), (LPCTSTR)ipstr(m_dwServerIP), m_nServerPort); @@ -594,10 +585,10 @@ bool CUpDownClient::ProcessHelloTypePacket(CSafeMemFile *data) // *) eDonkeyHybrid 0.40 - 1.2 sends an additional Int32. (Since 1.3 they don't send it any longer.) // *) MLdonkey sends an additional Int32 // - if (data->GetPosition() < data->GetLength()) { - UINT uAddHelloDataSize = (UINT)(data->GetLength() - data->GetPosition()); + if (data.GetPosition() < data.GetLength()) { + UINT uAddHelloDataSize = (UINT)(data.GetLength() - data.GetPosition()); if (uAddHelloDataSize == sizeof(uint32)) { - uint32 test = data->ReadUInt32(); + uint32 test = data.ReadUInt32(); if (test == 'KDLM') { m_bIsML = true; if (bDbgInfo) @@ -609,8 +600,8 @@ bool CUpDownClient::ProcessHelloTypePacket(CSafeMemFile *data) } } else if (bDbgInfo) { if (uAddHelloDataSize == sizeof(uint32) + sizeof(uint16)) { - uint32 dwAddHelloInt32 = data->ReadUInt32(); - uint16 w = data->ReadUInt16(); + uint32 dwAddHelloInt32 = data.ReadUInt32(); + uint16 w = data.ReadUInt16(); m_strHelloInfo.AppendFormat(_T("\n ***AddData: uint32=%u (0x%08x), uint16=%u (0x%04x)"), dwAddHelloInt32, dwAddHelloInt32, w, w); } else m_strHelloInfo.AppendFormat(_T("\n ***AddData: %u bytes"), uAddHelloDataSize); @@ -712,8 +703,8 @@ void CUpDownClient::SendHelloPacket() CSafeMemFile data(128); data.WriteUInt8(16); // size of userhash - SendHelloTypePacket(&data); - Packet *packet = new Packet(&data); + SendHelloTypePacket(data); + Packet *packet = new Packet(data); packet->opcode = OP_HELLO; if (thePrefs.GetDebugClientTCPLevel() > 0) DebugSend("OP_Hello", this); @@ -735,25 +726,25 @@ void CUpDownClient::SendMuleInfoPacket(bool bAnswer) data.WriteUInt8(EMULE_PROTOCOL); data.WriteUInt32(7); // nr. of tags CTag tag(ET_COMPRESSION, 1); - tag.WriteTagToFile(&data); + tag.WriteTagToFile(data); CTag tag2(ET_UDPVER, 4); - tag2.WriteTagToFile(&data); + tag2.WriteTagToFile(data); CTag tag3(ET_UDPPORT, thePrefs.GetUDPPort()); - tag3.WriteTagToFile(&data); + tag3.WriteTagToFile(data); CTag tag4(ET_SOURCEEXCHANGE, 3); - tag4.WriteTagToFile(&data); + tag4.WriteTagToFile(data); CTag tag5(ET_COMMENTS, 1); - tag5.WriteTagToFile(&data); + tag5.WriteTagToFile(data); CTag tag6(ET_EXTENDEDREQUEST, 2); - tag6.WriteTagToFile(&data); + tag6.WriteTagToFile(data); uint32 dwTagValue = (theApp.clientcredits->CryptoAvailable() ? 3 : 0); if (thePrefs.CanSeeShares() != vsfaNobody) // set 'Preview supported' only if 'View Shared Files' allowed dwTagValue |= 0x80; CTag tag7(ET_FEATURES, dwTagValue); - tag7.WriteTagToFile(&data); + tag7.WriteTagToFile(data); - Packet *packet = new Packet(&data, OP_EMULEPROT); + Packet *packet = new Packet(data, OP_EMULEPROT); packet->opcode = bAnswer ? OP_EMULEINFOANSWER : OP_EMULEINFO; if (thePrefs.GetDebugClientTCPLevel() > 0) @@ -800,7 +791,7 @@ void CUpDownClient::ProcessMuleInfoPacket(const uchar *pachPacket, uint32 nSize) if (bDbgInfo) m_strMuleInfo.AppendFormat(_T(" Tags=%u"), tagcount); for (uint32 i = 0; i < tagcount; ++i) { - CTag temptag(&data, false); + CTag temptag(data, false); switch (temptag.GetNameID()) { case ET_COMPRESSION: // Bits 31- 8: 0 - reserved @@ -925,8 +916,8 @@ void CUpDownClient::SendHelloAnswer() } CSafeMemFile data(128); - SendHelloTypePacket(&data); - Packet *packet = new Packet(&data); + SendHelloTypePacket(data); + Packet *packet = new Packet(data); packet->opcode = OP_HELLOANSWER; if (thePrefs.GetDebugClientTCPLevel() > 0) DebugSend("OP_HelloAnswer", this); @@ -939,18 +930,18 @@ void CUpDownClient::SendHelloAnswer() m_bHelloAnswerPending = false; } -void CUpDownClient::SendHelloTypePacket(CSafeMemFile *data) +void CUpDownClient::SendHelloTypePacket(CSafeMemFile &data) { - data->WriteHash16(thePrefs.GetUserHash()); - data->WriteUInt32(theApp.GetID()); - data->WriteUInt16(thePrefs.GetPort()); + data.WriteHash16(thePrefs.GetUserHash()); + data.WriteUInt32(theApp.GetID()); + data.WriteUInt16(thePrefs.GetPort()); uint32 tagcount = 6; if (theApp.clientlist->GetBuddy() && theApp.IsFirewalled()) tagcount += 2; - data->WriteUInt32(tagcount); + data.WriteUInt32(tagcount); // eD2K Name @@ -1077,9 +1068,9 @@ void CUpDownClient::SendHelloTypePacket(CSafeMemFile *data) dwIP = 0; nPort = 0; } - data->WriteUInt32(dwIP); - data->WriteUInt16(nPort); -// data->WriteUInt32(dwIP); //The Hybrid added some bits here, what ARE THEY FOR? + data.WriteUInt32(dwIP); + data.WriteUInt16(nPort); +// data.WriteUInt32(dwIP); //The Hybrid added some bits here, what ARE THEY FOR? } void CUpDownClient::ProcessMuleCommentPacket(const uchar *pachPacket, uint32 nSize) @@ -1159,7 +1150,7 @@ bool CUpDownClient::Disconnected(LPCTSTR pszReason, bool bFromSocket) // ensure that all possible block requests are removed from the partfile ClearDownloadBlockRequests(); if (GetDownloadState() == DS_CONNECTED || GetDownloadState() == DS_REQHASHSET) { // successfully connected, but probably no response to our file request - theApp.clientlist->m_globDeadSourceList.AddDeadSource(this); + theApp.clientlist->m_globDeadSourceList.AddDeadSource(*this); theApp.downloadqueue->RemoveSource(this); } } @@ -1183,8 +1174,8 @@ bool CUpDownClient::Disconnected(LPCTSTR pszReason, bool bFromSocket) m_reqfile->SetAICHHashSetNeeded(true); } if (m_iFileListRequested) { - LogWarning(LOG_STATUSBAR, GetResString(IDS_SHAREDFILES_FAILED), GetUserName()); m_iFileListRequested = 0; + LogWarning(LOG_STATUSBAR, GetResString(IDS_SHAREDFILES_FAILED), GetUserName()); } if (IsFriend()) @@ -1220,7 +1211,7 @@ bool CUpDownClient::Disconnected(LPCTSTR pszReason, bool bFromSocket) { if (m_eDownloadState != DS_NONE) // Unable to connect = Remove any download state theApp.downloadqueue->RemoveSource(this); - theApp.clientlist->m_globDeadSourceList.AddDeadSource(this); + theApp.clientlist->m_globDeadSourceList.AddDeadSource(*this); bDelete = true; } @@ -1360,7 +1351,7 @@ bool CUpDownClient::TryToConnect(bool bIgnoreMaxCon, bool bNoCallbacks, CRuntime // although we filter all received IPs (server sources, source exchange) and all incoming connection attempts, // we do have to filter outgoing connection attempts here too, because we may have updated the ip filter list if (theApp.ipfilter->IsFiltered(uClientIP)) { - theStats.filteredclients++; + ++theStats.filteredclients; if (thePrefs.GetLogFilteredIPs()) AddDebugLogLine(true, (LPCTSTR)GetResString(IDS_IPFILTERED), (LPCTSTR)ipstr(uClientIP), (LPCTSTR)theApp.ipfilter->GetLastHit()); if (Disconnected(_T("IPFilter"))) { @@ -1442,7 +1433,7 @@ bool CUpDownClient::TryToConnect(bool bIgnoreMaxCon, bool bNoCallbacks, CRuntime } //////////////////////////////////////////////////////////// // 4) Direct Callback Connections - else if (SupportsDirectUDPCallback() && thePrefs.GetUDPPort() != 0 && GetConnectIP() != 0) { + if (SupportsDirectUDPCallback() && thePrefs.GetUDPPort() != 0 && GetConnectIP() != 0) { m_eConnectingState = CCS_DIRECTCALLBACK; //DebugLog(_T("Direct Callback on port %u to client %s (%s) "), GetKadPort(), (LPCTSTR)DbgGetClientInfo(), (LPCTSTR)md4str(GetUserHash())); CSafeMemFile data; @@ -1452,7 +1443,7 @@ bool CUpDownClient::TryToConnect(bool bIgnoreMaxCon, bool bNoCallbacks, CRuntime data.WriteUInt8(GetMyConnectOptions(true, false)); if (thePrefs.GetDebugClientUDPLevel() > 0) DebugSend("OP_DIRECTCALLBACKREQ", this); - Packet *packet = new Packet(&data, OP_EMULEPROT); + Packet *packet = new Packet(data, OP_EMULEPROT); packet->opcode = OP_DIRECTCALLBACKREQ; theStats.AddUpDataOverheadOther(packet->size); theApp.clientudp->SendPacket(packet, GetConnectIP(), GetKadPort(), ShouldReceiveCryptUDPPackets(), GetUserHash(), false, 0); @@ -1481,12 +1472,12 @@ bool CUpDownClient::TryToConnect(bool bIgnoreMaxCon, bool bNoCallbacks, CRuntime if (HasValidBuddyID() && Kademlia::CKademlia::IsConnected() && ((GetBuddyIP() && GetBuddyPort()) || m_reqfile != NULL)) { if (GetBuddyIP() && GetBuddyPort()) { CSafeMemFile bio(34); - bio.WriteUInt128(&Kademlia::CUInt128(GetBuddyID())); - bio.WriteUInt128(&Kademlia::CUInt128(m_reqfile->GetFileHash())); + bio.WriteUInt128(Kademlia::CUInt128(GetBuddyID())); + bio.WriteUInt128(Kademlia::CUInt128(m_reqfile->GetFileHash())); bio.WriteUInt16(thePrefs.GetPort()); if (thePrefs.GetDebugClientKadUDPLevel() > 0 || thePrefs.GetDebugClientUDPLevel() > 0) DebugSend("KadCallbackReq", this); - Packet *packet = new Packet(&bio, OP_KADEMLIAHEADER); + Packet *packet = new Packet(bio, OP_KADEMLIAHEADER); packet->opcode = KADEMLIA_CALLBACK_REQ; theStats.AddUpDataOverheadKad(packet->size); m_eConnectingState = CCS_KADCALLBACK; @@ -1494,17 +1485,17 @@ bool CUpDownClient::TryToConnect(bool bIgnoreMaxCon, bool bNoCallbacks, CRuntime theApp.clientudp->SendPacket(packet, GetBuddyIP(), GetBuddyPort(), false, NULL, true, 0); SetDownloadState(DS_WAITCALLBACKKAD); } else if (m_reqfile != NULL) { - // I don't think we should ever have a buddy without its IP (any more), but nevertheless let the functionality in - //Create search to find buddy. + // I don't think we should ever have a buddy without its IP (any more), but nevertheless let + // the functionality in CSearch try to find a buddy. Kademlia::CSearch *findSource = new Kademlia::CSearch; findSource->SetSearchType(Kademlia::CSearch::FINDSOURCE); findSource->SetTargetID(Kademlia::CUInt128(GetBuddyID())); findSource->AddFileID(Kademlia::CUInt128(m_reqfile->GetFileHash())); if (Kademlia::CKademlia::GetPrefs()->GetTotalSource() > 0 || Kademlia::CSearchManager::AlreadySearchingFor(Kademlia::CUInt128(GetBuddyID()))) { - //There are too many source lookups already or we are already searching this key. - // bad luck, as lookups aren't supposed to hapen anyway, we just let it fail, if we want - // to actually really use lookups (so buddies without known IPs), this should be reworked - // for example by adding a queuesystem for queries + // There are too many source lookups or we are already searching this key. + // bad luck, as lookups aren't supposed to hapen anyway, we just let it fail + // if we really want to use lookups (so buddies without known IPs), this should be reworked + // for example by adding a queue system for queries DebugLogWarning(_T("TryToConnect: Buddy without known IP, Lookup currently impossible")); delete findSource; return true; @@ -1513,10 +1504,8 @@ bool CUpDownClient::TryToConnect(bool bIgnoreMaxCon, bool bNoCallbacks, CRuntime m_eConnectingState = CCS_KADCALLBACK; //Started lookup. SetDownloadState(DS_WAITCALLBACKKAD); - } else { - //This should never happen. - ASSERT(0); - } + } else + ASSERT(0); //This should never happen. } } else { ASSERT(0); @@ -1985,7 +1974,7 @@ void CUpDownClient::ProcessSignaturePacket(const uchar *pachPacket, uint32 nSize if (!theApp.clientcredits->CryptoAvailable()) return; - // we accept only one signature per IP, to avoid floods which need a lot cpu time for cryptfunctions + // we accept only one signature per IP, to avoid floods which need a lot CPU time for crypto-functions if (m_dwLastSignatureIP == GetIP()) { if (thePrefs.GetLogSecureIdent()) AddDebugLogLine(false, _T("received multiple signatures from one client")); @@ -2007,13 +1996,11 @@ void CUpDownClient::ProcessSignaturePacket(const uchar *pachPacket, uint32 nSize } if (theApp.clientcredits->VerifyIdent(credits, pachPacket + 1, pachPacket[0], GetIP(), byChaIPKind)) { - // result is saved in function above - //if (thePrefs.GetLogSecureIdent()) - // AddDebugLogLine(false, _T("'%s' has passed the secure identification, V2 State: %i"), GetUserName(), byChaIPKind); - - // inform our friend object if needed + // the result was saved in the function above if (GetFriend() != NULL && GetFriend()->IsTryingToConnect()) GetFriend()->UpdateFriendConnectionState(FCR_USERHASHVERIFIED); + //if (thePrefs.GetLogSecureIdent()) + // AddDebugLogLine(false, _T("'%s' has passed the secure identification, V2 State: %i"), GetUserName(), byChaIPKind); } else { if (GetFriend() != NULL && GetFriend()->IsTryingToConnect()) GetFriend()->UpdateFriendConnectionState(FCR_SECUREIDENTFAILED); @@ -2027,18 +2014,19 @@ void CUpDownClient::SendSecIdentStatePacket() { // check if we need public key and signature if (credits) { - uint8 nValue = 0; - if (theApp.clientcredits->CryptoAvailable()) { - if (credits->GetSecIDKeyLen() == 0) - nValue = IS_KEYANDSIGNEEDED; - else if (m_dwLastSignatureIP != GetIP()) - nValue = IS_SIGNATURENEEDED; - } - if (nValue == 0) { + if (!theApp.clientcredits->CryptoAvailable()) + return; + uint8 nValue; + if (credits->GetSecIDKeyLen() == 0) + nValue = IS_KEYANDSIGNEEDED; + else if (m_dwLastSignatureIP != GetIP()) + nValue = IS_SIGNATURENEEDED; + else { //if (thePrefs.GetLogSecureIdent()) - // AddDebugLogLine(false, _T("Not sending SecIdentState Packet, because State is Zero")); + // AddDebugLogLine(false, _T("Not sending SecIdentState Packet, because State IS_UNAVAILABLE")); return; } + // crypt: send random data to sign uint32 dwRandom = rand() + 1; credits->m_dwCryptRndChallengeFor = dwRandom; @@ -2104,14 +2092,14 @@ bool CUpDownClient::IsBanned() const return theApp.clientlist->IsBannedClient(GetIP()); } -void CUpDownClient::SendPreviewRequest(const CAbstractFile *pForFile) +void CUpDownClient::SendPreviewRequest(const CAbstractFile &rForFile) { if (m_fPreviewReqPending == 0) { m_fPreviewReqPending = 1; if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_RequestPreview", this, pForFile->GetFileHash()); + DebugSend("OP_RequestPreview", this, rForFile.GetFileHash()); Packet *packet = new Packet(OP_REQUESTPREVIEW, 16, OP_EMULEPROT); - md4cpy(packet->pBuffer, pForFile->GetFileHash()); + md4cpy(packet->pBuffer, rForFile.GetFileHash()); theStats.AddUpDataOverheadOther(packet->size); SafeConnectAndSendPacket(packet); } else @@ -2149,7 +2137,7 @@ void CUpDownClient::SendPreviewAnswer(const CKnownFile *pForFile, CxImage **imgF data.Write(abyResultBuffer, nResultSize); free(abyResultBuffer); } - Packet *packet = new Packet(&data, OP_EMULEPROT); + Packet *packet = new Packet(data, OP_EMULEPROT); packet->opcode = OP_PREVIEWANSWER; if (thePrefs.GetDebugClientTCPLevel() > 0) DebugSend("OP_PreviewAnswer", this, (uchar*)packet->pBuffer); @@ -2170,7 +2158,7 @@ void CUpDownClient::ProcessPreviewReq(const uchar *pachPacket, uint32 nSize) if (previewFile == NULL) SendPreviewAnswer(NULL, NULL, 0); else - previewFile->GrabImage(4, 0, true, 450, this); + previewFile->GrabImage(4, 15, true, 450, this); //start at 15 seconds; at 0 seconds frame usually were solid black } void CUpDownClient::ProcessPreviewAnswer(const uchar *pachPacket, uint32 nSize) @@ -2179,7 +2167,7 @@ void CUpDownClient::ProcessPreviewAnswer(const uchar *pachPacket, uint32 nSize) return; m_fPreviewReqPending = 0; CSafeMemFile data(pachPacket, nSize); - uchar Hash[16]; + uchar Hash[MDX_DIGEST_SIZE]; data.ReadHash16(Hash); uint8 nCount = data.ReadUInt8(); if (nCount == 0) { @@ -2193,10 +2181,10 @@ void CUpDownClient::ProcessPreviewAnswer(const uchar *pachPacket, uint32 nSize) BYTE *pBuffer = NULL; try { - for (int i = 0; i != nCount; ++i) { + for (int i = 0; i < nCount; ++i) { uint32 nImgSize = data.ReadUInt32(); if (nImgSize > nSize) - throw CString(_T("CUpDownClient::ProcessPreviewAnswer - Provided image size exceeds limit")); + throwCStr(_T("CUpDownClient::ProcessPreviewAnswer - Provided image size exceeds limit")); pBuffer = new BYTE[nImgSize]; data.Read(pBuffer, nImgSize); CxImage *image = new CxImage(pBuffer, nImgSize, CXIMAGE_FORMAT_PNG); @@ -2234,7 +2222,7 @@ bool CUpDownClient::SendPacket(Packet *packet, bool bVerifyConnection) socket->SendPacket(packet, true); return true; } - DebugLogError(_T("Outgoing packet (0x%X) discarded because expected socket or connection does not exists %s"), packet->opcode, (LPCTSTR)DbgGetClientInfo()); + DebugLogError(_T("Outgoing packet (0x%X) discarded because expected socket or connection does not exist %s"), packet->opcode, (LPCTSTR)DbgGetClientInfo()); delete packet; return false; } @@ -2279,7 +2267,7 @@ void CUpDownClient::AssertValid() const CHECK_BOOL(m_bFriendSlot); CHECK_BOOL(m_bCommentDirty); CHECK_BOOL(m_bIsML); - //ASSERT( m_clientSoft >= SO_EMULE && m_clientSoft <= SO_SHAREAZA || m_clientSoft == SO_MLDONKEY || m_clientSoft >= SO_EDONKEYHYBRID && m_clientSoft <= SO_UNKNOWN ); + //ASSERT(m_clientSoft >= SO_EMULE && m_clientSoft <= SO_SHAREAZA || m_clientSoft == SO_MLDONKEY || m_clientSoft >= SO_EDONKEYHYBRID && m_clientSoft <= SO_UNKNOWN); (void)m_strClientSoftware; (void)m_dwLastSourceRequest; (void)m_dwLastSourceAnswer; @@ -2638,7 +2626,7 @@ void CUpDownClient::CheckFailedFileIdReqs(const uchar *aucFileHash) theApp.clientlist->TrackBadRequest(this, -2); // reset so the client will not be re-banned right after the ban is lifted Ban(_T("FileReq flood")); } - throw CString(thePrefs.GetLogBannedClients() ? _T("FileReq flood") : _T("")); + throwCStr(thePrefs.GetLogBannedClients() ? _T("FileReq flood") : _T("")); } } } @@ -2710,7 +2698,7 @@ void CUpDownClient::GetDisplayImage(int &iImage, UINT &uOverlayImage) const uOverlayImage |= (static_cast(IsObfuscatedConnectionEstablished()) << 1); } -void CUpDownClient::ProcessChatMessage(CSafeMemFile *data, uint32 nLength) +void CUpDownClient::ProcessChatMessage(CSafeMemFile &data, uint32 nLength) { //filter me? if ((thePrefs.MsgOnlyFriends() && !IsFriend()) || (thePrefs.MsgOnlySecure() && GetUserName() == NULL)) { @@ -2722,7 +2710,7 @@ void CUpDownClient::ProcessChatMessage(CSafeMemFile *data, uint32 nLength) return; } - CString strMessage(data->ReadString(GetUnicodeSupport() != UTF8strNone, nLength)); + CString strMessage(data.ReadString(GetUnicodeSupport() != UTF8strNone, nLength)); if (thePrefs.GetDebugClientTCPLevel() > 0) Debug(_T(" %s\n"), (LPCTSTR)strMessage); @@ -2759,7 +2747,7 @@ void CUpDownClient::ProcessChatMessage(CSafeMemFile *data, uint32 nLength) m_strCaptchaChallenge = captcha.GetCaptchaText(); m_eChatCaptchaState = CA_CHALLENGESENT; ++m_cCaptchasSent; - Packet *packet = new Packet(&fileAnswer, OP_EMULEPROT, OP_CHATCAPTCHAREQ); + Packet *packet = new Packet(fileAnswer, OP_EMULEPROT, OP_CHATCAPTCHAREQ); theStats.AddUpDataOverheadOther(packet->size); if (!SafeConnectAndSendPacket(packet)) return; // deleted client while connecting @@ -2850,20 +2838,20 @@ void CUpDownClient::ProcessChatMessage(CSafeMemFile *data, uint32 nLength) theApp.emuledlg->chatwnd->chatselector.ProcessMessage(this, strMessage); } -void CUpDownClient::ProcessCaptchaRequest(CSafeMemFile *data) +void CUpDownClient::ProcessCaptchaRequest(CSafeMemFile &data) { // received a captcha request, check if we actually accept it (only after sending a message ourself to this client) if (GetChatCaptchaState() == CA_ACCEPTING && GetChatState() != MS_NONE && theApp.emuledlg->chatwnd->chatselector.GetItemByClient(this) != NULL) { // read tags (for future use) - for (uint32 i = data->ReadUInt8(); i > 0; --i) + for (uint32 i = data.ReadUInt8(); i > 0; --i) CTag tag(data, true); // sanitize checks - we want a small captcha not a wallpaper - uint32 nSize = (uint32)(data->GetLength() - data->GetPosition()); + uint32 nSize = (uint32)(data.GetLength() - data.GetPosition()); if (nSize > 128 && nSize < 4096) { - ULONGLONG pos = data->GetPosition(); - BYTE *byBuffer = data->Detach(); + ULONGLONG pos = data.GetPosition(); + BYTE *byBuffer = data.Detach(); CxImage imgCaptcha(&byBuffer[pos], nSize, CXIMAGE_FORMAT_BMP); //free(byBuffer); if (imgCaptcha.IsValid() && imgCaptcha.GetHeight() > 10 && imgCaptcha.GetHeight() < 50 @@ -2910,7 +2898,7 @@ void CUpDownClient::SendChatMessage(const CString &strMessage) { CSafeMemFile data; data.WriteString(strMessage, GetUnicodeSupport()); - Packet *packet = new Packet(&data, OP_EDONKEYPROT, OP_MESSAGE); + Packet *packet = new Packet(data, OP_EDONKEYPROT, OP_MESSAGE); theStats.AddUpDataOverheadOther(packet->size); SafeConnectAndSendPacket(packet); } @@ -2940,12 +2928,12 @@ void CUpDownClient::SendFirewallCheckUDPRequest() data.WriteUInt16(Kademlia::CKademlia::GetPrefs()->GetInternKadPort()); data.WriteUInt16(Kademlia::CKademlia::GetPrefs()->GetExternalKadPort()); data.WriteUInt32(Kademlia::CKademlia::GetPrefs()->GetUDPVerifyKey(GetConnectIP())); - Packet *packet = new Packet(&data, OP_EMULEPROT, OP_FWCHECKUDPREQ); + Packet *packet = new Packet(data, OP_EMULEPROT, OP_FWCHECKUDPREQ); theStats.AddUpDataOverheadKad(packet->size); SafeConnectAndSendPacket(packet); } -void CUpDownClient::ProcessFirewallCheckUDPRequest(CSafeMemFile *data) +void CUpDownClient::ProcessFirewallCheckUDPRequest(CSafeMemFile &data) { if (!Kademlia::CKademlia::IsRunning() || Kademlia::CKademlia::GetUDPListener() == NULL) { DebugLogWarning(_T("Ignored Kad Firewall request UDP because Kad is not running (%s)"), (LPCTSTR)DbgGetClientInfo()); @@ -2955,9 +2943,9 @@ void CUpDownClient::ProcessFirewallCheckUDPRequest(CSafeMemFile *data) bool bErrorAlreadyKnown = GetUploadState() != US_NONE || GetDownloadState() != DS_NONE || GetChatState() != MS_NONE || (Kademlia::CKademlia::GetRoutingZone()->GetContact(ntohl(GetConnectIP()), 0, false) != NULL); - uint16 nRemoteInternPort = data->ReadUInt16(); - uint16 nRemoteExternPort = data->ReadUInt16(); - uint32 dwSenderKey = data->ReadUInt32(); + uint16 nRemoteInternPort = data.ReadUInt16(); + uint16 nRemoteExternPort = data.ReadUInt16(); + uint32 dwSenderKey = data.ReadUInt32(); if (nRemoteInternPort == 0) { DebugLogError(_T("UDP Firewall check requested with Intern Port == 0 (%s)"), (LPCTSTR)DbgGetClientInfo()); return; @@ -2970,7 +2958,7 @@ void CUpDownClient::ProcessFirewallCheckUDPRequest(CSafeMemFile *data) fileTestPacket1.WriteUInt16(nRemoteInternPort); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_FIREWALLUDP", ntohl(GetConnectIP()), nRemoteInternPort); - Kademlia::CKademlia::GetUDPListener()->SendPacket(&fileTestPacket1, KADEMLIA2_FIREWALLUDP, ntohl(GetConnectIP()) + Kademlia::CKademlia::GetUDPListener()->SendPacket(fileTestPacket1, KADEMLIA2_FIREWALLUDP, ntohl(GetConnectIP()) , nRemoteInternPort, Kademlia::CKadUDPKey(dwSenderKey, theApp.GetPublicIP(false)), NULL); // if the client has a router with PAT (and therefore a different extern port than intern), test this port too @@ -2980,7 +2968,7 @@ void CUpDownClient::ProcessFirewallCheckUDPRequest(CSafeMemFile *data) fileTestPacket2.WriteUInt16(nRemoteExternPort); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_FIREWALLUDP", ntohl(GetConnectIP()), nRemoteExternPort); - Kademlia::CKademlia::GetUDPListener()->SendPacket(&fileTestPacket2, KADEMLIA2_FIREWALLUDP, ntohl(GetConnectIP()) + Kademlia::CKademlia::GetUDPListener()->SendPacket(fileTestPacket2, KADEMLIA2_FIREWALLUDP, ntohl(GetConnectIP()) , nRemoteExternPort, Kademlia::CKadUDPKey(dwSenderKey, theApp.GetPublicIP(false)), NULL); } DebugLog(_T("Answered UDP Firewall check request (%s)"), (LPCTSTR)DbgGetClientInfo()); @@ -2996,7 +2984,7 @@ void CUpDownClient::SetConnectOptions(uint8 byOptions, bool bEncryption, bool bC void CUpDownClient::SendSharedDirectories() { - //TODO: Don't send shared directories without any files + //TODO: Don't send empty shared directories theApp.sharedfiles->ResetPseudoDirNames(); //purge stale data // add shared directories CStringArray arFolders; @@ -3005,9 +2993,8 @@ void CUpDownClient::SendSharedDirectories() if (!strDir.IsEmpty()) arFolders.Add(strDir); } - - // add incoming folders - for (int iCat = 0; iCat < thePrefs.GetCatCount(); ++iCat) { + //add categories + for (INT_PTR iCat = 0; iCat < thePrefs.GetCatCount(); ++iCat) { const CString &strDir(theApp.sharedfiles->GetPseudoDirName(thePrefs.GetCategory(iCat)->strIncomingPath)); if (!strDir.IsEmpty()) arFolders.Add(strDir); @@ -3021,14 +3008,15 @@ void CUpDownClient::SendSharedDirectories() arFolders.Add(_T(OP_OTHER_SHARED_FILES)); // build packet + EUTF8str eUnicode = GetUnicodeSupport(); CSafeMemFile tempfile(80); tempfile.WriteUInt32(static_cast(arFolders.GetCount())); - for (int i = 0; i < arFolders.GetCount(); ++i) - tempfile.WriteString(arFolders[i], GetUnicodeSupport()); + for (INT_PTR i = 0; i < arFolders.GetCount(); ++i) + tempfile.WriteString(arFolders[i], eUnicode); if (thePrefs.GetDebugClientTCPLevel() > 0) DebugSend("OP_AskSharedDirsAnswer", this); - Packet *replypacket = new Packet(&tempfile); + Packet *replypacket = new Packet(tempfile); replypacket->opcode = OP_ASKSHAREDDIRSANS; theStats.AddUpDataOverheadOther(replypacket->size); VERIFY(SendPacket(replypacket, true)); diff --git a/srchybrid/BuddyButton.cpp b/srchybrid/BuddyButton.cpp index 612f28a9..2f4a1810 100644 --- a/srchybrid/BuddyButton.cpp +++ b/srchybrid/BuddyButton.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -64,7 +64,7 @@ static LRESULT CALLBACK BuddyButtonSubClassedProc(HWND hWnd, UINT uMessage, WPAR case WM_SIZE: { CRect rc; - GetClientRect(hWnd, rc); + ::GetClientRect(hWnd, rc); rc.left = rc.right; rc.right += pBuddyData->m_uButtonWidth; ::MapWindowPoints(hWnd, GetParent(hWnd), &rc.TopLeft(), 2); diff --git a/srchybrid/ButtonsTabCtrl.cpp b/srchybrid/ButtonsTabCtrl.cpp index 40dbf753..1bc6f015 100644 --- a/srchybrid/ButtonsTabCtrl.cpp +++ b/srchybrid/ButtonsTabCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/ButtonsTabCtrl.h b/srchybrid/ButtonsTabCtrl.h index 532fd296..246dbce1 100644 --- a/srchybrid/ButtonsTabCtrl.h +++ b/srchybrid/ButtonsTabCtrl.h @@ -6,7 +6,6 @@ class CButtonsTabCtrl : public CTabCtrl public: CButtonsTabCtrl() = default; - virtual ~CButtonsTabCtrl() = default; protected: void InternalInit(); diff --git a/srchybrid/CaptchaGenerator.cpp b/srchybrid/CaptchaGenerator.cpp index 879bf325..4e06c08e 100644 --- a/srchybrid/CaptchaGenerator.cpp +++ b/srchybrid/CaptchaGenerator.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -60,14 +60,13 @@ void CCaptchaGenerator::ReGenerateCaptcha(uint32 nLetterCount) for (uint32 i = 0; i < nLetterCount; ++i) { CxImage imgLetter(imgBlank); - strLetter[0] = schCaptchaContent[GetRandomUInt16() % (_countof(schCaptchaContent) - 1)]; + strLetter[0] = schCaptchaContent[rand() % (_countof(schCaptchaContent) - 1)]; m_strCaptchaText += strLetter[0]; - uint16 nRandomSize = GetRandomUInt16() % 10; - uint16 nRandomOffset = 3 + GetRandomUInt16() % 11; - imgLetter.DrawString(NULL, nRandomOffset, 32, strLetter, imgLetter.RGBtoRGBQUAD(RGB(0, 0, 0)), _T("Arial"), 40 - nRandomSize, 1000); - //imgLetter.DrawTextA(NULL, nRandomOffset, 32, strLetter, imgLetter.RGBtoRGBQUAD(RGB(0, 0, 0)), "Arial", 40 - nRandomSize, 1000); - float fRotate = 35.0f - (GetRandomUInt16() % 71); + int32_t iFontSize = rand() % 10; + int32_t iTextOffsetX = 3 + rand() % 11; + imgLetter.DrawString(NULL, iTextOffsetX, 32, strLetter, imgLetter.RGBtoRGBQUAD(RGB(0, 0, 0)), _T("Arial"), 40 - iFontSize, 1000); + float fRotate = 35.0f - (rand() % 71); imgLetter.Rotate2(fRotate, NULL, CxImage::IM_BILINEAR, CxImage::OM_BACKGROUND, 0, false, false); uint32 nOffset = i * CROWDEDSIZE; ASSERT(pimgResult->GetHeight() >= imgLetter.GetHeight() && pimgResult->GetWidth() >= nOffset + imgLetter.GetWidth()); diff --git a/srchybrid/CaptchaGenerator.h b/srchybrid/CaptchaGenerator.h index c559fc60..5762df7a 100644 --- a/srchybrid/CaptchaGenerator.h +++ b/srchybrid/CaptchaGenerator.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/CatDialog.cpp b/srchybrid/CatDialog.cpp index ebb0e6d2..5b1a51a9 100644 --- a/srchybrid/CatDialog.cpp +++ b/srchybrid/CatDialog.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -48,7 +48,7 @@ CCatDialog::CCatDialog(int index) { m_myCat = thePrefs.GetCategory(index); if (m_myCat != NULL) - newcolor = CLR_NONE; + m_newcolor = CLR_NONE; } CCatDialog::~CCatDialog() @@ -99,7 +99,7 @@ void CCatDialog::UpdateData() CheckDlgButton(IDC_REGEXPR, m_myCat->ac_regexpeval); - newcolor = m_myCat->color; + m_newcolor = m_myCat->color; m_ctlColor.SetColor(m_myCat->color == CLR_NONE ? m_ctlColor.GetDefaultColor() : m_myCat->color); SetDlgItemText(IDC_AUTOCATEXT, m_myCat->autocat); @@ -159,36 +159,34 @@ void CCatDialog::OnBnClickedOk() GetDlgItemText(IDC_COMMENT, m_myCat->strComment); - m_myCat->ac_regexpeval = IsDlgButtonChecked(IDC_REGEXPR) != 0; - MakeFoldername(m_myCat->strIncomingPath); - if (!thePrefs.IsShareableDirectory(m_myCat->strIncomingPath)) { + if (!thePrefs.IsShareableDirectory(m_myCat->strIncomingPath)) m_myCat->strIncomingPath = thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR); - MakeFoldername(m_myCat->strIncomingPath); - } - if (!PathFileExists(m_myCat->strIncomingPath)) - if (!::CreateDirectory(m_myCat->strIncomingPath, 0)) { - LocMessageBox(IDS_ERR_BADFOLDER, MB_OK, 0); - m_myCat->strIncomingPath = oldpath; - return; - } + if (!::PathFileExists(m_myCat->strIncomingPath) && !::CreateDirectory(m_myCat->strIncomingPath, 0)) { + ErrorBalloon(IDC_INCOMING, IDS_ERR_BADFOLDER); + m_myCat->strIncomingPath = oldpath; + return; + } if (m_myCat->strIncomingPath.CompareNoCase(oldpath) != 0) theApp.sharedfiles->Reload(); - m_myCat->color = newcolor; + m_myCat->color = m_newcolor; m_myCat->prio = m_prio.GetCurSel(); + + m_myCat->ac_regexpeval = IsDlgButtonChecked(IDC_REGEXPR) != 0; + GetDlgItemText(IDC_AUTOCATEXT, m_myCat->autocat); if (m_myCat->ac_regexpeval && !IsRegExpValid(m_myCat->autocat)) { - GetDlgItem(IDC_AUTOCATEXT)->SetFocus(); + ErrorBalloon(IDC_AUTOCATEXT, IDS_ERR_REGEXP); return; } GetDlgItemText(IDC_REGEXP, m_myCat->regexp); if (m_myCat->regexp.GetLength() > 0) { if (!IsRegExpValid(m_myCat->regexp)) { - GetDlgItem(IDC_REGEXP)->SetFocus(); + ErrorBalloon(IDC_REGEXP, IDS_ERR_REGEXP); return; } if (m_pacRegExp && m_pacRegExp->IsBound()) { @@ -207,7 +205,7 @@ void CCatDialog::OnBnClickedOk() LRESULT CCatDialog::OnSelChange(WPARAM wParam, LPARAM) { - newcolor = (wParam == CLR_DEFAULT) ? CLR_NONE : m_ctlColor.GetColor(); + m_newcolor = (wParam == CLR_DEFAULT) ? CLR_NONE : m_ctlColor.GetColor(); return 0; } @@ -218,3 +216,8 @@ void CCatDialog::OnDDBnClicked() box->SetWindowText(_T("")); box->SendMessage(WM_KEYDOWN, VK_DOWN, 0x00510001); } + +void CCatDialog::ErrorBalloon(int iEdit, UINT uid) +{ + static_cast(GetDlgItem(iEdit))->ShowBalloonTip(GetResString(IDS_ERROR), GetResString(uid), TTI_ERROR); +} \ No newline at end of file diff --git a/srchybrid/CatDialog.h b/srchybrid/CatDialog.h index 4b897449..c12b9d41 100644 --- a/srchybrid/CatDialog.h +++ b/srchybrid/CatDialog.h @@ -28,7 +28,7 @@ class CCatDialog : public CDialog { IDD = IDD_CAT }; - + void ErrorBalloon(int iEdit, UINT uid); public: explicit CCatDialog(int index); // standard constructor virtual ~CCatDialog(); @@ -38,7 +38,7 @@ class CCatDialog : public CDialog Category_Struct *m_myCat; CComboBox m_prio; CCustomAutoComplete *m_pacRegExp; - COLORREF newcolor; + COLORREF m_newcolor; void Localize(); void UpdateData(); diff --git a/srchybrid/ChatSelector.cpp b/srchybrid/ChatSelector.cpp index 61ccd653..eb2d5a0e 100644 --- a/srchybrid/ChatSelector.cpp +++ b/srchybrid/ChatSelector.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -16,13 +16,13 @@ //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "stdafx.h" #include "emule.h" -#include "ChatSelector.h" #include "HTRichEditCtrl.h" #include "emuledlg.h" #include "UpDownClient.h" #include "TaskbarNotifier.h" #include "ListenSocket.h" #include "ChatWnd.h" +#include "ChatSelector.h" #include "Log.h" #include "MenuCmds.h" #include "ClientDetailDialog.h" @@ -174,7 +174,7 @@ CChatItem* CChatSelector::StartSession(CUpDownClient *client, bool show) TCITEM newitem; newitem.mask = TCIF_PARAM | TCIF_TEXT | TCIF_IMAGE; newitem.lParam = (LPARAM)chatitem; - name.Replace(_T("&"), _T("&&")); + DupAmpersand(name); newitem.pszText = const_cast((LPCTSTR)name); newitem.iImage = 0; int iItemNr = InsertItem(GetItemCount(), &newitem); @@ -233,13 +233,16 @@ void CChatSelector::ProcessMessage(CUpDownClient *sender, const CString &message if (thePrefs.GetIRCAddTimeStamp()) AddTimeStamp(ci); ci->log->AppendKeyWord(sender->GetUserName(), RECV_SOURCE_MSG_COLOR); - ci->log->AppendText(_T(": ") + message + _T('\n')); + ci->log->AppendText(_T(": ")); + ci->log->AppendText(message); + ci->log->AppendText(_T("\n")); bool isCurTab = (GetTabByClient(sender) == GetCurSel()); if (!isCurTab || !GetParent()->IsWindowVisible()) { ci->notify = true; if (isCurTab && (isNewChatWindow || thePrefs.GetNotifierOnEveryChatMsg())) { - CString str(GetResString(IDS_TBN_NEWCHATMSG)); - str.AppendFormat(_T(" %s:'%s'\n"), sender->GetUserName(), (LPCTSTR)message); + CString str; + str.Format(_T("%s %s:'%s'\n"), (LPCTSTR)GetResString(IDS_TBN_NEWCHATMSG) + , sender->GetUserName(), (LPCTSTR)message); theApp.emuledlg->ShowNotifier(str, TBN_CHAT); } } @@ -267,7 +270,7 @@ void CChatSelector::ShowCaptchaResult(CUpDownClient *sender, const CString &strR } } -bool CChatSelector::SendMessage(const CString &rstrMessage) +bool CChatSelector::SendText(const CString &rstrText) { CChatItem *ci = GetCurrentChatItem(); if (!ci) @@ -275,7 +278,7 @@ bool CChatSelector::SendMessage(const CString &rstrMessage) if (ci->history.GetCount() == thePrefs.GetMaxChatHistoryLines()) ci->history.RemoveAt(0); - ci->history.Add(rstrMessage); + ci->history.Add(rstrText); ci->history_pos = ci->history.GetCount(); // advance spam filter stuff @@ -294,15 +297,17 @@ bool CChatSelector::SendMessage(const CString &rstrMessage) // there are three cases on connecting/sending the message: if (ci->client->socket && ci->client->socket->IsConnected()) { // 1.) the client is connected already - this is simple, just send it - ci->client->SendChatMessage(rstrMessage); + ci->client->SendChatMessage(rstrText); if (thePrefs.GetIRCAddTimeStamp()) AddTimeStamp(ci); ci->log->AppendKeyWord(thePrefs.GetUserNick(), SENT_TARGET_MSG_COLOR); - ci->log->AppendText(_T(": ") + rstrMessage + _T('\n')); + ci->log->AppendText(_T(": ")); + ci->log->AppendText(rstrText); + ci->log->AppendText(_T("\n")); } else if (ci->client->GetFriend() != NULL) { - // We are not connected and this client is a friend - friends have additional ways to connect and additional checks - // to make sure they are really friends, let the friend class is handling it - ci->strMessagePending = rstrMessage; + // We are not connected and this client is a friend - friends have additional ways to connect and additional + // checks to make sure they are really friends; let the friend class handle it + ci->strMessagePending = rstrText; ci->client->SetChatState(MS_CONNECTING); ci->client->GetFriend()->TryToConnect(this); } else { @@ -311,7 +316,7 @@ bool CChatSelector::SendMessage(const CString &rstrMessage) if (thePrefs.GetIRCAddTimeStamp()) AddTimeStamp(ci); ci->log->AppendKeyWord(_T("*** ") + GetResString(IDS_CONNECTING), STATUS_MSG_COLOR); - ci->strMessagePending = rstrMessage; + ci->strMessagePending = rstrText; ci->client->SetChatState(MS_CONNECTING); ci->client->TryToConnect(true); } @@ -338,7 +343,8 @@ void CChatSelector::ConnectingResult(CUpDownClient *sender, bool success) AddTimeStamp(ci); ci->log->AppendKeyWord(thePrefs.GetUserNick(), SENT_TARGET_MSG_COLOR); ci->log->AppendText(_T(": ")); - ci->log->AppendText(ci->strMessagePending + _T('\n')); + ci->log->AppendText(ci->strMessagePending); + ci->log->AppendText(_T("\n")); ci->strMessagePending.Empty(); } @@ -477,9 +483,7 @@ void CChatSelector::EndSession(CUpDownClient *client) int iTabItems = GetItemCount(); if (iTabItems > 0) { // select next tab - /*if (iCurSel == CB_ERR) - iCurSel = 0; - else*/ if (iCurSel >= iTabItems) + if (iCurSel >= iTabItems) iCurSel = iTabItems - 1; (void)SetCurSel(iCurSel); // returns CB_ERR if error or no prev. selection(!) if (GetCurSel() == CB_ERR) // get the real current selection @@ -629,7 +633,7 @@ void CChatSelector::ReportConnectionProgress(CUpDownClient *pClient, const CStri void CChatSelector::ClientObjectChanged(CUpDownClient *pOldClient, CUpDownClient *pNewClient) { - // the friend has decided to change the clients objects (because the old doesn't seems to be our friend) during a connection try + // the friend has decided to change the clients objects (because the old doesn't seem to be our friend) during a connection try // in order to not close and reopen a new session and lose the prior chat, switch the objects on an existing tab // nothing else changes since the tab is supposed to be still connected to the same friend CChatItem *ci = GetItemByClient(pOldClient); diff --git a/srchybrid/ChatSelector.h b/srchybrid/ChatSelector.h index b6e05645..554c4932 100644 --- a/srchybrid/ChatSelector.h +++ b/srchybrid/ChatSelector.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -50,7 +50,6 @@ class CChatSelector : public CClosableTabCtrl, private CFriendConnectionListener public: CChatSelector(); - virtual ~CChatSelector() = default; void Init(CChatWnd *pParent); CChatItem* StartSession(CUpDownClient *client, bool show = true); @@ -61,7 +60,7 @@ class CChatSelector : public CClosableTabCtrl, private CFriendConnectionListener void ProcessMessage(CUpDownClient *sender, const CString &message); void ShowCaptchaRequest(CUpDownClient *sender, HBITMAP bmpCaptcha); void ShowCaptchaResult(CUpDownClient *sender, const CString &strResult); - bool SendMessage(const CString &rstrMessage); + bool SendText(const CString &rstrText); void DeleteAllItems(); void ShowChat(); void ConnectingResult(CUpDownClient *sender, bool success); diff --git a/srchybrid/ChatWnd.cpp b/srchybrid/ChatWnd.cpp index fa5bdf7e..4196b612 100644 --- a/srchybrid/ChatWnd.cpp +++ b/srchybrid/ChatWnd.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -16,14 +16,13 @@ //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "stdafx.h" #include "emule.h" -#include "ChatWnd.h" #include "HTRichEditCtrl.h" -#include "FriendList.h" #include "emuledlg.h" #include "UpDownClient.h" #include "HelpIDs.h" #include "Opcodes.h" -#include "friend.h" +#include "FriendList.h" +#include "ChatWnd.h" #include "ClientCredits.h" #include "IconStatic.h" #include "UserMsgs.h" @@ -190,7 +189,7 @@ BOOL CChatWnd::OnInitDialog() m_wndFormat.ModifyStyle((theApp.m_ullComCtrlVer >= MAKEDLLVERULL(6, 16, 0, 0)) ? TBSTYLE_TRANSPARENT : 0, TBSTYLE_TOOLTIPS); m_wndFormat.SetExtendedStyle(m_wndFormat.GetExtendedStyle() | TBSTYLE_EX_MIXEDBUTTONS); TBBUTTON atb[1] = {}; - atb[0].iBitmap = 0; + //atb[0].iBitmap = 0; atb[0].idCommand = IDC_SMILEY; atb[0].fsState = TBSTATE_ENABLED; atb[0].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; @@ -345,11 +344,11 @@ LRESULT CChatWnd::DefWindowProc(UINT uMessage, WPARAM wParam, LPARAM lParam) void CChatWnd::StartSession(CUpDownClient *client) { - if (!client->GetUserName()) - return; - theApp.emuledlg->SetActiveDialog(this); - chatselector.StartSession(client, true); - EnableClose(); + if (client->GetUserName()) { + theApp.emuledlg->SetActiveDialog(this); + chatselector.StartSession(client, true); + EnableClose(); + } } void CChatWnd::OnShowWindow(BOOL bShow, UINT /*nStatus*/) @@ -479,9 +478,9 @@ void CChatWnd::OnSysColorChange() void CChatWnd::UpdateFriendlistCount(INT_PTR count) { - CString strTemp; - strTemp.Format(_T(" (%u)"), (unsigned)count); - SetDlgItemText(IDC_FRIENDS_LBL, GetResString(IDS_CW_FRIENDS) + strTemp); + CString sCount; + sCount.Format(_T("%s (%u)"), (LPCTSTR)GetResString(IDS_CW_FRIENDS), (unsigned)count); + SetDlgItemText(IDC_FRIENDS_LBL, sCount); } BOOL CChatWnd::OnHelpInfo(HELPINFO*) @@ -529,10 +528,9 @@ void CChatWnd::OnBnClickedClose() void CChatWnd::OnBnClickedSend() { - CString strMessage; - m_wndMessage.GetWindowText(strMessage); - strMessage.Trim(); - if (!strMessage.IsEmpty() && chatselector.SendMessage(strMessage)) + CString strText; + m_wndMessage.GetWindowText(strText); + if (!strText.Trim().IsEmpty() && chatselector.SendText(strText)) m_wndMessage.SetWindowText(_T("")); m_wndMessage.SetFocus(); diff --git a/srchybrid/ChatWnd.h b/srchybrid/ChatWnd.h index 9769ab07..2f8c77c2 100644 --- a/srchybrid/ChatWnd.h +++ b/srchybrid/ChatWnd.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/ClientCredits.cpp b/srchybrid/ClientCredits.cpp index 1d5f8593..2a1b7264 100644 --- a/srchybrid/ClientCredits.cpp +++ b/srchybrid/ClientCredits.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -22,11 +22,11 @@ #include "SafeFile.h" #include "Opcodes.h" #include "ServerConnect.h" -#include -#include -#include #include "emuledlg.h" #include "Log.h" +#include "cryptopp/base64.h" +#include "cryptopp/osrng.h" +#include "cryptopp/files.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -36,8 +36,8 @@ static char THIS_FILE[] = __FILE__; #define CLIENTS_MET_FILENAME _T("clients.met") -CClientCredits::CClientCredits(CreditStruct *in_credits) - : m_pCredits(in_credits) +CClientCredits::CClientCredits(const CreditStruct &in_credits) + : m_Credits(in_credits) { InitalizeIdent(); ClearWaitStartTime(); @@ -45,20 +45,14 @@ CClientCredits::CClientCredits(CreditStruct *in_credits) } CClientCredits::CClientCredits(const uchar *key) + : m_Credits() { - m_pCredits = new CreditStruct(); - md4cpy(m_pCredits->abyKey, key); + md4cpy(&m_Credits.abyKey, key); InitalizeIdent(); - m_dwUnSecureWaitTime = ::GetTickCount(); - m_dwSecureWaitTime = m_dwUnSecureWaitTime; + m_dwSecureWaitTime = m_dwUnSecureWaitTime = ::GetTickCount(); m_dwWaitTimeIP = 0; } -CClientCredits::~CClientCredits() -{ - delete m_pCredits; -} - void CClientCredits::AddDownloaded(uint32 bytes, uint32 dwForIP) { switch (GetCurrentIdentState(dwForIP)) { @@ -71,8 +65,8 @@ void CClientCredits::AddDownloaded(uint32 bytes, uint32 dwForIP) uint64 current = GetDownloadedTotal() + bytes; //recode - m_pCredits->nDownloadedLo = (uint32)current; - m_pCredits->nDownloadedHi = (uint32)(current >> 32); + m_Credits.nDownloadedLo = LODWORD(current); + m_Credits.nDownloadedHi = HIDWORD(current); } void CClientCredits::AddUploaded(uint32 bytes, uint32 dwForIP) @@ -87,18 +81,18 @@ void CClientCredits::AddUploaded(uint32 bytes, uint32 dwForIP) uint64 current = GetUploadedTotal() + bytes; //recode - m_pCredits->nUploadedLo = (uint32)current; - m_pCredits->nUploadedHi = (uint32)(current >> 32); + m_Credits.nUploadedLo = LODWORD(current); + m_Credits.nUploadedHi = HIDWORD(current); } uint64 CClientCredits::GetUploadedTotal() const { - return ((uint64)m_pCredits->nUploadedHi << 32) | m_pCredits->nUploadedLo; + return ((uint64)m_Credits.nUploadedHi << 32) | m_Credits.nUploadedLo; } uint64 CClientCredits::GetDownloadedTotal() const { - return ((uint64)m_pCredits->nDownloadedHi << 32) | m_pCredits->nDownloadedLo; + return ((uint64)m_Credits.nDownloadedHi << 32) | m_Credits.nDownloadedLo; } float CClientCredits::GetScoreRatio(uint32 dwForIP) const @@ -117,7 +111,7 @@ float CClientCredits::GetScoreRatio(uint32 dwForIP) const return 1.0f; float result; if (GetUploadedTotal()) - result = GetDownloadedTotal() * 2.0f / GetUploadedTotal(); + result = (GetDownloadedTotal() * 2) / (float)GetUploadedTotal(); else result = 10.0f; @@ -162,7 +156,8 @@ CClientCreditsList::~CClientCreditsList() void CClientCreditsList::LoadList() { - CString strFileName(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + CLIENTS_MET_FILENAME); + const CString &sConfDir(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); + const CString &strFileName(sConfDir + CLIENTS_MET_FILENAME); const int iOpenFlags = CFile::modeRead | CFile::osSequentialScan | CFile::typeBinary | CFile::shareDenyWrite; CSafeBufferedFile file; CFileException fexp; @@ -176,7 +171,7 @@ void CClientCreditsList::LoadList() } return; } - setvbuf(file.m_pStream, NULL, _IOFBF, 16384); + ::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); try { uint8 version = file.ReadUInt8(); @@ -187,7 +182,7 @@ void CClientCreditsList::LoadList() } // everything is OK, lets see if the backup exist... - CString strBakFileName(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + CLIENTS_MET_FILENAME _T(".bak")); + const CString &strBakFileName(sConfDir + CLIENTS_MET_FILENAME _T(".bak")); BOOL bCreateBackup = TRUE; @@ -220,7 +215,7 @@ void CClientCreditsList::LoadList() LogError(LOG_STATUSBAR, _T("%s"), (LPCTSTR)strError); return; } - setvbuf(file.m_pStream, NULL, _IOFBF, 16384); + ::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); file.Seek(1, CFile::begin); //set file pointer behind file version byte } @@ -230,15 +225,14 @@ void CClientCreditsList::LoadList() const time_t dwExpired = time(NULL) - DAY2S(150); // today - 150 days uint32 cDeleted = 0; for (uint32 i = 0; i < count; ++i) { - CreditStruct *newcstruct = new CreditStruct(); - file.Read(newcstruct, (version == CREDITFILE_VERSION_29) ? sizeof(CreditStruct_29a) : sizeof(CreditStruct)); + CreditStruct newcstruct{}; + file.Read(&newcstruct, (version == CREDITFILE_VERSION_29) ? sizeof(CreditStruct_29a) : sizeof(CreditStruct)); - if (newcstruct->nLastSeen < (uint32)dwExpired) { + if (newcstruct.nLastSeen < (uint32)dwExpired) ++cDeleted; - delete newcstruct; - } else { + else { CClientCredits *newcredits = new CClientCredits(newcstruct); - m_mapClients.SetAt(CCKey(newcredits->GetKey()), newcredits); + m_mapClients[CCKey(newcredits->GetKey())] = newcredits; } } file.Close(); @@ -265,10 +259,10 @@ void CClientCreditsList::SaveList() AddDebugLogLine(false, _T("Saving clients credit list file \"%s\""), CLIENTS_MET_FILENAME); m_nLastSaved = ::GetTickCount(); - CString name(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + CLIENTS_MET_FILENAME); + const CString &metname(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + CLIENTS_MET_FILENAME); CFile file;// no buffering needed here since we swap out the entire array CFileException fexp; - if (!file.Open(name, CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyWrite, &fexp)) { + if (!file.Open(metname, CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyWrite, &fexp)) { CString strError(GetResString(IDS_ERR_FAILED_CREDITSAVE)); TCHAR szError[MAX_CFEXP_ERRORMSG]; if (GetExceptionMessage(fexp, szError, _countof(szError))) @@ -277,25 +271,19 @@ void CClientCreditsList::SaveList() return; } - BYTE *pBuffer = new BYTE[m_mapClients.GetCount() * sizeof(CreditStruct)]; + byte *pBuffer = new byte[m_mapClients.GetCount() * sizeof(CreditStruct)]; //not CreditStruct[] because of alignment uint32 count = 0; - CCKey tempkey; - for (POSITION pos = m_mapClients.GetStartPosition(); pos != NULL;) { - CClientCredits *cur_credit; - m_mapClients.GetNextAssoc(pos, tempkey, cur_credit); - if (cur_credit->GetUploadedTotal() || cur_credit->GetDownloadedTotal()) { - memcpy(pBuffer + (count * sizeof(CreditStruct)), cur_credit->GetDataStruct(), sizeof(CreditStruct)); - ++count; - } + for (const CClientCreditsMap::CPair *pair = m_mapClients.PGetFirstAssoc(); pair != NULL; pair = m_mapClients.PGetNextAssoc(pair)) { + const CClientCredits *cur_credit = pair->value; + if (cur_credit->GetUploadedTotal() || cur_credit->GetDownloadedTotal()) + *reinterpret_cast(&pBuffer[sizeof(CreditStruct) * count++]) = cur_credit->m_Credits; } try { uint8 version = CREDITFILE_VERSION; file.Write(&version, 1); file.Write(&count, 4); - file.Write(pBuffer, count * sizeof(CreditStruct)); - if ((theApp.IsClosing() && thePrefs.GetCommitFiles() >= 1) || thePrefs.GetCommitFiles() >= 2) - file.Flush(); + file.Write(pBuffer, (UINT)(count * sizeof(CreditStruct))); file.Close(); } catch (CFileException *error) { CString strError(GetResString(IDS_ERR_FAILED_CREDITSAVE)); @@ -311,11 +299,11 @@ void CClientCreditsList::SaveList() CClientCredits* CClientCreditsList::GetCredit(const uchar *key) { - CClientCredits *result; CCKey tkey(key); + CClientCredits *result; if (!m_mapClients.Lookup(tkey, result)) { result = new CClientCredits(key); - m_mapClients.SetAt(CCKey(result->GetKey()), result); + m_mapClients[CCKey(result->GetKey())] = result; } result->SetLastSeen(); return result; @@ -329,13 +317,13 @@ void CClientCreditsList::Process() void CClientCredits::InitalizeIdent() { - if (m_pCredits->nKeySize == 0) { + if (m_Credits.nKeySize == 0) { memset(m_abyPublicKey, 0, sizeof m_abyPublicKey); // for debugging m_nPublicKeyLen = 0; IdentState = IS_NOTAVAILABLE; } else { - m_nPublicKeyLen = m_pCredits->nKeySize; - memcpy(m_abyPublicKey, m_pCredits->abySecureIdent, m_nPublicKeyLen); + m_nPublicKeyLen = m_Credits.nKeySize; + memcpy(m_abyPublicKey, m_Credits.abySecureIdent, m_nPublicKeyLen); IdentState = IS_IDNEEDED; } m_dwCryptRndChallengeFor = 0; @@ -347,15 +335,15 @@ void CClientCredits::Verified(uint32 dwForIP) { m_dwIdentIP = dwForIP; // client was verified, copy the key to store him if not done already - if (m_pCredits->nKeySize == 0) { - m_pCredits->nKeySize = m_nPublicKeyLen; - memcpy(m_pCredits->abySecureIdent, m_abyPublicKey, m_nPublicKeyLen); + if (m_Credits.nKeySize == 0) { + m_Credits.nKeySize = m_nPublicKeyLen; + memcpy(m_Credits.abySecureIdent, m_abyPublicKey, m_nPublicKeyLen); if (GetDownloadedTotal() > 0) { // for security reason, we have to delete all prior credits here - m_pCredits->nDownloadedHi = 0; - m_pCredits->nDownloadedLo = 1; - m_pCredits->nUploadedHi = 0; - m_pCredits->nUploadedLo = 1; // in order to save this client, set 1 byte + m_Credits.nDownloadedHi = 0; + m_Credits.nDownloadedLo = 1; + m_Credits.nUploadedHi = 0; + m_Credits.nUploadedLo = 1; // in order to save this client, set 1 byte if (thePrefs.GetVerbose()) DEBUG_ONLY(AddDebugLogLine(false, _T("Credits deleted due to new SecureIdent"))); } @@ -365,7 +353,7 @@ void CClientCredits::Verified(uint32 dwForIP) bool CClientCredits::SetSecureIdent(const uchar *pachIdent, uint8 nIdentLen) // verified Public key cannot change, use only if there is no public key yet { - if (MAXPUBKEYSIZE < nIdentLen || m_pCredits->nKeySize != 0) + if (MAXPUBKEYSIZE < nIdentLen || m_Credits.nKeySize != 0) return false; memcpy(m_abyPublicKey, pachIdent, nIdentLen); m_nPublicKeyLen = nIdentLen; @@ -395,7 +383,8 @@ void CClientCreditsList::InitalizeCrypting() return; // check if keyfile is there bool bCreateNewKey = false; - HANDLE hKeyFile = ::CreateFile(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + _T("cryptkey.dat") + const CString &cryptkeypath(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + _T("cryptkey.dat")); + HANDLE hKeyFile = ::CreateFile(cryptkeypath , GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hKeyFile != INVALID_HANDLE_VALUE) { if (::GetFileSize(hKeyFile, NULL) == 0) @@ -409,7 +398,7 @@ void CClientCreditsList::InitalizeCrypting() // load key try { // load private key - FileSource filesource((CStringA)(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + _T("cryptkey.dat")), true, new Base64Decoder); + FileSource filesource((CStringA)cryptkeypath, true, new Base64Decoder); m_pSignkey = new RSASSA_PKCS1v15_SHA_Signer(filesource); // calculate and store public key RSASSA_PKCS1v15_SHA_Verifier pubkey(*m_pSignkey); @@ -448,17 +437,15 @@ bool CClientCreditsList::CreateKeyPair() return false; } -uint8 CClientCreditsList::CreateSignature(CClientCredits *pTarget, uchar *pachOutput, uint8 nMaxSize, - uint32 ChallengeIP, uint8 byChaIPKind, - CryptoPP::RSASSA_PKCS1v15_SHA_Signer *sigkey) const +uint8 CClientCreditsList::CreateSignature(CClientCredits *pTarget, uchar *pachOutput, uint8 nMaxSize + , uint32 ChallengeIP, uint8 byChaIPKind, CryptoPP::RSASSA_PKCS1v15_SHA_Signer *sigkey) const { + ASSERT(pTarget != NULL && pachOutput != NULL); // sigkey param is used for debug only if (sigkey == NULL) sigkey = m_pSignkey; // create a signature of the public key from pTarget - ASSERT(pTarget); - ASSERT(pachOutput); if (!CryptoAvailable()) return 0; try { @@ -469,7 +456,7 @@ uint8 CClientCreditsList::CreateSignature(CClientCredits *pTarget, uchar *pachOu memcpy(abyBuffer, pTarget->GetSecureIdent(), keylen); // 4 additional bytes of random data sent from this client uint32 challenge = pTarget->m_dwCryptRndChallengeFrom; - ASSERT(challenge != 0); + ASSERT(challenge); PokeUInt32(&abyBuffer[keylen], challenge); size_t ChIpLen; if (byChaIPKind == 0) @@ -506,7 +493,7 @@ bool CClientCreditsList::VerifyIdent(CClientCredits *pTarget, const uchar *pachS byte abyBuffer[MAXPUBKEYSIZE + 9]; memcpy(abyBuffer, m_abyMyPublicKey, m_nMyPublicKeyLen); uint32 challenge = pTarget->m_dwCryptRndChallengeFor; - ASSERT(challenge != 0); + ASSERT(challenge); PokeUInt32(&abyBuffer[m_nMyPublicKeyLen], challenge); // v2 security improvements (not supported by 29b, not used as default by 29c) @@ -557,7 +544,6 @@ bool CClientCreditsList::CryptoAvailable() const return m_nMyPublicKeyLen > 0 && m_pSignkey != NULL && thePrefs.IsSecureIdentEnabled(); } - #ifdef _DEBUG bool CClientCreditsList::Debug_CheckCrypting() { @@ -572,43 +558,40 @@ bool CClientCreditsList::Debug_CheckCrypting() pub.GetMaterial().Save(asink); uint8 PublicKeyLen = (uint8)asink.TotalPutLength(); asink.MessageEnd(); - uint32 challenge = rand(); + uint32 challenge = GetRandomUInt32(); // create fake client which pretends to be this emule - CreditStruct *newcstruct = new CreditStruct(); - CClientCredits *newcredits = new CClientCredits(newcstruct); - newcredits->SetSecureIdent(m_abyMyPublicKey, m_nMyPublicKeyLen); - newcredits->m_dwCryptRndChallengeFrom = challenge; + CreditStruct emptystruct{}; + CClientCredits newcredits(emptystruct); + newcredits.SetSecureIdent(m_abyMyPublicKey, m_nMyPublicKeyLen); + newcredits.m_dwCryptRndChallengeFrom = challenge; // create signature with fake priv key uchar pachSignature[200] = {}; - uint8 sigsize = CreateSignature(newcredits, pachSignature, sizeof pachSignature, 0, 0, &priv); + uint8 sigsize = CreateSignature(&newcredits, pachSignature, sizeof pachSignature, 0, 0, &priv); // next fake client uses the random created public key - CreditStruct *newcstruct2 = new CreditStruct(); - CClientCredits *newcredits2 = new CClientCredits(newcstruct2); - newcredits2->m_dwCryptRndChallengeFor = challenge; + CClientCredits newcredits2(emptystruct); + newcredits2.m_dwCryptRndChallengeFor = challenge; // if you uncomment one of the following lines the check has to fail //abyPublicKey[5] = 34; //m_abyMyPublicKey[5] = 22; //pachSignature[5] = 232; - newcredits2->SetSecureIdent(abyPublicKey, PublicKeyLen); + newcredits2.SetSecureIdent(abyPublicKey, PublicKeyLen); //now verify this signature - if it's true everything is fine - bool bResult = VerifyIdent(newcredits2, pachSignature, sigsize, 0, 0); - - delete newcredits; - delete newcredits2; + bool bResult = VerifyIdent(&newcredits2, pachSignature, sigsize, 0, 0); return bResult; } #endif -uint32 CClientCredits::GetSecureWaitStartTime(uint32 dwForIP) + +DWORD CClientCredits::GetSecureWaitStartTime(uint32 dwForIP) { if (m_dwUnSecureWaitTime == 0 || m_dwSecureWaitTime == 0) SetSecWaitStartTime(dwForIP); - if (m_pCredits->nKeySize != 0) { // this client is a SecureHash Client + if (m_Credits.nKeySize != 0) { // this client is a SecureHash Client if (GetCurrentIdentState(dwForIP) == IS_IDENTIFIED) // good boy return m_dwSecureWaitTime; @@ -619,9 +602,9 @@ uint32 CClientCredits::GetSecureWaitStartTime(uint32 dwForIP) // bad boy // this can also happen if the client has not identified himself yet, but will do later - so maybe he is not a bad boy :) . /*CString buffer2, buffer; - for (uint16 i = 0;i != 16; ++i) { - buffer2.Format("%02X", m_pCredits->abyKey[i]); - buffer+=buffer2; + for (int i = 0; i < 16; ++i) { + buffer2.Format("%02X", m_Credits.abyKey[i]); + buffer += buffer2; } if (thePrefs.GetLogSecureIdent()) AddDebugLogLine(false, "Warning: WaitTime reset due to Invalid Ident for Userhash %s", buffer);*/ diff --git a/srchybrid/ClientCredits.h b/srchybrid/ClientCredits.h index 6314a7cb..dde3adc9 100644 --- a/srchybrid/ClientCredits.h +++ b/srchybrid/ClientCredits.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -16,7 +16,7 @@ //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #pragma once #include "MapKey.h" -#include +#include "cryptopp/rsa.h" #define MAXPUBKEYSIZE 80 @@ -27,7 +27,7 @@ #pragma pack(push, 1) struct CreditStruct_29a { - uchar abyKey[16]; + uchar abyKey[MDX_DIGEST_SIZE]; uint32 nUploadedLo; // uploaded TO him uint32 nDownloadedLo; // downloaded from him uint32 nLastSeen; @@ -35,6 +35,7 @@ struct CreditStruct_29a uint32 nDownloadedHi; // download high 32 uint16 nReserved3; }; + struct CreditStruct { uchar abyKey[MDX_DIGEST_SIZE]; @@ -62,38 +63,38 @@ class CClientCredits { friend class CClientCreditsList; public: - explicit CClientCredits(CreditStruct *in_credits); + explicit CClientCredits(const CreditStruct &in_credits); explicit CClientCredits(const uchar *key); - ~CClientCredits(); + ~CClientCredits() = default; CClientCredits(const CClientCredits&) = delete; CClientCredits& operator=(const CClientCredits&) = delete; - const uchar* GetKey() const { return m_pCredits->abyKey; } + const uchar* GetKey() const { return m_Credits.abyKey; } uchar* GetSecureIdent() { return m_abyPublicKey; } uint8 GetSecIDKeyLen() const { return m_nPublicKeyLen; } - CreditStruct* GetDataStruct() const { return m_pCredits; } + const CreditStruct* GetDataStruct() const { return &m_Credits; } void ClearWaitStartTime(); void AddDownloaded(uint32 bytes, uint32 dwForIP); void AddUploaded(uint32 bytes, uint32 dwForIP); uint64 GetUploadedTotal() const; uint64 GetDownloadedTotal() const; float GetScoreRatio(uint32 dwForIP) const; - void SetLastSeen() { m_pCredits->nLastSeen = static_cast(time(NULL)); } + void SetLastSeen() { m_Credits.nLastSeen = static_cast(time(NULL)); } bool SetSecureIdent(const uchar *pachIdent, uint8 nIdentLen); // Public key cannot change, use only if there is not public key yet uint32 m_dwCryptRndChallengeFor; uint32 m_dwCryptRndChallengeFrom; EIdentState GetCurrentIdentState(uint32 dwForIP) const; // can be != IdentState - uint32 GetSecureWaitStartTime(uint32 dwForIP); + DWORD GetSecureWaitStartTime(uint32 dwForIP); void SetSecWaitStartTime(uint32 dwForIP); protected: void Verified(uint32 dwForIP); EIdentState IdentState; private: void InitalizeIdent(); - CreditStruct *m_pCredits; + CreditStruct m_Credits; uint32 m_dwIdentIP; - uint32 m_dwSecureWaitTime; - uint32 m_dwUnSecureWaitTime; + DWORD m_dwSecureWaitTime; + DWORD m_dwUnSecureWaitTime; uint32 m_dwWaitTimeIP; // client IP assigned to the waittime byte m_abyPublicKey[80]; // even keys which are not verified will be stored here, and - if verified - copied into the struct uint8 m_nPublicKeyLen; @@ -123,9 +124,10 @@ class CClientCreditsList bool Debug_CheckCrypting(); #endif private: - CMap m_mapClients; + typedef CMap CClientCreditsMap; + CClientCreditsMap m_mapClients; CryptoPP::RSASSA_PKCS1v15_SHA_Signer *m_pSignkey; - uint32 m_nLastSaved; + DWORD m_nLastSaved; byte m_abyMyPublicKey[80]; uint8 m_nMyPublicKeyLen; }; \ No newline at end of file diff --git a/srchybrid/ClientDetailDialog.cpp b/srchybrid/ClientDetailDialog.cpp index bc727d41..22fb6600 100644 --- a/srchybrid/ClientDetailDialog.cpp +++ b/srchybrid/ClientDetailDialog.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -20,7 +20,6 @@ #include "UpDownClient.h" #include "PartFile.h" #include "ClientCredits.h" -#include "otherfunctions.h" #include "Server.h" #include "ServerList.h" #include "SharedFileList.h" @@ -125,7 +124,7 @@ BOOL CClientDetailPage::OnSetActive() SetDlgItemText(IDC_DDUP, CastItoXBytes(client->GetTransferredDown())); SetDlgItemText(IDC_DDOWN, CastItoXBytes(client->GetTransferredUp())); SetDlgItemText(IDC_DAVUR, CastItoXBytes(client->GetDownloadDatarate(), false, true)); - SetDlgItemText(IDC_DAVDR, CastItoXBytes(client->GetDatarate(), false, true)); + SetDlgItemText(IDC_DAVDR, CastItoXBytes(client->GetUploadDatarate(), false, true)); const CClientCredits *clcredits = client->Credits(); if (clcredits) { diff --git a/srchybrid/ClientDetailDialog.h b/srchybrid/ClientDetailDialog.h index 2709aefa..e3718b06 100644 --- a/srchybrid/ClientDetailDialog.h +++ b/srchybrid/ClientDetailDialog.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -36,7 +36,6 @@ class CClientDetailPage : public CResizablePage public: CClientDetailPage(); // standard constructor - virtual ~CClientDetailPage() = default; virtual BOOL OnInitDialog(); void Localize(); @@ -71,7 +70,6 @@ class CClientDetailDialog : public CListViewWalkerPropertySheet public: explicit CClientDetailDialog(CUpDownClient *pClient, CListCtrlItemWalk *pListCtrl = NULL); explicit CClientDetailDialog(const CSimpleArray *paClients, CListCtrlItemWalk *pListCtrl = NULL); - virtual ~CClientDetailDialog() = default; virtual BOOL OnInitDialog(); diff --git a/srchybrid/ClientList.cpp b/srchybrid/ClientList.cpp index 67b9c44f..f244a12d 100644 --- a/srchybrid/ClientList.cpp +++ b/srchybrid/ClientList.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -17,7 +17,6 @@ #include "stdafx.h" #include "emule.h" #include "ClientList.h" -#include "otherfunctions.h" #include "Kademlia/Kademlia/kademlia.h" #include "Kademlia/Kademlia/prefs.h" #include "Kademlia/Kademlia/search.h" @@ -27,9 +26,9 @@ #include "kademlia/kademlia/UDPFirewallTester.h" #include "kademlia/utils/UInt128.h" #include "LastCommonRouteFinder.h" +#include "UpDownClient.h" #include "UploadQueue.h" #include "DownloadQueue.h" -#include "UpDownClient.h" #include "ClientCredits.h" #include "ListenSocket.h" #include "Opcodes.h" @@ -54,7 +53,7 @@ CClientList::CClientList() { m_dwLastBanCleanUp = m_dwLastTrackedCleanUp = m_dwLastClientCleanUp = ::GetTickCount(); m_bannedList.InitHashTable(331); - m_trackedClientsList.InitHashTable(2011); + m_trackedClientsMap.InitHashTable(2011); m_globDeadSourceList.Init(true); } @@ -65,87 +64,84 @@ CClientList::~CClientList() void CClientList::GetStatistics(uint32 &ruTotalClients , int stats[NUM_CLIENTLIST_STATS] - , CMap &clientVersionEDonkey - , CMap &clientVersionEDonkeyHybrid - , CMap &clientVersionEMule - , CMap &clientVersionAMule) + , CClientVersionMap &clientVersionEDonkey + , CClientVersionMap &clientVersionEDonkeyHybrid + , CClientVersionMap &clientVersionEMule + , CClientVersionMap &clientVersionAMule) { ruTotalClients = (uint32)list.GetCount(); memset(stats, 0, NUM_CLIENTLIST_STATS * sizeof stats[0]); - for (POSITION pos = list.GetHeadPosition(); pos != NULL; ) { + for (POSITION pos = list.GetHeadPosition(); pos != NULL;) { const CUpDownClient *cur_client = list.GetNext(pos); if (cur_client->HasLowID()) - stats[14]++; + ++stats[14]; switch (cur_client->GetClientSoft()) { case SO_EMULE: case SO_OLDEMULE: - stats[2]++; - clientVersionEMule[cur_client->GetVersion()]++; + ++stats[2]; + ++clientVersionEMule[cur_client->GetVersion()]; break; case SO_EDONKEYHYBRID: - stats[4]++; - clientVersionEDonkeyHybrid[cur_client->GetVersion()]++; + ++stats[4]; + ++clientVersionEDonkeyHybrid[cur_client->GetVersion()]; break; case SO_AMULE: - stats[10]++; - clientVersionAMule[cur_client->GetVersion()]++; + ++stats[10]; + ++clientVersionAMule[cur_client->GetVersion()]; break; case SO_EDONKEY: - stats[1]++; - clientVersionEDonkey[cur_client->GetVersion()]++; + ++stats[1]; + ++clientVersionEDonkey[cur_client->GetVersion()]; break; case SO_MLDONKEY: - stats[3]++; + ++stats[3]; break; case SO_SHAREAZA: - stats[11]++; + ++stats[11]; break; - - // all remaining 'eMule Compatible' clients - case SO_CDONKEY: + case SO_CDONKEY: // all remaining 'eMule Compatible' clients case SO_XMULE: case SO_LPHANT: - stats[5]++; + ++stats[5]; break; - default: - stats[0]++; + ++stats[0]; } if (cur_client->Credits() != NULL) { switch (cur_client->Credits()->GetCurrentIdentState(cur_client->GetIP())) { case IS_IDENTIFIED: - stats[12]++; + ++stats[12]; break; case IS_IDFAILED: case IS_IDNEEDED: case IS_IDBADGUY: - stats[13]++; + ++stats[13]; } } if (cur_client->GetDownloadState() == DS_ERROR) - stats[6]++; // Error + ++stats[6]; // Error if (cur_client->GetUserPort() == 4662) - stats[8]++; // Default Port + ++stats[8]; // Default Port else - stats[9]++; // Other Port + ++stats[9]; // Other Port // Network client stats if (cur_client->GetServerIP() && cur_client->GetServerPort()) { - stats[15]++; // eD2K + ++stats[15]; // eD2K if (cur_client->GetKadPort()) { - stats[17]++; // eD2K/Kad - stats[16]++; // Kad + ++stats[17]; // eD2K/Kad + ++stats[16]; // Kad } } else if (cur_client->GetKadPort()) - stats[16]++; // Kad + ++stats[16]; // Kad else - stats[18]++; // Unknown + ++stats[18]; // Unknown } } @@ -194,23 +190,20 @@ bool CClientList::AttachToAlreadyKnown(CUpDownClient **client, CClientReqSocket { CUpDownClient *tocheck = *client; CUpDownClient *found_client = NULL; - CUpDownClient *found_client2 = NULL; for (POSITION pos = list.GetHeadPosition(); pos != NULL;) { - CUpDownClient *cur_client = list.GetNext(pos); - if (tocheck->Compare(cur_client, false)) //matching userhash - found_client2 = cur_client; + CUpDownClient *pclient = list.GetNext(pos); + if (found_client == NULL && tocheck->Compare(pclient, false)) //matching user hash + found_client = pclient; - if (tocheck->Compare(cur_client, true)) { //matching IP - found_client = cur_client; + if (tocheck->Compare(pclient, true)) { //matching IP + found_client = pclient; break; } } - if (found_client == NULL) - found_client = found_client2; if (found_client == NULL) return false; if (found_client == tocheck) { - //we found the same client instance (client may have sent more than one OP_HELLO). do not delete that client! + //we found the same client instance (client may have sent more than one OP_HELLO). Do not delete this client! return true; } if (sender) { @@ -336,7 +329,7 @@ CUpDownClient* CClientList::FindClientByServerID(uint32 uServerIP, uint32 uED2KU void CClientList::AddBannedClient(uint32 dwIP) { - m_bannedList.SetAt(dwIP, ::GetTickCount()); + m_bannedList[dwIP] = ::GetTickCount(); } bool CClientList::IsBannedClient(uint32 dwIP) const @@ -361,28 +354,28 @@ void CClientList::RemoveAllBannedClients() void CClientList::AddTrackClient(CUpDownClient *toadd) { - CDeletedClient *pResult = NULL; - if (m_trackedClientsList.Lookup(toadd->GetIP(), pResult)) { + CDeletedClient *pResult; + if (m_trackedClientsMap.Lookup(toadd->GetIP(), pResult)) { pResult->m_dwInserted = ::GetTickCount(); - for (int i = 0; i != pResult->m_ItemsList.GetCount(); ++i) + for (INT_PTR i = pResult->m_ItemsList.GetCount(); --i >= 0;) if (pResult->m_ItemsList[i].nPort == toadd->GetUserPort()) { // already tracked, update pResult->m_ItemsList[i].pHash = toadd->Credits(); return; } - pResult->m_ItemsList.Add(PORTANDHASH{toadd->GetUserPort(), toadd->Credits()}); + pResult->m_ItemsList.Add(PORTANDHASH{ toadd->GetUserPort(), toadd->Credits() }); } else - m_trackedClientsList.SetAt(toadd->GetIP(), new CDeletedClient(toadd)); + m_trackedClientsMap[toadd->GetIP()] = new CDeletedClient(toadd); } // true = everything OK, hash didn't change // false = hash changed -bool CClientList::ComparePriorUserhash(uint32 dwIP, uint16 nPort, void *pNewHash) +bool CClientList::ComparePriorUserhash(uint32 dwIP, uint16 nPort, const void *pNewHash) { - CDeletedClient *pResult = NULL; - if (m_trackedClientsList.Lookup(dwIP, pResult)) { - for (int i = 0; i != pResult->m_ItemsList.GetCount(); ++i) { + CDeletedClient *pResult; + if (m_trackedClientsMap.Lookup(dwIP, pResult)) { + for (INT_PTR i = pResult->m_ItemsList.GetCount(); --i >= 0;) { if (pResult->m_ItemsList[i].nPort == nPort) { if (pResult->m_ItemsList[i].pHash != pNewHash) return false; @@ -395,10 +388,8 @@ bool CClientList::ComparePriorUserhash(uint32 dwIP, uint16 nPort, void *pNewHash INT_PTR CClientList::GetClientsFromIP(uint32 dwIP) const { - CDeletedClient *pResult; - if (m_trackedClientsList.Lookup(dwIP, pResult)) - return pResult->m_ItemsList.GetCount(); - return 0; + const CDeletedClientMap::CPair *pair = m_trackedClientsMap.PLookup(dwIP); + return pair ? pair->value->m_ItemsList.GetCount() : 0; } void CClientList::TrackBadRequest(const CUpDownClient *upcClient, int nIncreaseCounter) @@ -408,35 +399,30 @@ void CClientList::TrackBadRequest(const CUpDownClient *upcClient, int nIncreaseC return; } CDeletedClient *pResult; - if (m_trackedClientsList.Lookup(upcClient->GetIP(), pResult)) { + if (m_trackedClientsMap.Lookup(upcClient->GetIP(), pResult)) { pResult->m_dwInserted = ::GetTickCount(); pResult->m_cBadRequest += nIncreaseCounter; } else { CDeletedClient *ccToAdd = new CDeletedClient(upcClient); ccToAdd->m_cBadRequest = nIncreaseCounter; - m_trackedClientsList.SetAt(upcClient->GetIP(), ccToAdd); + m_trackedClientsMap[upcClient->GetIP()] = ccToAdd; } } uint32 CClientList::GetBadRequests(const CUpDownClient *upcClient) const { - if (upcClient->GetIP() == 0) { - ASSERT(0); - return 0; - } - CDeletedClient *pResult; - if (m_trackedClientsList.Lookup(upcClient->GetIP(), pResult)) - return pResult->m_cBadRequest; - return 0; + ASSERT(upcClient->GetIP()); + const CDeletedClientMap::CPair *pair = m_trackedClientsMap.PLookup(upcClient->GetIP()); + return pair ? pair->value->m_cBadRequest : 0; } void CClientList::RemoveAllTrackedClients() { - for (POSITION pos = m_trackedClientsList.GetStartPosition(); pos != NULL;) { + for (POSITION pos = m_trackedClientsMap.GetStartPosition(); pos != NULL;) { uint32 nKey; CDeletedClient *pResult; - m_trackedClientsList.GetNextAssoc(pos, nKey, pResult); - m_trackedClientsList.RemoveKey(nKey); + m_trackedClientsMap.GetNextAssoc(pos, nKey, pResult); + m_trackedClientsMap.RemoveKey(nKey); delete pResult; } } @@ -446,15 +432,15 @@ void CClientList::Process() /////////////////////////////////////////////////////////////////////////// // Cleanup banned client list // - const DWORD tick = ::GetTickCount(); - if (tick >= m_dwLastBanCleanUp + BAN_CLEANUP_TIME) { - m_dwLastBanCleanUp = tick; + const DWORD curTick = ::GetTickCount(); + if (curTick >= m_dwLastBanCleanUp + BAN_CLEANUP_TIME) { + m_dwLastBanCleanUp = curTick; for (POSITION pos = m_bannedList.GetStartPosition(); pos != NULL;) { uint32 nKey; DWORD dwBantime; m_bannedList.GetNextAssoc(pos, nKey, dwBantime); - if (tick >= dwBantime + CLIENTBANTIME) + if (curTick >= dwBantime + CLIENTBANTIME) RemoveBannedClient(nKey); } } @@ -462,21 +448,21 @@ void CClientList::Process() /////////////////////////////////////////////////////////////////////////// // Cleanup tracked client list // - if (tick >= m_dwLastTrackedCleanUp + TRACKED_CLEANUP_TIME) { - m_dwLastTrackedCleanUp = tick; + if (curTick >= m_dwLastTrackedCleanUp + TRACKED_CLEANUP_TIME) { + m_dwLastTrackedCleanUp = curTick; if (thePrefs.GetLogBannedClients()) - AddDebugLogLine(false, _T("Cleaning up TrackedClientList, %u clients on List..."), (unsigned)m_trackedClientsList.GetCount()); - for (POSITION pos = m_trackedClientsList.GetStartPosition(); pos != NULL;) { + AddDebugLogLine(false, _T("Cleaning up TrackedClientList, %u clients on List..."), (unsigned)m_trackedClientsMap.GetCount()); + for (POSITION pos = m_trackedClientsMap.GetStartPosition(); pos != NULL;) { uint32 nKey; CDeletedClient *pResult; - m_trackedClientsList.GetNextAssoc(pos, nKey, pResult); - if (tick >= pResult->m_dwInserted + KEEPTRACK_TIME) { - m_trackedClientsList.RemoveKey(nKey); + m_trackedClientsMap.GetNextAssoc(pos, nKey, pResult); + if (curTick >= pResult->m_dwInserted + KEEPTRACK_TIME) { + m_trackedClientsMap.RemoveKey(nKey); delete pResult; } } if (thePrefs.GetLogBannedClients()) - AddDebugLogLine(false, _T("...done, %u clients left on list"), (unsigned)m_trackedClientsList.GetCount()); + AddDebugLogLine(false, _T("...done, %u clients left on list"), (unsigned)m_trackedClientsMap.GetCount()); } /////////////////////////////////////////////////////////////////////////// @@ -511,8 +497,7 @@ void CClientList::Process() // we want a UDP firewall check from this client and are just waiting to get connected to send the request break; case KS_CONNECTED_FWCHECK: - //We successfully connected to the client. - //We now send an ack to let them know. + //We successfully connected to the client; now send an ack to let them know. if (cur_client->GetKadVersion() >= KADEMLIA_VERSION7_49a) { // the result is now sent per TCP instead of UDP, because this will fail if our intern UDP port is unreachable. // But we want the TCP testresult regardless if UDP is firewalled, the new UDP state and test takes care of the rest @@ -653,7 +638,7 @@ void CClientList::Debug_SocketDeleted(CClientReqSocket *deleted) const { for (POSITION pos = list.GetHeadPosition(); pos != NULL;) { CUpDownClient *cur_client = list.GetNext(pos); - if (!AfxIsValidAddress(cur_client, sizeof CUpDownClient)) + if (!cur_client) AfxDebugBreak(); if (thePrefs.m_iDbgHeap >= 2) ASSERT_VALID(cur_client); @@ -809,9 +794,9 @@ void CClientList::CleanUpClientList() // no state for some code lines and the code is also not prepared that a client object gets // invalid while working with it (aka setting a new state) // so this way is just the easy and safe one to go (as long as emule is basically single threaded) - const DWORD tick = ::GetTickCount(); - if (tick >= m_dwLastClientCleanUp + CLIENTLIST_CLEANUP_TIME) { - m_dwLastClientCleanUp = tick; + const DWORD curTick = ::GetTickCount(); + if (curTick >= m_dwLastClientCleanUp + CLIENTLIST_CLEANUP_TIME) { + m_dwLastClientCleanUp = curTick; uint32 cDeleted = 0; for (POSITION pos = list.GetHeadPosition(); pos != NULL;) { const CUpDownClient *pCurClient = list.GetNext(pos); @@ -834,7 +819,7 @@ CDeletedClient::CDeletedClient(const CUpDownClient *pClient) { m_cBadRequest = 0; m_dwInserted = ::GetTickCount(); - m_ItemsList.Add(PORTANDHASH{pClient->GetUserPort(), pClient->Credits()}); + m_ItemsList.Add(PORTANDHASH{ pClient->GetUserPort(), pClient->Credits() }); } // ZZ:DownloadManager --> @@ -858,18 +843,18 @@ void CClientList::ProcessA4AFClients() const void CClientList::AddKadFirewallRequest(uint32 dwIP) { - const DWORD tick = ::GetTickCount(); - listFirewallCheckRequests.AddHead(IPANDTICS{dwIP, tick}); - while (!listFirewallCheckRequests.IsEmpty() && tick >= listFirewallCheckRequests.GetTail().dwInserted + SEC2MS(180)) + const DWORD curTick = ::GetTickCount(); + listFirewallCheckRequests.AddHead(IPANDTICS{ dwIP, curTick }); + while (!listFirewallCheckRequests.IsEmpty() && curTick >= listFirewallCheckRequests.GetTail().dwInserted + SEC2MS(180)) listFirewallCheckRequests.RemoveTail(); } bool CClientList::IsKadFirewallCheckIP(uint32 dwIP) const { - const DWORD tick = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); for (POSITION pos = listFirewallCheckRequests.GetHeadPosition(); pos != NULL;) { const IPANDTICS &iptick = listFirewallCheckRequests.GetNext(pos); - if (tick >= iptick.dwInserted + SEC2MS(180)) + if (curTick >= iptick.dwInserted + SEC2MS(180)) break; if (iptick.dwIP == dwIP) return true; @@ -886,17 +871,17 @@ void CClientList::AddConnectingClient(CUpDownClient *pToAdd) } ASSERT(pToAdd->GetConnectingState() != CCS_NONE); - m_liConnectingClients.AddTail(CONNECTINGCLIENT{pToAdd, ::GetTickCount()}); + m_liConnectingClients.AddTail(CONNECTINGCLIENT{ pToAdd, ::GetTickCount() }); } void CClientList::ProcessConnectingClientsList() { // we do check if any connects have timed out by now - const DWORD tick = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); for (POSITION pos = m_liConnectingClients.GetHeadPosition(); pos != NULL;) { POSITION pos2 = pos; const CONNECTINGCLIENT cc = m_liConnectingClients.GetNext(pos); - if (tick >= cc.dwInserted + SEC2MS(45)) { + if (curTick >= cc.dwInserted + SEC2MS(45)) { ASSERT(cc.pClient->GetConnectingState() != CCS_NONE); m_liConnectingClients.RemoveAt(pos2); if (cc.pClient->Disconnected(_T("Connection try timeout"))) @@ -905,7 +890,7 @@ void CClientList::ProcessConnectingClientsList() } } -void CClientList::RemoveConnectingClient(CUpDownClient *pToRemove) +void CClientList::RemoveConnectingClient(const CUpDownClient *pToRemove) { for (POSITION pos = m_liConnectingClients.GetHeadPosition(); pos != NULL;) { POSITION pos2 = pos; @@ -918,18 +903,18 @@ void CClientList::RemoveConnectingClient(CUpDownClient *pToRemove) void CClientList::AddTrackCallbackRequests(uint32 dwIP) { - const DWORD tick = ::GetTickCount(); - listDirectCallbackRequests.AddHead(IPANDTICS{dwIP, tick}); - while (!listDirectCallbackRequests.IsEmpty() && tick >= listDirectCallbackRequests.GetTail().dwInserted + SEC2MS(180)) + const DWORD curTick = ::GetTickCount(); + listDirectCallbackRequests.AddHead(IPANDTICS{ dwIP, curTick }); + while (!listDirectCallbackRequests.IsEmpty() && curTick >= listDirectCallbackRequests.GetTail().dwInserted + SEC2MS(180)) listDirectCallbackRequests.RemoveTail(); } bool CClientList::AllowCalbackRequest(uint32 dwIP) const { - const DWORD tick = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); for (POSITION pos = listDirectCallbackRequests.GetHeadPosition(); pos != NULL;) { const IPANDTICS &iptick = listDirectCallbackRequests.GetNext(pos); - if (iptick.dwIP == dwIP && tick < iptick.dwInserted + SEC2MS(180)) + if (iptick.dwIP == dwIP && curTick < iptick.dwInserted + SEC2MS(180)) return false; } return true; diff --git a/srchybrid/ClientList.h b/srchybrid/ClientList.h index 5af5602e..2816b195 100644 --- a/srchybrid/ClientList.h +++ b/srchybrid/ClientList.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -42,12 +42,12 @@ struct PORTANDHASH struct IPANDTICS { uint32 dwIP; - uint32 dwInserted; + DWORD dwInserted; }; struct CONNECTINGCLIENT { CUpDownClient *pClient; - uint32 dwInserted; + DWORD dwInserted; }; @@ -56,7 +56,7 @@ class CDeletedClient public: explicit CDeletedClient(const CUpDownClient *pClient); CArray m_ItemsList; - uint32 m_dwInserted; + DWORD m_dwInserted; uint32 m_cBadRequest; }; @@ -68,6 +68,8 @@ enum buddyState }; // ----------------------CClientList Class--------------- +typedef CMap CClientVersionMap; + class CClientList { friend class CClientListCtrl; @@ -80,10 +82,10 @@ class CClientList void AddClient(CUpDownClient *toadd, bool bSkipDupTest = false); void RemoveClient(CUpDownClient *toremove, LPCTSTR pszReason = NULL); void GetStatistics(uint32 &ruTotalClients, int stats[NUM_CLIENTLIST_STATS], - CMap &clientVersionEDonkey, - CMap &clientVersionEDonkeyHybrid, - CMap &clientVersionEMule, - CMap &clientVersionAMule); + CClientVersionMap &clientVersionEDonkey, + CClientVersionMap &clientVersionEDonkeyHybrid, + CClientVersionMap &clientVersionEMule, + CClientVersionMap &clientVersionAMule); INT_PTR GetClientCount() { return list.GetCount(); } void DeleteAll(); bool AttachToAlreadyKnown(CUpDownClient **client, CClientReqSocket *sender); @@ -105,11 +107,11 @@ class CClientList // Tracked clients void AddTrackClient(CUpDownClient *toadd); - bool ComparePriorUserhash(uint32 dwIP, uint16 nPort, void *pNewHash); + bool ComparePriorUserhash(uint32 dwIP, uint16 nPort, const void *pNewHash); INT_PTR GetClientsFromIP(uint32 dwIP) const; void TrackBadRequest(const CUpDownClient *upcClient, int nIncreaseCounter); uint32 GetBadRequests(const CUpDownClient *upcClient) const; - INT_PTR GetTrackedCount() const { return m_trackedClientsList.GetCount(); } + INT_PTR GetTrackedCount() const { return m_trackedClientsMap.GetCount(); } void RemoveAllTrackedClients(); // Kad client list, buddy handling @@ -132,7 +134,7 @@ class CClientList // Connecting Clients void AddConnectingClient(CUpDownClient *pToAdd); - void RemoveConnectingClient(CUpDownClient *pToRemove); + void RemoveConnectingClient(const CUpDownClient *pToRemove); void Process(); bool IsValidClient(CUpDownClient *tocheck) const; @@ -153,7 +155,8 @@ class CClientList CUpDownClientPtrList list; CUpDownClientPtrList m_KadList; CMap m_bannedList; - CMap m_trackedClientsList; + typedef CMap CDeletedClientMap; + CDeletedClientMap m_trackedClientsMap; CUpDownClient *m_pBuddy; CList listFirewallCheckRequests; CList listDirectCallbackRequests; diff --git a/srchybrid/ClientListCtrl.cpp b/srchybrid/ClientListCtrl.cpp index 69c2defa..59c6d7dd 100644 --- a/srchybrid/ClientListCtrl.cpp +++ b/srchybrid/ClientListCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -61,47 +61,38 @@ void CClientListCtrl::Init() SetPrefsKey(_T("ClientListCtrl")); SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP); - InsertColumn(0, GetResString(IDS_QL_USERNAME), LVCFMT_LEFT, DFLT_CLIENTNAME_COL_WIDTH); - InsertColumn(1, GetResString(IDS_CL_UPLOADSTATUS), LVCFMT_LEFT, 100); - InsertColumn(2, GetResString(IDS_CL_TRANSFUP), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH); - InsertColumn(3, GetResString(IDS_CL_DOWNLSTATUS), LVCFMT_LEFT, 100); - InsertColumn(4, GetResString(IDS_CL_TRANSFDOWN), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH); - InsertColumn(5, GetResString(IDS_CD_CSOFT), LVCFMT_LEFT, DFLT_CLIENTSOFT_COL_WIDTH); - InsertColumn(6, GetResString(IDS_CONNECTED), LVCFMT_LEFT, 50); - CString coltemp; - coltemp = GetResString(IDS_CD_UHASH); - coltemp.Remove(_T(':')); - InsertColumn(7, coltemp, LVCFMT_LEFT, DFLT_HASH_COL_WIDTH); + InsertColumn(0, _T(""), LVCFMT_LEFT, DFLT_CLIENTNAME_COL_WIDTH); //IDS_QL_USERNAME + InsertColumn(1, _T(""), LVCFMT_LEFT, 100); //IDS_CL_UPLOADSTATUS + InsertColumn(2, _T(""), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH); //IDS_CL_TRANSFUP + InsertColumn(3, _T(""), LVCFMT_LEFT, 100); //IDS_CL_DOWNLSTATUS + InsertColumn(4, _T(""), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH); //IDS_CL_TRANSFDOWN + InsertColumn(5, _T(""), LVCFMT_LEFT, DFLT_CLIENTSOFT_COL_WIDTH); //IDS_CD_CSOFT + InsertColumn(6, _T(""), LVCFMT_LEFT, 50); //IDS_CONNECTED + InsertColumn(7, _T(""), LVCFMT_LEFT, DFLT_HASH_COL_WIDTH); //IDS_CD_UHASH SetAllIcons(); Localize(); LoadSettings(); SetSortArrow(); - SortItems(SortProc, GetSortItem() + (GetSortAscending() ? 0 : 100)); + SortItems(SortProc, MAKELONG(GetSortItem(), !GetSortAscending())); } void CClientListCtrl::Localize() { - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); - HDITEM hdi; - hdi.mask = HDI_TEXT; - static const UINT uids[7] = { - IDS_QL_USERNAME, IDS_CL_UPLOADSTATUS, IDS_CL_TRANSFUP, IDS_CL_DOWNLSTATUS - , IDS_CL_TRANSFDOWN, IDS_CD_CSOFT, IDS_CONNECTED + IDS_QL_USERNAME, IDS_CL_UPLOADSTATUS, IDS_CL_TRANSFUP, IDS_CL_DOWNLSTATUS, IDS_CL_TRANSFDOWN + , IDS_CD_CSOFT, IDS_CONNECTED }; - for (int i = 0; i < _countof(uids); ++i) { - const CString &strRes(GetResString(uids[i])); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(i, &hdi); - } + LocaliseHeaderCtrl(uids, _countof(uids)); CString strRes(GetResString(IDS_CD_UHASH)); strRes.Remove(_T(':')); + HDITEM hdi; + hdi.mask = HDI_TEXT; hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(7, &hdi); + GetHeaderCtrl()->SetItem(7, &hdi); } void CClientListCtrl::OnSysColorChange() @@ -113,61 +104,59 @@ void CClientListCtrl::OnSysColorChange() void CClientListCtrl::SetAllIcons() { ApplyImageList(NULL); - m_pImageList = theApp.emuledlg->transferwnd->GetClientIconList(); // Apply the image list also to the listview control, even if we use our own 'DrawItem'. // This is needed to give the listview control a chance to initialize the row height. ASSERT((GetStyle() & LVS_SHAREIMAGELISTS) != 0); + m_pImageList = &theApp.emuledlg->GetClientIconList(); VERIFY(ApplyImageList(*m_pImageList) == NULL); } void CClientListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { - if (theApp.IsClosing() || !lpDrawItemStruct->itemData) + if (!lpDrawItemStruct->itemData || theApp.IsClosing()) return; - CMemoryDC dc(CDC::FromHandle(lpDrawItemStruct->hDC), &lpDrawItemStruct->rcItem); + CRect rcItem(lpDrawItemStruct->rcItem); + CMemoryDC dc(CDC::FromHandle(lpDrawItemStruct->hDC), rcItem); BOOL bCtrlFocused; InitItemMemDC(dc, lpDrawItemStruct, bCtrlFocused); - CRect rcItem(lpDrawItemStruct->rcItem); RECT rcClient; GetClientRect(&rcClient); const CUpDownClient *client = reinterpret_cast(lpDrawItemStruct->itemData); - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); + const CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); int iCount = pHeaderCtrl->GetItemCount(); - rcItem.right = rcItem.left - sm_iLabelOffset; - rcItem.left += sm_iIconOffset; + LONG itemLeft = rcItem.left; + LONG iIconY = max((rcItem.Height() - 15) / 2, 0); for (int iCurrent = 0; iCurrent < iCount; ++iCurrent) { int iColumn = pHeaderCtrl->OrderToIndex(iCurrent); - if (!IsColumnHidden(iColumn)) { - UINT uDrawTextAlignment; - int iColumnWidth = GetColumnWidth(iColumn, uDrawTextAlignment); - rcItem.right += iColumnWidth; - if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) { - const CString &sItem(GetItemDisplayText(client, iColumn)); - switch (iColumn) { - case 0: //user name - { - int iImage; - UINT uOverlayImage; - client->GetDisplayImage(iImage, uOverlayImage); - - int iIconPosY = (rcItem.Height() > 16) ? ((rcItem.Height() - 16) / 2) : 1; - const POINT point = {rcItem.left, rcItem.top + iIconPosY}; - m_pImageList->Draw(dc, iImage, point, ILD_NORMAL | INDEXTOOVERLAYMASK(uOverlayImage)); - - rcItem.left += 16 + sm_iLabelOffset; - dc.DrawText(sItem, -1, &rcItem, MLC_DT_TEXT | uDrawTextAlignment); - rcItem.left -= 16; - rcItem.right -= sm_iSubItemInset; - } - break; - default: - dc.DrawText(sItem, -1, &rcItem, MLC_DT_TEXT | uDrawTextAlignment); + if (IsColumnHidden(iColumn)) + continue; + + UINT uDrawTextAlignment; + int iColumnWidth = GetColumnWidth(iColumn, uDrawTextAlignment); + rcItem.left = itemLeft; + rcItem.right = itemLeft + iColumnWidth - sm_iSubItemInset; + if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) { + const CString &sItem(GetItemDisplayText(client, iColumn)); + switch (iColumn) { + case 0: //user name + { + int iImage; + UINT uOverlayImage; + client->GetDisplayImage(iImage, uOverlayImage); + + rcItem.left = itemLeft + sm_iIconOffset; + const POINT point = { rcItem.left, rcItem.top + iIconY }; + m_pImageList->Draw(dc, iImage, point, ILD_NORMAL | INDEXTOOVERLAYMASK(uOverlayImage)); + rcItem.left += 16 + sm_iLabelOffset - sm_iSubItemInset; } + default: //any text column + rcItem.left += sm_iSubItemInset; + dc.DrawText(sItem, -1, &rcItem, MLC_DT_TEXT | uDrawTextAlignment); } - rcItem.left += iColumnWidth; } + itemLeft += iColumnWidth; } DrawFocusRect(dc, &lpDrawItemStruct->rcItem, lpDrawItemStruct->itemState & ODS_FOCUS, bCtrlFocused, lpDrawItemStruct->itemState & ODS_SELECTED); @@ -215,16 +204,16 @@ CString CClientListCtrl::GetItemDisplayText(const CUpDownClient *client, int iSu void CClientListCtrl::OnLvnGetDispInfo(LPNMHDR pNMHDR, LRESULT *pResult) { if (!theApp.IsClosing()) { - // Although we have an owner drawn listview control we store the text for the primary item in the listview, to be - // capable of quick searching those items via the keyboard. Because our listview items may change their contents, - // we do this via a text callback function. The listview control will send us the LVN_DISPINFO notification if - // it needs to know the contents of the primary item. + // Although we have an owner drawn listview control we store the text for the primary item in the + // listview, to be capable of quick searching those items via the keyboard. Because our listview + // items may change their contents, we do this via a text callback function. The listview control + // will send us the LVN_DISPINFO notification if it needs to know the contents of the primary item. // - // But, the listview control sends this notification all the time, even if we do not search for an item. At least - // this notification is only sent for the visible items and not for all items in the list. Though, because this - // function is invoked *very* often, do *NOT* put any time consuming code in here. + // But, the listview control sends this notification all the time, even if we do not search for an item. + // At least this notification is only sent for the visible items and not for all items in the list. + // Though, because this function is invoked *very* often, do *NOT* put any time consuming code in here. // - // Vista: That callback is used to get the strings for the label tips for the sub(!) items. + // Vista: That callback is used to get the strings for the label tips for the sub(!)-items. // const LVITEMW &rItem = reinterpret_cast(pNMHDR)->item; if (rItem.mask & LVIF_TEXT) { @@ -238,10 +227,10 @@ void CClientListCtrl::OnLvnGetDispInfo(LPNMHDR pNMHDR, LRESULT *pResult) void CClientListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) { - NMLISTVIEW *pNMListView = reinterpret_cast(pNMHDR); + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); bool sortAscending; - if (GetSortItem() != pNMListView->iSubItem) { - switch (pNMListView->iSubItem) { + if (GetSortItem() != pNMLV->iSubItem) { + switch (pNMLV->iSubItem) { case 1: // Upload State case 2: // Uploaded Total case 4: // Downloaded Total @@ -256,10 +245,9 @@ void CClientListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) sortAscending = !GetSortAscending(); // Sort table - UpdateSortHistory(pNMListView->iSubItem + (sortAscending ? 0 : 100)); - SetSortArrow(pNMListView->iSubItem, sortAscending); - SortItems(SortProc, pNMListView->iSubItem + (sortAscending ? 0 : 100)); - + UpdateSortHistory(MAKELONG(pNMLV->iSubItem, !sortAscending)); + SetSortArrow(pNMLV->iSubItem, sortAscending); + SortItems(SortProc, MAKELONG(pNMLV->iSubItem, !sortAscending)); *pResult = 0; } @@ -267,9 +255,9 @@ int CALLBACK CClientListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lP { const CUpDownClient *item1 = reinterpret_cast(lParam1); const CUpDownClient *item2 = reinterpret_cast(lParam2); - LONG_PTR iColumn = (lParamSort >= 100) ? lParamSort - 100 : lParamSort; + int iResult = 0; - switch (iColumn) { + switch (LOWORD(lParamSort)) { case 0: //user name if (item1->GetUserName() && item2->GetUserName()) iResult = CompareLocaleStringNoCase(item1->GetUserName(), item2->GetUserName()); @@ -278,20 +266,15 @@ int CALLBACK CClientListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lP else if (item2->GetUserName() == NULL) iResult = -1; // place clients with no user names at bottom break; - case 1: //upload status iResult = item1->GetUploadState() - item2->GetUploadState(); break; - case 2: //transferred up if (item1->credits && item2->credits) - iResult = CompareUnsigned64(item1->credits->GetUploadedTotal(), item2->credits->GetUploadedTotal()); - else if (item1->credits) - iResult = 1; + iResult = CompareUnsigned(item1->credits->GetUploadedTotal(), item2->credits->GetUploadedTotal()); else - iResult = -1; + iResult = (item1->credits) ? 1 : -1; break; - case 3: //download status if (item1->GetDownloadState() == item2->GetDownloadState()) { if (item1->IsRemoteQueueFull() && item2->IsRemoteQueueFull()) @@ -303,44 +286,36 @@ int CALLBACK CClientListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lP } else iResult = item1->GetDownloadState() - item2->GetDownloadState(); break; - case 4: //transferred down if (item1->credits && item2->credits) - iResult = CompareUnsigned64(item1->credits->GetDownloadedTotal(), item2->credits->GetDownloadedTotal()); - else if (item1->credits) - iResult = 1; + iResult = CompareUnsigned(item1->credits->GetDownloadedTotal(), item2->credits->GetDownloadedTotal()); else - iResult = -1; + iResult = (item1->credits) ? 1 : -1; break; - case 5: //software if (item1->GetClientSoft() == item2->GetClientSoft()) iResult = item1->GetVersion() - item2->GetVersion(); else iResult = -(item1->GetClientSoft() - item2->GetClientSoft()); // invert result to place eMule's at top break; - case 6: //connected if (item1->socket && item2->socket) iResult = item1->socket->IsConnected() - item2->socket->IsConnected(); - else if (item1->socket) - iResult = 1; else - iResult = -1; + iResult = (item1->socket) ? 1 : -1; break; - case 7: //hash iResult = memcmp(item1->GetUserHash(), item2->GetUserHash(), 16); } - if (lParamSort >= 100) + if (HIWORD(lParamSort)) iResult = -iResult; - //call secondary sort order, if this one results in equal + //call secondary sort order, if the first one resulted as equal if (iResult == 0) { - int dwNextSort = theApp.emuledlg->transferwnd->GetClientList()->GetNextSortOrder((int)lParamSort); - if (dwNextSort != -1) - iResult = SortProc(lParam1, lParam2, dwNextSort); + LPARAM iNextSort = theApp.emuledlg->transferwnd->GetClientList()->GetNextSortOrder(lParamSort); + if (iNextSort != -1) + iResult = SortProc(lParam1, lParam2, iNextSort); } return iResult; @@ -422,15 +397,15 @@ BOOL CClientListCtrl::OnCommand(WPARAM wParam, LPARAM) Kademlia::CKademlia::Bootstrap(ntohl(client->GetIP()), client->GetKadPort()); } } - return true; + return TRUE; } void CClientListCtrl::AddClient(const CUpDownClient *client) { - if (!theApp.IsClosing() && !thePrefs.IsKnownClientListDisabled()) { + if (!thePrefs.IsKnownClientListDisabled() && !theApp.IsClosing()) { int iItemCount = GetItemCount(); InsertItem(LVIF_TEXT | LVIF_PARAM, iItemCount, LPSTR_TEXTCALLBACK, 0, 0, 0, (LPARAM)client); - theApp.emuledlg->transferwnd->UpdateListCount(CTransferDlg::wnd2Clients, iItemCount + 1); + theApp.emuledlg->transferwnd->UpdateListCount(CTransferWnd::wnd2Clients, iItemCount + 1); } } @@ -443,15 +418,15 @@ void CClientListCtrl::RemoveClient(const CUpDownClient *client) int iItem = FindItem(&find); if (iItem >= 0) { DeleteItem(iItem); - theApp.emuledlg->transferwnd->UpdateListCount(CTransferDlg::wnd2Clients); + theApp.emuledlg->transferwnd->UpdateListCount(CTransferWnd::wnd2Clients); } } } void CClientListCtrl::RefreshClient(const CUpDownClient *client) { - if (!theApp.IsClosing() - && theApp.emuledlg->activewnd == theApp.emuledlg->transferwnd + if (theApp.emuledlg->activewnd == theApp.emuledlg->transferwnd + && !theApp.IsClosing() && theApp.emuledlg->transferwnd->GetClientList()->IsWindowVisible()) { LVFINDINFO find; @@ -488,10 +463,10 @@ void CClientListCtrl::ShowKnownClients() { DeleteAllItems(); int iItemCount = 0; - for (POSITION pos = theApp.clientlist->list.GetHeadPosition(); pos != NULL; ) { + for (POSITION pos = theApp.clientlist->list.GetHeadPosition(); pos != NULL;) { int iItem = InsertItem(LVIF_TEXT | LVIF_PARAM, iItemCount, LPSTR_TEXTCALLBACK, 0, 0, 0, (LPARAM)theApp.clientlist->list.GetNext(pos)); Update(iItem); ++iItemCount; } - theApp.emuledlg->transferwnd->UpdateListCount(CTransferDlg::wnd2Clients, iItemCount); + theApp.emuledlg->transferwnd->UpdateListCount(CTransferWnd::wnd2Clients, iItemCount); } \ No newline at end of file diff --git a/srchybrid/ClientListCtrl.h b/srchybrid/ClientListCtrl.h index a04e0436..ff95b76c 100644 --- a/srchybrid/ClientListCtrl.h +++ b/srchybrid/ClientListCtrl.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -24,6 +24,7 @@ class CClientListCtrl : public CMuleListCtrl, public CListCtrlItemWalk { DECLARE_DYNAMIC(CClientListCtrl) + CImageList *m_pImageList; public: CClientListCtrl(); @@ -38,7 +39,6 @@ class CClientListCtrl : public CMuleListCtrl, public CListCtrlItemWalk void ShowKnownClients(); protected: - CImageList *m_pImageList; void SetAllIcons(); CString GetItemDisplayText(const CUpDownClient *client, int iSubItem) const; static int CALLBACK SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); diff --git a/srchybrid/ClientStateDefs.h b/srchybrid/ClientStateDefs.h index a2a43adc..985949c1 100644 --- a/srchybrid/ClientStateDefs.h +++ b/srchybrid/ClientStateDefs.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -36,7 +36,7 @@ enum EDownloadState : uint8 DS_REQHASHSET, DS_NONEEDEDPARTS, DS_TOOMANYCONNS, - DS_TOOMANYCONNSKAD, + DS_TOOMANYCONNSKAD, //unused since 0.49b DS_LOWTOLOWIP, DS_BANNED, DS_ERROR, diff --git a/srchybrid/ClientUDPSocket.cpp b/srchybrid/ClientUDPSocket.cpp index f8183f16..5e52b454 100644 --- a/srchybrid/ClientUDPSocket.cpp +++ b/srchybrid/ClientUDPSocket.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -18,19 +18,18 @@ #include "emule.h" #include "ClientUDPSocket.h" #include "Packets.h" +#include "UpDownClient.h" #include "DownloadQueue.h" #include "Statistics.h" #include "PartFile.h" #include "SharedFileList.h" #include "UploadQueue.h" -#include "UpDownClient.h" #include "Preferences.h" #include "ClientList.h" #include "EncryptedDatagramSocket.h" #include "IPFilter.h" #include "Listensocket.h" #include "Log.h" -#include "OtherFunctions.h" #include "SafeFile.h" #include "kademlia/kademlia/Kademlia.h" #include "kademlia/kademlia/UDPFirewallTester.h" @@ -76,47 +75,49 @@ void CClientUDPSocket::OnReceive(int nErrorCode) SOCKADDR_IN sockAddr = {}; int iSockAddrLen = sizeof sockAddr; int nRealLen = ReceiveFrom(buffer, sizeof buffer, (LPSOCKADDR)&sockAddr, &iSockAddrLen); - if (!(theApp.ipfilter->IsFiltered(sockAddr.sin_addr.s_addr) || theApp.clientlist->IsBannedClient(sockAddr.sin_addr.s_addr))) { - BYTE *pBuffer; - uint32 nReceiverVerifyKey; - uint32 nSenderVerifyKey; - int nPacketLen = DecryptReceivedClient(buffer, nRealLen, &pBuffer, sockAddr.sin_addr.s_addr, &nReceiverVerifyKey, &nSenderVerifyKey); - if (nPacketLen >= 1) { - CString strError; - try { - switch (pBuffer[0]) { - case OP_EMULEPROT: - if (nPacketLen < 2) - throw CString(_T("eMule packet too short")); - ProcessPacket(pBuffer + 2, nPacketLen - 2, pBuffer[1], sockAddr.sin_addr.s_addr, ntohs(sockAddr.sin_port)); - break; - case OP_KADEMLIAPACKEDPROT: - { - theStats.AddDownDataOverheadKad(nPacketLen); - if (nPacketLen < 2) - throw CString(_T("Kad packet (compressed) too short")); - uint32 nNewSize = nPacketLen * 10 + 300; - BYTE *unpack = NULL; - uLongf unpackedsize = 0; - int iZLibResult = Z_OK; - do { - delete[] unpack; - unpack = new BYTE[nNewSize]; - unpackedsize = nNewSize - 2; - iZLibResult = uncompress(unpack + 2, &unpackedsize, pBuffer + 2, nPacketLen - 2); - nNewSize *= 2; // size for the next try if needed - } while (iZLibResult == Z_BUF_ERROR && nNewSize < 250000); + if (theApp.ipfilter->IsFiltered(sockAddr.sin_addr.s_addr) || theApp.clientlist->IsBannedClient(sockAddr.sin_addr.s_addr) || !sockAddr.sin_port) + return; - if (iZLibResult != Z_OK) { - delete[] unpack; - strError.Format(_T("Failed to uncompress Kad packet: zip error: %d (%hs)"), iZLibResult, zError(iZLibResult)); - throw strError; - } + BYTE *pBuffer; + uint32 nReceiverVerifyKey; + uint32 nSenderVerifyKey; + int nPacketLen = DecryptReceivedClient(buffer, nRealLen, &pBuffer, sockAddr.sin_addr.s_addr, &nReceiverVerifyKey, &nSenderVerifyKey); + if (nPacketLen > 0) { + CString strError; + try { + switch (pBuffer[0]) { + case OP_EMULEPROT: + if (nPacketLen < 2) + strError = _T("eMule packet too short"); + else + ProcessPacket(pBuffer + 2, nPacketLen - 2, pBuffer[1], sockAddr.sin_addr.s_addr, ntohs(sockAddr.sin_port)); + break; + case OP_KADEMLIAPACKEDPROT: + theStats.AddDownDataOverheadKad(nPacketLen); + if (nPacketLen < 2) + strError = _T("Kad packet (compressed) too short"); + else { + BYTE* unpack = NULL; + uLongf unpackedsize = 0; + uint32 nNewSize = nPacketLen * 10 + 300; + int iZLibResult = Z_OK; + do { + delete[] unpack; + unpack = new BYTE[nNewSize]; + unpackedsize = nNewSize - 2; + iZLibResult = uncompress(unpack + 2, &unpackedsize, pBuffer + 2, nPacketLen - 2); + nNewSize *= 2; // size for the next try if needed + } while (iZLibResult == Z_BUF_ERROR && nNewSize < 250000); + if (iZLibResult != Z_OK) { + delete[] unpack; + strError.Format(_T("Failed to uncompress Kad packet: zip error: %d (%hs)"), iZLibResult, zError(iZLibResult)); + } else { unpack[0] = OP_KADEMLIAHEADER; unpack[1] = pBuffer[1]; try { - Kademlia::CKademlia::ProcessPacket(unpack, unpackedsize + 2, ntohl(sockAddr.sin_addr.s_addr), ntohs(sockAddr.sin_port) + Kademlia::CKademlia::ProcessPacket(unpack, unpackedsize + 2 + , ntohl(sockAddr.sin_addr.s_addr), ntohs(sockAddr.sin_port) , (Kademlia::CPrefs::GetUDPVerifyKey(sockAddr.sin_addr.s_addr) == nReceiverVerifyKey) , Kademlia::CKadUDPKey(nSenderVerifyKey, theApp.GetPublicIP(false))); } catch (...) { @@ -125,73 +126,71 @@ void CClientUDPSocket::OnReceive(int nErrorCode) } delete[] unpack; } - break; - case OP_KADEMLIAHEADER: - theStats.AddDownDataOverheadKad(nPacketLen); - if (nPacketLen < 2) - throw CString(_T("Kad packet too short")); + } + break; + case OP_KADEMLIAHEADER: + theStats.AddDownDataOverheadKad(nPacketLen); + if (nPacketLen < 2) + strError = _T("Kad packet too short"); + else Kademlia::CKademlia::ProcessPacket(pBuffer, nPacketLen, ntohl(sockAddr.sin_addr.s_addr), ntohs(sockAddr.sin_port) , (Kademlia::CPrefs::GetUDPVerifyKey(sockAddr.sin_addr.s_addr) == nReceiverVerifyKey) , Kademlia::CKadUDPKey(nSenderVerifyKey, theApp.GetPublicIP(false))); - - break; - default: - strError.Format(_T("Unknown protocol 0x%02x"), pBuffer[0]); - throw strError; - } - } catch (CFileException *error) { - error->Delete(); - strError = _T("Invalid packet received"); - } catch (CMemoryException *error) { - error->Delete(); - strError = _T("Memory exception"); - } catch (const CString &error) { - strError = error; - } catch (Kademlia::CIOException *error) { - error->Delete(); - strError = _T("Invalid packet received"); - } catch (CException *error) { - error->Delete(); - strError = _T("General packet error"); + break; + default: + strError.Format(_T("Unknown protocol 0x%02x"), pBuffer[0]); } + //code above does not need to throw strError + } catch (CFileException *error) { + error->Delete(); + strError = _T("Invalid packet received"); + } catch (CMemoryException *error) { + error->Delete(); + strError = _T("Memory exception"); + } catch (const CString &error) { + strError = error; + } catch (Kademlia::CIOException *error) { + error->Delete(); + strError = _T("Invalid packet received"); + } catch (CException *error) { + error->Delete(); + strError = _T("General packet error"); #ifndef _DEBUG - catch (...) { - strError = _T("Unknown exception"); - ASSERT(0); - } + } catch (...) { + strError = _T("Unknown exception"); + ASSERT(0); #endif - if (thePrefs.GetVerbose() && !strError.IsEmpty()) { - CString strClientInfo; - CUpDownClient *client; - if (pBuffer[0] == OP_EMULEPROT) - client = theApp.clientlist->FindClientByIP_UDP(sockAddr.sin_addr.s_addr, ntohs(sockAddr.sin_port)); - else - client = theApp.clientlist->FindClientByIP_KadPort(sockAddr.sin_addr.s_addr, ntohs(sockAddr.sin_port)); - if (client) - strClientInfo = client->DbgGetClientInfo(); - else - strClientInfo.Format(_T("%s:%hu"), (LPCTSTR)ipstr(sockAddr.sin_addr), ntohs(sockAddr.sin_port)); - - DebugLogWarning(_T("Client UDP socket: prot=0x%02x opcode=0x%02x sizeaftercrypt=%u realsize=%u %s: %s"), pBuffer[0], pBuffer[1], nPacketLen, nRealLen, (LPCTSTR)strError, (LPCTSTR)strClientInfo); - } - } else if (nPacketLen == SOCKET_ERROR) { - DWORD dwError = WSAGetLastError(); - if (dwError == WSAECONNRESET) { - // Depending on local and remote OS and depending on used local (remote?) router we may receive - // WSAECONNRESET errors. According some KB articles, this is a special way of winsock to report - // that a sent UDP packet was not received by the remote host because it was not listening on - // the specified port -> no eMule running there. - // - // TODO: So, actually we should do something with this information and drop the related Kad node - // or eMule client... - ; - } - if (thePrefs.GetVerbose() && dwError != WSAECONNRESET) { - CString strClientInfo; - if (iSockAddrLen > 0 && sockAddr.sin_addr.s_addr != 0 && sockAddr.sin_addr.s_addr != INADDR_NONE) - strClientInfo.Format(_T(" from %s:%u"), (LPCTSTR)ipstr(sockAddr.sin_addr), ntohs(sockAddr.sin_port)); - DebugLogError(_T("Error: Client UDP socket, failed to receive data%s: %s"), (LPCTSTR)strClientInfo, (LPCTSTR)GetErrorMessage(dwError, 1)); - } + } + if (thePrefs.GetVerbose() && !strError.IsEmpty()) { + CString strClientInfo; + CUpDownClient *client; + if (pBuffer[0] == OP_EMULEPROT) + client = theApp.clientlist->FindClientByIP_UDP(sockAddr.sin_addr.s_addr, ntohs(sockAddr.sin_port)); + else + client = theApp.clientlist->FindClientByIP_KadPort(sockAddr.sin_addr.s_addr, ntohs(sockAddr.sin_port)); + if (client) + strClientInfo = client->DbgGetClientInfo(); + else + strClientInfo.Format(_T("%s:%hu"), (LPCTSTR)ipstr(sockAddr.sin_addr), ntohs(sockAddr.sin_port)); + + DebugLogWarning(_T("Client UDP socket: prot=0x%02x opcode=0x%02x sizeaftercrypt=%u realsize=%u %s: %s"), pBuffer[0], pBuffer[1], nPacketLen, nRealLen, (LPCTSTR)strError, (LPCTSTR)strClientInfo); + } + } else if (nPacketLen == SOCKET_ERROR) { + DWORD dwError = WSAGetLastError(); + if (dwError == WSAECONNRESET) { + // Depending on local and remote OS and depending on used local (remote?) router we may receive + // WSAECONNRESET errors. According to some KB articles, this is a special way of winsock to report + // that a sent UDP packet was not received by the remote host because it was not listening on + // the specified port -> no eMule running there. + // + // TODO: So, actually we should do something with this information and drop the related Kad node + // or eMule client... + ; + } else if (thePrefs.GetVerbose()) { + CString strClientInfo; + if (iSockAddrLen > 0 && sockAddr.sin_addr.s_addr != 0 && sockAddr.sin_addr.s_addr != INADDR_NONE) + strClientInfo.Format(_T(" from %s:%u"), (LPCTSTR)ipstr(sockAddr.sin_addr), ntohs(sockAddr.sin_port)); + DebugLogError(_T("Error: Client UDP socket, failed to receive data%s: %s"), (LPCTSTR)strClientInfo, (LPCTSTR)GetErrorMessage(dwError, 1)); } } } @@ -228,7 +227,7 @@ bool CClientUDPSocket::ProcessPacket(const BYTE *packet, UINT size, uint8 opcode { theStats.AddDownDataOverheadFileRequest(size); CSafeMemFile data_in(packet, size); - uchar reqfilehash[16]; + uchar reqfilehash[MDX_DIGEST_SIZE]; data_in.ReadHash16(reqfilehash); CKnownFile *reqfile = theApp.sharedfiles->GetFileByID(reqfilehash); @@ -254,7 +253,7 @@ bool CClientUDPSocket::ProcessPacket(const BYTE *packet, UINT size, uint8 opcode //Make sure we are still thinking about the same file if (md4equ(reqfilehash, sender->GetUploadFileID())) { - sender->AddAskedCount(); + sender->IncrementAskedCount(); sender->SetLastUpRequest(); //I messed up when I first added extended info to UDP //I should have originally used the entire ProcessExtendedInfo the first time. @@ -276,14 +275,14 @@ bool CClientUDPSocket::ProcessPacket(const BYTE *packet, UINT size, uint8 opcode CSafeMemFile data_out(128); if (sender->GetUDPVersion() > 3) { if (reqfile->IsPartFile()) - static_cast(reqfile)->WritePartStatus(&data_out); + static_cast(reqfile)->WritePartStatus(data_out); else data_out.WriteUInt16(0); } data_out.WriteUInt16((uint16)(theApp.uploadqueue->GetWaitingPosition(sender))); if (thePrefs.GetDebugClientUDPLevel() > 0) DebugSend("OP_ReaskAck", sender); - Packet *response = new Packet(&data_out, OP_EMULEPROT); + Packet *response = new Packet(data_out, OP_EMULEPROT); response->opcode = OP_REASKACK; theStats.AddUpDataOverheadFileRequest(response->size); SendPacket(response, ip, port, sender->ShouldReceiveCryptUDPPackets(), sender->GetUserHash(), false, 0); @@ -336,7 +335,7 @@ bool CClientUDPSocket::ProcessPacket(const BYTE *packet, UINT size, uint8 opcode uint16 nRank = data_in.ReadUInt16(); sender->SetRemoteQueueFull(false); sender->UDPReaskACK(nRank); - sender->AddAskedCountDown(); + sender->IncrementAskedCountDown(); } else if (sender != NULL) DebugLogError(_T("Received UDP Packet (OP_REASKACK) which was not requested (pendingflag == false); Ignored packet - %s"), (LPCTSTR)sender->DbgGetClientInfo()); } @@ -377,7 +376,7 @@ bool CClientUDPSocket::ProcessPacket(const BYTE *packet, UINT size, uint8 opcode theApp.clientlist->AddTrackCallbackRequests(ip); CSafeMemFile data(packet, size); uint16 nRemoteTCPPort = data.ReadUInt16(); - uchar uchUserHash[16]; + uchar uchUserHash[MDX_DIGEST_SIZE]; data.ReadHash16(uchUserHash); uint8 byConnectOptions = data.ReadUInt8(); CUpDownClient *pRequester = theApp.clientlist->FindClientByUserHash(uchUserHash, ip, nRemoteTCPPort); @@ -431,11 +430,14 @@ SocketSentBytes CClientUDPSocket::SendControlData(uint32 maxNumberOfBytesToSend, // ZZ:UploadBandWithThrottler (UDP) --> // NOTE: *** This function is invoked from a *different* thread! uint32 sentBytes = 0; + DWORD curTick; + sendLocker.Lock(); // <-- ZZ:UploadBandWithThrottler (UDP) + curTick = ::GetTickCount(); while (!controlpacket_queue.IsEmpty() && !IsBusy() && sentBytes < maxNumberOfBytesToSend) { // ZZ:UploadBandWithThrottler (UDP) UDPPack *cur_packet = controlpacket_queue.RemoveHead(); - if (::GetTickCount() < cur_packet->dwTime + UDPMAXQUEUETIME) { + if (curTick < cur_packet->dwTime + UDPMAXQUEUETIME) { int nLen = (int)cur_packet->packet->size + 2; int iLen = cur_packet->bEncrypt && (theApp.GetPublicIP() > 0 || cur_packet->bKad) ? EncryptOverheadSize(cur_packet->bKad) : 0; @@ -455,6 +457,7 @@ SocketSentBytes CClientUDPSocket::SendControlData(uint32 maxNumberOfBytesToSend, } else { controlpacket_queue.AddHead(cur_packet); //try to resend ::Sleep(20); + curTick = ::GetTickCount(); } delete[] sendbuffer; } else { @@ -469,7 +472,7 @@ SocketSentBytes CClientUDPSocket::SendControlData(uint32 maxNumberOfBytesToSend, sendLocker.Unlock(); - return SocketSentBytes{0, sentBytes, true}; + return SocketSentBytes{ 0, sentBytes, true }; // <-- ZZ:UploadBandWithThrottler (UDP) } @@ -524,7 +527,7 @@ bool CClientUDPSocket::SendPacket(Packet *packet, uint32 dwIP, uint16 nPort, boo bool CClientUDPSocket::Create() { if (thePrefs.GetUDPPort()) { - if (!CAsyncSocket::Create(thePrefs.GetUDPPort(), SOCK_DGRAM, FD_READ | FD_WRITE, thePrefs.GetBindAddrW())) + if (!CAsyncSocket::Create(thePrefs.GetUDPPort(), SOCK_DGRAM, FD_READ | FD_WRITE, thePrefs.GetBindAddr())) return false; m_port = thePrefs.GetUDPPort(); // the default socket size seems to be insufficient for this UDP socket diff --git a/srchybrid/ClientUDPSocket.h b/srchybrid/ClientUDPSocket.h index a56b6834..6188be20 100644 --- a/srchybrid/ClientUDPSocket.h +++ b/srchybrid/ClientUDPSocket.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -26,7 +26,7 @@ struct UDPPack Packet *packet; uint32 dwIP; uint16 nPort; - uint32 dwTime; + DWORD dwTime; bool bEncrypt; bool bKad; uint32 nReceiverVerifyKey; @@ -54,7 +54,7 @@ class CClientUDPSocket : public CAsyncSocket, public CEncryptedDatagramSocket, p virtual void OnReceive(int nErrorCode); private: - int SendTo(uchar *lpBuf, int nBufLen, uint32 dwIP, uint16 nPort); + int SendTo(uchar *lpBuf, int nBufLen, uint32 dwIP, uint16 nPort); bool IsBusy() const { return m_bWouldBlock; } CTypedPtrList controlpacket_queue; diff --git a/srchybrid/ClientVersionInfo.h b/srchybrid/ClientVersionInfo.h index 747dc89b..11359d1f 100644 --- a/srchybrid/ClientVersionInfo.h +++ b/srchybrid/ClientVersionInfo.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -21,10 +21,10 @@ #define CVI_IGNORED (UINT_MAX) // Version comparison rules -// == means same client type, same or ignored version (for example eMule/0.4.* == eMule/0.4.2 ) -// != means different client or different defined version (for example eMule/0.4.2 != SomeClient/0.4.2 ) -// > mean _same client type_ and higher version, which therefore cannot be completely undefined ( for example eMule/1.* > eMule/0.4.2 ) -// >= same as > but here the version can be undefined ( for example eMule/* >= eMule/0.4.2 ) +// == means same client type, same or ignored version (for example, eMule/0.4.* == eMule/0.4.2) +// != means different client or different defined version (for example, eMule/0.4.2 != SomeClient/0.4.2) +// > mean _same client type_ and higher version, which therefore cannot be completely undefined (for example, eMule/1.* > eMule/0.4.2) +// >= same as > but here the version can be undefined (for example, eMule/* >= eMule/0.4.2) class CClientVersionInfo { void init(UINT nVerMajor, UINT nVerMinor, UINT nVerUpdate, UINT nVerBuild, UINT ClientTypeMajor, UINT ClientTypeMinor) @@ -47,8 +47,8 @@ class CClientVersionInfo theApp.QueueDebugLogLine(false, _T("PeerCache Error: Bad Version info in PeerCache Descriptor found: %s"), (LPCTSTR)strPCEncodedVersion); return; } - const CString &strClientType(strPCEncodedVersion.Left(posSeparator).Trim()); - const CString &strVersionNumber(strPCEncodedVersion.Mid(posSeparator + 1).Trim()); + const CString strClientType(strPCEncodedVersion.Left(posSeparator).Trim()); + const CString strVersionNumber(strPCEncodedVersion.Mid(posSeparator + 1).Trim()); if (strClientType.CompareNoCase(_T("eMule")) == 0) m_ClientTypeMajor = SO_EMULE; @@ -64,31 +64,22 @@ class CClientVersionInfo CString strNumber = strVersionNumber.Tokenize(_T("."), iPos); if (strNumber.IsEmpty()) return; - if (strNumber == _T("*")) - m_nVerMajor = UINT_MAX; - else - m_nVerMajor = _tstoi(strNumber); + m_nVerMajor = (strNumber == _T("*")) ? CVI_IGNORED : _tstoi(strNumber); + strNumber = strVersionNumber.Tokenize(_T("."), iPos); if (strNumber.IsEmpty()) return; - if (strNumber == _T("*")) - m_nVerMinor = UINT_MAX; - else - m_nVerMinor = _tstoi(strNumber); + m_nVerMinor = (strNumber == _T("*")) ? CVI_IGNORED : _tstoi(strNumber); + strNumber = strVersionNumber.Tokenize(_T("."), iPos); if (strNumber.IsEmpty()) return; - if (strNumber == _T("*")) - m_nVerUpdate = UINT_MAX; - else - m_nVerUpdate = _tstoi(strNumber); + m_nVerUpdate = (strNumber == _T("*")) ? CVI_IGNORED : _tstoi(strNumber); + strNumber = strVersionNumber.Tokenize(_T("."), iPos); if (strNumber.IsEmpty()) return; - if (strNumber == _T("*")) - m_nVerBuild = UINT_MAX; - else - m_nVerBuild = _tstoi(strNumber); + m_nVerBuild = (strNumber == _T("*")) ? CVI_IGNORED : _tstoi(strNumber); } CClientVersionInfo(uint32 dwTagVersionInfo, UINT nClientMajor) @@ -109,17 +100,6 @@ class CClientVersionInfo init(CVI_IGNORED, CVI_IGNORED, CVI_IGNORED, CVI_IGNORED, SO_UNKNOWN, SO_UNKNOWN); } - CClientVersionInfo(const CClientVersionInfo &cv) - { - *this = cv; - } - - CClientVersionInfo& operator=(const CClientVersionInfo &cv) - { - init(cv.m_nVerMajor, cv.m_nVerMinor, cv.m_nVerUpdate, cv.m_nVerBuild, cv.m_ClientTypeMajor, cv.m_ClientTypeMinor); - return *this; - } - friend bool operator==(const CClientVersionInfo &c1, const CClientVersionInfo &c2) { return (c1.m_nVerMajor == CVI_IGNORED || c2.m_nVerMajor == CVI_IGNORED || c1.m_nVerMajor == c2.m_nVerMajor) @@ -137,18 +117,16 @@ class CClientVersionInfo friend bool operator >(const CClientVersionInfo &c1, const CClientVersionInfo &c2) { - if ((c1.m_ClientTypeMajor == CVI_IGNORED || c2.m_ClientTypeMajor == CVI_IGNORED || c1.m_ClientTypeMajor != c2.m_ClientTypeMajor) - || (c1.m_ClientTypeMinor != c2.m_ClientTypeMinor)) + if (c1.m_ClientTypeMajor == CVI_IGNORED || c2.m_ClientTypeMajor == CVI_IGNORED + || c1.m_ClientTypeMajor != c2.m_ClientTypeMajor || c1.m_ClientTypeMinor != c2.m_ClientTypeMinor) + { return false; - if (c1.m_nVerMajor != CVI_IGNORED && c2.m_nVerMajor != CVI_IGNORED && c1.m_nVerMajor > c2.m_nVerMajor) - return true; - if (c1.m_nVerMinor != CVI_IGNORED && c2.m_nVerMinor != CVI_IGNORED && c1.m_nVerMinor > c2.m_nVerMinor) - return true; - if (c1.m_nVerUpdate != CVI_IGNORED && c2.m_nVerUpdate != CVI_IGNORED && c1.m_nVerUpdate > c2.m_nVerUpdate) - return true; - if (c1.m_nVerBuild != CVI_IGNORED && c2.m_nVerBuild != CVI_IGNORED && c1.m_nVerBuild > c2.m_nVerBuild) - return true; - return false; + } + return (c1.m_nVerMajor != CVI_IGNORED && c2.m_nVerMajor != CVI_IGNORED && c1.m_nVerMajor > c2.m_nVerMajor) + || (c1.m_nVerMinor != CVI_IGNORED && c2.m_nVerMinor != CVI_IGNORED && c1.m_nVerMinor > c2.m_nVerMinor) + || (c1.m_nVerUpdate != CVI_IGNORED && c2.m_nVerUpdate != CVI_IGNORED && c1.m_nVerUpdate > c2.m_nVerUpdate) + || (c1.m_nVerBuild != CVI_IGNORED && c2.m_nVerBuild != CVI_IGNORED && c1.m_nVerBuild > c2.m_nVerBuild); + } friend bool operator <(const CClientVersionInfo &c1, const CClientVersionInfo &c2) diff --git a/srchybrid/ClosableTabCtrl.cpp b/srchybrid/ClosableTabCtrl.cpp index e1f7d50e..ea360ef0 100644 --- a/srchybrid/ClosableTabCtrl.cpp +++ b/srchybrid/ClosableTabCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/ClosableTabCtrl.h b/srchybrid/ClosableTabCtrl.h index 4cd40222..09621620 100644 --- a/srchybrid/ClosableTabCtrl.h +++ b/srchybrid/ClosableTabCtrl.h @@ -6,7 +6,6 @@ class CClosableTabCtrl : public CTabCtrl public: CClosableTabCtrl(); - virtual ~CClosableTabCtrl() = default; BOOL DeleteItem(int nItem); bool m_bClosable; diff --git a/srchybrid/Collection.cpp b/srchybrid/Collection.cpp index e785c7b6..8b748601 100644 --- a/srchybrid/Collection.cpp +++ b/srchybrid/Collection.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -60,12 +60,8 @@ CCollection::CCollection(const CCollection *pCollection) } m_CollectionFilesMap.InitHashTable(1031); - CSKey key; - for (POSITION pos = pCollection->m_CollectionFilesMap.GetStartPosition(); pos != NULL;) { - CCollectionFile *pCollectionFile; - pCollection->m_CollectionFilesMap.GetNextAssoc(pos, key, pCollectionFile); - AddFileToCollection(pCollectionFile, true); - } + for (const CCollectionFilesMap::CPair *pair = pCollection->m_CollectionFilesMap.PGetFirstAssoc(); pair != NULL; pair = pCollection->m_CollectionFilesMap.PGetNextAssoc(pair)) + AddFileToCollection(pair->value, true); } CCollection::~CCollection() @@ -77,7 +73,6 @@ CCollection::~CCollection() m_CollectionFilesMap.GetNextAssoc(pos, key, pCollectionFile); delete pCollectionFile; } - m_CollectionFilesMap.RemoveAll(); } CCollectionFile* CCollection::AddFileToCollection(CAbstractFile *pAbstractFile, bool bCreateClone) @@ -89,15 +84,15 @@ CCollectionFile* CCollection::AddFileToCollection(CAbstractFile *pAbstractFile, return pCollectionFile; } - pCollectionFile = NULL; - if (bCreateClone) pCollectionFile = new CCollectionFile(pAbstractFile); else if (pAbstractFile->IsKindOf(RUNTIME_CLASS(CCollectionFile))) pCollectionFile = static_cast(pAbstractFile); + else + pCollectionFile = NULL; if (pCollectionFile) - m_CollectionFilesMap.SetAt(key, pCollectionFile); + m_CollectionFilesMap[key] = pCollectionFile; return pCollectionFile; } @@ -127,82 +122,80 @@ void CCollection::SetCollectionAuthorKey(const byte *abyCollectionAuthorKey, uin bool CCollection::InitCollectionFromFile(const CString &sFilePath, const CString &sFileName) { - bool bCollectionLoaded = false; - CSafeFile data; - if (data.Open(sFilePath, CFile::modeRead | CFile::shareDenyWrite | CFile::typeBinary)) { - try { - uint32 nVersion = data.ReadUInt32(); - if (nVersion == COLLECTION_FILE_VERSION1_INITIAL || nVersion == COLLECTION_FILE_VERSION2_LARGEFILES) { - for (uint32 headerTagCount = data.ReadUInt32(); headerTagCount > 0; --headerTagCount) { - CTag tag(&data, true); - switch (tag.GetNameID()) { - case FT_FILENAME: - if (tag.IsStr()) - m_sCollectionName = tag.GetStr(); - break; - case FT_COLLECTIONAUTHOR: - if (tag.IsStr()) - m_sCollectionAuthorName = tag.GetStr(); - break; - case FT_COLLECTIONAUTHORKEY: - if (tag.IsBlob()) - SetCollectionAuthorKey(tag.GetBlob(), tag.GetBlobSize()); - } + if (!data.Open(sFilePath, CFile::modeRead | CFile::shareDenyWrite | CFile::typeBinary)) + return false; + bool bCollectionLoaded = false; + try { + uint32 nVersion = data.ReadUInt32(); + if (nVersion == COLLECTION_FILE_VERSION1_INITIAL || nVersion == COLLECTION_FILE_VERSION2_LARGEFILES) { + for (uint32 headerTagCount = data.ReadUInt32(); headerTagCount > 0; --headerTagCount) { + CTag tag(data, true); + switch (tag.GetNameID()) { + case FT_FILENAME: + if (tag.IsStr()) + m_sCollectionName = tag.GetStr(); + break; + case FT_COLLECTIONAUTHOR: + if (tag.IsStr()) + m_sCollectionAuthorName = tag.GetStr(); + break; + case FT_COLLECTIONAUTHORKEY: + if (tag.IsBlob()) + SetCollectionAuthorKey(tag.GetBlob(), tag.GetBlobSize()); } - for (uint32 fileCount = data.ReadUInt32(); fileCount > 0; --fileCount) - try { - CCollectionFile *pCollectionFile = new CCollectionFile(&data); - AddFileToCollection(pCollectionFile, false); - } catch (...) { - } - - bCollectionLoaded = true; } - if (m_pabyCollectionAuthorKey != NULL) { - bool bResult = false; - if (data.GetLength() > data.GetPosition()) { - using namespace CryptoPP; + for (uint32 fileCount = data.ReadUInt32(); fileCount > 0; --fileCount) + try { + CCollectionFile *pCollectionFile = new CCollectionFile(data); + AddFileToCollection(pCollectionFile, false); + } catch (...) { + ASSERT(0); + } - uint32 nPos = (uint32)data.GetPosition(); - data.SeekToBegin(); - BYTE *pMessage = new BYTE[nPos]; - VERIFY(data.Read(pMessage, nPos) == nPos); + bCollectionLoaded = true; + } + if (m_pabyCollectionAuthorKey != NULL) { + bool bResult = false; + if (data.GetLength() > data.GetPosition()) { + using namespace CryptoPP; - StringSource ss_Pubkey(m_pabyCollectionAuthorKey, m_nKeySize, true, 0); - RSASSA_PKCS1v15_SHA_Verifier pubkey(ss_Pubkey); + uint32 nPos = (uint32)data.GetPosition(); + data.SeekToBegin(); + BYTE *pMessage = new BYTE[nPos]; + VERIFY(data.Read(pMessage, nPos) == nPos); - UINT nSignLen = (UINT)(data.GetLength() - data.GetPosition()); - BYTE *pSignature = new BYTE[nSignLen]; - VERIFY(data.Read(pSignature, nSignLen) == nSignLen); + StringSource ss_Pubkey(m_pabyCollectionAuthorKey, m_nKeySize, true, 0); + RSASSA_PKCS1v15_SHA_Verifier pubkey(ss_Pubkey); - bResult = pubkey.VerifyMessage(pMessage, nPos, pSignature, nSignLen); + UINT nSignLen = (UINT)(data.GetLength() - data.GetPosition()); + BYTE *pSignature = new BYTE[nSignLen]; + VERIFY(data.Read(pSignature, nSignLen) == nSignLen); - delete[] pMessage; - delete[] pSignature; - } - if (!bResult) { - DebugLogWarning(_T("Collection %s: Verification of public key failed!"), (LPCTSTR)m_sCollectionName); - delete[] m_pabyCollectionAuthorKey; - m_pabyCollectionAuthorKey = NULL; - m_nKeySize = 0; - m_sCollectionAuthorName.Empty(); - } else - DebugLog(_T("Collection %s: Public key verified"), (LPCTSTR)m_sCollectionName); + bResult = pubkey.VerifyMessage(pMessage, nPos, pSignature, nSignLen); - } else + delete[] pMessage; + delete[] pSignature; + } + if (!bResult) { + DebugLogWarning(_T("Collection %s: Verification of public key failed!"), (LPCTSTR)m_sCollectionName); + delete[] m_pabyCollectionAuthorKey; + m_pabyCollectionAuthorKey = NULL; + m_nKeySize = 0; m_sCollectionAuthorName.Empty(); - data.Close(); - } catch (CFileException *error) { - error->Delete(); - return false; - } catch (...) { - ASSERT(0); - data.Close(); - return false; - } - } else + } else + DebugLog(_T("Collection %s: Public key verified"), (LPCTSTR)m_sCollectionName); + + } else + m_sCollectionAuthorName.Empty(); + data.Close(); + } catch (CFileException *error) { + error->Delete(); return false; + } catch (...) { + ASSERT(0); + return false; + } if (!bCollectionLoaded) { CStdioFile data1; @@ -221,27 +214,25 @@ bool CCollection::InitCollectionFromFile(const CString &sFilePath, const CString delete pCollectionFile; } catch (...) { ASSERT(0); - data1.Close(); return false; } } } data1.Close(); - m_sCollectionName = sFileName; - DEBUG_ONLY(m_sCollectionName.Replace(COLLECTION_FILEEXTENSION, _T(""))); - bCollectionLoaded = true; + //No collection name tag; use file name without extension + int iLen = sFileName.GetLength(); + if (HasCollectionExtention(sFileName)) + iLen -= _countof(COLLECTION_FILEEXTENSION) - 1; + m_sCollectionName = sFileName.Left(iLen); m_bTextFormat = true; + return true; } catch (CFileException *error) { error->Delete(); - return false; } catch (...) { ASSERT(0); - data1.Close(); - return false; } } } - return bCollectionLoaded; } @@ -249,27 +240,23 @@ void CCollection::WriteToFileAddShared(CryptoPP::RSASSA_PKCS1v15_SHA_Signer *pSi { using namespace CryptoPP; - CString sFilePath; - sFilePath.Format(_T("%s\\%s%s"), (LPCTSTR)thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR), (LPCTSTR)m_sCollectionName, COLLECTION_FILEEXTENSION); + CString sFilePath(thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR)); + sFilePath.AppendFormat(_T("%s%s"), (LPCTSTR)m_sCollectionName, COLLECTION_FILEEXTENSION); if (m_bTextFormat) { CStdioFile data; if (data.Open(sFilePath, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite | CFile::typeText)) { try { - CSKey key; - for (POSITION pos = m_CollectionFilesMap.GetStartPosition(); pos != NULL;) { - CCollectionFile *pCollectionFile; - m_CollectionFilesMap.GetNextAssoc(pos, key, pCollectionFile); - if (pCollectionFile) - data.WriteString(pCollectionFile->GetED2kLink() + _T('\n')); - } + for (const CCollectionFilesMap::CPair *pair = m_CollectionFilesMap.PGetFirstAssoc(); pair != NULL; pair = m_CollectionFilesMap.PGetNextAssoc(pair)) + if (pair->value) + data.WriteString(pair->value->GetED2kLink() + _T('\n')); + data.Close(); } catch (CFileException *error) { error->Delete(); return; } catch (...) { ASSERT(0); - data.Close(); return; } } @@ -280,46 +267,32 @@ void CCollection::WriteToFileAddShared(CryptoPP::RSASSA_PKCS1v15_SHA_Signer *pSi //Version // check first if we have any large files in the map - write use lowest version possible uint32 dwVersion = COLLECTION_FILE_VERSION1_INITIAL; - for (POSITION pos = m_CollectionFilesMap.GetStartPosition(); pos != NULL;) { - CCollectionFile *pCollectionFile; - CSKey key; - m_CollectionFilesMap.GetNextAssoc(pos, key, pCollectionFile); - if (pCollectionFile->IsLargeFile()) { + for (const CCollectionFilesMap::CPair *pair = m_CollectionFilesMap.PGetFirstAssoc(); pair != NULL; pair = m_CollectionFilesMap.PGetNextAssoc(pair)) + if (pair->value->IsLargeFile()) { dwVersion = COLLECTION_FILE_VERSION2_LARGEFILES; break; } - } - data.WriteUInt32(dwVersion); - - uint32 uTagCount = 1; + data.WriteUInt32(dwVersion); //NumberHeaderTags - if (m_pabyCollectionAuthorKey != NULL) - uTagCount += 2; - - - data.WriteUInt32(uTagCount); + data.WriteUInt32(m_pabyCollectionAuthorKey ? 3 : 1); CTag collectionName(FT_FILENAME, m_sCollectionName); - collectionName.WriteTagToFile(&data, UTF8strRaw); + collectionName.WriteTagToFile(data, UTF8strRaw); if (m_pabyCollectionAuthorKey != NULL) { CTag collectionAuthor(FT_COLLECTIONAUTHOR, m_sCollectionAuthorName); - collectionAuthor.WriteTagToFile(&data, UTF8strRaw); + collectionAuthor.WriteTagToFile(data, UTF8strRaw); CTag collectionAuthorKey(FT_COLLECTIONAUTHORKEY, m_nKeySize, m_pabyCollectionAuthorKey); - collectionAuthorKey.WriteTagToFile(&data, UTF8strRaw); + collectionAuthorKey.WriteTagToFile(data, UTF8strRaw); } //Total Files data.WriteUInt32((uint32)m_CollectionFilesMap.GetCount()); - CSKey key; - for (POSITION pos = m_CollectionFilesMap.GetStartPosition(); pos != NULL;) { - CCollectionFile *pCollectionFile; - m_CollectionFilesMap.GetNextAssoc(pos, key, pCollectionFile); - pCollectionFile->WriteCollectionInfo(&data); - } + for (const CCollectionFilesMap::CPair *pair = m_CollectionFilesMap.PGetFirstAssoc(); pair != NULL; pair = m_CollectionFilesMap.PGetNextAssoc(pair)) + pair->value->WriteCollectionInfo(data); if (pSignKey != NULL) { uint32 nPos = (uint32)data.GetPosition(); @@ -343,7 +316,6 @@ void CCollection::WriteToFileAddShared(CryptoPP::RSASSA_PKCS1v15_SHA_Signer *pSi return; } catch (...) { ASSERT(0); - data.Close(); return; } } @@ -354,14 +326,12 @@ void CCollection::WriteToFileAddShared(CryptoPP::RSASSA_PKCS1v15_SHA_Signer *pSi bool CCollection::HasCollectionExtention(const CString &sFileName) { - return sFileName.Find(COLLECTION_FILEEXTENSION) >= 0; + return ExtensionIs(sFileName, COLLECTION_FILEEXTENSION); } CString CCollection::GetCollectionAuthorKeyString() { - if (m_pabyCollectionAuthorKey == NULL) - return CString(); - return EncodeBase16(m_pabyCollectionAuthorKey, m_nKeySize); + return m_pabyCollectionAuthorKey ? EncodeBase16(m_pabyCollectionAuthorKey, m_nKeySize) : CString(); } CString CCollection::GetAuthorKeyHashString() const diff --git a/srchybrid/Collection.h b/srchybrid/Collection.h index faa12afa..8c861f24 100644 --- a/srchybrid/Collection.h +++ b/srchybrid/Collection.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( merkur-@users.sourceforge.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -16,10 +16,10 @@ //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #pragma once #include "MapKey.h" -#include -#include -#include -#include +#include "cryptopp/rsa.h" +#include "cryptopp/base64.h" +#include "cryptopp/osrng.h" +#include "cryptopp/files.h" #define COLLECTION_FILEEXTENSION _T(".emulecollection") @@ -38,14 +38,14 @@ class CCollection ~CCollection(); CCollection(const CCollection&) = delete; CCollection& operator=(const CCollection&) = delete; - bool InitCollectionFromFile(const CString &sFilePath, const CString &sFileName); + bool InitCollectionFromFile(const CString &sFilePath, const CString &sFileName); CCollectionFile* AddFileToCollection(CAbstractFile *pAbstractFile, bool bCreateClone); - void RemoveFileFromCollection(CAbstractFile *pAbstractFile); - void WriteToFileAddShared(CryptoPP::RSASSA_PKCS1v15_SHA_Signer *pSignKey = NULL); - void SetCollectionAuthorKey(const byte *abyCollectionAuthorKey, uint32 nSize); - CString GetCollectionAuthorKeyString(); - static bool HasCollectionExtention(const CString &sFileName); + void RemoveFileFromCollection(CAbstractFile *pAbstractFile); + void WriteToFileAddShared(CryptoPP::RSASSA_PKCS1v15_SHA_Signer *pSignKey = NULL); + void SetCollectionAuthorKey(const byte *abyCollectionAuthorKey, uint32 nSize); + CString GetCollectionAuthorKeyString(); CString GetAuthorKeyHashString() const; + static bool HasCollectionExtention(const CString &sFileName); CString m_sCollectionName; CString m_sCollectionAuthorName; diff --git a/srchybrid/CollectionCreateDialog.cpp b/srchybrid/CollectionCreateDialog.cpp index ad5c7e88..fac9dca0 100644 --- a/srchybrid/CollectionCreateDialog.cpp +++ b/srchybrid/CollectionCreateDialog.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -152,19 +152,18 @@ BOOL CCollectionCreateDialog::OnInitDialog() AddAnchor(IDC_COLLECTIONCREATESIGNCHECK, BOTTOM_LEFT, BOTTOM_RIGHT); EnableSaveRestore(PREF_INI_SECTION); - CSKey key; - for (POSITION pos = m_pCollection->m_CollectionFilesMap.GetStartPosition(); pos != NULL;) { - CCollectionFile *pCollectionFile; - m_pCollection->m_CollectionFilesMap.GetNextAssoc(pos, key, pCollectionFile); - m_CollectionListCtrl.AddFileToList(pCollectionFile); - } - CString strTitle; - strTitle.Format(GetResString(IDS_COLLECTIONLIST) + _T(" (%u)"), m_CollectionListCtrl.GetItemCount()); + for (CCollectionFilesMap::CPair *pair = m_pCollection->m_CollectionFilesMap.PGetFirstAssoc(); pair != NULL; pair = m_pCollection->m_CollectionFilesMap.PGetNextAssoc(pair)) + m_CollectionListCtrl.AddFileToList(pair->value); + + CString strTitle(GetResString(IDS_COLLECTIONLIST)); + strTitle.AppendFormat(_T(" (%d)"), m_CollectionListCtrl.GetItemCount()); m_CollectionListLabel.SetWindowText(strTitle); OnBnClickedCollectionViewShared(); - m_CollectionNameEdit.SetWindowText(CleanupFilename(m_pCollection->m_sCollectionName)); + CString sFileName(CleanupFilename(m_pCollection->m_sCollectionName)); + m_CollectionNameEdit.SetWindowText(sFileName); + m_CollectionCreateFormatCheck.SetCheck(m_pCollection->m_bTextFormat); OnBnClickedCollectionFormat(); GetDlgItem(IDC_CCOLL_SAVE)->EnableWindow(m_CollectionListCtrl.GetItemCount() > 0); @@ -188,8 +187,8 @@ void CCollectionCreateDialog::AddSelectedFiles() m_CollectionListCtrl.AddFileToList(pCollectionFile); } - CString strTitle; - strTitle.Format(GetResString(IDS_COLLECTIONLIST) + _T(" (%u)"), m_CollectionListCtrl.GetItemCount()); + CString strTitle(GetResString(IDS_COLLECTIONLIST)); + strTitle.AppendFormat(_T(" (%d)"), m_CollectionListCtrl.GetItemCount()); m_CollectionListLabel.SetWindowText(strTitle); GetDlgItem(IDC_CCOLL_SAVE)->EnableWindow(m_CollectionListCtrl.GetItemCount() > 0); @@ -228,8 +227,8 @@ void CCollectionCreateDialog::OnBnClickedCollectionAdd() void CCollectionCreateDialog::OnBnClickedOk() { - //Some users have noted that the collection can at times - //save a collection with an invalid name... + //Some users have noted that a collection + //could be saved with an invalid name... OnEnKillFocusCollectionName(); CString sFileName; @@ -241,13 +240,14 @@ void CCollectionCreateDialog::OnBnClickedOk() m_pCollection->m_bTextFormat = (m_CollectionCreateFormatCheck.GetCheck() == BST_CHECKED); CString sFilePath; - sFilePath.Format(_T("%s\\%s")COLLECTION_FILEEXTENSION, (LPCTSTR)thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR), (LPCTSTR)m_pCollection->m_sCollectionName); + sFilePath.Format(_T("%s%s") COLLECTION_FILEEXTENSION, (LPCTSTR)thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR), (LPCTSTR)m_pCollection->m_sCollectionName); using namespace CryptoPP; RSASSA_PKCS1v15_SHA_Signer *pSignkey = NULL; if (m_CollectionCreateSignNameKeyCheck.GetCheck()) { bool bCreateNewKey = false; - HANDLE hKeyFile = ::CreateFile(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + _T("collectioncryptkey.dat"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + const CString &collkeypath(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + _T("collectioncryptkey.dat")); + HANDLE hKeyFile = ::CreateFile(collkeypath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hKeyFile != INVALID_HANDLE_VALUE) { if (::GetFileSize(hKeyFile, NULL) == 0) bCreateNewKey = true; @@ -255,12 +255,13 @@ void CCollectionCreateDialog::OnBnClickedOk() } else bCreateNewKey = true; + const CStringA collkeypathA(collkeypath); if (bCreateNewKey) try { AutoSeededRandomPool rng; InvertibleRSAFunction privkey; privkey.Initialize(rng, 1024); - Base64Encoder privkeysink(new FileSink((CStringA)(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + _T("collectioncryptkey.dat")))); + Base64Encoder privkeysink(new FileSink(collkeypathA)); privkey.DEREncode(privkeysink); privkeysink.MessageEnd(); } catch (...) { @@ -268,7 +269,7 @@ void CCollectionCreateDialog::OnBnClickedOk() } try { - FileSource filesource((CStringA)(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + _T("collectioncryptkey.dat")), true, new Base64Decoder); + FileSource filesource(collkeypathA, true, new Base64Decoder); pSignkey = new RSASSA_PKCS1v15_SHA_Signer(filesource); RSASSA_PKCS1v15_SHA_Verifier pubkey(*pSignkey); byte abyMyPublicKey[1000]; @@ -284,7 +285,7 @@ void CCollectionCreateDialog::OnBnClickedOk() m_pCollection->m_sCollectionAuthorName = thePrefs.GetUserNick(); } - if (PathFileExists(sFilePath)) { + if (::PathFileExists(sFilePath)) { if (LocMessageBox(IDS_COLL_REPLACEEXISTING, MB_ICONWARNING | MB_DEFBUTTON2 | MB_YESNO, 0) == IDNO) return; @@ -312,18 +313,14 @@ void CCollectionCreateDialog::UpdateAvailFiles() { m_CollectionAvailListCtrl.DeleteAllItems(); - CMap Files_Map; + CKnownFilesMap Files_Map; if (m_bSharedFiles) theApp.sharedfiles->CopySharedFileMap(Files_Map); else theApp.knownfiles->CopyKnownFileMap(Files_Map); - CCKey key; - for (POSITION pos = Files_Map.GetStartPosition(); pos != NULL;) { - CKnownFile *pKnownFile; - Files_Map.GetNextAssoc(pos, key, pKnownFile); - m_CollectionAvailListCtrl.AddFileToList(pKnownFile); - } + for (CKnownFilesMap::CPair *pair = Files_Map.PGetFirstAssoc(); pair != NULL; pair = Files_Map.PGetNextAssoc(pair)) + m_CollectionAvailListCtrl.AddFileToList(pair->value); } void CCollectionCreateDialog::OnBnClickedCollectionViewShared() @@ -353,9 +350,11 @@ void CCollectionCreateDialog::OnEnKillFocusCollectionName() { CString sFileName; m_CollectionNameEdit.GetWindowText(sFileName); - CString sNewFileName(ValidFilename(sFileName)); - if (sNewFileName.Compare(sFileName) != 0) + const CString &sNewFileName(ValidFilename(sFileName)); + if (sNewFileName != sFileName) { m_CollectionNameEdit.SetWindowText(sNewFileName); + m_CollectionNameEdit.SetFocus(); + } } void CCollectionCreateDialog::OnBnClickedCollectionFormat() diff --git a/srchybrid/CollectionCreateDialog.h b/srchybrid/CollectionCreateDialog.h index 413e6fa1..f8d55c21 100644 --- a/srchybrid/CollectionCreateDialog.h +++ b/srchybrid/CollectionCreateDialog.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/CollectionFile.cpp b/srchybrid/CollectionFile.cpp index 62f0fae6..2891beac 100644 --- a/srchybrid/CollectionFile.cpp +++ b/srchybrid/CollectionFile.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -33,9 +33,9 @@ static char THIS_FILE[] = __FILE__; IMPLEMENT_DYNAMIC(CCollectionFile, CAbstractFile) -CCollectionFile::CCollectionFile(CFileDataIO *in_data) +CCollectionFile::CCollectionFile(CFileDataIO &in_data) { - for (uint32 cnt = in_data->ReadUInt32(); cnt > 0; --cnt) + for (uint32 cnt = in_data.ReadUInt32(); cnt > 0; --cnt) try { CTag *toadd = new CTag(in_data, true); m_taglist.Add(toadd); @@ -59,13 +59,13 @@ CCollectionFile::CCollectionFile(CFileDataIO *in_data) // here we have two choices // - if the server/client sent us a file type, we could use it (though it could be wrong) - // - we always trust our file type list and determine the file type by the extension of the file + // - we always trust our file type list and determine the file type by the file's extension // // if we received a file type from server, we use it. // if we did not receive a file type, we determine it by examining the file's extension. // - // but, in no case, we will use the receive file type when adding this search result to the download queue, to avoid - // that we are using 'wrong' file types in part files. (this has to be handled when creating the part files) + // to avoid using 'wrong' file types for part files when adding a search result to the download queue, + // in no case we will use the received file type (this has to be handled when creating the part files) const CString &rstrFileType(GetStrTagValue(FT_FILETYPE)); CCollectionFile::SetFileName(GetStrTagValue(FT_FILENAME), false, rstrFileType.IsEmpty()); CCollectionFile::SetFileSize(GetInt64TagValue(FT_FILESIZE)); @@ -136,10 +136,10 @@ bool CCollectionFile::InitFromLink(const CString &sLink) return true; } -void CCollectionFile::WriteCollectionInfo(CFileDataIO *out_data) +void CCollectionFile::WriteCollectionInfo(CFileDataIO &out_data) { INT_PTR cnt = m_taglist.GetCount(); - out_data->WriteUInt32((uint32)cnt); + out_data.WriteUInt32((uint32)cnt); for (INT_PTR i = 0; i < cnt; ++i) { CTag tempTag(*m_taglist[i]); diff --git a/srchybrid/CollectionFile.h b/srchybrid/CollectionFile.h index fddbd091..af587377 100644 --- a/srchybrid/CollectionFile.h +++ b/srchybrid/CollectionFile.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -26,11 +26,10 @@ class CCollectionFile : public CAbstractFile public: CCollectionFile() = default; - explicit CCollectionFile(CFileDataIO *in_data); + explicit CCollectionFile(CFileDataIO &in_data); explicit CCollectionFile(CAbstractFile *pAbstractFile); - virtual ~CCollectionFile() = default; bool InitFromLink(const CString &sLink); - void WriteCollectionInfo(CFileDataIO *out_data); + void WriteCollectionInfo(CFileDataIO &out_data); virtual void UpdateFileRatingCommentAvail(bool bForceUpdate = false); }; \ No newline at end of file diff --git a/srchybrid/CollectionListCtrl.cpp b/srchybrid/CollectionListCtrl.cpp index ec91e9e0..5469a007 100644 --- a/srchybrid/CollectionListCtrl.cpp +++ b/srchybrid/CollectionListCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( merkur-@users.sourceforge.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -40,7 +40,6 @@ class CCollectionFileDetailsSheet : public CListViewWalkerPropertySheet public: explicit CCollectionFileDetailsSheet(CTypedPtrList &aFiles, UINT uInvokePage = 0, CListCtrlItemWalk *pListCtrl = NULL); - virtual ~CCollectionFileDetailsSheet() = default; virtual BOOL OnInitDialog(); @@ -157,26 +156,22 @@ void CCollectionListCtrl::Init(const CString &strNameAdd) LoadSettings(); SetSortArrow(); - SortItems(SortProc, MAKELONG(GetSortItem(), static_cast(!GetSortAscending()))); + SortItems(SortProc, MAKELONG(GetSortItem(), !GetSortAscending())); } void CCollectionListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) { - NMLISTVIEW *pNMListView = reinterpret_cast(pNMHDR); - + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); // Determine ascending based on whether already sorted on this column - int iSortItem = GetSortItem(); - bool bOldSortAscending = GetSortAscending(); - bool bSortAscending = (iSortItem != pNMListView->iSubItem) || !bOldSortAscending; + bool bSortAscending = (GetSortItem() != pNMLV->iSubItem || !GetSortAscending()); - // Item is column clicked - iSortItem = pNMListView->iSubItem; + // Item is the column clicked + int iSortItem = pNMLV->iSubItem; // Sort table - UpdateSortHistory(MAKELONG(iSortItem, (bSortAscending ? 0 : 0x0001))); + UpdateSortHistory(MAKELONG(iSortItem, !bSortAscending)); SetSortArrow(iSortItem, bSortAscending); - SortItems(SortProc, MAKELONG(iSortItem, (bSortAscending ? 0 : 0x0001))); - + SortItems(SortProc, MAKELONG(iSortItem, !bSortAscending)); *pResult = 0; } @@ -192,15 +187,12 @@ int CALLBACK CCollectionListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARA case colName: iResult = CompareLocaleStringNoCase(item1->GetFileName(), item2->GetFileName()); break; - case colSize: - iResult = CompareUnsigned64(item1->GetFileSize(), item2->GetFileSize()); + iResult = CompareUnsigned(item1->GetFileSize(), item2->GetFileSize()); break; - case colHash: iResult = memcmp(item1->GetFileHash(), item2->GetFileHash(), 16); break; - default: return 0; } @@ -235,7 +227,7 @@ void CCollectionListCtrl::AddFileToList(CAbstractFile *pAbstractFile) } int iImage = theApp.GetFileTypeSystemImageIdx(pAbstractFile->GetFileName()); - iItem = InsertItem(LVIF_TEXT | LVIF_PARAM | (iImage > 0 ? LVIF_IMAGE : 0), GetItemCount(), NULL, 0, 0, iImage, (LPARAM)pAbstractFile); + iItem = InsertItem(LVIF_TEXT | LVIF_PARAM | (iImage > 0 ? LVIF_IMAGE : 0), GetItemCount(), _T(""), 0, 0, iImage, (LPARAM)pAbstractFile); if (iItem >= 0) { SetItemText(iItem, colName, pAbstractFile->GetFileName()); SetItemText(iItem, colSize, CastItoXBytes(pAbstractFile->GetFileSize())); diff --git a/srchybrid/CollectionListCtrl.h b/srchybrid/CollectionListCtrl.h index e9ee0c15..3a02902c 100644 --- a/srchybrid/CollectionListCtrl.h +++ b/srchybrid/CollectionListCtrl.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( merkur-@users.sourceforge.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -27,10 +27,8 @@ class CCollectionListCtrl : public CMuleListCtrl, public CListCtrlItemWalk public: CCollectionListCtrl(); - virtual ~CCollectionListCtrl() = default; void Init(const CString &strNameAdd); -// void Localize(); void AddFileToList(CAbstractFile *pAbstractFile); void RemoveFileFromList(CAbstractFile *pAbstractFile); diff --git a/srchybrid/CollectionViewDialog.cpp b/srchybrid/CollectionViewDialog.cpp index 1fa2d9f7..2fc08893 100644 --- a/srchybrid/CollectionViewDialog.cpp +++ b/srchybrid/CollectionViewDialog.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -20,6 +20,7 @@ #include "CollectionViewDialog.h" #include "Collection.h" #include "CollectionFile.h" +#include "OtherFunctions.h" #include "DownloadQueue.h" #include "TransferDlg.h" #include "CatDialog.h" @@ -61,7 +62,7 @@ void CCollectionViewDialog::DoDataExchange(CDataExchange *pDX) { CDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_COLLECTIONVEWLIST, m_CollectionViewList); - DDX_Control(pDX, IDC_COLLECTIONVIEWCATEGORYCHECK, m_AddNewCatagory); + DDX_Control(pDX, IDC_COLLECTIONVIEWCATEGORYCHECK, m_AddNewCategory); DDX_Control(pDX, IDC_COLLECTIONVIEWLISTLABEL, m_CollectionViewListLabel); DDX_Control(pDX, IDC_COLLECTIONVIEWLISTICON, m_CollectionViewListIcon); DDX_Control(pDX, IDC_VIEWCOLLECTIONDL, m_CollectionDownload); @@ -92,10 +93,10 @@ BOOL CCollectionViewDialog::OnInitDialog() m_CollectionViewList.Init(_T("CollectionView")); SetIcon(m_icoWnd = theApp.LoadIcon(_T("Collection_View")), FALSE); - m_AddNewCatagory.SetCheck(0); + m_AddNewCategory.SetCheck(0); - CString str(GetResString(IDS_VIEWCOLLECTION)); - str.AppendFormat(_T(": %s"), (LPCTSTR)m_pCollection->m_sCollectionName); + CString str; + str.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_VIEWCOLLECTION), (LPCTSTR)m_pCollection->m_sCollectionName); SetWindowText(str); m_icoColl = theApp.LoadIcon(_T("AABCollectionFileType")); @@ -123,25 +124,22 @@ BOOL CCollectionViewDialog::OnInitDialog() AddAnchor(IDC_VIEWCOLLECTIONDL, BOTTOM_RIGHT); EnableSaveRestore(PREF_INI_SECTION); - CSKey key; - for (POSITION pos = m_pCollection->m_CollectionFilesMap.GetStartPosition(); pos != NULL;) { - CCollectionFile *pCollectionFile; - m_pCollection->m_CollectionFilesMap.GetNextAssoc(pos, key, pCollectionFile); - - int iImage = theApp.GetFileTypeSystemImageIdx(pCollectionFile->GetFileName()); - int iItem = m_CollectionViewList.InsertItem(LVIF_TEXT | LVIF_PARAM | (iImage > 0 ? LVIF_IMAGE : 0), m_CollectionViewList.GetItemCount(), NULL, 0, 0, iImage, (LPARAM)pCollectionFile); + for (CCollectionFilesMap::CPair *pair = m_pCollection->m_CollectionFilesMap.PGetFirstAssoc(); pair != NULL; pair = m_pCollection->m_CollectionFilesMap.PGetNextAssoc(pair)) { + const CCollectionFile *pFile = pair->value; + int iImage = theApp.GetFileTypeSystemImageIdx(pFile->GetFileName()); + int iItem = m_CollectionViewList.InsertItem(LVIF_TEXT | LVIF_PARAM | (iImage > 0 ? LVIF_IMAGE : 0), m_CollectionViewList.GetItemCount(), _T(""), 0, 0, iImage, (LPARAM)pFile); if (iItem >= 0) { - m_CollectionViewList.SetItemText(iItem, colName, pCollectionFile->GetFileName()); - m_CollectionViewList.SetItemText(iItem, colSize, (LPCTSTR)CastItoXBytes(pCollectionFile->GetFileSize())); - m_CollectionViewList.SetItemText(iItem, colHash, md4str(pCollectionFile->GetFileHash())); + m_CollectionViewList.SetItemText(iItem, colName, pFile->GetFileName()); + m_CollectionViewList.SetItemText(iItem, colSize, (LPCTSTR)CastItoXBytes(pFile->GetFileSize())); + m_CollectionViewList.SetItemText(iItem, colHash, md4str(pFile->GetFileHash())); } } for (int iItem = m_CollectionViewList.GetItemCount(); --iItem >= 0;) m_CollectionViewList.SetItemState(iItem, LVIS_SELECTED, LVIS_SELECTED); - CString strTitle(GetResString(IDS_COLLECTIONLIST)); - strTitle.AppendFormat(_T(" (%d)"), m_CollectionViewList.GetItemCount()); + CString strTitle; + strTitle.Format(_T("%s (%d)"), (LPCTSTR)GetResString(IDS_COLLECTIONLIST), m_CollectionViewList.GetItemCount()); m_CollectionViewListLabel.SetWindowText(strTitle); return TRUE; @@ -156,13 +154,13 @@ void CCollectionViewDialog::OnNmDblClkCollectionList(LPNMHDR, LRESULT *pResult) void CCollectionViewDialog::DownloadSelected() { int iNewIndex = 0; - for (int iIndex = (int)thePrefs.GetCatCount(); --iIndex > 0;) + for (INT_PTR iIndex = thePrefs.GetCatCount(); --iIndex > 0;) if (!m_pCollection->m_sCollectionName.CompareNoCase(thePrefs.GetCategory(iIndex)->strTitle)) { - iNewIndex = iIndex; + iNewIndex = (int)iIndex; break; } - if (m_AddNewCatagory.GetCheck() && !iNewIndex) { + if (m_AddNewCategory.GetCheck() && !iNewIndex) { iNewIndex = theApp.emuledlg->transferwnd->AddCategory(m_pCollection->m_sCollectionName, thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR), _T(""), _T(""), true); theApp.emuledlg->searchwnd->UpdateCatTabs(); } @@ -175,9 +173,9 @@ void CCollectionViewDialog::DownloadSelected() } while (!collectionFileList.IsEmpty()) { - CCollectionFile *pCollectionFile = collectionFileList.RemoveHead(); - if (pCollectionFile) - theApp.downloadqueue->AddSearchToDownload(pCollectionFile->GetED2kLink(), thePrefs.AddNewFilesPaused(), iNewIndex); + const CCollectionFile *pFile = collectionFileList.RemoveHead(); + if (pFile) + theApp.downloadqueue->AddSearchToDownload(pFile->GetED2kLink(), thePrefs.AddNewFilesPaused(), iNewIndex); } } diff --git a/srchybrid/CollectionViewDialog.h b/srchybrid/CollectionViewDialog.h index aaf24104..478d6c6a 100644 --- a/srchybrid/CollectionViewDialog.h +++ b/srchybrid/CollectionViewDialog.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -44,7 +44,7 @@ class CCollectionViewDialog : public CResizableDialog }; protected: - CButton m_AddNewCatagory; + CButton m_AddNewCategory; CStatic m_CollectionViewListLabel; CStatic m_CollectionViewListIcon; CButton m_CollectionDownload; diff --git a/srchybrid/ColorButton.cpp b/srchybrid/ColorButton.cpp index 5c64e253..e40d6662 100644 --- a/srchybrid/ColorButton.cpp +++ b/srchybrid/ColorButton.cpp @@ -301,12 +301,9 @@ void CColorButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) //** Draw Focus //****************************************************** if (state & ODS_FOCUS) { - RECT rFocus = {rDraw.left, - rDraw.top, - rDraw.right - 1, - rDraw.bottom}; - - pDC->DrawFocusRect(&rFocus); + --rDraw.right; + pDC->DrawFocusRect(&rDraw); + ++rDraw.right; } int const cxedge = ::GetSystemMetrics(SM_CXEDGE); @@ -378,7 +375,6 @@ void CColorButton::DrawArrow(CDC *pDC, ptsArrow[2].x = (pRect->left + pRect->right) / 2; ptsArrow[2].y = pRect->bottom; break; - case 1: // Up ptsArrow[0].x = pRect->left; ptsArrow[0].y = pRect->bottom; @@ -387,7 +383,6 @@ void CColorButton::DrawArrow(CDC *pDC, ptsArrow[2].x = (pRect->left + pRect->right) / 2; ptsArrow[2].y = pRect->top; break; - case 2: // Left ptsArrow[0].x = pRect->right; ptsArrow[0].y = pRect->top; @@ -396,7 +391,6 @@ void CColorButton::DrawArrow(CDC *pDC, ptsArrow[2].x = pRect->left; ptsArrow[2].y = (pRect->top + pRect->bottom) / 2; break; - case 3: // Right ptsArrow[0].x = pRect->left; ptsArrow[0].y = pRect->top; @@ -405,7 +399,6 @@ void CColorButton::DrawArrow(CDC *pDC, ptsArrow[2].x = pRect->right; ptsArrow[2].y = (pRect->top + pRect->bottom) / 2; break; - default: return; } diff --git a/srchybrid/ColorButton.h b/srchybrid/ColorButton.h index 9afec31c..eb1d1a81 100644 --- a/srchybrid/ColorButton.h +++ b/srchybrid/ColorButton.h @@ -159,15 +159,15 @@ class CColorButton : public CButton static void DrawArrow(CDC *pDC, LPRECT pRect, int iDirection = 0, - COLORREF clrArrow = RGB(0,0,0)); + COLORREF clrArrow = RGB(0, 0, 0)); DECLARE_MESSAGE_MAP() COLORREF m_Color; COLORREF m_DefaultColor; - CString m_strDefaultText; - CString m_strCustomText; + CString m_strDefaultText; + CString m_strCustomText; BOOL m_bPopupActive; BOOL m_bTrackSelection; diff --git a/srchybrid/ColourPopup.cpp b/srchybrid/ColourPopup.cpp index b7503fda..e0a0eff5 100644 --- a/srchybrid/ColourPopup.cpp +++ b/srchybrid/ColourPopup.cpp @@ -117,7 +117,7 @@ CColourPopup::CColourPopup(CPoint p, COLORREF crColour, CWnd *pParentWnd } else colourArrayPassed = NULL; //if an array is passed without a size parameter, ignore it and use the defaults - Initialise(); //If not a custom palette intialise as NORMAL! + Initialise(); //If not a custom palette initialise as NORMAL! m_crColour = m_crInitialColour = crColour; m_pParent = pParentWnd; @@ -203,13 +203,13 @@ BOOL CColourPopup::Create(CPoint p, COLORREF crColour, CWnd *pParentWnd m_crColour = m_crInitialColour = crColour; // Get the class name and create the window - static const CString &szClassName = AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS|CS_HREDRAW|CS_VREDRAW + static const CString &szClassName(AfxRegisterWndClass(CS_CLASSDC|CS_SAVEBITS|CS_HREDRAW|CS_VREDRAW , AfxGetApp()->LoadStandardCursor(IDC_ARROW) - , (HBRUSH) (COLOR_BTNFACE+1) - , 0); + , (HBRUSH)COLOR_BTNSHADOW + , 0)); if (!CWnd::CreateEx(0, szClassName, _T(""), WS_VISIBLE|WS_POPUP - , p.x, p.y, 100, 100 // size updated soon + , p.x, p.y, 100, 100 // size to be updated soon , pParentWnd->GetSafeHwnd(), 0, NULL)) { return FALSE; @@ -468,7 +468,7 @@ int CColourPopup::GetIndex(int row, int col) const return DEFAULT_BOX_VALUE; if (row < 0 || col < 0 || row >= m_nNumRows || col >= m_nNumColumns) return INVALID_COLOUR; - if (row*m_nNumColumns + col >= m_nNumColours) + if (row * m_nNumColumns + col >= m_nNumColours) return INVALID_COLOUR; return row * m_nNumColumns + col; } @@ -681,7 +681,7 @@ void CColourPopup::ChangeSelection(int nIndex) void CColourPopup::EndSelection(int nMessage) { - ReleaseCapture(); + ::ReleaseCapture(); // If custom text selected, perform a custom colour selection if (nMessage != UM_CPN_SELENDCANCEL && m_nCurrentSel == CUSTOM_BOX_VALUE) { @@ -756,7 +756,7 @@ void CColourPopup::DrawCell(CDC *pDC, int nIndex) // fill background bool b = (m_nChosenColourSel == nIndex && m_nCurrentSel != nIndex); pDC->FillSolidRect(TextButtonRect, ::GetSysColor(b ? COLOR_3DLIGHT : COLOR_3DFACE)); - + // Draw thin line around text CRect LineRect = TextButtonRect; LineRect.DeflateRect(2 * m_nMargin, 2 * m_nMargin); @@ -841,7 +841,7 @@ void CColourPopup::OnKillFocus(CWnd *pNewWnd) { CWnd::OnKillFocus(pNewWnd); - ReleaseCapture(); + ::ReleaseCapture(); //DestroyWindow(); - causes crash when Custom colour dialog appears. } diff --git a/srchybrid/ComboBoxEx2.cpp b/srchybrid/ComboBoxEx2.cpp index 7494e275..28a50624 100644 --- a/srchybrid/ComboBoxEx2.cpp +++ b/srchybrid/ComboBoxEx2.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/ComboBoxEx2.h b/srchybrid/ComboBoxEx2.h index cf65746a..407e9b32 100644 --- a/srchybrid/ComboBoxEx2.h +++ b/srchybrid/ComboBoxEx2.h @@ -5,7 +5,6 @@ class CComboBoxEx2 : public CComboBoxEx DECLARE_DYNAMIC(CComboBoxEx2) public: CComboBoxEx2() = default; - virtual ~CComboBoxEx2() = default; int AddItem(LPCTSTR pszText, int iImage); BOOL SelectItemDataString(LPCTSTR pszText); diff --git a/srchybrid/CommentDialog.cpp b/srchybrid/CommentDialog.cpp index ed5a0d36..66953e75 100644 --- a/srchybrid/CommentDialog.cpp +++ b/srchybrid/CommentDialog.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -219,7 +219,7 @@ void CCommentDialog::Localize() m_ratebox.AddItem(GetResString(IDS_CMT_FAIR), 3); m_ratebox.AddItem(GetResString(IDS_CMT_GOOD), 4); m_ratebox.AddItem(GetResString(IDS_CMT_EXCELLENT), 5); - UpdateHorzExtent(m_ratebox, 16); // adjust dropdown width to ensure all strings are fully visible + UpdateHorzExtent(m_ratebox, 16); // adjust drop-down width to ensure all strings are fully visible m_ratebox.SetCurSel(m_iRating); RefreshData(); } diff --git a/srchybrid/CommentDialog.h b/srchybrid/CommentDialog.h index da625cec..399928cc 100644 --- a/srchybrid/CommentDialog.h +++ b/srchybrid/CommentDialog.h @@ -20,7 +20,6 @@ class CCommentDialog : public CResizablePage int m_iRating; public: CCommentDialog(); // standard constructor - virtual ~CCommentDialog() = default; virtual BOOL OnInitDialog(); void SetFiles(const CSimpleArray *paFiles) { m_paFiles = paFiles; m_bDataChanged = true; } diff --git a/srchybrid/CommentDialogLst.cpp b/srchybrid/CommentDialogLst.cpp index 2b2f929d..1416d977 100644 --- a/srchybrid/CommentDialogLst.cpp +++ b/srchybrid/CommentDialogLst.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -17,8 +17,8 @@ #include "stdafx.h" #include "emule.h" #include "CommentDialogLst.h" -#include "PartFile.h" #include "UpDownClient.h" +#include "PartFile.h" #include "UserMsgs.h" #include "kademlia/kademlia/kademlia.h" #include "kademlia/kademlia/SearchManager.h" @@ -133,13 +133,12 @@ void CCommentDialogLst::RefreshData(bool deleteOld) bool kadsearchable = true; for (int i = 0; i < m_paFiles->GetSize(); ++i) { CAbstractFile *file = static_cast((*m_paFiles)[i]); - if (file->IsPartFile()) { + if (file->IsPartFile()) for (POSITION pos = static_cast(file)->srclist.GetHeadPosition(); pos != NULL;) { const CUpDownClient *cur_src = static_cast(file)->srclist.GetNext(pos); if (cur_src->HasFileRating() || !cur_src->GetFileComment().IsEmpty()) m_lstComments.AddItem(cur_src); } - } const CTypedPtrList &list = file->getNotes(); for (POSITION pos = list.GetHeadPosition(); pos != NULL;) @@ -195,11 +194,11 @@ void CCommentDialogLst::OnBnClickedFilter() strCommentFilters.MakeLower(); CString strNewCommentFilters; for (int iPos = 0; iPos >= 0;) { - CString strFilter = strCommentFilters.Tokenize(_T("|"), iPos); + CString strFilter(strCommentFilters.Tokenize(_T("|"), iPos)); if (!strFilter.Trim().IsEmpty()) { if (!strNewCommentFilters.IsEmpty()) strNewCommentFilters += _T('|'); - strNewCommentFilters += strFilter.Trim(); + strNewCommentFilters += strFilter; } } diff --git a/srchybrid/CommentDialogLst.h b/srchybrid/CommentDialogLst.h index 5a50d6c9..a945d04c 100644 --- a/srchybrid/CommentDialogLst.h +++ b/srchybrid/CommentDialogLst.h @@ -19,7 +19,6 @@ class CCommentDialogLst : public CResizablePage public: CCommentDialogLst(); - virtual ~CCommentDialogLst() = default; virtual BOOL OnInitDialog(); void SetFiles(const CSimpleArray *paFiles) { m_paFiles = paFiles; m_bDataChanged = true; } diff --git a/srchybrid/CommentListCtrl.cpp b/srchybrid/CommentListCtrl.cpp index f975437c..16163308 100644 --- a/srchybrid/CommentListCtrl.cpp +++ b/srchybrid/CommentListCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( merkur-@users.sourceforge.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -42,11 +42,11 @@ void CCommentListCtrl::Init() ASSERT((GetStyle() & LVS_SINGLESEL) == 0); SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP); - InsertColumn(colRating, GetResString(IDS_QL_RATING), LVCFMT_LEFT, 80); - InsertColumn(colComment, GetResString(IDS_COMMENT), LVCFMT_LEFT, 340); - InsertColumn(colFileName, GetResString(IDS_DL_FILENAME), LVCFMT_LEFT, DFLT_FILENAME_COL_WIDTH); - InsertColumn(colUserName, GetResString(IDS_QL_USERNAME), LVCFMT_LEFT, DFLT_CLIENTNAME_COL_WIDTH); - InsertColumn(colOrigin, GetResString(IDS_NETWORK), LVCFMT_LEFT, 80); + InsertColumn(colRating, _T(""), LVCFMT_LEFT, 80); //IDS_QL_RATING + InsertColumn(colComment, _T(""), LVCFMT_LEFT, 340); //IDS_COMMENT + InsertColumn(colFileName, _T(""), LVCFMT_LEFT, DFLT_FILENAME_COL_WIDTH); //IDS_DL_FILENAME + InsertColumn(colUserName, _T(""), LVCFMT_LEFT, DFLT_CLIENTNAME_COL_WIDTH); //IDS_QL_USERNAME + InsertColumn(colOrigin, _T(""), LVCFMT_LEFT, 80); //IDS_NETWORK CImageList iml; iml.Create(16, 16, theApp.m_iDfltImageListColorFlags | ILC_MASK, 0, 1); @@ -63,7 +63,7 @@ void CCommentListCtrl::Init() LoadSettings(); SetSortArrow(); - SortItems(SortProc, MAKELONG(GetSortItem(), static_cast(!GetSortAscending()))); + SortItems(SortProc, MAKELONG(GetSortItem(), !GetSortAscending())); } int CALLBACK CCommentListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) @@ -104,21 +104,17 @@ int CALLBACK CCommentListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM l void CCommentListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) { - LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); - + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); // Determine ascending based on whether already sorted on this column - int iSortItem = GetSortItem(); - bool bOldSortAscending = GetSortAscending(); - bool bSortAscending = (iSortItem != pNMLV->iSubItem) ? true : !bOldSortAscending; + bool bSortAscending = (GetSortItem() != pNMLV->iSubItem || !GetSortAscending()); // Item is column clicked - iSortItem = pNMLV->iSubItem; + int iSortItem = pNMLV->iSubItem; // Sort table - UpdateSortHistory(MAKELONG(iSortItem, (bSortAscending ? 0 : 0x0001))); + UpdateSortHistory(MAKELONG(iSortItem, !bSortAscending)); SetSortArrow(iSortItem, bSortAscending); - SortItems(SortProc, MAKELONG(iSortItem, (bSortAscending ? 0 : 0x0001))); - + SortItems(SortProc, MAKELONG(iSortItem, !bSortAscending)); *pResult = 0; } @@ -159,8 +155,7 @@ BOOL CCommentListCtrl::OnCommand(WPARAM wParam, LPARAM lParam) int CCommentListCtrl::FindClientComment(const void *pClientCookie) { - int iItems = GetItemCount(); - for (int i = 0; i < iItems; ++i) { + for (int i = GetItemCount(); --i >= 0;) { const SComment *pComment = reinterpret_cast(GetItemData(i)); if (pComment && pComment->m_pClientCookie == pClientCookie) return i; @@ -203,7 +198,7 @@ void CCommentListCtrl::AddItem(const Kademlia::CEntry *entry) void CCommentListCtrl::OnLvnDeleteItem(LPNMHDR pNMHDR, LRESULT *pResult) { - LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); delete reinterpret_cast(pNMLV->lParam); *pResult = 0; } \ No newline at end of file diff --git a/srchybrid/CommentListCtrl.h b/srchybrid/CommentListCtrl.h index 65fa3069..9497663c 100644 --- a/srchybrid/CommentListCtrl.h +++ b/srchybrid/CommentListCtrl.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -29,7 +29,6 @@ class CCommentListCtrl : public CMuleListCtrl public: CCommentListCtrl() = default; - virtual ~CCommentListCtrl() = default; void Init(); void AddItem(const CUpDownClient *client); diff --git a/srchybrid/CorruptionBlackBox.cpp b/srchybrid/CorruptionBlackBox.cpp index affed6b7..31e3da11 100644 --- a/srchybrid/CorruptionBlackBox.cpp +++ b/srchybrid/CorruptionBlackBox.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -34,38 +34,26 @@ static char THIS_FILE[] = __FILE__; CCBBRecord::CCBBRecord(uint64 nStartPos, uint64 nEndPos, uint32 dwIP, EBBRStatus BBRStatus) { - if (nStartPos > nEndPos) { + if (nStartPos <= nEndPos) { + m_nStartPos = nStartPos; + m_nEndPos = nEndPos; + m_dwIP = dwIP; + m_BBRStatus = BBRStatus; + } else ASSERT(0); - return; - } - m_nStartPos = nStartPos; - m_nEndPos = nEndPos; - m_dwIP = dwIP; - m_BBRStatus = BBRStatus; -} - -CCBBRecord& CCBBRecord::operator=(const CCBBRecord &cv) -{ - m_nStartPos = cv.m_nStartPos; - m_nEndPos = cv.m_nEndPos; - m_dwIP = cv.m_dwIP; - m_BBRStatus = cv.m_BBRStatus; - return *this; } bool CCBBRecord::Merge(uint64 nStartPos, uint64 nEndPos, uint32 dwIP, EBBRStatus BBRStatus) { - if (m_dwIP == dwIP && m_BBRStatus == BBRStatus && (nStartPos == m_nEndPos + 1 || nEndPos + 1 == m_nStartPos)) { - if (nStartPos == m_nEndPos + 1) - m_nEndPos = nEndPos; - else if (nEndPos + 1 == m_nStartPos) - m_nStartPos = nStartPos; - else - ASSERT(0); - - return true; - } - return false; + if (m_dwIP != dwIP || m_BBRStatus != BBRStatus) + return false; + if (nStartPos == m_nEndPos + 1) + m_nEndPos = nEndPos; + else if (nEndPos + 1 == m_nStartPos) + m_nStartPos = nStartPos; + else + return false; + return true; } bool CCBBRecord::CanMerge(uint64 nStartPos, uint64 nEndPos, uint32 dwIP, EBBRStatus BBRStatus) const @@ -75,87 +63,84 @@ bool CCBBRecord::CanMerge(uint64 nStartPos, uint64 nEndPos, uint32 dwIP, EBBRSta void CCorruptionBlackBox::Init(EMFileSize nFileSize) { - m_aaRecords.SetSize((INT_PTR)(((uint64)nFileSize + (PARTSIZE - 1)) / PARTSIZE)); + m_aaRecords.SetSize((INT_PTR)(((uint64)nFileSize + PARTSIZE - 1) / PARTSIZE)); } void CCorruptionBlackBox::Free() { - m_aaRecords.RemoveAll(); - m_aaRecords.FreeExtra(); + m_aaRecords.SetSize(0); } void CCorruptionBlackBox::TransferredData(uint64 nStartPos, uint64 nEndPos, const CUpDownClient *pSender) { - if (nEndPos - nStartPos >= PARTSIZE) { - ASSERT(0); - return; - } - if (nStartPos > nEndPos) { + if (nEndPos - nStartPos >= PARTSIZE || nStartPos > nEndPos) { ASSERT(0); return; } + if (!pSender) //importing parts return; uint32 dwSenderIP = pSender->GetIP(); // we store records separated for each part, so we don't have to search all entries every time // convert pos to relative block pos - UINT nPart = (UINT)(nStartPos / PARTSIZE); - uint64 nRelStartPos = nStartPos - nPart * PARTSIZE; - uint64 nRelEndPos = nEndPos - nPart * PARTSIZE; + INT_PTR nPart = (INT_PTR)(nStartPos / PARTSIZE); + const uint64 nStart = nPart * PARTSIZE; + uint64 nRelStartPos = nStartPos - nStart; + uint64 nRelEndPos = nEndPos - nStart; if (nRelEndPos >= PARTSIZE) { // data crosses the part boundary, split it nRelEndPos = PARTSIZE - 1; - uint64 nTmpStartPos = nPart * PARTSIZE + nRelEndPos + 1; - ASSERT(nTmpStartPos % PARTSIZE == 0); // remove later - TransferredData(nTmpStartPos, nEndPos, pSender); - } - if ((INT_PTR)nPart >= m_aaRecords.GetCount()) { - //ASSERT( false ); - m_aaRecords.SetSize(nPart + 1); + TransferredData(nStart + PARTSIZE, nEndPos, pSender); } + INT_PTR posMerge = -1; uint64 ndbgRewritten = 0; for (INT_PTR i = 0; i < m_aaRecords[nPart].GetCount(); ++i) { - CCBBRecord &cbb = m_aaRecords[nPart][i]; - if (cbb.CanMerge(nRelStartPos, nRelEndPos, dwSenderIP, BBR_NONE)) + CCBBRecord &cbbRec(m_aaRecords[nPart][i]); + if (cbbRec.CanMerge(nRelStartPos, nRelEndPos, dwSenderIP, BBR_NONE)) posMerge = i; // check if there is already a pending entry and overwrite it - else if (cbb.m_BBRStatus == BBR_NONE) { - if (cbb.m_nStartPos >= nRelStartPos && cbb.m_nEndPos <= nRelEndPos) { - // old one is included in new one -> delete - ndbgRewritten += (cbb.m_nEndPos - cbb.m_nStartPos) + 1; + else if (cbbRec.m_BBRStatus == BBR_NONE) { + if (cbbRec.m_nStartPos >= nRelStartPos && cbbRec.m_nEndPos <= nRelEndPos) { + // old one is included into the new one -> delete + ndbgRewritten += (cbbRec.m_nEndPos - cbbRec.m_nStartPos) + 1; m_aaRecords[nPart].RemoveAt(i); --i; - } else if (cbb.m_nStartPos < nRelStartPos && cbb.m_nEndPos > nRelEndPos) { - // old one includes new one - // check if the old one and new one have the same ip - if (dwSenderIP != cbb.m_dwIP) { - // different IP, means we have to split it 2 times - uint64 nTmpStartPos1 = nRelEndPos + 1; - uint64 nTmpEndPos1 = cbb.m_nEndPos; - uint64 nTmpStartPos2 = cbb.m_nStartPos; - uint64 nTmpEndPos2 = nRelStartPos - 1; - cbb.m_nStartPos = nRelStartPos; - cbb.m_nEndPos = nRelEndPos; - uint32 dwOldIP = cbb.m_dwIP; - cbb.m_dwIP = dwSenderIP; - m_aaRecords[nPart].Add(CCBBRecord(nTmpStartPos1, nTmpEndPos1, dwOldIP)); - m_aaRecords[nPart].Add(CCBBRecord(nTmpStartPos2, nTmpEndPos2, dwOldIP)); - // and are done then + } else if (cbbRec.m_nStartPos < nRelStartPos && cbbRec.m_nEndPos > nRelEndPos) { + // old one includes the new one + // check if both old and new have the same ip + if (dwSenderIP != cbbRec.m_dwIP) { + // different IP; we have to split this into 3 blocks + // TODO + // verify that this split will not decrease the amount of the verified data for the old IP, + // or incorrect total good bytes count for the old IP would be seen in EvaluateData() + uint64 nOldStartPos = cbbRec.m_nStartPos; + uint64 nOldEndPos = cbbRec.m_nEndPos; + uint32 dwOldIP = cbbRec.m_dwIP; + //adjust the original block + cbbRec.m_nStartPos = nRelStartPos; + cbbRec.m_nEndPos = nRelEndPos; + cbbRec.m_dwIP = dwSenderIP; + + m_aaRecords[nPart].Add(CCBBRecord(nOldStartPos, nRelStartPos - 1, dwOldIP)); + //prepare to add one more block + nRelStartPos = cbbRec.m_nEndPos + 1; + nRelEndPos = nOldEndPos; + dwSenderIP = dwOldIP; + ndbgRewritten += nRelEndPos - nRelStartPos + 1; + break; // done here } - DEBUG_ONLY(AddDebugLogLine(DLP_DEFAULT, false, _T("CorruptionBlackBox: Debug: %i bytes were rewritten and records replaced with new stats (1)"), (nRelEndPos - nRelStartPos) + 1)); - return; - } else if (cbb.m_nStartPos >= nRelStartPos && cbb.m_nStartPos <= nRelEndPos) { - // old one overlaps new one on the right side - ASSERT(nRelEndPos > cbb.m_nStartPos); - ndbgRewritten += nRelEndPos - cbb.m_nStartPos; - cbb.m_nStartPos = nRelEndPos + 1; - } else if (cbb.m_nEndPos >= nRelStartPos && cbb.m_nEndPos <= nRelEndPos) { - // old one overlaps new one on the left side - ASSERT(cbb.m_nEndPos > nRelStartPos); - ndbgRewritten += cbb.m_nEndPos - nRelStartPos; - cbb.m_nEndPos = nRelStartPos - 1; + } else if (cbbRec.m_nStartPos >= nRelStartPos && cbbRec.m_nStartPos <= nRelEndPos) { + // old one overlaps the new one on the right side + ASSERT(nRelEndPos > cbbRec.m_nStartPos); + ndbgRewritten += nRelEndPos - cbbRec.m_nStartPos; + cbbRec.m_nStartPos = nRelEndPos + 1; + } else if (cbbRec.m_nEndPos >= nRelStartPos && cbbRec.m_nEndPos <= nRelEndPos) { + // old one overlaps the new one on the left side + ASSERT(cbbRec.m_nEndPos > nRelStartPos); + ndbgRewritten += cbbRec.m_nEndPos - nRelStartPos; + cbbRec.m_nEndPos = nRelStartPos - 1; } } } @@ -165,65 +150,57 @@ void CCorruptionBlackBox::TransferredData(uint64 nStartPos, uint64 nEndPos, cons m_aaRecords[nPart].Add(CCBBRecord(nRelStartPos, nRelEndPos, dwSenderIP, BBR_NONE)); if (ndbgRewritten > 0) - DEBUG_ONLY(AddDebugLogLine(DLP_DEFAULT, false, _T("CorruptionBlackBox: Debug: %i bytes were rewritten and records replaced with new stats (2)"), ndbgRewritten)); + DEBUG_ONLY(AddDebugLogLine(DLP_DEFAULT, false, _T("CorruptionBlackBox: Debug: %i bytes were rewritten and records replaced with new stats"), ndbgRewritten)); } void CCorruptionBlackBox::VerifiedData(uint64 nStartPos, uint64 nEndPos) { - if (nEndPos - nStartPos >= PARTSIZE) { + if (nEndPos >= nStartPos + PARTSIZE) { ASSERT(0); return; } // convert pos to relative block pos - UINT nPart = (UINT)(nStartPos / PARTSIZE); + INT_PTR nPart = (INT_PTR)(nStartPos / PARTSIZE); uint64 nRelStartPos = nStartPos - nPart * PARTSIZE; uint64 nRelEndPos = nEndPos - nPart * PARTSIZE; if (nRelEndPos >= PARTSIZE) { ASSERT(0); return; } - if ((INT_PTR)nPart >= m_aaRecords.GetCount()) { - //ASSERT( false ); - m_aaRecords.SetSize(nPart + 1); - } #ifdef _DEBUG uint64 nDbgVerifiedBytes = 0; //uint32 nDbgOldEntries = m_aaRecords[nPart].GetCount(); CMap mapDebug; #endif for (INT_PTR i = 0; i < m_aaRecords[nPart].GetCount(); ++i) { - CCBBRecord &cbb = m_aaRecords[nPart][i]; - if (cbb.m_BBRStatus == BBR_NONE || cbb.m_BBRStatus == BBR_VERIFIED) { - if (cbb.m_nStartPos >= nRelStartPos && cbb.m_nEndPos <= nRelEndPos) - ; - else if (cbb.m_nStartPos < nRelStartPos && cbb.m_nEndPos > nRelEndPos) { - // need to split it 2* - uint64 nTmpStartPos1 = nRelEndPos + 1; - uint64 nTmpEndPos1 = cbb.m_nEndPos; - uint64 nTmpStartPos2 = cbb.m_nStartPos; - uint64 nTmpEndPos2 = nRelStartPos - 1; - cbb.m_nStartPos = nRelStartPos; - cbb.m_nEndPos = nRelEndPos; - m_aaRecords[nPart].Add(CCBBRecord(nTmpStartPos1, nTmpEndPos1, cbb.m_dwIP, cbb.m_BBRStatus)); - m_aaRecords[nPart].Add(CCBBRecord(nTmpStartPos2, nTmpEndPos2, cbb.m_dwIP, cbb.m_BBRStatus)); - } else if (cbb.m_nStartPos >= nRelStartPos && cbb.m_nStartPos <= nRelEndPos) { - // need to split it - uint64 nTmpStartPos = nRelEndPos + 1; - uint64 nTmpEndPos = cbb.m_nEndPos; - cbb.m_nEndPos = nRelEndPos; - m_aaRecords[nPart].Add(CCBBRecord(nTmpStartPos, nTmpEndPos, cbb.m_dwIP, cbb.m_BBRStatus)); - } else if (cbb.m_nEndPos >= nRelStartPos && cbb.m_nEndPos <= nRelEndPos) { - // need to split it - uint64 nTmpStartPos = cbb.m_nStartPos; - uint64 nTmpEndPos = nRelStartPos - 1; - cbb.m_nStartPos = nRelStartPos; - m_aaRecords[nPart].Add(CCBBRecord(nTmpStartPos, nTmpEndPos, cbb.m_dwIP, cbb.m_BBRStatus)); + CCBBRecord &cbbRec(m_aaRecords[nPart][i]); + if (cbbRec.m_BBRStatus == BBR_NONE || cbbRec.m_BBRStatus == BBR_VERIFIED) { + if (cbbRec.m_nStartPos >= nRelStartPos && cbbRec.m_nEndPos <= nRelEndPos) + ; //all this block is inside the new verified data; only set status to verified + else if (cbbRec.m_nStartPos < nRelStartPos && cbbRec.m_nEndPos > nRelEndPos) { + // new data fully within this block; split this block into 3 + uint64 nOldStartPos = cbbRec.m_nStartPos; + uint64 nOldEndPos = cbbRec.m_nEndPos; + cbbRec.m_nStartPos = nRelStartPos; + cbbRec.m_nEndPos = nRelEndPos; + m_aaRecords[nPart].Add(CCBBRecord(nRelEndPos + 1, nOldEndPos, cbbRec.m_dwIP, cbbRec.m_BBRStatus)); + m_aaRecords[nPart].Add(CCBBRecord(nOldStartPos, nRelStartPos - 1, cbbRec.m_dwIP, cbbRec.m_BBRStatus)); + } else if (cbbRec.m_nStartPos >= nRelStartPos && cbbRec.m_nStartPos <= nRelEndPos) { + // split off the tail of this block + uint64 nOldEndPos = cbbRec.m_nEndPos; + cbbRec.m_nEndPos = nRelEndPos; + m_aaRecords[nPart].Add(CCBBRecord(nRelEndPos + 1, nOldEndPos, cbbRec.m_dwIP, cbbRec.m_BBRStatus)); + } else if (cbbRec.m_nEndPos >= nRelStartPos && cbbRec.m_nEndPos <= nRelEndPos) { + // split off the head of this block + uint64 nOldStartPos = cbbRec.m_nStartPos; + cbbRec.m_nStartPos = nRelStartPos; + m_aaRecords[nPart].Add(CCBBRecord(nOldStartPos, nRelStartPos - 1, cbbRec.m_dwIP, cbbRec.m_BBRStatus)); } else continue; - cbb.m_BBRStatus = BBR_VERIFIED; + cbbRec.m_BBRStatus = BBR_VERIFIED; #ifdef _DEBUG - nDbgVerifiedBytes += cbb.m_nEndPos - cbb.m_nStartPos + 1; - mapDebug.SetAt(cbb.m_dwIP, 1); + nDbgVerifiedBytes += cbbRec.m_nEndPos - cbbRec.m_nStartPos + 1; + mapDebug[cbbRec.m_dwIP] = 1; #endif } } @@ -242,49 +219,41 @@ void CCorruptionBlackBox::CorruptedData(uint64 nStartPos, uint64 nEndPos) return; } // convert pos to relative block pos - UINT nPart = (UINT)(nStartPos / PARTSIZE); + INT_PTR nPart = (INT_PTR)(nStartPos / PARTSIZE); uint64 nRelStartPos = nStartPos - nPart * PARTSIZE; uint64 nRelEndPos = nEndPos - nPart * PARTSIZE; if (nRelEndPos >= PARTSIZE) { ASSERT(0); return; } - if ((INT_PTR)nPart >= m_aaRecords.GetCount()) { - //ASSERT( false ); - m_aaRecords.SetSize(nPart + 1); - } uint64 nDbgVerifiedBytes = 0; for (INT_PTR i = 0; i < m_aaRecords[nPart].GetCount(); ++i) { - CCBBRecord &cbb = m_aaRecords[nPart][i]; - if (cbb.m_BBRStatus == BBR_NONE) { - if (cbb.m_nStartPos >= nRelStartPos && cbb.m_nEndPos <= nRelEndPos) + CCBBRecord &cbbRec(m_aaRecords[nPart][i]); + if (cbbRec.m_BBRStatus == BBR_NONE) { + if (cbbRec.m_nStartPos >= nRelStartPos && cbbRec.m_nEndPos <= nRelEndPos) ; - else if (cbb.m_nStartPos < nRelStartPos && cbb.m_nEndPos > nRelEndPos) { + else if (cbbRec.m_nStartPos < nRelStartPos && cbbRec.m_nEndPos > nRelEndPos) { // need to split it 2* - uint64 nTmpStartPos1 = nRelEndPos + 1; - uint64 nTmpEndPos1 = cbb.m_nEndPos; - uint64 nTmpStartPos2 = cbb.m_nStartPos; - uint64 nTmpEndPos2 = nRelStartPos - 1; - cbb.m_nStartPos = nRelStartPos; - cbb.m_nEndPos = nRelEndPos; - m_aaRecords[nPart].Add(CCBBRecord(nTmpStartPos1, nTmpEndPos1, cbb.m_dwIP, cbb.m_BBRStatus)); - m_aaRecords[nPart].Add(CCBBRecord(nTmpStartPos2, nTmpEndPos2, cbb.m_dwIP, cbb.m_BBRStatus)); - } else if (cbb.m_nStartPos >= nRelStartPos && cbb.m_nStartPos <= nRelEndPos) { + uint64 nOldStartPos = cbbRec.m_nStartPos; + uint64 nOldEndPos = cbbRec.m_nEndPos; + cbbRec.m_nStartPos = nRelStartPos; + cbbRec.m_nEndPos = nRelEndPos; + m_aaRecords[nPart].Add(CCBBRecord(nRelEndPos + 1, nOldEndPos, cbbRec.m_dwIP, cbbRec.m_BBRStatus)); + m_aaRecords[nPart].Add(CCBBRecord(nOldStartPos, nRelStartPos - 1, cbbRec.m_dwIP, cbbRec.m_BBRStatus)); + } else if (cbbRec.m_nStartPos >= nRelStartPos && cbbRec.m_nStartPos <= nRelEndPos) { // need to split it - uint64 nTmpStartPos = nRelEndPos + 1; - uint64 nTmpEndPos = cbb.m_nEndPos; - cbb.m_nEndPos = nRelEndPos; - m_aaRecords[nPart].Add(CCBBRecord(nTmpStartPos, nTmpEndPos, cbb.m_dwIP, cbb.m_BBRStatus)); - } else if (cbb.m_nEndPos >= nRelStartPos && cbb.m_nEndPos <= nRelEndPos) { + uint64 nOldEndPos = cbbRec.m_nEndPos; + cbbRec.m_nEndPos = nRelEndPos; + m_aaRecords[nPart].Add(CCBBRecord(nRelEndPos + 1, nOldEndPos, cbbRec.m_dwIP, cbbRec.m_BBRStatus)); + } else if (cbbRec.m_nEndPos >= nRelStartPos && cbbRec.m_nEndPos <= nRelEndPos) { // need to split it - uint64 nTmpStartPos = cbb.m_nStartPos; - uint64 nTmpEndPos = nRelStartPos - 1; - cbb.m_nStartPos = nRelStartPos; - m_aaRecords[nPart].Add(CCBBRecord(nTmpStartPos, nTmpEndPos, cbb.m_dwIP, cbb.m_BBRStatus)); + uint64 nOldStartPos = cbbRec.m_nStartPos; + cbbRec.m_nStartPos = nRelStartPos; + m_aaRecords[nPart].Add(CCBBRecord(nOldStartPos, nRelStartPos - 1, cbbRec.m_dwIP, cbbRec.m_BBRStatus)); } else continue; - cbb.m_BBRStatus = BBR_CORRUPTED; - nDbgVerifiedBytes += cbb.m_nEndPos - cbb.m_nStartPos + 1; + cbbRec.m_BBRStatus = BBR_CORRUPTED; + nDbgVerifiedBytes += cbbRec.m_nEndPos - cbbRec.m_nStartPos + 1; } } AddDebugLogLine(DLP_HIGH, false, _T("Found and marked %I64u recorded bytes of %I64u as corrupted in the CorruptionBlackBox records"), nDbgVerifiedBytes, (nEndPos - nStartPos) + 1); @@ -293,13 +262,13 @@ void CCorruptionBlackBox::CorruptedData(uint64 nStartPos, uint64 nEndPos) void CCorruptionBlackBox::EvaluateData(uint16 nPart) { CArray aGuiltyClients; - for (INT_PTR i = 0; i < m_aaRecords[nPart].GetCount(); ++i) + for (INT_PTR i = m_aaRecords[nPart].GetCount(); --i >= 0;) if (m_aaRecords[nPart][i].m_BBRStatus == BBR_CORRUPTED) aGuiltyClients.Add(m_aaRecords[nPart][i].m_dwIP); // check if any IPs are already banned, so we can skip the test for those for (INT_PTR k = 0; k < aGuiltyClients.GetCount();) { - // remove doubles + // remove duplicates for (INT_PTR y = aGuiltyClients.GetCount(); --y > k;) if (aGuiltyClients[k] == aGuiltyClients[y]) aGuiltyClients.RemoveAt(y); @@ -310,33 +279,31 @@ void CCorruptionBlackBox::EvaluateData(uint16 nPart) } else ++k; } - if (aGuiltyClients.IsEmpty()) - return; + const INT_PTR iClients = aGuiltyClients.GetCount(); + if (iClients <= 0) + return; // parse all recorded data for this file to produce statistics for the involved clients // first init arrays for the statistics CArray aDataCorrupt, aDataVerified; - aDataCorrupt.SetSize(aGuiltyClients.GetCount()); - memset(&aDataCorrupt[0], 0, aGuiltyClients.GetCount() * sizeof aDataCorrupt[0]); - aDataVerified.SetSize(aGuiltyClients.GetCount()); - memset(&aDataVerified[0], 0, aGuiltyClients.GetCount() * sizeof aDataVerified[0]); + aDataCorrupt.InsertAt(0, 0, iClients); + aDataVerified.InsertAt(0, 0, iClients); // now the parsing - for (INT_PTR iPart = 0; iPart < m_aaRecords.GetCount(); ++iPart) - for (INT_PTR i = 0; i < m_aaRecords[iPart].GetCount(); ++i) - for (INT_PTR k = 0; k < aGuiltyClients.GetCount(); ++k) { - const CCBBRecord &cbb = m_aaRecords[iPart][i]; - if (cbb.m_dwIP == aGuiltyClients[k]) - if (cbb.m_BBRStatus == BBR_CORRUPTED) - // corrupted data records are always counted as at least blocksize or bigger - aDataCorrupt[k] += max(cbb.m_nEndPos - cbb.m_nStartPos + 1, (uint64)EMBLOCKSIZE); - else if (cbb.m_BBRStatus == BBR_VERIFIED) - aDataVerified[k] += cbb.m_nEndPos - cbb.m_nStartPos + 1; + for (INT_PTR iPart = m_aaRecords.GetCount(); --iPart >= 0;) + for (INT_PTR i = m_aaRecords[iPart].GetCount(); --i >= 0;) + for (INT_PTR k = 0; k < iClients; ++k) { + const CCBBRecord &cbbRec(m_aaRecords[iPart][i]); + if (cbbRec.m_dwIP == aGuiltyClients[k]) + if (cbbRec.m_BBRStatus == BBR_CORRUPTED) + // corrupted data records are always counted as at least block size (180 KB) or more + aDataCorrupt[k] += max(cbbRec.m_nEndPos - cbbRec.m_nStartPos + 1, (uint64)EMBLOCKSIZE); + else if (cbbRec.m_BBRStatus == BBR_VERIFIED) + aDataVerified[k] += cbbRec.m_nEndPos - cbbRec.m_nStartPos + 1; } - for (INT_PTR k = 0; k < aGuiltyClients.GetCount(); ++k) { - // calculate the percentage of corrupted data for each client and ban - // him if the limit is reached + // calculate percentage of corrupted data for each client and ban if over the limit + for (INT_PTR k = 0; k < iClients; ++k) { int nCorruptPercentage; if ((aDataVerified[k] + aDataCorrupt[k]) > 0) nCorruptPercentage = (int)((aDataCorrupt[k] * 100) / (aDataVerified[k] + aDataCorrupt[k])); @@ -347,20 +314,24 @@ void CCorruptionBlackBox::EvaluateData(uint16 nPart) } CUpDownClient *pClient = theApp.clientlist->FindClientByIP(aGuiltyClients[k]); if (nCorruptPercentage > CBB_BANTHRESHOLD) { //evil client - if (pClient != NULL) { - AddDebugLogLine(DLP_HIGH, false, _T("CorruptionBlackBox: Banning: Found client which sent %s of %s corrupted data, %s"), (LPCTSTR)CastItoXBytes(aDataCorrupt[k]), (LPCTSTR)CastItoXBytes((aDataVerified[k] + aDataCorrupt[k])), (LPCTSTR)pClient->DbgGetClientInfo()); + if (pClient) { theApp.clientlist->AddTrackClient(pClient); pClient->Ban(_T("Identified as a sender of corrupt data")); - } else { - AddDebugLogLine(DLP_HIGH, false, _T("CorruptionBlackBox: Banning: Found client which sent %s of %s corrupted data, %s"), (LPCTSTR)CastItoXBytes(aDataCorrupt[k]), (LPCTSTR)CastItoXBytes((aDataVerified[k] + aDataCorrupt[k])), (LPCTSTR)ipstr(aGuiltyClients[k])); + } else theApp.clientlist->AddBannedClient(aGuiltyClients[k]); - } + + AddDebugLogLine(DLP_HIGH, false, _T("CorruptionBlackBox: Banning: Found client which sent %s of %s corrupted data, %s") + , (LPCTSTR)CastItoXBytes(aDataCorrupt[k]) + , (LPCTSTR)CastItoXBytes((aDataVerified[k] + aDataCorrupt[k])) + , (LPCTSTR)(pClient ? pClient->DbgGetClientInfo() : ipstr(aGuiltyClients[k]))); } else { //suspected client - if (pClient != NULL) { - AddDebugLogLine(DLP_DEFAULT, false, _T("CorruptionBlackBox: Reporting: Found client which probably sent %s of %s corrupted data, but it is within the acceptable limit, %s"), (LPCTSTR)CastItoXBytes(aDataCorrupt[k]), (LPCTSTR)CastItoXBytes((aDataVerified[k] + aDataCorrupt[k])), (LPCTSTR)pClient->DbgGetClientInfo()); + if (pClient) theApp.clientlist->AddTrackClient(pClient); - } else - AddDebugLogLine(DLP_DEFAULT, false, _T("CorruptionBlackBox: Reporting: Found client which probably sent %s of %s corrupted data, but it is within the acceptable limit, %s"), (LPCTSTR)CastItoXBytes(aDataCorrupt[k]), (LPCTSTR)CastItoXBytes((aDataVerified[k] + aDataCorrupt[k])), (LPCTSTR)ipstr(aGuiltyClients[k])); + + AddDebugLogLine(DLP_DEFAULT, false, _T("CorruptionBlackBox: Reporting: Found client which probably sent %s of %s corrupted data, but it is within the acceptable limit, %s") + , (LPCTSTR)CastItoXBytes(aDataCorrupt[k]) + , (LPCTSTR)CastItoXBytes((aDataVerified[k] + aDataCorrupt[k])) + , (LPCTSTR)(pClient ? pClient->DbgGetClientInfo() : ipstr(aGuiltyClients[k]))); } } } \ No newline at end of file diff --git a/srchybrid/CorruptionBlackBox.h b/srchybrid/CorruptionBlackBox.h index a0b3fbf9..39cd7bad 100644 --- a/srchybrid/CorruptionBlackBox.h +++ b/srchybrid/CorruptionBlackBox.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -31,8 +31,6 @@ class CCBBRecord { public: CCBBRecord(uint64 nStartPos = 0, uint64 nEndPos = 0, uint32 dwIP = 0, EBBRStatus BBRStatus = BBR_NONE); - CCBBRecord(const CCBBRecord &cv) { *this = cv; } - CCBBRecord& operator=(const CCBBRecord &cv); bool Merge(uint64 nStartPos, uint64 nEndPos, uint32 dwIP, EBBRStatus BBRStatus = BBR_NONE); bool CanMerge(uint64 nStartPos, uint64 nEndPos, uint32 dwIP, EBBRStatus BBRStatus = BBR_NONE) const; diff --git a/srchybrid/CreditsDlg.cpp b/srchybrid/CreditsDlg.cpp index 251c92f9..0702b066 100644 --- a/srchybrid/CreditsDlg.cpp +++ b/srchybrid/CreditsDlg.cpp @@ -50,7 +50,7 @@ END_MESSAGE_MAP() // CCreditsDlg message handlers /// -/// +/// /// /// BOOL CCreditsDlg::OnInitDialog() diff --git a/srchybrid/CreditsThread.cpp b/srchybrid/CreditsThread.cpp index 971c2098..622d5c69 100644 --- a/srchybrid/CreditsThread.cpp +++ b/srchybrid/CreditsThread.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -208,19 +208,21 @@ void CCreditsThread::CreateCredits() m_dcCredits.SetBkMode(TRANSPARENT); - int y = 0; + unsigned y = 0; int nTextHeight = m_dcCredits.GetTextExtent(_T("Wy")).cy; - for (int n = 0; n < m_arCredits.GetCount(); ++n) { + for (INT_PTR n = 0; n < m_arCredits.GetCount(); ++n) { const CString &cs(m_arCredits[n]); + if (cs.GetLength() < 3) + continue; switch (cs[0]) { case _T('B'): // it's a bitmap { CBitmap bmp; - if (!bmp.LoadBitmap(cs.Mid(2))) { + if (!bmp.LoadBitmap(CPTR(cs, 2))) { CString sMsg; - sMsg.Format(_T("Could not find bitmap resource \"%s\". Be sure to assign the bitmap a QUOTED resource name"), (LPCTSTR)cs.Mid(2)); + sMsg.Format(_T("Could not find bitmap resource \"%s\". Be sure to assign the bitmap a QUOTED resource name"), CPTR(cs, 2)); AfxMessageBox(sMsg); return; } @@ -242,7 +244,7 @@ void CCreditsThread::CreateCredits() } break; case _T('S'): // it's a vertical space - y += _ttoi(cs.Mid(2)); + y += _ttoi(CPTR(cs, 2)); break; default: // it's a text string { @@ -260,9 +262,9 @@ void CCreditsThread::CreateCredits() if (nColor != nLastColor) m_dcCredits.SetTextColor(m_arColors[nColor]); - RECT rect = { 0, y, m_rectScreen.Width(), y + nTextHeight }; + RECT rect = { 0, (LONG)y, m_rectScreen.Width(), (LONG)y + nTextHeight }; - m_dcCredits.DrawText(cs.Mid(6), &rect, DT_CENTER); + m_dcCredits.DrawText(CPTR(cs, 6), &rect, DT_CENTER); y += nTextHeight; } @@ -293,11 +295,11 @@ void CCreditsThread::InitFonts() LOGFONT lf = {}; // font 0 // SMALL ARIAL - CFont *font0 = new CFont; lf.lfHeight = 12; lf.lfWeight = 500; lf.lfQuality = NONANTIALIASED_QUALITY; _tcscpy(lf.lfFaceName, _T("Arial")); + CFont *font0 = new CFont; font0->CreateFontIndirect(&lf); m_arFonts.Add(font0); @@ -307,12 +309,12 @@ void CCreditsThread::InitFonts() // font 1 // MEDIUM BOLD ARIAL - CFont *font1 = new CFont; memset((void*)&lf, 0, sizeof lf); lf.lfHeight = 14; lf.lfWeight = 600; lf.lfQuality = NONANTIALIASED_QUALITY; _tcscpy(lf.lfFaceName, _T("Arial")); + CFont *font1 = new CFont; font1->CreateFontIndirect(&lf); m_arFonts.Add(font1); @@ -322,13 +324,13 @@ void CCreditsThread::InitFonts() // font 2 // LARGE ITALIC HEAVY BOLD TIMES ROMAN - CFont *font2 = new CFont; memset((void*)&lf, 0, sizeof lf); lf.lfHeight = 16; lf.lfWeight = 700; //lf.lfItalic = TRUE; lf.lfQuality = ANTIALIASED_QUALITY; _tcscpy(lf.lfFaceName, _T("Arial")); + CFont *font2 = new CFont; font2->CreateFontIndirect(&lf); m_arFonts.Add(font2); @@ -337,12 +339,12 @@ void CCreditsThread::InitFonts() m_arFontHeights.Add(nTextHeight); // font 3 - CFont *font3 = new CFont; memset((void*)&lf, 0, sizeof lf); lf.lfHeight = 25; lf.lfWeight = 900; lf.lfQuality = ANTIALIASED_QUALITY; _tcscpy(lf.lfFaceName, _T("Arial")); + CFont *font3 = new CFont; font3->CreateFontIndirect(&lf); m_arFonts.Add(font3); @@ -388,7 +390,7 @@ void CCreditsThread::InitText() m_arCredits.Add(_T("03:00:eMule")); m_arCredits.Add(_T("02:01:Version ") + theApp.m_strCurVersionLong); - m_arCredits.Add(_T("01:06:Copyright (C) 2002-2021 Merkur")); + m_arCredits.Add(_T("01:06:Copyright (C) 2002-2023 Merkur")); m_arCredits.Add(_T("S:50")); m_arCredits.Add(_T("02:04:Developers")); m_arCredits.Add(_T("S:5")); @@ -555,17 +557,19 @@ void CCreditsThread::InitText() int CCreditsThread::CalcCreditsHeight() { - int nHeight = 0; + unsigned nHeight = 0; - for (int n = 0; n < m_arCredits.GetCount(); ++n) { + for (INT_PTR n = 0; n < m_arCredits.GetCount(); ++n) { const CString &cs(m_arCredits[n]); + if (cs.GetLength() < 3) + continue; switch (cs[0]) { case _T('B'): // it's a bitmap { CBitmap bmp; - if (!bmp.LoadBitmap(cs.Mid(2))) { + if (!bmp.LoadBitmap(CPTR(cs, 2))) { CString sMsg; - sMsg.Format(_T("Could not find bitmap resource \"%s\". Be sure to assign the bitmap a QUOTED resource name"), (LPCTSTR)cs.Mid(2)); + sMsg.Format(_T("Could not find bitmap resource \"%s\". Be sure to assign the bitmap a QUOTED resource name"), CPTR(cs, 2)); AfxMessageBox(sMsg); return -1; } @@ -577,7 +581,7 @@ int CCreditsThread::CalcCreditsHeight() } break; case _T('S'): // it's a vertical space - nHeight += _ttoi(cs.Mid(2)); + nHeight += _ttoi(CPTR(cs, 2)); break; default: // it's a text string { diff --git a/srchybrid/CreditsThread.h b/srchybrid/CreditsThread.h index 445b6550..d7083309 100644 --- a/srchybrid/CreditsThread.h +++ b/srchybrid/CreditsThread.h @@ -55,7 +55,5 @@ class CCreditsThread : public CGDIThread // Implementation protected: - virtual ~CCreditsThread() = default; - DECLARE_MESSAGE_MAP() }; diff --git a/srchybrid/CustomAutoComplete.cpp b/srchybrid/CustomAutoComplete.cpp index 0cf3df13..51891ec6 100644 --- a/srchybrid/CustomAutoComplete.cpp +++ b/srchybrid/CustomAutoComplete.cpp @@ -65,7 +65,7 @@ CCustomAutoComplete::~CCustomAutoComplete() bool CCustomAutoComplete::Bind(HWND p_hWndEdit, DWORD p_dwOptions, LPCTSTR p_lpszFormatString) { ATLASSERT(::IsWindow(p_hWndEdit)); - if (m_fBound || m_pac) + if (m_bBound || m_pac) return false; if (SUCCEEDED(m_pac.CoCreateInstance(CLSID_AutoComplete))) { @@ -78,7 +78,7 @@ bool CCustomAutoComplete::Bind(HWND p_hWndEdit, DWORD p_dwOptions, LPCTSTR p_lps } if (SUCCEEDED(m_pac->Init(p_hWndEdit, this, NULL, p_lpszFormatString))) { - m_fBound = true; + m_bBound = true; return true; } } @@ -87,9 +87,9 @@ bool CCustomAutoComplete::Bind(HWND p_hWndEdit, DWORD p_dwOptions, LPCTSTR p_lps void CCustomAutoComplete::Unbind() { - if (m_fBound && m_pac) { + if (m_bBound && m_pac) { m_pac.Release(); - m_fBound = false; + m_bBound = false; } } @@ -111,26 +111,22 @@ int CCustomAutoComplete::FindItem(const CString &rstr) bool CCustomAutoComplete::AddItem(const CString &p_sItem, int iPos) { - if (p_sItem.GetLength() != 0) { + if (p_sItem.GetLength() > 0) { int oldpos = FindItem(p_sItem); - if (oldpos == -1) { - // use a LRU list - if (iPos == -1) + if (oldpos < 0) { + if (iPos < 0) m_asList.Add(p_sItem); else m_asList.InsertAt(iPos, p_sItem); - + // use a LRU list if (m_asList.GetCount() > m_iMaxItemCount) m_asList.SetSize(m_iMaxItemCount); return true; - } else if (iPos >= 0) { + } + if (iPos >= 0) { m_asList.RemoveAt(oldpos); - if (oldpos < iPos) - --iPos; + iPos -= static_cast(oldpos < iPos); m_asList.InsertAt(iPos, p_sItem); - - if (m_asList.GetCount() > m_iMaxItemCount) - m_asList.SetSize(m_iMaxItemCount); return true; } } @@ -156,12 +152,12 @@ bool CCustomAutoComplete::RemoveItem(const CString &p_sItem) bool CCustomAutoComplete::RemoveSelectedItem() { - if (!m_fBound || !m_pac) + if (!m_bBound || !m_pac) return false; DWORD dwFlags; LPWSTR pwszItem; - CComQIPtr pIAutoCompleteDropDown = m_pac; + CComQIPtr pIAutoCompleteDropDown(m_pac); if (!pIAutoCompleteDropDown || FAILED(pIAutoCompleteDropDown->GetDropDownStatus(&dwFlags, &pwszItem))) return false; @@ -172,21 +168,20 @@ bool CCustomAutoComplete::RemoveSelectedItem() bool CCustomAutoComplete::Clear() { - if (!m_asList.IsEmpty()) { - m_asList.RemoveAll(); - return true; - } - return false; + if (m_asList.IsEmpty()) + return false; + m_asList.RemoveAll(); + return true; } bool CCustomAutoComplete::Disable() { - return m_pac && m_fBound && SUCCEEDED(EnDisable(FALSE)); + return m_bBound && m_pac && SUCCEEDED(EnDisable(false)); } bool CCustomAutoComplete::Enable() { - return m_pac && !m_fBound && SUCCEEDED(EnDisable(TRUE)); + return !m_bBound && m_pac && SUCCEEDED(EnDisable(true)); } const CStringArray& CCustomAutoComplete::GetList() const @@ -199,33 +194,33 @@ const CStringArray& CCustomAutoComplete::GetList() const // STDMETHODIMP_(ULONG) CCustomAutoComplete::AddRef() noexcept { - return static_cast(InterlockedIncrement(&m_nRefCount)); + return static_cast(::InterlockedIncrement(&m_nRefCount)); } STDMETHODIMP_(ULONG) CCustomAutoComplete::Release() noexcept { - LONG nCount = InterlockedDecrement(&m_nRefCount); + LONG nCount = ::InterlockedDecrement(&m_nRefCount); if (nCount == 0) delete this; return static_cast(nCount); } -STDMETHODIMP CCustomAutoComplete::QueryInterface(REFIID riid, void **ppvObject) noexcept +STDMETHODIMP CCustomAutoComplete::QueryInterface(REFIID iid, LPVOID *ppvObj) noexcept { - if (ppvObject == NULL) + if (ppvObj == NULL) return E_POINTER; - if (IID_IUnknown == riid) - *ppvObject = static_cast(this); - else if (IID_IEnumString == riid) - *ppvObject = static_cast(this); + if (IID_IUnknown == iid) + *ppvObj = static_cast(this); + else if (IID_IEnumString == iid) + *ppvObj = static_cast(this); else - *ppvObject = NULL; - if (*ppvObject != NULL) { - ((LPUNKNOWN)*ppvObject)->AddRef(); - return S_OK; - } - return E_NOINTERFACE; + *ppvObj = NULL; + if (*ppvObj == NULL) + return E_NOINTERFACE; + + ((LPUNKNOWN)*ppvObj)->AddRef(); + return S_OK; } // @@ -233,18 +228,16 @@ STDMETHODIMP CCustomAutoComplete::QueryInterface(REFIID riid, void **ppvObject) // STDMETHODIMP CCustomAutoComplete::Next(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched) noexcept { - HRESULT hr = S_FALSE; - if (!celt) celt = 1; if (pceltFetched) *pceltFetched = 0; ULONG i; for (i = 0; i < celt; ++i) { - if (m_nCurrentElement == (ULONG)m_asList.GetCount()) + if (m_nCurrentElement >= (ULONG)m_asList.GetCount()) break; - rgelt[i] = (LPWSTR)CoTaskMemAlloc((ULONG)(sizeof(WCHAR) * (m_asList[m_nCurrentElement].GetLength() + 1))); + rgelt[i] = (LPWSTR)::CoTaskMemAlloc(sizeof(WCHAR) * ((SIZE_T)m_asList[m_nCurrentElement].GetLength() + 1)); wcscpy(rgelt[i], (CStringW)m_asList[m_nCurrentElement]); if (pceltFetched) @@ -252,11 +245,7 @@ STDMETHODIMP CCustomAutoComplete::Next(ULONG celt, LPOLESTR *rgelt, ULONG *pcelt ++m_nCurrentElement; } - - if (i == celt) - hr = S_OK; - - return hr; + return (i == celt) ? S_OK : S_FALSE; } STDMETHODIMP CCustomAutoComplete::Skip(ULONG celt) noexcept @@ -293,17 +282,17 @@ void CCustomAutoComplete::InternalInit() { m_nCurrentElement = 0; m_nRefCount = 0; - m_fBound = false; m_iMaxItemCount = 30; + m_bBound = false; } -HRESULT CCustomAutoComplete::EnDisable(BOOL p_fEnable) +HRESULT CCustomAutoComplete::EnDisable(bool p_bEnable) { ATLASSERT(m_pac); - HRESULT hr = m_pac->Enable(p_fEnable); + HRESULT hr = m_pac->Enable(p_bEnable); if (SUCCEEDED(hr)) - m_fBound = (p_fEnable != FALSE); + m_bBound = p_bEnable; return hr; } @@ -315,17 +304,15 @@ bool CCustomAutoComplete::LoadList(LPCTSTR pszFileName) // verify Unicode byte order mark 0xFEFF WORD wBOM = fgetwc(fp); - if (wBOM != 0xFEFFui16) { + if (wBOM != u'\xFEFF') { fclose(fp); return false; } TCHAR szItem[256]; - while (_fgetts(szItem, _countof(szItem), fp) != NULL) { - CString strItem(szItem); - strItem.Trim(_T(" \r\n")); - AddItem(strItem, -1); - } + while (_fgetts(szItem, _countof(szItem), fp) != NULL) + AddItem(CString(szItem).Trim(_T(" \r\n")), -1); + fclose(fp); return true; } @@ -335,7 +322,7 @@ bool CCustomAutoComplete::SaveList(LPCTSTR pszFileName) FILE *fp = _tfsopen(pszFileName, _T("wb"), _SH_DENYWR); if (fp == NULL) return false; - bool ret = (fputwc(0xFEFFui16, fp) != WEOF); // write Unicode byte order mark 0xFEFF + bool ret = (fputwc(u'\xFEFF', fp) != WEOF); // write Unicode byte order mark 0xFEFF for (int i = 0; ret && i < m_asList.GetCount(); ++i) ret = (_ftprintf(fp, _T("%s\r\n"), (LPCTSTR)m_asList[i]) > 0); return fclose(fp) ? false : ret; diff --git a/srchybrid/CustomAutoComplete.h b/srchybrid/CustomAutoComplete.h index f1e331ee..35e3698a 100644 --- a/srchybrid/CustomAutoComplete.h +++ b/srchybrid/CustomAutoComplete.h @@ -7,8 +7,7 @@ #include #include -class CCustomAutoComplete : - public IEnumString +class CCustomAutoComplete : public IEnumString { private: CStringArray m_asList; @@ -16,8 +15,8 @@ class CCustomAutoComplete : ULONG m_nCurrentElement; ULONG m_nRefCount; - bool m_fBound; int m_iMaxItemCount; + bool m_bBound; // Constructors/destructors public: @@ -29,7 +28,7 @@ class CCustomAutoComplete : public: bool Bind(HWND p_hWndEdit, DWORD p_dwOptions = 0, LPCTSTR p_lpszFormatString = NULL); void Unbind(); - bool IsBound() const { return m_fBound; } + bool IsBound() const { return m_bBound; } bool SetList(const CStringArray &p_sItemList); const CStringArray& GetList() const; @@ -50,7 +49,7 @@ class CCustomAutoComplete : public: STDMETHOD_(ULONG, AddRef)(); STDMETHOD_(ULONG, Release)(); - STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject); + STDMETHOD(QueryInterface)(REFIID iid, LPVOID *ppvObj); public: STDMETHOD(Next)(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched); @@ -61,6 +60,6 @@ class CCustomAutoComplete : // Internal implementation private: void InternalInit(); - HRESULT EnDisable(BOOL p_fEnable); + HRESULT EnDisable(bool p_bEnable); int FindItem(const CString &rstr); }; \ No newline at end of file diff --git a/srchybrid/DeadSourceList.cpp b/srchybrid/DeadSourceList.cpp index 2b990f19..685bc527 100644 --- a/srchybrid/DeadSourceList.cpp +++ b/srchybrid/DeadSourceList.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -15,8 +15,8 @@ //along with this program; if not, write to the Free Software //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "StdAfx.h" -#include "deadsourcelist.h" #include "opcodes.h" +#include "deadsourcelist.h" #include "updownclient.h" #include "Log.h" @@ -27,35 +27,47 @@ static char THIS_FILE[] = __FILE__; #endif -#define CLEANUPTIME MIN2MS(60) +#define CLEANUPTIME MIN2MS(60) -#define BLOCKTIME (::GetTickCount() + MIN2MS(m_bGlobalList ? 15 : 45)) -#define BLOCKTIMEFW (::GetTickCount() + MIN2MS(m_bGlobalList ? 30 : 45)) +#define BLOCKTIME (MIN2MS(m_bGlobalList ? 15 : 45)) +#define BLOCKTIMEFW (MIN2MS(m_bGlobalList ? 30 : 45)) /////////////////////////////////////////////////////////////////////////////////////// //// CDeadSource -CDeadSource::CDeadSource(uint32 dwID, uint16 nPort, uint32 dwServerIP, uint16 nKadPort) - : m_dwID(dwID) - , m_dwServerIP(dwServerIP) - , m_nPort(nPort) - , m_nKadPort(nKadPort) - , m_aucHash() -{ -} - -CDeadSource::CDeadSource(const uchar *paucHash) - : m_dwID() +CDeadSource::CDeadSource() + : m_aucHash() , m_dwServerIP() + , m_dwID() , m_nPort() , m_nKadPort() { - md4cpy(m_aucHash, paucHash); } -bool operator==(const CDeadSource &ds1, const CDeadSource &ds2){ - //ASSERT( ((ds1.m_dwID + ds1.m_dwServerIP) ^ isnulmd4(ds1.m_aucHash)) != 0 ); - //ASSERT( ((ds2.m_dwID + ds2.m_dwServerIP) ^ isnulmd4(ds2.m_aucHash)) != 0 ); +CDeadSource::CDeadSource(const CUpDownClient &client) +{ + if (!client.HasLowID() || client.GetServerIP() != 0) { + md4clr(m_aucHash); + m_dwServerIP = client.GetServerIP(); + m_dwID = client.GetUserIDHybrid(); + m_nPort = client.GetUserPort(); + m_nKadPort = (client.HasLowID() ? 0 : client.GetKadPort()); + } else { + if (client.HasValidBuddyID() || client.SupportsDirectUDPCallback()) + md4cpy(m_aucHash, client.GetUserHash()); + else + md4clr(m_aucHash); + m_dwServerIP = 0; + m_dwID = 0; + m_nPort = 0; + m_nKadPort = 0; + } +} + +bool operator==(const CDeadSource &ds1, const CDeadSource &ds2) +{ + //ASSERT((ds1.m_dwID + ds1.m_dwServerIP) ^ isnulmd4(ds1.m_aucHash)); + //ASSERT((ds2.m_dwID + ds2.m_dwServerIP) ^ isnulmd4(ds2.m_aucHash)); return ( // lowid ed2k and highid kad + ed2k check ((ds1.m_dwID != 0 && ds1.m_dwID == ds2.m_dwID) && ((ds1.m_nPort != 0 && ds1.m_nPort == ds2.m_nPort) || (ds1.m_nKadPort != 0 && ds1.m_nKadPort == ds2.m_nKadPort)) && (ds1.m_dwServerIP == ds2.m_dwServerIP || !::IsLowID(ds1.m_dwID)) ) @@ -65,11 +77,11 @@ bool operator==(const CDeadSource &ds1, const CDeadSource &ds2){ CDeadSource& CDeadSource::operator=(const CDeadSource &ds) { - m_dwID = ds.m_dwID; + md4cpy(m_aucHash, ds.m_aucHash); m_dwServerIP = ds.m_dwServerIP; + m_dwID = ds.m_dwID; m_nPort = ds.m_nPort; m_nKadPort = ds.m_nKadPort; - md4cpy(m_aucHash, ds.m_aucHash); return *this; } @@ -84,82 +96,47 @@ CDeadSourceList::CDeadSourceList() void CDeadSourceList::Init(bool bGlobalList) { - m_dwLastCleanUp = ::GetTickCount(); m_mapDeadSources.InitHashTable(bGlobalList ? 3001 : 503); m_bGlobalList = bGlobalList; + m_dwLastCleanUp = ::GetTickCount(); } -bool CDeadSourceList::IsDeadSource(const CUpDownClient *pToCheck) const +bool CDeadSourceList::IsDeadSource(const CUpDownClient &client) const { - uint32 dwExpTime; -// bool bDbgCheck = false; - if (!pToCheck->HasLowID() || pToCheck->GetServerIP() != 0) { - if (m_mapDeadSources.Lookup(CDeadSource(pToCheck->GetUserIDHybrid(), pToCheck->GetUserPort(), pToCheck->GetServerIP(), pToCheck->GetKadPort()), dwExpTime)) - if (::GetTickCount() < dwExpTime) - return true; -// bDbgCheck = true; - } - if (((pToCheck->HasValidBuddyID() || pToCheck->SupportsDirectUDPCallback()) && !isnulmd4(pToCheck->GetUserHash())) || (pToCheck->HasLowID() && pToCheck->GetServerIP() == 0)) { - if (m_mapDeadSources.Lookup(CDeadSource(pToCheck->GetUserHash()), dwExpTime)) { - if (::GetTickCount() < dwExpTime) - return true; - } -// bDbgCheck = true; - } -// ASSERT ( bDbgCheck ); - return false; + const CDeadSourcesMap::CPair *pair = m_mapDeadSources.PLookup(CDeadSource(client)); + return (pair && ::GetTickCount() < pair->value); } -void CDeadSourceList::AddDeadSource(const CUpDownClient *pToAdd) +void CDeadSourceList::AddDeadSource(const CUpDownClient &client) { //if (thePrefs.GetLogFilteredIPs()) // AddDebugLogLine(DLP_VERYLOW, false, _T("Added source to bad source list (%s) - file %s : %s") // , m_bGlobalList? _T("Global") : _T("Local") // , (pToAdd->GetRequestFile() != NULL) ? (LPCTSTR)pToAdd->GetRequestFile()->GetFileName() : _T("???") // , (LPCTSTR)pToAdd->DbgGetClientInfo()); + DWORD curTick = ::GetTickCount(); + m_mapDeadSources[CDeadSource(client)] = curTick + (client.HasLowID() ? BLOCKTIMEFW : BLOCKTIME); - if (!pToAdd->HasLowID()) - m_mapDeadSources.SetAt(CDeadSource(pToAdd->GetUserIDHybrid(), pToAdd->GetUserPort(), pToAdd->GetServerIP(), pToAdd->GetKadPort()), BLOCKTIME); - else { -// bool bDbgCheck = false; - if (pToAdd->GetServerIP() != 0) { -// bDbgCheck = true; - m_mapDeadSources.SetAt(CDeadSource(pToAdd->GetUserIDHybrid(), pToAdd->GetUserPort(), pToAdd->GetServerIP(), 0), BLOCKTIMEFW); - } - if (pToAdd->HasValidBuddyID() || pToAdd->SupportsDirectUDPCallback()) { -// bDbgCheck = true; - m_mapDeadSources.SetAt(CDeadSource(pToAdd->GetUserHash()), BLOCKTIMEFW); - } -// ASSERT( bDbgCheck ); - } - if (::GetTickCount() >= m_dwLastCleanUp + CLEANUPTIME) + if (curTick >= m_dwLastCleanUp + CLEANUPTIME) CleanUp(); } -void CDeadSourceList::RemoveDeadSource(const CUpDownClient *client) +void CDeadSourceList::RemoveDeadSource(const CUpDownClient &client) { - if (!client->HasLowID()) - m_mapDeadSources.RemoveKey(CDeadSource(client->GetUserIDHybrid(), client->GetUserPort(), client->GetServerIP(), client->GetKadPort())); - else { - if (client->GetServerIP() != 0) - m_mapDeadSources.RemoveKey(CDeadSource(client->GetUserIDHybrid(), client->GetUserPort(), client->GetServerIP(), 0)); - if (client->HasValidBuddyID() || client->SupportsDirectUDPCallback()) - m_mapDeadSources.RemoveKey(CDeadSource(client->GetUserHash())); - } + m_mapDeadSources.RemoveKey(CDeadSource(client)); } void CDeadSourceList::CleanUp() { - const uint32 dwTick = ::GetTickCount(); - m_dwLastCleanUp = dwTick; + m_dwLastCleanUp = ::GetTickCount(); //if (thePrefs.GetLogFilteredIPs()) // AddDebugLogLine(DLP_VERYLOW, false, _T("Cleaning up DeadSourceList (%s), %i clients on List..."), m_bGlobalList ? _T("Global") : _T("Local"), m_mapDeadSources.GetCount()); CDeadSource dsKey; for (POSITION pos = m_mapDeadSources.GetStartPosition(); pos != NULL;) { - uint32 dwExpTime; + DWORD dwExpTime; m_mapDeadSources.GetNextAssoc(pos, dsKey, dwExpTime); - if (dwTick >= dwExpTime) + if (m_dwLastCleanUp >= dwExpTime) m_mapDeadSources.RemoveKey(dsKey); } //if (thePrefs.GetLogFilteredIPs()) diff --git a/srchybrid/DeadSourceList.h b/srchybrid/DeadSourceList.h index af5a4d44..f87b9e12 100644 --- a/srchybrid/DeadSourceList.h +++ b/srchybrid/DeadSourceList.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -24,18 +24,18 @@ class CDeadSource : public CObject { public: + CDeadSource(); + explicit CDeadSource(const CUpDownClient &client); CDeadSource(const CDeadSource &ds) { *this = ds; } - CDeadSource(uint32 dwID = 0, uint16 nPort = 0, uint32 dwServerIP = 0, uint16 nKadPort = 0); - explicit CDeadSource(const uchar *paucHash); CDeadSource& operator=(const CDeadSource &ds); friend bool operator==(const CDeadSource &ds1, const CDeadSource &ds2); - uint32 m_dwID; + uchar m_aucHash[MDX_DIGEST_SIZE]; uint32 m_dwServerIP; + uint32 m_dwID; uint16 m_nPort; uint16 m_nKadPort; - uchar m_aucHash[16]; }; template<> inline UINT AFXAPI HashKey(const CDeadSource &ds) @@ -44,13 +44,12 @@ template<> inline UINT AFXAPI HashKey(const CDeadSource &ds) if (hash != 0) { if (::IsLowID(hash)) hash ^= ds.m_dwServerIP; - } else { - ASSERT(!isnulmd4(ds.m_aucHash)); - hash = 1; - for (unsigned i = 0; i < 16; ++i) - hash += (ds.m_aucHash[i] + 1) * ((i * i) + 1); + return hash; } - return hash; + ASSERT(!isnulmd4(ds.m_aucHash)); + for (int i = MDX_DIGEST_SIZE; --i >= 0;) + hash += (ds.m_aucHash[i] + 1) * (i * i + 1); + return hash + 1; }; /////////////////////////////////////////////////////////////////////////////////////// @@ -61,17 +60,18 @@ class CDeadSourceList public: CDeadSourceList(); ~CDeadSourceList() = default; - void AddDeadSource(const CUpDownClient *pToAdd); - void RemoveDeadSource(const CUpDownClient *client); - bool IsDeadSource(const CUpDownClient *pToCheck) const; - INT_PTR GetDeadSourcesCount() const { return m_mapDeadSources.GetCount(); } - void Init(bool bGlobalList); + void AddDeadSource(const CUpDownClient &client); + void RemoveDeadSource(const CUpDownClient &client); + bool IsDeadSource(const CUpDownClient &client) const; + INT_PTR GetDeadSourcesCount() const { return m_mapDeadSources.GetCount(); } + void Init(bool bGlobalList); protected: - void CleanUp(); + void CleanUp(); private: - CMap m_mapDeadSources; - uint32 m_dwLastCleanUp; + typedef CMap CDeadSourcesMap; + CDeadSourcesMap m_mapDeadSources; + DWORD m_dwLastCleanUp; bool m_bGlobalList; }; \ No newline at end of file diff --git a/srchybrid/DebugHelpers.h b/srchybrid/DebugHelpers.h index 82c29cf9..5ff6983c 100644 --- a/srchybrid/DebugHelpers.h +++ b/srchybrid/DebugHelpers.h @@ -1,8 +1,8 @@ #pragma once #define CHECK_OBJ(pObj) if (pObj != NULL) ASSERT_VALID(pObj) -#define CHECK_PTR(ptr) ASSERT( ptr == NULL || AfxIsValidAddress(ptr, sizeof(*ptr)) ); -#define CHECK_ARR(ptr, len) ASSERT( (ptr == NULL && len == 0) || (ptr != NULL && len != 0 && AfxIsValidAddress(ptr, len)) ); -#define CHECK_BOOL(bVal) ASSERT( (int)(bVal) == 0 || (int)(bVal) == 1 ); +#define CHECK_PTR(ptr) (void)ptr; +#define CHECK_ARR(ptr, len) ASSERT((ptr == NULL) == (len == 0)); +#define CHECK_BOOL(bVal) ASSERT((int)(bVal) == 0 || (int)(bVal) == 1); #define CRASH_HERE() (*((int*)NULL) = 0) diff --git a/srchybrid/Debug_FileSize.h b/srchybrid/Debug_FileSize.h index 5e1a07ea..e84854aa 100644 --- a/srchybrid/Debug_FileSize.h +++ b/srchybrid/Debug_FileSize.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -135,9 +135,9 @@ class CEMFileSize ASSERT(m_nSize >= nSize1 && m_nSize >= nSize2 && m_nSize <= MAX_EMULE_FILE_SIZE); } } - void Check() const + void Check() const { - ASSERT( m_nSize != _UI64_MAX && m_nSize <= MAX_EMULE_FILE_SIZE); + ASSERT(m_nSize != _UI64_MAX && m_nSize <= MAX_EMULE_FILE_SIZE); } uint64 m_nSize; }; \ No newline at end of file diff --git a/srchybrid/DialogMinTrayBtn.cpp b/srchybrid/DialogMinTrayBtn.cpp index 9a7983c5..405f2a6a 100644 --- a/srchybrid/DialogMinTrayBtn.cpp +++ b/srchybrid/DialogMinTrayBtn.cpp @@ -4,7 +4,7 @@ // Supports WinXP styles (thanks to David Yuheng Zhao for CVisualStylesXP - yuheng_zhao@yahoo.com) // ------------------------------------------------------------ // DialogMinTrayBtn.hpp -// zegzav - 2002,2003 - eMule project (http://www.emule-project.net) +// zegzav - 2002,2003 - eMule project (https://www.emule-project.net) // ------------------------------------------------------------ #include "stdafx.h" #include "DialogMinTrayBtn.h" @@ -22,8 +22,6 @@ static char THIS_FILE[] = __FILE__; #endif -static BOOL (WINAPI *s_pfnTransparentBlt)(HDC, int, int, int, int, HDC, int, int, int, int, UINT) = NULL; - #if 0 // define this to use that source file as template #define TEMPLATE template @@ -126,16 +124,6 @@ TEMPLATE void CDialogMinTrayBtn::MinTrayBtnInit() m_bMinTrayBtnActive = FALSE; m_bMinTrayBtnHitTest = FALSE; m_nMinTrayBtnTimerId = 0; - - // - Load the 'MSIMG32.DLL' only, if it's really needed. - if (MinTrayBtnInitBitmap() && !s_pfnTransparentBlt) { - HMODULE hMsImg32 = LoadLibrary(_T("MSIMG32.DLL")); - if (hMsImg32) { - (FARPROC &)s_pfnTransparentBlt = GetProcAddress(hMsImg32, "TransparentBlt"); - if (!s_pfnTransparentBlt) - FreeLibrary(hMsImg32); - } - } } TEMPLATE BOOL CDialogMinTrayBtn::OnInitDialog() @@ -211,7 +199,7 @@ TEMPLATE void CDialogMinTrayBtn::OnLButtonUp(UINT nFlags, CPoint point) return; } - ReleaseCapture(); + ::ReleaseCapture(); m_bMinTrayBtnCapture = FALSE; MinTrayBtnSetUp(); @@ -224,7 +212,7 @@ TEMPLATE void CDialogMinTrayBtn::OnTimer(UINT_PTR nIDEvent) { if (!IsWindowsClassicStyle() && nIDEvent == m_nMinTrayBtnTimerId) { // Visual XP Style (hot button) - CPoint point; + POINT point; if (::GetCursorPos(&point)) { BOOL bHitTest = MinTrayBtnHitTest(point); if (m_bMinTrayBtnHitTest != bHitTest) { @@ -294,6 +282,8 @@ TEMPLATE void CDialogMinTrayBtn::MinTrayBtnShow() if (MinTrayBtnIsVisible()) return; + if (!m_nMinTrayBtnTimerId) + m_nMinTrayBtnTimerId = SetTimer(TIMERMINTRAYBTN_ID, TIMERMINTRAYBTN_PERIOD, NULL); m_bMinTrayBtnVisible = TRUE; if (IsWindowVisible()) RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW); @@ -305,6 +295,11 @@ TEMPLATE void CDialogMinTrayBtn::MinTrayBtnHide() return; m_bMinTrayBtnVisible = FALSE; + if (m_nMinTrayBtnTimerId) { + KillTimer(m_nMinTrayBtnTimerId); + m_nMinTrayBtnTimerId = 0; + } + if (IsWindowVisible()) RedrawWindow(NULL, NULL, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW); } @@ -325,7 +320,7 @@ TEMPLATE void CDialogMinTrayBtn::MinTrayBtnDisable() m_bMinTrayBtnEnabled = FALSE; if (m_bMinTrayBtnCapture) { - ReleaseCapture(); + ::ReleaseCapture(); m_bMinTrayBtnCapture = FALSE; } MinTrayBtnSetUp(); @@ -388,12 +383,14 @@ TEMPLATE void CDialogMinTrayBtn::MinTrayBtnDraw() if (!m_bMinTrayBtnActive) iState += 4; // inactive state TRAYBS_Ixxx - if (m_bmMinTrayBtnBitmap.m_hObject && s_pfnTransparentBlt) { + if (m_bmMinTrayBtnBitmap.m_hObject) { // known theme (bitmap) CBitmap *pBmpOld; CDC dcMem; if (dcMem.CreateCompatibleDC(pDC) && (pBmpOld = dcMem.SelectObject(&m_bmMinTrayBtnBitmap)) != NULL) { - s_pfnTransparentBlt(pDC->m_hDC, btn.left, btn.top, btn.Width(), btn.Height(), dcMem.m_hDC, 0, BMP_TRAYBTN_HEIGHT * (iState - 1), BMP_TRAYBTN_WIDTH, BMP_TRAYBTN_HEIGHT, BMP_TRAYBTN_TRANSCOLOR); + ::TransparentBlt(pDC->m_hDC, btn.left, btn.top, btn.Width(), btn.Height() + , dcMem.m_hDC, 0, BMP_TRAYBTN_HEIGHT * (iState - 1) + , BMP_TRAYBTN_WIDTH, BMP_TRAYBTN_HEIGHT, BMP_TRAYBTN_TRANSCOLOR); dcMem.SelectObject(pBmpOld); } } else { @@ -467,8 +464,7 @@ TEMPLATE INT CDialogMinTrayBtn::GetVisualStylesXPColor() const WCHAR *p = wcsrchr(szwThemeFile, _T('\\')); if (p == NULL) return -1; - ++p; - if (_wcsicmp(p, VISUALSTYLESXP_DEFAULTFILE) == 0) { + if (_wcsicmp(&p[1], VISUALSTYLESXP_DEFAULTFILE) == 0) { if (_wcsicmp(szwThemeColor, VISUALSTYLESXP_NAMEBLUE) == 0) return VISUALSTYLESXP_BLUE; if (_wcsicmp(szwThemeColor, VISUALSTYLESXP_NAMEMETALLIC) == 0) diff --git a/srchybrid/DialogMinTrayBtn.h b/srchybrid/DialogMinTrayBtn.h index 051c7bb6..9e0afc0a 100644 --- a/srchybrid/DialogMinTrayBtn.h +++ b/srchybrid/DialogMinTrayBtn.h @@ -4,12 +4,12 @@ // Supports WinXP styles (thanks to David Yuheng Zhao for CVisualStylesXP - yuheng_zhao@yahoo.com) // ------------------------------------------------------------ // DialogMinTrayBtn.h -// zegzav - 2002,2003 - eMule project (http://www.emule-project.net) +// zegzav - 2002,2003 - eMule project (https://www.emule-project.net) // ------------------------------------------------------------ #pragma once #define HTMINTRAYBUTTON 65 -template class CDialogMinTrayBtn : public BASE +template class CDialogMinTrayBtn : public BASE { public: // constructor diff --git a/srchybrid/DirectDownloadDlg.cpp b/srchybrid/DirectDownloadDlg.cpp index 8f448a83..dc70104b 100644 --- a/srchybrid/DirectDownloadDlg.cpp +++ b/srchybrid/DirectDownloadDlg.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -17,10 +17,9 @@ #include "stdafx.h" #include "emule.h" #include "DirectDownloadDlg.h" -#include "OtherFunctions.h" +#include "ED2KLink.h" #include "emuleDlg.h" #include "DownloadQueue.h" -#include "ED2KLink.h" #include "Preferences.h" #ifdef _DEBUG @@ -88,14 +87,14 @@ void CDirectDownloadDlg::OnOK() const CString &sToken(strLinks.Tokenize(_T(" \t\r\n"), iPos)); //tokenize by whitespace if (sToken.IsEmpty()) break; - bool bSlash = (sToken.Right(1) == _T("/")); + bool bSlash = (sToken[sToken.GetLength() - 1] == _T('/')); CED2KLink *pLink = NULL; try { pLink = CED2KLink::CreateLinkFromUrl(bSlash ? sToken : sToken + _T('/')); if (pLink) { if (pLink->GetKind() != CED2KLink::kFile) - throw CString(_T("bad link")); - theApp.downloadqueue->AddFileLinkToDownload(pLink->GetFileLink(), thePrefs.GetCatCount() ? m_cattabs.GetCurSel() : 0); + throwCStr(_T("bad link")); + theApp.downloadqueue->AddFileLinkToDownload(*pLink->GetFileLink(), thePrefs.GetCatCount() ? m_cattabs.GetCurSel() : 0); delete pLink; pLink = NULL; } @@ -163,13 +162,11 @@ void CDirectDownloadDlg::UpdateCatTabs() { int oldsel = m_cattabs.GetCurSel(); m_cattabs.DeleteAllItems(); - for (int ix = 0; ix < thePrefs.GetCatCount(); ++ix) { - CString label = (ix == 0) ? GetResString(IDS_ALL) : thePrefs.GetCategory(ix)->strTitle; - label.Replace(_T("&"), _T("&&")); - m_cattabs.InsertItem(ix, label); + for (INT_PTR i = thePrefs.GetCatCount(); --i >= 0;) { + CString label(i ? thePrefs.GetCategory(i)->strTitle : GetResString(IDS_ALL)); + DupAmpersand(label); + m_cattabs.InsertItem(0, label); } - if (oldsel >= m_cattabs.GetItemCount() || oldsel == -1) - oldsel = 0; - m_cattabs.SetCurSel(oldsel); + m_cattabs.SetCurSel(oldsel >= 0 && oldsel < m_cattabs.GetItemCount() ? oldsel : 0); } \ No newline at end of file diff --git a/srchybrid/DirectDownloadDlg.h b/srchybrid/DirectDownloadDlg.h index d1985390..405a8c2d 100644 --- a/srchybrid/DirectDownloadDlg.h +++ b/srchybrid/DirectDownloadDlg.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/DirectoryTreeCtrl.cpp b/srchybrid/DirectoryTreeCtrl.cpp index 305b6b39..5e143f61 100644 --- a/srchybrid/DirectoryTreeCtrl.cpp +++ b/srchybrid/DirectoryTreeCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -55,15 +55,10 @@ BEGIN_MESSAGE_MAP(CDirectoryTreeCtrl, CTreeCtrl) ON_WM_DESTROY() END_MESSAGE_MAP() -CDirectoryTreeCtrl::CDirectoryTreeCtrl() - : m_bSelectSubDirs() -{ -} - CDirectoryTreeCtrl::~CDirectoryTreeCtrl() { // don't destroy the system's image list - m_image.Detach(); + m_images.Detach(); } void CDirectoryTreeCtrl::OnDestroy() @@ -85,10 +80,9 @@ void CDirectoryTreeCtrl::OnTvnItemexpanding(LPNMHDR pNMHDR, LRESULT *pResult) LPNMTREEVIEW pNMTreeView = reinterpret_cast(pNMHDR); HTREEITEM hItem = pNMTreeView->itemNew.hItem; // remove all sub-items - for (HTREEITEM hRemove = GetChildItem(hItem); hRemove;) { + HTREEITEM hRemove; + while ((hRemove = GetChildItem(hItem)) != NULL) DeleteItem(hRemove); - hRemove = GetChildItem(hItem); - } // fetch all subdirectories and add them to the node AddSubdirectories(hItem, GetFullPath(hItem)); @@ -146,15 +140,9 @@ void CDirectoryTreeCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) void CDirectoryTreeCtrl::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) { - // If we let any keystrokes which are handled by us -- but not by the tree - // control -- pass to the control, the user will hear a system event - // sound (Standard Error!) - BOOL bCallDefault = TRUE; - - if (GetKeyState(VK_CONTROL) < 0 && nChar == VK_SPACE) - bCallDefault = FALSE; - - if (bCallDefault) + // If we let any keystrokes which are handled by us - but not by the tree control - + // be passed to the control, the user will hear a system event sound (Standard Error!) + if (GetKeyState(VK_CONTROL) >= 0 || nChar != VK_SPACE) CTreeCtrl::OnChar(nChar, nRepCnt, nFlags); } @@ -171,8 +159,7 @@ void CDirectoryTreeCtrl::MarkChildren(HTREEITEM hChild, bool mark) void CDirectoryTreeCtrl::OnTvnGetdispinfo(LPNMHDR pNMHDR, LRESULT *pResult) { - LPNMTVDISPINFO pTVDispInfo = reinterpret_cast(pNMHDR); - pTVDispInfo->item.cChildren = 1; + reinterpret_cast(pNMHDR)->item.cChildren = 1; *pResult = 0; } @@ -188,15 +175,14 @@ void CDirectoryTreeCtrl::Init() SHFILEINFO shFinfo; // Get the system image list using a "path" which is available on all systems. [patch by bluecow] - HIMAGELIST hImgList = (HIMAGELIST)SHGetFileInfo(_T("."), 0, &shFinfo, sizeof(shFinfo), - SHGFI_SYSICONINDEX | SHGFI_SMALLICON); + HIMAGELIST hImgList = (HIMAGELIST)::SHGetFileInfo(_T("."), 0, &shFinfo, sizeof(shFinfo), SHGFI_SYSICONINDEX | SHGFI_SMALLICON); if (!hImgList) { TRACE(_T("Cannot retrieve the Handle of SystemImageList!")); //return; } - m_image.m_hImageList = hImgList; - SetImageList(&m_image, TVSIL_NORMAL); + m_images.m_hImageList = hImgList; + SetImageList(&m_images, TVSIL_NORMAL); //////////////////////////////// TCHAR drivebuffer[500]; @@ -215,21 +201,28 @@ void CDirectoryTreeCtrl::Init() pos += _tcslen(pos) + 1; } } + for (INT_PTR i = 0; i < m_lstUNC.GetCount(); ++i) { + const CString &sUNC(m_lstUNC[i]); + AddChildItem(NULL, sUNC.Left(sUNC.GetLength() - 1)); + } + ShowWindow(SW_SHOW); } HTREEITEM CDirectoryTreeCtrl::AddChildItem(HTREEITEM hRoot, const CString &strText) { CString strDir(GetFullPath(hRoot)); - if (hRoot != NULL) - slosh(strDir); + ASSERT(strDir.IsEmpty() || strDir.Right(1) == _T("\\")); strDir += strText; slosh(strDir); + TVINSERTSTRUCT itInsert = {}; + itInsert.hParent = hRoot; + itInsert.hInsertAfter = hRoot ? TVI_SORT : TVI_LAST; + itInsert.item.pszText = const_cast((LPCTSTR)strText); // START: changed by FoRcHa ///// - itInsert.item.mask = TVIF_CHILDREN | TVIF_HANDLE | TVIF_TEXT - | TVIF_STATE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; + itInsert.item.mask = TVIF_CHILDREN | TVIF_HANDLE | TVIF_TEXT | TVIF_STATE | TVIF_IMAGE | TVIF_SELECTEDIMAGE; itInsert.item.stateMask = TVIS_BOLD | TVIS_STATEIMAGEMASK; // END: changed by FoRcHa /////// @@ -237,19 +230,14 @@ HTREEITEM CDirectoryTreeCtrl::AddChildItem(HTREEITEM hRoot, const CString &strTe // used to display the + symbol next to each item itInsert.item.cChildren = HasSubdirectories(strDir) ? I_CHILDRENCALLBACK : 0; - itInsert.item.pszText = const_cast((LPCTSTR)strText); - itInsert.hInsertAfter = hRoot ? TVI_SORT : TVI_LAST; - itInsert.hParent = hRoot; - // START: added by FoRcHa //////////////// - UINT nType = GetDriveType(strDir); + UINT nType = ::GetDriveType(strDir); if (DRIVE_REMOVABLE <= nType && nType <= DRIVE_RAMDISK) itInsert.item.iImage = nType; SHFILEINFO shFinfo; shFinfo.szDisplayName[0] = _T('\0'); - if (!SHGetFileInfo(strDir, 0, &shFinfo, sizeof(shFinfo), - SHGFI_ICON | SHGFI_SMALLICON | SHGFI_DISPLAYNAME)) { + if (!::SHGetFileInfo(strDir, 0, &shFinfo, sizeof(shFinfo), SHGFI_ICON | SHGFI_SMALLICON | SHGFI_DISPLAYNAME)) { TRACE(_T("Error getting SystemFileInfo!")); itInsert.itemex.iImage = 0; // :( } else { @@ -264,8 +252,7 @@ HTREEITEM CDirectoryTreeCtrl::AddChildItem(HTREEITEM hRoot, const CString &strTe } } - if (!SHGetFileInfo(strDir, 0, &shFinfo, sizeof(shFinfo), - SHGFI_ICON | SHGFI_OPENICON | SHGFI_SMALLICON)) { + if (!::SHGetFileInfo(strDir, 0, &shFinfo, sizeof(shFinfo), SHGFI_ICON | SHGFI_OPENICON | SHGFI_SMALLICON)) { TRACE(_T("Error Getting SystemFileInfo!")); itInsert.itemex.iImage = 0; } else { @@ -286,22 +273,19 @@ CString CDirectoryTreeCtrl::GetFullPath(HTREEITEM hItem) CString strDir; for (HTREEITEM hSearchItem = hItem; hSearchItem != NULL; hSearchItem = GetParentItem(hSearchItem)) { const STreeItem *pti = reinterpret_cast(GetItemData(hSearchItem)); - const CString &strSearchItemDir(pti ? pti->strPath : GetItemText(hSearchItem)); - strDir = strSearchItemDir + _T('\\') + strDir; + strDir.Insert(0, _T('\\')); //trailing backslash + strDir.Insert(0, pti ? pti->strPath : GetItemText(hSearchItem)); } return strDir; } void CDirectoryTreeCtrl::AddSubdirectories(HTREEITEM hRoot, const CString &strDir) { - CString sDir(strDir); - slosh(sDir); - + ASSERT(strDir.Right(1) == _T("\\")); CFileFind finder; - BOOL bWorking = finder.FindFile(sDir + _T("*.*")); - while (bWorking) { - bWorking = finder.FindNextFile(); - if (!finder.IsDots() && !finder.IsSystem() && finder.IsDirectory()) { + for (BOOL bFound = finder.FindFile(strDir + _T("*.*")); bFound;) { + bFound = finder.FindNextFile(); + if (finder.IsDirectory() && !finder.IsDots() && !finder.IsSystem()) { CString strFilename(finder.GetFileName()); int i = strFilename.ReverseFind(_T('\\')); if (i >= 0) @@ -309,41 +293,16 @@ void CDirectoryTreeCtrl::AddSubdirectories(HTREEITEM hRoot, const CString &strDi AddChildItem(hRoot, strFilename); } } - finder.Close(); } bool CDirectoryTreeCtrl::HasSubdirectories(const CString &strDir) { - CString sDir(strDir); - slosh(sDir); - - // Never try to enumerate the files of a drive and thus physically access the drive, just - // get the information whether the drive has subdirectories in the root folder. Depending - // on the physical drive type (floppy disk, CD-ROM drive, etc.) this creates an annoying - // physical access to that drive - which is to be avoided always. Even Windows - // Explorer shows all drives by default with a '+' sign (which means that the user has - // to explicitly open the drive to really get the content) - and that approach will be fine - // for eMule as well. - // Since the restriction for drives 'A:' and 'B:' was removed, this gets more important now. - if (PathIsRoot(sDir)) - return true; - CFileFind finder; - BOOL bWorking = finder.FindFile(sDir + _T("*.*")); - while (bWorking) { - bWorking = finder.FindNextFile(); - if (!finder.IsDots() && !finder.IsSystem() && finder.IsDirectory()) { - finder.Close(); - return true; - } - } - finder.Close(); - return false; + return ::HasSubdirectories(strDir); } void CDirectoryTreeCtrl::GetSharedDirectories(CStringList &list) { - for (POSITION pos = m_lstShared.GetHeadPosition(); pos != NULL;) - list.AddTail(m_lstShared.GetNext(pos)); + list.AddTail(&m_lstShared); } void CDirectoryTreeCtrl::SetSharedDirectories(CStringList &list) @@ -352,20 +311,35 @@ void CDirectoryTreeCtrl::SetSharedDirectories(CStringList &list) for (POSITION pos = list.GetHeadPosition(); pos != NULL;) { const CString &sDir(list.GetNext(pos)); - if (!::PathIsUNC(sDir)) - m_lstShared.AddTail(sDir); + m_lstShared.AddTail(sDir); + if (::PathIsUNC(sDir)) { + const CString &sShare(GetShareName(sDir)); + INT_PTR i = m_lstUNC.GetCount(); + if (!i) { + m_lstUNC.Add(sShare); + continue; + } + while (--i >= 0) { + int cmp = sShare.CompareNoCase(m_lstUNC[i]); + if (cmp >= 0) { + if (cmp) + m_lstUNC.InsertAt(i + 1, sShare); + break; + } + } + } } Init(); } bool CDirectoryTreeCtrl::HasSharedSubdirectory(const CString &strDir) { - CString sDir(strDir); - sDir.MakeLower(); - slosh(sDir); + int iLen = strDir.GetLength(); + ASSERT(iLen > 0); + bool bSlosh = (strDir[iLen - 1] == _T('\\')); for (POSITION pos = m_lstShared.GetHeadPosition(); pos != NULL;) { - CString str(m_lstShared.GetNext(pos)); - if (str.MakeLower().Find(sDir) == 0 && sDir != str) + const CString &sDir(m_lstShared.GetNext(pos)); + if (_tcsnicmp(sDir, strDir, iLen) == 0 && iLen < sDir.GetLength() && (bSlosh || sDir[iLen] == _T('\\'))) return true; } return false; @@ -385,43 +359,37 @@ void CDirectoryTreeCtrl::CheckChanged(HTREEITEM hItem, bool bChecked) bool CDirectoryTreeCtrl::IsShared(const CString &strDir) { - CString sDir(strDir); - unslosh(sDir); - for (POSITION pos = m_lstShared.GetHeadPosition(); pos != NULL; ) { - CString str = m_lstShared.GetNext(pos); - unslosh(str); - if (str.CompareNoCase(sDir) == 0) + for (POSITION pos = m_lstShared.GetHeadPosition(); pos != NULL;) + if (EqualPaths(m_lstShared.GetNext(pos), strDir)) return true; - } + return false; } void CDirectoryTreeCtrl::AddShare(const CString &strDir) { - CString sDir(strDir); - slosh(sDir); - if (!IsShared(sDir) && sDir.CompareNoCase(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)) != 0) - m_lstShared.AddTail(sDir); + ASSERT(strDir.Right(1) == _T('\\')); + if (!IsShared(strDir) && thePrefs.IsShareableDirectory(strDir)) + m_lstShared.AddTail(strDir); } void CDirectoryTreeCtrl::DelShare(const CString &strDir) { - CString sDir(strDir); - slosh(sDir); - for (POSITION pos = m_lstShared.GetHeadPosition(); pos != NULL; ) { + ASSERT(strDir.Right(1) == _T('\\')); + for (POSITION pos = m_lstShared.GetHeadPosition(); pos != NULL;) { POSITION pos2 = pos; - if (m_lstShared.GetNext(pos).CompareNoCase(sDir) == 0) + if (EqualPaths(m_lstShared.GetNext(pos), strDir)) { m_lstShared.RemoveAt(pos2); + break; + } } } void CDirectoryTreeCtrl::UpdateParentItems(HTREEITEM hChild) { - HTREEITEM hSearch = GetParentItem(hChild); - while (hSearch != NULL) { + HTREEITEM hSearch = hChild; + while ((hSearch = GetParentItem(hSearch)) != NULL) SetItemState(hSearch, (HasSharedSubdirectory(GetFullPath(hSearch)) ? TVIS_BOLD : 0), TVIS_BOLD); - hSearch = GetParentItem(hSearch); - } } void CDirectoryTreeCtrl::OnContextMenu(CWnd*, CPoint point) @@ -458,25 +426,23 @@ void CDirectoryTreeCtrl::OnContextMenu(CWnd*, CPoint point) bool bMenuIsEmpty = true; // add all shared directories - int iCnt = 0; + UINT_PTR iCnt = 0; + const CString &sView1(GetResString(IDS_VIEW1)); + CString sViewPath; for (POSITION pos = m_lstShared.GetHeadPosition(); pos != NULL; ++iCnt) { - CString strDisplayPath(m_lstShared.GetNext(pos)); - PathRemoveBackslash(strDisplayPath.GetBuffer(strDisplayPath.GetLength())); - strDisplayPath.ReleaseBuffer(); - SharedMenu.AppendMenu(MF_STRING, MP_SHAREDFOLDERS_FIRST + iCnt, GetResString(IDS_VIEW1) + strDisplayPath); + sViewPath.Format(_T("%s%s"), (LPCTSTR)sView1, (LPCTSTR)m_lstShared.GetNext(pos)); + SharedMenu.AppendMenu(MF_STRING, MP_SHAREDFOLDERS_FIRST + iCnt, sViewPath); bMenuIsEmpty = false; } // add right clicked folder, if any if (hItem) { - m_strLastRightClicked = GetFullPath(hItem); + m_strLastRightClicked = GetFullPath(hItem); //trailing backslash if (!IsShared(m_strLastRightClicked)) { - CString strDisplayPath(m_strLastRightClicked); - PathRemoveBackslash(strDisplayPath.GetBuffer(strDisplayPath.GetLength())); - strDisplayPath.ReleaseBuffer(); + sViewPath.Format(_T("%s%s%s"), (LPCTSTR)sView1, (LPCTSTR)m_strLastRightClicked, (LPCTSTR)GetResString(IDS_VIEW2)); if (!bMenuIsEmpty) SharedMenu.AppendMenu(MF_SEPARATOR); - SharedMenu.AppendMenu(MF_STRING, MP_SHAREDFOLDERS_FIRST - 1, GetResString(IDS_VIEW1) + strDisplayPath + GetResString(IDS_VIEW2)); + SharedMenu.AppendMenu(MF_STRING, MP_SHAREDFOLDERS_FIRST - 1, sViewPath); bMenuIsEmpty = false; } } diff --git a/srchybrid/DirectoryTreeCtrl.h b/srchybrid/DirectoryTreeCtrl.h index eb73cfe1..22b8fbf1 100644 --- a/srchybrid/DirectoryTreeCtrl.h +++ b/srchybrid/DirectoryTreeCtrl.h @@ -10,6 +10,11 @@ class CDirectoryTreeCtrl : public CTreeCtrl DECLARE_DYNAMIC(CDirectoryTreeCtrl) public: + // construction / destruction + CDirectoryTreeCtrl() = default; + virtual ~CDirectoryTreeCtrl(); + virtual BOOL OnCommand(WPARAM wParam, LPARAM); + // initialize control void Init(); // get all shared directories @@ -18,7 +23,6 @@ class CDirectoryTreeCtrl : public CTreeCtrl void SetSharedDirectories(CStringList &list); private: - CImageList m_image; // add a new item HTREEITEM AddChildItem(HTREEITEM hRoot, const CString &strText); // add subdirectory items @@ -26,7 +30,7 @@ class CDirectoryTreeCtrl : public CTreeCtrl // return the full path of an item (like C:\abc\somewhere\inheaven\) CString GetFullPath(HTREEITEM hItem); // returns true if strDir has at least one subdirectory - bool HasSubdirectories(const CString &strDir); + static bool HasSubdirectories(const CString &strDir); // check status of an item has changed void CheckChanged(HTREEITEM hItem, bool bChecked); // returns true if a subdirectory of strDir is shared @@ -41,15 +45,11 @@ class CDirectoryTreeCtrl : public CTreeCtrl void DelShare(const CString &strDir); void MarkChildren(HTREEITEM hChild, bool mark); + CImageList m_images; CStringList m_lstShared; + CStringArray m_lstUNC; CString m_strLastRightClicked; - bool m_bSelectSubDirs; - -public: - // construction / destruction - CDirectoryTreeCtrl(); - virtual ~CDirectoryTreeCtrl(); - virtual BOOL OnCommand(WPARAM wParam, LPARAM); +// bool m_bSelectSubDirs; protected: DECLARE_MESSAGE_MAP() diff --git a/srchybrid/DownloadClient.cpp b/srchybrid/DownloadClient.cpp index 39c17f03..7572d226 100644 --- a/srchybrid/DownloadClient.cpp +++ b/srchybrid/DownloadClient.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -18,7 +18,6 @@ #include "emule.h" #include "UpDownClient.h" #include "PartFile.h" -#include "OtherFunctions.h" #include "ListenSocket.h" #include "PeerCacheSocket.h" #include "Preferences.h" @@ -63,8 +62,7 @@ void CUpDownClient::DrawStatusBar(CDC *dc, const CRect &rect, bool onlygreyrect, if (m_reqfile) { s_StatusBar.SetFileSize(m_reqfile->GetFileSize()); - s_StatusBar.SetHeight(rect.Height()); - s_StatusBar.SetWidth(rect.Width()); + s_StatusBar.SetRect(rect); s_StatusBar.Fill(crNeither); if (!onlygreyrect && m_abyPartStatus) { @@ -89,34 +87,34 @@ void CUpDownClient::DrawStatusBar(CDC *dc, const CRect &rect, bool onlygreyrect, crNextPending = RGB(255, 208, 0); } - char *pcNextPendingBlks = NULL; + char *pcNextPendingBlks; if (m_eDownloadState == DS_DOWNLOADING) { - pcNextPendingBlks = new char[m_nPartCount]; - memset(pcNextPendingBlks, 'N', m_nPartCount); // do not use '_strnset' for uninitialized memory! + pcNextPendingBlks = new char[m_nPartCount]{}; for (POSITION pos = m_PendingBlocks_list.GetHeadPosition(); pos != NULL;) { UINT uPart = (UINT)(m_PendingBlocks_list.GetNext(pos)->block->StartOffset / PARTSIZE); if (uPart < m_nPartCount) - pcNextPendingBlks[uPart] = 'Y'; + pcNextPendingBlks[uPart] = 1; } - } + } else + pcNextPendingBlks = NULL; - for (UINT i = 0; i < m_nPartCount; ++i) { + for (UINT i = 0; i < m_nPartCount; ++i) if (m_abyPartStatus[i]) { uint64 uBegin = PARTSIZE * i; uint64 uEnd = min(uBegin + PARTSIZE, (uint64)m_reqfile->GetFileSize()); COLORREF colour; - if (m_reqfile->IsComplete(uBegin, uEnd - 1, false)) + if (m_reqfile->IsComplete(uBegin, uEnd - 1)) colour = crBoth; else if (m_eDownloadState == DS_DOWNLOADING && GetSessionDown() && m_nLastBlockOffset >= uBegin && m_nLastBlockOffset < uEnd) colour = crPending; - else if (pcNextPendingBlks != NULL && pcNextPendingBlks[i] == 'Y') + else if (pcNextPendingBlks && pcNextPendingBlks[i]) colour = crNextPending; else colour = crClientOnly; s_StatusBar.FillRange(uBegin, uEnd, colour); } - } + delete[] pcNextPendingBlks; } } else @@ -133,7 +131,7 @@ bool CUpDownClient::Compare(const CUpDownClient *tocomp, bool bIgnoreUserhash) c if (HasLowID()) { //User is firewalled. Must do two checks. if (GetIP() != 0 && GetIP() == tocomp->GetIP()) { - //The IP of both match + //Both IPs match if (GetUserPort() != 0 && GetUserPort() == tocomp->GetUserPort()) //IP-UserPort matches return true; @@ -144,7 +142,7 @@ bool CUpDownClient::Compare(const CUpDownClient *tocomp, bool bIgnoreUserhash) c if (GetUserIDHybrid() != 0 && GetUserIDHybrid() == tocomp->GetUserIDHybrid() && GetServerIP() != 0 && GetServerIP() == tocomp->GetServerIP() && GetServerPort() != 0 && GetServerPort() == tocomp->GetServerPort()) - { //Both have the same lowID, serverIP and Port. + { //Both have the same lowID, server IP and port. return true; } #if defined(_DEBUG) @@ -154,7 +152,6 @@ bool CUpDownClient::Compare(const CUpDownClient *tocomp, bool bIgnoreUserhash) c return true; } #endif - //Both IP, and Server do not match. return false; } @@ -186,29 +183,33 @@ bool CUpDownClient::AskForDownload() theApp.downloadqueue->AddFailedUDPFileReasks(); m_bUDPPending = false; } - if (!(socket && socket->IsConnected())) { // already connected, skip all the special checks + if (socket && socket->IsConnected()) // already connected, skip all the special checks + SetLastTriedToConnectTime(); + else { if (theApp.listensocket->TooManySockets()) { if (GetDownloadState() != DS_TOOMANYCONNS) SetDownloadState(DS_TOOMANYCONNS); return true; } - m_dwLastTriedToConnect = ::GetTickCount(); - // if it's a lowid client which is on our queue we may delay the re-ask up to 20 min - // to give the lowid a chance to connect to us with its own re-ask - if (HasLowID() && GetUploadState() == US_ONUPLOADQUEUE && !m_bReaskPending && GetLastAskedTime() > 0) { - SetDownloadState(DS_ONQUEUE); - m_bReaskPending = true; - return true; - } - // if we are lowid <-> lowid but contacted the source before already, keep it in the hope that we might turn highid again - if (HasLowID() && !theApp.CanDoCallback(this) && GetLastAskedTime() > 0) { - if (GetDownloadState() != DS_LOWTOLOWIP) - SetDownloadState(DS_LOWTOLOWIP); - m_bReaskPending = true; - return true; + SetLastTriedToConnectTime(); + + if (HasLowID() && GetLastAskedTime() > 0) { + // if it's a lowid client which is on our queue we may delay the re-ask up to 20 min + // to give the lowid a chance to connect to us with its own re-ask + if (GetUploadState() == US_ONUPLOADQUEUE && !m_bReaskPending) { + SetDownloadState(DS_ONQUEUE); + m_bReaskPending = true; + return true; + } + // if we are lowid <-> lowid but contacted the source before already, keep it in the hope that we might turn highid again + if (!theApp.CanDoCallback(this)) { + if (GetDownloadState() != DS_LOWTOLOWIP) + SetDownloadState(DS_LOWTOLOWIP); + m_bReaskPending = true; + return true; + } } - } else - m_dwLastTriedToConnect = ::GetTickCount(); + } SwapToAnotherFile(_T("A4AF check before TCP file re-ask. CUpDownClient::AskForDownload()"), true, false, false, NULL, true, true); SetDownloadState(DS_CONNECTING); return TryToConnect(); @@ -221,10 +222,10 @@ bool CUpDownClient::IsSourceRequestAllowed() const bool CUpDownClient::IsSourceRequestAllowed(CPartFile *partfile, bool sourceExchangeCheck) const { - DWORD dwTickCount = ::GetTickCount() + CONNECTION_LATENCY; - DWORD nTimePassedClient = dwTickCount - GetLastAskedForSources(); //was GetLastSrcAnswerTime(); - DWORD nTimePassedFile = dwTickCount - partfile->GetLastAnsweredTime(); - bool bNeverAskedBefore = GetLastAskedForSources() == 0; + DWORD dwTicks = ::GetTickCount() + CONNECTION_LATENCY; + DWORD nTimePassedClient = dwTicks - GetLastAskedForSources(); //was GetLastSrcAnswerTime(); + DWORD nTimePassedFile = dwTicks - partfile->GetLastAnsweredTime(); + bool bNeverAskedBefore = (GetLastAskedForSources() == 0); UINT uSources = partfile->GetSourceCount(); UINT uValidSources = partfile->GetValidSourcesCount(); @@ -257,8 +258,8 @@ bool CUpDownClient::IsSourceRequestAllowed(CPartFile *partfile, bool sourceExcha ) // OR if file is not rare || - ((bNeverAskedBefore || nTimePassedClient > (DWORD)(SOURCECLIENTREASKS * MINCOMMONPENALTY)) - && (nTimePassedFile > (DWORD)(SOURCECLIENTREASKF * MINCOMMONPENALTY)) + ((bNeverAskedBefore || nTimePassedClient > SOURCECLIENTREASKS * MINCOMMONPENALTY) + && (nTimePassedFile > SOURCECLIENTREASKF * MINCOMMONPENALTY) && (!sourceExchangeCheck || partfile == m_reqfile || (uValidSources < SOURCECLIENTREASKS / SOURCECLIENTREASKF && uValidSources < uReqValidSources)) ) ); @@ -269,37 +270,37 @@ void CUpDownClient::SendFileRequest() // normally asktime has already been reset here, and SwapToAnotherFile will return without much work, so check to make sure SwapToAnotherFile(_T("A4AF check before TCP file re-ask. CUpDownClient::SendFileRequest()"), true, false, false, NULL, true, true); - ASSERT(m_reqfile != NULL); - if (!m_reqfile) + if (!m_reqfile) { + ASSERT(0); return; - AddAskedCountDown(); + } + IncrementAskedCountDown(); if (SupportMultiPacket() || SupportsFileIdentifiers()) { CSafeMemFile dataFileReq(96); + LPCSTR pDebug; if (SupportsFileIdentifiers()) { - m_reqfile->GetFileIdentifier().WriteIdentifier(&dataFileReq); - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_MultiPacket_Ext2", this, m_reqfile->GetFileHash()); + m_reqfile->GetFileIdentifier().WriteIdentifier(dataFileReq); + pDebug = "OP_MultiPacket_Ext2"; } else { dataFileReq.WriteHash16(m_reqfile->GetFileHash()); if (SupportExtMultiPacket()) { dataFileReq.WriteUInt64(m_reqfile->GetFileSize()); - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_MultiPacket_Ext", this, m_reqfile->GetFileHash()); - } else { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_MultiPacket", this, m_reqfile->GetFileHash()); - } + pDebug = "OP_MultiPacket_Ext"; + } else + pDebug = "OP_MultiPacket"; } + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugSend(pDebug, this, m_reqfile->GetFileHash()); // OP_REQUESTFILENAME + ExtInfo if (thePrefs.GetDebugClientTCPLevel() > 0) DebugSend("OP_MPReqFileName", this, m_reqfile->GetFileHash()); dataFileReq.WriteUInt8(OP_REQUESTFILENAME); if (GetExtendedRequestsVersion() > 0) { - m_reqfile->WritePartStatus(&dataFileReq); + m_reqfile->WritePartStatus(dataFileReq); if (GetExtendedRequestsVersion() > 1) - m_reqfile->WriteCompleteSourcesCount(&dataFileReq); + m_reqfile->WriteCompleteSourcesCount(dataFileReq); } // OP_SETREQFILEID @@ -343,7 +344,7 @@ void CUpDownClient::SendFileRequest() dataFileReq.WriteUInt8(OP_AICHFILEHASHREQ); } - Packet *packet = new Packet(&dataFileReq, OP_EMULEPROT); + Packet *packet = new Packet(dataFileReq, OP_EMULEPROT); if (SupportsFileIdentifiers()) packet->opcode = OP_MULTIPACKET_EXT2; else if (SupportExtMultiPacket()) @@ -357,26 +358,27 @@ void CUpDownClient::SendFileRequest() dataFileReq.WriteHash16(m_reqfile->GetFileHash()); //This is extended information if (GetExtendedRequestsVersion() > 0) { - m_reqfile->WritePartStatus(&dataFileReq); + m_reqfile->WritePartStatus(dataFileReq); if (GetExtendedRequestsVersion() > 1) - m_reqfile->WriteCompleteSourcesCount(&dataFileReq); + m_reqfile->WriteCompleteSourcesCount(dataFileReq); } if (thePrefs.GetDebugClientTCPLevel() > 0) DebugSend("OP_FileRequest", this, m_reqfile->GetFileHash()); - Packet *packet = new Packet(&dataFileReq); + Packet *packet = new Packet(dataFileReq); packet->opcode = OP_REQUESTFILENAME; theStats.AddUpDataOverheadFileRequest(packet->size); SendPacket(packet); - // 26-Jul-2003: removed requesting the file status for files <= PARTSIZE for better compatibility with ed2k protocol (eDonkeyHybrid). - // if the remote client answers the OP_REQUESTFILENAME with OP_REQFILENAMEANSWER the file is shared by the remote client. if we - // know that the file is shared, we know also that the file is complete and don't need to request the file status. + // 26-Jul-2003: removed requesting the file status for files <= PARTSIZE for better compatibility + // with ed2k protocol (eDonkeyHybrid). if the remote client answers the OP_REQUESTFILENAME + // with OP_REQFILENAMEANSWER the file is shared by the remote client. if we know that the file + // is shared, we know also that the file is complete and don't need to request the file status. if (m_reqfile->GetPartCount() > 1) { if (thePrefs.GetDebugClientTCPLevel() > 0) DebugSend("OP_SetReqFileID", this, m_reqfile->GetFileHash()); CSafeMemFile dataSetReqFileID(16); dataSetReqFileID.WriteHash16(m_reqfile->GetFileHash()); - packet = new Packet(&dataSetReqFileID); + packet = new Packet(dataSetReqFileID); packet->opcode = OP_SETREQFILEID; theStats.AddUpDataOverheadFileRequest(packet->size); SendPacket(packet); @@ -440,7 +442,7 @@ void CUpDownClient::SendStartupLoadReq() DebugSend("OP_StartupLoadReq", this); CSafeMemFile dataStartupLoadReq(16); dataStartupLoadReq.WriteHash16(m_reqfile->GetFileHash()); - Packet *packet = new Packet(&dataStartupLoadReq); + Packet *packet = new Packet(dataStartupLoadReq); packet->opcode = OP_STARTUPLOADREQ; theStats.AddUpDataOverheadFileRequest(packet->size); SetDownloadState(DS_ONQUEUE); @@ -464,9 +466,10 @@ void CUpDownClient::ProcessFileInfo(CSafeMemFile *data, CPartFile *file) m_strClientFilename = data->ReadString(GetUnicodeSupport() != UTF8strNone); if (thePrefs.GetDebugClientTCPLevel() > 0) Debug(_T(" Filename=\"%s\"\n"), (LPCTSTR)m_strClientFilename); - // 26-Jul-2003: removed requesting the file status for files <= PARTSIZE for better compatibility with ed2k protocol (eDonkeyHybrid). - // if the remote client answers the OP_REQUESTFILENAME with OP_REQFILENAMEANSWER the file is shared by the remote client. if we - // know that the file is shared, we know also that the file is complete and don't need to request the file status. + // 26-Jul-2003: removed requesting the file status for files <= PARTSIZE for better compatibility with + // ed2k protocol (eDonkeyHybrid). If the remote client answers the OP_REQUESTFILENAME with OP_REQFILENAMEANSWER + // the file is shared by the remote client. If the file is shared, we know also that the file + // is complete and don't need to request the file status. if (m_reqfile->GetPartCount() == 1) { delete[] m_abyPartStatus; m_abyPartStatus = NULL; @@ -478,8 +481,8 @@ void CUpDownClient::ProcessFileInfo(CSafeMemFile *data, CPartFile *file) if (thePrefs.GetDebugClientTCPLevel() > 0) { int iNeeded = 0; char *psz = new char[m_nPartCount + 1]; - for (uint16 i = 0; i < m_nPartCount; ++i) { - iNeeded += static_cast(!m_reqfile->IsComplete(i, false)); + for (UINT i = 0; i < m_nPartCount; ++i) { + iNeeded += static_cast(!m_reqfile->IsComplete(i)); psz[i] = m_abyPartStatus[i] ? '#' : '.'; } psz[m_nPartCount] = '\0'; @@ -524,9 +527,9 @@ void CUpDownClient::ProcessFileStatus(bool bUdpPacket, CSafeMemFile *data, CPart return; m_abyPartStatus = new uint8[m_nPartCount]; memset(m_abyPartStatus, 1, m_nPartCount); - if (bUdpPacket ? (thePrefs.GetDebugClientUDPLevel() > 0) : (thePrefs.GetDebugClientTCPLevel() > 0)) - for (uint16 i = 0; i < m_nPartCount; ++i) - iNeeded += static_cast(!m_reqfile->IsComplete(i, false)); + if ((bUdpPacket ? thePrefs.GetDebugClientUDPLevel() : thePrefs.GetDebugClientTCPLevel()) > 0) + for (UINT i = 0; i < m_nPartCount; ++i) + iNeeded += static_cast(!m_reqfile->IsComplete(i)); } else { if (m_reqfile->GetED2KPartCount() != nED2KPartCount) { if (thePrefs.GetVerbose()) { @@ -541,25 +544,21 @@ void CUpDownClient::ProcessFileStatus(bool bUdpPacket, CSafeMemFile *data, CPart m_nPartCount = m_reqfile->GetPartCount(); m_abyPartStatus = new uint8[m_nPartCount]; - for (uint16 done = 0; done != m_nPartCount;) { + for (UINT done = 0; done < m_nPartCount;) { uint8 toread = data->ReadUInt8(); - for (UINT i = 0; i != 8; ++i) { + for (UINT i = 0; i < 8 && done < m_nPartCount; ++i) { m_abyPartStatus[done] = (toread >> i) & 1; - if (m_abyPartStatus[done] && !m_reqfile->IsComplete(done, false)) { - bPartsNeeded = true; - ++iNeeded; - } - - if (++done >= m_nPartCount) - break; + iNeeded += static_cast(m_abyPartStatus[done] && !m_reqfile->IsComplete(done)); + ++done; } } + bPartsNeeded = (iNeeded > 0); } // NOTE: This function is invoked for TCP and UDP sockets! - if (bUdpPacket ? (thePrefs.GetDebugClientUDPLevel() > 0) : (thePrefs.GetDebugClientTCPLevel() > 0)) { + if ((bUdpPacket ? thePrefs.GetDebugClientUDPLevel() : thePrefs.GetDebugClientTCPLevel()) > 0) { TCHAR *psz = new TCHAR[m_nPartCount + 1]; - for (uint16 i = 0; i < m_nPartCount; ++i) + for (UINT i = 0; i < m_nPartCount; ++i) psz[i] = m_abyPartStatus[i] ? _T('#') : _T('.'); psz[m_nPartCount] = _T('\0'); Debug(_T(" Parts=%hu %s Needed=%i\n"), m_nPartCount, psz, iNeeded); @@ -570,12 +569,9 @@ void CUpDownClient::ProcessFileStatus(bool bUdpPacket, CSafeMemFile *data, CPart m_reqfile->UpdateAvailablePartsCount(); if (bUdpPacket) { - if (bPartsNeeded) - SetDownloadState(DS_ONQUEUE); - else { - SetDownloadState(DS_NONEEDEDPARTS); - //SwapToAnotherFile(_T("A4AF for NNP file. CUpDownClient::ProcessFileStatus() UDP"), true, false, false, NULL, true, false); - } + SetDownloadState(bPartsNeeded ? DS_ONQUEUE : DS_NONEEDEDPARTS); + //if (!bPartsNeeded) + // SwapToAnotherFile(_T("A4AF for NNP file. CUpDownClient::ProcessFileStatus() UDP"), true, false, false, NULL, true, false); } else { if (!bPartsNeeded) { SetDownloadState(DS_NONEEDEDPARTS); @@ -594,27 +590,30 @@ bool CUpDownClient::AddRequestForAnotherFile(CPartFile *file) { if (m_OtherNoNeeded_list.Find(file) || m_OtherRequests_list.Find(file)) return false; + m_OtherRequests_list.AddTail(file); file->A4AFsrclist.AddTail(this); // [enkeyDEV(Ottavio84) -A4AF-] - return true; } -void CUpDownClient::ClearDownloadBlockRequests() +void CUpDownClient::ClearPendingBlockRequest(const Pending_Block_Struct *pending) { - while (!m_PendingBlocks_list.IsEmpty()) { - const Pending_Block_Struct *pending = m_PendingBlocks_list.RemoveHead(); - if (m_reqfile) - m_reqfile->RemoveBlockFromList(pending->block->StartOffset, pending->block->EndOffset); - - delete pending->block; - // Not always allocated - if (pending->zStream) { - inflateEnd(pending->zStream); - delete pending->zStream; - } - delete pending; + if (m_reqfile) + m_reqfile->RemoveBlockFromList(pending->block->StartOffset, pending->block->EndOffset); + + delete pending->block; + // Not always allocated + if (pending->zStream) { + inflateEnd(pending->zStream); + delete pending->zStream; } + delete pending; +} + +void CUpDownClient::ClearDownloadBlockRequests() +{ + while (!m_PendingBlocks_list.IsEmpty()) + ClearPendingBlockRequest(m_PendingBlocks_list.RemoveHead()); } void CUpDownClient::SetDownloadState(EDownloadState nNewState, LPCTSTR pszReason) @@ -622,7 +621,7 @@ void CUpDownClient::SetDownloadState(EDownloadState nNewState, LPCTSTR pszReason if (m_eDownloadState != nNewState) { switch (nNewState) { case DS_CONNECTING: - m_dwLastTriedToConnect = ::GetTickCount(); + SetLastTriedToConnectTime(); break; case DS_TOOMANYCONNSKAD: //This client had already been set to DS_CONNECTING. @@ -644,15 +643,6 @@ void CUpDownClient::SetDownloadState(EDownloadState nNewState, LPCTSTR pszReason // If we set this, we will not re-ask for that file until some time has passed. SetLastAskedTime(); //DontSwapTo(m_reqfile); - - /*default: - switch( m_nDownloadState ) { - case DS_WAITCALLBACK: - case DS_WAITCALLBACKKAD: - break; - default: - m_dwLastTriedToConnect = ::GetTickCount() - MIN2MS(20); - }*/ } if (m_reqfile) { @@ -714,6 +704,7 @@ void CUpDownClient::SetDownloadState(EDownloadState nNewState, LPCTSTR pszReason socket->DisableDownloadLimit(); } else m_eDownloadState = nNewState; + if (GetDownloadState() == DS_DOWNLOADING) { if (IsEmuleClient()) SetRemoteQueueFull(false); @@ -726,24 +717,25 @@ void CUpDownClient::SetDownloadState(EDownloadState nNewState, LPCTSTR pszReason void CUpDownClient::ProcessHashSet(const uchar *packet, uint32 size, bool bFileIdentifiers) { - if (!m_fHashsetRequestingMD4) + if (!m_fHashsetRequestingMD4) { if (!bFileIdentifiers) - throw CString(_T("unrequested hashset")); - else if (!m_fHashsetRequestingAICH) - throw CString(_T("unrequested hashset2")); + throwCStr(_T("unrequested hashset")); + if (!m_fHashsetRequestingAICH) + throwCStr(_T("unrequested hashset2")); + } CSafeMemFile data(packet, size); if (bFileIdentifiers) { CFileIdentifierSA fileIdent; - if (!fileIdent.ReadIdentifier(&data)) - throw CString(_T("Invalid FileIdentifier")); + if (!fileIdent.ReadIdentifier(data)) + throwCStr(_T("Invalid FileIdentifier")); if (m_reqfile == NULL || !m_reqfile->GetFileIdentifier().CompareRelaxed(fileIdent)) { CheckFailedFileIdReqs(packet); throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (ProcessHashSet2)"); } bool bMD4 = m_fHashsetRequestingMD4 != 0; bool bAICH = m_fHashsetRequestingAICH != 0; - if (!m_reqfile->GetFileIdentifier().ReadHashSetsFromPacket(&data, bMD4, bAICH)) { + if (!m_reqfile->GetFileIdentifier().ReadHashSetsFromPacket(data, bMD4, bAICH)) { if (m_fHashsetRequestingMD4) m_reqfile->m_bMD4HashsetNeeded = true; if (m_fHashsetRequestingAICH) @@ -768,11 +760,11 @@ void CUpDownClient::ProcessHashSet(const uchar *packet, uint32 size, bool bFileI m_reqfile->SetAICHHashSetNeeded(true); } } else { - if ((!m_reqfile) || !md4equ(packet, m_reqfile->GetFileHash())) { + if (!m_reqfile || !md4equ(packet, m_reqfile->GetFileHash())) { CheckFailedFileIdReqs(packet); throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (ProcessHashSet)"); } - if (!m_reqfile->GetFileIdentifier().LoadMD4HashsetFromFile(&data, true)) { + if (!m_reqfile->GetFileIdentifier().LoadMD4HashsetFromFile(data, true)) { m_reqfile->m_bMD4HashsetNeeded = true; throw GetResString(IDS_ERR_BADHASHSET); } @@ -782,22 +774,24 @@ void CUpDownClient::ProcessHashSet(const uchar *packet, uint32 size, bool bFileI SendStartupLoadReq(); } -void CUpDownClient::CreateBlockRequests(int iMinBlocks, int iMaxBlocks) +void CUpDownClient::CreateBlockRequests(int blockCount) { - ASSERT(iMinBlocks >= 1 && iMaxBlocks >= iMinBlocks/*&& iMaxBlocks <= 3*/); + ASSERT(blockCount > 0 && blockCount <= 9); + //prevent uncontrolled growth + if ((int)m_PendingBlocks_list.GetCount() > 2 * blockCount) + return; + + //count out unprocessed blocks + for (POSITION pos = m_PendingBlocks_list.GetHeadPosition(); pos != NULL;) + blockCount -= static_cast(m_PendingBlocks_list.GetNext(pos)->fQueued == 0); - if (iMinBlocks <= m_PendingBlocks_list.GetCount()) + if (blockCount <= 0) return; - uint16 count = (uint16)(iMaxBlocks - m_PendingBlocks_list.GetCount()); - - Requested_Block_Struct **toadd = new Requested_Block_Struct*[count]; - if (m_reqfile->GetNextRequestedBlock(this, toadd, &count)) - for (UINT i = 0; i < count; ++i) { - Pending_Block_Struct *pblock = new Pending_Block_Struct; - pblock->block = toadd[i]; - m_PendingBlocks_list.AddTail(pblock); - ASSERT(m_PendingBlocks_list.GetCount() <= iMaxBlocks); - } + + Requested_Block_Struct **toadd = new Requested_Block_Struct*[blockCount]; + if (m_reqfile->GetNextRequestedBlock(this, toadd, blockCount)) + for (int i = 0; i < blockCount; ++i) + m_PendingBlocks_list.AddTail(new Pending_Block_Struct{ toadd[i] }); delete[] toadd; } @@ -808,26 +802,24 @@ void CUpDownClient::SendBlockRequests() if (!m_reqfile) return; - // prevent locking of too many blocks when we are on a slow (probably standby/trickle) slot - int blockCount = 3; // max pending block requests - int maxBlockDelta = 1; // blockcount - maxBlockDelta = minPendingBlockRequests - if (IsEmuleClient() && m_byCompatibleClient == 0 && m_reqfile->GetFileSize() - m_reqfile->GetCompletedSize() <= PARTSIZE * 4) { - // if there's less than two chunks left, request fewer blocks for - // slow downloads, so they don't lock blocks from faster clients. - // Only trust eMule clients to be able to handle less blocks than three - if (GetDownloadDatarate() < 600 || GetSessionPayloadDown() < 40 * 1024) { - blockCount = 1; - maxBlockDelta = 0; - } else if (GetDownloadDatarate() < 1200) { - blockCount = 2; - maxBlockDelta = 0; - } - } else if (GetDownloadDatarate() > 1024 * 75) { - blockCount = 6; - maxBlockDelta = 2; - } + // Fast uploader/slow downloader combination requires special treatment. + // + // For example, getting 360 KB (2 blocks) at 9 KB/s rate takes 40 seconds. + // An uploader with 100 Mbit/s connection delivers the data in a fraction of a second + // while downloader would be receiving the data long after. + // Should it be longer than 40 s, uploader will disconnect on time out. + + // Restrict the number of requested blocks when we are on a slow/standby/trickle slot or + // download is limited on our side. + int blockCount; // max pending block requests + if (IsEmuleClient() && m_byCompatibleClient == 0 && GetDownloadDatarate() < 9 * 1024) + blockCount = (GetDownloadDatarate() < 4 * 1024) ? 1 : 2; + else if (GetDownloadDatarate() > 75 * 1024) + blockCount = (GetDownloadDatarate() > 150 * 1024) ? 9 : 6; + else + blockCount = 3; - CreateBlockRequests(blockCount - maxBlockDelta, blockCount); + CreateBlockRequests(blockCount); if (m_PendingBlocks_list.IsEmpty()) { SendCancelTransfer(); SetDownloadState(DS_NONEEDEDPARTS); @@ -842,7 +834,7 @@ void CUpDownClient::SendBlockRequests() if (pending->fQueued) continue; ASSERT(pending->block->StartOffset <= pending->block->EndOffset); - if (pending->block->StartOffset > _UI32_MAX || pending->block->EndOffset >= _UI32_MAX) { + if (pending->block->EndOffset >= _UI32_MAX) { if (!SupportsLargeFiles()) { ASSERT(0); SendCancelTransfer(); @@ -855,13 +847,14 @@ void CUpDownClient::SendBlockRequests() if (listToRequest.GetCount() >= 3) break; } + if (!IsEmuleClient() && listToRequest.GetCount() < 3) { - for (POSITION pos = m_PendingBlocks_list.GetHeadPosition(); pos != NULL; ) { + for (POSITION pos = m_PendingBlocks_list.GetHeadPosition(); pos != NULL;) { Pending_Block_Struct *pending = m_PendingBlocks_list.GetNext(pos); if (!pending->fQueued) continue; ASSERT(pending->block->StartOffset <= pending->block->EndOffset); - if (pending->block->StartOffset > _UI32_MAX || pending->block->EndOffset >= _UI32_MAX) { + if (pending->block->EndOffset >= _UI32_MAX) { if (!SupportsLargeFiles()) { ASSERT(0); SendCancelTransfer(); @@ -875,153 +868,109 @@ void CUpDownClient::SendBlockRequests() break; } } else if (listToRequest.IsEmpty()) { - // do not re-request blocks, at least eMule clients don't need expect this to work properly so its - // just overhead (and its not protocol standard, but we used to do so since forever) - // by adding a range of min to max pending blocks this means we do not send a request after every received - // packet any more + // do not re-request blocks, at least eMule clients need not expect this to work properly + // so it's just overhead (and it's not protocol standard, but we used to do so since forever) + // by adding a range of min to max pending blocks + // this means we do not send a request after every received packet any more return; } - Packet *packet; - if (bI64Offsets) { - const int iPacketSize = 16 + (3 * 8) + (3 * 8); // 64 - packet = new Packet(OP_REQUESTPARTS_I64, iPacketSize, OP_EMULEPROT); - CSafeMemFile data((BYTE*)packet->pBuffer, iPacketSize); - data.WriteHash16(m_reqfile->GetFileHash()); - POSITION pos = listToRequest.GetHeadPosition(); - for (uint32 i = 0; i < 3; ++i) { - if (pos) { - Pending_Block_Struct *pending = listToRequest.GetNext(pos); - ASSERT(pending->block->StartOffset <= pending->block->EndOffset); - //ASSERT( pending->zStream == NULL ); - //ASSERT( pending->totalUnzipped == 0 ); - pending->fZStreamError = 0; - pending->fRecovered = 0; - pending->fQueued = 1; - data.WriteUInt64(pending->block->StartOffset); - } else - data.WriteUInt64(0); - } - pos = listToRequest.GetHeadPosition(); - for (uint32 i = 0; i < 3; ++i) { - if (pos) { - const Requested_Block_Struct *block = listToRequest.GetNext(pos)->block; - uint64 endpos = block->EndOffset + 1; - data.WriteUInt64(endpos); - if (thePrefs.GetDebugClientTCPLevel() > 0) { - CString strInfo; - strInfo.Format(_T(" Block request %u: %s"), i, (LPCTSTR)DbgGetBlockInfo(block)); - strInfo.AppendFormat(_T(", Complete=%s"), m_reqfile->IsComplete(block->StartOffset, block->EndOffset, false) ? _T("Yes(NOTE:)") : _T("No")); - strInfo.AppendFormat(_T(", PureGap=%s"), m_reqfile->IsPureGap(block->StartOffset, block->EndOffset) ? _T("Yes") : _T("No(NOTE:)")); - strInfo.AppendFormat(_T(", AlreadyReq=%s\n"), m_reqfile->IsAlreadyRequested(block->StartOffset, block->EndOffset) ? _T("Yes") : _T("No(NOTE:)")); - Debug(strInfo); - } - } else { - data.WriteUInt64(0); - if (thePrefs.GetDebugClientTCPLevel() > 0) - Debug(_T(" Block request %u: \n"), i); - } - } - } else { - const int iPacketSize = 16 + (3 * 4) + (3 * 4); // 40 - packet = new Packet(OP_REQUESTPARTS, iPacketSize); - CSafeMemFile data((BYTE*)packet->pBuffer, iPacketSize); - data.WriteHash16(m_reqfile->GetFileHash()); - POSITION pos = listToRequest.GetHeadPosition(); - for (uint32 i = 0; i < 3; ++i) { - if (pos) { - Pending_Block_Struct *pending = listToRequest.GetNext(pos); - ASSERT(pending->block->StartOffset <= pending->block->EndOffset); - //ASSERT( pending->zStream == NULL ); - //ASSERT( pending->totalUnzipped == 0 ); - pending->fZStreamError = 0; - pending->fRecovered = 0; - pending->fQueued = 1; - data.WriteUInt32((uint32)pending->block->StartOffset); - } else - data.WriteUInt32(0); - } - pos = listToRequest.GetHeadPosition(); - for (uint32 i = 0; i < 3; ++i) { - if (pos) { - const Requested_Block_Struct *block = listToRequest.GetNext(pos)->block; - uint64 endpos = block->EndOffset + 1; - data.WriteUInt32((uint32)endpos); - if (thePrefs.GetDebugClientTCPLevel() > 0) { - CString strInfo; - strInfo.Format(_T(" Block request %u: %s"), i, (LPCTSTR)DbgGetBlockInfo(block)); - strInfo.AppendFormat(_T(", Complete=%s"), m_reqfile->IsComplete(block->StartOffset, block->EndOffset, false) ? _T("Yes(NOTE:)") : _T("No")); - strInfo.AppendFormat(_T(", PureGap=%s"), m_reqfile->IsPureGap(block->StartOffset, block->EndOffset) ? _T("Yes") : _T("No(NOTE:)")); - strInfo.AppendFormat(_T(", AlreadyReq=%s\n"), m_reqfile->IsAlreadyRequested(block->StartOffset, block->EndOffset) ? _T("Yes") : _T("No(NOTE:)")); - Debug(strInfo); - } - } else { - data.WriteUInt32(0); - if (thePrefs.GetDebugClientTCPLevel() > 0) - Debug(_T(" Block request %u: \n"), i); - } + //Use this array to write all offsets in one pass + uint64 aOffs[3 * 2]; //0..2 - start points, 3..5 - end points + + POSITION pos = listToRequest.GetHeadPosition(); + for (int i = 0; i < 3; ++i) + if (pos) { + Pending_Block_Struct *pending = listToRequest.GetNext(pos); + ASSERT(pending->block->StartOffset <= pending->block->EndOffset); + pending->fZStreamError = 0; + pending->fRecovered = 0; + pending->fQueued = 1; + aOffs[i] = pending->block->StartOffset; + aOffs[i + 3] = pending->block->EndOffset + 1; + if (thePrefs.GetDebugClientTCPLevel() > 0) + Debug(_T(" Block request %d: %s, Complete=%s, PureGap=%s, AlreadyReq=%s\n") + , i + , (LPCTSTR)DbgGetBlockInfo(pending->block) + , m_reqfile->IsComplete(aOffs[i], aOffs[i + 3] - 1) ? _T("Yes(NOTE:)") : _T("No") + , m_reqfile->IsPureGap(aOffs[i], aOffs[i + 3] - 1) ? _T("Yes") : _T("No(NOTE:)") + , m_reqfile->IsAlreadyRequested(aOffs[i], aOffs[i + 3] - 1) ? _T("Yes") : _T("No(NOTE:)")); + } else { + aOffs[i] = aOffs[i + 3] = 0; + if (thePrefs.GetDebugClientTCPLevel() > 0) + Debug(_T(" Block request %d: \n"), i); } - } + + Packet *packet; + if (bI64Offsets) + packet = new Packet(OP_REQUESTPARTS_I64, 16 + (3 * 8) + (3 * 8), OP_EMULEPROT); //size 64 + else + packet = new Packet(OP_REQUESTPARTS, 16 + (3 * 4) + (3 * 4)); //size 40 + CSafeMemFile data((BYTE*)packet->pBuffer, packet->size); + data.WriteHash16(m_reqfile->GetFileHash()); + for (int i = 0; i < 3 * 2; ++i) + if (bI64Offsets) + data.WriteUInt64(aOffs[i]); + else + data.WriteUInt32((uint32)aOffs[i]); theStats.AddUpDataOverheadFileRequest(packet->size); if (thePrefs.GetDebugClientTCPLevel() > 0) DebugSend("OP_RequestParts", this, m_reqfile->GetFileHash()); SendPacket(packet, true); - // on highspeed downloads, we want this packet to get out asap, so wakeup the throttler if it is sleeping - // because there was nothing to send yet + // on high-speed downloads, we want this packet to get out ASAP, so wake up + // the throttler if it is sleeping because there was nothing to send yet theApp.uploadBandwidthThrottler->NewUploadDataAvailable(); } -/* Barry - Originally this only wrote to disk when a full 180k block - had been received from a client, and only asked for data in +/* Barry - Originally, this wrote to disk only when a full 180k block + had been received from a client, and asked for data only by 180k blocks. - This meant that on average 90k was lost for every connection + This means that on average 90k was lost for every connection to a client data source. That is a lot of wasted data. - To reduce the lost data, packets are now written to a buffer + To reduce data loss, packets are now written to a buffer and flushed to disk regularly regardless of size downloaded. This includes compressed packets. - Data is also requested only where gaps are, not in 180k blocks. + Data is also requested only where the gaps are, not in 180k blocks. The requests will still not exceed 180k, but may be smaller to fill a gap. */ void CUpDownClient::ProcessBlockPacket(const uchar *packet, uint32 size, bool packed, bool bI64Offsets) { if (!bI64Offsets) { - uint32 nDbgStartPos = *((uint32*)(packet + 16)); + uint32 nDbgStartPos = *(uint32*)&packet[16]; if (thePrefs.GetDebugClientTCPLevel() > 1) { if (packed) - Debug(_T(" Start=%u BlockSize=%u Size=%u %s\n"), nDbgStartPos, *((uint32*)(packet + 16 + 4)), size - 24, (LPCTSTR)DbgGetFileInfo(packet)); + Debug(_T(" Start=%u BlockSize=%u Size=%u %s\n"), nDbgStartPos, *(uint32*)&packet[16 + 4], size - 24, (LPCTSTR)DbgGetFileInfo(packet)); else - Debug(_T(" Start=%u End=%u Size=%u %s\n"), nDbgStartPos, *((uint32*)(packet + 16 + 4)), *((uint32*)(packet + 16 + 4)) - nDbgStartPos, (LPCTSTR)DbgGetFileInfo(packet)); + Debug(_T(" Start=%u End=%u Size=%u %s\n"), nDbgStartPos, *(uint32*)&packet[16 + 4], *(uint32*)&packet[16 + 4] - nDbgStartPos, (LPCTSTR)DbgGetFileInfo(packet)); } } // Ignore if no data required - if (!(GetDownloadState() == DS_DOWNLOADING || GetDownloadState() == DS_NONEEDEDPARTS)) { + if (GetDownloadState() != DS_DOWNLOADING && GetDownloadState() != DS_NONEEDEDPARTS) { TRACE("%s - Invalid download state\n", __FUNCTION__); return; } - // Update stats m_dwLastBlockReceived = ::GetTickCount(); // Read data from packet CSafeMemFile data(packet, size); - uchar fileID[16]; + uchar fileID[MDX_DIGEST_SIZE]; data.ReadHash16(fileID); - int nHeaderSize = 16; + int nHeaderSize = MDX_DIGEST_SIZE; // Check that this data is for the correct file if (!m_reqfile || !md4equ(packet, m_reqfile->GetFileHash())) throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (ProcessBlockPacket)"); // Find the start & end positions, and size of this chunk of data - uint64 nStartPos; - uint64 nEndPos; + uint64 nStartPos, nEndPos; if (bI64Offsets) { nStartPos = data.ReadUInt64(); @@ -1031,7 +980,7 @@ void CUpDownClient::ProcessBlockPacket(const uchar *packet, uint32 size, bool pa nHeaderSize += 4; } if (packed) { - (void)data.ReadUInt32(); + data.Seek((LONGLONG)sizeof(uint32), CFile::current); //skip size nHeaderSize += 4; nEndPos = nStartPos + (size - nHeaderSize); } else if (bI64Offsets) { @@ -1044,7 +993,7 @@ void CUpDownClient::ProcessBlockPacket(const uchar *packet, uint32 size, bool pa uint32 uTransferredFileDataSize = size - nHeaderSize; // Check that packet size matches the declared data size + header size (24) - if (nEndPos == nStartPos || size != ((nEndPos - nStartPos) + nHeaderSize)) + if (nEndPos <= nStartPos || size != ((nEndPos - nStartPos) + nHeaderSize)) throw GetResString(IDS_ERR_BADDATABLOCK) + _T(" (ProcessBlockPacket)"); // -khaos--+++> @@ -1058,138 +1007,137 @@ void CUpDownClient::ProcessBlockPacket(const uchar *packet, uint32 size, bool pa if (credits) credits->AddDownloaded(uTransferredFileDataSize, GetIP()); - // Move end back one, should be inclusive + // Move end back by one, should be inclusive --nEndPos; // Loop through to find the reserved block that this is within - for (POSITION pos = m_PendingBlocks_list.GetHeadPosition(); pos != NULL; ) { + for (POSITION pos = m_PendingBlocks_list.GetHeadPosition(); pos != NULL;) { POSITION posLast = pos; Pending_Block_Struct *cur_block = m_PendingBlocks_list.GetNext(pos); - if ((cur_block->block->StartOffset <= nStartPos) && (cur_block->block->EndOffset >= nStartPos)) { - // Found reserved block + if (cur_block->block->StartOffset > nStartPos || cur_block->block->EndOffset < nStartPos) + continue; - if (cur_block->fZStreamError) { - if (thePrefs.GetVerbose()) - AddDebugLogLine(false, _T("PrcBlkPkt: Ignoring %u bytes of block starting at %I64u because of erroneous zstream state for file \"%s\" - %s"), uTransferredFileDataSize, nStartPos, (LPCTSTR)m_reqfile->GetFileName(), (LPCTSTR)DbgGetClientInfo()); - m_reqfile->RemoveBlockFromList(cur_block->block->StartOffset, cur_block->block->EndOffset); - return; - } + // Found the reserved block + if (cur_block->fZStreamError) { + if (thePrefs.GetVerbose()) + AddDebugLogLine(false, _T("PrcBlkPkt: Ignoring %u bytes of block starting at %I64u because of erroneous zstream state for file \"%s\" - %s"), uTransferredFileDataSize, nStartPos, (LPCTSTR)m_reqfile->GetFileName(), (LPCTSTR)DbgGetClientInfo()); + m_reqfile->RemoveBlockFromList(cur_block->block->StartOffset, cur_block->block->EndOffset); + return; + } - // Remember this start pos, used to draw part downloading in list - m_nLastBlockOffset = nStartPos; + // Remember this start pos, used to draw part downloading in list + m_nLastBlockOffset = nStartPos; - // Occasionally packets are duplicated, no point writing it twice - // This will be 0 in these cases, or the length written otherwise - uint32 lenWritten = 0; + // Occasionally packets are duplicated, no point writing it twice + // This will be 0 in these cases, or the length written otherwise + uint32 lenWritten = 0; - // Handle differently depending on whether packed or not - if (!packed) { - // security sanitize check - if (nEndPos > cur_block->block->EndOffset) { - DebugLogError(_T("Received Blockpacket exceeds requested boundaries (requested end: %I64u, Part %u, received end %I64u, Part %u), file %s, client %s"), cur_block->block->EndOffset - , (uint32)(cur_block->block->EndOffset / PARTSIZE), nEndPos, (uint32)(nEndPos / PARTSIZE), (LPCTSTR)m_reqfile->GetFileName(), (LPCTSTR)DbgGetClientInfo()); - m_reqfile->RemoveBlockFromList(cur_block->block->StartOffset, cur_block->block->EndOffset); - return; - } - // Write to disk (will be buffered in part file class) - lenWritten = m_reqfile->WriteToBuffer(uTransferredFileDataSize - , packet + nHeaderSize - , nStartPos - , nEndPos - , cur_block->block - , this); - } else { // Packed - ASSERT((int)size > 0); - // Create space to store unzipped data, the size is only an initial guess, will be resized in unzip() if not big enough - uint32 lenUnzipped = (size * 2); - // Don't get too big - if (lenUnzipped > (EMBLOCKSIZE + 300)) - lenUnzipped = (EMBLOCKSIZE + 300); - BYTE *unzipped = new BYTE[lenUnzipped]; - - // Try to unzip the packet - int result = unzip(cur_block, packet + nHeaderSize, uTransferredFileDataSize, &unzipped, &lenUnzipped); - // no block can be uncompressed to >2GB, 'lenUnzipped' is obviously erroneous. - if (result == Z_OK && (int)lenUnzipped >= 0) { - if (lenUnzipped > 0) { // Write any unzipped data to disk - ASSERT((int)lenUnzipped > 0); - - // Use the current start and end positions for the uncompressed data - nStartPos = cur_block->block->StartOffset + cur_block->totalUnzipped - lenUnzipped; - nEndPos = cur_block->block->StartOffset + cur_block->totalUnzipped - 1; - - if (nStartPos > cur_block->block->EndOffset || nEndPos > cur_block->block->EndOffset) { - DebugLogError(_T("PrcBlkPkt: ") + GetResString(IDS_ERR_CORRUPTCOMPRPKG), (LPCTSTR)m_reqfile->GetFileName(), 666); - m_reqfile->RemoveBlockFromList(cur_block->block->StartOffset, cur_block->block->EndOffset); - // There is no chance to recover from this error - } else { - // Write uncompressed data to file - lenWritten = m_reqfile->WriteToBuffer(uTransferredFileDataSize, - unzipped, - nStartPos, - nEndPos, - cur_block->block, - this); - } - } - } else { - if (thePrefs.GetVerbose()) { - CString strZipError; - if (cur_block->zStream && cur_block->zStream->msg) - strZipError.Format(_T(" - %hs"), cur_block->zStream->msg); - if (result == Z_OK && (int)lenUnzipped < 0) { - ASSERT(0); - strZipError.AppendFormat(_T("; Z_OK,lenUnzipped=%u"), lenUnzipped); - } - DebugLogError(_T("PrcBlkPkt: ") + GetResString(IDS_ERR_CORRUPTCOMPRPKG) + strZipError, (LPCTSTR)m_reqfile->GetFileName(), result); - } - m_reqfile->RemoveBlockFromList(cur_block->block->StartOffset, cur_block->block->EndOffset); - - // If we had a zstream error, there is no chance that we could recover from it nor that we - // could use the current zstream (which is in error state) any longer. - if (cur_block->zStream) { - inflateEnd(cur_block->zStream); - delete cur_block->zStream; - cur_block->zStream = NULL; + // Handle differently depending on whether packed or not + if (!packed) { + // security sanitize check + if (nEndPos > cur_block->block->EndOffset) { + DebugLogError(_T("Received Blockpacket exceeds requested boundaries (requested end: %I64u, Part %u, received end %I64u, Part %u), file %s, client %s"), cur_block->block->EndOffset + , (uint32)(cur_block->block->EndOffset / PARTSIZE), nEndPos, (uint32)(nEndPos / PARTSIZE), (LPCTSTR)m_reqfile->GetFileName(), (LPCTSTR)DbgGetClientInfo()); + m_reqfile->RemoveBlockFromList(cur_block->block->StartOffset, cur_block->block->EndOffset); + return; + } + // Write to disk (will be buffered in part file class) + lenWritten = m_reqfile->WriteToBuffer(uTransferredFileDataSize + , &packet[nHeaderSize] + , nStartPos + , nEndPos + , cur_block->block + , this + , true); //copy data to a new buffer + } else { // Packed + ASSERT((int)size > 0); + // Create space to store unzipped data, the size is only an initial guess, will be resized in unzip() if not big enough + // Don't get too big + uint32 lenUnzipped = min(size * 2, EMBLOCKSIZE + 300); + BYTE *unzipped = new BYTE[lenUnzipped]; + + // Try to unzip the packet + int result = unzip(cur_block, &packet[nHeaderSize], uTransferredFileDataSize, &unzipped, &lenUnzipped); + // no block can be uncompressed to >2GB, 'lenUnzipped' is obviously erroneous. + if (result == Z_OK && (int)lenUnzipped >= 0) { + if (lenUnzipped > 0) { // Write any unzipped data to disk + ASSERT((int)lenUnzipped > 0); + + // Use the current start and end positions for the uncompressed data + nStartPos = cur_block->block->StartOffset + cur_block->totalUnzipped - lenUnzipped; + nEndPos = cur_block->block->StartOffset + cur_block->totalUnzipped - 1; + + if (nStartPos > cur_block->block->EndOffset || nEndPos > cur_block->block->EndOffset) { + DebugLogError(_T("PrcBlkPkt: ") + GetResString(IDS_ERR_CORRUPTCOMPRPKG), (LPCTSTR)m_reqfile->GetFileName(), 666); + m_reqfile->RemoveBlockFromList(cur_block->block->StartOffset, cur_block->block->EndOffset); + // There is no chance to recover from this error + } else { + // Write uncompressed data to file + lenWritten = m_reqfile->WriteToBuffer(uTransferredFileDataSize + , unzipped + , nStartPos + , nEndPos + , cur_block->block + , this + , false); //use the given buffer, no copy + if (lenWritten) + unzipped = NULL; //do not delete the buffer } - - // Although we can't further use the current zstream, there is no need to disconnect the sending - // client because the next zstream (a series of 10K-blocks which build a 180K-block) could be - // valid again. Just ignore all further blocks for the current zstream. - cur_block->fZStreamError = 1; - cur_block->totalUnzipped = 0; } - delete[] unzipped; - } - - // These checks only need to be done if any data was written - if (lenWritten > 0) { - m_nTransferredDown += uTransferredFileDataSize; - m_nCurSessionPayloadDown += lenWritten; - SetTransferredDownMini(); - - // If finished reserved block - if (nEndPos == cur_block->block->EndOffset) { - m_reqfile->RemoveBlockFromList(cur_block->block->StartOffset, cur_block->block->EndOffset); - delete cur_block->block; - // Not always allocated - if (cur_block->zStream) { - inflateEnd(cur_block->zStream); - delete cur_block->zStream; + } else { + if (thePrefs.GetVerbose()) { + CString strZipError; + if (cur_block->zStream && cur_block->zStream->msg) + strZipError.Format(_T(" - %hs"), cur_block->zStream->msg); + if (result == Z_OK && (int)lenUnzipped < 0) { + ASSERT(0); + strZipError.AppendFormat(_T("; Z_OK,lenUnzipped=%u"), lenUnzipped); } - delete cur_block; - m_PendingBlocks_list.RemoveAt(posLast); + DebugLogError(_T("PrcBlkPkt: ") + GetResString(IDS_ERR_CORRUPTCOMPRPKG) + strZipError, (LPCTSTR)m_reqfile->GetFileName(), result); + } + m_reqfile->RemoveBlockFromList(cur_block->block->StartOffset, cur_block->block->EndOffset); - // Request next block - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("More block requests", this); - SendBlockRequests(); + // If we had a zstream error, there is no chance that we could recover from it, + // nor that we could use the current zstream (which is in error state) any longer. + if (cur_block->zStream) { + inflateEnd(cur_block->zStream); + delete cur_block->zStream; + cur_block->zStream = NULL; } + + // Although we can't further use the current zstream, there is no need to disconnect the sending + // client because the next zstream (a series of 10K-blocks which build a 180K-block) could be + // valid again. Just ignore all further blocks for the current zstream. + cur_block->fZStreamError = 1; + cur_block->totalUnzipped = 0; } + delete[] unzipped; + } - // Stop looping and exit method - return; + // These checks only need to be done if any data was written + // Additionally, asynchronous writing allows tricks such as disconnecting from client while + // file data is being in buffers. + // Hence additional checks. + if (lenWritten > 0 && !m_PendingBlocks_list.IsEmpty() && cur_block->block) { + m_nTransferredDown += uTransferredFileDataSize; + m_nCurSessionPayloadDown += lenWritten; + cur_block->block->transferred += lenWritten; //cur_block->block was invalid! + SetTransferredDownMini(); + + // If finished reserved block + if (nEndPos == cur_block->block->EndOffset) { + m_PendingBlocks_list.RemoveAt(posLast); + ClearPendingBlockRequest(cur_block); + + // Request next block + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugSend("More block requests", this); + SendBlockRequests(); + } } + + // Stop looping and exit method + return; } TRACE("%s - Dropping packet\n", __FUNCTION__); @@ -1212,9 +1160,9 @@ int CUpDownClient::unzip(Pending_Block_Struct *block, const BYTE *zipped, uint32 zS = block->zStream; // Initialise stream values - zS->zalloc = (alloc_func)0; - zS->zfree = (free_func)0; - zS->opaque = (voidpf)0; + zS->zalloc = (alloc_func)NULL; + zS->zfree = (free_func)NULL; + zS->opaque = (voidpf)NULL; // Set output data streams, do this here to avoid overwriting on recursive calls zS->next_out = (*unzipped); @@ -1290,10 +1238,8 @@ int CUpDownClient::unzip(Pending_Block_Struct *block, const BYTE *zipped, uint32 // Should not get here unless input data is corrupt if (thePrefs.GetVerbose()) { CString strZipError; - if (zS->msg) - strZipError.Format(_T(" %d: '%hs'"), err, zS->msg); - else if (err != Z_OK) - strZipError.Format(_T(" %d: '%hs'"), err, zError(err)); + if (zS->msg || err != Z_OK) + strZipError.Format(_T(" %d: '%hs'"), err, zS->msg ? zS->msg : zError(err)); TRACE_UNZIP("; Error: %s\n", strZipError); DebugLogError(_T("Unexpected zip error%s in file \"%s\""), (LPCTSTR)strZipError, m_reqfile ? (LPCTSTR)m_reqfile->GetFileName() : _T("")); } @@ -1314,22 +1260,21 @@ int CUpDownClient::unzip(Pending_Block_Struct *block, const BYTE *zipped, uint32 uint32 CUpDownClient::CalculateDownloadRate() { // Patch By BadWolf - Accurate data rate Calculation - m_AverageDDR_list.AddTail(TransferredData{m_nDownDataRateMS, ::GetTickCount()}); + const DWORD curTick = ::GetTickCount(); + m_AverageDDR_list.AddTail(TransferredData{ m_nDownDataRateMS, curTick }); m_nSumForAvgDownDataRate += m_nDownDataRateMS; m_nDownDataRateMS = 0; while (m_AverageDDR_list.GetCount() > 500) m_nSumForAvgDownDataRate -= m_AverageDDR_list.RemoveHead().datalen; - if (m_AverageDDR_list.GetCount() > 1) { - DWORD dwDuration = m_AverageDDR_list.GetTail().timestamp - m_AverageDDR_list.GetHead().timestamp; - if (dwDuration) - m_nDownDatarate = (UINT)(1000U * (ULONGLONG)m_nSumForAvgDownDataRate / dwDuration); - } else + if (m_AverageDDR_list.GetCount() > 1 && curTick > m_AverageDDR_list.GetHead().timestamp) + m_nDownDatarate = (UINT)(SEC2MS(m_nSumForAvgDownDataRate) / (curTick - m_AverageDDR_list.GetHead().timestamp)); + else m_nDownDatarate = 0; + // END Patch By BadWolf - ++m_cShowDR; - if (m_cShowDR == 30) { + if (++m_cShowDR >= 30) { m_cShowDR = 0; UpdateDisplayedInfo(); } @@ -1344,11 +1289,8 @@ void CUpDownClient::CheckDownloadTimeout() ASSERT(DOWNLOADTIMEOUT < m_pPCDownSocket->GetTimeOut()); OnPeerCacheDownSocketTimeout(); } else { - if (socket != NULL) - if (!socket->IsRawDataMode()) - SendCancelTransfer(); - else - ASSERT(0); + if (socket != NULL && !socket->IsRawDataMode()) + SendCancelTransfer(); else ASSERT(0); SetDownloadState(DS_ONQUEUE, _T("Timeout. More than 100 seconds since last complete block was received.")); @@ -1384,7 +1326,7 @@ void CUpDownClient::UDPReaskFNF() if (thePrefs.GetVerbose()) AddDebugLogLine(DLP_LOW, false, _T("UDP FNF-Answer: %s - %s"), (LPCTSTR)DbgGetClientInfo(), (LPCTSTR)DbgGetFileInfo(m_reqfile ? m_reqfile->GetFileHash() : NULL)); if (m_reqfile) - m_reqfile->m_DeadSourceList.AddDeadSource(this); + m_reqfile->m_DeadSourceList.AddDeadSource(*this); switch (GetDownloadState()) { case DS_ONQUEUE: case DS_NONEEDEDPARTS: @@ -1397,10 +1339,8 @@ void CUpDownClient::UDPReaskFNF() if (!socket && Disconnected(_T("UDPReaskFNF socket=NULL"))) delete this; } - } else { - if (thePrefs.GetVerbose()) - DebugLogWarning(_T("UDP FNF-Answer: %s - did not remove client because of current download state"), GetUserName()); - } + } else if (thePrefs.GetVerbose()) + DebugLogWarning(_T("UDP FNF-Answer: %s - did not remove client because of current download state"), GetUserName()); } void CUpDownClient::UDPReaskForDownload() @@ -1413,8 +1353,9 @@ void CUpDownClient::UDPReaskForDownload() if (m_nTotalUDPPackets > 3 && (m_nFailedUDPPackets / (float)m_nTotalUDPPackets > .3)) return; - if (GetUDPPort() != 0 && GetUDPVersion() != 0 && thePrefs.GetUDPPort() != 0 && - !theApp.IsFirewalled() && !(socket && socket->IsConnected()) && !thePrefs.GetProxySettings().bUseProxy) { + if (GetUDPPort() != 0 && GetUDPVersion() != 0 && thePrefs.GetUDPPort() != 0 + && !theApp.IsFirewalled() && !(socket && socket->IsConnected()) && !thePrefs.GetProxySettings().bUseProxy) + { if (!HasLowID()) { //don't use udp to ask for sources if (IsSourceRequestAllowed()) @@ -1426,17 +1367,18 @@ void CUpDownClient::UDPReaskForDownload() m_bUDPPending = true; CSafeMemFile data(128); data.WriteHash16(m_reqfile->GetFileHash()); - if (GetUDPVersion() > 3) { - if (m_reqfile->IsPartFile()) - reinterpret_cast(m_reqfile)->WritePartStatus(&data); - else - data.WriteUInt16(0); - } - if (GetUDPVersion() > 2) + if (GetUDPVersion() > 2) { + if (GetUDPVersion() > 3) + if (m_reqfile->IsPartFile()) + reinterpret_cast(m_reqfile)->WritePartStatus(data); + else + data.WriteUInt16(0); + data.WriteUInt16(m_reqfile->m_nCompleteSourcesCount); + } if (thePrefs.GetDebugClientUDPLevel() > 0) DebugSend("OP_ReaskFilePing", this, m_reqfile->GetFileHash()); - Packet *response = new Packet(&data, OP_EMULEPROT); + Packet *response = new Packet(data, OP_EMULEPROT); response->opcode = OP_REASKFILEPING; theStats.AddUpDataOverheadFileRequest(response->size); theApp.downloadqueue->AddUDPFileReasks(); @@ -1447,17 +1389,18 @@ void CUpDownClient::UDPReaskForDownload() CSafeMemFile data(128); data.WriteHash16(GetBuddyID()); data.WriteHash16(m_reqfile->GetFileHash()); - if (GetUDPVersion() > 3) { - if (m_reqfile->IsPartFile()) - reinterpret_cast(m_reqfile)->WritePartStatus(&data); - else - data.WriteUInt16(0); - } - if (GetUDPVersion() > 2) + if (GetUDPVersion() > 2) { + if (GetUDPVersion() > 3) + if (m_reqfile->IsPartFile()) + reinterpret_cast(m_reqfile)->WritePartStatus(data); + else + data.WriteUInt16(0); + data.WriteUInt16(m_reqfile->m_nCompleteSourcesCount); + } if (thePrefs.GetDebugClientUDPLevel() > 0) DebugSend("OP_ReaskCallbackUDP", this, m_reqfile->GetFileHash()); - Packet *response = new Packet(&data, OP_EMULEPROT); + Packet *response = new Packet(data, OP_EMULEPROT); response->opcode = OP_REASKCALLBACKUDP; theStats.AddUpDataOverheadFileRequest(response->size); theApp.downloadqueue->AddUDPFileReasks(); @@ -1470,7 +1413,7 @@ void CUpDownClient::UDPReaskForDownload() void CUpDownClient::UpdateDisplayedInfo(bool force) { - DWORD curTick = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); #ifndef _DEBUG if (!force && curTick < m_lastRefreshedDLDisplay + MINWAIT_BEFORE_DLDISPLAY_WINDOWUPDATE + m_random_update_wait) return; @@ -1483,12 +1426,12 @@ void CUpDownClient::UpdateDisplayedInfo(bool force) m_lastRefreshedDLDisplay = curTick; } -const bool CUpDownClient::IsInNoNeededList(const CPartFile *fileToCheck) const +bool CUpDownClient::IsInNoNeededList(const CPartFile *fileToCheck) const { return m_OtherNoNeeded_list.Find(const_cast(fileToCheck)) != NULL; } -const bool CUpDownClient::SwapToRightFile(CPartFile *SwapTo, CPartFile *cur_file, bool ignoreSuspensions, bool SwapToIsNNPFile, bool curFileisNNPFile, bool &wasSkippedDueToSourceExchange, bool doAgressiveSwapping, bool debug) +bool CUpDownClient::SwapToRightFile(CPartFile *SwapTo, CPartFile *cur_file, bool ignoreSuspensions, bool SwapToIsNNPFile, bool curFileisNNPFile, bool &wasSkippedDueToSourceExchange, bool doAgressiveSwapping, bool debug) { bool printDebug = debug && thePrefs.GetLogA4AF(); @@ -1501,13 +1444,13 @@ const bool CUpDownClient::SwapToRightFile(CPartFile *SwapTo, CPartFile *cur_file return true; if ((!curFileisNNPFile && cur_file->GetSourceCount() < cur_file->GetMaxSources()) - || (curFileisNNPFile && cur_file->GetSourceCount() < cur_file->GetMaxSources()*.8)) + || (curFileisNNPFile && cur_file->GetSourceCount() < cur_file->GetMaxSources() * 4 / 5)) { if (printDebug) - AddDebugLogLine(DLP_VERYLOW, false, _T("oooo Debug: cur_file does probably not have too many sources.")); + AddDebugLogLine(DLP_VERYLOW, false, _T("oooo Debug: cur_file probably does not have too many sources.")); if (SwapTo->GetSourceCount() > SwapTo->GetMaxSources() - || (SwapTo->GetSourceCount() >= SwapTo->GetMaxSources()*.8 + || (SwapTo->GetSourceCount() >= SwapTo->GetMaxSources() * 4 / 5 && SwapTo == m_reqfile && (GetDownloadState() == DS_LOWTOLOWIP || GetDownloadState() == DS_REMOTEQUEUEFULL) ) @@ -1522,44 +1465,48 @@ const bool CUpDownClient::SwapToRightFile(CPartFile *SwapTo, CPartFile *cur_file if (printDebug) AddDebugLogLine(DLP_VERYLOW, false, _T("oooo Debug: No suspend block.")); - DWORD tempTick = ::GetTickCount(); + DWORD curTick = ::GetTickCount(); DWORD curAsked = GetLastAskedTime(cur_file); DWORD swapAsked = GetLastAskedTime(SwapTo); bool rightFileHasHigherPrio = CPartFile::RightFileHasHigherPrio(SwapTo, cur_file); - DWORD allNnpReaskTime = (DWORD)(FILEREASKTIME * 2 * (m_OtherNoNeeded_list.GetCount() + static_cast(GetDownloadState() == DS_NONEEDEDPARTS))); // wait two re-ask interval for each nnp file before re-asking an nnp file + // wait two re-ask interval for each nnp file before re-asking an nnp file + DWORD allNnpReaskTime = (DWORD)(FILEREASKTIME * 2 * (m_OtherNoNeeded_list.GetCount() + static_cast(GetDownloadState() == DS_NONEEDEDPARTS))); DWORD curReask = curAsked + allNnpReaskTime; - if (!SwapToIsNNPFile && (!curFileisNNPFile || curAsked == 0 || tempTick >= curReask) && rightFileHasHigherPrio || - SwapToIsNNPFile && curFileisNNPFile && + if (!SwapToIsNNPFile && (!curFileisNNPFile || curAsked == 0 || curTick >= curReask) && rightFileHasHigherPrio + || SwapToIsNNPFile && curFileisNNPFile && ( - swapAsked != 0 && - ( - curAsked == 0 || - (swapAsked > curAsked && (tempTick >= curReask || (rightFileHasHigherPrio && tempTick < swapAsked + allNnpReaskTime))) - ) || - rightFileHasHigherPrio && swapAsked == 0 && curAsked == 0 - ) || - SwapToIsNNPFile && !curFileisNNPFile) { + swapAsked != 0 + && ( + curAsked == 0 + || (swapAsked > curAsked && (curTick >= curReask || (rightFileHasHigherPrio && curTick < swapAsked + allNnpReaskTime))) + ) + || rightFileHasHigherPrio && swapAsked == 0 && curAsked == 0 + ) + || SwapToIsNNPFile && !curFileisNNPFile) + { if (printDebug) if (!SwapToIsNNPFile && !curFileisNNPFile && rightFileHasHigherPrio) AddDebugLogLine(DLP_VERYLOW, false, _T("oooo Debug: Higher prio.")); - else if (!SwapToIsNNPFile && (curAsked == 0 || tempTick >= curReask) && rightFileHasHigherPrio) + else if (!SwapToIsNNPFile && (curAsked == 0 || curTick >= curReask) && rightFileHasHigherPrio) AddDebugLogLine(DLP_VERYLOW, false, _T("oooo Debug: Time to re-ask nnp and it had higher prio.")); - else if (swapAsked != 0 && - ( - curAsked == 0 || - (swapAsked > curAsked && (tempTick >= curReask || (rightFileHasHigherPrio && tempTick < swapAsked + allNnpReaskTime))) + else if (swapAsked != 0 + && ( + curAsked == 0 + || (swapAsked > curAsked && (curTick >= curReask || (rightFileHasHigherPrio && curTick < swapAsked + allNnpReaskTime))) + ) ) - ) + { AddDebugLogLine(DLP_VERYLOW, false, _T("oooo Debug: Both nnp and cur_file has longer time since re-asked.")); + } else if (SwapToIsNNPFile && !curFileisNNPFile) AddDebugLogLine(DLP_VERYLOW, false, _T("oooo Debug: SwapToIsNNPFile && !curFileisNNPFile")); else AddDebugLogLine(DLP_VERYLOW, false, _T("oooo Debug: Higher prio for unknown reason!")); - if (IsSourceRequestAllowed(cur_file) && (cur_file->AllowSwapForSourceExchange() || (cur_file == m_reqfile && RecentlySwappedForSourceExchange())) || - !(IsSourceRequestAllowed(SwapTo) && (SwapTo->AllowSwapForSourceExchange() || (SwapTo == m_reqfile && RecentlySwappedForSourceExchange()))) || - (GetDownloadState() == DS_ONQUEUE && GetRemoteQueueRank() <= 50)) + if (IsSourceRequestAllowed(cur_file) && (cur_file->AllowSwapForSourceExchange() || (cur_file == m_reqfile && RecentlySwappedForSourceExchange())) + || !(IsSourceRequestAllowed(SwapTo) && (SwapTo->AllowSwapForSourceExchange() || (SwapTo == m_reqfile && RecentlySwappedForSourceExchange()))) + || (GetDownloadState() == DS_ONQUEUE && GetRemoteQueueRank() <= 50)) { if (printDebug) AddDebugLogLine(DLP_LOW, false, _T("oooo Debug: Source Request check OK.")); @@ -1571,9 +1518,9 @@ const bool CUpDownClient::SwapToRightFile(CPartFile *SwapTo, CPartFile *cur_file wasSkippedDueToSourceExchange = true; } - if (IsSourceRequestAllowed(cur_file, true) && (cur_file->AllowSwapForSourceExchange() || (cur_file == m_reqfile && RecentlySwappedForSourceExchange())) && - !(IsSourceRequestAllowed(SwapTo, true) && (SwapTo->AllowSwapForSourceExchange() || (SwapTo == m_reqfile && RecentlySwappedForSourceExchange()))) && - (GetDownloadState() != DS_ONQUEUE || GetRemoteQueueRank() > 50)) + if (IsSourceRequestAllowed(cur_file, true) && (cur_file->AllowSwapForSourceExchange() || (cur_file == m_reqfile && RecentlySwappedForSourceExchange())) + && !(IsSourceRequestAllowed(SwapTo, true) && (SwapTo->AllowSwapForSourceExchange() || (SwapTo == m_reqfile && RecentlySwappedForSourceExchange()))) + && (GetDownloadState() != DS_ONQUEUE || GetRemoteQueueRank() > 50)) { wasSkippedDueToSourceExchange = true; @@ -1603,7 +1550,7 @@ bool CUpDownClient::SwapToAnotherFile(LPCTSTR reason, bool bIgnoreNoNeeded, bool if (!bRemoveCompletely && allowSame && thePrefs.GetA4AFSaveCpu()) { // Only swap if we can't keep the old source if (printDebug) - AddDebugLogLine(DLP_LOW, false, _T("ooo Debug: return false since prefs setting to save cpu is enabled.")); + AddDebugLogLine(DLP_LOW, false, _T("ooo Debug: return false since prefs setting to save CPU is enabled.")); return false; } @@ -1711,7 +1658,7 @@ bool CUpDownClient::SwapToAnotherFile(LPCTSTR reason, bool bIgnoreNoNeeded, bool usedList = &m_OtherRequests_list; finalpos = pos2; } else { - if (printDebug && SwapTo) + if (printDebug) //SwapToRightFile ensured that SwapTo != NULL AddDebugLogLine(DLP_VERYLOW, false, _T("ooo Debug: Keeping file %s"), (LPCTSTR)SwapTo->GetFileName()); if (wasSkippedDueToSourceExchange) { if (printDebug) @@ -1786,7 +1733,7 @@ bool CUpDownClient::SwapToAnotherFile(LPCTSTR reason, bool bIgnoreNoNeeded, bool usedList = &m_OtherNoNeeded_list; finalpos = pos2; } else { - if (printDebug) //SwapTo cannot be NULL here; it was checked in SwapToRightFile + if (printDebug) //SwapToRightFile ensured that SwapTo != NULL AddDebugLogLine(DLP_VERYLOW, false, _T("ooo Debug: Keeping file %s"), (LPCTSTR)SwapTo->GetFileName()); if (wasSkippedDueToSourceExchange) { if (debug && thePrefs.GetVerbose()) @@ -1820,7 +1767,7 @@ bool CUpDownClient::SwapToAnotherFile(LPCTSTR reason, bool bIgnoreNoNeeded, bool SwapTo->SetSwapForSourceExchangeTick(); SetSwapForSourceExchangeTick(); - strInfo = _T("******SourceExchange-Swap****** ") + strInfo; + strInfo.Insert(0, _T("******SourceExchange-Swap****** ")); if (printDebug) AddDebugLogLine(DLP_VERYLOW, false, _T("ooo Debug: Due to sourceExchange.")); else if (thePrefs.GetLogA4AF() && m_reqfile == SwapTo) //m_reqfile != NULL here @@ -1900,16 +1847,16 @@ bool CUpDownClient::DoSwap(CPartFile *SwapTo, bool bRemoveCompletely, LPCTSTR re void CUpDownClient::DontSwapTo(/*const*/ CPartFile *file) { - DWORD dwNow = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); for (POSITION pos = m_DontSwap_list.GetHeadPosition(); pos != NULL;) { PartFileStamp &pfs = m_DontSwap_list.GetNext(pos); if (pfs.file == file) { - pfs.timestamp = dwNow; + pfs.timestamp = curTick; return; } } - m_DontSwap_list.AddHead(PartFileStamp{file, dwNow}); + m_DontSwap_list.AddHead(PartFileStamp{ file, curTick }); } bool CUpDownClient::IsSwapSuspended(const CPartFile *file, const bool allowShortReaskTime, const bool fileIsNNP) @@ -1917,7 +1864,7 @@ bool CUpDownClient::IsSwapSuspended(const CPartFile *file, const bool allowShort if (file == m_reqfile) return false; - // Don't swap if we have re-asked this client too recently + // Don't swap if we have re-asked this client very short time ago if (GetTimeUntilReask(file, allowShortReaskTime, true, fileIsNNP) > 0) return true; @@ -1934,19 +1881,17 @@ bool CUpDownClient::IsSwapSuspended(const CPartFile *file, const bool allowShort } return true; } - if (pfs.file == NULL) // in which cases should this happen? + if (pfs.file == NULL) // in which case should this happen? m_DontSwap_list.RemoveAt(pos2); } return false; } -uint32 CUpDownClient::GetTimeUntilReask(const CPartFile *file, const bool allowShortReaskTime, const bool useGivenNNP, const bool givenNNP) const +DWORD CUpDownClient::GetTimeUntilReask(const CPartFile *file, const bool allowShortReaskTime, const bool useGivenNNP, const bool givenNNP) const { DWORD lastAskedTimeTick = GetLastAskedTime(file); - if (lastAskedTimeTick != 0) { - const DWORD tick = ::GetTickCount(); - + if (lastAskedTimeTick > 0) { DWORD reaskTime; if (allowShortReaskTime || (file == m_reqfile && GetDownloadState() == DS_NONE)) reaskTime = MIN_REQUESTTIME; @@ -1958,18 +1903,19 @@ uint32 CUpDownClient::GetTimeUntilReask(const CPartFile *file, const bool allowS } else reaskTime = FILEREASKTIME; - if (tick < lastAskedTimeTick + reaskTime) - return reaskTime - (tick - lastAskedTimeTick); + const DWORD curTick = ::GetTickCount(); + if (curTick < lastAskedTimeTick + reaskTime) + return reaskTime - (curTick - lastAskedTimeTick); } return 0; } -uint32 CUpDownClient::GetTimeUntilReask(const CPartFile *file) const +DWORD CUpDownClient::GetTimeUntilReask(const CPartFile *file) const { return GetTimeUntilReask(file, false); } -uint32 CUpDownClient::GetTimeUntilReask() const +DWORD CUpDownClient::GetTimeUntilReask() const { return GetTimeUntilReask(m_reqfile); } @@ -2086,7 +2032,7 @@ void CUpDownClient::CheckQueueRankFlood() theApp.clientlist->TrackBadRequest(this, -2); // reset so the client will not be re-banned right after the ban is lifted Ban(_T("QR flood")); } - throw CString(thePrefs.GetLogBannedClients() ? _T("QR flood") : _T("")); + throwCStr(thePrefs.GetLogBannedClients() ? _T("QR flood") : _T("")); } } } else { @@ -2095,18 +2041,15 @@ void CUpDownClient::CheckQueueRankFlood() } } -DWORD CUpDownClient::GetLastAskedTime(const CPartFile *partFile) const +DWORD CUpDownClient::GetLastAskedTime(const CPartFile *pFile) const { - CPartFile *file = const_cast(partFile); - if (file == NULL) - file = m_reqfile; - - DWORD lastChangedTick; - return m_fileReaskTimes.Lookup(file, lastChangedTick) ? lastChangedTick : 0; + const CFileReaskTimesMap::CPair *pair = m_fileReaskTimes.PLookup(pFile ? pFile : m_reqfile); + return pair ? pair->value : 0; } +// TODO fileident optimize to save some memory void CUpDownClient::SetReqFileAICHHash(CAICHHash *val) -{ // TODO fileident optimize to save some memory +{ if (m_pReqFileAICHHash != NULL && m_pReqFileAICHHash != val) delete m_pReqFileAICHHash; m_pReqFileAICHHash = val; @@ -2123,8 +2066,8 @@ void CUpDownClient::SendAICHRequest(CPartFile *pForFile, uint16 nPart) CSafeMemFile data; data.WriteHash16(pForFile->GetFileHash()); data.WriteUInt16(nPart); - pForFile->GetAICHRecoveryHashSet()->GetMasterHash().Write(&data); - Packet *packet = new Packet(&data, OP_EMULEPROT, OP_AICHREQUEST); + pForFile->GetAICHRecoveryHashSet()->GetMasterHash().Write(data); + Packet *packet = new Packet(data, OP_EMULEPROT, OP_AICHREQUEST); if (thePrefs.GetDebugClientTCPLevel() > 0) DebugSend("OP_AichRequest", this, (uchar*)packet->pBuffer); theStats.AddUpDataOverheadFileRequest(packet->size); @@ -2134,7 +2077,7 @@ void CUpDownClient::SendAICHRequest(CPartFile *pForFile, uint16 nPart) void CUpDownClient::ProcessAICHAnswer(const uchar *packet, UINT size) { if (!m_fAICHRequested) - throw CString(_T("Received unrequested AICH Packet")); + throwCStr(_T("Received unrequested AICH Packet")); m_fAICHRequested = false; @@ -2143,18 +2086,18 @@ void CUpDownClient::ProcessAICHAnswer(const uchar *packet, UINT size) CAICHRecoveryHashSet::ClientAICHRequestFailed(this); return; } - uchar abyHash[16]; + uchar abyHash[MDX_DIGEST_SIZE]; data.ReadHash16(abyHash); CPartFile *pPartFile = theApp.downloadqueue->GetFileByID(abyHash); CAICHRequestedData request = CAICHRecoveryHashSet::GetAICHReqDetails(this); uint16 nPart = data.ReadUInt16(); if (pPartFile != NULL && request.m_pPartFile == pPartFile && request.m_pClient == this && nPart == request.m_nPart) { - CAICHHash ahMasterHash(&data); + CAICHHash ahMasterHash(data); CAICHRecoveryHashSet *rhashset = pPartFile->GetAICHRecoveryHashSet(); if ((rhashset->GetStatus() == AICH_TRUSTED || rhashset->GetStatus() == AICH_VERIFIED) && ahMasterHash == rhashset->GetMasterHash()) { - if (rhashset->ReadRecoveryData((uint64)request.m_nPart*PARTSIZE, &data)) { + if (rhashset->ReadRecoveryData(request.m_nPart * PARTSIZE, data)) { // finally all checks passed, everything seem to be fine AddDebugLogLine(DLP_DEFAULT, false, _T("AICH Packet Answer: Succeeded to read and validate received recovery data")); CAICHRecoveryHashSet::RemoveClientAICHRequest(this); @@ -2173,13 +2116,13 @@ void CUpDownClient::ProcessAICHAnswer(const uchar *packet, UINT size) void CUpDownClient::ProcessAICHRequest(const uchar *packet, UINT size) { if (size != (16u + 2u + CAICHHash::GetHashSize())) - throw CString(_T("Received AICH Request Packet with wrong size")); + throwCStr(_T("Received AICH Request Packet with wrong size")); CSafeMemFile data(packet, size); uchar abyHash[MDX_DIGEST_SIZE]; data.ReadHash16(abyHash); uint16 nPart = data.ReadUInt16(); - CAICHHash ahMasterHash(&data); + CAICHHash ahMasterHash(data); CKnownFile *pKnownFile = theApp.sharedfiles->GetFileByID(abyHash); if (pKnownFile != NULL) { const CFileIdentifier &fileid = pKnownFile->GetFileIdentifier(); @@ -2193,14 +2136,14 @@ void CUpDownClient::ProcessAICHRequest(const uchar *packet, UINT size) CSafeMemFile fileResponse; fileResponse.WriteHash16(pKnownFile->GetFileHash()); fileResponse.WriteUInt16(nPart); - fileid.GetAICHHash().Write(&fileResponse); + fileid.GetAICHHash().Write(fileResponse); CAICHRecoveryHashSet recHashSet(pKnownFile, pKnownFile->GetFileSize()); recHashSet.SetMasterHash(fileid.GetAICHHash(), AICH_HASHSETCOMPLETE); - if (recHashSet.CreatePartRecoveryData((uint64)nPart*PARTSIZE, &fileResponse)) { + if (recHashSet.CreatePartRecoveryData(nPart * PARTSIZE, fileResponse)) { AddDebugLogLine(DLP_HIGH, false, _T("AICH Packet Request: Successfully created and send recovery data for %s to %s"), (LPCTSTR)pKnownFile->GetFileName(), (LPCTSTR)DbgGetClientInfo()); if (thePrefs.GetDebugClientTCPLevel() > 0) DebugSend("OP_AichAnswer", this, pKnownFile->GetFileHash()); - Packet *packAnswer = new Packet(&fileResponse, OP_EMULEPROT, OP_AICHANSWER); + Packet *packAnswer = new Packet(fileResponse, OP_EMULEPROT, OP_AICHANSWER); theStats.AddUpDataOverheadFileRequest(packAnswer->size); SafeConnectAndSendPacket(packAnswer); return; @@ -2223,14 +2166,14 @@ void CUpDownClient::ProcessAICHFileHash(CSafeMemFile *data, CPartFile *file, con { CPartFile *pPartFile = file; if (pPartFile == NULL && data != NULL) { - uchar abyHash[16]; + uchar abyHash[MDX_DIGEST_SIZE]; data->ReadHash16(abyHash); pPartFile = theApp.downloadqueue->GetFileByID(abyHash); } CAICHHash ahMasterHash; if (pAICHHash == NULL) { if (data) - ahMasterHash.Read(data); + ahMasterHash.Read(*data); } else ahMasterHash = *pAICHHash; if (pPartFile != NULL && pPartFile == GetRequestFile()) { @@ -2241,7 +2184,7 @@ void CUpDownClient::ProcessAICHFileHash(CSafeMemFile *data, CPartFile *file, con // this a legacy client and he sent us a hash different from our verified one, which means // the file identifiers are different. We handle this just like a FNF-Answer to our download request // and remove the client from our sourcelist, because we sure don't want to download from him - pPartFile->m_DeadSourceList.AddDeadSource(this); + pPartFile->m_DeadSourceList.AddDeadSource(*this); DebugLogWarning(_T("Client answered with different AICH hash than local verified on in ProcessAICHFileHash, removing source. File %s, client %s"), (LPCTSTR)pPartFile->GetFileName(), (LPCTSTR)DbgGetClientInfo()); // if this client does not have my file but may hava a different one // we try to swap to other file while ignoring no needed parts files @@ -2263,9 +2206,8 @@ void CUpDownClient::ProcessAICHFileHash(CSafeMemFile *data, CPartFile *file, con case DS_NONEEDEDPARTS: case DS_DOWNLOADING: DontSwapTo(pPartFile); // ZZ:DownloadManager - if (!SwapToAnotherFile(_T("Source says it doesn't have the file (AICH mismatch). CUpDownClient::ProcessAICHFileHash"), true, true, true, NULL, false, false)) { // ZZ:DownloadManager + if (!SwapToAnotherFile(_T("Source says it doesn't have the file (AICH mismatch). CUpDownClient::ProcessAICHFileHash"), true, true, true, NULL, false, false)) // ZZ:DownloadManager theApp.downloadqueue->RemoveSource(this); - } } } } else @@ -2280,7 +2222,7 @@ void CUpDownClient::SendHashSetRequest() if (thePrefs.GetDebugClientTCPLevel() > 0) DebugSend("OP_HashSetRequest2", this, m_reqfile->GetFileHash()); CSafeMemFile filePacket(60); - m_reqfile->GetFileIdentifier().WriteIdentifier(&filePacket); + m_reqfile->GetFileIdentifier().WriteIdentifier(filePacket); // 6 Request Options - RESERVED // 1 Request AICH HashSet // 1 Request MD4 HashSet @@ -2302,7 +2244,7 @@ void CUpDownClient::SendHashSetRequest() DEBUG_ONLY(DebugLog(_T("Sending HashSet Request: MD4 %s, AICH %s to client %s"), m_fHashsetRequestingMD4 ? _T("Yes") : _T("No") , m_fHashsetRequestingAICH ? _T("Yes") : _T("No"), (LPCTSTR)DbgGetClientInfo())); filePacket.WriteUInt8(byOptions); - packet = new Packet(&filePacket, OP_EMULEPROT, OP_HASHSETREQUEST2); + packet = new Packet(filePacket, OP_EMULEPROT, OP_HASHSETREQUEST2); } else { if (thePrefs.GetDebugClientTCPLevel() > 0) DebugSend("OP_HashSetRequest", this, m_reqfile->GetFileHash()); diff --git a/srchybrid/DownloadClientsCtrl.cpp b/srchybrid/DownloadClientsCtrl.cpp index b2a618d5..2b687422 100644 --- a/srchybrid/DownloadClientsCtrl.cpp +++ b/srchybrid/DownloadClientsCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -21,13 +21,13 @@ #include "ClientDetailDialog.h" #include "MemDC.h" #include "MenuCmds.h" -#include "FriendList.h" #include "TransferDlg.h" -#include "ChatWnd.h" #include "UpDownClient.h" #include "UploadQueue.h" #include "ClientCredits.h" #include "PartFile.h" +#include "FriendList.h" +#include "ChatWnd.h" #include "Kademlia/Kademlia/Kademlia.h" #include "SharedFileList.h" @@ -60,59 +60,31 @@ void CDownloadClientsCtrl::Init() SetPrefsKey(_T("DownloadClientsCtrl")); SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP); - InsertColumn(0, GetResString(IDS_QL_USERNAME), LVCFMT_LEFT, DFLT_CLIENTNAME_COL_WIDTH); - InsertColumn(1, GetResString(IDS_CD_CSOFT), LVCFMT_LEFT, DFLT_CLIENTSOFT_COL_WIDTH); - InsertColumn(2, GetResString(IDS_FILE), LVCFMT_LEFT, DFLT_FILENAME_COL_WIDTH); - InsertColumn(3, GetResString(IDS_DL_SPEED), LVCFMT_RIGHT, DFLT_DATARATE_COL_WIDTH); - InsertColumn(4, GetResString(IDS_AVAILABLEPARTS), LVCFMT_LEFT, DFLT_PARTSTATUS_COL_WIDTH); - InsertColumn(5, GetResString(IDS_CL_TRANSFDOWN), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH); - InsertColumn(6, GetResString(IDS_CL_TRANSFUP), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH); - InsertColumn(7, GetResString(IDS_META_SRCTYPE), LVCFMT_LEFT, 100); + InsertColumn(0, _T(""), LVCFMT_LEFT, DFLT_CLIENTNAME_COL_WIDTH); //IDS_QL_USERNAME + InsertColumn(1, _T(""), LVCFMT_LEFT, DFLT_CLIENTSOFT_COL_WIDTH); //IDS_CD_CSOFT + InsertColumn(2, _T(""), LVCFMT_LEFT, DFLT_FILENAME_COL_WIDTH); //IDS_FILE + InsertColumn(3, _T(""), LVCFMT_RIGHT, DFLT_DATARATE_COL_WIDTH); //IDS_DL_SPEED + InsertColumn(4, _T(""), LVCFMT_LEFT, DFLT_PARTSTATUS_COL_WIDTH); //IDS_AVAILABLEPARTS + InsertColumn(5, _T(""), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH); //IDS_CL_TRANSFDOWN + InsertColumn(6, _T(""), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH); //IDS_CL_TRANSFUP + InsertColumn(7, _T(""), LVCFMT_LEFT, 100); //IDS_META_SRCTYPE SetAllIcons(); Localize(); LoadSettings(); SetSortArrow(); - SortItems(SortProc, GetSortItem() + (GetSortAscending() ? 0 : 100)); + SortItems(SortProc, MAKELONG(GetSortItem(), !GetSortAscending())); } void CDownloadClientsCtrl::Localize() { - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); - HDITEM hdi; - hdi.mask = HDI_TEXT; - - CString strRes(GetResString(IDS_QL_USERNAME)); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(0, &hdi); - - strRes = GetResString(IDS_CD_CSOFT); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(1, &hdi); - - strRes = GetResString(IDS_FILE); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(2, &hdi); - - strRes = GetResString(IDS_DL_SPEED); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(3, &hdi); - - strRes = GetResString(IDS_AVAILABLEPARTS); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(4, &hdi); - - strRes = GetResString(IDS_CL_TRANSFDOWN); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(5, &hdi); - - strRes = GetResString(IDS_CL_TRANSFUP); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(6, &hdi); + static const UINT uids[8] = + { + IDS_QL_USERNAME, IDS_CD_CSOFT, IDS_FILE, IDS_DL_SPEED, IDS_AVAILABLEPARTS + , IDS_CL_TRANSFDOWN, IDS_CL_TRANSFUP, IDS_META_SRCTYPE + }; - strRes = GetResString(IDS_META_SRCTYPE); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(7, &hdi); + LocaliseHeaderCtrl(uids, _countof(uids)); } void CDownloadClientsCtrl::OnSysColorChange() @@ -124,67 +96,67 @@ void CDownloadClientsCtrl::OnSysColorChange() void CDownloadClientsCtrl::SetAllIcons() { ApplyImageList(NULL); - m_pImageList = theApp.emuledlg->transferwnd->GetClientIconList(); // Apply the image list also to the listview control, even if we use our own 'DrawItem'. // This is needed to give the listview control a chance to initialize the row height. ASSERT((GetStyle() & LVS_SHAREIMAGELISTS) != 0); + m_pImageList = &theApp.emuledlg->GetClientIconList(); VERIFY(ApplyImageList(*m_pImageList) == NULL); } void CDownloadClientsCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { - if (theApp.IsClosing() || !lpDrawItemStruct->itemData) + if (!lpDrawItemStruct->itemData || theApp.IsClosing()) return; - CMemoryDC dc(CDC::FromHandle(lpDrawItemStruct->hDC), &lpDrawItemStruct->rcItem); + CRect rcItem(lpDrawItemStruct->rcItem); + CMemoryDC dc(CDC::FromHandle(lpDrawItemStruct->hDC), rcItem); BOOL bCtrlFocused; InitItemMemDC(dc, lpDrawItemStruct, bCtrlFocused); - CRect rcClient; - GetClientRect(rcClient); + RECT rcClient; + GetClientRect(&rcClient); const CUpDownClient *client = reinterpret_cast(lpDrawItemStruct->itemData); - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); + const CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); int iCount = pHeaderCtrl->GetItemCount(); - CRect rcItem(lpDrawItemStruct->rcItem); - rcItem.right = rcItem.left - sm_iLabelOffset; - rcItem.left += sm_iIconOffset; + LONG itemLeft = rcItem.left; + LONG iIconY = max((rcItem.Height() - 15) / 2, 0); for (int iCurrent = 0; iCurrent < iCount; ++iCurrent) { int iColumn = pHeaderCtrl->OrderToIndex(iCurrent); - if (!IsColumnHidden(iColumn)) { - UINT uDrawTextAlignment; - int iColumnWidth = GetColumnWidth(iColumn, uDrawTextAlignment); - rcItem.right += iColumnWidth; - if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) { - const CString &sItem(GetItemDisplayText(client, iColumn)); - switch (iColumn) { - case 0: - { - int iImage; - UINT uOverlayImage; - client->GetDisplayImage(iImage, uOverlayImage); - int iIconPosY = (rcItem.Height() > 16) ? ((rcItem.Height() - 16) / 2) : 1; - const POINT point = {rcItem.left, rcItem.top + iIconPosY}; - m_pImageList->Draw(dc, iImage, point, ILD_NORMAL | INDEXTOOVERLAYMASK(uOverlayImage)); - - rcItem.left += 16 + sm_iLabelOffset; - dc.DrawText(sItem, -1, &rcItem, MLC_DT_TEXT | uDrawTextAlignment); - rcItem.left -= 16; - rcItem.right -= sm_iSubItemInset; - } - break; - case 4: - ++rcItem.top; - --rcItem.bottom; - client->DrawStatusBar(dc, &rcItem, false, thePrefs.UseFlatBar()); - ++rcItem.bottom; - --rcItem.top; - break; - default: - dc.DrawText(sItem, -1, &rcItem, MLC_DT_TEXT | uDrawTextAlignment); + if (IsColumnHidden(iColumn)) + continue; + + UINT uDrawTextAlignment; + int iColumnWidth = GetColumnWidth(iColumn, uDrawTextAlignment); + rcItem.left = itemLeft; + rcItem.right = itemLeft + iColumnWidth; + if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) { + const CString &sItem(GetItemDisplayText(client, iColumn)); + switch (iColumn) { + case 0: //user name + { + int iImage; + UINT uOverlayImage; + client->GetDisplayImage(iImage, uOverlayImage); + + rcItem.left += sm_iIconOffset; + const POINT point = { rcItem.left, rcItem.top + iIconY }; + m_pImageList->Draw(dc, iImage, point, ILD_NORMAL | INDEXTOOVERLAYMASK(uOverlayImage)); + rcItem.left += 16 + sm_iLabelOffset - sm_iSubItemInset; } + default: //any text column + rcItem.left += sm_iSubItemInset; + rcItem.right -= sm_iSubItemInset; + dc.DrawText(sItem, -1, &rcItem, MLC_DT_TEXT | uDrawTextAlignment); + break; + case 4: //download status bar + ++rcItem.top; + --rcItem.bottom; + client->DrawStatusBar(dc, &rcItem, false, thePrefs.UseFlatBar()); + ++rcItem.bottom; + --rcItem.top; } - rcItem.left += iColumnWidth; } + itemLeft += iColumnWidth; } DrawFocusRect(dc, &lpDrawItemStruct->rcItem, lpDrawItemStruct->itemState & ODS_FOCUS, bCtrlFocused, lpDrawItemStruct->itemState & ODS_SELECTED); @@ -256,16 +228,16 @@ CString CDownloadClientsCtrl::GetItemDisplayText(const CUpDownClient *client, in void CDownloadClientsCtrl::OnLvnGetDispInfo(LPNMHDR pNMHDR, LRESULT *pResult) { if (!theApp.IsClosing()) { - // Although we have an owner drawn listview control we store the text for the primary item in the listview, to be - // capable of quick searching those items via the keyboard. Because our listview items may change their contents, - // we do this via a text callback function. The listview control will send us the LVN_DISPINFO notification if - // it needs to know the contents of the primary item. + // Although we have an owner drawn listview control we store the text for the primary item in the + // listview, to be capable of quick searching those items via the keyboard. Because our listview + // items may change their contents, we do this via a text callback function. The listview control + // will send us the LVN_DISPINFO notification if it needs to know the contents of the primary item. // - // But, the listview control sends this notification all the time, even if we do not search for an item. At least - // this notification is only sent for the visible items and not for all items in the list. Though, because this - // function is invoked *very* often, do *NOT* put any time consuming code in here. + // But, the listview control sends this notification all the time, even if we do not search for an item. + // At least this notification is only sent for the visible items and not for all items in the list. + // Though, because this function is invoked *very* often, do *NOT* put any time consuming code in here. // - // Vista: That callback is used to get the strings for the label tips for the sub(!) items. + // Vista: That callback is used to get the strings for the label tips for the sub(!)-items. // const LVITEMW &rItem = reinterpret_cast(pNMHDR)->item; if (rItem.mask & LVIF_TEXT) { @@ -279,12 +251,10 @@ void CDownloadClientsCtrl::OnLvnGetDispInfo(LPNMHDR pNMHDR, LRESULT *pResult) void CDownloadClientsCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) { - NMLISTVIEW *pNMListView = reinterpret_cast(pNMHDR); + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); bool sortAscending; - if (GetSortItem() == pNMListView->iSubItem) - sortAscending = !GetSortAscending(); - else - switch (pNMListView->iSubItem) { + if (GetSortItem() != pNMLV->iSubItem) + switch (pNMLV->iSubItem) { case 1: // Client Software case 3: // Download Rate case 4: // Part Count @@ -295,12 +265,13 @@ void CDownloadClientsCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) default: sortAscending = true; } + else + sortAscending = !GetSortAscending(); // Sort table - UpdateSortHistory(pNMListView->iSubItem + (sortAscending ? 0 : 100)); - SetSortArrow(pNMListView->iSubItem, sortAscending); - SortItems(SortProc, pNMListView->iSubItem + (sortAscending ? 0 : 100)); - + UpdateSortHistory(MAKELONG(pNMLV->iSubItem, !sortAscending)); + SetSortArrow(pNMLV->iSubItem, sortAscending); + SortItems(SortProc, MAKELONG(pNMLV->iSubItem, !sortAscending)); *pResult = 0; } @@ -308,9 +279,9 @@ int CALLBACK CDownloadClientsCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPAR { const CUpDownClient *item1 = reinterpret_cast(lParam1); const CUpDownClient *item2 = reinterpret_cast(lParam2); - LPARAM iColumn = (lParamSort >= 100) ? lParamSort - 100 : lParamSort; + int iResult = 0; - switch (iColumn) { + switch (LOWORD(lParamSort)) { case 0: //user name if (item1->GetUserName() && item2->GetUserName()) iResult = CompareLocaleStringNoCase(item1->GetUserName(), item2->GetUserName()); @@ -325,7 +296,7 @@ int CALLBACK CDownloadClientsCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPAR else iResult = -(item1->GetClientSoft() - item2->GetClientSoft()); // invert result to place eMule's at top break; - case 2: + case 2: //file name { const CKnownFile *file1 = item1->GetRequestFile(); const CKnownFile *file2 = item2->GetRequestFile(); @@ -343,24 +314,24 @@ int CALLBACK CDownloadClientsCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPAR case 4: //part count iResult = CompareUnsigned(item1->GetPartCount(), item2->GetPartCount()); break; - case 5: //download sessions + case 5: //session download iResult = CompareUnsigned(item1->GetSessionDown(), item2->GetSessionDown()); break; - case 6: + case 6: //session upload iResult = CompareUnsigned(item1->GetSessionUp(), item2->GetSessionUp()); break; - case 7: + case 7: //source origin iResult = item1->GetSourceFrom() - item2->GetSourceFrom(); } - if (lParamSort >= 100) + if (HIWORD(lParamSort)) iResult = -iResult; - //call secondary sort order, if this one's results is equal + //call secondary sort order, if the first one resulted as equal if (iResult == 0) { - int dwNextSort = theApp.emuledlg->transferwnd->GetDownloadClientsList()->GetNextSortOrder((int)lParamSort); - if (dwNextSort != -1) - iResult = SortProc(lParam1, lParam2, dwNextSort); + LPARAM iNextSort = theApp.emuledlg->transferwnd->GetDownloadClientsList()->GetNextSortOrder(lParamSort); + if (iNextSort != -1) + iResult = SortProc(lParam1, lParam2, iNextSort); } return iResult; @@ -368,15 +339,15 @@ int CALLBACK CDownloadClientsCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPAR void CDownloadClientsCtrl::OnNmDblClk(LPNMHDR, LRESULT *pResult) { -int iSel = GetNextItem(-1, LVIS_SELECTED | LVIS_FOCUSED); -if (iSel >= 0) { - CUpDownClient *client = reinterpret_cast(GetItemData(iSel)); - if (client) { - CClientDetailDialog dialog(client, this); - dialog.DoModal(); + int iSel = GetNextItem(-1, LVIS_SELECTED | LVIS_FOCUSED); + if (iSel >= 0) { + CUpDownClient *client = reinterpret_cast(GetItemData(iSel)); + if (client) { + CClientDetailDialog dialog(client, this); + dialog.DoModal(); + } } -} -*pResult = 0; + *pResult = 0; } void CDownloadClientsCtrl::OnContextMenu(CWnd*, CPoint point) @@ -436,7 +407,7 @@ BOOL CDownloadClientsCtrl::OnCommand(WPARAM wParam, LPARAM) Kademlia::CKademlia::Bootstrap(ntohl(client->GetIP()), client->GetKadPort()); } } - return true; + return TRUE; } void CDownloadClientsCtrl::AddClient(const CUpDownClient *client) @@ -446,7 +417,7 @@ void CDownloadClientsCtrl::AddClient(const CUpDownClient *client) int iItemCount = GetItemCount(); InsertItem(LVIF_TEXT | LVIF_PARAM, iItemCount, LPSTR_TEXTCALLBACK, 0, 0, 0, (LPARAM)client); - theApp.emuledlg->transferwnd->UpdateListCount(CTransferDlg::wnd2Downloading, iItemCount + 1); + theApp.emuledlg->transferwnd->UpdateListCount(CTransferWnd::wnd2Downloading, iItemCount + 1); } void CDownloadClientsCtrl::RemoveClient(const CUpDownClient *client) @@ -460,14 +431,14 @@ void CDownloadClientsCtrl::RemoveClient(const CUpDownClient *client) int iItem = FindItem(&find); if (iItem >= 0) { DeleteItem(iItem); - theApp.emuledlg->transferwnd->UpdateListCount(CTransferDlg::wnd2Downloading, GetItemCount()); + theApp.emuledlg->transferwnd->UpdateListCount(CTransferWnd::wnd2Downloading, GetItemCount()); } } void CDownloadClientsCtrl::RefreshClient(const CUpDownClient *client) { - if (!theApp.IsClosing() - && theApp.emuledlg->activewnd == theApp.emuledlg->transferwnd + if (theApp.emuledlg->activewnd == theApp.emuledlg->transferwnd + && !theApp.IsClosing() && theApp.emuledlg->transferwnd->GetDownloadClientsList()->IsWindowVisible()) { LVFINDINFO find; diff --git a/srchybrid/DownloadClientsCtrl.h b/srchybrid/DownloadClientsCtrl.h index 10212847..64d20e37 100644 --- a/srchybrid/DownloadClientsCtrl.h +++ b/srchybrid/DownloadClientsCtrl.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -37,7 +37,7 @@ class CDownloadClientsCtrl : public CMuleListCtrl, public CListCtrlItemWalk void ShowSelectedUserDetails(); protected: - CImageList* m_pImageList; + CImageList *m_pImageList; void SetAllIcons(); CString GetItemDisplayText(const CUpDownClient *client, int iSubItem) const; diff --git a/srchybrid/DownloadListCtrl.cpp b/srchybrid/DownloadListCtrl.cpp index 787849d8..c56a588e 100644 --- a/srchybrid/DownloadListCtrl.cpp +++ b/srchybrid/DownloadListCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -17,7 +17,6 @@ #include "stdafx.h" #include "emule.h" #include "DownloadListCtrl.h" -#include "otherfunctions.h" #include "updownclient.h" #include "MenuCmds.h" #include "ClientDetailDialog.h" @@ -41,7 +40,6 @@ #include "Preview.h" #include "StringConversion.h" #include "AddSourceDlg.h" -#include "ToolTipCtrlX.h" #include "CollectionViewDialog.h" #include "SearchDlg.h" #include "SharedFileList.h" @@ -87,7 +85,6 @@ CDownloadListCtrl::CDownloadListCtrl() , m_dwLastAvailableCommandsCheck() , m_availableCommandsDirty(true) { - m_tooltip = new CToolTipCtrlX; SetGeneralPurposeFind(true); SetSkinKey(_T("DownloadsLv")); } @@ -107,7 +104,6 @@ CDownloadListCtrl::~CDownloadListCtrl() delete m_ListItems.begin()->second; // second = CtrlItem_Struct* m_ListItems.erase(m_ListItems.begin()); } - delete m_tooltip; } void CDownloadListCtrl::Init() @@ -118,31 +114,27 @@ void CDownloadListCtrl::Init() CToolTipCtrl *tooltip = GetToolTips(); if (tooltip) { - m_tooltip->SetFileIconToolTip(true); - m_tooltip->SubclassWindow(*tooltip); + m_tooltip.SetFileIconToolTip(true); + m_tooltip.SubclassWindow(*tooltip); tooltip->ModifyStyle(0, TTS_NOPREFIX); tooltip->SetDelayTime(TTDT_AUTOPOP, SEC2MS(20)); tooltip->SetDelayTime(TTDT_INITIAL, SEC2MS(thePrefs.GetToolTipDelay())); } - InsertColumn(0, GetResString(IDS_DL_FILENAME), LVCFMT_LEFT, DFLT_FILENAME_COL_WIDTH); - InsertColumn(1, GetResString(IDS_DL_SIZE), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH); - InsertColumn(2, GetResString(IDS_DL_TRANSF), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH, -1, true); - InsertColumn(3, GetResString(IDS_DL_TRANSFCOMPL), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH); - InsertColumn(4, GetResString(IDS_DL_SPEED), LVCFMT_RIGHT, DFLT_DATARATE_COL_WIDTH); - InsertColumn(5, GetResString(IDS_DL_PROGRESS), LVCFMT_LEFT, DFLT_PARTSTATUS_COL_WIDTH); - InsertColumn(6, GetResString(IDS_DL_SOURCES), LVCFMT_RIGHT, 60); - InsertColumn(7, GetResString(IDS_PRIORITY), LVCFMT_LEFT, DFLT_PRIORITY_COL_WIDTH); - InsertColumn(8, GetResString(IDS_STATUS), LVCFMT_LEFT, 70); - InsertColumn(9, GetResString(IDS_DL_REMAINS), LVCFMT_LEFT, 110); - CString stitle(GetResString(IDS_LASTSEENCOMPL)); - stitle.Remove(_T(':')); - InsertColumn(10, stitle, LVCFMT_LEFT, 150, -1, true); - stitle = GetResString(IDS_FD_LASTCHANGE); - stitle.Remove(_T(':')); - InsertColumn(11, stitle, LVCFMT_LEFT, 120, -1, true); - InsertColumn(12, GetResString(IDS_CAT), LVCFMT_LEFT, 100, -1, true); - InsertColumn(13, GetResString(IDS_ADDEDON), LVCFMT_LEFT, 120); + InsertColumn(0, _T(""), LVCFMT_LEFT, DFLT_FILENAME_COL_WIDTH); //IDS_DL_FILENAME + InsertColumn(1, _T(""), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH); //IDS_DL_SIZE + InsertColumn(2, _T(""), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH, -1, true); //IDS_DL_TRANSF + InsertColumn(3, _T(""), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH); //IDS_DL_TRANSFCOMPL + InsertColumn(4, _T(""), LVCFMT_RIGHT, DFLT_DATARATE_COL_WIDTH); //IDS_DL_SPEED + InsertColumn(5, _T(""), LVCFMT_LEFT, DFLT_PARTSTATUS_COL_WIDTH); //IDS_DL_PROGRESS + InsertColumn(6, _T(""), LVCFMT_RIGHT, 60); //IDS_DL_SOURCES + InsertColumn(7, _T(""), LVCFMT_LEFT, DFLT_PRIORITY_COL_WIDTH); //IDS_PRIORITY + InsertColumn(8, _T(""), LVCFMT_LEFT, 70); //IDS_STATUS + InsertColumn(9, _T(""), LVCFMT_LEFT, 110); //IDS_DL_REMAINS + InsertColumn(10, _T(""), LVCFMT_LEFT, 150, -1, true); //IDS_LASTSEENCOMPL + InsertColumn(11, _T(""), LVCFMT_LEFT, 120, -1, true); //IDS_FD_LASTCHANGE + InsertColumn(12, _T(""), LVCFMT_LEFT, 100, -1, true); //IDS_CAT + InsertColumn(13, _T(""), LVCFMT_LEFT, 120); //IDS_ADDEDON SetAllIcons(); Localize(); @@ -169,9 +161,9 @@ void CDownloadListCtrl::Init() adder = 0; } else { SetSortArrow(GetSortItem(), GetSortAscending() ? arrowDoubleUp : arrowDoubleDown); - adder = 81; + adder = 81; //9+81=90 - used in Compare(,,) } - SortItems(SortProc, GetSortItem() + (GetSortAscending() ? 0 : 100) + adder); + SortItems(SortProc, MAKELONG(GetSortItem() + adder, !GetSortAscending())); } void CDownloadListCtrl::OnSysColorChange() @@ -186,27 +178,27 @@ void CDownloadListCtrl::SetAllIcons() ApplyImageList(NULL); m_ImageList.DeleteImageList(); m_ImageList.Create(16, 16, theApp.m_iDfltImageListColorFlags | ILC_MASK, 0, 1); - m_ImageList.Add(CTempIconLoader(_T("SrcDownloading"))); - m_ImageList.Add(CTempIconLoader(_T("SrcOnQueue"))); - m_ImageList.Add(CTempIconLoader(_T("SrcConnecting"))); - m_ImageList.Add(CTempIconLoader(_T("SrcNNPQF"))); - m_ImageList.Add(CTempIconLoader(_T("SrcUnknown"))); - m_ImageList.Add(CTempIconLoader(_T("ClientCompatible"))); - m_ImageList.Add(CTempIconLoader(_T("Friend"))); - m_ImageList.Add(CTempIconLoader(_T("ClientEDonkey"))); - m_ImageList.Add(CTempIconLoader(_T("ClientMLDonkey"))); - m_ImageList.Add(CTempIconLoader(_T("ClientEDonkeyHybrid"))); - m_ImageList.Add(CTempIconLoader(_T("ClientShareaza"))); - m_ImageList.Add(CTempIconLoader(_T("Server"))); - m_ImageList.Add(CTempIconLoader(_T("ClientAMule"))); - m_ImageList.Add(CTempIconLoader(_T("ClientLPhant"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_NotRated"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_Fake"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_Poor"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_Fair"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_Good"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_Excellent"))); - m_ImageList.Add(CTempIconLoader(_T("Collection_Search"))); // rating for comments are searched on kad + m_ImageList.Add(CTempIconLoader(_T("SrcDownloading"))); //0 + m_ImageList.Add(CTempIconLoader(_T("SrcOnQueue"))); //1 + m_ImageList.Add(CTempIconLoader(_T("SrcConnecting"))); //2 + m_ImageList.Add(CTempIconLoader(_T("SrcNNPQF"))); //3 + m_ImageList.Add(CTempIconLoader(_T("SrcUnknown"))); //4 + m_ImageList.Add(CTempIconLoader(_T("ClientCompatible")));//5 + m_ImageList.Add(CTempIconLoader(_T("Friend"))); //6 + m_ImageList.Add(CTempIconLoader(_T("ClientEDonkey"))); //7 + m_ImageList.Add(CTempIconLoader(_T("ClientMLDonkey"))); //8 + m_ImageList.Add(CTempIconLoader(_T("ClientEDonkeyHybrid")));//9 + m_ImageList.Add(CTempIconLoader(_T("ClientShareaza"))); //10 + m_ImageList.Add(CTempIconLoader(_T("Server"))); //11 + m_ImageList.Add(CTempIconLoader(_T("ClientAMule"))); //12 + m_ImageList.Add(CTempIconLoader(_T("ClientLPhant"))); //13 + m_ImageList.Add(CTempIconLoader(_T("Rating_NotRated")));//14 + m_ImageList.Add(CTempIconLoader(_T("Rating_Fake"))); //15 + m_ImageList.Add(CTempIconLoader(_T("Rating_Poor"))); //16 + m_ImageList.Add(CTempIconLoader(_T("Rating_Fair"))); //17 + m_ImageList.Add(CTempIconLoader(_T("Rating_Good"))); //18 + m_ImageList.Add(CTempIconLoader(_T("Rating_Excellent")));//19 + m_ImageList.Add(CTempIconLoader(_T("Collection_Search"))); //20 rating for comments are searched on kad m_ImageList.SetOverlayImage(m_ImageList.Add(CTempIconLoader(_T("ClientSecureOvl"))), 1); m_ImageList.SetOverlayImage(m_ImageList.Add(CTempIconLoader(_T("OverlayObfu"))), 2); m_ImageList.SetOverlayImage(m_ImageList.Add(CTempIconLoader(_T("OverlaySecureObfu"))), 3); @@ -218,24 +210,20 @@ void CDownloadListCtrl::SetAllIcons() void CDownloadListCtrl::Localize() { - static const UINT uids[10] = + static const UINT uids[14] = { IDS_DL_FILENAME, IDS_DL_SIZE, IDS_DL_TRANSF, IDS_DL_TRANSFCOMPL, IDS_DL_SPEED , IDS_DL_PROGRESS, IDS_DL_SOURCES, IDS_PRIORITY, IDS_STATUS, IDS_DL_REMAINS + , 0/*IDS_LASTSEENCOMPL*/, 0/*IDS_FD_LASTCHANGE*/, IDS_CAT, IDS_ADDEDON }; + LocaliseHeaderCtrl(uids, _countof(uids)); + CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); HDITEM hdi; hdi.mask = HDI_TEXT; - CString strRes; - - for (int i = 0; i < _countof(uids); ++i) { - strRes = GetResString(uids[i]); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(i, &hdi); - } - strRes = GetResString(IDS_LASTSEENCOMPL); + CString strRes(GetResString(IDS_LASTSEENCOMPL)); strRes.Remove(_T(':')); hdi.pszText = const_cast((LPCTSTR)strRes); pHeaderCtrl->SetItem(10, &hdi); @@ -245,14 +233,6 @@ void CDownloadListCtrl::Localize() hdi.pszText = const_cast((LPCTSTR)strRes); pHeaderCtrl->SetItem(11, &hdi); - strRes = GetResString(IDS_CAT); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(12, &hdi); - - strRes = GetResString(IDS_ADDEDON); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(13, &hdi); - CreateMenus(); ShowFilesCount(); } @@ -270,7 +250,7 @@ void CDownloadListCtrl::AddFile(CPartFile *toadd) // The same file shall be added only once ASSERT(m_ListItems.find(toadd) == m_ListItems.end()); - m_ListItems.insert(ListItemsPair(toadd, newitem)); + m_ListItems.emplace(toadd, newitem); if (toadd->CheckShowItemInGivenCat(curTab)) InsertItem(LVIF_PARAM | LVIF_TEXT, itemnr, LPSTR_TEXTCALLBACK, 0, 0, 0, (LPARAM)newitem); @@ -280,31 +260,16 @@ void CDownloadListCtrl::AddFile(CPartFile *toadd) void CDownloadListCtrl::AddSource(CPartFile *owner, CUpDownClient *source, bool notavailable) { - // Create new Item - CtrlItem_Struct *newitem = new CtrlItem_Struct; - newitem->owner = owner; - newitem->type = (notavailable ? UNAVAILABLE_SOURCE : AVAILABLE_SOURCE); - newitem->value = source; - newitem->dwUpdated = 0; - - // Update cross link to the owner - ListItems::const_iterator ownerIt = m_ListItems.find(owner); - ASSERT(ownerIt != m_ListItems.end()); - CtrlItem_Struct *ownerItem = ownerIt->second; - ASSERT(ownerItem->value == owner); - newitem->parent = ownerItem; - - // The same source could be added a few times but only one time per file - + ItemType itemtype = notavailable ? UNAVAILABLE_SOURCE : AVAILABLE_SOURCE; // Update the other instances of this source bool bFound = false; - for (ListItems::const_iterator it = m_ListItems.find(source); it != m_ListItems.end() && it->first == source; ++it) { + for (ListItems::const_iterator it = m_ListItems.lower_bound(source); it != m_ListItems.end() && it->first == source; ++it) { CtrlItem_Struct *cur_item = it->second; // Check if this source has been already added to this file => to be sure if (cur_item->owner == owner) { // Update this instance with its new setting - cur_item->type = newitem->type; + cur_item->type = itemtype; cur_item->dwUpdated = 0; bFound = true; } else if (!notavailable) { @@ -314,12 +279,24 @@ void CDownloadListCtrl::AddSource(CPartFile *owner, CUpDownClient *source, bool } } - if (bFound) { - delete newitem; + // The same source could be added a few times but only once per file + if (bFound) return; - } - - m_ListItems.insert(ListItemsPair(source, newitem)); + + ListItems::const_iterator ownerIt = m_ListItems.find(owner); + ASSERT(ownerIt != m_ListItems.end()); + CtrlItem_Struct *ownerItem = ownerIt->second; + ASSERT(ownerItem->value == owner); + + // Create new Item + CtrlItem_Struct *newitem = new CtrlItem_Struct; + newitem->type = itemtype; + newitem->owner = owner; + newitem->value = source; + newitem->parent = ownerItem; // cross link to the owner + newitem->dwUpdated = 0; + + m_ListItems.emplace(source, newitem); if (owner->srcarevisible) { // find parent from the CListCtrl to add source @@ -338,7 +315,7 @@ void CDownloadListCtrl::RemoveSource(CUpDownClient *source, CPartFile *owner) return; // Retrieve all entries matching the source - for (ListItems::const_iterator it = m_ListItems.find(source); it != m_ListItems.end() && it->first == source;) { + for (ListItems::const_iterator it = m_ListItems.lower_bound(source); it != m_ListItems.end() && it->first == source;) { const CtrlItem_Struct *delItem = it->second; if (owner == NULL || owner == delItem->owner) { // Remove it from the m_ListItems @@ -352,7 +329,7 @@ void CDownloadListCtrl::RemoveSource(CUpDownClient *source, CPartFile *owner) if (iItem >= 0) DeleteItem(iItem); - // finally it could be delete + // finally it could be deleted delete delItem; } else ++it; @@ -397,7 +374,7 @@ void CDownloadListCtrl::UpdateItem(void *toupdate) return; // Retrieve all entries matching the source - for (ListItems::const_iterator it = m_ListItems.find(toupdate); it != m_ListItems.end() && it->first == toupdate; ++it) { + for (ListItems::const_iterator it = m_ListItems.lower_bound(toupdate); it != m_ListItems.end() && it->first == toupdate; ++it) { CtrlItem_Struct *updateItem = it->second; // Find entry in CListCtrl and update object @@ -421,14 +398,14 @@ void CDownloadListCtrl::DrawFileItem(CDC *dc, int nColumn, LPCRECT lpRect, UINT switch (nColumn) { case 0: // file name { - int iIconPosY = (rcDraw.Height() > theApp.GetSmallSytemIconSize().cy) ? ((rcDraw.Height() - theApp.GetSmallSytemIconSize().cy) / 2) : 0; + LONG iIconPosY = max((rcDraw.Height() - theApp.GetSmallSytemIconSize().cy) / 2, 0); int iImage = theApp.GetFileTypeSystemImageIdx(pPartFile->GetFileName()); if (theApp.GetSystemImageList() != NULL) ::ImageList_Draw(theApp.GetSystemImageList(), iImage, dc->GetSafeHdc(), rcDraw.left, rcDraw.top + iIconPosY, ILD_TRANSPARENT); rcDraw.left += theApp.GetSmallSytemIconSize().cx; if (thePrefs.ShowRatingIndicator() && (pPartFile->HasComment() || pPartFile->HasRating() || pPartFile->IsKadCommentSearchRunning())) { - m_ImageList.Draw(dc, pPartFile->UserRating(true) + 14, CPoint(rcDraw.left + 2, rcDraw.top + iIconPosY), ILD_NORMAL); + m_ImageList.Draw(dc, 14 + pPartFile->UserRating(true), CPoint(rcDraw.left + 2, rcDraw.top + iIconPosY), ILD_NORMAL); rcDraw.left += 2 + RATING_ICON_WIDTH; } @@ -438,8 +415,8 @@ void CDownloadListCtrl::DrawFileItem(CDC *dc, int nColumn, LPCRECT lpRect, UINT break; case 5: // progress { - rcDraw.bottom--; - rcDraw.top++; + --rcDraw.bottom; + ++rcDraw.top; int iWidth = rcDraw.Width(); int iHeight = rcDraw.Height(); @@ -449,15 +426,15 @@ void CDownloadListCtrl::DrawFileItem(CDC *dc, int nColumn, LPCRECT lpRect, UINT HGDIOBJ hOldBitmap; cdcStatus.CreateCompatibleDC(dc); int cx = pCtrlItem->status.GetBitmapDimension().cx; - DWORD dwTicks = ::GetTickCount(); - if (dwTicks >= pCtrlItem->dwUpdated + DLC_BARUPDATE || cx != iWidth || !pCtrlItem->dwUpdated) { + const DWORD curTick = ::GetTickCount(); + if (curTick >= pCtrlItem->dwUpdated + DLC_BARUPDATE || cx != iWidth || !pCtrlItem->dwUpdated) { pCtrlItem->status.DeleteObject(); pCtrlItem->status.CreateCompatibleBitmap(dc, iWidth, iHeight); hOldBitmap = cdcStatus.SelectObject(pCtrlItem->status); CRect rec_status(0, 0, iWidth, iHeight); pPartFile->DrawStatusBar(&cdcStatus, rec_status, thePrefs.UseFlatBar()); - pCtrlItem->dwUpdated = dwTicks + (rand() & 0x7f); + pCtrlItem->dwUpdated = curTick + (rand() & 0x7f); } else hOldBitmap = cdcStatus.SelectObject(pCtrlItem->status); dc->BitBlt(rcDraw.left, rcDraw.top, iWidth, iHeight, &cdcStatus, 0, 0, SRCCOPY); @@ -466,7 +443,7 @@ void CDownloadListCtrl::DrawFileItem(CDC *dc, int nColumn, LPCRECT lpRect, UINT if (thePrefs.GetUseDwlPercentage()) { COLORREF oldclr = dc->SetTextColor(RGB(255, 255, 255)); int iOMode = dc->SetBkMode(TRANSPARENT); - dc->DrawText(sItem.Mid(sItem.ReverseFind(_T(' ')) + 1), -1, rcDraw, (MLC_DT_TEXT & ~DT_LEFT) | DT_CENTER); + dc->DrawText(CPTR(sItem, sItem.ReverseFind(_T(' ')) + 1), -1, rcDraw, (MLC_DT_TEXT & ~DT_LEFT) | DT_CENTER); dc->SetBkMode(iOMode); dc->SetTextColor(oldclr); } @@ -586,9 +563,9 @@ void CDownloadListCtrl::DrawSourceItem(CDC *dc, int nColumn, LPCRECT lpRect, UIN case 0: // icon, name, status { CRect rcItem(*lpRect); - int iIconPosY = (rcItem.Height() > 16) ? ((rcItem.Height() - 16) / 2) : 1; + int iIconPosY = (rcItem.Height() > 16) ? ((rcItem.Height() - 15) / 2) : 0; POINT point = {rcItem.left, rcItem.top + iIconPosY}; - int nImg; + int iImage; if (pCtrlItem->type == AVAILABLE_SOURCE) { switch (pClient->GetDownloadState()) { case DS_CONNECTED: @@ -597,60 +574,57 @@ void CDownloadListCtrl::DrawSourceItem(CDC *dc, int nColumn, LPCRECT lpRect, UIN case DS_WAITCALLBACKKAD: case DS_TOOMANYCONNS: case DS_TOOMANYCONNSKAD: - nImg = 2; + iImage = 2; break; case DS_ONQUEUE: - nImg = pClient->IsRemoteQueueFull() ? 3 : 1; + iImage = pClient->IsRemoteQueueFull() ? 3 : 1; break; case DS_DOWNLOADING: case DS_REQHASHSET: - nImg = 0; + iImage = 0; break; case DS_NONEEDEDPARTS: case DS_ERROR: - nImg = 3; + iImage = 3; break; default: - nImg = 4; + iImage = 4; } } else - nImg = 3; - m_ImageList.Draw(dc, nImg, point, ILD_NORMAL); + iImage = 3; + m_ImageList.Draw(dc, iImage, point, ILD_NORMAL); rcItem.left += 20; - UINT uOvlImg = 0; - if ((pClient->Credits() && pClient->Credits()->GetCurrentIdentState(pClient->GetIP()) == IS_IDENTIFIED)) - uOvlImg |= 1; - if (pClient->IsObfuscatedConnectionEstablished()) - uOvlImg |= 2; + UINT uOvlImg = static_cast((pClient->Credits() && pClient->Credits()->GetCurrentIdentState(pClient->GetIP()) == IS_IDENTIFIED)); + uOvlImg |= (static_cast(pClient->IsObfuscatedConnectionEstablished()) << 1); - POINT point2 = {rcItem.left, rcItem.top + iIconPosY}; if (pClient->IsFriend()) - nImg = 6; + iImage = 6; else switch (pClient->GetClientSoft()) { case SO_EDONKEYHYBRID: - nImg = 9; + iImage = 9; break; case SO_MLDONKEY: - nImg = 8; + iImage = 8; break; case SO_SHAREAZA: - nImg = 10; + iImage = 10; break; case SO_URL: - nImg = 11; + iImage = 11; break; case SO_AMULE: - nImg = 12; + iImage = 12; break; case SO_LPHANT: - nImg = 13; + iImage = 13; break; default: - nImg = pClient->ExtProtocolAvailable() ? 5 : 7; + iImage = pClient->ExtProtocolAvailable() ? 5 : 7; } - m_ImageList.Draw(dc, nImg, point2, ILD_NORMAL | INDEXTOOVERLAYMASK(uOvlImg)); + const POINT point2 = { rcItem.left, rcItem.top + iIconPosY }; + m_ImageList.Draw(dc, iImage, point2, ILD_NORMAL | INDEXTOOVERLAYMASK(uOvlImg)); rcItem.left += 20; dc->DrawText(sItem, -1, &rcItem, MLC_DT_TEXT | uDrawTextAlignment); @@ -659,26 +633,26 @@ void CDownloadListCtrl::DrawSourceItem(CDC *dc, int nColumn, LPCRECT lpRect, UIN case 5: // file info { CRect rcDraw(lpRect); - rcDraw.bottom--; - rcDraw.top++; + --rcDraw.bottom; + ++rcDraw.top; int iWidth = rcDraw.Width(); int iHeight = rcDraw.Height(); if (pCtrlItem->status == (HBITMAP)NULL) VERIFY(pCtrlItem->status.CreateBitmap(1, 1, 1, 8, NULL)); - CDC cdcStatus; HGDIOBJ hOldBitmap; + CDC cdcStatus; cdcStatus.CreateCompatibleDC(dc); int cx = pCtrlItem->status.GetBitmapDimension().cx; - DWORD dwTicks = ::GetTickCount(); - if (dwTicks >= pCtrlItem->dwUpdated + DLC_BARUPDATE || cx != iWidth || !pCtrlItem->dwUpdated) { + const DWORD curTick = ::GetTickCount(); + if (curTick >= pCtrlItem->dwUpdated + DLC_BARUPDATE || cx != iWidth || !pCtrlItem->dwUpdated) { pCtrlItem->status.DeleteObject(); pCtrlItem->status.CreateCompatibleBitmap(dc, iWidth, iHeight); hOldBitmap = cdcStatus.SelectObject(pCtrlItem->status); CRect rec_status(0, 0, iWidth, iHeight); pClient->DrawStatusBar(&cdcStatus, rec_status, (pCtrlItem->type == UNAVAILABLE_SOURCE), thePrefs.UseFlatBar()); - pCtrlItem->dwUpdated = dwTicks + (rand() & 0x7f); + pCtrlItem->dwUpdated = curTick + (rand() & 0x7f); } else hOldBitmap = cdcStatus.SelectObject(pCtrlItem->status); dc->BitBlt(rcDraw.left, rcDraw.top, iWidth, iHeight, &cdcStatus, 0, 0, SRCCOPY); @@ -698,14 +672,14 @@ void CDownloadListCtrl::DrawSourceItem(CDC *dc, int nColumn, LPCRECT lpRect, UIN void CDownloadListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { - if (theApp.IsClosing() || !lpDrawItemStruct->itemData) + if (!lpDrawItemStruct->itemData || theApp.IsClosing()) return; - CMemoryDC dc(CDC::FromHandle(lpDrawItemStruct->hDC), &lpDrawItemStruct->rcItem); + RECT rcItem(lpDrawItemStruct->rcItem); + CMemoryDC dc(CDC::FromHandle(lpDrawItemStruct->hDC), &rcItem); BOOL bCtrlFocused; InitItemMemDC(dc, lpDrawItemStruct, bCtrlFocused); - RECT rcItem(lpDrawItemStruct->rcItem); - CRect rcClient; + RECT rcClient; GetClientRect(&rcClient); CtrlItem_Struct *content = reinterpret_cast(lpDrawItemStruct->itemData); if (m_pFontBold) @@ -715,89 +689,51 @@ void CDownloadListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { dc.SelectObject(m_pFontBold); } - BOOL notLast = lpDrawItemStruct->itemID + 1 != (UINT)GetItemCount(); - BOOL notFirst = lpDrawItemStruct->itemID != 0; + + bool isChild = content->type != FILE_TYPE; + bool notLast = lpDrawItemStruct->itemID + 1 < (UINT)GetItemCount(); + bool notFirst = lpDrawItemStruct->itemID > 0; int tree_start = 0; int tree_end = 0; - int iTreeOffset = 6; - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); + int iTreeOffset = 8 - sm_iLabelOffset; //6 + const CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); int iCount = pHeaderCtrl->GetItemCount(); + LONG itemLeft = rcItem.left; rcItem.right = rcItem.left - sm_iLabelOffset; rcItem.left += sm_iIconOffset; - if (content->type == FILE_TYPE) { - if (!g_bLowColorDesktop && (lpDrawItemStruct->itemState & ODS_SELECTED) == 0) { - DWORD dwCatColor = thePrefs.GetCatColor(static_cast(content->value)->GetCategory(), COLOR_WINDOWTEXT); - if (dwCatColor > 0) - dc.SetTextColor(dwCatColor); - } - - for (int iCurrent = 0; iCurrent < iCount; ++iCurrent) { - int iColumn = pHeaderCtrl->OrderToIndex(iCurrent); - if (!IsColumnHidden(iColumn)) { - UINT uDrawTextAlignment; - int iColumnWidth = GetColumnWidth(iColumn, uDrawTextAlignment); - if (iColumn == 5) { - int iNextLeft = rcItem.left + iColumnWidth; - int iNextRight = rcItem.right + iColumnWidth; - //set up tree vars - rcItem.left = rcItem.right + iTreeOffset; - rcItem.right = rcItem.left + min(8, iColumnWidth); - tree_start = rcItem.left + 1; - tree_end = rcItem.right; - //normal column stuff - rcItem.left = rcItem.right + 1; - rcItem.right = tree_start + iColumnWidth - iTreeOffset; - if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) - DrawFileItem(dc, 5, &rcItem, uDrawTextAlignment, content); - rcItem.left = iNextLeft; - rcItem.right = iNextRight; - } else { - rcItem.right += iColumnWidth; - if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) - DrawFileItem(dc, iColumn, &rcItem, uDrawTextAlignment, content); - if (iColumn == 0) { - rcItem.left += sm_iLabelOffset; - rcItem.right -= sm_iSubItemInset; - } - rcItem.left += iColumnWidth; - } - } - } - } else if (content->type == UNAVAILABLE_SOURCE || content->type == AVAILABLE_SOURCE) { - for (int iCurrent = 0; iCurrent < iCount; ++iCurrent) { - int iColumn = pHeaderCtrl->OrderToIndex(iCurrent); - if (!IsColumnHidden(iColumn)) { - UINT uDrawTextAlignment; - int iColumnWidth = GetColumnWidth(iColumn, uDrawTextAlignment); - if (iColumn == 5) { - int iNextLeft = rcItem.left + iColumnWidth; - int iNextRight = rcItem.right + iColumnWidth; - //set up tree vars - rcItem.left = rcItem.right + iTreeOffset; - rcItem.right = rcItem.left + min(8, iColumnWidth); - tree_start = rcItem.left + 1; - tree_end = rcItem.right; - //normal column stuff - rcItem.left = rcItem.right + 1; - rcItem.right = tree_start + iColumnWidth - iTreeOffset; - if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) - DrawSourceItem(dc, 5, &rcItem, uDrawTextAlignment, content); - rcItem.left = iNextLeft; - rcItem.right = iNextRight; - } else { - rcItem.right += iColumnWidth; - if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) - DrawSourceItem(dc, iColumn, &rcItem, uDrawTextAlignment, content); - if (iColumn == 0) { - rcItem.left += sm_iLabelOffset; - rcItem.right -= sm_iSubItemInset; - } - rcItem.left += iColumnWidth; - } - } + if (!isChild && !g_bLowColorDesktop && (lpDrawItemStruct->itemState & ODS_SELECTED) == 0) { + DWORD dwCatColor = thePrefs.GetCatColor(static_cast(content->value)->GetCategory(), COLOR_WINDOWTEXT); + if (dwCatColor > 0) + dc.SetTextColor(dwCatColor); + } + for (int iCurrent = 0; iCurrent < iCount; ++iCurrent) { + int iColumn = pHeaderCtrl->OrderToIndex(iCurrent); + if (IsColumnHidden(iColumn)) + continue; + + UINT uDrawTextAlignment; + int iColumnWidth = GetColumnWidth(iColumn, uDrawTextAlignment); + rcItem.left = itemLeft; + rcItem.right = itemLeft + iColumnWidth; + switch (iColumn) { + case 5: //progress + //set up tree vars + tree_start = rcItem.left + 1; + rcItem.left += iTreeOffset; + tree_end = rcItem.left; + rcItem.right -= iTreeOffset - sm_iLabelOffset; + default: + rcItem.left += sm_iLabelOffset; + rcItem.right -= sm_iLabelOffset; + if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) + if (isChild) + DrawSourceItem(dc, iColumn, &rcItem, uDrawTextAlignment, content); + else + DrawFileItem(dc, iColumn, &rcItem, uDrawTextAlignment, content); } + itemLeft += iColumnWidth; } DrawFocusRect(dc, &lpDrawItemStruct->rcItem, lpDrawItemStruct->itemState & ODS_FOCUS, bCtrlFocused, lpDrawItemStruct->itemState & ODS_SELECTED); @@ -809,11 +745,10 @@ void CDownloadListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) dc.SetBoundsRect(&tree_rect, DCB_DISABLE); //gather some information - BOOL hasNext = notLast && - reinterpret_cast(GetItemData(lpDrawItemStruct->itemID + 1))->type != FILE_TYPE; - BOOL isOpenRoot = hasNext && content->type == FILE_TYPE; - BOOL isChild = content->type != FILE_TYPE; - //BOOL isExpandable = !isChild && static_cast(content->value)->GetSourceCount() > 0; + bool hasNext = notLast + && reinterpret_cast(GetItemData(lpDrawItemStruct->itemID + 1))->type != FILE_TYPE; + bool isOpenRoot = hasNext && content->type == FILE_TYPE; + //bool isExpandable = !isChild && static_cast(content->value)->GetSourceCount() > 0; //might as well calculate these now int treeCenter = tree_start + 3; int middle = (rcItem.top + rcItem.bottom + 1) / 2; @@ -837,7 +772,8 @@ void CDownloadListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) //draw circle RECT circle_rec = { treeCenter - 2, middle - 2, treeCenter + 3, middle + 3 }; COLORREF crBk = dc.GetBkColor(); - dc.FrameRect(&circle_rec, &CBrush(m_crWindowText)); + CBrush brush(m_crWindowText); + dc.FrameRect(&circle_rec, &brush); dc.SetPixelV(circle_rec.left, circle_rec.top, crBk); dc.SetPixelV(circle_rec.right - 1, circle_rec.top, crBk); dc.SetPixelV(circle_rec.left, circle_rec.bottom - 1, crBk); @@ -867,7 +803,7 @@ void CDownloadListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) void CDownloadListCtrl::HideSources(CPartFile *toCollapse) { - SetRedraw(FALSE); + SetRedraw(false); for (int i = GetItemCount(); --i >= 0;) { CtrlItem_Struct *item = reinterpret_cast(GetItemData(i)); if (item != NULL && item->owner == toCollapse) { @@ -877,7 +813,7 @@ void CDownloadListCtrl::HideSources(CPartFile *toCollapse) } } toCollapse->srcarevisible = false; - SetRedraw(TRUE); + SetRedraw(true); } void CDownloadListCtrl::ExpandCollapseItem(int iItem, int iAction, bool bCollapseSource) @@ -910,7 +846,7 @@ void CDownloadListCtrl::ExpandCollapseItem(int iItem, int iAction, bool bCollaps return; } - // Check if the source branch is disable + // Check if the sources branch is visible if (!partfile->srcarevisible) { if (iAction > COLLAPSE_ONLY) { SetRedraw(false); @@ -927,14 +863,12 @@ void CDownloadListCtrl::ExpandCollapseItem(int iItem, int iAction, bool bCollaps SetRedraw(true); } - } else { - if (iAction == EXPAND_COLLAPSE || iAction == COLLAPSE_ONLY) { - if (GetItemState(iItem, LVIS_SELECTED | LVIS_FOCUSED) != (LVIS_SELECTED | LVIS_FOCUSED)) { - SetItemState(iItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); - SetSelectionMark(iItem); - } - HideSources(partfile); + } else if (iAction == EXPAND_COLLAPSE || iAction == COLLAPSE_ONLY) { + if (GetItemState(iItem, LVIS_SELECTED | LVIS_FOCUSED) != (LVIS_SELECTED | LVIS_FOCUSED)) { + SetItemState(iItem, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + SetSelectionMark(iItem); } + HideSources(partfile); } } @@ -996,16 +930,21 @@ void CDownloadListCtrl::OnContextMenu(CWnd*, CPoint point) UINT uCurPrioMenuItem; if (pFile->IsAutoDownPriority()) uCurPrioMenuItem = MP_PRIOAUTO; - else if (pFile->GetDownPriority() == PR_HIGH) - uCurPrioMenuItem = MP_PRIOHIGH; - else if (pFile->GetDownPriority() == PR_NORMAL) - uCurPrioMenuItem = MP_PRIONORMAL; - else if (pFile->GetDownPriority() == PR_LOW) - uCurPrioMenuItem = MP_PRIOLOW; - else { - uCurPrioMenuItem = 0; - ASSERT(0); - } + else + switch (pFile->GetDownPriority()) { + case PR_HIGH: + uCurPrioMenuItem = MP_PRIOHIGH; + break; + case PR_NORMAL: + uCurPrioMenuItem = MP_PRIONORMAL; + break; + case PR_LOW: + uCurPrioMenuItem = MP_PRIOLOW; + break; + default: + uCurPrioMenuItem = 0; + ASSERT(0); + } if (bFirstItem) { bFirstItem = false; @@ -1226,15 +1165,15 @@ void CDownloadListCtrl::FillCatsMenu(CMenu &rCatsMenu, int iFilesInCats) } } rCatsMenu.AppendMenu(MF_STRING, MP_NEWCAT, GetResString(IDS_NEW) + _T("...")); - CString label = GetResString(IDS_CAT_UNASSIGN); + CString label(GetResString(IDS_CAT_UNASSIGN)); label.Remove('('); label.Remove(')'); // Remove braces without having to put a new/changed resource string in rCatsMenu.AppendMenu(MF_STRING | ((iFilesInCats == 0) ? MF_GRAYED : MF_ENABLED), MP_ASSIGNCAT, label); if (thePrefs.GetCatCount() > 1) { rCatsMenu.AppendMenu(MF_SEPARATOR); - for (int i = 1; i < thePrefs.GetCatCount(); ++i) { + for (INT_PTR i = 1; i < thePrefs.GetCatCount(); ++i) { label = thePrefs.GetCategory(i)->strTitle; - label.Replace(_T("&"), _T("&&")); + DupAmpersand(label); rCatsMenu.AppendMenu(MF_STRING, MP_ASSIGNCAT + i, label); } } @@ -1321,7 +1260,7 @@ BOOL CDownloadListCtrl::OnCommand(WPARAM wParam, LPARAM) case MPG_DELETE: // keyboard del will continue to remove completed files from the screen while cancel will now also be available for complete files if (selectedCount > 0) { SetRedraw(false); - CString fileList; + CString fileList(GetResString(selectedCount == 1 ? IDS_Q_CANCELDL2 : IDS_Q_CANCELDL)); bool validdelete = false; bool removecompl = false; int cFiles = 0; @@ -1337,8 +1276,8 @@ BOOL CDownloadListCtrl::OnCommand(WPARAM wParam, LPARAM) } else if (cur_file->GetStatus() == PS_COMPLETE) removecompl = true; } - CString quest(GetResString(selectedCount == 1 ? IDS_Q_CANCELDL2 : IDS_Q_CANCELDL)); - if ((removecompl && !validdelete) || (validdelete && AfxMessageBox(quest + fileList, MB_DEFBUTTON2 | MB_ICONQUESTION | MB_YESNO) == IDYES)) { + + if ((removecompl && !validdelete) || (validdelete && AfxMessageBox(fileList, MB_DEFBUTTON2 | MB_ICONQUESTION | MB_YESNO) == IDYES)) { bool bRemovedItems = !selectedList.IsEmpty(); while (!selectedList.IsEmpty()) { CPartFile *partfile = selectedList.RemoveHead(); @@ -1493,8 +1432,8 @@ BOOL CDownloadListCtrl::OnCommand(WPARAM wParam, LPARAM) } } theApp.CopyTextToClipboard(str); - break; } + break; case MP_SEARCHRELATED: theApp.emuledlg->searchwnd->SearchRelatedFiles(selectedList); theApp.emuledlg->SetActiveDialog(theApp.emuledlg->searchwnd); @@ -1526,8 +1465,8 @@ BOOL CDownloadListCtrl::OnCommand(WPARAM wParam, LPARAM) if (pPartFile->IsPreviewableFileType() && !pPartFile->IsReadyForPreview()) pPartFile->SetPauseOnPreview(!bAllPausedOnPreview); } - break; } + break; case MP_VIEWFILECOMMENTS: ShowFileDialog(IDD_COMMENTLST); break; @@ -1554,8 +1493,8 @@ BOOL CDownloadListCtrl::OnCommand(WPARAM wParam, LPARAM) partfile->UpdateDisplayedInfo(true); } } - break; } + break; case MP_ADDSOURCE: if (selectedCount == 1) { CAddSourceDlg as; @@ -1574,13 +1513,13 @@ BOOL CDownloadListCtrl::OnCommand(WPARAM wParam, LPARAM) break; } else nCatNumber = (int)(wParam - MP_ASSIGNCAT); - SetRedraw(FALSE); + SetRedraw(false); while (!selectedList.IsEmpty()) { CPartFile *partfile = selectedList.RemoveHead(); partfile->SetCategory(nCatNumber); partfile->UpdateDisplayedInfo(true); } - SetRedraw(TRUE); + SetRedraw(true); UpdateCurrentCategoryView(); if (thePrefs.ShowCatTabInfos()) theApp.emuledlg->transferwnd->UpdateCatTabTitles(); @@ -1634,12 +1573,10 @@ BOOL CDownloadListCtrl::OnCommand(WPARAM wParam, LPARAM) void CDownloadListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) { - NMLISTVIEW *pNMListView = reinterpret_cast(pNMHDR); + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); bool sortAscending; - if (GetSortItem() == pNMListView->iSubItem) - sortAscending = !GetSortAscending(); - else - switch (pNMListView->iSubItem) { + if (GetSortItem() != pNMLV->iSubItem) + switch (pNMLV->iSubItem) { case 2: // Transferred case 3: // Completed case 4: // Download rate @@ -1652,28 +1589,26 @@ void CDownloadListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) default: sortAscending = true; } + else + sortAscending = !GetSortAscending(); // Ornis 4-way-sorting int adder = 0; - if (pNMListView->iSubItem == 9) { + if (pNMLV->iSubItem == 9) { if (GetSortItem() == 9 && sortAscending) // check for 'ascending' because the initial sort order is also 'ascending' m_bRemainSort = !m_bRemainSort; - adder = m_bRemainSort ? 81 : 0; + if (m_bRemainSort) + adder = 81; } - // Sort table if (adder == 0) - SetSortArrow(pNMListView->iSubItem, sortAscending); + SetSortArrow(pNMLV->iSubItem, sortAscending); else - SetSortArrow(pNMListView->iSubItem, sortAscending ? arrowDoubleUp : arrowDoubleDown); - if (!sortAscending) - adder += 100; - UpdateSortHistory(pNMListView->iSubItem + adder); - SortItems(SortProc, pNMListView->iSubItem + adder); - + SetSortArrow(pNMLV->iSubItem, sortAscending ? arrowDoubleUp : arrowDoubleDown); + UpdateSortHistory(MAKELONG(pNMLV->iSubItem + adder, !sortAscending)); + SortItems(SortProc, MAKELONG(pNMLV->iSubItem + adder, !sortAscending)); // Save new preferences thePrefs.TransferlistRemainSortStyle(m_bRemainSort); - *pResult = 0; } @@ -1682,47 +1617,36 @@ int CALLBACK CDownloadListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM const CtrlItem_Struct *item1 = reinterpret_cast(lParam1); const CtrlItem_Struct *item2 = reinterpret_cast(lParam2); - int OrgSort = (int)lParamSort; - int sortMod = 1; - if (lParamSort >= 100) { - sortMod = -1; - lParamSort -= 100; - } - - int comp; + int iResult; if (item1->type == FILE_TYPE && item2->type != FILE_TYPE) { if (item1->value == item2->parent->value) return -1; - comp = Compare(static_cast(item1->value), static_cast(item2->parent->value), lParamSort); - } else if (item2->type == FILE_TYPE && item1->type != FILE_TYPE) { + iResult = Compare(static_cast(item1->value), static_cast(item2->parent->value), lParamSort); + } else if (item1->type != FILE_TYPE && item2->type == FILE_TYPE) { if (item1->parent->value == item2->value) return 1; - comp = Compare(static_cast(item1->parent->value), static_cast(item2->value), lParamSort); - } else if (item1->type == FILE_TYPE) { - const CPartFile *file1 = static_cast(item1->value); - const CPartFile *file2 = static_cast(item2->value); - comp = Compare(file1, file2, lParamSort); - } else { + iResult = Compare(static_cast(item1->parent->value), static_cast(item2->value), lParamSort); + } else if (item1->type == FILE_TYPE) + iResult = Compare(static_cast(item1->value), static_cast(item2->value), lParamSort); + else { if (item1->parent->value != item2->parent->value) { - comp = Compare(static_cast(item1->parent->value), static_cast(item2->parent->value), lParamSort); - return sortMod * comp; + iResult = Compare(static_cast(item1->parent->value), static_cast(item2->parent->value), lParamSort); + return HIWORD(lParamSort) ? -iResult : iResult; } if (item1->type != item2->type) return item1->type - item2->type; - const CUpDownClient *client1 = static_cast(item1->value); - const CUpDownClient *client2 = static_cast(item2->value); - comp = Compare(client1, client2, lParamSort); + iResult = Compare(static_cast(item1->value), static_cast(item2->value), lParamSort); } - //call secondary sort order, if this one results in equal - if (comp == 0) { - int dwNextSort = theApp.emuledlg->transferwnd->GetDownloadList()->GetNextSortOrder(OrgSort); - if (dwNextSort != -1) - return SortProc(lParam1, lParam2, dwNextSort); + //call secondary sort order, if the first one resulted as equal + if (iResult == 0) { + LPARAM iNextSort = theApp.emuledlg->transferwnd->GetDownloadList()->GetNextSortOrder(lParamSort); + if (iNextSort != -1) + return SortProc(lParam1, lParam2, iNextSort); } - return sortMod * comp; + return HIWORD(lParamSort) ? -iResult : iResult; } void CDownloadListCtrl::ClearCompleted(int incat) @@ -1773,34 +1697,34 @@ void CDownloadListCtrl::OnListModified(LPNMHDR pNMHDR, LRESULT* /*pResult*/) NMLISTVIEW *pNMListView = reinterpret_cast(pNMHDR); //this works because true is equal to 1 and false equal to 0 - BOOL notLast = pNMListView->iItem + 1 != GetItemCount(); - BOOL notFirst = pNMListView->iItem != 0; - RedrawItems(pNMListView->iItem - (int)notFirst, pNMListView->iItem + (int)notLast); + int notLast = static_cast(pNMListView->iItem + 1 != GetItemCount()); + int notFirst = static_cast(pNMListView->iItem != 0); + RedrawItems(pNMListView->iItem - notFirst, pNMListView->iItem + notLast); m_availableCommandsDirty = true; } int CDownloadListCtrl::Compare(const CPartFile *file1, const CPartFile *file2, LPARAM lParamSort) { - switch (lParamSort) { - case 0: //filename asc + switch (LOWORD(lParamSort)) { + case 0: //filename return CompareLocaleStringNoCase(file1->GetFileName(), file2->GetFileName()); - case 1: //size asc - return CompareUnsigned64(file1->GetFileSize(), file2->GetFileSize()); - case 2: //transferred asc - return CompareUnsigned64(file1->GetTransferred(), file2->GetTransferred()); - case 3: //completed asc - return CompareUnsigned64(file1->GetCompletedSize(), file2->GetCompletedSize()); - case 4: //speed asc + case 1: //size + return CompareUnsigned(file1->GetFileSize(), file2->GetFileSize()); + case 2: //transferred + return CompareUnsigned(file1->GetTransferred(), file2->GetTransferred()); + case 3: //completed + return CompareUnsigned(file1->GetCompletedSize(), file2->GetCompletedSize()); + case 4: //speed return CompareUnsigned(file1->GetDatarate(), file2->GetDatarate()); - case 5: //progress asc + case 5: //progress return sgn((float)file1->GetCompletedSize() / (float)file1->GetFileSize() - (float)file2->GetCompletedSize() / (float)file2->GetFileSize()); //compare exact ratio instead of rounded percents - case 6: //sources asc + case 6: //sources return CompareUnsigned(file1->GetSourceCount(), file2->GetSourceCount()); - case 7: //priority asc + case 7: //priority return CompareUnsigned(file1->GetDownPriority(), file2->GetDownPriority()); - case 8: //Status asc - return sgn(file1->getPartfileStatusRank() - file2->getPartfileStatusRank()); - case 9: //Remaining Time asc + case 8: //Status + return (file1->getPartfileStatusRank() - file2->getPartfileStatusRank()); + case 9: //Remaining Time { //Make ascending sort so we can have the smaller remaining time on the top //instead of unknowns so we can see which files are about to finish better. @@ -1822,20 +1746,20 @@ int CDownloadListCtrl::Compare(const CPartFile *file1, const CPartFile *file2, L //If descending, put first on top as it is bigger. //If ascending, put first on bottom as it is bigger. - return CompareUnsigned((uint32)f1, (uint32)f2); + return CompareUnsigned(f1, f2); } - case 90: //Remaining SIZE asc - return CompareUnsigned64(file1->GetFileSize() - file1->GetCompletedSize(), file2->GetFileSize() - file2->GetCompletedSize()); - case 10: //last seen complete asc + case 90: //Remaining SIZE + return CompareUnsigned(file1->GetFileSize() - file1->GetCompletedSize(), file2->GetFileSize() - file2->GetCompletedSize()); + case 10: //last seen complete return sgn(file1->lastseencomplete - file2->lastseencomplete); - case 11: //last received Time asc + case 11: //last received Time return sgn(file1->GetLastReceptionDate() - file2->GetLastReceptionDate()); case 12: //category //TODO: 'GetCategory' SHOULD be a 'const' function and 'GetResString' should NOT be called. return CompareLocaleStringNoCase((const_cast(file1)->GetCategory() != 0) ? thePrefs.GetCategory(const_cast(file1)->GetCategory())->strTitle : GetResString(IDS_ALL), (const_cast(file2)->GetCategory() != 0) ? thePrefs.GetCategory(const_cast(file2)->GetCategory())->strTitle : GetResString(IDS_ALL)); - case 13: // added on asc + case 13: // added on return sgn(file1->GetCrFileDate() - file2->GetCrFileDate()); } return 0; @@ -1843,8 +1767,8 @@ int CDownloadListCtrl::Compare(const CPartFile *file1, const CPartFile *file2, L int CDownloadListCtrl::Compare(const CUpDownClient *client1, const CUpDownClient *client2, LPARAM lParamSort) { - switch (lParamSort) { - case 0: //name asc + switch (LOWORD(lParamSort)) { + case 0: //name if (client1->GetUserName() && client2->GetUserName()) return CompareLocaleStringNoCase(client1->GetUserName(), client2->GetUserName()); if (client1->GetUserName() == NULL) @@ -1852,20 +1776,20 @@ int CDownloadListCtrl::Compare(const CUpDownClient *client1, const CUpDownClient if (client2->GetUserName() == NULL) return -1; // place clients with no user names at bottom return 0; - case 1: //size but we use status asc + case 1: //size but we use status return client1->GetSourceFrom() - client2->GetSourceFrom(); - case 2: //transferred asc - case 3: //completed asc + case 2: //transferred + case 3: //completed return CompareUnsigned(client1->GetTransferredDown(), client2->GetTransferredDown()); - case 4: //speed asc + case 4: //speed return CompareUnsigned(client1->GetDownloadDatarate(), client2->GetDownloadDatarate()); - case 5: //progress asc + case 5: //progress return CompareUnsigned(client1->GetAvailablePartCount(), client2->GetAvailablePartCount()); case 6: if (client1->GetClientSoft() == client2->GetClientSoft()) return client1->GetVersion() - client2->GetVersion(); return -(client1->GetClientSoft() - client2->GetClientSoft()); // invert result to place eMule's at top - case 7: //qr asc + case 7: //qr if (client1->GetDownloadState() == DS_DOWNLOADING) return (client2->GetDownloadState() == DS_DOWNLOADING) ? 0 : -1; if (client2->GetDownloadState() == DS_DOWNLOADING) @@ -1879,7 +1803,7 @@ int CDownloadListCtrl::Compare(const CUpDownClient *client1, const CUpDownClient if (client2->GetRemoteQueueRank() == 0) return -1; return CompareUnsigned(client1->GetRemoteQueueRank(), client2->GetRemoteQueueRank()); - case 8: //state asc + case 8: //state if (client1->GetDownloadState() == client2->GetDownloadState()) { if (client1->IsRemoteQueueFull() && client2->IsRemoteQueueFull()) return 0; @@ -1961,8 +1885,8 @@ void CDownloadListCtrl::CreateMenus() m_PrioMenu.AppendMenu(MF_STRING, MP_PRIOHIGH, GetResString(IDS_PRIOHIGH)); m_PrioMenu.AppendMenu(MF_STRING, MP_PRIOAUTO, GetResString(IDS_PRIOAUTO)); - CString sPrio(GetResString(IDS_PRIORITY)); - sPrio.AppendFormat(_T(" (%s)"), (LPCTSTR)GetResString(IDS_DOWNLOAD)); + CString sPrio; + sPrio.Format(_T("%s (%s)"), (LPCTSTR)GetResString(IDS_PRIORITY), (LPCTSTR)GetResString(IDS_DOWNLOAD)); m_FileMenu.AppendMenu(MF_STRING | MF_POPUP, (UINT_PTR)m_PrioMenu.m_hMenu, sPrio, _T("FILEPRIORITY")); // Add file commands @@ -2233,31 +2157,31 @@ void CDownloadListCtrl::UpdateCurrentCategoryView(CPartFile *thisfile) const CtrlItem_Struct *cur_item = it->second; if (cur_item->type == FILE_TYPE) { CPartFile *file = static_cast(cur_item->value); - if (!file->CheckShowItemInGivenCat(curTab)) - HideFile(file); - else + if (file->CheckShowItemInGivenCat(curTab)) ShowFile(file); + else + HideFile(file); } } } void CDownloadListCtrl::ChangeCategory(int newsel) { - SetRedraw(FALSE); + SetRedraw(false); - // remove all displayed files with a different cat and show the correct ones + // show the files of the selected category, remove all others for (ListItems::const_iterator it = m_ListItems.begin(); it != m_ListItems.end(); ++it) { const CtrlItem_Struct *cur_item = it->second; if (cur_item->type == FILE_TYPE) { CPartFile *file = static_cast(cur_item->value); - if (!file->CheckShowItemInGivenCat(newsel)) - HideFile(file); - else + if (file->CheckShowItemInGivenCat(newsel)) ShowFile(file); + else + HideFile(file); } } - SetRedraw(TRUE); + SetRedraw(true); curTab = newsel; ShowFilesCount(); } @@ -2330,16 +2254,16 @@ void CDownloadListCtrl::MoveCompletedfilesCat(UINT from, UINT to) void CDownloadListCtrl::OnLvnGetDispInfo(LPNMHDR pNMHDR, LRESULT *pResult) { if (!theApp.IsClosing()) { - // Although we have an owner drawn listview control we store the text for the primary item in the listview, to be - // capable of quick searching those items via the keyboard. Because our listview items may change their contents, - // we do this via a text callback function. The listview control will send us the LVN_DISPINFO notification if - // it needs to know the contents of the primary item. + // Although we have an owner drawn listview control we store the text for the primary item in the + // listview, to be capable of quick searching those items via the keyboard. Because our listview + // items may change their contents, we do this via a text callback function. The listview control + // will send us the LVN_DISPINFO notification if it needs to know the contents of the primary item. // - // But, the listview control sends this notification all the time, even if we do not search for an item. At least - // this notification is only sent for the visible items and not for all items in the list. Though, because this - // function is invoked *very* often, do *NOT* put any time consuming code in here. + // But, the listview control sends this notification all the time, even if we do not search for an item. + // At least this notification is only sent for the visible items and not for all items in the list. + // Though, because this function is invoked *very* often, do *NOT* put any time consuming code in here. // - // Vista: That callback is used to get the strings for the label tips for the sub(!) items. + // Vista: That callback is used to get the strings for the label tips for the sub(!)-items. // const LVITEM &rItem = reinterpret_cast(pNMHDR)->item; /*TRACE("CDownloadListCtrl::OnLvnGetDispInfo iItem=%d iSubItem=%d", rItem.iItem, rItem.iSubItem); @@ -2387,10 +2311,9 @@ void CDownloadListCtrl::OnLvnGetInfoTip(LPNMHDR pNMHDR, LRESULT *pResult) CString info; // build info text and display it - if (content->type == 1) { // for downloading files - const CPartFile *partfile = static_cast(content->value); - info = partfile->GetInfoSummary(); - } else if (content->type == 3 || content->type == 2) { // for sources + if (content->type == 1) // for downloading files + info = static_cast(content->value)->GetInfoSummary(); + else if (content->type == 3 || content->type == 2) { // for sources const CUpDownClient *client = static_cast(content->value); if (client->IsEd2kClient()) { in_addr server; @@ -2631,9 +2554,11 @@ CImageList* CDownloadListCtrl::CreateDragImage(int /*iItem*/, LPPOINT lpPoint) bool CDownloadListCtrl::ReportAvailableCommands(CList &liAvailableCommands) { - if (::GetTickCount() < m_dwLastAvailableCommandsCheck + SEC2MS(3) && !m_availableCommandsDirty) + const DWORD curTick = ::GetTickCount(); + + if (curTick < m_dwLastAvailableCommandsCheck + SEC2MS(3) && !m_availableCommandsDirty) return false; - m_dwLastAvailableCommandsCheck = ::GetTickCount(); + m_dwLastAvailableCommandsCheck = curTick; m_availableCommandsDirty = false; int iSel = GetNextItem(-1, LVIS_SELECTED); @@ -2642,13 +2567,13 @@ bool CDownloadListCtrl::ReportAvailableCommands(CList &liAvailableCommands) if (content != NULL && content->type == FILE_TYPE) { // get merged settings int iSelectedItems = 0; -// int iFilesNotDone = 0; + //int iFilesNotDone = 0; int iFilesToPause = 0; int iFilesToStop = 0; int iFilesToResume = 0; int iFilesToOpen = 0; -// int iFilesGetPreviewParts = 0; -// int iFilesPreviewType = 0; + //int iFilesGetPreviewParts = 0; + //int iFilesPreviewType = 0; int iFilesToPreview = 0; int iFilesToCancel = 0; for (POSITION pos = GetFirstSelectedItemPosition(); pos != NULL;) { @@ -2659,13 +2584,13 @@ bool CDownloadListCtrl::ReportAvailableCommands(CList &liAvailableCommands) ++iSelectedItems; iFilesToCancel += static_cast(pFile->GetStatus() != PS_COMPLETING); -// iFilesNotDone += static_cast(pFile->GetStatus()!=PS_COMPLETE && pFile->GetStatus()!=PS_COMPLETING); + //iFilesNotDone += static_cast(pFile->GetStatus()!=PS_COMPLETE && pFile->GetStatus()!=PS_COMPLETING); iFilesToStop += static_cast(pFile->CanStopFile()); iFilesToPause += static_cast(pFile->CanPauseFile()); iFilesToResume += static_cast(pFile->CanResumeFile()); iFilesToOpen += static_cast(pFile->CanOpenFile()); -// iFilesGetPreviewParts += static_cast(pFile->GetPreviewPrio()); -// iFilesPreviewType += static_cast(pFile->IsPreviewableFileType()); + //iFilesGetPreviewParts += static_cast(pFile->GetPreviewPrio()); + //iFilesPreviewType += static_cast(pFile->IsPreviewableFileType()); iFilesToPreview += static_cast(pFile->IsReadyForPreview()); } diff --git a/srchybrid/DownloadListCtrl.h b/srchybrid/DownloadListCtrl.h index 43427075..081988ca 100644 --- a/srchybrid/DownloadListCtrl.h +++ b/srchybrid/DownloadListCtrl.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -15,10 +15,11 @@ //along with this program; if not, write to the Free Software //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #pragma once +#include #include "MuleListCtrl.h" #include "TitleMenu.h" -#include #include "ListCtrlItemWalk.h" +#include "ToolTipCtrlX.h" #define COLLAPSE_ONLY 0 #define EXPAND_ONLY 1 @@ -28,7 +29,6 @@ class CPartFile; class CUpDownClient; class CDownloadListCtrl; -class CToolTipCtrlX; /////////////////////////////////////////////////////////////////////////////// @@ -135,8 +135,8 @@ class CDownloadListCtrl : public CMuleListCtrl, public CDownloadListListCtrlItem ListItems m_ListItems; CFont m_fontBold; // may contain a locally created bold font CFont *m_pFontBold;// points to the bold font which is to be used (may be the locally created or the default bold font) - CToolTipCtrlX *m_tooltip; - uint32 m_dwLastAvailableCommandsCheck; + CToolTipCtrlX m_tooltip; + DWORD m_dwLastAvailableCommandsCheck; bool m_availableCommandsDirty; void ShowFileDialog(UINT uInvokePage); diff --git a/srchybrid/DownloadQueue.cpp b/srchybrid/DownloadQueue.cpp index 1b66d5df..fd6bd869 100644 --- a/srchybrid/DownloadQueue.cpp +++ b/srchybrid/DownloadQueue.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -17,15 +17,14 @@ #include "stdafx.h" #include #include "emule.h" -#include "DownloadQueue.h" #include "UpDownClient.h" +#include "DownloadQueue.h" #include "PartFile.h" #include "ed2kLink.h" #include "SearchFile.h" #include "ClientList.h" #include "Statistics.h" #include "SharedFileList.h" -#include "OtherFunctions.h" #include "SafeFile.h" #include "ServerConnect.h" #include "ServerList.h" @@ -50,19 +49,18 @@ static char THIS_FILE[] = __FILE__; CDownloadQueue::CDownloadQueue() : cur_udpserver() , m_datarateMS() - , lastfile() + , m_lastfile() , m_dwLastA4AFtime() - , lastcheckdiskspacetime() - , lastudpsearchtime() - , lastudpstattime() - , udcounter() - , m_cRequestsSentToServer() + , m_lastcheckdiskspacetime() + , m_lastudpsearchtime() + , m_lastudpstattime() , m_dwNextTCPSrcReq() + , m_udcounter() + , m_cRequestsSentToServer() , m_iSearchedServers() , m_nUDPFileReasks() , m_nFailedUDPFileReasks() - , datarate() - , filesrdy() + , m_datarate() { SetLastKademliaFileRequest(); } @@ -82,14 +80,13 @@ void CDownloadQueue::Init() CFileFind ff; int count = 0; + CString searchPath; for (INT_PTR i = 0; i < thePrefs.GetTempDirCount(); ++i) { - CString searchPath; - searchPath.Format(_T("%s\\*.part.met"), (LPCTSTR)thePrefs.GetTempDir(i)); + searchPath.Format(_T("%s*.part.met"), (LPCTSTR)thePrefs.GetTempDir(i)); //check all part.met files - bool end = !ff.FindFile(searchPath, 0); - while (!end) { - end = !ff.FindNextFile(); + for (BOOL bFound = ff.FindFile(searchPath); bFound;) { + bFound = ff.FindNextFile(); if (ff.IsDirectory()) continue; CPartFile *toadd = new CPartFile(); @@ -114,13 +111,11 @@ void CDownloadQueue::Init() } else delete toadd; } - ff.Close(); //try recovering any part.met files searchPath += _T(".backup"); - end = !ff.FindFile(searchPath, 0); - while (!end) { - end = !ff.FindNextFile(); + for (BOOL bFound = ff.FindFile(searchPath); bFound;) { + bFound = ff.FindNextFile(); if (ff.IsDirectory()) continue; CPartFile *toadd = new CPartFile(); @@ -154,7 +149,7 @@ CDownloadQueue::~CDownloadQueue() { while (!filelist.IsEmpty()) delete filelist.RemoveHead(); - m_srcwnd.DestroyWindow(); // just to avoid a MFC warning + m_srcwnd.DestroyWindow(); // just to avoid an MFC warning } void CDownloadQueue::AddSearchToDownload(CSearchFile *toadd, uint8 paused, int cat) @@ -264,9 +259,9 @@ void CDownloadQueue::StartNextFile(int cat, bool force) pfile->ResumeFile(); } -void CDownloadQueue::AddFileLinkToDownload(CED2KFileLink *pLink, int cat) +void CDownloadQueue::AddFileLinkToDownload(const CED2KFileLink &Link, int cat) { - CPartFile *newfile = new CPartFile(pLink, cat); + CPartFile *newfile = new CPartFile(Link, cat); if (newfile->GetStatus() == PS_ERROR) { delete newfile; newfile = NULL; @@ -275,31 +270,29 @@ void CDownloadQueue::AddFileLinkToDownload(CED2KFileLink *pLink, int cat) CPartFile *partfile = newfile; if (partfile == NULL) - partfile = GetFileByID(pLink->GetHashKey()); + partfile = GetFileByID(Link.GetHashKey()); if (partfile) { // match the file identifier and only if they are the same add possible sources - CFileIdentifierSA tmpFileIdent(pLink->GetHashKey(), pLink->GetSize(), pLink->GetAICHHash(), pLink->HasValidAICHHash()); + CFileIdentifierSA tmpFileIdent(Link.GetHashKey(), Link.GetSize(), Link.GetAICHHash(), Link.HasValidAICHHash()); CFileIdentifier &fileid = partfile->GetFileIdentifier(); if (fileid.CompareRelaxed(tmpFileIdent)) { - if (pLink->HasValidSources()) - partfile->AddClientSources(pLink->SourcesList, 1, false); + if (Link.HasValidSources()) + partfile->AddClientSources(Link.SourcesList, 1, false); if (!fileid.HasAICHHash() && tmpFileIdent.HasAICHHash()) { fileid.SetAICHHash(tmpFileIdent.GetAICHHash()); partfile->GetAICHRecoveryHashSet()->SetMasterHash(tmpFileIdent.GetAICHHash(), AICH_VERIFIED); partfile->GetAICHRecoveryHashSet()->FreeHashSet(); - } } else - DebugLogWarning(_T("FileIdentifier mismatch when trying to add ed2k link to existing download - AICH Hash or Size might differ, no sources added. File: %s"), - (LPCTSTR)partfile->GetFileName()); + DebugLogWarning(_T("FileIdentifier mismatch when adding ed2k link to existing download - AICH hash or size might differ, no sources added. File: %s") + , (LPCTSTR)partfile->GetFileName()); } - if (pLink->HasHostnameSources()) { - for (POSITION pos = pLink->m_HostnameSourcesList.GetHeadPosition(); pos != NULL;) { - const SUnresolvedHostname *pUnresHost = pLink->m_HostnameSourcesList.GetNext(pos); - m_srcwnd.AddToResolve(pLink->GetHashKey(), pUnresHost->strHostname, pUnresHost->nPort, pUnresHost->strURL); + if (Link.HasHostnameSources()) + for (POSITION pos = Link.m_HostnameSourcesList.GetHeadPosition(); pos != NULL;) { + const SUnresolvedHostname *pUnresHost = Link.m_HostnameSourcesList.GetNext(pos); + m_srcwnd.AddToResolve(Link.GetHashKey(), pUnresHost->strHostname, pUnresHost->nPort, pUnresHost->strURL); } - } } void CDownloadQueue::AddToResolved(CPartFile *pFile, SUnresolvedHostname *pUH) @@ -322,7 +315,8 @@ void CDownloadQueue::AddDownload(CPartFile *newfile, bool paused) theApp.emuledlg->transferwnd->GetDownloadList()->AddFile(newfile); AddLogLine(true, GetResString(IDS_NEWDOWNLOAD), (LPCTSTR)newfile->GetFileName()); CString msgTemp; - msgTemp.Format(GetResString(IDS_NEWDOWNLOAD) + _T('\n'), (LPCTSTR)newfile->GetFileName()); + msgTemp.Format(GetResString(IDS_NEWDOWNLOAD), (LPCTSTR)newfile->GetFileName()); + msgTemp += _T('\n'); theApp.emuledlg->ShowNotifier(msgTemp, TBN_DOWNLOADADDED); ExportPartMetFilesOverview(); } @@ -353,8 +347,8 @@ void CDownloadQueue::Process() uint32 downspeed; uint64 maxDownload = thePrefs.GetMaxDownloadInBytesPerSec(true); - if (maxDownload != UNLIMITED * 1024ull && datarate > 1500) { - downspeed = (uint32)((maxDownload * 100) / (datarate + 1)); + if (maxDownload != UNLIMITED * 1024ull && m_datarate > 1500) { + downspeed = (uint32)(maxDownload * 100 / (m_datarate + 1)); if (downspeed < 50) downspeed = 50; else if (downspeed > 200) @@ -362,16 +356,17 @@ void CDownloadQueue::Process() } else downspeed = 0; - while (!average_dr_list.IsEmpty() && ::GetTickCount() >= average_dr_list.GetHead().timestamp + SEC2MS(10)) + DWORD curTick = ::GetTickCount() - SEC2MS(10); + while (!average_dr_list.IsEmpty() && curTick >= average_dr_list.GetHead().timestamp) m_datarateMS -= average_dr_list.RemoveHead().datalen; if (average_dr_list.GetCount() > 1) - datarate = (uint32)(m_datarateMS / average_dr_list.GetCount()); + m_datarate = (uint32)(m_datarateMS / average_dr_list.GetCount()); else - datarate = 0; + m_datarate = 0; uint32 datarateX = 0; - ++udcounter; + ++m_udcounter; theStats.m_fGlobalDone = 0; theStats.m_fGlobalSize = 0; @@ -389,38 +384,37 @@ void CDownloadQueue::Process() if (cur_file->GetStatus() == PS_ERROR) theStats.m_dwOverallStatus |= STATE_ERROROUS; - if (cur_file->GetStatus() == PS_READY || cur_file->GetStatus() == PS_EMPTY) - datarateX += cur_file->Process(downspeed, udcounter); + datarateX += cur_file->Process(downspeed, m_udcounter); else - //This will make sure we don't keep old sources to paused and stopped files. + //This will ensure we don't keep old sources for paused and stopped files. cur_file->StopPausedFile(); } - average_dr_list.AddTail(TransferredData{datarateX, ::GetTickCount()}); + curTick = ::GetTickCount(); + average_dr_list.AddTail(TransferredData{ datarateX, curTick }); m_datarateMS += datarateX; - if (udcounter == 5 - && theApp.serverconnect->IsUDPSocketAvailable() - && (!lastudpstattime || ::GetTickCount() >= lastudpstattime + UDPSERVERSTATTIME)) - { - lastudpstattime = ::GetTickCount(); - theApp.serverlist->ServerStats(); - } - - if (udcounter >= 10) { - udcounter = 0; + if (m_udcounter == 5) { + if (theApp.serverconnect->IsUDPSocketAvailable() + && (!m_lastudpstattime || curTick >= m_lastudpstattime + UDPSERVERSTATTIME)) + { + m_lastudpstattime = curTick; + theApp.serverlist->ServerStats(); + } + } else if (m_udcounter >= 10) { + m_udcounter = 0; if (theApp.serverconnect->IsUDPSocketAvailable()) - if (!lastudpsearchtime || ::GetTickCount() >= lastudpsearchtime + UDPSERVERREASKTIME) + if (!m_lastudpsearchtime || curTick >= m_lastudpsearchtime + UDPSERVERREASKTIME) SendNextUDPPacket(); } CheckDiskspaceTimed(); // ZZ:DownloadManager --> - if (!m_dwLastA4AFtime || ::GetTickCount() >= m_dwLastA4AFtime + MIN2MS(8)) { + if (!m_dwLastA4AFtime || curTick >= m_dwLastA4AFtime + MIN2MS(8)) { theApp.clientlist->ProcessA4AFClients(); - m_dwLastA4AFtime = ::GetTickCount(); + m_dwLastA4AFtime = curTick; } // <-- ZZ:DownloadManager } @@ -464,16 +458,15 @@ bool CDownloadQueue::CheckAndAddSource(CPartFile *sender, CUpDownClient *source) return false; } - if (source->HasValidHash()) { - if (md4equ(source->GetUserHash(), thePrefs.GetUserHash())) { - if (thePrefs.GetVerbose()) - AddDebugLogLine(false, _T("Tried to add source with matching hash to your own.")); - delete source; - return false; - } + if (source->HasValidHash() && md4equ(source->GetUserHash(), thePrefs.GetUserHash())) { + if (thePrefs.GetVerbose()) + AddDebugLogLine(false, _T("Tried to add source with a hash matching your own.")); + delete source; + return false; } + // filter sources which are known to be temporarily dead/useless - if (theApp.clientlist->m_globDeadSourceList.IsDeadSource(source) || sender->m_DeadSourceList.IsDeadSource(source)) { + if (theApp.clientlist->m_globDeadSourceList.IsDeadSource(*source) || sender->m_DeadSourceList.IsDeadSource(*source)) { //if (thePrefs.GetLogFilteredIPs()) // AddDebugLogLine(DLP_DEFAULT, false, _T("Rejected source because it was found on the DeadSourcesList (%s) for file %s : %s") // ,sender->m_DeadSourceList.IsDeadSource(source)? _T("Local") : _T("Global"), (LPCTSTR)sender->GetFileName(), (LPCTSTR)source->DbgGetClientInfo() ); @@ -481,7 +474,7 @@ bool CDownloadQueue::CheckAndAddSource(CPartFile *sender, CUpDownClient *source) return false; } - // filter sources which are incompatible with our encryption setting (one requires it, and the other one doesn't supports it) + // filter sources which are incompatible with our encryption setting (one requires it, and the other one doesn't support it) if ((source->RequiresCryptLayer() && (!thePrefs.IsClientCryptLayerSupported() || !source->HasValidHash())) || (thePrefs.IsClientCryptLayerRequired() && (!source->SupportsCryptLayer() || !source->HasValidHash()))) { #if defined(_DEBUG) || defined(_BETA) || defined(_DEVBUILD) //if (thePrefs.GetDebugSourceExchange()) // TODO: Uncomment after testing @@ -510,7 +503,7 @@ bool CDownloadQueue::CheckAndAddSource(CPartFile *sender, CUpDownClient *source) } } } - //our new source is real new but maybe it is already uploading to us? + //our new source is really new, but maybe it is already uploading to us? //if yes the known client will be attached to the var "source" //and the old source client will be deleted if (theApp.clientlist->AttachToAlreadyKnown(&source, NULL)) { @@ -521,9 +514,9 @@ bool CDownloadQueue::CheckAndAddSource(CPartFile *sender, CUpDownClient *source) // downloading) we may get a little in trouble here when "moving" this source to some other partfile without // further checks and updates. if (!md4equ(srcfile->GetFileHash(), sender->GetFileHash())) - AddDebugLogLine(false, _T("*** CDownloadQueue::CheckAndAddSource -- added potential wrong source (%u)(diff. filehash) to file \"%s\""), source->GetUserIDHybrid(), (LPCTSTR)sender->GetFileName()); - if (srcfile->GetPartCount() != 0 && srcfile->GetPartCount() != sender->GetPartCount()) - AddDebugLogLine(false, _T("*** CDownloadQueue::CheckAndAddSource -- added potential wrong source (%u)(diff. partcount) to file \"%s\""), source->GetUserIDHybrid(), (LPCTSTR)sender->GetFileName()); + AddDebugLogLine(false, _T("*** CDownloadQueue::CheckAndAddSource -- added potentially wrong source (%u)(diff. filehash) to file \"%s\""), source->GetUserIDHybrid(), (LPCTSTR)sender->GetFileName()); + if (srcfile->GetPartCount() > 0 && srcfile->GetPartCount() != sender->GetPartCount()) + AddDebugLogLine(false, _T("*** CDownloadQueue::CheckAndAddSource -- added potentially wrong source (%u)(diff. partcount) to file \"%s\""), source->GetUserIDHybrid(), (LPCTSTR)sender->GetFileName()); } #endif source->SetRequestFile(sender); @@ -535,7 +528,7 @@ bool CDownloadQueue::CheckAndAddSource(CPartFile *sender, CUpDownClient *source) } #ifdef _DEBUG - if (thePrefs.GetVerbose() && source->GetPartCount() != 0 && source->GetPartCount() != sender->GetPartCount()) + if (thePrefs.GetVerbose() && source->GetPartCount() > 0 && source->GetPartCount() != sender->GetPartCount()) DEBUG_ONLY(AddDebugLogLine(false, _T("*** CDownloadQueue::CheckAndAddSource -- New added source (%u, %s) had still value in partcount"), source->GetUserIDHybrid(), (LPCTSTR)sender->GetFileName())); #endif @@ -550,14 +543,14 @@ bool CDownloadQueue::CheckAndAddKnownSource(CPartFile *sender, CUpDownClient *so return false; // filter sources which are known to be temporarily dead/useless - if ((theApp.clientlist->m_globDeadSourceList.IsDeadSource(source) && !bIgnoreGlobDeadList) || sender->m_DeadSourceList.IsDeadSource(source)) { + if ((theApp.clientlist->m_globDeadSourceList.IsDeadSource(*source) && !bIgnoreGlobDeadList) || sender->m_DeadSourceList.IsDeadSource(*source)) { //if (thePrefs.GetLogFilteredIPs()) // AddDebugLogLine(DLP_DEFAULT, false, _T("Rejected source because it was found on the DeadSourcesList (%s) for file %s : %s") // ,sender->m_DeadSourceList.IsDeadSource(source)? _T("Local") : _T("Global"), (LPCTSTR)sender->GetFileName(), (LPCTSTR)source->DbgGetClientInfo()); return false; } - // filter sources which are incompatible with our encryption setting (one requires it, and the other one doesn't supports it) + // filter sources which are incompatible with our encryption setting (one requires it, and the other one doesn't support it) if ((source->RequiresCryptLayer() && (!thePrefs.IsClientCryptLayerSupported() || !source->HasValidHash())) || (thePrefs.IsClientCryptLayerRequired() && (!source->SupportsCryptLayer() || !source->HasValidHash()))) { #if defined(_DEBUG) || defined(_BETA) || defined(_DEVBUILD) //if (thePrefs.GetDebugSourceExchange()) // TODO: Uncomment after testing @@ -571,7 +564,7 @@ bool CDownloadQueue::CheckAndAddKnownSource(CPartFile *sender, CUpDownClient *so // by adding that client to the source list and filtering that client's LAN IP when sending sources to // a client within the internet. // - // "IPfilter" is not needed here, because that "known" client was already IPfiltered when receiving OP_HELLO. + // IP filter is not needed here, because that "known" client was already filtered when receiving OP_HELLO. if (!source->HasLowID()) { uint32 nClientIP = htonl(source->GetUserIDHybrid()); if (!IsGoodIP(nClientIP)) { // check for 0-IP, localhost and LAN addresses @@ -603,7 +596,7 @@ bool CDownloadQueue::CheckAndAddKnownSource(CPartFile *sender, CUpDownClient *so // further checks and updates. if (!md4equ(srcfile->GetFileHash(), sender->GetFileHash())) AddDebugLogLine(false, _T("*** CDownloadQueue::CheckAndAddKnownSource -- added potential wrong source (%u)(diff. filehash) to file \"%s\""), source->GetUserIDHybrid(), (LPCTSTR)sender->GetFileName()); - if (srcfile->GetPartCount() != 0 && srcfile->GetPartCount() != sender->GetPartCount()) + if (srcfile->GetPartCount() > 0 && srcfile->GetPartCount() != sender->GetPartCount()) AddDebugLogLine(false, _T("*** CDownloadQueue::CheckAndAddKnownSource -- added potential wrong source (%u)(diff. partcount) to file \"%s\""), source->GetUserIDHybrid(), (LPCTSTR)sender->GetFileName()); } #endif @@ -613,7 +606,7 @@ bool CDownloadQueue::CheckAndAddKnownSource(CPartFile *sender, CUpDownClient *so if (thePrefs.GetDebugSourceExchange()) AddDebugLogLine(false, _T("SXRecv: Passively added source; %s, File=\"%s\""), (LPCTSTR)source->DbgGetClientInfo(), (LPCTSTR)sender->GetFileName()); #ifdef _DEBUG - if (thePrefs.GetVerbose() && source->GetPartCount() != 0 && source->GetPartCount() != sender->GetPartCount()) + if (thePrefs.GetVerbose() && source->GetPartCount() > 0 && source->GetPartCount() != sender->GetPartCount()) DEBUG_ONLY(AddDebugLogLine(false, _T("*** CDownloadQueue::CheckAndAddKnownSource -- New added source (%u, %s) had still value in partcount"), source->GetUserIDHybrid(), (LPCTSTR)sender->GetFileName())); #endif @@ -726,13 +719,13 @@ bool CDownloadQueue::IsMaxFilesPerUDPServerPacketReached(uint32 nFiles, uint32 n return nFiles != 0; } -bool CDownloadQueue::SendGlobGetSourcesUDPPacket(CSafeMemFile *data, bool bExt2Packet, uint32 nFiles, uint32 nIncludedLargeFiles) +bool CDownloadQueue::SendGlobGetSourcesUDPPacket(CSafeMemFile &data, bool bExt2Packet, uint32 nFiles, uint32 nIncludedLargeFiles) { bool bSentPacket = false; if (cur_udpserver) { #ifdef _DEBUG - int iPacketSize = (int)data->GetLength(); + int iPacketSize = (int)data.GetLength(); #endif Packet packet(data); if (bExt2Packet) { @@ -797,11 +790,11 @@ bool CDownloadQueue::SendNextUDPPacket() // get the next file to search sources for CPartFile *nextfile = NULL; while (!bSentPacket && !(nextfile && (nextfile->GetStatus() == PS_READY || nextfile->GetStatus() == PS_EMPTY))) { - if (lastfile == NULL) // we just started the global source searching or have switched the server + if (m_lastfile == NULL) // we just started the global source searching or have switched the server // get the first file to search sources for nextfile = filelist.GetHead(); else { - POSITION pos = filelist.Find(lastfile); + POSITION pos = filelist.Find(m_lastfile); if (pos == NULL) // the last file is no longer in the DL-list (may have been finished or cancelled) // get the first file to search sources for nextfile = filelist.GetHead(); @@ -810,7 +803,7 @@ bool CDownloadQueue::SendNextUDPPacket() if (pos == 0) { // finished asking the current server for all files // if there are pending requests for the current server, send them if (dataGlobGetSources.GetLength() > 0) { - if (SendGlobGetSourcesUDPPacket(&dataGlobGetSources, bGetSources2Packet, iFiles, iLargeFiles)) + if (SendGlobGetSourcesUDPPacket(dataGlobGetSources, bGetSources2Packet, iFiles, iLargeFiles)) bSentPacket = true; dataGlobGetSources.SetLength(0); iFiles = 0; @@ -833,7 +826,7 @@ bool CDownloadQueue::SendNextUDPPacket() // if we already sent a packet, switch to the next file at next function call if (bSentPacket) { - lastfile = NULL; + m_lastfile = NULL; break; } @@ -846,7 +839,7 @@ bool CDownloadQueue::SendNextUDPPacket() nextfile = filelist.GetAt(pos); } } - lastfile = nextfile; + m_lastfile = nextfile; } if (!bSentPacket && nextfile && nextfile->GetSourceCount() < nextfile->GetMaxSourcePerFileUDP() && (bServerSupportsLargeFiles || !nextfile->IsLargeFile())) { @@ -872,7 +865,7 @@ bool CDownloadQueue::SendNextUDPPacket() ASSERT(dataGlobGetSources.GetLength() == 0 || !bSentPacket); if (!bSentPacket && dataGlobGetSources.GetLength() > 0) - SendGlobGetSourcesUDPPacket(&dataGlobGetSources, bGetSources2Packet, iFiles, iLargeFiles); + SendGlobGetSourcesUDPPacket(dataGlobGetSources, bGetSources2Packet, iFiles, iLargeFiles); // send max 35 UDP request to one server per interval // if we have more than 35 files, we rotate the list and use it as a queue @@ -897,7 +890,7 @@ bool CDownloadQueue::SendNextUDPPacket() } } while (cur_udpserver == pConnectedServer || cur_udpserver->GetFailedCount() >= thePrefs.GetDeadServerRetries()); ++m_iSearchedServers; - lastfile = NULL; + m_lastfile = NULL; } return true; @@ -906,8 +899,8 @@ bool CDownloadQueue::SendNextUDPPacket() void CDownloadQueue::StopUDPRequests() { cur_udpserver = NULL; - lastudpsearchtime = ::GetTickCount(); - lastfile = NULL; + m_lastudpsearchtime = ::GetTickCount(); + m_lastfile = NULL; m_iSearchedServers = 0; } @@ -930,7 +923,7 @@ void CDownloadQueue::HeapSort(UINT first, UINT last) { UINT r; POSITION pos1 = filelist.FindIndex(first); - for (r = first; !(r & (UINT)INT_MIN) && (r << 1) < last; ) { + for (r = first; !(r & (UINT)INT_MIN) && (r << 1) < last;) { UINT r2 = (r << 1) + 1; POSITION pos2 = filelist.FindIndex(r2); if (r2 != last) { @@ -964,20 +957,20 @@ void CDownloadQueue::SortByPriority() void CDownloadQueue::CheckDiskspaceTimed() { - if (!lastcheckdiskspacetime || ::GetTickCount() >= lastcheckdiskspacetime + DISKSPACERECHECKTIME) + if (!m_lastcheckdiskspacetime || ::GetTickCount() >= m_lastcheckdiskspacetime + DISKSPACERECHECKTIME) CheckDiskspace(); } void CDownloadQueue::CheckDiskspace(bool bNotEnoughSpaceLeft) { - lastcheckdiskspacetime = ::GetTickCount(); + m_lastcheckdiskspacetime = ::GetTickCount(); // sorting the list could be done here, but I prefer to "see" that function call in the calling functions. //SortByPriority(); // If disabled, resume any previously paused files if (!thePrefs.IsCheckDiskspaceEnabled()) { - if (!bNotEnoughSpaceLeft) // avoid worse case, if we already had 'disk full' + if (!bNotEnoughSpaceLeft) // avoid the worst case, if we already had 'disk full' for (POSITION pos = filelist.GetHeadPosition(); pos != NULL;) { CPartFile *cur_file = filelist.GetNext(pos); switch (cur_file->GetStatus()) { @@ -985,59 +978,42 @@ void CDownloadQueue::CheckDiskspace(bool bNotEnoughSpaceLeft) case PS_ERROR: case PS_COMPLETING: case PS_COMPLETE: - continue; + break; + default: + cur_file->ResumeFileInsufficient(); } - cur_file->ResumeFileInsufficient(); } return; } - uint64 nTotalAvailableSpaceMain = bNotEnoughSpaceLeft ? 0 : GetFreeDiskSpaceX(thePrefs.GetTempDir()); - // 'bNotEnoughSpaceLeft' - avoid worse case of having already 'disk full' - if (thePrefs.GetMinFreeDiskSpace() == 0) { - for (POSITION pos = filelist.GetHeadPosition(); pos != NULL;) { - CPartFile *cur_file = filelist.GetNext(pos); - - uint64 nTotalAvailableSpace = bNotEnoughSpaceLeft ? 0 : - ((thePrefs.GetTempDirCount() == 1) ? nTotalAvailableSpaceMain : GetFreeDiskSpaceX(cur_file->GetTempPath())); - - switch (cur_file->GetStatus()) { - case PS_PAUSED: - case PS_ERROR: - case PS_COMPLETING: - case PS_COMPLETE: - continue; - } + uint64 nTotalAvailableSpaceMain = bNotEnoughSpaceLeft ? 0 : GetFreeDiskSpaceX(thePrefs.GetTempDir()); - // Pause the file only if it would grow in size and would exceed the currently available free space - uint64 nSpaceToGo = cur_file->GetNeededSpace(); - if (nSpaceToGo <= nTotalAvailableSpace) { - nTotalAvailableSpace -= nSpaceToGo; - cur_file->ResumeFileInsufficient(); - } else - cur_file->PauseFile(true); - } - } else { - for (POSITION pos = filelist.GetHeadPosition(); pos != NULL;) { - CPartFile *cur_file = filelist.GetNext(pos); - switch (cur_file->GetStatus()) { - case PS_PAUSED: - case PS_ERROR: - case PS_COMPLETING: - case PS_COMPLETE: - continue; - } + for (POSITION pos = filelist.GetHeadPosition(); pos != NULL;) { + CPartFile* cur_file = filelist.GetNext(pos); + switch (cur_file->GetStatus()) { + case PS_PAUSED: + case PS_ERROR: + case PS_COMPLETING: + case PS_COMPLETE: + break; + default: uint64 nTotalAvailableSpace = bNotEnoughSpaceLeft ? 0 : - ((thePrefs.GetTempDirCount() == 1) ? nTotalAvailableSpaceMain : GetFreeDiskSpaceX(cur_file->GetTempPath())); - if (nTotalAvailableSpace < thePrefs.GetMinFreeDiskSpace()) { + ((thePrefs.GetTempDirCount() == 1) ? nTotalAvailableSpaceMain : GetFreeDiskSpaceX(cur_file->GetTmpPath())); + if (thePrefs.GetMinFreeDiskSpace() == 0) { + // Pause the file only if it would grow in size and would exceed the currently available free space + if (cur_file->GetNeededSpace() <= nTotalAvailableSpace) + cur_file->ResumeFileInsufficient(); + else + cur_file->PauseFile(true); + } else if (nTotalAvailableSpace < thePrefs.GetMinFreeDiskSpace()) { // Compressed/sparse files: always pause the file // Normal files: pause the file only if it would still grow if (!cur_file->IsNormalFile() || cur_file->GetNeededSpace() > 0) cur_file->PauseFile(true); } else { - // doesn't work this way. resuming the file without checking if there is a chance to successfully + // Doesn't work this way. Resuming the file without checking if there is a chance to successfully // flush any available buffered file data will pause the file right after it was resumed and disturb // the StopPausedFile function. //cur_file->ResumeFileInsufficient(); @@ -1268,7 +1244,7 @@ void CDownloadQueue::SetAutoCat(CPartFile *newfile) return; bool bFound = false; - for (int i = (int)thePrefs.GetCatCount(); --i > 0;) { + for (INT_PTR i = thePrefs.GetCatCount(); --i > 0;) { CString catExt(thePrefs.GetCategory(i)->autocat); if (catExt.IsEmpty()) continue; @@ -1285,7 +1261,7 @@ void CDownloadQueue::SetAutoCat(CPartFile *newfile) break; // HoaX_69: Allow wildcards in autocat string // thanks to: bluecow, khaos and SlugFiller - if ((cmpExt.FindOneOf(_T("*?")) && PathMatchSpec(fullname, cmpExt)) // Use wildcards + if ((cmpExt.FindOneOf(_T("*?")) && ::PathMatchSpec(fullname, cmpExt)) // Use wildcards || fullname.Find(cmpExt) >= 0) //simple string comparison { bFound = true; @@ -1294,7 +1270,7 @@ void CDownloadQueue::SetAutoCat(CPartFile *newfile) } } if (bFound) { - newfile->SetCategory(i); + newfile->SetCategory((UINT)i); return; } } @@ -1325,13 +1301,14 @@ void CDownloadQueue::RemoveLocalServerRequest(CPartFile *pFile) void CDownloadQueue::ProcessLocalRequests() { - if (!m_localServerReqQueue.IsEmpty() && ::GetTickCount() >= m_dwNextTCPSrcReq) { + const DWORD curTick = ::GetTickCount(); + if (!m_localServerReqQueue.IsEmpty() && curTick >= m_dwNextTCPSrcReq) { CSafeMemFile dataTcpFrame(22); const int iMaxFilesPerTcpFrame = 15; int iFiles = 0; while (!m_localServerReqQueue.IsEmpty() && iFiles < iMaxFilesPerTcpFrame) { - // find the file with the longest waitingtime - uint32 dwBestWaitTime = _UI32_MAX; + // find the file with the longest waiting time + DWORD dwBestWaitTime = _UI32_MAX; POSITION posNextRequest = NULL; for (POSITION pos = m_localServerReqQueue.GetHeadPosition(); pos != NULL;) { POSITION pos2 = pos; @@ -1358,12 +1335,12 @@ void CDownloadQueue::ProcessLocalRequests() if (posNextRequest != NULL) { CPartFile *cur_file = m_localServerReqQueue.GetAt(posNextRequest); cur_file->m_bLocalSrcReqQueued = false; - cur_file->m_LastSearchTime = ::GetTickCount(); + cur_file->m_LastSearchTime = curTick; m_localServerReqQueue.RemoveAt(posNextRequest); if (cur_file->IsLargeFile() && (theApp.serverconnect->GetCurrentServer() == NULL || !theApp.serverconnect->GetCurrentServer()->SupportsLargeFilesTCP())) { ASSERT(0); - DebugLogError(_T("Large file (%s) on local requestqueue for server without support for large files"), (LPCTSTR)cur_file->GetFileName()); + DebugLogError(_T("Large file (%s) on local request queue for server without support for large files"), (LPCTSTR)cur_file->GetFileName()); continue; } @@ -1385,7 +1362,7 @@ void CDownloadQueue::ProcessLocalRequests() else byOpcode = OP_GETSOURCES; - Packet packet(&smPacket, OP_EDONKEYPROT, byOpcode); + Packet packet(smPacket, OP_EDONKEYPROT, byOpcode); if (thePrefs.GetDebugServerTCPLevel() > 0) Debug(_T(">>> Sending OP_GetSources%s(%2u/%2u); %s\n"), (byOpcode == OP_GETSOURCES) ? _T("") : _T("_OBFU"), iFiles, iMaxFilesPerTcpFrame, (LPCTSTR)DbgGetFileInfo(cur_file->GetFileHash())); dataTcpFrame.Write(packet.GetPacket(), packet.GetRealPacketSize()); @@ -1398,7 +1375,7 @@ void CDownloadQueue::ProcessLocalRequests() int iSize = (int)dataTcpFrame.GetLength(); if (iSize > 0) { // create one 'packet' which contains all buffered OP_GETSOURCES eD2K packets to be sent with one TCP frame - // server credits: 16*iMaxFilesPerTcpFrame+1 = 241 + // server credits: 16 * iMaxFilesPerTcpFrame + 1 = 241 Packet *packet = new Packet(new char[iSize], (uint32)dataTcpFrame.GetLength(), true, false); dataTcpFrame.Seek(0, CFile::begin); dataTcpFrame.Read(packet->GetPacket(), iSize); @@ -1407,7 +1384,7 @@ void CDownloadQueue::ProcessLocalRequests() } // next TCP frame with up to 15 source requests is allowed to be sent in - m_dwNextTCPSrcReq = ::GetTickCount() + SEC2MS(iMaxFilesPerTcpFrame * (16 + 4)); + m_dwNextTCPSrcReq = curTick + SEC2MS(iMaxFilesPerTcpFrame * (16 + 4)); } } @@ -1441,7 +1418,8 @@ int CDownloadQueue::GetDownloadFilesStats(uint64 &rui64TotalFileSize /////////////////////////////////////////////////////////////////////////////// // CSourceHostnameResolveWnd -#define WM_HOSTNAMERESOLVED (WM_USER + 0x101) // does not need to be placed in "UserMsgs.h" +//It is safer to keep all message codes different (see also AsyncSocketEx.h and UserMsgs.h) +#define WM_HOSTNAMERESOLVED (WM_USER+0x105) // does not need to be placed in "UserMsgs.h" BEGIN_MESSAGE_MAP(CSourceHostnameResolveWnd, CWnd) ON_MESSAGE(WM_HOSTNAMERESOLVED, OnHostnameResolved) @@ -1460,12 +1438,12 @@ CSourceHostnameResolveWnd::~CSourceHostnameResolveWnd() void CSourceHostnameResolveWnd::AddToResolve(const uchar *fileid, LPCSTR pszHostname, uint16 port, LPCTSTR pszURL) { - bool bResolving = !m_toresolve.IsEmpty(); - // double checking if (!theApp.downloadqueue->GetFileByID(fileid)) return; + bool bResolving = !m_toresolve.IsEmpty(); + Hostname_Entry *entry = new Hostname_Entry; md4cpy(entry->fileid, fileid); entry->strHostname = pszHostname; @@ -1478,7 +1456,7 @@ void CSourceHostnameResolveWnd::AddToResolve(const uchar *fileid, LPCSTR pszHost memset(m_aucHostnameBuffer, 0, sizeof m_aucHostnameBuffer); if (!WSAAsyncGetHostByName(m_hWnd, WM_HOSTNAMERESOLVED, entry->strHostname, m_aucHostnameBuffer, sizeof m_aucHostnameBuffer)) { - m_toresolve.RemoveHead(); + m_toresolve.RemoveTail(); delete entry; } } @@ -1516,7 +1494,7 @@ LRESULT CSourceHostnameResolveWnd::OnHostnameResolved(WPARAM, LPARAM lParam) Hostname_Entry *entry = m_toresolve.GetHead(); memset(m_aucHostnameBuffer, 0, sizeof m_aucHostnameBuffer); if (WSAAsyncGetHostByName(m_hWnd, WM_HOSTNAMERESOLVED, entry->strHostname, m_aucHostnameBuffer, sizeof m_aucHostnameBuffer) != 0) - return TRUE; + break; m_toresolve.RemoveHead(); delete entry; } @@ -1525,13 +1503,13 @@ LRESULT CSourceHostnameResolveWnd::OnHostnameResolved(WPARAM, LPARAM lParam) bool CDownloadQueue::DoKademliaFileRequest() const { - return (::GetTickCount() >= lastkademliafilerequest + KADEMLIAASKTIME); + return (::GetTickCount() >= m_lastkademliafilerequest + KADEMLIAASKTIME); } -void CDownloadQueue::KademliaSearchFile(uint32 searchID, const Kademlia::CUInt128 *pcontactID, const Kademlia::CUInt128 *pbuddyID, uint8 type, uint32 ip, uint16 tcp, uint16 udp, uint32 dwBuddyIP, uint16 dwBuddyPort, uint8 byCryptOptions) +void CDownloadQueue::KademliaSearchFile(uint32 nSearchID, const Kademlia::CUInt128 *pcontactID, const Kademlia::CUInt128 *pbuddyID, uint8 type, uint32 ip, uint16 tcp, uint16 udp, uint32 dwBuddyIP, uint16 dwBuddyPort, uint8 byCryptOptions) { //Safety measure to make sure we are looking for these sources - CPartFile *temp = GetFileByKadFileSearchID(searchID); + CPartFile *temp = GetFileByKadFileSearchID(nSearchID); if (!temp) return; //Do we need more sources? @@ -1547,7 +1525,7 @@ void CDownloadQueue::KademliaSearchFile(uint32 searchID, const Kademlia::CUInt12 if ((ip == Kademlia::CKademlia::GetIPAddress() || ED2Kip == theApp.serverconnect->GetClientID()) && tcp == thePrefs.GetPort()) return; CUpDownClient *ctemp = NULL; - //DEBUG_ONLY( DebugLog(_T("Kadsource received, type %u, IP %s"), type, (LPCTSTR)ipstr(ED2Kip)) ); + //DEBUG_ONLY( DebugLog(_T("Kad source received, type %u, IP %s"), type, (LPCTSTR)ipstr(ED2Kip)) ); switch (type) { case 4: case 1: @@ -1631,9 +1609,9 @@ void CDownloadQueue::KademliaSearchFile(uint32 searchID, const Kademlia::CUInt12 void CDownloadQueue::ExportPartMetFilesOverview() const { - CString strFileListPath(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + _T("downloads.txt")); + const CString &strFileListPath(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + _T("downloads.txt")); - CString strTmpFileListPath = strFileListPath; + CString strTmpFileListPath(strFileListPath); PathRenameExtension(strTmpFileListPath.GetBuffer(MAX_PATH), _T(".tmp")); strTmpFileListPath.ReleaseBuffer(); @@ -1643,13 +1621,13 @@ void CDownloadQueue::ExportPartMetFilesOverview() const CString strError; TCHAR szError[MAX_CFEXP_ERRORMSG]; if (GetExceptionMessage(fexp, szError, _countof(szError))) - strError.AppendFormat(_T(" - %s"), szError); + strError.Format(_T(" - %s"), szError); LogError(_T("Failed to create part.met file list%s"), (LPCTSTR)strError); return; } // write Unicode byte order mark 0xFEFF - fputwc(0xFEFFui16, file.m_pStream); + fputwc(u'\xFEFF', file.m_pStream); try { file.printf(_T("Date: %s\r\n"), (LPCTSTR)CTime::GetCurrentTime().Format(_T("%c"))); @@ -1661,7 +1639,7 @@ void CDownloadQueue::ExportPartMetFilesOverview() const for (POSITION pos = filelist.GetHeadPosition(); pos != NULL;) { const CPartFile *pPartFile = filelist.GetNext(pos); if (pPartFile->GetStatus(true) != PS_COMPLETE) { - CString strPartFilePath(pPartFile->GetFilePath()); + const CString &strPartFilePath(pPartFile->GetFilePath()); TCHAR szNam[_MAX_FNAME]; TCHAR szExt[_MAX_EXT]; _tsplitpath(strPartFilePath, NULL, NULL, szNam, szExt); @@ -1672,14 +1650,14 @@ void CDownloadQueue::ExportPartMetFilesOverview() const } } - if ((theApp.IsClosing() && thePrefs.GetCommitFiles() >= 1) || thePrefs.GetCommitFiles() >= 2) { + if (thePrefs.GetCommitFiles() >= 2 || (thePrefs.GetCommitFiles() >= 1 && theApp.IsClosing())) { file.Flush(); // flush file stream buffers to disk buffers if (_commit(_fileno(file.m_pStream)) != 0) // commit disk buffers to disk AfxThrowFileException(CFileException::hardIO, ::GetLastError(), file.GetFileName()); } file.Close(); - CString strBakFileListPath = strFileListPath; + CString strBakFileListPath(strFileListPath); PathRenameExtension(strBakFileListPath.GetBuffer(MAX_PATH), _T(".bak")); strBakFileListPath.ReleaseBuffer(); @@ -1692,7 +1670,7 @@ void CDownloadQueue::ExportPartMetFilesOverview() const CString strError; TCHAR szError[MAX_CFEXP_ERRORMSG]; if (GetExceptionMessage(*e, szError, _countof(szError))) - strError.AppendFormat(_T(" - %s"), szError); + strError.Format(_T(" - %s"), szError); LogError(_T("Failed to write part.met file list%s"), (LPCTSTR)strError); e->Delete(); file.Abort(); @@ -1711,103 +1689,123 @@ void CDownloadQueue::OnConnectionState(bool bConnected) CString CDownloadQueue::GetOptimalTempDir(UINT nCat, EMFileSize nFileSize) { + const INT_PTR iTempDirCnt = thePrefs.GetTempDirCount(); // shortcut - if (thePrefs.GetTempDirCount() == 1) + if (iTempDirCnt == 1) return thePrefs.GetTempDir(); - CMap mapNeededSpaceOnDrive; - CMap mapFreeSpaceOnDrive; - - sint64 llBuffer = 0; + struct tmpDir + { + INT_PTR iDrive; //-1 for UNC paths; 0 to 25 for drives from a: to z: + //-2 for skipping the entry + CString sShare; //when iDrive is -1, this is a share name (\\server\share\) + sint64 llFreeSpace; //free space - (reserved minimum) - (collected space to complete all files on the drive) + }; + CArray aDrive; + aDrive.SetSize(iTempDirCnt); + + // Step 1: collect free space on drives sint64 llHighestFreeSpace = 0; - int nHighestFreeSpaceDrive = -1; - // first collect the free space on drives - for (INT_PTR i = 0; i < thePrefs.GetTempDirCount(); ++i) { - const int nDriveNumber = GetPathDriveNumber(thePrefs.GetTempDir(i)); - if (mapFreeSpaceOnDrive.Lookup(nDriveNumber, llBuffer)) - continue; - llBuffer = GetFreeDiskSpaceX(thePrefs.GetTempDir(i)) - thePrefs.GetMinFreeDiskSpace(); - mapFreeSpaceOnDrive.SetAt(nDriveNumber, llBuffer); - if (llBuffer > llHighestFreeSpace) { - nHighestFreeSpaceDrive = nDriveNumber; - llHighestFreeSpace = llBuffer; - } + INT_PTR nHighestFreeSpaceDrive = -1; + for (INT_PTR i = 0; i < iTempDirCnt; ++i) { + const CString &sDir(thePrefs.GetTempDir(i)); + INT_PTR iDrive = GetPathDriveNumber(sDir); + ASSERT(iDrive >= 0 || ::PathIsUNC(sDir)); + if (iDrive < 0) //UNC path + aDrive[i].sShare = GetShareName(sDir).MakeLower(); + //Free space is calculated per drive (or share), but several temp directories may be on one drive + INT_PTR j; + for (j = 0; j < i; ++j) + if (iDrive == aDrive[j].iDrive && (iDrive >= 0 || aDrive[i].sShare == aDrive[j].sShare)) + break; + if (i >= j) { + aDrive[i].iDrive = iDrive; + sint64 llSpace = GetFreeDiskSpaceX(sDir) - thePrefs.GetMinFreeDiskSpace(); + if (llSpace > llHighestFreeSpace) { + nHighestFreeSpaceDrive = i; + llHighestFreeSpace = llSpace; + } + aDrive[i].llFreeSpace = llSpace; + } else + aDrive[i].iDrive = -2; //data for this drive is already known } - // now get the space we would need to download all files in the current queue + // Step 2: collect the space we need to download all files in the current queue for (POSITION pos = filelist.GetHeadPosition(); pos != NULL;) { const CPartFile *pCurFile = filelist.GetNext(pos); - const int nDriveNumber = GetPathDriveNumber(pCurFile->GetTempPath()); - - sint64 llNeededForCompletion = 0; switch (pCurFile->GetStatus(false)) { case PS_READY: case PS_EMPTY: case PS_WAITINGFORHASH: case PS_INSUFFICIENT: - llNeededForCompletion = (uint64)pCurFile->GetFileSize() - (uint64)pCurFile->GetRealFileSize(); - if (llNeededForCompletion < 0) - llNeededForCompletion = 0; + { + sint64 llSpace = (uint64)pCurFile->GetFileSize() - (uint64)pCurFile->GetRealFileSize(); + if (llSpace > 0) { + const CString &sPath(pCurFile->GetTmpPath()); + INT_PTR iDrive = GetPathDriveNumber(sPath); + ASSERT(iDrive >= 0 || ::PathIsUNC(sPath)); + CString sUNC; + if (iDrive < 0) + sUNC = GetShareName(sPath).MakeLower(); + + for (INT_PTR i = 0; i < iTempDirCnt; ++i) //look up for the same drive or share + if (iDrive == aDrive[i].iDrive && (iDrive >= 0 || sUNC == aDrive[i].sShare)) { + aDrive[i].llFreeSpace -= llSpace; + break; + } + } + } } - if (!mapNeededSpaceOnDrive.Lookup(nDriveNumber, llBuffer)) - llBuffer = 0; - mapNeededSpaceOnDrive.SetAt(nDriveNumber, llBuffer + llNeededForCompletion); } sint64 llHighestTotalSpace = 0; - int nHighestTotalSpaceDir = -1; - int nHighestFreeSpaceDir = -1; - int nAnyAvailableDir = -1; - // first round (0): on same drive as incoming and enough space for all downloading + INT_PTR nHighestTotalSpaceDir = -1; + INT_PTR nHighestFreeSpaceDir = -1; + INT_PTR nAnyAvailableDir = -1; + // first round (0): on the same drive as incoming and enough space for all downloading // second round (1): enough space for all downloading // third round (2): largest actual free space - for (INT_PTR i = 0; i < thePrefs.GetTempDirCount(); ++i) { - const int nDriveNumber = GetPathDriveNumber(thePrefs.GetTempDir(i)); - sint64 llAvailableSpace; - if (!mapFreeSpaceOnDrive.Lookup(nDriveNumber, llAvailableSpace)) - llAvailableSpace = 0; - if (mapNeededSpaceOnDrive.Lookup(nDriveNumber, llBuffer)) - llAvailableSpace -= llBuffer; + for (INT_PTR i = 0; i < iTempDirCnt; ++i) { + if (aDrive[i].iDrive == -2) + continue; + const sint64 llAvailableSpace = aDrive[i].llFreeSpace; // no condition can be met for a large file on a FAT volume if (nFileSize <= OLD_MAX_EMULE_FILE_SIZE || !IsFileOnFATVolume(thePrefs.GetTempDir(i))) { - // condition 0 - // needs to be same drive and enough space - if (GetPathDriveNumber(thePrefs.GetCatPath(nCat)) == nDriveNumber && - llAvailableSpace > (sint64)(uint64)nFileSize) { - //this one is perfect - return thePrefs.GetTempDir(i); - } - // condition 1 - // needs to have enough space for downloading - if (llAvailableSpace > (sint64)nFileSize && llAvailableSpace > llHighestTotalSpace) { - llHighestTotalSpace = llAvailableSpace; - nHighestTotalSpaceDir = (int)i; + if (llAvailableSpace >= (sint64)(uint64)nFileSize) { + // condition 0 + // needs to be the same drive and enough space + if (GetPathDriveNumber(thePrefs.GetCatPath(nCat)) == aDrive[i].iDrive) + return thePrefs.GetTempDir(i); //this one is perfect + + // condition 1 + // needs to have enough space for downloading + if (llAvailableSpace > llHighestTotalSpace) { + llHighestTotalSpace = llAvailableSpace; + nHighestTotalSpaceDir = i; + } } // condition 2 - // first one which has the highest actually free space - if (nDriveNumber == nHighestFreeSpaceDrive && nHighestFreeSpaceDir == -1) - nHighestFreeSpaceDir = (int)i; + // the first one with the highest actually free space (see Step 1) + if (i == nHighestFreeSpaceDrive && nHighestFreeSpaceDir < 0) + nHighestFreeSpaceDir = i; // condition 3 - // any directory which can be used for this file (ak not FAT for large files) - if (nAnyAvailableDir == -1) - nAnyAvailableDir = (int)i; + // any directory which can be used for this file (aka not FAT for large files) + if (nAnyAvailableDir < 0) + nAnyAvailableDir = i; } } - if (nHighestTotalSpaceDir != -1) // condition 0 was apparently too much, take 1 + if (nHighestTotalSpaceDir >= 0) // condition 0 was apparently too strong, take 1 return thePrefs.GetTempDir(nHighestTotalSpaceDir); - if (nHighestFreeSpaceDir != -1) // condition 1 could not be met too, take 2 + if (nHighestFreeSpaceDir >= 0) // condition 1 could not be met too, take 2 return thePrefs.GetTempDir(nHighestFreeSpaceDir); - if (nAnyAvailableDir != -1) - return thePrefs.GetTempDir(nAnyAvailableDir); - // so was condition 2 and 3, take 4... wait there is no 3 - this must be a bug - ASSERT(0); - return thePrefs.GetTempDir(); + ASSERT(nAnyAvailableDir >= 0); + return thePrefs.GetTempDir(max(nAnyAvailableDir, 0)); } void CDownloadQueue::RefilterAllComments() diff --git a/srchybrid/DownloadQueue.h b/srchybrid/DownloadQueue.h index 5e0fb677..a16f2578 100644 --- a/srchybrid/DownloadQueue.h +++ b/srchybrid/DownloadQueue.h @@ -1,4 +1,4 @@ -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -22,6 +22,7 @@ class CServer; class CPartFile; class CSharedFileList; class CKnownFile; +class CED2KFileLink; struct SUnresolvedHostname; namespace Kademlia @@ -45,7 +46,7 @@ class CSourceHostnameResolveWnd : public CWnd private: struct Hostname_Entry { - uchar fileid[16]; + uchar fileid[MDX_DIGEST_SIZE]; CStringA strHostname; uint16 port; CString strURL; @@ -72,7 +73,7 @@ class CDownloadQueue void AddDownload(CPartFile *newfile, bool paused); void AddSearchToDownload(CSearchFile *toadd, uint8 paused = 2, int cat = 0); void AddSearchToDownload(const CString &link, uint8 paused = 2, int cat = 0); - void AddFileLinkToDownload(class CED2KFileLink *pLink, int cat = 0); + void AddFileLinkToDownload(const CED2KFileLink &Link, int cat = 0); void RemoveFile(CPartFile *toremove); void DeleteAll(); @@ -108,7 +109,7 @@ class CDownloadQueue } SDownloadStats; void GetDownloadSourcesStats(SDownloadStats &results); int GetDownloadFilesStats(uint64 &rui64TotalFileSize, uint64 &rui64TotalLeftToTransfer, uint64 &rui64TotalAdditionalNeededSpace); - uint32 GetDatarate() const { return datarate; } + uint32 GetDatarate() const { return m_datarate; } void AddUDPFileReasks() { ++m_nUDPFileReasks; } uint32 GetUDPFileReasks() const { return m_nUDPFileReasks; } @@ -129,14 +130,14 @@ class CDownloadQueue void ResetLocalServerRequests(); // searching in Kad - void SetLastKademliaFileRequest() { lastkademliafilerequest = ::GetTickCount(); } + void SetLastKademliaFileRequest() { m_lastkademliafilerequest = ::GetTickCount(); } bool DoKademliaFileRequest() const; - void KademliaSearchFile(uint32 searchID, const Kademlia::CUInt128 *pcontactID, const Kademlia::CUInt128 *pbuddyID, uint8 type, uint32 ip, uint16 tcp, uint16 udp, uint32 dwBuddyIP, uint16 dwBuddyPort, uint8 byCryptOptions); + void KademliaSearchFile(uint32 nSearchID, const Kademlia::CUInt128 *pcontactID, const Kademlia::CUInt128 *pbuddyID, uint8 type, uint32 ip, uint16 tcp, uint16 udp, uint32 dwBuddyIP, uint16 dwBuddyPort, uint8 byCryptOptions); // searching on global servers void StopUDPRequests(); - // check diskspace + // check disk space void SortByPriority(); void CheckDiskspace(bool bNotEnoughSpaceLeft = false); void CheckDiskspaceTimed(); @@ -154,7 +155,7 @@ class CDownloadQueue bool SendNextUDPPacket(); void ProcessLocalRequests(); bool IsMaxFilesPerUDPServerPacketReached(uint32 nFiles, uint32 nIncludedLargeFiles) const; - bool SendGlobGetSourcesUDPPacket(CSafeMemFile *data, bool bExt2Packet, uint32 nFiles, uint32 nIncludedLargeFiles); + bool SendGlobGetSourcesUDPPacket(CSafeMemFile &data, bool bExt2Packet, uint32 nFiles, uint32 nIncludedLargeFiles); private: bool CompareParts(POSITION pos1, POSITION pos2); @@ -163,23 +164,6 @@ class CDownloadQueue CTypedPtrList filelist; CTypedPtrList m_localServerReqQueue; - uint64 m_datarateMS; - CPartFile *lastfile; - DWORD m_dwLastA4AFtime; // ZZ:DownloadManager - uint32 lastcheckdiskspacetime; - uint32 lastudpsearchtime; - uint32 lastudpstattime; - UINT udcounter; - UINT m_cRequestsSentToServer; - uint32 m_dwNextTCPSrcReq; - uint32 lastkademliafilerequest; - int m_iSearchedServers; - - uint32 m_nUDPFileReasks; - uint32 m_nFailedUDPFileReasks; - uint32 datarate; - uint16 filesrdy; - // By BadWolf - Accurate Speed Measurement typedef struct { @@ -190,4 +174,19 @@ class CDownloadQueue // END By BadWolf - Accurate Speed Measurement CSourceHostnameResolveWnd m_srcwnd; + uint64 m_datarateMS; + CPartFile *m_lastfile; + DWORD m_dwLastA4AFtime; // ZZ:DownloadManager + DWORD m_lastcheckdiskspacetime; + DWORD m_lastudpsearchtime; + DWORD m_lastudpstattime; + DWORD m_lastkademliafilerequest; + DWORD m_dwNextTCPSrcReq; + UINT m_udcounter; + UINT m_cRequestsSentToServer; + int m_iSearchedServers; + + uint32 m_nUDPFileReasks; + uint32 m_nFailedUDPFileReasks; + uint32 m_datarate; }; \ No newline at end of file diff --git a/srchybrid/Drawgdix.h b/srchybrid/Drawgdix.h index 3b95109f..1fafc029 100644 --- a/srchybrid/Drawgdix.h +++ b/srchybrid/Drawgdix.h @@ -26,10 +26,10 @@ class CSelStock CGdiObject* Old() class CSelPen - CSelPen(CDC *pDC, COLORREF col, int sty=PS_SOLID, int wid = 0) + CSelPen(CDC *pDC, COLORREF col, int sty = PS_SOLID, int wid = 0) CSelPen(CDC *pDC, CPen *pPen) void Select(CPen *pPen) - void Select(COLORREF col, int sty=PS_SOLID, int wid = 0) + void Select(COLORREF col, int sty = PS_SOLID, int wid = 0) class CSelBrush CSelBrush(CDC *pDC, CBrush *pBrush) @@ -650,7 +650,7 @@ class CSelROP2 : public CSelect : CSelect(pDC) , m_OldRop() { - /*VERIFY(m_OldRop=m_pDC->GetROP2());*/ + /*VERIFY(m_OldRop = m_pDC->GetROP2());*/ } CSelROP2(CDC *pDC, int drawMode) diff --git a/srchybrid/DropDownButton.cpp b/srchybrid/DropDownButton.cpp index c3657e6c..86d81fc6 100644 --- a/srchybrid/DropDownButton.cpp +++ b/srchybrid/DropDownButton.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -91,7 +91,7 @@ void CDropDownButton::SetWindowText(LPCTSTR pszString) int id = (int)::GetWindowLongPtr(m_hWnd, GWLP_ID); int cx = m_bSingleDropDownBtn ? 0 : GetBtnWidth(id); - TBBUTTONINFO tbbi = {}; + TBBUTTONINFO tbbi; tbbi.cbSize = (UINT)sizeof tbbi; tbbi.dwMask = TBIF_TEXT; tbbi.pszText = const_cast(pszString); @@ -114,7 +114,7 @@ void CDropDownButton::SetIcon(LPCTSTR pszResourceID) if (pImlOld) pImlOld->DeleteImageList(); - TBBUTTONINFO tbbi = {}; + TBBUTTONINFO tbbi; tbbi.cbSize = (UINT)sizeof tbbi; tbbi.dwMask = TBIF_IMAGE; tbbi.iImage = 0; diff --git a/srchybrid/DropDownButton.h b/srchybrid/DropDownButton.h index 47c8e3dc..22497002 100644 --- a/srchybrid/DropDownButton.h +++ b/srchybrid/DropDownButton.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -22,7 +22,6 @@ class CDropDownButton : public CToolBarCtrlX DECLARE_DYNAMIC(CDropDownButton) public: CDropDownButton(); - virtual ~CDropDownButton() = default; BOOL Create(DWORD dwStyle, const RECT &rect, CWnd *pParentWnd, UINT nID, bool bSingleDropDownBtn = true); BOOL Init(bool bSingleDropDownBtn = true, bool bWholeDropDown = false); diff --git a/srchybrid/DropTarget.cpp b/srchybrid/DropTarget.cpp index cbe94b1c..5d789e77 100644 --- a/srchybrid/DropTarget.cpp +++ b/srchybrid/DropTarget.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -146,8 +146,7 @@ CMainFrameDropTarget::CMainFrameDropTarget() , m_cfHTML((CLIPFORMAT)RegisterClipboardFormat(_T("HTML Format"))) , m_cfShellURL((CLIPFORMAT)RegisterClipboardFormat(CFSTR_SHELLURL)) { - ASSERT(m_cfHTML != 0); - ASSERT(m_cfShellURL != 0); + ASSERT(m_cfHTML && m_cfShellURL); } HRESULT CMainFrameDropTarget::PasteHTMLDocument(IHTMLDocument2 *doc, PASTEURLDATA* /*pPaste*/) @@ -179,7 +178,7 @@ HRESULT CMainFrameDropTarget::PasteHTMLDocument(IHTMLDocument2 *doc, PASTEURLDAT theApp.emuledlg->ProcessED2KLink(CString(bstrHref)); hrPasteResult = S_OK; } - anchor.Release(); // conserve memory + anchor.Release(); // free memory } } } @@ -314,7 +313,7 @@ HRESULT CMainFrameDropTarget::PasteHTML(COleDataObject &data) HRESULT hrPasteResult = E_FAIL; HGLOBAL hMem = data.GetGlobalData(m_cfHTML); if (hMem != NULL) { - LPCSTR pszClipboard = (LPCSTR)GlobalLock(hMem); + LPCSTR pszClipboard = (LPCSTR)::GlobalLock(hMem); if (pszClipboard != NULL) { hrPasteResult = S_FALSE; // default: nothing was pasted LPCSTR pszHTML = strchr(pszClipboard, '<'); @@ -323,9 +322,9 @@ HRESULT CMainFrameDropTarget::PasteHTML(COleDataObject &data) PASTEURLDATA Paste(bstrHTMLText); hrPasteResult = PasteHTML(&Paste); } - GlobalUnlock(hMem); + ::GlobalUnlock(hMem); } - GlobalFree(hMem); + ::GlobalFree(hMem); } return hrPasteResult; } @@ -335,7 +334,7 @@ HRESULT CMainFrameDropTarget::PasteText(CLIPFORMAT cfData, COleDataObject &data) HRESULT hrPasteResult = E_FAIL; HANDLE hMem = data.GetGlobalData(cfData); if (hMem != NULL) { - LPCSTR pszUrlA = (LPCSTR)GlobalLock(hMem); + LPCSTR pszUrlA = (LPCSTR)::GlobalLock(hMem); if (pszUrlA != NULL) { // skip white space while (isspace(*pszUrlA)) @@ -352,10 +351,9 @@ HRESULT CMainFrameDropTarget::PasteText(CLIPFORMAT cfData, COleDataObject &data) } } } - - GlobalUnlock(hMem); + ::GlobalUnlock(hMem); } - GlobalFree(hMem); + ::GlobalFree(hMem); } return hrPasteResult; } @@ -380,7 +378,7 @@ HRESULT CMainFrameDropTarget::AddUrlFileContents(LPCTSTR pszFileName) theApp.emuledlg->ProcessED2KLink(pwszUrl); else hrResult = S_FALSE; - CoTaskMemFree(pwszUrl); + ::CoTaskMemFree(pwszUrl); } } } @@ -395,7 +393,7 @@ HRESULT CMainFrameDropTarget::PasteHDROP(COleDataObject &data) HRESULT hrPasteResult = E_FAIL; HANDLE hMem = data.GetGlobalData(CF_HDROP); if (hMem != NULL) { - LPDROPFILES lpDrop = (LPDROPFILES)GlobalLock(hMem); + LPDROPFILES lpDrop = (LPDROPFILES)::GlobalLock(hMem); if (lpDrop != NULL) { if (lpDrop->fWide) { LPCWSTR pszFileNameW = (LPCWSTR)((LPBYTE)lpDrop + lpDrop->pFiles); @@ -414,60 +412,58 @@ HRESULT CMainFrameDropTarget::PasteHDROP(COleDataObject &data) pszFileNameA += strlen(pszFileNameA) + 1; } } - GlobalUnlock(hMem); + ::GlobalUnlock(hMem); } - GlobalFree(hMem); + ::GlobalFree(hMem); } return hrPasteResult; } BOOL CMainFrameDropTarget::IsSupportedDropData(COleDataObject *pDataObject) { - BOOL bResult; - //************************************************************************ //*** THIS FUNCTION HAS TO BE AS FAST AS POSSIBLE!!! //************************************************************************ - if (m_cfHTML && pDataObject->IsDataAvailable(m_cfHTML)) { - // If the data is in 'HTML Format', there is no need to check the contents. - bResult = TRUE; - } else if (m_cfShellURL && pDataObject->IsDataAvailable(m_cfShellURL)) { - // If the data is in 'UniformResourceLocator', there is no need to check the contents. - bResult = TRUE; - } else if (pDataObject->IsDataAvailable(CF_UNICODETEXT)) { + // If the data is in 'HTML Format', there is no need to check the contents. + if (m_cfHTML && pDataObject->IsDataAvailable(m_cfHTML)) + return TRUE; + + // If the data is in 'UniformResourceLocator', there is no need to check the contents. + if (m_cfShellURL && pDataObject->IsDataAvailable(m_cfShellURL)) + return TRUE; + + BOOL bResult = FALSE; // Unknown data format + if (pDataObject->IsDataAvailable(CF_UNICODETEXT)) { // // Check text data // - bResult = FALSE; HANDLE hMem = pDataObject->GetGlobalData(CF_UNICODETEXT); if (hMem != NULL) { - LPCWSTR lpszUrl = (LPCWSTR)GlobalLock(hMem); + LPCWSTR lpszUrl = (LPCWSTR)::GlobalLock(hMem); if (lpszUrl != NULL) { // skip white space while (isspace(*lpszUrl)) ++lpszUrl; bResult = IsUrlSchemeSupportedW(lpszUrl); - GlobalUnlock(hMem); + ::GlobalUnlock(hMem); } - GlobalFree(hMem); + ::GlobalFree(hMem); } } else if (pDataObject->IsDataAvailable(CF_HDROP)) { // // Check HDROP data // - bResult = FALSE; - HANDLE hMem = pDataObject->GetGlobalData(CF_HDROP); if (hMem != NULL) { - LPDROPFILES lpDrop = (LPDROPFILES)GlobalLock(hMem); + LPDROPFILES lpDrop = (LPDROPFILES)::GlobalLock(hMem); if (lpDrop != NULL) { // Just check, if there's at least one file we can import if (lpDrop->fWide) { LPCWSTR pszFileW = (LPCWSTR)((LPBYTE)lpDrop + lpDrop->pFiles); while (*pszFileW != L'\0') { - int iLen = (int)wcslen(pszFileW); - LPCWSTR pszExtW = GetFileExtW(pszFileW, iLen); + size_t iLen = wcslen(pszFileW); + LPCWSTR pszExtW = GetFileExtW(pszFileW, (int)iLen); if (pszExtW != NULL && _wcsicmp(pszExtW, FILEEXTDOT_INETSHRTCUTW) == 0) { bResult = TRUE; break; @@ -477,8 +473,8 @@ BOOL CMainFrameDropTarget::IsSupportedDropData(COleDataObject *pDataObject) } else { LPCSTR pszFileA = (LPCSTR)((LPBYTE)lpDrop + lpDrop->pFiles); while (*pszFileA != '\0') { - int iLen = (int)strlen(pszFileA); - LPCSTR pszExtA = GetFileExtA(pszFileA, iLen); + size_t iLen = strlen(pszFileA); + LPCSTR pszExtA = GetFileExtA(pszFileA, (int)iLen); if (pszExtA != NULL && _stricmp(pszExtA, FILEEXTDOT_INETSHRTCUTA) == 0) { bResult = TRUE; break; @@ -486,15 +482,11 @@ BOOL CMainFrameDropTarget::IsSupportedDropData(COleDataObject *pDataObject) pszFileA += iLen + 1; } } - GlobalUnlock(hMem); + ::GlobalUnlock(hMem); } - GlobalFree(hMem); + ::GlobalFree(hMem); } - } else { - // Unknown data format - bResult = FALSE; } - return bResult; } diff --git a/srchybrid/ED2KLink.cpp b/srchybrid/ED2KLink.cpp index 5d01a286..b2ebbb0e 100644 --- a/srchybrid/ED2KLink.cpp +++ b/srchybrid/ED2KLink.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -17,11 +17,10 @@ #include "stdafx.h" #include #include "resource.h" +#include "opcodes.h" #include "ED2KLink.h" -#include "OtherFunctions.h" #include "SafeFile.h" #include "StringConversion.h" -#include "opcodes.h" #include "preferences.h" #include "ATLComTime.h" @@ -32,24 +31,6 @@ static char THIS_FILE[] = __FILE__; #endif - -namespace -{ - struct autoFree - { - explicit autoFree(LPTSTR p) - : m_p(p) - { - } - ~autoFree() - { - free(m_p); - } - private: - LPTSTR m_p; - }; -} - ///////////////////////////////////////////// // CED2KServerListLink implementation ///////////////////////////////////////////// @@ -127,21 +108,24 @@ CED2KFileLink::CED2KFileLink(LPCTSTR pszName, LPCTSTR pszSize, LPCTSTR pszHash // at the same time. However, to avoid the pasting of raw UTF-8 strings (which would lead // to a greater mess in the network) we always try to decode from UTF-8, even if the string // did not contain escape sequences. + UINT uid = 0; if (m_name.IsEmpty()) - throw GetResString(IDS_ERR_NOTAFILELINK); - - if (_tcslen(pszHash) != 32) - throw GetResString(IDS_ERR_ILLFORMEDHASH); - - const sint64 iSize = _tstoi64(pszSize); - if (iSize <= 0) - throw GetResString(IDS_ERR_NOTAFILELINK); - if ((uint64)iSize > MAX_EMULE_FILE_SIZE) - throw GetResString(IDS_ERR_TOOLARGEFILE); - if ((uint64)iSize > OLD_MAX_EMULE_FILE_SIZE && !thePrefs.CanFSHandleLargeFiles(0)) - throw GetResString(IDS_ERR_FSCANTHANDLEFILE); - if (!strmd4(pszHash, m_hash)) - throw GetResString(IDS_ERR_ILLFORMEDHASH); + uid = IDS_ERR_NOTAFILELINK; + else if (_tcslen(pszHash) != 32) + uid = IDS_ERR_ILLFORMEDHASH; + else { + const sint64 iSize = _tstoi64(pszSize); + if (iSize <= 0) + uid = IDS_ERR_NOTAFILELINK; + else if ((uint64)iSize > MAX_EMULE_FILE_SIZE) + uid = IDS_ERR_TOOLARGEFILE; + else if ((uint64)iSize > OLD_MAX_EMULE_FILE_SIZE && !thePrefs.CanFSHandleLargeFiles(0)) + uid = IDS_ERR_FSCANTHANDLEFILE; + else if (!strmd4(pszHash, m_hash)) + uid = IDS_ERR_ILLFORMEDHASH; + } + if (uid) + throw GetResString(uid); bool bError = false; for (int i = 0; !bError && i < astrParams.GetCount(); ++i) { @@ -222,14 +206,11 @@ CED2KFileLink::CED2KFileLink(LPCTSTR pszName, LPCTSTR pszSize, LPCTSTR pszHash } break; case _T('h'): - { - const CString &strHash(strParam.Mid(iPos + 1)); - if (!strHash.IsEmpty()) { - if (DecodeBase32(strHash, m_AICHHash.GetRawHash(), CAICHHash::GetHashSize()) == CAICHHash::GetHashSize()) { - m_bAICHHashValid = true; - ASSERT(m_AICHHash.GetString().CompareNoCase(strHash) == 0); - break; - } + if (strParam[iPos + 1]) { //not empty + if (DecodeBase32(CPTR(strParam, iPos + 1), m_AICHHash.GetRawHash(), CAICHHash::GetHashSize()) == CAICHHash::GetHashSize()) { + m_bAICHHashValid = true; + ASSERT(m_AICHHash.GetString().CompareNoCase(CPTR(strParam, iPos + 1)) == 0); + break; } } default: @@ -242,106 +223,106 @@ CED2KFileLink::CED2KFileLink(LPCTSTR pszName, LPCTSTR pszSize, LPCTSTR pszHash m_hashset = NULL; } - if (pszSources && *pszSources) { - LPTSTR pNewString = _tcsdup(pszSources); - if (!pNewString) - throw CString(_T("No memory")); - autoFree liberator(pNewString); - LPTSTR pCh = pNewString; - - pCh = _tcsstr(pCh, _T("sources")); - if (pCh != NULL) { - pCh += 7; // point to char after "sources" - LPTSTR pEnd = pCh; - while (*pEnd) - ++pEnd; // make pEnd point to the terminating NULL - bool bAllowSources; - // if there's an expiration date... - if (*pCh == _T('@') && (pEnd - pCh) > 7) { - TCHAR date[3]; - ++pCh; // after '@' - date[2] = 0; // terminate the two character string - date[0] = *pCh++; - date[1] = *pCh++; - int nYear = (int)_tcstol(date, 0, 10); - date[0] = *pCh++; - date[1] = *pCh++; - int nMonth = (int)_tcstol(date, 0, 10); - date[0] = *pCh++; - date[1] = *pCh++; - int nDay = (int)_tcstol(date, 0, 10); - COleDateTime expirationDate(2000 + nYear, nMonth, nDay, 0, 0, 0); - bAllowSources = (expirationDate.GetStatus() == COleDateTime::DateTimeStatus::valid - && COleDateTime::GetCurrentTime() < expirationDate); - } else - bAllowSources = true; - - // increment pCh to point to the first "ip:port" and check for sources - if (bAllowSources && ++pCh < pEnd) { - //uint32 dwServerIP = 0; - is unknown here - //uint16 nServerPort = 0; - uint16 nCount = 0; - int nInvalid = 0; - SourcesList = new CSafeMemFile(256); - SourcesList->WriteUInt16(nCount); // init to 0, we'll fix this at the end. - // for each "ip:port" source string until the end - // limit to prevent overflow (uint16 due to CPartFile::AddClientSources) - while (*pCh != 0 && nCount < MAXSHORT) { - LPTSTR pIP = pCh; - // find the end of this ip:port string & start of next ip:port string. - if ((pCh = _tcschr(pCh, _T(','))) != NULL) - *pCh++ = 0; // terminate current "ip:port" and point to next "ip:port" - else - pCh = pEnd; - - LPTSTR pPort = _tcschr(pIP, _T(':')); - // if port is not present for this ip, go to the next ip. - if (pPort == NULL) { - ++nInvalid; - continue; - } - *pPort++ = 0; // terminate ip string and point pPort to port string. - unsigned long uPort = _tcstoul(pPort, 0, 10); - // skip bad ips / ports - if (!uPort || uPort > _UI16_MAX) { - ++nInvalid; - continue; - } - CStringA sIPa(pIP); - unsigned long dwID = inet_addr(sIPa); - if (dwID == INADDR_NONE) { // hostname? - if (_tcslen(pIP) > 512) { - ++nInvalid; - continue; - } - SUnresolvedHostname *hostname = new SUnresolvedHostname; - hostname->strHostname = sIPa; - hostname->nPort = static_cast(uPort); - m_HostnameSourcesList.AddTail(hostname); - continue; - } - //TODO: This will filter out *.*.*.0 clients. Is there a nice way to fix? - if (::IsLowID(dwID)) { // ip - ++nInvalid; - continue; - } + if (!pszSources || !*pszSources) + return; + LPCTSTR pCh = pszSources; + pCh = _tcsstr(pCh, _T("sources")); + if (pCh == NULL) + return; + pCh += 7; // point to char after "sources" + LPCTSTR pEnd = pCh; // make a pointer to the terminating NUL + while (*pEnd) + ++pEnd; + + // if there's an expiration date... + if (*pCh == _T('@')) { + if (pEnd - pCh <= 7) + return; + TCHAR date[3]; + date[2] = 0; // terminate the string + + struct tm tmexp = {}; + date[0] = *++pCh; + date[1] = *++pCh; + tmexp.tm_year = (int)_tcstol(date, NULL, 10) + (2000 - 1900); //since 1900 + date[0] = *++pCh; + date[1] = *++pCh; + tmexp.tm_mon = (int)_tcstol(date, NULL, 10) - 1; + date[0] = *++pCh; + date[1] = *++pCh; + tmexp.tm_mday = (int)_tcstol(date, NULL, 10); + time_t tExpire = mktime(&tmexp); + //no time zone information, assume UTC + if (tExpire == (time_t)-1 || tExpire <= time(NULL)) + return; + ++pCh; + } - SourcesList->WriteUInt32(dwID); - SourcesList->WriteUInt16(static_cast(uPort)); - SourcesList->WriteUInt32(0); // dwServerIP - SourcesList->WriteUInt16(0); // nServerPort - ++nCount; - } - if (nCount) { - SourcesList->SeekToBegin(); - SourcesList->WriteUInt16(nCount); - SourcesList->SeekToBegin(); - } else { - delete SourcesList; - SourcesList = NULL; - } + if (++pCh >= pEnd) //make pCh to point to the first "ip:port" and check for sources + return; + //uint32 dwServerIP = 0; - unknown here + //uint16 nServerPort = 0; + int nInvalid = 0; + SourcesList = new CSafeMemFile(256); + uint16 nCount = 0; + SourcesList->WriteUInt16(nCount); // init to 0, we'll fix this at the end. + // for each "ip:port" source string until the end + // limit to prevent overflow (uint16 due to CPartFile::AddClientSources) + while (*pCh != 0 && nCount < MAXSHORT) { + LPCTSTR pIP = pCh; + LPCTSTR pNext; + // find the end of this ip:port string & start of next ip:port string. + if ((pCh = _tcschr(pCh, _T(','))) != NULL) + pNext = pCh++; // ends the current "ip:port" and point to next "ip:port" + else + pNext = pCh = pEnd; + + LPCTSTR pPort = _tcschr(pIP, _T(':')); + // if port is not present for this ip, skip to the next ip + if (pPort == NULL || pPort >= pNext) { + ++nInvalid; + continue; + } + CStringA sIPa(pIP, static_cast(pPort - pIP)); + ++pPort; // move to port string + unsigned long uPort = _tcstoul(pPort, NULL, 10); + // skip bad ips and ports + if (!uPort || uPort > _UI16_MAX) { + ++nInvalid; + continue; + } + unsigned long dwID = inet_addr(sIPa); + if (dwID == INADDR_NONE) { // host name? + if (_tcslen(pIP) > 512) { + ++nInvalid; + continue; } + SUnresolvedHostname *hostname = new SUnresolvedHostname; + hostname->strHostname = sIPa; + hostname->nPort = static_cast(uPort); + m_HostnameSourcesList.AddTail(hostname); + continue; + } + //TODO: This will filter out *.*.*.0 clients. Is there a nice way to fix? + if (::IsLowID(dwID)) { // ip + ++nInvalid; + continue; } + + SourcesList->WriteUInt32(dwID); + SourcesList->WriteUInt16(static_cast(uPort)); + SourcesList->WriteUInt32(0); // dwServerIP + SourcesList->WriteUInt16(0); // nServerPort + ++nCount; + } + + if (nCount) { + SourcesList->SeekToBegin(); + SourcesList->WriteUInt16(nCount); + SourcesList->SeekToBegin(); + } else { + delete SourcesList; + SourcesList = NULL; } } diff --git a/srchybrid/ED2kLinkDlg.cpp b/srchybrid/ED2kLinkDlg.cpp index 76968fc5..85992355 100644 --- a/srchybrid/ED2kLinkDlg.cpp +++ b/srchybrid/ED2kLinkDlg.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/ED2kLinkDlg.h b/srchybrid/ED2kLinkDlg.h index aa2fabbe..5ba41dd8 100644 --- a/srchybrid/ED2kLinkDlg.h +++ b/srchybrid/ED2kLinkDlg.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -34,7 +34,6 @@ class CED2kLinkDlg : public CResizablePage CString m_strLinks; public: CED2kLinkDlg(); - virtual ~CED2kLinkDlg() = default; virtual BOOL OnInitDialog(); void SetFiles(const CSimpleArray *paFiles) { m_paFiles = paFiles; m_bDataChanged = true; } diff --git a/srchybrid/EMSocket.cpp b/srchybrid/EMSocket.cpp index 48a1828f..152e71e1 100644 --- a/srchybrid/EMSocket.cpp +++ b/srchybrid/EMSocket.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -53,23 +53,22 @@ namespace _strdate(osDate); int len = _snprintf(temp, 1021, "%s %s: %s\r\n", osDate, osTime, bufferline); if (len > 0) { - HANDLE hFile = ::CreateFile("c:\\EMSocket.log", // open MYFILE.TXT - GENERIC_WRITE, // open for reading - FILE_SHARE_READ, // share for reading - NULL, // no security - OPEN_ALWAYS, // existing file only - FILE_ATTRIBUTE_NORMAL, // normal file - NULL); // no attr. template + HANDLE hFile = ::CreateFile(_T("c:\\EMSocket.log") // open MYFILE.TXT + , GENERIC_WRITE // open for reading + , FILE_SHARE_READ // share for reading + , NULL // no security + , OPEN_ALWAYS // existing file only + , FILE_ATTRIBUTE_NORMAL // normal file + , NULL); // no attr. template if (hFile != INVALID_HANDLE_VALUE) { DWORD nbBytesWritten = 0; SetFilePointer(hFile, 0, NULL, FILE_END); - BOOL b = ::WriteFile( - hFile, // handle to file - temp, // data buffer - len, // number of bytes to write - &nbBytesWritten, // number of bytes written - NULL // overlapped buffer + BOOL b = ::WriteFile(hFile // handle to file + , temp // data buffer + , len // number of bytes to write + , &nbBytesWritten // number of bytes written + , NULL // overlapped buffer ); ::CloseHandle(hFile); } @@ -112,11 +111,11 @@ CEMSocket::CEMSocket() , m_bBusy() , m_hasSent() , m_bUseBigSendBuffers() + , m_bUseOverlappedSend(true) , m_bPendingSendOv() { lastCalledSend = timeGetTime(); lastSent = lastCalledSend > SEC2MS(1) ? lastCalledSend - SEC2MS(1) : 0; - m_bUseOverlappedSend = true; } CEMSocket::~CEMSocket() @@ -312,7 +311,7 @@ void CEMSocket::OnReceive(int nErrorCode) return; } - char *rptr = GlobalReadBuffer; // floating index initialized with begin of buffer + char *rptr = GlobalReadBuffer; // floating index initialized with the buffer base const char *rend = GlobalReadBuffer + ret; // end of buffer // Loop, processing packets until we run out of them while (rend >= rptr + PACKET_HEADER_SIZE || (pendingPacket != NULL && rend > rptr)) { @@ -321,7 +320,7 @@ void CEMSocket::OnReceive(int nErrorCode) // 1. There is no pending incoming packet // 2. There is already a partial pending incoming packet // - // It's important to remember that emule exchanges two kinds of packet + // It's important to remember that emule exchanges two kinds of packets // - The control packet // - The data packet for the transport of the block // @@ -330,39 +329,34 @@ void CEMSocket::OnReceive(int nErrorCode) // maximum size for one packet on the network is 1300 bytes. // It's the reason why most of the blocks were split before being sent. // - // Conclusion: When the download limit is disabled, this method can be called - // at least 8 times (10240/1300) by the lower layer before the split packet was - // rebuild and transferred to the above layer for processing. + // Conclusion: When the download limit is disabled, this method may be called + // 8 times (10240/1300) by the lower layer before the split packet was + // rebuilt and transferred to the above layer for processing. // // The purpose of this algorithm is to limit the amount of data exchanged between buffers if (pendingPacket == NULL) { - pendingPacket = new Packet(rptr); // Create new packet container. - rptr += PACKET_HEADER_SIZE; // Only the header is initialized so far - // Bugfix We still need to check for a valid protocol // Remark: the default eMule v0.26b had removed this test...... - switch (pendingPacket->prot) { + switch (reinterpret_cast(rptr)->eDonkeyID) { case OP_EDONKEYPROT: case OP_PACKEDPROT: case OP_EMULEPROT: - // Security: Check for buffer overflow (2MB) - if (pendingPacket->size > sizeof GlobalReadBuffer) { - delete pendingPacket; - pendingPacket = NULL; - OnError(ERR_TOOBIG); - return; - } break; default: EMTrace("CEMSocket::OnReceive ERROR Wrong header"); - delete pendingPacket; - pendingPacket = NULL; OnError(ERR_WRONGHEADER); return; } + // Security: Check for buffer overflow (2MB) + if (reinterpret_cast(rptr)->packetlength - 1 > sizeof GlobalReadBuffer) { + OnError(ERR_TOOBIG); + return; + } // Init data buffer + pendingPacket = new Packet(rptr); // Create new packet container. + rptr += PACKET_HEADER_SIZE; // Only the header is initialized so far pendingPacket->pBuffer = new char[pendingPacket->size + 1]; pendingPacketSize = 0; } @@ -383,7 +377,6 @@ void CEMSocket::OnReceive(int nErrorCode) EMTrace("CEMSocket::PacketReceived on %d, opcode=%X, realSize=%d", (SOCKET)this, pendingPacket->opcode, pendingPacket->GetRealPacketSize()); #endif - // Process packet bool bPacketResult = PacketReceived(pendingPacket); delete pendingPacket; @@ -461,7 +454,7 @@ void CEMSocket::SendPacket(Packet *packet, bool controlpacket, uint32 actualPayl theApp.uploadBandwidthThrottler->QueueForSendingControlPacket(this, m_hasSent); } else { bool first = !((sendbuffer && !m_currentPacket_is_controlpacket) || !standardpacket_queue.IsEmpty()); - standardpacket_queue.AddTail(StandardPacketQueueEntry{packet, actualPayloadSize}); + standardpacket_queue.AddTail(StandardPacketQueueEntry{ packet, actualPayloadSize }); // reset timeout for the first time if (first) { @@ -479,52 +472,22 @@ void CEMSocket::SendPacket(Packet *packet, bool controlpacket, uint32 actualPayl uint64 CEMSocket::GetSentBytesCompleteFileSinceLastCallAndReset() { - sendLocker.Lock(); - - uint64 sentBytes = m_numberOfSentBytesCompleteFile; - m_numberOfSentBytesCompleteFile = 0; - - sendLocker.Unlock(); - - return sentBytes; + return (uint64)::InterlockedExchange64((LONG64*)&m_numberOfSentBytesCompleteFile, 0); } uint64 CEMSocket::GetSentBytesPartFileSinceLastCallAndReset() { - sendLocker.Lock(); - - uint64 sentBytes = m_numberOfSentBytesPartFile; - m_numberOfSentBytesPartFile = 0; - - sendLocker.Unlock(); - - return sentBytes; + return (uint64)::InterlockedExchange64((LONG64*)&m_numberOfSentBytesPartFile, 0); } uint64 CEMSocket::GetSentBytesControlPacketSinceLastCallAndReset() { - sendLocker.Lock(); - - uint64 sentBytes = m_numberOfSentBytesControlPacket; - m_numberOfSentBytesControlPacket = 0; - - sendLocker.Unlock(); - - return sentBytes; + return (uint64)::InterlockedExchange64((LONG64*)&m_numberOfSentBytesControlPacket, 0); } -uint64 CEMSocket::GetSentPayloadSinceLastCall(bool bReset) +uint32 CEMSocket::GetSentPayloadSinceLastCall(bool bReset) { - if (!bReset) - return m_actualPayloadSizeSent; - sendLocker.Lock(); - - uint64 sentBytes = m_actualPayloadSizeSent; - m_actualPayloadSizeSent = 0; - - sendLocker.Unlock(); - - return sentBytes; + return bReset ? (uint32)::InterlockedExchange((LONG*)&m_actualPayloadSizeSent, 0) : m_actualPayloadSizeSent; } void CEMSocket::OnSend(int nErrorCode) @@ -590,9 +553,7 @@ SocketSentBytes CEMSocket::Send(uint32 maxNumberOfBytesToSend, uint32 minFragSiz SocketSentBytes CEMSocket::SendStd(uint32 maxNumberOfBytesToSend, uint32 minFragSize, bool onlyAllowedToSendControlPacket) { //EMTrace("CEMSocket::Send controlcount %i, standardcount %i, isbusy: %i", controlpacket_queue.GetCount(), standardpacket_queue.GetCount(), IsBusy()); - bool anErrorHasOccured = false; - uint32 sentStandardPacketBytesThisCall = 0; - uint32 sentControlPacketBytesThisCall = 0; + SocketSentBytes ret = { 0, 0, true }; sendLocker.Lock(); if (byConnected == ES_CONNECTED && IsEncryptionLayerReady()) { @@ -604,16 +565,18 @@ SocketSentBytes CEMSocket::SendStd(uint32 maxNumberOfBytesToSend, uint32 minFrag lastCalledSend = timeGetTime(); bool bWasLongTimeSinceSend = (lastCalledSend >= lastSent + SEC2MS(1)); - while (sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall < maxNumberOfBytesToSend && !anErrorHasOccured // don't send more than allowed. Also, there should have been no error in earlier loop - && (sendbuffer != NULL || !controlpacket_queue.IsEmpty() || !standardpacket_queue.IsEmpty()) // there must exist something to send - && ( !onlyAllowedToSendControlPacket // this means we are allowed to send both types of packets, so proceed + uint32 sentBytes = ret.sentBytesStandardPackets + ret.sentBytesControlPackets; + while (sentBytes < maxNumberOfBytesToSend // don't send more than allowed + && ret.success // there should have been no error in earlier loop + && (sendbuffer != NULL || !controlpacket_queue.IsEmpty() || (!standardpacket_queue.IsEmpty() && !onlyAllowedToSendControlPacket)) // there must exist something to send + && ( !onlyAllowedToSendControlPacket // this means we are allowed to send both types of packets, so proceed || (sendbuffer != NULL && m_currentPacket_is_controlpacket) // We are in the process of sending a control packet. We are always allowed to send those - || (sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall > 0 && (sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall) % minFragSize != 0) // Once we've started, continue to send until an even minFragsize to minimize packet overhead + || (sentBytes > 0 && sentBytes % minFragSize != 0) // Once we've started, continue to send until an even minFragsize to minimize packet overhead || (sendbuffer == NULL && !controlpacket_queue.IsEmpty()) // There's a control packet in queue, and we are not currently sending anything, so we will handle the control packet next - || (sendbuffer != NULL && !m_currentPacket_is_controlpacket && bWasLongTimeSinceSend && !controlpacket_queue.IsEmpty() && (sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall) < minFragSize) // We have waited to long to clean the current packet (which may be a standard packet that is in the way). Proceed no matter what the value of onlyAllowedToSendControlPacket. - ) + || (sendbuffer != NULL && !m_currentPacket_is_controlpacket && bWasLongTimeSinceSend && !controlpacket_queue.IsEmpty() && sentBytes < minFragSize) // We have waited too long to clean the current packet (which may be a standard packet that is in the way). Proceed no matter what the value of onlyAllowedToSendControlPacket. + ) ) - { // If we are currently not in the progress of sending a packet, we will need to find the next one to send + { // If we are not sending a packet currently, we will need to find one to send if (sendbuffer == NULL) { Packet *curPacket = NULL; m_currentPacket_is_controlpacket = !controlpacket_queue.IsEmpty(); @@ -629,7 +592,7 @@ SocketSentBytes CEMSocket::SendStd(uint32 maxNumberOfBytesToSend, uint32 minFrag ASSERT(0); theApp.QueueDebugLogLine(true, _T("EMSocket: Couldn't get a new packet! There's an error in the first while condition in EMSocket::Send()")); - return SocketSentBytes{sentStandardPacketBytesThisCall, sentControlPacketBytesThisCall, true}; + return ret; } // There's a standard packet to send StandardPacketQueueEntry queueEntry = standardpacket_queue.RemoveHead(); @@ -655,26 +618,25 @@ SocketSentBytes CEMSocket::SendStd(uint32 maxNumberOfBytesToSend, uint32 minFrag // is sent, or until we reach maximum bytes to send for this call, or until we get an error. // NOTE! If send would block (returns WSAEWOULDBLOCK), we will return from this method INSIDE this loop. while (sent < sendblen - && sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall < maxNumberOfBytesToSend - && ( - !onlyAllowedToSendControlPacket // this means we are allowed to send both types of packets, so proceed + && sentBytes < maxNumberOfBytesToSend + && ( !onlyAllowedToSendControlPacket // this means we are allowed to send both types of packets, so proceed || m_currentPacket_is_controlpacket - || (bWasLongTimeSinceSend && sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall < minFragSize) - || (sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall) % minFragSize != 0 - ) - && !anErrorHasOccured) + || (bWasLongTimeSinceSend && sentBytes < minFragSize) + || sentBytes % minFragSize != 0 + ) + && ret.success) { uint32 tosend = sendblen - sent; if (!onlyAllowedToSendControlPacket || m_currentPacket_is_controlpacket) { - if (tosend > maxNumberOfBytesToSend - (sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall)) - tosend = maxNumberOfBytesToSend - (sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall); - } else if (bWasLongTimeSinceSend && minFragSize > sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall) { - if (tosend > minFragSize - (sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall)) - tosend = minFragSize - (sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall); + if (tosend > maxNumberOfBytesToSend - sentBytes) + tosend = maxNumberOfBytesToSend - sentBytes; + } else if (bWasLongTimeSinceSend && minFragSize > sentBytes) { + if (tosend > minFragSize - sentBytes) + tosend = minFragSize - sentBytes; } else { - uint32 nextFragMaxBytesToSent = GetNextFragSize(sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall, minFragSize); - if (nextFragMaxBytesToSent >= sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall && tosend > nextFragMaxBytesToSent - (sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall)) - tosend = nextFragMaxBytesToSent - (sentStandardPacketBytesThisCall + sentControlPacketBytesThisCall); + uint32 nextFragMaxBytesToSent = GetNextFragSize(sentBytes, minFragSize); + if (nextFragMaxBytesToSent >= sentBytes && tosend > nextFragMaxBytesToSent - sentBytes) + tosend = nextFragMaxBytesToSent - sentBytes; } ASSERT(tosend != 0 && tosend <= sendblen - sent); @@ -690,10 +652,10 @@ SocketSentBytes CEMSocket::SendStd(uint32 maxNumberOfBytesToSend, uint32 minFrag sendLocker.Unlock(); // Send() blocked, onsend will be called when ready to send again - return SocketSentBytes{sentStandardPacketBytesThisCall, sentControlPacketBytesThisCall, true}; + return ret; } // Send() gave an error - anErrorHasOccured = true; + ret.success = false; //DEBUG_ONLY( AddDebugLogLine(true,"EMSocket: An error has occurred: %i", error) ); } else { // we managed to send some bytes. Perform bookkeeping. @@ -701,18 +663,19 @@ SocketSentBytes CEMSocket::SendStd(uint32 maxNumberOfBytesToSend, uint32 minFrag m_hasSent = true; sent += result; - + sentBytes = result; // Log send bytes in correct class if (!m_currentPacket_is_controlpacket) { - sentStandardPacketBytesThisCall += result; + ret.sentBytesStandardPackets += result; if (m_currentPackageIsFromPartFile) - m_numberOfSentBytesPartFile += result; + ::InterlockedAdd64((LONG64*)&m_numberOfSentBytesPartFile, result); else - m_numberOfSentBytesCompleteFile += result; + ::InterlockedAdd64((LONG64*)&m_numberOfSentBytesCompleteFile, result); + } else { - sentControlPacketBytesThisCall += result; - m_numberOfSentBytesControlPacket += result; + ret.sentBytesControlPackets += result; + ::InterlockedAdd64((LONG64*)&m_numberOfSentBytesControlPacket, result); } } } @@ -725,7 +688,7 @@ SocketSentBytes CEMSocket::SendStd(uint32 maxNumberOfBytesToSend, uint32 minFrag sendblen = 0; if (!m_currentPacket_is_controlpacket) { - m_actualPayloadSizeSent += m_actualPayloadSize; + ::InterlockedAdd((LONG*)&m_actualPayloadSizeSent, m_actualPayloadSize); m_actualPayloadSize = 0; lastFinishedStandard = timeGetTime(); // reset timeout @@ -747,7 +710,7 @@ SocketSentBytes CEMSocket::SendStd(uint32 maxNumberOfBytesToSend, uint32 minFrag //CleanSendLatencyList(); sendLocker.Unlock(); - return SocketSentBytes{sentStandardPacketBytesThisCall, sentControlPacketBytesThisCall, !anErrorHasOccured}; + return ret; } /** @@ -766,9 +729,7 @@ SocketSentBytes CEMSocket::SendOv(uint32 maxNumberOfBytesToSend, uint32 minFragS { //EMTrace("CEMSocket::Send controlcount %i, standardcount %i, isbusy: %i", controlpacket_queue.GetCount(), standardpacket_queue.GetCount(), IsBusy()); ASSERT(m_pProxyLayer == NULL); - bool anErrorHasOccured = false; - uint32 sentStandardPacketBytesThisCall = 0; - uint32 sentControlPacketBytesThisCall = 0; + SocketSentBytes ret = {0, 0, true}; sendLocker.Lock(); if (byConnected == ES_CONNECTED && IsEncryptionLayerReady() && !IsBusyExtensiveCheck() && maxNumberOfBytesToSend > 0) { @@ -778,12 +739,12 @@ SocketSentBytes CEMSocket::SendOv(uint32 maxNumberOfBytesToSend, uint32 minFragS maxNumberOfBytesToSend = GetNextFragSize(maxNumberOfBytesToSend, minFragSize); lastCalledSend = timeGetTime(); ASSERT(!m_bPendingSendOv && m_aBufferSend.IsEmpty()); - sint32 nBytesLeft = maxNumberOfBytesToSend; - if (sendbuffer != NULL || !controlpacket_queue.IsEmpty() || !standardpacket_queue.IsEmpty()) { + if (sendbuffer != NULL || !controlpacket_queue.IsEmpty() || (!standardpacket_queue.IsEmpty() && !onlyAllowedToSendControlPacket)) { // WSASend takes multiple buffers which is quite nice for our case, as we have to call send // only once regardless how many packets we want to ship without moving memory. // But before we can do this, collect all buffers we want to send in this call + sint32 nBytesLeft = maxNumberOfBytesToSend; // first send the existing sendbuffer (already started packet) if (sendbuffer != NULL) { WSABUF pCurBuf; @@ -798,15 +759,15 @@ SocketSentBytes CEMSocket::SendOv(uint32 maxNumberOfBytesToSend, uint32 minFragS sendbuffer = NULL; sendblen = 0; } - sentStandardPacketBytesThisCall += pCurBuf.len; // Sendbuffer is always a standard packet in this method + ret.sentBytesStandardPackets += pCurBuf.len; // Sendbuffer is always a standard packet in this method lastFinishedStandard = timeGetTime(); m_bAccelerateUpload = false; - m_actualPayloadSizeSent += m_actualPayloadSize; + ::InterlockedAdd((LONG*)&m_actualPayloadSizeSent, m_actualPayloadSize); m_actualPayloadSize = 0; if (m_currentPackageIsFromPartFile) - m_numberOfSentBytesPartFile += pCurBuf.len; + ::InterlockedAdd64((LONG64*)&m_numberOfSentBytesPartFile, pCurBuf.len); else - m_numberOfSentBytesCompleteFile += pCurBuf.len; + ::InterlockedAdd64((LONG64*)&m_numberOfSentBytesCompleteFile, pCurBuf.len); } // next send all control packets if there are any and we have bytes left @@ -817,52 +778,54 @@ SocketSentBytes CEMSocket::SendOv(uint32 maxNumberOfBytesToSend, uint32 minFragS pCurBuf.len = curPacket->GetRealPacketSize(); pCurBuf.buf = curPacket->DetachPacket(); delete curPacket; - // encrypting which cannot be done transparent by base class + // encrypting which cannot be done transparently in the base class CryptPrepareSendData((uchar*)pCurBuf.buf, pCurBuf.len); m_aBufferSend.Add(pCurBuf); nBytesLeft -= pCurBuf.len; - sentControlPacketBytesThisCall += pCurBuf.len; + ret.sentBytesControlPackets += pCurBuf.len; } // and now finally the standard packets if there are any, and we have bytes left, and we are allowed to - while (!standardpacket_queue.IsEmpty() && nBytesLeft > 0 && !onlyAllowedToSendControlPacket) { - StandardPacketQueueEntry queueEntry = standardpacket_queue.RemoveHead(); - WSABUF pCurBuf; - Packet *curPacket = queueEntry.packet; - m_currentPackageIsFromPartFile = curPacket->IsFromPF(); - - // can we send it right away or only a part of it? - if (queueEntry.packet->GetRealPacketSize() <= (uint32)nBytesLeft) { - // yay - pCurBuf.len = curPacket->GetRealPacketSize(); - pCurBuf.buf = curPacket->DetachPacket(); - CryptPrepareSendData((uchar*)pCurBuf.buf, pCurBuf.len);// encrypting which cannot be done transparent by base class - m_actualPayloadSizeSent += queueEntry.actualPayloadSize; - lastFinishedStandard = timeGetTime(); - m_bAccelerateUpload = false; - } else { // aww, well first stuff everything into the sendbuffer and then send what we can of it - ASSERT(sendbuffer == NULL); - m_actualPayloadSize = queueEntry.actualPayloadSize; - sendblen = curPacket->GetRealPacketSize(); - sendbuffer = curPacket->DetachPacket(); - sent = 0; - CryptPrepareSendData((uchar*)sendbuffer, sendblen); // encrypting which cannot be done transparent by base class - pCurBuf.len = min(sendblen - sent, (uint32)nBytesLeft); - pCurBuf.buf = new CHAR[pCurBuf.len]; - memcpy(pCurBuf.buf, sendbuffer, pCurBuf.len); - sent += pCurBuf.len; - ASSERT(sent < sendblen); - m_currentPacket_is_controlpacket = false; + if (!onlyAllowedToSendControlPacket) + while (!standardpacket_queue.IsEmpty() && nBytesLeft > 0) { + StandardPacketQueueEntry queueEntry = standardpacket_queue.RemoveHead(); + WSABUF pCurBuf; + Packet *curPacket = queueEntry.packet; + m_currentPackageIsFromPartFile = curPacket->IsFromPF(); + + // can we send it right away or only a part of it? + if (queueEntry.packet->GetRealPacketSize() <= (uint32)nBytesLeft) { + // yay + pCurBuf.len = curPacket->GetRealPacketSize(); + pCurBuf.buf = curPacket->DetachPacket(); + CryptPrepareSendData((uchar*)pCurBuf.buf, pCurBuf.len);// encrypting which cannot be done transparent by base class + ::InterlockedAdd((LONG*)&m_actualPayloadSizeSent, queueEntry.actualPayloadSize); + lastFinishedStandard = timeGetTime(); + m_bAccelerateUpload = false; + } else { // aww, well first stuff everything into the sendbuffer and then send what we can of it + ASSERT(sendbuffer == NULL); + m_actualPayloadSize = queueEntry.actualPayloadSize; + sendblen = curPacket->GetRealPacketSize(); + sendbuffer = curPacket->DetachPacket(); + sent = 0; + CryptPrepareSendData((uchar*)sendbuffer, sendblen); // encrypting which cannot be done transparent by base class + pCurBuf.len = min(sendblen - sent, (uint32)nBytesLeft); + pCurBuf.buf = new CHAR[pCurBuf.len]; + memcpy(pCurBuf.buf, sendbuffer, pCurBuf.len); + sent += pCurBuf.len; + ASSERT(sent < sendblen); + m_currentPacket_is_controlpacket = false; + } + delete curPacket; + m_aBufferSend.Add(pCurBuf); + nBytesLeft -= pCurBuf.len; + ret.sentBytesStandardPackets += pCurBuf.len; + if (m_currentPackageIsFromPartFile) + ::InterlockedAdd64((LONG64*)&m_numberOfSentBytesPartFile, pCurBuf.len); + else + ::InterlockedAdd64((LONG64*)&m_numberOfSentBytesCompleteFile, pCurBuf.len); } - delete curPacket; - m_aBufferSend.Add(pCurBuf); - nBytesLeft -= pCurBuf.len; - sentStandardPacketBytesThisCall += pCurBuf.len; - if (m_currentPackageIsFromPartFile) - m_numberOfSentBytesPartFile += pCurBuf.len; - else - m_numberOfSentBytesCompleteFile += pCurBuf.len; - } + if (m_aBufferSend.GetCount() > 0) { // all right, prepare to send our collected buffers memset(&m_PendingSendOperation, 0, sizeof WSAOVERLAPPED); @@ -873,9 +836,9 @@ SocketSentBytes CEMSocket::SendOv(uint32 maxNumberOfBytesToSend, uint32 minFragS else { int nError = WSAGetLastError(); if (nError != WSA_IO_PENDING) { - anErrorHasOccured = true; + ret.success = false; theApp.QueueDebugLogLineEx(ERROR, _T("WSASend() Error: %u, %s"), nError, (LPCTSTR)GetErrorMessage(nError)); - CleanUpOverlappedSendOperation(true); + CleanUpOverlappedSendOperation(false); } } } @@ -891,12 +854,12 @@ SocketSentBytes CEMSocket::SendOv(uint32 maxNumberOfBytesToSend, uint32 minFragS } sendLocker.Unlock(); - return SocketSentBytes{sentStandardPacketBytesThisCall, sentControlPacketBytesThisCall, !anErrorHasOccured}; + return ret; } uint32 CEMSocket::GetNextFragSize(uint32 current, uint32 minFragSize) { - return (current % minFragSize == 0) ? current : minFragSize * (current / minFragSize + 1); + return (min(_I32_MAX, current + minFragSize - 1) / minFragSize) * minFragSize; } /** @@ -938,7 +901,7 @@ uint32 CEMSocket::GetNeededBytes() timeleft = timetotal - timeleft; // don't use 'GetTimeOut' here in case the timeout value is high, if (timeleft * sizetotal >= timetotal * sizeleft) { - // Don't let the socket itself to time out - Might happen when switching from spread(non-focus) slot to trickle slot + // Don't let the socket itself to time out - Might happen when switching from spread (non-focus) slot to trickle slot return static_cast(sendgap >= SEC2MS(20)); } uint64 decval = timeleft * sizetotal / timetotal; @@ -1024,9 +987,9 @@ void CEMSocket::RemoveAllLayers() m_pProxyLayer = NULL; } -int CEMSocket::OnLayerCallback(std::list &callbacks) +int CEMSocket::OnLayerCallback(std::vector &callbacks) { - for (std::list::const_iterator iter = callbacks.begin(); iter != callbacks.end(); ++iter) { + for (std::vector::const_iterator iter = callbacks.begin(); iter != callbacks.end(); ++iter) { if (iter->nType == LAYERCALLBACK_LAYERSPECIFIC) { if (iter->pLayer == m_pProxyLayer) { m_strLastProxyError = GetProxyError((int)iter->wParam); @@ -1133,11 +1096,10 @@ CString CEMSocket::GetFullErrorMessage(DWORD dwError) if (!GetLastProxyError().IsEmpty()) { strError = GetLastProxyError(); // If we had a proxy error and the socket error is WSAECONNABORTED, we just 'aborted' - // the TCP connection ourself - no need to show that self-created error too. + // the TCP connection ourself - no need to add that self-created error too. if (dwError == WSAECONNABORTED) return strError; } - // Winsock error if (dwError) { if (!strError.IsEmpty()) @@ -1196,7 +1158,8 @@ bool CEMSocket::IsBusyExtensiveCheck() return false; } -// won't always deliver the proper result (sometimes reports busy even if it isn't any more and thread related errors) but doesn't needs locks or function calls +// won't always deliver the proper result (sometimes reports busy even if it isn't any more +// and thread related errors) but doesn't need locks or function calls bool CEMSocket::IsBusyQuickCheck() const { return m_bUseOverlappedSend ? m_bPendingSendOv : m_bBusy; @@ -1208,7 +1171,7 @@ void CEMSocket::CleanUpOverlappedSendOperation(bool bCancel) if (m_bPendingSendOv) { m_bPendingSendOv = false; if (bCancel && CancelIo((HANDLE)GetSocketHandle())) - for (int i = 5; --i >= 0;) { //it could loop forever, so use sleep + for (int i = 5; --i >= 0;) { //use counter and sleep(), because this may loop forever DWORD dwTransferred, dwFlags; if (WSAGetOverlappedResult(GetSocketHandle(), &m_PendingSendOperation, &dwTransferred, FALSE, &dwFlags)) break; diff --git a/srchybrid/EMSocket.h b/srchybrid/EMSocket.h index 77143ea8..7c9f10a6 100644 --- a/srchybrid/EMSocket.h +++ b/srchybrid/EMSocket.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -75,7 +75,7 @@ class CEMSocket : public CEncryptedStreamSocket, public ThrottledFileSocket // Z uint64 GetSentBytesCompleteFileSinceLastCallAndReset(); uint64 GetSentBytesPartFileSinceLastCallAndReset(); uint64 GetSentBytesControlPacketSinceLastCallAndReset(); - uint64 GetSentPayloadSinceLastCall(bool bReset); + uint32 GetSentPayloadSinceLastCall(bool bReset); void TruncateQueues(); virtual SocketSentBytes SendControlData(uint32 maxNumberOfBytesToSend, uint32 minFragSize) { return Send(maxNumberOfBytesToSend, minFragSize, true); }; @@ -89,7 +89,7 @@ class CEMSocket : public CEncryptedStreamSocket, public ThrottledFileSocket // Z #endif protected: - virtual int OnLayerCallback(std::list &callbacks); + virtual int OnLayerCallback(std::vector &callbacks); virtual void DataReceived(const BYTE *pcData, UINT uSize); virtual bool PacketReceived(Packet *packet) = 0; diff --git a/srchybrid/EditDelayed.cpp b/srchybrid/EditDelayed.cpp index 4fa46e52..adb3383b 100644 --- a/srchybrid/EditDelayed.cpp +++ b/srchybrid/EditDelayed.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -75,12 +75,12 @@ void CEditDelayed::OnDestroy() void CEditDelayed::OnTimer(UINT_PTR nIDEvent) { - //ASSERT( nIDEvent == DELAYED_EVALUATE_TIMER_ID ); + //ASSERT(nIDEvent == DELAYED_EVALUATE_TIMER_ID); if (nIDEvent == DELAYED_EVALUATE_TIMER_ID) { - DWORD dwTick = ::GetTickCount(); - if (dwTick >= m_dwLastModified + 400) { + const DWORD curTick = ::GetTickCount(); + if (curTick >= m_dwLastModified + 400) { DoDelayedEvalute(); - m_dwLastModified = dwTick; + m_dwLastModified = curTick; } } @@ -95,7 +95,7 @@ void CEditDelayed::OnSetFocus(CWnd *pOldWnd) // Create timer ASSERT(m_uTimerResult == 0); m_uTimerResult = SetTimer(DELAYED_EVALUATE_TIMER_ID, 100, NULL); - ASSERT(m_uTimerResult != 0); + ASSERT(m_uTimerResult); ShowColumnText(false); } @@ -105,7 +105,7 @@ void CEditDelayed::OnKillFocus(CWnd *pNewWnd) { if (!m_bShuttingDown) { // Kill timer - ASSERT(m_uTimerResult != 0); + ASSERT(m_uTimerResult); VERIFY(KillTimer(DELAYED_EVALUATE_TIMER_ID)); m_uTimerResult = 0; @@ -150,13 +150,13 @@ void CEditDelayed::DoDelayedEvalute(bool bForce) return; } - // Fire 'evaluate' event only, if content really has changed. + // Fire 'evaluate' event only if content really has changed. CString strContent; GetWindowText(strContent); - if (m_strLastEvaluatedContent == strContent && !bForce) - return; - m_strLastEvaluatedContent = strContent; - GetParent()->SendMessage(UM_DELAYED_EVALUATE, (WPARAM)m_nCurrentColumnIdx, (LPARAM)(LPCTSTR)m_strLastEvaluatedContent); + if (m_strLastEvaluatedContent != strContent || bForce) { + m_strLastEvaluatedContent = strContent; + GetParent()->SendMessage(UM_DELAYED_EVALUATE, (WPARAM)m_nCurrentColumnIdx, (LPARAM)(LPCTSTR)m_strLastEvaluatedContent); + } } void CEditDelayed::OnInit(CHeaderCtrl *pColumnHeader, CArray *paIgnoredColumns) @@ -171,10 +171,7 @@ void CEditDelayed::OnInit(CHeaderCtrl *pColumnHeader, CArray *paIgnore CImageList *pImageList = new CImageList(); pImageList->Create(16, 16, theApp.m_iDfltImageListColorFlags | ILC_MASK, 0, 1); - if (pColumnHeader != NULL) - pImageList->Add(CTempIconLoader(_T("SEARCHEDIT"))); - else - pImageList->Add(CTempIconLoader(_T("KADNODESEARCH"))); + pImageList->Add(CTempIconLoader(pColumnHeader ? _T("SEARCHEDIT") : _T("KADNODESEARCH"))); m_iwColumn.SetImageList(pImageList); m_iwColumn.Create(_T(""), WS_CHILD | WS_VISIBLE, CRect(0, 0, ICON_LEFTSPACE, rectWindow.bottom), this, 1); @@ -227,13 +224,13 @@ void CEditDelayed::OnLButtonDown(UINT nFlags, CPoint point) int nIdx = m_pctrlColumnHeader->OrderToIndex(i); m_pctrlColumnHeader->GetItem(nIdx, &hdi); szBuffer[_countof(szBuffer) - 1] = _T('\0'); - bool bIgnored = false; - for (int j = 0; j < m_aIgnoredColumns.GetCount(); ++j) + bool bVisible = true; + for (INT_PTR j = m_aIgnoredColumns.GetCount(); --j >= 0;) if (m_aIgnoredColumns[j] == nIdx) { - bIgnored = true; + bVisible = false; break; } - if (hdi.cxy > 0 && !bIgnored) // ignore hidden columns + if (hdi.cxy > 0 && bVisible) // ignore hidden columns menu.AppendMenu(MF_STRING | ((m_nCurrentColumnIdx == nIdx) ? MF_CHECKED : MF_UNCHECKED), MP_FILTERCOLUMNS + nIdx, hdi.pszText); } @@ -262,7 +259,7 @@ void CEditDelayed::OnLButtonUp(UINT nFlags, CPoint point) { if (m_bShowResetButton) { m_iwReset.ShowIcon(0); - ReleaseCapture(); + ::ReleaseCapture(); RECT editRect; GetClientRect(&editRect); @@ -315,7 +312,7 @@ void CEditDelayed::ShowColumnText(bool bShow) hdi.cchTextMax = _countof(szBuffer); if (m_pctrlColumnHeader->GetItem(m_nCurrentColumnIdx, &hdi)) { szBuffer[_countof(szBuffer) - 1] = _T('\0'); - SetWindowText(hdi.pszText); + SetWindowText(szBuffer); } } else SetWindowText(m_strAlternateText); @@ -327,7 +324,7 @@ void CEditDelayed::ShowColumnText(bool bShow) HBRUSH CEditDelayed::CtlColor(CDC *pDC, UINT) { - // Use gray text color when showing the column text so it doesn't gets confused with typed in text + // Use gray text color when showing the column text so it doesn't get confused with typed in text HBRUSH hbr = ::GetSysColorBrush(COLOR_WINDOW); pDC->SetTextColor(::GetSysColor(m_bShowsColumnText ? COLOR_GRAYTEXT : COLOR_WINDOWTEXT)); pDC->SetBkColor(::GetSysColor(COLOR_WINDOW)); @@ -365,9 +362,9 @@ BEGIN_MESSAGE_MAP(CIconWnd, CStatic) END_MESSAGE_MAP() CIconWnd::CIconWnd() + : m_pImageList() + , m_nCurrentIcon() { - m_pImageList = NULL; - m_nCurrentIcon = 0; } CIconWnd::~CIconWnd() @@ -377,9 +374,9 @@ CIconWnd::~CIconWnd() void CIconWnd::OnPaint() { - CPaintDC dc(this); RECT rect; GetClientRect(&rect); + CPaintDC dc(this); dc.FillSolidRect(&rect, ::GetSysColor(COLOR_WINDOW)); m_pImageList->Draw(&dc, m_nCurrentIcon, POINT{ 2, (rect.bottom - 16) / 2 }, ILD_NORMAL); } @@ -391,9 +388,9 @@ BOOL CIconWnd::OnEraseBkgnd(CDC*) void CIconWnd::ShowIcon(int nIconNumber) { - if (nIconNumber == m_nCurrentIcon) - return; - m_nCurrentIcon = nIconNumber; - Invalidate(); - UpdateWindow(); + if (nIconNumber != m_nCurrentIcon) { + m_nCurrentIcon = nIconNumber; + Invalidate(); + UpdateWindow(); + } } \ No newline at end of file diff --git a/srchybrid/EditDelayed.h b/srchybrid/EditDelayed.h index 8720f9a8..5cdcce43 100644 --- a/srchybrid/EditDelayed.h +++ b/srchybrid/EditDelayed.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -30,8 +30,8 @@ class CIconWnd : public CStatic void ShowIcon(int nIconNumber); protected: - int m_nCurrentIcon; CImageList *m_pImageList; + int m_nCurrentIcon; DECLARE_MESSAGE_MAP() afx_msg void OnPaint(); diff --git a/srchybrid/EditX.cpp b/srchybrid/EditX.cpp index eb138bbc..954eb17c 100644 --- a/srchybrid/EditX.cpp +++ b/srchybrid/EditX.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/Emule.cpp b/srchybrid/Emule.cpp index 2da2ca1e..7581e794 100644 --- a/srchybrid/Emule.cpp +++ b/srchybrid/Emule.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -40,10 +40,10 @@ #include "ClientList.h" #include "FriendList.h" #include "ClientUDPSocket.h" +#include "UpDownClient.h" #include "DownloadQueue.h" #include "IPFilter.h" #include "Statistics.h" -#include "OtherFunctions.h" #include "WebServer.h" #include "UploadQueue.h" #include "SharedFileList.h" @@ -53,7 +53,6 @@ #include "ClientCredits.h" #include "KnownFileList.h" #include "Server.h" -#include "UpDownClient.h" #include "ED2KLink.h" #include "Preferences.h" #include "secrunasuser.h" @@ -71,6 +70,7 @@ #include "UPnPImplWrapper.h" #include "VisualStylesXP.h" #include "UploadDiskIOThread.h" +#include "PartFileWriteThread.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -94,7 +94,6 @@ static char THIS_FILE[] = __FILE__; CLogFile theLog; CLogFile theVerboseLog; bool g_bLowColorDesktop = false; -bool g_bGdiPlusInstalled = false; //#define USE_16COLOR_ICONS @@ -108,8 +107,7 @@ _CRT_ALLOC_HOOK g_pfnPrevCrtAllocHook = NULL; CMap g_allocations; int eMuleAllocHook(int mode, void *pUserData, size_t nSize, int nBlockUse, long lRequest, const unsigned char *pszFileName, int nLine) noexcept; -//CString _strCrtDebugReportFilePath(_T("eMule CRT Debug Log.log")); -// don't use a CString for that memory - it will not be available on application termination! +// Cannot use a CString for that memory - it will be unavailable on application termination! #define APP_CRT_DEBUG_LOG_FILE _T("eMule CRT Debug Log.log") static TCHAR s_szCrtDebugReportFilePath[MAX_PATH] = APP_CRT_DEBUG_LOG_FILE; #endif //_DEBUG @@ -216,7 +214,7 @@ void InitDEP() // not reach this code path at all because the "/NXCOMPAT" option is specified. // However, the code path is here for safety reasons. dwFlags = PROCESS_DEP_ENABLE; - // VS2005: Disable ATL-thunks. + // VS2005: Disable ATL thunks. dwFlags |= PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION; (*pfnSetProcessDEPPolicy)(dwFlags); } @@ -228,7 +226,7 @@ void InitDEP() /////////////////////////////////////////////////////////////////////////////// // Heap Corruption Detection // -// For Windows Vista and later. Does *not* have any performance impact! +// For Windows XP SP3 and later. Does *not* have any performance impact! // #ifndef HeapEnableTerminationOnCorruption #define HeapEnableTerminationOnCorruption (HEAP_INFORMATION_CLASS)1 @@ -307,13 +305,6 @@ CemuleApp::CemuleApp(LPCTSTR lpszAppName) srand((unsigned)time(NULL)); - // NOTE: Do *NOT* forget to specify /DELAYLOAD:gdiplus.dll as link parameter. - HMODULE hLib = LoadLibrary(_T("gdiplus.dll")); - if (hLib != NULL) { - g_bGdiPlusInstalled = GetProcAddress(hLib, "GdiplusStartup") != NULL; - FreeLibrary(hLib); - } - // MOD Note: Do not change this part - Merkur // this is the "base" version number ... @@ -430,7 +421,8 @@ BOOL CemuleApp::InitInstance() _CrtSetReportMode(_CRT_ASSERT, _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_REPORT_MODE) | _CRTDBG_MODE_DEBUG); #endif free((void*)m_pszProfileName); - m_pszProfileName = _tcsdup(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + _T("preferences.ini")); + const CString &sConfDir(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); + m_pszProfileName = _tcsdup(sConfDir + _T("preferences.ini")); #ifdef _DEBUG oldMemState.Checkpoint(); @@ -448,7 +440,7 @@ BOOL CemuleApp::InitInstance() #if !defined(_BETA) && !defined(_DEVBUILD) if (theCrashDumper.uCreateCrashDump > 0) #endif - theCrashDumper.Enable(_T("eMule ") + m_strCurVersionLongDbg, true, thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); + theCrashDumper.Enable(_T("eMule ") + m_strCurVersionLongDbg, true, sConfDir); /////////////////////////////////////////////////////////////////////////// // Locale initialization -- BE VERY CAREFUL HERE!!! @@ -481,7 +473,7 @@ BOOL CemuleApp::InitInstance() case _WINVER_2003_: m_ullComCtrlVer = MAKEDLLVERULL(6, 0, 0, 0); break; - default: //Vista .. Win10 + default: //Vista .. Win11 m_ullComCtrlVer = MAKEDLLVERULL(6, 16, 0, 0); }; @@ -630,6 +622,7 @@ BOOL CemuleApp::InitInstance() // ZZ:UploadSpeedSense <-- m_pUploadDiskIOThread = new CUploadDiskIOThread(); + m_pPartFileWriteThread = new CPartFileWriteThread(); thePerfLog.Startup(); emuledlg->DoModal(); @@ -695,11 +688,11 @@ int eMuleAllocHook(int mode, void *pUserData, size_t nSize, int nBlockUse, long count = 0; if (mode == _HOOK_ALLOC) { _CrtSetAllocHook(g_pfnPrevCrtAllocHook); - g_allocations.SetAt(pszFileName, count + 1); + g_allocations[pszFileName] = count + 1; _CrtSetAllocHook(&eMuleAllocHook); } else if (mode == _HOOK_FREE) { _CrtSetAllocHook(g_pfnPrevCrtAllocHook); - g_allocations.SetAt(pszFileName, count - 1); + g_allocations[pszFileName] = count - 1; _CrtSetAllocHook(&eMuleAllocHook); } return g_pfnPrevCrtAllocHook(mode, pUserData, nSize, nBlockUse, lRequest, pszFileName, nLine); @@ -717,11 +710,9 @@ bool CemuleApp::ProcessCommandline() if (_tcsicmp(pszParam, _T("assertfile")) == 0) _CrtSetReportHook(CrtDebugReportCB); #endif - if (_tcsicmp(pszParam, _T("ignoreinstances")) == 0) - bIgnoreRunningInstances = true; + bIgnoreRunningInstances |= (_tcsicmp(pszParam, _T("ignoreinstances")) == 0); - if (_tcsicmp(pszParam, _T("AutoStart")) == 0) - m_bAutoStart = true; + m_bAutoStart |= (_tcsicmp(pszParam, _T("AutoStart")) == 0); } } @@ -729,17 +720,16 @@ bool CemuleApp::ProcessCommandline() ParseCommandLine(cmdInfo); // If we create our TCP listen socket with SO_REUSEADDR, we have to ensure that there are - // not 2 emules are running using the same port. + // no 2 eMules are running on the same port. // NOTE: This will not prevent from some other application using that port! UINT uTcpPort = GetProfileInt(_T("eMule"), _T("Port"), DEFAULT_TCP_PORT_OLD); CString strMutextName; strMutextName.Format(_T("%s:%u"), EMULE_GUID, uTcpPort); m_hMutexOneInstance = CreateMutex(NULL, FALSE, strMutextName); - HWND maininst = NULL; const CString &command(cmdInfo.m_strFileName); - //this codepart is to determine special cases when we do add a link to our eMule + //this code part is to determine special cases when we do add a link to our eMule //because in this case it would be nonsense to start another instance! bool bAlreadyRunning = false; if (bIgnoreRunningInstances @@ -748,6 +738,7 @@ bool CemuleApp::ProcessCommandline() { bIgnoreRunningInstances = false; } + HWND maininst = NULL; if (!bIgnoreRunningInstances) switch (::GetLastError()) { case ERROR_ALREADY_EXISTS: @@ -758,7 +749,7 @@ bool CemuleApp::ProcessCommandline() if (cmdInfo.m_nShellCommand == CCommandLineInfo::FileOpen) { if (command.Find(_T("://")) > 0 || command.Find(_T("magnet:?")) >= 0) { - sendstruct.cbData = (command.GetLength() + 1) * sizeof(TCHAR); + sendstruct.cbData = static_cast((command.GetLength() + 1) * sizeof(TCHAR)); sendstruct.dwData = OP_ED2KLINK; sendstruct.lpData = const_cast((LPCTSTR)command); if (maininst) { @@ -768,7 +759,7 @@ bool CemuleApp::ProcessCommandline() m_strPendingLink = command; } else if (CCollection::HasCollectionExtention(command)) { - sendstruct.cbData = (command.GetLength() + 1) * sizeof(TCHAR); + sendstruct.cbData = static_cast((command.GetLength() + 1) * sizeof(TCHAR)); sendstruct.dwData = OP_COLLECTION; sendstruct.lpData = const_cast((LPCTSTR)command); if (maininst) { @@ -778,7 +769,7 @@ bool CemuleApp::ProcessCommandline() m_strPendingLink = command; } else { - sendstruct.cbData = (command.GetLength() + 1) * sizeof(TCHAR); + sendstruct.cbData = static_cast((command.GetLength() + 1) * sizeof(TCHAR)); sendstruct.dwData = OP_CLCOMMAND; sendstruct.lpData = const_cast((LPCTSTR)command); if (maininst) { @@ -831,7 +822,7 @@ CString CemuleApp::CreateKadSourceLink(const CAbstractFile *f) CString strLink; if (Kademlia::CKademlia::IsConnected() && theApp.clientlist->GetBuddy() && theApp.IsFirewalled()) { CString KadID; - Kademlia::CKademlia::GetPrefs()->GetKadID().Xor(Kademlia::CUInt128(true)).ToHexString(&KadID); + Kademlia::CKademlia::GetPrefs()->GetKadID().Xor(Kademlia::CUInt128(true)).ToHexString(KadID); strLink.Format(_T("ed2k://|file|%s|%I64u|%s|/|kadsources,%s:%s|/") , (LPCTSTR)EncodeUrlUtf8(StripInvalidFilenameChars(f->GetFileName())) , (uint64)f->GetFileSize() @@ -847,27 +838,27 @@ bool CemuleApp::CopyTextToClipboard(const CString &strText) if (strText.IsEmpty()) return false; - HGLOBAL hGlobalT = GlobalAlloc(GHND | GMEM_SHARE, (strText.GetLength() + 1) * sizeof(TCHAR)); + HGLOBAL hGlobalT = ::GlobalAlloc(GHND | GMEM_SHARE, (strText.GetLength() + 1) * sizeof(TCHAR)); if (hGlobalT != NULL) { - LPTSTR pGlobalT = static_cast(GlobalLock(hGlobalT)); + LPTSTR pGlobalT = static_cast(::GlobalLock(hGlobalT)); if (pGlobalT != NULL) { _tcscpy(pGlobalT, strText); - GlobalUnlock(hGlobalT); + ::GlobalUnlock(hGlobalT); } else { - GlobalFree(hGlobalT); + ::GlobalFree(hGlobalT); hGlobalT = NULL; } } CStringA strTextA(strText); - HGLOBAL hGlobalA = GlobalAlloc(GHND | GMEM_SHARE, (strTextA.GetLength() + 1) * sizeof(char)); + HGLOBAL hGlobalA = ::GlobalAlloc(GHND | GMEM_SHARE, (strTextA.GetLength() + 1) * sizeof(char)); if (hGlobalA != NULL) { - LPSTR pGlobalA = static_cast(GlobalLock(hGlobalA)); + LPSTR pGlobalA = static_cast(::GlobalLock(hGlobalA)); if (pGlobalA != NULL) { strcpy(pGlobalA, strTextA); - GlobalUnlock(hGlobalA); + ::GlobalUnlock(hGlobalA); } else { - GlobalFree(hGlobalA); + ::GlobalFree(hGlobalA); hGlobalA = NULL; } } @@ -882,7 +873,7 @@ bool CemuleApp::CopyTextToClipboard(const CString &strText) if (SetClipboardData(CF_UNICODETEXT, hGlobalT) != NULL) ++iCopied; else { - GlobalFree(hGlobalT); + ::GlobalFree(hGlobalT); hGlobalT = NULL; } } @@ -890,7 +881,7 @@ bool CemuleApp::CopyTextToClipboard(const CString &strText) if (SetClipboardData(CF_TEXT, hGlobalA) != NULL) ++iCopied; else { - GlobalFree(hGlobalA); + ::GlobalFree(hGlobalA); hGlobalA = NULL; } } @@ -900,9 +891,9 @@ bool CemuleApp::CopyTextToClipboard(const CString &strText) if (iCopied == 0) { if (hGlobalT) - GlobalFree(hGlobalT); + ::GlobalFree(hGlobalT); if (hGlobalA) - GlobalFree(hGlobalA); + ::GlobalFree(hGlobalA); return false; } @@ -913,40 +904,32 @@ bool CemuleApp::CopyTextToClipboard(const CString &strText) //TODO: Move to emule-window CString CemuleApp::CopyTextFromClipboard() { - if (IsClipboardFormatAvailable(CF_UNICODETEXT)) { - if (OpenClipboard(NULL)) { - bool bResult = false; - CString strClipboard; - HGLOBAL hMem = GetClipboardData(CF_UNICODETEXT); - if (hMem) { - LPCWSTR pwsz = (LPCWSTR)GlobalLock(hMem); - if (pwsz) { - strClipboard = pwsz; - GlobalUnlock(hMem); - bResult = true; - } + bool bResult = false; + CString strClipboard; + if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL)) { + HGLOBAL hMem = GetClipboardData(CF_UNICODETEXT); + if (hMem) { + LPCWSTR pwsz = (LPCWSTR)::GlobalLock(hMem); + if (pwsz) { + strClipboard = pwsz; + ::GlobalUnlock(hMem); + bResult = true; } - CloseClipboard(); - if (bResult) - return strClipboard; } + CloseClipboard(); } - - if (!IsClipboardFormatAvailable(CF_TEXT) || !OpenClipboard(NULL)) - return CString(); - - CString retstring; - HGLOBAL hglb = GetClipboardData(CF_TEXT); - if (hglb != NULL) { - LPCSTR lptstr = (LPCSTR)GlobalLock(hglb); - if (lptstr != NULL) { - retstring = lptstr; - GlobalUnlock(hglb); + if (!bResult && IsClipboardFormatAvailable(CF_TEXT) && OpenClipboard(NULL)) { + HGLOBAL hMem = GetClipboardData(CF_TEXT); + if (hMem != NULL) { + LPCSTR lptstr = (LPCSTR)::GlobalLock(hMem); + if (lptstr != NULL) { + strClipboard = lptstr; + ::GlobalUnlock(hMem); + } } + CloseClipboard(); } - CloseClipboard(); - - return retstring; + return strClipboard; } void CemuleApp::OnlineSig() // Added By Bouc7 @@ -955,11 +938,10 @@ void CemuleApp::OnlineSig() // Added By Bouc7 return; static LPCTSTR const _szFileName = _T("onlinesig.dat"); - CString strFullPath; - strFullPath.Format(_T("%s%s"), (LPCTSTR)thePrefs.GetMuleDirectory(EMULE_CONFIGBASEDIR), _szFileName); + const CString &strSigPath(thePrefs.GetMuleDirectory(EMULE_CONFIGBASEDIR) + _szFileName); // The 'onlinesig.dat' is potentially read by other applications at more or less frequent intervals. - // - Set the file shareing mode to allow other processes to read the file while we are writing + // - Set the file sharing mode to allow other processes to read the file while we are writing // it (see also next point). // - Try to write the hole file data at once, so other applications are always reading // a consistent amount of file data. C-RTL uses a 4 KB buffer, this is large enough to write @@ -968,12 +950,12 @@ void CemuleApp::OnlineSig() // Added By Bouc7 // compatibility with older eMule versions. CSafeBufferedFile file; CFileException fexp; - if (!file.Open(strFullPath, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite | CFile::typeBinary, &fexp)) { + if (!file.Open(strSigPath, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite | CFile::typeBinary, &fexp)) { CString strError; strError.Format(_T("%s %s"), (LPCTSTR)GetResString(IDS_ERROR_SAVEFILE), _szFileName); TCHAR szError[MAX_CFEXP_ERRORMSG]; GetExceptionMessage(fexp, szError, _countof(szError)); - strError.AppendFormat(_T(" - %s"), szError); + strError.Format(_T(" - %s"), szError); LogError(LOG_STATUSBAR, _T("%s"), (LPCTSTR)strError); return; } @@ -1047,7 +1029,7 @@ bool CemuleApp::GetLangHelpFilePath(CString &strResult) strResult.Truncate(pos); strResult.AppendFormat(_T("\\eMule%s.chm"), (LPCTSTR)temp); } - bool bFound = PathFileExists(strResult); + bool bFound = ::PathFileExists(strResult); if (!bFound && langID > 0) { strResult = m_pszHelpFilePath; // if not exists, use original help (English) strResult.Replace(_T(".HLP"), _T(".chm")); @@ -1092,7 +1074,7 @@ bool CemuleApp::ShowWebHelp(UINT uTopic) int CemuleApp::GetFileTypeSystemImageIdx(LPCTSTR pszFilePath, int iLength /* = -1 */, bool bNormalsSize) { DWORD dwFileAttributes; - LPCTSTR pszCacheExt = NULL; + LPCTSTR pszCacheExt; if (iLength == -1) iLength = (int)_tcslen(pszFilePath); if (iLength > 0 && (pszFilePath[iLength - 1] == _T('\\') || pszFilePath[iLength - 1] == _T('/'))) { @@ -1102,6 +1084,7 @@ int CemuleApp::GetFileTypeSystemImageIdx(LPCTSTR pszFilePath, int iLength /* = - } else { dwFileAttributes = FILE_ATTRIBUTE_NORMAL; // search last '.' character *after* the last '\\' character + pszCacheExt = _T(""); //default is an empty extension for (int i = iLength; --i >= 0;) { if (pszFilePath[i] == _T('\\') || pszFilePath[i] == _T('/')) break; @@ -1111,8 +1094,6 @@ int CemuleApp::GetFileTypeSystemImageIdx(LPCTSTR pszFilePath, int iLength /* = - break; } } - if (pszCacheExt == NULL) - pszCacheExt = _T(""); // empty extension } // Search extension in "ext->idx" cache. @@ -1121,29 +1102,28 @@ int CemuleApp::GetFileTypeSystemImageIdx(LPCTSTR pszFilePath, int iLength /* = - if (!m_aBigExtToSysImgIdx.Lookup(pszCacheExt, vData)) { // Get index for the system's big icon image list SHFILEINFO sfi; - HIMAGELIST hResult = (HIMAGELIST)SHGetFileInfo(pszFilePath, dwFileAttributes, &sfi, sizeof(sfi), - SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX); + HIMAGELIST hResult = (HIMAGELIST)::SHGetFileInfo(pszFilePath, dwFileAttributes, &sfi, sizeof(sfi), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX); if (hResult == 0) return 0; ASSERT(m_hBigSystemImageList == NULL || m_hBigSystemImageList == hResult); m_hBigSystemImageList = hResult; // Store icon index in local cache - m_aBigExtToSysImgIdx.SetAt(pszCacheExt, (LPVOID)sfi.iIcon); + m_aBigExtToSysImgIdx[pszCacheExt] = (LPVOID)sfi.iIcon; return sfi.iIcon; } } else if (!m_aExtToSysImgIdx.Lookup(pszCacheExt, vData)) { - // Get index for the system's small icon image list + // Get index for the system's small icon image list SHFILEINFO sfi; - HIMAGELIST hResult = (HIMAGELIST)SHGetFileInfo(pszFilePath, dwFileAttributes, &sfi, sizeof(sfi), - SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_SMALLICON); + HIMAGELIST hResult = (HIMAGELIST)::SHGetFileInfo(pszFilePath, dwFileAttributes, &sfi, sizeof(sfi) + , SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_SMALLICON); if (hResult == 0) return 0; ASSERT(m_hSystemImageList == NULL || m_hSystemImageList == hResult); m_hSystemImageList = hResult; // Store icon index in local cache - m_aExtToSysImgIdx.SetAt(pszCacheExt, (LPVOID)sfi.iIcon); + m_aExtToSysImgIdx[pszCacheExt] = (LPVOID)sfi.iIcon; return sfi.iIcon; } @@ -1153,7 +1133,7 @@ int CemuleApp::GetFileTypeSystemImageIdx(LPCTSTR pszFilePath, int iLength /* = - bool CemuleApp::IsConnected(bool bIgnoreEd2k, bool bIgnoreKad) { - return (theApp.serverconnect->IsConnected() && !bIgnoreEd2k) || (Kademlia::CKademlia::IsConnected() && !bIgnoreKad); + return (!bIgnoreEd2k && theApp.serverconnect->IsConnected()) || (!bIgnoreKad && Kademlia::CKademlia::IsConnected()); } bool CemuleApp::IsPortchangeAllowed() @@ -1172,8 +1152,11 @@ uint32 CemuleApp::GetID() uint32 CemuleApp::GetPublicIP(bool bIgnoreKadIP) const { - if (m_dwPublicIP == 0 && Kademlia::CKademlia::IsConnected() && Kademlia::CKademlia::GetIPAddress() && !bIgnoreKadIP) - return ntohl(Kademlia::CKademlia::GetIPAddress()); + if (!bIgnoreKadIP && m_dwPublicIP == 0 && Kademlia::CKademlia::IsConnected()) { + uint32 uIP = Kademlia::CKademlia::GetIPAddress(); + if (uIP) + return ntohl(uIP); + } return m_dwPublicIP; } @@ -1216,13 +1199,13 @@ bool CemuleApp::CanDoCallback(CUpDownClient *client) bool eLow = theApp.serverconnect->IsLowID(); if (!Kademlia::CKademlia::IsConnected() || Kademlia::CKademlia::IsFirewalled()) - return ed2k & !eLow; //callback for high ID server connection + return ed2k && !eLow; //callback for high ID server connection //KAD is connected and Open //Special case of a low ID server connection //If the client connects to the same server, we prevent callback //as it breaks the protocol and will get us banned. - if (ed2k & eLow) { + if ((ed2k & eLow) != 0) { const CServer *srv = theApp.serverconnect->GetCurrentServer(); return (client->GetServerIP() != srv->GetIP() || client->GetServerPort() != srv->GetPort()); } @@ -1246,11 +1229,11 @@ HICON CemuleApp::LoadIcon(LPCTSTR lpszResourceName, int cx, int cy, UINT uFlags) #endif HICON hIcon = NULL; - LPCTSTR pszSkinProfile = thePrefs.GetSkinProfile(); - if (pszSkinProfile != NULL && pszSkinProfile[0] != _T('\0')) { + const CString &sSkinProfile(thePrefs.GetSkinProfile()); + if (!sSkinProfile.IsEmpty()) { // load icon resource file specification from skin profile TCHAR szSkinResource[MAX_PATH]; - GetPrivateProfileString(_T("Icons"), lpszResourceName, _T(""), szSkinResource, _countof(szSkinResource), pszSkinProfile); + GetPrivateProfileString(_T("Icons"), lpszResourceName, NULL, szSkinResource, _countof(szSkinResource), sSkinProfile); if (szSkinResource[0] != _T('\0')) { // expand any optional available environment strings TCHAR szExpSkinRes[MAX_PATH]; @@ -1261,11 +1244,11 @@ HICON CemuleApp::LoadIcon(LPCTSTR lpszResourceName, int cx, int cy, UINT uFlags) // create absolute path to icon resource file TCHAR szFullResPath[MAX_PATH]; - if (PathIsRelative(szSkinResource)) { + if (::PathIsRelative(szSkinResource)) { TCHAR szSkinResFolder[MAX_PATH]; - _tcsncpy(szSkinResFolder, pszSkinProfile, _countof(szSkinResFolder)); + _tcsncpy(szSkinResFolder, sSkinProfile, _countof(szSkinResFolder)); szSkinResFolder[_countof(szSkinResFolder) - 1] = _T('\0'); - PathRemoveFileSpec(szSkinResFolder); + ::PathRemoveFileSpec(szSkinResFolder); _tmakepathlimit(szFullResPath, NULL, szSkinResFolder, szSkinResource, NULL); } else { _tcsncpy(szFullResPath, szSkinResource, _countof(szFullResPath)); @@ -1278,19 +1261,14 @@ HICON CemuleApp::LoadIcon(LPCTSTR lpszResourceName, int cx, int cy, UINT uFlags) int iIconIndex = 0; int iComma = strFullResPath.ReverseFind(_T(',')); if (iComma >= 0) { - if (_stscanf((LPCTSTR)strFullResPath + iComma + 1, _T("%d"), &iIconIndex) == 1) - bExtractIcon = true; + bExtractIcon |= (_stscanf(CPTR(strFullResPath, iComma + 1), _T("%d"), &iIconIndex) == 1); strFullResPath.Truncate(iComma); } if (bExtractIcon) { if (uFlags != 0 || !(cx == cy && (cx == 16 || cx == 32))) { - static UINT(WINAPI *_pfnPrivateExtractIcons)(LPCTSTR, int, int, int, HICON*, UINT*, UINT, UINT) - = (UINT(WINAPI*)(LPCTSTR, int, int, int, HICON*, UINT*, UINT, UINT))(void*)GetProcAddress(GetModuleHandle(_T("user32")), _TWINAPI("PrivateExtractIcons")); - if (_pfnPrivateExtractIcons) { - UINT uIconId; - (*_pfnPrivateExtractIcons)(strFullResPath, iIconIndex, cx, cy, &hIcon, &uIconId, 1, uFlags); - } + UINT uIconId; + ::PrivateExtractIcons(strFullResPath, iIconIndex, cx, cy, &hIcon, &uIconId, 1, uFlags); } if (hIcon == NULL) { @@ -1329,7 +1307,8 @@ HICON CemuleApp::LoadIcon(LPCTSTR lpszResourceName, int cx, int cy, UINT uFlags) // If the ICO file contains a 16x16 icon, 'LoadImage' will though return a 32x32 icon, // if LR_DEFAULTSIZE is specified! -> always specify the requested size! hIcon = (HICON)::LoadImage(NULL, szFullResPath, IMAGE_ICON, cx, cy, uFlags | LR_LOADFROMFILE); - if (hIcon == NULL && ::GetLastError() != ERROR_PATH_NOT_FOUND && g_bGdiPlusInstalled) { + if (hIcon == NULL && ::GetLastError() != ERROR_PATH_NOT_FOUND/* && g_bGdiPlusInstalled*/) { + // NOTE: Do *NOT* forget to specify /DELAYLOAD:gdiplus.dll as link parameter. ULONG_PTR gdiplusToken = 0; Gdiplus::GdiplusStartupInput gdiplusStartupInput; if (Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) == Gdiplus::Ok) { @@ -1359,11 +1338,11 @@ HICON CemuleApp::LoadIcon(LPCTSTR lpszResourceName, int cx, int cy, UINT uFlags) HBITMAP CemuleApp::LoadImage(LPCTSTR lpszResourceName, LPCTSTR pszResourceType) const { - LPCTSTR pszSkinProfile = thePrefs.GetSkinProfile(); - if (pszSkinProfile != NULL && pszSkinProfile[0] != _T('\0')) { + const CString &sSkinProfile(thePrefs.GetSkinProfile()); + if (!sSkinProfile.IsEmpty()) { // load resource file specification from skin profile TCHAR szSkinResource[MAX_PATH]; - GetPrivateProfileString(_T("Bitmaps"), lpszResourceName, _T(""), szSkinResource, _countof(szSkinResource), pszSkinProfile); + GetPrivateProfileString(_T("Bitmaps"), lpszResourceName, NULL, szSkinResource, _countof(szSkinResource), sSkinProfile); if (szSkinResource[0] != _T('\0')) { // expand any optional available environment strings TCHAR szExpSkinRes[MAX_PATH]; @@ -1374,11 +1353,11 @@ HBITMAP CemuleApp::LoadImage(LPCTSTR lpszResourceName, LPCTSTR pszResourceType) // create absolute path to resource file TCHAR szFullResPath[MAX_PATH]; - if (PathIsRelative(szSkinResource)) { + if (::PathIsRelative(szSkinResource)) { TCHAR szSkinResFolder[MAX_PATH]; - _tcsncpy(szSkinResFolder, pszSkinProfile, _countof(szSkinResFolder)); + _tcsncpy(szSkinResFolder, sSkinProfile, _countof(szSkinResFolder)); szSkinResFolder[_countof(szSkinResFolder) - 1] = _T('\0'); - PathRemoveFileSpec(szSkinResFolder); + ::PathRemoveFileSpec(szSkinResFolder); _tmakepathlimit(szFullResPath, NULL, szSkinResFolder, szSkinResource, NULL); } else { _tcsncpy(szFullResPath, szSkinResource, _countof(szFullResPath)); @@ -1392,18 +1371,18 @@ HBITMAP CemuleApp::LoadImage(LPCTSTR lpszResourceName, LPCTSTR pszResourceType) } CEnBitmap bmp; - if (bmp.LoadImage(lpszResourceName, pszResourceType)) - return (HBITMAP)bmp.Detach(); - return NULL; + return bmp.LoadImage(lpszResourceName, pszResourceType) ? (HBITMAP)bmp.Detach() : NULL; } CString CemuleApp::GetSkinFileItem(LPCTSTR lpszResourceName, LPCTSTR pszResourceType) const { - LPCTSTR pszSkinProfile = thePrefs.GetSkinProfile(); - if (pszSkinProfile != NULL && pszSkinProfile[0] != _T('\0')) { + TCHAR szFullResPath[MAX_PATH]; + *szFullResPath = _T('\0'); + const CString &sSkinProfile(thePrefs.GetSkinProfile()); + if (!sSkinProfile.IsEmpty()) { // load resource file specification from skin profile TCHAR szSkinResource[MAX_PATH]; - GetPrivateProfileString(pszResourceType, lpszResourceName, _T(""), szSkinResource, _countof(szSkinResource), pszSkinProfile); + GetPrivateProfileString(pszResourceType, lpszResourceName, NULL, szSkinResource, _countof(szSkinResource), sSkinProfile); if (szSkinResource[0] != _T('\0')) { // expand any optional available environment strings TCHAR szExpSkinRes[MAX_PATH]; @@ -1413,30 +1392,27 @@ CString CemuleApp::GetSkinFileItem(LPCTSTR lpszResourceName, LPCTSTR pszResource } // create absolute path to resource file - TCHAR szFullResPath[MAX_PATH]; - if (PathIsRelative(szSkinResource)) { + if (::PathIsRelative(szSkinResource)) { TCHAR szSkinResFolder[MAX_PATH]; - _tcsncpy(szSkinResFolder, pszSkinProfile, _countof(szSkinResFolder)); + _tcsncpy(szSkinResFolder, sSkinProfile, _countof(szSkinResFolder)); szSkinResFolder[_countof(szSkinResFolder) - 1] = _T('\0'); - PathRemoveFileSpec(szSkinResFolder); + ::PathRemoveFileSpec(szSkinResFolder); _tmakepathlimit(szFullResPath, NULL, szSkinResFolder, szSkinResource, NULL); } else { _tcsncpy(szFullResPath, szSkinResource, _countof(szFullResPath)); szFullResPath[_countof(szFullResPath) - 1] = _T('\0'); } - - return szFullResPath; } } - return CString(); + return CString(szFullResPath); } bool CemuleApp::LoadSkinColor(LPCTSTR pszKey, COLORREF &crColor) const { - LPCTSTR pszSkinProfile = thePrefs.GetSkinProfile(); - if (pszSkinProfile != NULL && pszSkinProfile[0] != _T('\0')) { + const CString &sSkinProfile(thePrefs.GetSkinProfile()); + if (!sSkinProfile.IsEmpty()) { TCHAR szColor[MAX_PATH]; - GetPrivateProfileString(_T("Colors"), pszKey, _T(""), szColor, _countof(szColor), pszSkinProfile); + GetPrivateProfileString(_T("Colors"), pszKey, NULL, szColor, _countof(szColor), sSkinProfile); if (szColor[0] != _T('\0')) { int red, grn, blu; if (_stscanf(szColor, _T("%i , %i , %i"), &red, &grn, &blu) == 3) { @@ -1483,14 +1459,14 @@ void CemuleApp::AddEd2kLinksToDownload(const CString &strLinks, int cat) const CString &sToken(strLinks.Tokenize(_T(" \t\r\n"), iPos)); //tokenize by whitespace if (sToken.IsEmpty()) break; - bool bSlash = (sToken.Right(1) == _T("/")); + bool bSlash = (sToken[sToken.GetLength() - 1] == _T('/')); CED2KLink *pLink = NULL; try { pLink = CED2KLink::CreateLinkFromUrl(bSlash ? sToken : sToken + _T('/')); if (pLink) { if (pLink->GetKind() != CED2KLink::kFile) - throw CString(_T("bad link")); - downloadqueue->AddFileLinkToDownload(pLink->GetFileLink(), cat); + throwCStr(_T("bad link")); + downloadqueue->AddFileLinkToDownload(*pLink->GetFileLink(), cat); delete pLink; pLink = NULL; } @@ -1519,7 +1495,7 @@ void CemuleApp::SearchClipboard() // Do not alter (trim) 'strLinks' and then copy back to 'm_strLastClipboardContents'! The // next clipboard content compare would fail because of the modified string. LPCTSTR pszTrimmedLinks = strLinks; - while (_istspace(*pszTrimmedLinks)) // Skip leading whitespaces + while (_istspace(*pszTrimmedLinks)) // Skip leading white space ++pszTrimmedLinks; m_bGuardClipboardPrompt = !_tcsnicmp(pszTrimmedLinks, _T("ed2k://|file|"), 13); if (m_bGuardClipboardPrompt) { @@ -1551,12 +1527,12 @@ bool CemuleApp::IsEd2kLinkInClipboard(LPCSTR pszLinkType, int iLinkTypeLen) HGLOBAL hText = GetClipboardData(CF_TEXT); if (hText != NULL) { // Use the ANSI string - LPCSTR pszText = (LPCSTR)GlobalLock(hText); + LPCSTR pszText = (LPCSTR)::GlobalLock(hText); if (pszText != NULL) { while (isspace(*pszText)) ++pszText; bFoundLink = (_strnicmp(pszText, pszLinkType, iLinkTypeLen) == 0); - GlobalUnlock(hText); + ::GlobalUnlock(hText); } } CloseClipboard(); @@ -1831,7 +1807,7 @@ void CemuleApp::CreateBackwardDiagonalBrush() LOGBRUSH logBrush = {}; logBrush.lbStyle = BS_PATTERN; logBrush.lbHatch = (ULONG_PTR)bm.GetSafeHandle(); - logBrush.lbColor = RGB(0, 0, 0); + //logBrush.lbColor = RGB(0, 0, 0); VERIFY(m_brushBackwardDiagonal.CreateBrushIndirect(&logBrush)); } } @@ -1976,15 +1952,11 @@ void CemuleApp::UpdateLargeIconSize() void CemuleApp::ResetStandByIdleTimer() { // check if anything is going on (ongoing upload, download or connected) and reset the idle timer if so - if (IsConnected() || (uploadqueue != NULL && uploadqueue->GetUploadQueueLength() > 0) + if (IsConnected() + || (uploadqueue != NULL && uploadqueue->GetUploadQueueLength() > 0) || (downloadqueue != NULL && downloadqueue->GetDatarate() > 0)) { - EXECUTION_STATE(WINAPI *pfnSetThreadExecutionState)(EXECUTION_STATE); - (FARPROC&)pfnSetThreadExecutionState = GetProcAddress(GetModuleHandle(_T("kernel32")), "SetThreadExecutionState"); - if (pfnSetThreadExecutionState) - VERIFY(pfnSetThreadExecutionState(ES_SYSTEM_REQUIRED)); - else - ASSERT(0); + VERIFY(::SetThreadExecutionState(ES_SYSTEM_REQUIRED)); } } diff --git a/srchybrid/Emule.h b/srchybrid/Emule.h index 0fca63bb..1eec582c 100644 --- a/srchybrid/Emule.h +++ b/srchybrid/Emule.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -24,7 +24,7 @@ #define DEFAULT_TCP_PORT_OLD 4662 #define DEFAULT_UDP_PORT_OLD (DEFAULT_TCP_PORT_OLD+10) -#define PORTTESTURL _T("http://porttest.emule-project.net/connectiontest.php?tcpport=%i&udpport=%i&lang=%i") +#define PORTTESTURL _T("https://porttest.emule-project.net/connectiontest.php?tcpport=%i&udpport=%i&lang=%i") class CSearchList; class CUploadQueue; @@ -50,6 +50,7 @@ class CPeerCacheFinder; class CFirewallOpener; class CUPnPImplWrapper; class CUploadDiskIOThread; +class CPartFileWriteThread; struct SLogItem; @@ -93,6 +94,8 @@ class CemuleApp : public CWinApp CFirewallOpener *m_pFirewallOpener; CUPnPImplWrapper *m_pUPnPFinder; CUploadDiskIOThread *m_pUploadDiskIOThread; + CPartFileWriteThread *m_pPartFileWriteThread; + static const UINT m_nVersionMjr; static const UINT m_nVersionMin; diff --git a/srchybrid/EmuleDlg.cpp b/srchybrid/EmuleDlg.cpp index d3990f9e..06ff8af5 100644 --- a/srchybrid/EmuleDlg.cpp +++ b/srchybrid/EmuleDlg.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -30,8 +30,10 @@ #include #include #include +#include #include "emule.h" #include "emuleDlg.h" +#include "otherfunctions.h" #include "ServerWnd.h" #include "KademliaWnd.h" #include "TransferWnd.h" @@ -103,9 +105,9 @@ #include "VisualStylesXP.h" #include "UPnPImpl.h" #include "UPnPImplWrapper.h" -#include #include "ExitBox.h" #include "UploadDiskIOThread.h" +#include "PartFileWriteThread.h" #include "ImportParts.h" #ifdef _DEBUG @@ -153,6 +155,7 @@ BEGIN_MESSAGE_MAP(CemuleDlg, CTrayDialog) ON_WM_DESTROY() ON_WM_SETTINGCHANGE() ON_WM_DEVICECHANGE() + ON_MESSAGE(WM_DISPLAYCHANGE, OnDisplayChange) ON_MESSAGE(WM_POWERBROADCAST, OnPowerBroadcast) /////////////////////////////////////////////////////////////////////////// @@ -261,6 +264,7 @@ CemuleDlg::CemuleDlg(CWnd *pParent /*=NULL*/) , notifierenabled() { g_uMainThreadId = GetCurrentThreadId(); + SetClientIconList(); preferenceswnd = new CPreferencesDlg; serverwnd = new CServerWnd; kademliawnd = new CKademliaWnd; @@ -276,6 +280,35 @@ CemuleDlg::CemuleDlg(CWnd *pParent /*=NULL*/) m_pDropTarget = new CMainFrameDropTarget; } +void CemuleDlg::SetClientIconList() +{ + m_IconList.Create(16, 16, theApp.m_iDfltImageListColorFlags | ILC_MASK, 0, 1); + m_IconList.Add(CTempIconLoader(_T("ClientEDonkey"))); //0 - eDonkey + m_IconList.Add(CTempIconLoader(_T("ClientEDonkeyPlus"))); + m_IconList.Add(CTempIconLoader(_T("ClientCompatible"))); //2 - Compat + m_IconList.Add(CTempIconLoader(_T("ClientCompatiblePlus"))); + m_IconList.Add(CTempIconLoader(_T("Friend"))); //4 - friend + m_IconList.Add(CTempIconLoader(_T("ClientMLDonkey"))); //5 - ML + m_IconList.Add(CTempIconLoader(_T("ClientMLDonkeyPlus"))); + m_IconList.Add(CTempIconLoader(_T("ClientEDonkeyHybrid"))); //7 - Hybrid + m_IconList.Add(CTempIconLoader(_T("ClientEDonkeyHybridPlus"))); + m_IconList.Add(CTempIconLoader(_T("ClientShareaza"))); //9 - Shareaza + m_IconList.Add(CTempIconLoader(_T("ClientShareazaPlus"))); + m_IconList.Add(CTempIconLoader(_T("ClientAMule"))); //11 - amule + m_IconList.Add(CTempIconLoader(_T("ClientAMulePlus"))); + m_IconList.Add(CTempIconLoader(_T("ClientLPhant"))); //13 - Lphant + m_IconList.Add(CTempIconLoader(_T("ClientLPhantPlus"))); + m_IconList.Add(CTempIconLoader(_T("Server"))); //15 - http source + m_IconList.SetOverlayImage(m_IconList.Add(CTempIconLoader(_T("ClientSecureOvl"))), 1); + m_IconList.SetOverlayImage(m_IconList.Add(CTempIconLoader(_T("OverlayObfu"))), 2); + m_IconList.SetOverlayImage(m_IconList.Add(CTempIconLoader(_T("OverlaySecureObfu"))), 3); +} + +CImageList& CemuleDlg::GetClientIconList() +{ + return m_IconList; +} + void DestroyIconsArr(HICON *pIcon, size_t cnt) { while (cnt-- > 0) @@ -367,7 +400,7 @@ BOOL CemuleDlg::OnInitDialog() if (m_bInitedCOM) { typedef BOOL(WINAPI *PChangeWindowMessageFilter)(UINT message, DWORD dwFlag); PChangeWindowMessageFilter ChangeWindowMessageFilter - = (PChangeWindowMessageFilter)(GetProcAddress(GetModuleHandle(TEXT("user32.dll")), "ChangeWindowMessageFilter")); + = (PChangeWindowMessageFilter)(GetProcAddress(GetModuleHandle(_T("user32.dll")), "ChangeWindowMessageFilter")); if (ChangeWindowMessageFilter) { ChangeWindowMessageFilter(UWM_TASK_BUTTON_CREATED, 1); ChangeWindowMessageFilter(WM_COMMAND, 1); @@ -551,7 +584,7 @@ BOOL CemuleDlg::OnInitDialog() /////////////////////////////////////////////////////////////////////////// // Restore saved window placement // - WINDOWPLACEMENT wp = {}; + WINDOWPLACEMENT wp; wp.length = (UINT)sizeof wp; wp = thePrefs.GetEmuleWindowPlacement(); if (m_bStartMinimized) { @@ -674,27 +707,26 @@ void CALLBACK CemuleDlg::StartupTimer(HWND /*hwnd*/, UINT /*uiMsg*/, UINT_PTR /* try { switch (theApp.emuledlg->status) { case 0: - theApp.emuledlg->status++; + ++theApp.emuledlg->status; theApp.emuledlg->ready = true; theApp.sharedfiles->SetOutputCtrl(&theApp.emuledlg->sharedfileswnd->sharedfilesctrl); - theApp.emuledlg->status++; - break; + ++theApp.emuledlg->status; case 1: break; case 2: - theApp.emuledlg->status++; + ++theApp.emuledlg->status; try { theApp.serverlist->Init(); } catch (...) { ASSERT(0); LogError(LOG_STATUSBAR, _T("Failed to initialize server list - Unknown exception")); } - theApp.emuledlg->status++; + ++theApp.emuledlg->status; case 3: break; case 4: { - theApp.emuledlg->status++; + ++theApp.emuledlg->status; bool bError = false; // NOTE: If we have an unhandled exception in CDownloadQueue::Init, MFC will silently catch it @@ -740,7 +772,7 @@ void CALLBACK CemuleDlg::StartupTimer(HWND /*hwnd*/, UINT /*uiMsg*/, UINT_PTR /* } break; case 5: - theApp.emuledlg->status++; + ++theApp.emuledlg->status; if (thePrefs.IsStoringSearchesEnabled()) theApp.searchlist->LoadSearches(); break; @@ -1012,36 +1044,31 @@ void CemuleDlg::ShowConnectionState() ShowConnectionStateIcon(); statusbar->SetText(GetConnectionStateString(), SBarConnected, 0); + TBBUTTONINFO tbbi; + tbbi.cbSize = (UINT)sizeof(TBBUTTONINFO); + tbbi.dwMask = TBIF_IMAGE | TBIF_TEXT; + if (theApp.IsConnected()) { CString strPane(GetResString(IDS_MAIN_BTN_DISCONNECT)); - TBBUTTONINFO tbi; - tbi.cbSize = (UINT)sizeof(TBBUTTONINFO); - tbi.dwMask = TBIF_IMAGE | TBIF_TEXT; - tbi.iImage = 1; - tbi.pszText = const_cast((LPCTSTR)strPane); - toolbar->SetButtonInfo(TBBTN_CONNECT, &tbi); + tbbi.iImage = 1; + tbbi.pszText = const_cast((LPCTSTR)strPane); + toolbar->SetButtonInfo(TBBTN_CONNECT, &tbbi); strPane.Remove(_T('&')); if (!theApp.emuledlg->m_SysMenuOptions.ModifyMenuW(MP_CONNECT, MF_STRING, MP_DISCONNECT, strPane)) theApp.emuledlg->m_SysMenuOptions.ModifyMenuW(MP_DISCONNECT, MF_STRING, MP_DISCONNECT, strPane); //replace "Cancel" with "Disconnect" } else { if (theApp.serverconnect->IsConnecting() || Kademlia::CKademlia::IsRunning()) { CString strPane(GetResString(IDS_MAIN_BTN_CANCEL)); - TBBUTTONINFO tbi; - tbi.cbSize = (UINT)sizeof(TBBUTTONINFO); - tbi.dwMask = TBIF_IMAGE | TBIF_TEXT; - tbi.iImage = 2; - tbi.pszText = const_cast((LPCTSTR)strPane); - toolbar->SetButtonInfo(TBBTN_CONNECT, &tbi); + tbbi.iImage = 2; + tbbi.pszText = const_cast((LPCTSTR)strPane); + toolbar->SetButtonInfo(TBBTN_CONNECT, &tbbi); strPane.Remove(_T('&')); theApp.emuledlg->m_SysMenuOptions.ModifyMenuW(MP_CONNECT, MF_STRING, MP_DISCONNECT, strPane); } else { CString strPane(GetResString(IDS_MAIN_BTN_CONNECT)); - TBBUTTONINFO tbi; - tbi.cbSize = (UINT)sizeof(TBBUTTONINFO); - tbi.dwMask = TBIF_IMAGE | TBIF_TEXT; - tbi.iImage = 0; - tbi.pszText = const_cast((LPCTSTR)strPane); - toolbar->SetButtonInfo(TBBTN_CONNECT, &tbi); + tbbi.iImage = 0; + tbbi.pszText = const_cast((LPCTSTR)strPane); + toolbar->SetButtonInfo(TBBTN_CONNECT, &tbbi); strPane.Remove(_T('&')); theApp.emuledlg->m_SysMenuOptions.ModifyMenuW(MP_DISCONNECT, MF_STRING, MP_CONNECT, strPane); } @@ -1068,9 +1095,9 @@ void CemuleDlg::ShowUserCount() statusbar->SetText(buffer, SBarUsers, 0); } -void CemuleDlg::ShowMessageState(UINT iconnr) +void CemuleDlg::ShowMessageState(UINT nIcon) { - m_iMsgIcon = iconnr; + m_iMsgIcon = nIcon; statusbar->SetIcon(SBarChatMsg, imicons[m_iMsgIcon]); } @@ -1123,20 +1150,20 @@ void CemuleDlg::ShowTransferRate(bool bForceAll) m_uUpDatarate = theApp.uploadqueue->GetDatarate(); const CString &strTransferRate = GetTransferRateString(); - if (TrayIsVisible() || bForceAll) { + if (TrayIconVisible() || bForceAll) { // set tray icon int iDownRatePercent = (int)ceil((m_uDownDatarate / 10.24) / thePrefs.GetMaxGraphDownloadRate()); if (iDownRatePercent > 100) iDownRatePercent = 100; UpdateTrayIcon(iDownRatePercent); - CString buffer2; - buffer2.Format(_T("eMule v%s (%s)\r\n%s") + CString buffer; + buffer.Format(_T("eMule v%s (%s)\r\n%s") , (LPCTSTR)theApp.m_strCurVersionLong , (LPCTSTR)GetResString(theApp.IsConnected() ? IDS_CONNECTED : IDS_DISCONNECTED) , (LPCTSTR)strTransferRate); - TraySetToolTip(buffer2); + TraySetToolTip(buffer); } if (IsWindowVisible() || bForceAll) { @@ -1154,19 +1181,16 @@ void CemuleDlg::ShowTransferRate(bool bForceAll) void CemuleDlg::ShowPing() { - if (IsWindowVisible()) { - if (thePrefs.IsDynUpEnabled()) { - CString buffer; - CurrentPingStruct lastPing = theApp.lastCommonRouteFinder->GetCurrentPing(); - if (lastPing.state.IsEmpty()) { - if (lastPing.lowest > 0 && !thePrefs.IsDynUpUseMillisecondPingTolerance()) - buffer.Format(_T("%.1f | %ums | %u%%"), lastPing.currentLimit / 1024.0f, lastPing.latency, lastPing.latency * 100 / lastPing.lowest); - else - buffer.Format(_T("%.1f | %ums"), lastPing.currentLimit / 1024.0f, lastPing.latency); - } else - buffer = lastPing.state; - statusbar->SetText(buffer, SBarUSS, 0); - }; + if (IsWindowVisible() && thePrefs.IsDynUpEnabled()) { + CurrentPingStruct lastPing = theApp.lastCommonRouteFinder->GetCurrentPing(); + CString &strState(lastPing.state); + if (strState.IsEmpty()) { + if (lastPing.lowest > 0 && !thePrefs.IsDynUpUseMillisecondPingTolerance()) + strState.Format(_T("%.1f | %ums | %u%%"), lastPing.currentLimit / 1024.0f, lastPing.latency, lastPing.latency * 100 / lastPing.lowest); + else + strState.Format(_T("%.1f | %ums"), lastPing.currentLimit / 1024.0f, lastPing.latency); + } + statusbar->SetText(strState, SBarUSS, 0); } } @@ -1239,56 +1263,58 @@ void CemuleDlg::OnSize(UINT nType, int cx, int cy) CTrayDialog::OnSize(nType, cx, cy); SetStatusBarPartsSize(); // we might receive this message during shutdown -> bad - if (!theApp.IsClosing() && transferwnd != NULL) + if (transferwnd != NULL && !theApp.IsClosing()) transferwnd->VerifyCatTabSize(); } void CemuleDlg::ProcessED2KLink(LPCTSTR pszData) { try { - CString link2(pszData); - link2.Replace(_T("%7c"), _T("|")); - CString link(OptUtf8ToStr(URLDecode(link2))); - CED2KLink *pLink = CED2KLink::CreateLinkFromUrl(link); - _ASSERT(pLink != 0); + CString link(pszData); + link.Replace(_T("%7c"), _T("|")); + CED2KLink *pLink = CED2KLink::CreateLinkFromUrl(OptUtf8ToStr(URLDecode(link))); + ASSERT(pLink); switch (pLink->GetKind()) { case CED2KLink::kFile: { CED2KFileLink *pFileLink = pLink->GetFileLink(); - _ASSERT(pFileLink != 0); - theApp.downloadqueue->AddFileLinkToDownload(pFileLink, searchwnd->GetSelectedCat()); + ASSERT(pFileLink); + theApp.downloadqueue->AddFileLinkToDownload(*pFileLink, searchwnd->GetSelectedCat()); } break; case CED2KLink::kServerList: { CED2KServerListLink *pListLink = pLink->GetServerListLink(); - _ASSERT(pListLink != 0); - const CString &strAddress = pListLink->GetAddress(); + ASSERT(pListLink); + const CString &strAddress(pListLink->GetAddress()); if (!strAddress.IsEmpty()) serverwnd->UpdateServerMetFromURL(strAddress); } break; case CED2KLink::kNodesList: { - CED2KNodesListLink *pListLink = pLink->GetNodesListLink(); - _ASSERT(pListLink != 0); - const CString &strAddress = pListLink->GetAddress(); - // Because the nodes.dat is vital for kad and its routing and doesn't needs to be updated in general - // we request a confirm to avoid accidental / malicious updating of this file. This is a bit inconsistent - // as the same kinda applies to the server.met, but those require more updates and are easier to understand - CString strConfirm; - strConfirm.Format(GetResString(IDS_CONFIRMNODESDOWNLOAD), (LPCTSTR)strAddress); - if (!strAddress.IsEmpty() && AfxMessageBox(strConfirm, MB_YESNO | MB_ICONQUESTION, 0) == IDYES) - kademliawnd->UpdateNodesDatFromURL(strAddress); + const CED2KNodesListLink *pListLink = pLink->GetNodesListLink(); + ASSERT(pListLink); + const CString &strAddress(pListLink->GetAddress()); + // Because the nodes.dat is vital for kad and its routing and doesn't need to be + // updated in general, we request a confirm to avoid accidental / malicious updating + // of this file. This is a bit inconsistent as the same kinda applies to the server.met, + // but those require more updates and are easier to understand + if (!strAddress.IsEmpty()) { + CString strConfirm; + strConfirm.Format(GetResString(IDS_CONFIRMNODESDOWNLOAD), (LPCTSTR)strAddress); + if (AfxMessageBox(strConfirm, MB_YESNO | MB_ICONQUESTION, 0) == IDYES) + kademliawnd->UpdateNodesDatFromURL(strAddress); + } } break; case CED2KLink::kServer: { - CString defName; CED2KServerLink *pSrvLink = pLink->GetServerLink(); - _ASSERT(pSrvLink != 0); + ASSERT(pSrvLink); CServer *pSrv = new CServer(pSrvLink->GetPort(), pSrvLink->GetAddress()); - _ASSERT(pSrv != 0); + ASSERT(pSrv); + CString defName; pSrvLink->GetDefaultName(defName); pSrv->SetListName(defName); @@ -1305,7 +1331,7 @@ void CemuleDlg::ProcessED2KLink(LPCTSTR pszData) case CED2KLink::kSearch: { CED2KSearchLink *pListLink = pLink->GetSearchLink(); - _ASSERT(pListLink != 0); + ASSERT(pListLink); SetActiveDialog(searchwnd); searchwnd->ProcessEd2kSearchLinkRequest(pListLink->GetSearchTerm()); } @@ -1325,13 +1351,11 @@ LRESULT CemuleDlg::OnWMData(WPARAM, LPARAM lParam) PCOPYDATASTRUCT data = (PCOPYDATASTRUCT)lParam; ULONG_PTR op = data->dwData; if ((op == OP_ED2KLINK && thePrefs.IsBringToFront()) || op == OP_COLLECTION) { - FlashWindow(TRUE); if (IsIconic()) ShowWindow(SW_SHOWNORMAL); - else if (TrayHide()) - RestoreWindow(); else - SetForegroundWindow(); + RestoreWindow(); + FlashWindow(TRUE); } switch (op) { case OP_ED2KLINK: @@ -1340,7 +1364,7 @@ LRESULT CemuleDlg::OnWMData(WPARAM, LPARAM lParam) case OP_COLLECTION: { CCollection *pCollection = new CCollection(); - CString strPath((LPCTSTR)data->lpData); + const CString &strPath((LPCTSTR)data->lpData); if (pCollection->InitCollectionFromFile(strPath, strPath.Right(strPath.GetLength() - 1 - strPath.ReverseFind(_T('\\'))))) { CCollectionViewDialog dialog; dialog.SetCollection(pCollection); @@ -1366,16 +1390,15 @@ LRESULT CemuleDlg::OnWMData(WPARAM, LPARAM lParam) } else if (clcommand == _T("help") || clcommand == _T("/?")) ; // show usage else if (clcommand.Left(7) == _T("limits=") && clcommand.GetLength() > 8) { - CString up(clcommand.Mid(7)); - int pos = up.Find(_T(',')); + clcommand.Delete(0, 7); + int pos = clcommand.Find(_T(',')); if (pos > 0) { - const CString &down(up.Mid(pos + 1)); - if (!down.IsEmpty()) - thePrefs.SetMaxDownload(_tstoi(down)); - up.Truncate(pos); + if (clcommand[pos + 1]) + thePrefs.SetMaxDownload(_tstoi(CPTR(clcommand, pos + 1))); + clcommand.Truncate(pos); } - if (!up.IsEmpty()) - thePrefs.SetMaxUpload(_tstoi(up)); + if (!clcommand.IsEmpty()) + thePrefs.SetMaxUpload(_tstoi(clcommand)); } else if (clcommand == _T("reloadipf")) theApp.ipfilter->LoadFromDefaultFile(); else if (clcommand == _T("restore")) @@ -1400,7 +1423,7 @@ LRESULT CemuleDlg::OnWMData(WPARAM, LPARAM lParam) fclose(file); } } - //else show "unknown command"; + //else show "unknown command"; Or "usage" } } return TRUE; @@ -1431,7 +1454,7 @@ LRESULT CemuleDlg::OnFileHashed(WPARAM wParam, LPARAM lParam) } else { ASSERT(!result->IsKindOf(RUNTIME_CLASS(CPartFile))); - // File hashing finished for a shared file (none partfile) + // File hashing finished for a shared file (not a partfile) when: // - reading shared directories at startup and hashing files which were not found in known.met // - reading shared directories during runtime (user hit Reload button, added a shared directory, ...) theApp.sharedfiles->FileHashingFinished(result); @@ -1483,12 +1506,13 @@ LRESULT CemuleDlg::OnFileCompleted(WPARAM wParam, LPARAM lParam) LRESULT CemuleDlg::OnImportPart(WPARAM wParam, LPARAM lParam) { CPartFile *partfile = reinterpret_cast(lParam); - ImportPart_Struct *importpart = reinterpret_cast(wParam); - if (!theApp.IsClosing() && AfxIsValidAddress(partfile, sizeof(CPartFile)) && theApp.downloadqueue->IsPartFile(partfile)) // could have been cancelled - partfile->WriteToBuffer(importpart->end - importpart->start + 1, importpart->data, importpart->start, importpart->end, NULL, NULL); + ImportPart_Struct *imp = reinterpret_cast(wParam); + if (theApp.downloadqueue->IsPartFile(partfile) && !theApp.IsClosing()) // could have been cancelled + if (partfile->WriteToBuffer(imp->end - imp->start + 1, imp->data, imp->start, imp->end, NULL, NULL, false)) + imp->data = NULL; //do not delete the buffer - delete[] importpart->data; - delete importpart; + delete[] imp->data; + delete imp; return 0; } @@ -1516,7 +1540,7 @@ BOOL CemuleDlg::OnQueryEndSession() void CemuleDlg::OnEndSession(BOOL bEnding) { AddDebugLogLine(DLP_VERYLOW, _T("%hs: bEnding=%d"), __FUNCTION__, bEnding); - if (!theApp.IsClosing() && bEnding) { + if (bEnding && !theApp.IsClosing()) { // If eMule was *not* started with "RUNAS": // When user is logging of (or reboots or shutdown system), Windows sends the // WM_QUERYENDSESSION/WM_ENDSESSION to all top level windows. @@ -1619,12 +1643,11 @@ bool CemuleDlg::CanClose() { if (theApp.m_app_state == APP_STATE_RUNNING && thePrefs.IsConfirmExitEnabled()) { theApp.m_app_state = APP_STATE_ASKCLOSE; //disable tray menu - if (IsIconic()) - ShowWindow(SW_SHOWNORMAL); // XMessageBox has a bug when displaying in minimized windows, but it makes sense to restore it for this prompt anyway + RestoreWindow(); // make sure the window is in foreground for this prompt ExitBox request; request.DoModal(); if (request.WasCancelled()) { - if (theApp.m_app_state == APP_STATE_ASKCLOSE) //if the application state did not change + if (theApp.m_app_state == APP_STATE_ASKCLOSE) //if the application state has not changed theApp.m_app_state = APP_STATE_RUNNING; //then keep running return false; } @@ -1635,10 +1658,10 @@ bool CemuleDlg::CanClose() void CemuleDlg::OnClose() { static LONG closing = 0; - if (InterlockedExchange(&closing, 1)) + if (::InterlockedExchange(&closing, 1)) return; //already closing if (!CanClose()) { - InterlockedExchange(&closing, 0); + ::InterlockedExchange(&closing, 0); return; } theApp.m_app_state = APP_STATE_SHUTTINGDOWN; @@ -1691,6 +1714,7 @@ void CemuleDlg::OnClose() sLock1.Lock(SEC2MS(2)); theApp.m_pUploadDiskIOThread->EndThread(); + theApp.m_pPartFileWriteThread->EndThread(); // saving data & stuff theApp.emuledlg->preferenceswnd->m_wndSecurity.DeleteDDB(); @@ -1764,6 +1788,7 @@ void CemuleDlg::OnClose() delete theApp.lastCommonRouteFinder; theApp.lastCommonRouteFinder = NULL; delete theApp.m_pUPnPFinder; theApp.m_pUPnPFinder = NULL; delete theApp.m_pUploadDiskIOThread; theApp.m_pUploadDiskIOThread = NULL; + delete theApp.m_pPartFileWriteThread; theApp.m_pPartFileWriteThread = NULL; thePrefs.Uninit(); theApp.m_app_state = APP_STATE_DONE; @@ -1795,12 +1820,12 @@ LRESULT CemuleDlg::OnCloseMiniMule(WPARAM wParam, LPARAM) return 0; } -void CemuleDlg::OnTrayLButtonUp(CPoint) +void CemuleDlg::OnTrayLButtonUp() { if (theApp.IsClosing()) return; - // Avoid re-entrancy problems with the main window, options dialog and minimule window + // Avoid re-entrance problems with the main window, options dialog and minimule window if (IsPreferencesDlgOpen()) { MessageBeep(MB_OK); preferenceswnd->SetForegroundWindow(); @@ -1843,7 +1868,7 @@ void CemuleDlg::OnTrayRButtonUp(CPoint pt) if (theApp.m_app_state != APP_STATE_RUNNING) return; - // Avoid re-entrancy problems with main window, options dialog and minimule window + // Avoid re-entrance problems with main window, options dialog and minimule window if (IsPreferencesDlgOpen()) { MessageBeep(MB_OK); preferenceswnd->SetForegroundWindow(); @@ -1856,7 +1881,7 @@ void CemuleDlg::OnTrayRButtonUp(CPoint pt) TRACE("%s - m_pMiniMule->GetAutoClose() -> DestroyMiniMule();\n", __FUNCTION__); DestroyMiniMule(); } else if (m_pMiniMule->m_hWnd && !m_pMiniMule->IsWindowEnabled()) { - // Avoid re-entrancy problems with main window, options dialog and minimule window + // Avoid re-entrance problems with main window, options dialog and minimule window MessageBeep(MB_OK); return; } @@ -1904,22 +1929,22 @@ void CemuleDlg::OnTrayRButtonUp(CPoint pt) void CemuleDlg::AddSpeedSelectorMenus(CMenu *addToMenu) { - CString text; - const CString &kbyps = GetResString(IDS_KBYTESPERSEC); + const CString &kbyps(GetResString(IDS_KBYTESPERSEC)); // Create UploadPopup Menu ASSERT(m_menuUploadCtrl.m_hMenu == NULL); + CString text; if (m_menuUploadCtrl.CreateMenu()) { int rate = thePrefs.GetMaxGraphUploadRate(true); - text.Format(_T("20%%\t%i %s"), (int)(rate*0.2), (LPCTSTR)kbyps); + text.Format(_T("20%%\t%i %s"), max(rate * 1 / 5, 1), (LPCTSTR)kbyps); m_menuUploadCtrl.AppendMenu(MF_STRING, MP_QS_U20, text); - text.Format(_T("40%%\t%i %s"), (int)(rate*0.4), (LPCTSTR)kbyps); + text.Format(_T("40%%\t%i %s"), max(rate * 2 / 5, 1), (LPCTSTR)kbyps); m_menuUploadCtrl.AppendMenu(MF_STRING, MP_QS_U40, text); - text.Format(_T("60%%\t%i %s"), (int)(rate*0.6), (LPCTSTR)kbyps); + text.Format(_T("60%%\t%i %s"), max(rate * 3 / 5, 1), (LPCTSTR)kbyps); m_menuUploadCtrl.AppendMenu(MF_STRING, MP_QS_U60, text); - text.Format(_T("80%%\t%i %s"), (int)(rate*0.8), (LPCTSTR)kbyps); + text.Format(_T("80%%\t%i %s"), max(rate * 4 / 5, 1), (LPCTSTR)kbyps); m_menuUploadCtrl.AppendMenu(MF_STRING, MP_QS_U80, text); - text.Format(_T("100%%\t%i %s"), rate, (LPCTSTR)kbyps); - m_menuUploadCtrl.AppendMenu(MF_STRING, MP_QS_U100, text); + //text.Format(_T("100%%\t%i %s"), rate, (LPCTSTR)kbyps); + //m_menuUploadCtrl.AppendMenu(MF_STRING, MP_QS_U100, text); m_menuUploadCtrl.AppendMenu(MF_SEPARATOR); if (GetRecMaxUpload() > 0) { @@ -1988,11 +2013,8 @@ void CemuleDlg::StartConnection() void CemuleDlg::CloseConnection() { - if (theApp.serverconnect->IsConnected()) - theApp.serverconnect->Disconnect(); - - if (theApp.serverconnect->IsConnecting()) - theApp.serverconnect->StopConnectionTry(); + theApp.serverconnect->StopConnectionTry(); + theApp.serverconnect->Disconnect(); Kademlia::CKademlia::Stop(); theApp.OnlineSig(); // Added By Bouc7 @@ -2229,7 +2251,7 @@ HBRUSH CemuleDlg::GetCtlColor(CDC* /*pDC*/, CWnd* /*pWnd*/, UINT /*nCtlColor*/) { // This function could be used to give the entire eMule (at least all of the main windows) // a somewhat more Vista like look by giving them all a bright background color. - // However, again, the owner drawn tab controls are noticeable disturbing that attempt. They + // However, again, the owner drawn tab controls are noticeably disturbing that attempt. They // do not change their background color accordingly. They don't use NMCUSTOMDRAW nor to they // use WM_CTLCOLOR... // @@ -2576,13 +2598,12 @@ BOOL CemuleDlg::OnCommand(WPARAM wParam, LPARAM lParam) else if (wParam >= MP_SCHACTIONS && wParam <= MP_SCHACTIONS + 99) { theApp.scheduler->ActivateSchedule(wParam - MP_SCHACTIONS); theApp.scheduler->SaveOriginals(); // use the new settings as original - } #ifdef HAVE_WIN7_SDK_H - else if (HIWORD(wParam) == THBN_CLICKED) { + } else if (HIWORD(wParam) == THBN_CLICKED) { OnTBBPressed(LOWORD(wParam)); return TRUE; - } #endif + } return CTrayDialog::OnCommand(wParam, lParam); } @@ -2623,7 +2644,7 @@ void CemuleDlg::ShowToolPopup(bool toolsonly) CMenu scheduler; scheduler.CreateMenu(); - const CString &schedonoff = GetResString(thePrefs.IsSchedulerEnabled() ? IDS_HM_SCHED_OFF : IDS_HM_SCHED_ON); + const CString &schedonoff(GetResString(thePrefs.IsSchedulerEnabled() ? IDS_HM_SCHED_OFF : IDS_HM_SCHED_ON)); scheduler.AppendMenu(MF_STRING, MP_HM_SCHEDONOFF, schedonoff); if (theApp.scheduler->GetCount() > 0) { @@ -2837,6 +2858,7 @@ void CemuleDlg::DestroySplash() { if (m_pSplashWnd != NULL) { m_pSplashWnd->EndDialog(IDOK); //deletes the dialog + delete m_pSplashWnd; m_pSplashWnd = NULL; } #ifdef _BETA @@ -2872,9 +2894,9 @@ BOOL CemuleApp::IsIdleMessage(MSG *pMsg) if (pMsg->message == WM_TIMER) { // Allow this WM_TIMER message to trigger idle processing only if we did not do so // since some seconds. - DWORD dwNow = ::GetTickCount(); - if (dwNow >= s_dwLastIdleMessage + SEC2MS(5)) { - s_dwLastIdleMessage = dwNow; + const DWORD curTick = ::GetTickCount(); + if (curTick >= s_dwLastIdleMessage + SEC2MS(5)) { + s_dwLastIdleMessage = curTick; return TRUE;// Request idle processing (will send a WM_KICKIDLE) } return FALSE; // No idle processing @@ -3129,18 +3151,18 @@ LRESULT CemuleDlg::OnPeerCacheResponse(WPARAM wParam, LPARAM lParam) void CemuleDlg::CreateToolbarCmdIconMap() { - m_mapTbarCmdToIcon.SetAt(TBBTN_CONNECT, _T("Connect")); - m_mapTbarCmdToIcon.SetAt(TBBTN_KAD, _T("Kademlia")); - m_mapTbarCmdToIcon.SetAt(TBBTN_SERVER, _T("Server")); - m_mapTbarCmdToIcon.SetAt(TBBTN_TRANSFERS, _T("Transfer")); - m_mapTbarCmdToIcon.SetAt(TBBTN_SEARCH, _T("Search")); - m_mapTbarCmdToIcon.SetAt(TBBTN_SHARED, _T("SharedFiles")); - m_mapTbarCmdToIcon.SetAt(TBBTN_MESSAGES, _T("Messages")); - m_mapTbarCmdToIcon.SetAt(TBBTN_IRC, _T("IRC")); - m_mapTbarCmdToIcon.SetAt(TBBTN_STATS, _T("Statistics")); - m_mapTbarCmdToIcon.SetAt(TBBTN_OPTIONS, _T("Preferences")); - m_mapTbarCmdToIcon.SetAt(TBBTN_TOOLS, _T("Tools")); - m_mapTbarCmdToIcon.SetAt(TBBTN_HELP, _T("Help")); + m_mapTbarCmdToIcon[TBBTN_CONNECT] = _T("Connect"); + m_mapTbarCmdToIcon[TBBTN_KAD] = _T("Kademlia"); + m_mapTbarCmdToIcon[TBBTN_SERVER] = _T("Server"); + m_mapTbarCmdToIcon[TBBTN_TRANSFERS] = _T("Transfer"); + m_mapTbarCmdToIcon[TBBTN_SEARCH] = _T("Search"); + m_mapTbarCmdToIcon[TBBTN_SHARED] = _T("SharedFiles"); + m_mapTbarCmdToIcon[TBBTN_MESSAGES] = _T("Messages"); + m_mapTbarCmdToIcon[TBBTN_IRC] = _T("IRC"); + m_mapTbarCmdToIcon[TBBTN_STATS] = _T("Statistics"); + m_mapTbarCmdToIcon[TBBTN_OPTIONS] = _T("Preferences"); + m_mapTbarCmdToIcon[TBBTN_TOOLS] = _T("Tools"); + m_mapTbarCmdToIcon[TBBTN_HELP] = _T("Help"); } LPCTSTR CemuleDlg::GetIconFromCmdId(UINT uId) @@ -3183,27 +3205,26 @@ BOOL CemuleDlg::OnChevronPushed(UINT id, LPNMHDR pNMHDR, LRESULT *plResult) CTitleMenu menu; menu.CreatePopupMenu(); menu.AddMenuTitle(_T("eMule"), true); + + TBBUTTONINFO tbbi; + tbbi.cbSize = (UINT)sizeof tbbi; + tbbi.dwMask = TBIF_BYINDEX | TBIF_COMMAND | TBIF_STYLE | TBIF_STATE | TBIF_TEXT; + for (; i < iButtons; ++i) { TCHAR szString[256]; - szString[0] = _T('\0'); - TBBUTTONINFO tbbi = {}; - tbbi.cbSize = (UINT)sizeof tbbi; - tbbi.dwMask = TBIF_BYINDEX | TBIF_COMMAND | TBIF_STYLE | TBIF_STATE | TBIF_TEXT; tbbi.cchText = _countof(szString); tbbi.pszText = szString; - if (toolbar->GetButtonInfo(i, &tbbi) != -1) { + if (toolbar->GetButtonInfo(i, &tbbi) >= 0) { szString[_countof(szString) - 1] = _T('\0'); if (tbbi.fsStyle & TBSTYLE_SEP) { if (!bLastMenuItemIsSep) bLastMenuItemIsSep = menu.AppendMenu(MF_SEPARATOR, 0, (LPCTSTR)NULL); - } else { - if (szString[0] != _T('\0') && menu.AppendMenu(MF_STRING, tbbi.idCommand, szString, GetIconFromCmdId(tbbi.idCommand))) { - bLastMenuItemIsSep = FALSE; - if (tbbi.fsState & TBSTATE_CHECKED) - menu.CheckMenuItem(tbbi.idCommand, MF_BYCOMMAND | MF_CHECKED); - if ((tbbi.fsState & TBSTATE_ENABLED) == 0) - menu.EnableMenuItem(tbbi.idCommand, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); - } + } else if (*szString && menu.AppendMenu(MF_STRING, tbbi.idCommand, szString, GetIconFromCmdId(tbbi.idCommand))) { + bLastMenuItemIsSep = FALSE; + if (tbbi.fsState & TBSTATE_CHECKED) + menu.CheckMenuItem(tbbi.idCommand, MF_BYCOMMAND | MF_CHECKED); + if ((tbbi.fsState & TBSTATE_ENABLED) == 0) + menu.EnableMenuItem(tbbi.idCommand, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); } } } @@ -3240,13 +3261,13 @@ INT_PTR CemuleDlg::ShowPreferences(UINT uStartPageID) LRESULT CemuleDlg::OnWebAddDownloads(WPARAM wParam, LPARAM lParam) { - CString link((TCHAR*)wParam); - if (link.GetLength() == 32 && link.Left(4).CompareNoCase(_T("ed2k")) != 0) { - uchar fileid[16]; + const CString link((LPCTSTR)wParam); + if (link.GetLength() == 32 && _tcsnicmp(link, _T("ed2k"), 4) != 0) { + uchar fileid[MDX_DIGEST_SIZE]; DecodeBase16(link, link.GetLength(), fileid, _countof(fileid)); theApp.searchlist->AddFileToDownloadByHash(fileid, (uint8)lParam); } else - theApp.AddEd2kLinksToDownload((LPCTSTR)wParam, (int)lParam); + theApp.AddEd2kLinksToDownload(link, (int)lParam); return 0; } @@ -3322,7 +3343,6 @@ LRESULT CemuleDlg::OnWebGUIInteraction(WPARAM wParam, LPARAM lParam) } else AddLogLine(true, GetResString(IDS_WEB_REBOOT) + _T(' ') + GetResString(IDS_ACCESSDENIED)); break; - case WEBGUIIA_UPD_CATTABS: theApp.emuledlg->transferwnd->UpdateCatTabTitles(); break; @@ -3348,23 +3368,18 @@ LRESULT CemuleDlg::OnWebGUIInteraction(WPARAM wParam, LPARAM lParam) if (lParam != 1) // !ED2K Kademlia::CKademlia::Stop(); break; - case WEBGUIIA_SERVER_REMOVE: serverwnd->serverlistctrl.RemoveServer(reinterpret_cast(lParam)); break; - case WEBGUIIA_SHARED_FILES_RELOAD: theApp.sharedfiles->Reload(); break; - case WEBGUIIA_ADD_TO_STATIC: serverwnd->serverlistctrl.StaticServerFileAppend(reinterpret_cast(lParam)); break; - case WEBGUIIA_REMOVE_FROM_STATIC: serverwnd->serverlistctrl.StaticServerFileRemove(reinterpret_cast(lParam)); break; - case WEBGUIIA_UPDATESERVERMETFROMURL: theApp.emuledlg->serverwnd->UpdateServerMetFromURL((TCHAR*)lParam); break; @@ -3376,11 +3391,11 @@ LRESULT CemuleDlg::OnWebGUIInteraction(WPARAM wParam, LPARAM lParam) break; case WEBGUIIA_KAD_BOOTSTRAP: { - CString dest((TCHAR*)lParam); - int pos = dest.Find(_T(':')); + CString ip((LPCTSTR)lParam); + int pos = ip.Find(_T(':')); if (pos >= 0) { - uint16 port = (uint16)_tstoi(dest.Right(dest.GetLength() - pos - 1)); - const CString &ip = dest.Left(pos); + uint16 port = (uint16)_tstoi(CPTR(ip, pos + 1)); + ip.Truncate(pos); Kademlia::CKademlia::Bootstrap(ip, port); } } @@ -3504,8 +3519,9 @@ void CemuleDlg::StartUPnP(bool bReset, uint16 nForceTCPPort, uint16 nForceUDPPor , (nForceUDPPort ? nForceUDPPort : thePrefs.GetUDPPort()) , (thePrefs.GetWSUseUPnP() ? thePrefs.GetWSPort() : 0)); } else - theApp.emuledlg->PostMessage(UM_UPNP_RESULT, (WPARAM)CUPnPImpl::UPNP_FAILED, 0); + /*theApp.emuledlg->*/PostMessage(UM_UPNP_RESULT, (WPARAM)CUPnPImpl::UPNP_FAILED, 0); } catch (const CUPnPImpl::UPnPError&) { + //ignore } catch (CException *e) { e->Delete(); } @@ -3546,7 +3562,7 @@ BOOL CemuleDlg::OnDeviceChange(UINT nEventType, DWORD_PTR dwData) // // WM_DEVICECHANGE is *NOT* sent for: // Floppy disk drives - // ZIP disk drives (although Windows Explorer recognizes a changed media, we do not get a message) + // ZIP disk drives (although Windows Explorer recognises a changed media, we do not get a message) // CD-ROM drives (although MSDN says different...) // if ((nEventType == DBT_DEVICEARRIVAL || nEventType == DBT_DEVICEREMOVECOMPLETE) && !IsBadReadPtr((void*)dwData, sizeof(DEV_BROADCAST_HDR))) { @@ -3588,6 +3604,12 @@ BOOL CemuleDlg::OnDeviceChange(UINT nEventType, DWORD_PTR dwData) return __super::OnDeviceChange(nEventType, dwData); } +LRESULT CemuleDlg::OnDisplayChange(WPARAM, LPARAM) +{ + TrayReset(); + return 0; +} + ////////////////////////////////////////////////////////////////// // Windows 7 GUI goodies @@ -3637,8 +3659,7 @@ void CemuleDlg::UpdateThumbBarButtons(bool initialAddToDlg) } // set tooltips in widechar if (uid) { - CString tooltip(GetResString(uid)); - tooltip.Remove('&'); + const CString &tooltip(GetResNoAmp(uid)); wcscpy(m_thbButtons[i].szTip, tooltip); m_thbButtons[i].dwMask |= THB_TOOLTIP; } @@ -3654,7 +3675,7 @@ void CemuleDlg::UpdateThumbBarButtons(bool initialAddToDlg) ::DestroyIcon(m_thbButtons[i].hIcon); } -// Handle pressed thumbbar button +// Handle thumbbar buttons void CemuleDlg::OnTBBPressed(UINT id) { switch (id) { @@ -3675,11 +3696,11 @@ void CemuleDlg::OnTBBPressed(UINT id) } } -// When Windows tells us, the taskbarbutton was created, it is safe to initialize our taskbar stuff +// When Windows tells us, the taskbar button was created, it is safe to initialize our taskbar stuff LRESULT CemuleDlg::OnTaskbarBtnCreated(WPARAM, LPARAM) { // Sanity check that the OS is Win 7 or later - if (!theApp.IsClosing() && thePrefs.GetWindowsVersion() >= _WINVER_7_) { + if (thePrefs.GetWindowsVersion() >= _WINVER_7_ && !theApp.IsClosing()) { if (m_pTaskbarList) m_pTaskbarList.Release(); diff --git a/srchybrid/EmuleDlg.h b/srchybrid/EmuleDlg.h index e974bcba..9a243099 100644 --- a/srchybrid/EmuleDlg.h +++ b/srchybrid/EmuleDlg.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -65,15 +65,19 @@ class CemuleDlg : public CTrayDialog IDD = IDD_EMULE_DIALOG }; + //Client icons for all windows + CImageList m_IconList; + void SetClientIconList(); public: explicit CemuleDlg(CWnd *pParent = NULL); ~CemuleDlg(); + CImageList& GetClientIconList(); void ShowConnectionState(); void ShowNotifier(LPCTSTR pszText, TbnMsg nMsgType, LPCTSTR pszLink = NULL, bool bForceSoundOFF = false); void SendNotificationMail(TbnMsg nMsgType, LPCTSTR pszText); void ShowUserCount(); - void ShowMessageState(UINT iconnr); + void ShowMessageState(UINT nIcon); void SetActiveDialog(CWnd *dlg); CWnd* GetActiveDialog() const { return activewnd; } void ShowTransferRate(bool bForceAll = false); @@ -130,8 +134,8 @@ class CemuleDlg : public CTrayDialog void RefreshUPnP(bool bRequestAnswer = false); HBRUSH GetCtlColor(CDC*, CWnd*, UINT); - virtual void OnTrayRButtonUp(CPoint); - virtual void OnTrayLButtonUp(CPoint pt); + virtual void OnTrayRButtonUp(CPoint pt); + virtual void OnTrayLButtonUp(); virtual void TrayMinimizeToTrayChange(); virtual void RestoreWindow(); virtual void HtmlHelp(DWORD_PTR dwData, UINT nCmd = 0x000F); @@ -265,6 +269,7 @@ class CemuleDlg : public CTrayDialog afx_msg void OnShowWindow(BOOL bShow, UINT nStatus); afx_msg BOOL OnChevronPushed(UINT id, LPNMHDR pNMHDR, LRESULT *plResult); afx_msg LRESULT OnPowerBroadcast(WPARAM wParam, LPARAM lParam); + afx_msg LRESULT OnDisplayChange(WPARAM, LPARAM); // quick-speed changer -- based on xrmb afx_msg void QuickSpeedUpload(UINT nID); @@ -297,19 +302,14 @@ class CemuleDlg : public CTrayDialog afx_msg LRESULT OnWebAddDownloads(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnWebSetCatPrio(WPARAM wParam, LPARAM lParam); afx_msg LRESULT OnAddRemoveFriend(WPARAM wParam, LPARAM lParam); - // VersionCheck DNS afx_msg LRESULT OnVersionCheckResponse(WPARAM, LPARAM lParam); - // Peercache DNS afx_msg LRESULT OnPeerCacheResponse(WPARAM wParam, LPARAM lParam); - // MiniMule afx_msg LRESULT OnCloseMiniMule(WPARAM wParam, LPARAM); - // Terminal Services afx_msg LRESULT OnConsoleThreadEvent(WPARAM wParam, LPARAM lParam); - // UPnP afx_msg LRESULT OnUPnPResult(WPARAM wParam, LPARAM lParam); }; diff --git a/srchybrid/EnBitmap.cpp b/srchybrid/EnBitmap.cpp index 0fd7984b..60c053e5 100644 --- a/srchybrid/EnBitmap.cpp +++ b/srchybrid/EnBitmap.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -38,19 +38,18 @@ BOOL CEnBitmap::LoadImage(UINT uIDRes, LPCTSTR pszResourceType, HMODULE hInst, C BOOL CEnBitmap::LoadImage(LPCTSTR lpszResourceName, LPCTSTR szResourceType, HMODULE hInst, COLORREF crBack) { - ASSERT(m_hObject == NULL); // only attach once, detach on destroy - - if (m_hObject != NULL) + if (m_hObject != NULL) { // only attach once, detach on destroy + ASSERT(0); return FALSE; + } - int nSize = 0; BOOL bResult = FALSE; // first call is to get buffer size + int nSize; if (GetResource(lpszResourceName, szResourceType, hInst, 0, nSize)) { if (nSize > 0) { BYTE *pBuff = new BYTE[nSize]; - // this loads it if (GetResource(lpszResourceName, szResourceType, hInst, pBuff, nSize)) { IPicture *pPicture = LoadFromBuffer(pBuff, nSize); @@ -70,34 +69,23 @@ BOOL CEnBitmap::LoadImage(LPCTSTR lpszResourceName, LPCTSTR szResourceType, HMOD BOOL CEnBitmap::LoadImage(LPCTSTR szImagePath, COLORREF crBack) { - ASSERT(m_hObject == NULL); // only attach once, detach on destroy - - if (m_hObject != NULL) + if (m_hObject != NULL) { // only attach once, detach on destroy + ASSERT(0); return FALSE; - - // If GDI+ is available, use that API because it supports more file formats and images with alpha channels. - // That DLL is installed with WinXP is available as redistributable from Microsoft for Win98+. As this DLL - // may not be available on some OS but we have to link statically to it, we have to take some special care. - // - extern bool g_bGdiPlusInstalled; - if (g_bGdiPlusInstalled) { - CImage img; - if (SUCCEEDED(img.Load(szImagePath))) { - CBitmap::Attach(img.Detach()); - return TRUE; - } } - BOOL bResult = FALSE; - CFile cFile; - CFileException e; + CImage img; + if (SUCCEEDED(img.Load(szImagePath))) + return CBitmap::Attach(img.Detach()); + BOOL bResult = FALSE; + CFileException e; + CFile cFile; if (cFile.Open(szImagePath, CFile::modeRead | CFile::typeBinary | CFile::shareDenyWrite, &e)) { int nSize = (int)cFile.GetLength(); BYTE *pBuff = new BYTE[nSize]; if (cFile.Read(pBuff, nSize) > 0) { IPicture *pPicture = LoadFromBuffer(pBuff, nSize); - if (pPicture) { bResult = Attach(pPicture, crBack); pPicture->Release(); @@ -105,7 +93,6 @@ BOOL CEnBitmap::LoadImage(LPCTSTR szImagePath, COLORREF crBack) } delete[] pBuff; } - return bResult; } @@ -113,12 +100,12 @@ IPicture* CEnBitmap::LoadFromBuffer(BYTE *pBuff, int nSize) { IPicture *pPicture = NULL; - HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, nSize); + HGLOBAL hGlobal = ::GlobalAlloc(GMEM_MOVEABLE, nSize); if (hGlobal != NULL) { - void *pData = GlobalLock(hGlobal); + void *pData = ::GlobalLock(hGlobal); if (pData != NULL) { memcpy(pData, pBuff, nSize); - GlobalUnlock(hGlobal); + ::GlobalUnlock(hGlobal); IStream *pStream = NULL; if (CreateStreamOnHGlobal(hGlobal, TRUE/*fDeleteOnRelease*/, &pStream) == S_OK) { @@ -130,9 +117,9 @@ IPicture* CEnBitmap::LoadFromBuffer(BYTE *pBuff, int nSize) VERIFY(OleLoadPicture(pStream, nSize, TRUE/*FALSE*/, IID_IPicture, (LPVOID*)&pPicture) == S_OK); pStream->Release(); } else - GlobalFree(hGlobal); + ::GlobalFree(hGlobal); } else - GlobalFree(hGlobal); + ::GlobalFree(hGlobal); } return pPicture; // caller releases @@ -140,35 +127,27 @@ IPicture* CEnBitmap::LoadFromBuffer(BYTE *pBuff, int nSize) BOOL CEnBitmap::GetResource(LPCTSTR lpName, LPCTSTR lpType, HMODULE hInst, void *pResource, int &nBufSize) { - HRSRC hResInfo; - HANDLE hRes; - LPSTR lpRes = NULL; - bool bResult = FALSE; - // Find the resource - hResInfo = FindResource(hInst, lpName, lpType); - + HRSRC hResInfo = FindResource(hInst, lpName, lpType); if (hResInfo == NULL) - return false; + return FALSE; // Load the resource - hRes = LoadResource(hInst, hResInfo); - + HANDLE hRes = LoadResource(hInst, hResInfo); if (hRes == NULL) - return false; + return FALSE; - // Lock the resource - lpRes = (char*)LockResource(hRes); + bool bResult = FALSE; + // Lock the resource + LPCSTR lpRes = (LPCSTR)LockResource(hRes); if (lpRes != NULL) { if (pResource == NULL) { nBufSize = SizeofResource(hInst, hResInfo); - bResult = true; - } else { - if (nBufSize >= (int)SizeofResource(hInst, hResInfo)) { - memcpy(pResource, lpRes, nBufSize); - bResult = true; - } + bResult = TRUE; + } else if (nBufSize >= (int)SizeofResource(hInst, hResInfo)) { + memcpy(pResource, lpRes, nBufSize); + bResult = TRUE; } UnlockResource(hRes); @@ -215,7 +194,8 @@ BOOL CEnBitmap::Attach(IPicture *pPicture, COLORREF crBack) HRESULT hr = pPicture->Render(dcMem, 0, 0, nWidth, nHeight, 0, hmHeight, hmWidth, -hmHeight, NULL); dcMem.SelectObject(pOldBM); - bResult = (hr == S_OK) && CBitmap::Attach(bmMem.Detach()); + if (hr == S_OK) + bResult = CBitmap::Attach(bmMem.Detach()); } } diff --git a/srchybrid/EnBitmap.h b/srchybrid/EnBitmap.h index 896ee5e0..66edc661 100644 --- a/srchybrid/EnBitmap.h +++ b/srchybrid/EnBitmap.h @@ -4,7 +4,6 @@ class CEnBitmap : public CBitmap { public: CEnBitmap() = default; - virtual ~CEnBitmap() = default; BOOL LoadImage(LPCTSTR szImagePath, COLORREF crBack = 0); BOOL LoadImage(UINT uIDRes, LPCTSTR pszResourceType, HMODULE hInst = NULL, COLORREF crBack = 0); diff --git a/srchybrid/EncryptedDatagramSocket.cpp b/srchybrid/EncryptedDatagramSocket.cpp index c9378d83..fa477957 100644 --- a/srchybrid/EncryptedDatagramSocket.cpp +++ b/srchybrid/EncryptedDatagramSocket.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -110,7 +110,7 @@ #include "safefile.h" #include "kademlia/kademlia/prefs.h" #include "kademlia/kademlia/kademlia.h" -#include +#include "cryptopp/osrng.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -118,7 +118,7 @@ static char THIS_FILE[] = __FILE__; #endif -#define CRYPT_HEADER_PADDING 0 // padding is currently disabled for UDP; the length in low 4 bits +#define CRYPT_HEADER_PADDING 0 // padding is currently disabled for UDP; the length in low 4 bits (0 - 15) #pragma pack(push, 1) struct Crypt_Header_Struct @@ -198,7 +198,7 @@ int CEncryptedDatagramSocket::DecryptReceivedClient(BYTE *pbyBufIn, int nBufLen, bKadRecvKeyUsed = false; if (Kademlia::CKademlia::GetPrefs()) { uchar achKeyData[18]; - memcpy(achKeyData, Kademlia::CKademlia::GetPrefs()->GetKadID().GetData(), 16); + md4cpy(achKeyData, Kademlia::CKademlia::GetPrefs()->GetKadID().GetData()); PokeUInt16(&achKeyData[16], crypt.wRandomKeyPart); // random key part sent from remote client md5.Calculate(achKeyData, sizeof achKeyData); } @@ -239,13 +239,15 @@ int CEncryptedDatagramSocket::DecryptReceivedClient(BYTE *pbyBufIn, int nBufLen, // debug output notices // the following cases are "allowed" but shouldn't happen given that there is only our implementation yet if (bKad) { - LPCTSTR p = NULL; + LPCTSTR p; if (crypt.byProtocol & 0x01) p = _T("ed2k bit"); else if (!bKadRecvKeyUsed && (crypt.byProtocol & 0x02)) p = _T("nodeid key, recvkey"); else if (bKadRecvKeyUsed && !(crypt.byProtocol & 0x02)) p = _T("recvkey key, nodeid"); + else + p = NULL; if (p) DebugLog(_T("Received obfuscated UDP packet from clientIP: %s with wrong key marker bits (kad packet, %s bit)"), (LPCTSTR)ipstr(dwIP), p); } @@ -253,7 +255,7 @@ int CEncryptedDatagramSocket::DecryptReceivedClient(BYTE *pbyBufIn, int nBufLen, nResult -= CRYPT_HEADER_WITHOUTPADDING; crypt.byPadding[0] &= 0xf; if (nResult <= crypt.byPadding[0]) { - DebugLogError(_T("Invalid obfuscated UDP packet from clientIP: %s, Paddingsize (%u) larger than received bytes"), (LPCTSTR)ipstr(dwIP), crypt.byPadding[0]); + DebugLogError(_T("Invalid obfuscated UDP packet from clientIP: %s, Padding size (%u) larger than received bytes"), (LPCTSTR)ipstr(dwIP), crypt.byPadding[0]); return nBufLen; // pass through, let the Receive function do the error handling on this junk } if (crypt.byPadding[0] > 0) { @@ -289,11 +291,11 @@ uint32 CEncryptedDatagramSocket::EncryptSendClient(uchar *pbyBuf, uint32 nBufLen { ASSERT(theApp.GetPublicIP() != 0 || bKad); ASSERT(thePrefs.IsClientCryptLayerSupported()); - ASSERT(pachClientHashOrKadID != NULL || nReceiverVerifyKey != 0); + ASSERT(pachClientHashOrKadID != NULL || nReceiverVerifyKey); ASSERT((nReceiverVerifyKey == 0 && nSenderVerifyKey == 0) || bKad); uint8 byKadRecKeyUsed = 0; //nodeid marker - const uint16 nRandomKeyPart = (uint16)cryptRandomGen.GenerateWord32(0x0000, 0xFFFFu); + const uint16 nRandomKeyPart = (uint16)cryptRandomGen.GenerateWord32(0, _UI16_MAX); MD5Sum md5; if (bKad) { if ((pachClientHashOrKadID == NULL || isnulmd4(pachClientHashOrKadID)) && nReceiverVerifyKey != 0) { @@ -331,7 +333,7 @@ uint32 CEncryptedDatagramSocket::EncryptSendClient(uchar *pbyBuf, uint32 nBufLen if (bKad) { bySemiRandomNotProtocolMarker &= ~3; // clear marker bits bySemiRandomNotProtocolMarker |= byKadRecKeyUsed; //set kad reckey/nodeid marker bit - } else + } else bySemiRandomNotProtocolMarker |= 1; // set the ed2k marker bit switch (bySemiRandomNotProtocolMarker) { @@ -357,8 +359,10 @@ uint32 CEncryptedDatagramSocket::EncryptSendClient(uchar *pbyBuf, uint32 nBufLen crypt.wRandomKeyPart = nRandomKeyPart; crypt.dwMagic = MAGICVALUE_UDP_SYNC_CLIENT; crypt.byPadding[0] = CRYPT_HEADER_PADDING; - for (int i = CRYPT_HEADER_PADDING; i > 0; --i) - crypt.byPadding[i] = (uchar)rand(); // they actually don't really need to be random, but it doesn't hurt either +#if (CRYPT_HEADER_PADDING > 0) + memset(&crypt.byPadding[1], nRandomKeyPart, CRYPT_HEADER_PADDING); + RC4Crypt(&crypt.byPadding[1], CRYPT_HEADER_PADDING, &keySendKey); +#endif if (bKad) { crypt.dwReceiverKey = nReceiverVerifyKey; crypt.dwSenderKey = nSenderVerifyKey; @@ -372,7 +376,7 @@ uint32 CEncryptedDatagramSocket::EncryptSendClient(uchar *pbyBuf, uint32 nBufLen return nBufLen; } -int CEncryptedDatagramSocket::DecryptReceivedServer(BYTE *pbyBufIn, int nBufLen, BYTE **ppbyBufOut, uint32 dwBaseKey, uint32 dbgIP) +int CEncryptedDatagramSocket::DecryptReceivedServer(BYTE *pbyBufIn, int nBufLen, BYTE **ppbyBufOut, uint32 dwBaseKey, const SOCKADDR_IN &dbgIP) { int nResult = nBufLen; *ppbyBufOut = pbyBufIn; @@ -397,12 +401,13 @@ int CEncryptedDatagramSocket::DecryptReceivedServer(BYTE *pbyBufIn, int nBufLen, if (crypt.dwMagic == MAGICVALUE_UDP_SYNC_SERVER) { // yup this is an encrypted packet if (thePrefs.GetDebugServerUDPLevel() > 0) - DEBUG_ONLY(DebugLog(_T("Received obfuscated UDP packet from ServerIP: %s"), (LPCTSTR)ipstr(dbgIP))); + DEBUG_ONLY(DebugLog(_T("Received obfuscated UDP packet from ServerIP: %s:%u"), (LPCTSTR)ipstr(dbgIP.sin_addr.s_addr), ntohs(dbgIP.sin_port))); RC4Crypt((uchar*)crypt.byPadding, 1, &keyReceiveKey); crypt.byPadding[0] &= 0xf; nResult -= CRYPT_HEADER_WITHOUTPADDING; if (nResult <= crypt.byPadding[0]) { - DebugLogError(_T("Invalid obfuscated UDP packet from ServerIP: %s, Padding size (%u) larger than received bytes"), (LPCTSTR)ipstr(dbgIP), crypt.byPadding[0]); + DebugLogError(_T("Invalid obfuscated UDP packet from Server IP=%s:%u, Padding size (%u) larger than received bytes") + , (LPCTSTR)ipstr(dbgIP.sin_addr.s_addr), ntohs(dbgIP.sin_port), crypt.byPadding[0]); return nBufLen; // pass through, let the Receive function do the error handling on this junk } if (crypt.byPadding[0] > 0) { @@ -414,16 +419,17 @@ int CEncryptedDatagramSocket::DecryptReceivedServer(BYTE *pbyBufIn, int nBufLen, theStats.AddDownDataOverheadCrypt(nBufLen - nResult); } else // pass through, let the Receive function do the error handling on this junk - DebugLogWarning(_T("Obfuscated packet expected but magicvalue mismatch on UDP packet from ServerIP: %s"), (LPCTSTR)ipstr(dbgIP)); + DebugLogWarning(_T("Obfuscated packet expected, but magicvalue mismatch on UDP packet from Server IP=%s:%u") + , (LPCTSTR)ipstr(dbgIP.sin_addr.s_addr), ntohs(dbgIP.sin_port)); return nResult; } uint32 CEncryptedDatagramSocket::EncryptSendServer(uchar *pbyBuf, uint32 nBufLen, uint32 dwBaseKey) { ASSERT(thePrefs.IsServerCryptLayerUDPEnabled()); - ASSERT(dwBaseKey != 0); + ASSERT(dwBaseKey); - const uint16 nRandomKeyPart = (uint16)cryptRandomGen.GenerateWord32(0x0000, 0xFFFFu); + const uint16 nRandomKeyPart = (uint16)cryptRandomGen.GenerateWord32(0, _UI16_MAX); uchar achKeyData[7]; PokeUInt32(achKeyData, dwBaseKey); @@ -451,8 +457,10 @@ uint32 CEncryptedDatagramSocket::EncryptSendServer(uchar *pbyBuf, uint32 nBufLen crypt.wRandomKeyPart = nRandomKeyPart; crypt.dwMagic = MAGICVALUE_UDP_SYNC_SERVER; crypt.byPadding[0] = CRYPT_HEADER_PADDING; - for (int i = CRYPT_HEADER_PADDING; i > 0; --i) - crypt.byPadding[i] = (uchar)rand(); // padding don't really need to be random, but it doesn't hurt either +#if (CRYPT_HEADER_PADDING > 0) + memset(&crypt.byPadding[1], nRandomKeyPart , CRYPT_HEADER_PADDING); + RC4Crypt(&crypt.byPadding[1], CRYPT_HEADER_PADDING, &keySendKey); +#endif const uint32 nCryptHeaderLen = EncryptOverheadSize(false); nBufLen += nCryptHeaderLen; diff --git a/srchybrid/EncryptedDatagramSocket.h b/srchybrid/EncryptedDatagramSocket.h index ffb42463..f92b6f97 100644 --- a/srchybrid/EncryptedDatagramSocket.h +++ b/srchybrid/EncryptedDatagramSocket.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -26,7 +26,7 @@ class CEncryptedDatagramSocket static int DecryptReceivedClient(BYTE *pbyBufIn, int nBufLen, BYTE **ppbyBufOut, uint32 dwIP, uint32 *nReceiverVerifyKey, uint32 *nSenderVerifyKey); static uint32 EncryptSendClient(uchar *pbyBuf, uint32 nBufLen, const uchar *pachClientHashOrKadID, bool bKad, uint32 nReceiverVerifyKey, uint32 nSenderVerifyKey); - static int DecryptReceivedServer(BYTE *pbyBufIn, int nBufLen, BYTE **ppbyBufOut, uint32 dwBaseKey, uint32 dbgIP); + static int DecryptReceivedServer(BYTE *pbyBufIn, int nBufLen, BYTE **ppbyBufOut, uint32 dwBaseKey, const SOCKADDR_IN &dbgIP); static uint32 EncryptSendServer(uchar *pbyBuf, uint32 nBufLen, uint32 dwBaseKey); static int EncryptOverheadSize(bool bKad); diff --git a/srchybrid/EncryptedStreamSocket.cpp b/srchybrid/EncryptedStreamSocket.cpp index 1ec89352..598c751a 100644 --- a/srchybrid/EncryptedStreamSocket.cpp +++ b/srchybrid/EncryptedStreamSocket.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -41,9 +41,9 @@ - Additional Comments: - RandomKeyPart is needed to make multiple connections between two clients look different (but still random), since otherwise the same key would be used and RC4 would create the same output. Since the key is a MD5 hash it doesn't weaken the key if that part is known - - Why DH-KeyAgreement isn't used as basic obfuscation key: It doesn't offers substantial more protection against passive connection based protocol identification, it has about 200 bytes more overhead, + - Why DH-KeyAgreement isn't used as basic obfuscation key: It doesn't offer substantial more protection against passive connection based protocol identification, it has about 200 bytes more overhead, needs more CPU time, we cannot say if the received data is junk, unencrypted or part of the key agreement before the handshake is finished without losing the complete randomness, - it doesn't offers substantial protection against eavesdropping without added authentication + it doesn't offer substantial protection against eavesdropping without added authentication Basic Obfuscated Handshake Protocol Client <-> Server: - RC4 Key creation: @@ -84,7 +84,7 @@ Basic Obfuscated Handshake Protocol Client <-> Server: #include "opcodes.h" #include "clientlist.h" #include "ServerConnect.h" -#include +#include "cryptopp/osrng.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -189,11 +189,11 @@ int CEncryptedStreamSocket::Send(const void *lpBuf, int nBufLen, int nFlags) return CAsyncSocketEx::Send(lpBuf, nBufLen, nFlags); } -int CEncryptedStreamSocket::SendOv(CArray &raBuffer, LPWSAOVERLAPPED lpOverlapped) +int CEncryptedStreamSocket::SendOv(CArray &aBuffer, LPWSAOVERLAPPED lpOverlapped) { if (!IsEncryptionLayerReady()) { ASSERT(0); // must be a bug - return -1; + return SOCKET_ERROR; } if (m_bServerCrypt && m_StreamCryptState == ECS_ENCRYPTING && m_pfiSendBuffer != NULL) { ASSERT(m_NegotiatingState == ONS_BASIC_SERVER_DELAYEDSENDING); @@ -203,7 +203,7 @@ int CEncryptedStreamSocket::SendOv(CArray &raBuffer, LPWSAOVERLAPPED lpO wbuf.buf = new CHAR[wbuf.len]; m_pfiSendBuffer->SeekToBegin(); m_pfiSendBuffer->Read(wbuf.buf, wbuf.len); - raBuffer.InsertAt(0, wbuf); + aBuffer.InsertAt(0, wbuf); m_NegotiatingState = ONS_COMPLETE; delete m_pfiSendBuffer; m_pfiSendBuffer = NULL; @@ -216,7 +216,8 @@ int CEncryptedStreamSocket::SendOv(CArray &raBuffer, LPWSAOVERLAPPED lpO m_StreamCryptState = ECS_NONE; DebugLogError(_T("CEncryptedStreamSocket: Overwriting State ECS_UNKNOWN with ECS_NONE because of premature Send() (%s)"), (LPCTSTR)DbgGetIPString()); } - return WSASend(GetSocketHandle(), raBuffer.GetData(), (DWORD)raBuffer.GetCount(), NULL, 0, lpOverlapped, NULL); + + return WSASend(GetSocketHandle(), aBuffer.GetData(), (DWORD)aBuffer.GetCount(), NULL, 0, lpOverlapped, NULL); } bool CEncryptedStreamSocket::IsEncryptionLayerReady() diff --git a/srchybrid/EncryptedStreamSocket.h b/srchybrid/EncryptedStreamSocket.h index f94dde49..6217af3b 100644 --- a/srchybrid/EncryptedStreamSocket.h +++ b/srchybrid/EncryptedStreamSocket.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -25,7 +25,7 @@ #pragma once #include "AsyncSocketEx.h" -#include +#include "cryptopp/integer.h" #define ERR_WRONGHEADER 0x01 #define ERR_TOOBIG 0x02 @@ -94,7 +94,7 @@ class CEncryptedStreamSocket : public CAsyncSocketEx uint8 m_dbgbyEncryptionMethodSet; protected: - int SendOv(CArray &raBuffer, LPWSAOVERLAPPED lpOverlapped); + int SendOv(CArray &aBuffer, LPWSAOVERLAPPED lpOverlapped); virtual void OnError(int nErrorCode) = 0; CString DbgGetIPString(); void CryptPrepareSendData(uchar *pBuffer, uint32 nLen); diff --git a/srchybrid/Exceptions.h b/srchybrid/Exceptions.h index 38af2974..a1c7ca82 100644 --- a/srchybrid/Exceptions.h +++ b/srchybrid/Exceptions.h @@ -4,7 +4,7 @@ #define CATCH_DFLT_ALL(fname) #else #define CATCH_DFLT_ALL(fname) \ - catch(...){ \ + catch(...) { \ if (thePrefs.GetVerbose()) \ DebugLogError(LOG_STATUSBAR, _T("Unknown exception in ") fname); \ ASSERT(0); \ diff --git a/srchybrid/ExitBox.cpp b/srchybrid/ExitBox.cpp index a5335cab..2e4ec467 100644 --- a/srchybrid/ExitBox.cpp +++ b/srchybrid/ExitBox.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/ExitBox.h b/srchybrid/ExitBox.h index f487b6f0..b1c279bc 100644 --- a/srchybrid/ExitBox.h +++ b/srchybrid/ExitBox.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -28,7 +28,6 @@ class ExitBox : public CDialog public: explicit ExitBox(CWnd *pParent = NULL); // standard constructor - virtual ~ExitBox() = default; bool WasCancelled() const { return m_cancel;} diff --git a/srchybrid/FileDetailDialog.cpp b/srchybrid/FileDetailDialog.cpp index de9d41b7..b4a8971a 100644 --- a/srchybrid/FileDetailDialog.cpp +++ b/srchybrid/FileDetailDialog.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -72,7 +72,7 @@ void UpdateFileDetailsPages(CListViewPropertySheet *pSheet } bool bFound = false; - for (int i = (int)pSheet->GetPages().GetCount(); --i >= 0;) + for (INT_PTR i = pSheet->GetPages().GetCount(); --i >= 0;) if (pSheet->GetPages()[i] == pToShow) { bFound = true; break; diff --git a/srchybrid/FileDetailDialog.h b/srchybrid/FileDetailDialog.h index 8e89c1ef..c179bdcc 100644 --- a/srchybrid/FileDetailDialog.h +++ b/srchybrid/FileDetailDialog.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -31,7 +31,6 @@ class CFileDetailDialog : public CListViewWalkerPropertySheet void Localize(); public: explicit CFileDetailDialog(const CSimpleArray *paFiles, UINT uInvokePage = 0, CListCtrlItemWalk *pListCtrl = NULL); - virtual ~CFileDetailDialog() = default; virtual BOOL OnInitDialog(); diff --git a/srchybrid/FileDetailDialogInfo.cpp b/srchybrid/FileDetailDialogInfo.cpp index e844060d..db1feb73 100644 --- a/srchybrid/FileDetailDialogInfo.cpp +++ b/srchybrid/FileDetailDialogInfo.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -83,7 +83,7 @@ BOOL CFileDetailDialogInfo::OnInitDialog() // no need to refresh data explicitly because // 'OnSetActive' will be called right after 'OnInitDialog' - + // start timer for calling 'RefreshData' VERIFY((m_timer = SetTimer(IDT_REFRESH, SEC2MS(5), NULL)) != 0); @@ -150,7 +150,7 @@ void CFileDetailDialogInfo::RefreshData() struct tm tmTemp; struct tm *ptimLastSeenComplete = file->lastseencomplete.GetLocalTm(&tmTemp); if (file->lastseencomplete == 0 || ptimLastSeenComplete == NULL) - str.Format(GetResString(IDS_NEVER)); + str = GetResString(IDS_NEVER); else { str.Format(_T("%s ") + GetResString(IDS_TIMEBEFORE) , (LPCTSTR)file->lastseencomplete.Format(thePrefs.GetDateTimeFormat()) @@ -195,32 +195,34 @@ void CFileDetailDialogInfo::RefreshData() } // file type - CString ext; - bool showwarning = false; - int pos = fname.ReverseFind(_T('.')); - if (fname.ReverseFind(_T('\\')) < pos) - ext = fname.Mid(pos + 1).MakeUpper(); + LPCTSTR pDot = ::PathFindExtension(fname); + CString szExt(pDot + static_cast(*pDot != _T('\0'))); //skip the dot + szExt.MakeUpper(); + bool showwarning = false; EFileType bycontent = GetFileTypeEx(file, false, true); if (bycontent != FILETYPE_UNKNOWN) { str.Format(_T("%s (%s)"), (LPCTSTR)GetFileTypeName(bycontent), (LPCTSTR)GetResString(IDS_VERIFIED)); - switch (IsExtensionTypeOf(bycontent, ext)) { + UINT uid; + switch (IsExtensionTypeOf(bycontent, szExt)) { case -1: showwarning = true; - str.AppendFormat(_T(" - %s: %s"), (LPCTSTR)GetResString(IDS_INVALIDFILEEXT), (LPCTSTR)ext); + uid = IDS_INVALIDFILEEXT; break; case 0: - str.AppendFormat(_T(" - %s: %s"), (LPCTSTR)GetResString(IDS_UNKNOWNFILEEXT), (LPCTSTR)ext); + uid = IDS_UNKNOWNFILEEXT; + break; + default: + uid = 0; } - } else { - // not verified - if (pos >= 0) { - str = fname.Mid(pos + 1).MakeUpper(); - str.AppendFormat(_T(" (%s)"), (LPCTSTR)GetResString(IDS_UNVERIFIED)); - } else - str = GetResString(IDS_UNKNOWN); - } + if (uid) + str.AppendFormat(_T(" - %s: %s"), (LPCTSTR)GetResString(uid), (LPCTSTR)szExt); + } else if (!szExt.IsEmpty()) + str.Format(_T("%s (%s)"), (LPCTSTR)szExt, (LPCTSTR)GetResString(IDS_UNVERIFIED)); + else + str = GetResString(IDS_UNKNOWN); + m_bShowFileTypeWarning = showwarning; SetDlgItemText(IDC_FD_X11, str); } else { @@ -302,13 +304,13 @@ void CFileDetailDialogInfo::RefreshData() SetDlgItemText(IDC_TRANSFERRED, CastItoXBytes(uTransferred)); - str.Format(_T("%s (%.1f%%)"), (LPCTSTR)CastItoXBytes(uCompleted), uFileSize != 0 ? (uCompleted * 100.0 / uFileSize) : 0.0); + str.Format(_T("%s (%.1f%%)"), (LPCTSTR)CastItoXBytes(uCompleted), (uFileSize != 0 ? uCompleted * 100.0 / uFileSize : 0.0)); SetDlgItemText(IDC_COMPLSIZE, str); - str.Format(_T("%s (%.1f%%)"), (LPCTSTR)CastItoXBytes(uCorrupted), uTransferred != 0 ? (uCorrupted * 100.0 / uTransferred) : 0.0); + str.Format(_T("%s (%.1f%%)"), (LPCTSTR)CastItoXBytes(uCorrupted), (uTransferred != 0 ? uCorrupted * 100.0 / uTransferred : 0.0)); SetDlgItemText(IDC_CORRUPTED, str); - str.Format(_T("%s (%.1f%%)"), (LPCTSTR)CastItoXBytes(uFileSize - uCompleted), uFileSize != 0 ? ((uFileSize - uCompleted) * 100.0 / uFileSize) : 0.0); + str.Format(_T("%s (%.1f%%)"), (LPCTSTR)CastItoXBytes(uFileSize - uCompleted), (uFileSize != 0 ? (uFileSize - uCompleted) * 100.0 / uFileSize : 0.0)); SetDlgItemText(IDC_REMAINING, str); str.Format(_T("%u %s"), uRecoveredParts, (LPCTSTR)GetResString(IDS_FD_PARTS)); diff --git a/srchybrid/FileDetailDialogInfo.h b/srchybrid/FileDetailDialogInfo.h index 1ca6696a..c9a238ae 100644 --- a/srchybrid/FileDetailDialogInfo.h +++ b/srchybrid/FileDetailDialogInfo.h @@ -27,7 +27,6 @@ class CFileDetailDialogInfo : public CResizablePage public: CFileDetailDialogInfo(); // standard constructor - virtual ~CFileDetailDialogInfo() = default; virtual BOOL OnInitDialog(); void SetFiles(const CSimpleArray *paFiles) { m_paFiles = paFiles; m_bDataChanged = true; } diff --git a/srchybrid/FileDetailDialogName.cpp b/srchybrid/FileDetailDialogName.cpp index 4451e5a6..55093884 100644 --- a/srchybrid/FileDetailDialogName.cpp +++ b/srchybrid/FileDetailDialogName.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -90,7 +90,7 @@ BOOL CFileDetailDialogName::OnInitDialog() m_listFileNames.LoadSettings(); m_listFileNames.SetSortArrow(); - m_listFileNames.SortItems(&CompareListNameItems, m_listFileNames.GetSortItem() + (m_listFileNames.GetSortAscending() ? 0 : 10)); + m_listFileNames.SortItems(&CompareListNameItems, MAKELONG(m_listFileNames.GetSortItem(), !m_listFileNames.GetSortAscending())); Localize(); @@ -165,7 +165,7 @@ void CFileDetailDialogName::FillSourcenameList() // update const CPartFile *file = static_cast((*m_paFiles)[0]); - for (POSITION pos = file->srclist.GetHeadPosition(); pos != NULL; ) { + for (POSITION pos = file->srclist.GetHeadPosition(); pos != NULL;) { CUpDownClient *cur_src = file->srclist.GetNext(pos); if (cur_src->GetRequestFile() != file || cur_src->GetClientFilename().IsEmpty()) continue; @@ -173,7 +173,7 @@ void CFileDetailDialogName::FillSourcenameList() info.psz = cur_src->GetClientFilename(); int itempos = m_listFileNames.FindItem(&info, -1); if (itempos == -1) { - FCtrlItem_Struct *newitem = new FCtrlItem_Struct(); + FCtrlItem_Struct *newitem = new FCtrlItem_Struct{}; newitem->count = 1; newitem->filename = cur_src->GetClientFilename(); @@ -188,7 +188,7 @@ void CFileDetailDialogName::FillSourcenameList() m_listFileNames.SetItemText(ix, 1, _T("1")); } else { FCtrlItem_Struct *item = reinterpret_cast(m_listFileNames.GetItemData(itempos)); - item->count++; + ++item->count; CString strText; strText.Format(_T("%i"), item->count); m_listFileNames.SetItemText(itempos, 1, strText); @@ -204,7 +204,7 @@ void CFileDetailDialogName::FillSourcenameList() } } - m_listFileNames.SortItems(&CompareListNameItems, m_listFileNames.GetSortItem() + (m_listFileNames.GetSortAscending() ? 0 : 10)); + m_listFileNames.SortItems(&CompareListNameItems, MAKELONG(m_listFileNames.GetSortItem(), !m_listFileNames.GetSortAscending())); } void CFileDetailDialogName::TakeOver() @@ -245,7 +245,7 @@ void CFileDetailDialogName::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) } m_listFileNames.SetSortArrow(pNMListView->iSubItem, sortAscending); - m_listFileNames.SortItems(&CompareListNameItems, pNMListView->iSubItem + (sortAscending ? 0 : 10)); + m_listFileNames.SortItems(&CompareListNameItems, MAKELONG(pNMListView->iSubItem, !sortAscending)); *pResult = 0; } @@ -256,19 +256,17 @@ int CALLBACK CFileDetailDialogName::CompareListNameItems(LPARAM lParam1, LPARAM const FCtrlItem_Struct *item2 = reinterpret_cast(lParam2); int iResult; - switch (lParamSort) { + switch (LOWORD(lParamSort)) { case 0: - case 10: iResult = CompareLocaleStringNoCase(item1->filename, item2->filename); break; case 1: - case 11: iResult = CompareUnsigned(item1->count, item2->count); break; default: - iResult = 0; + return 0; } - return (lParamSort < 10) ? iResult : -iResult; + return HIWORD(lParamSort) ? -iResult : iResult; } void CFileDetailDialogName::OnNmDblClkList(LPNMHDR, LRESULT *pResult) @@ -304,13 +302,13 @@ BOOL CFileDetailDialogName::OnCommand(WPARAM wParam, LPARAM lParam) switch (wParam) { case MP_MESSAGE: TakeOver(); - return true; + return TRUE; case MP_COPYSELECTED: Copy(); - return true; + return TRUE; case MP_RESTORE: FillSourcenameList(); - return true; + return TRUE; } } return CResizablePage::OnCommand(wParam, lParam); @@ -321,14 +319,13 @@ void CFileDetailDialogName::RenameFile() if (CanRenameFile()) { CString strNewFileName; GetDlgItemText(IDC_FILENAME, strNewFileName); - strNewFileName.Trim(); - if (strNewFileName.IsEmpty() || !IsValidEd2kString(strNewFileName)) - return; - CPartFile *file = static_cast((*m_paFiles)[0]); - file->SetFileName(strNewFileName, true); - file->UpdateDisplayedInfo(); - file->SavePartFile(); - GetParent()->SendMessage(UM_DATA_CHANGED); //refresh notification for FileDetailDialog + if (!strNewFileName.Trim().IsEmpty() && IsValidEd2kString(strNewFileName)) { + CPartFile *file = static_cast((*m_paFiles)[0]); + file->SetFileName(strNewFileName, true); + file->UpdateDisplayedInfo(); + file->SavePartFile(); + GetParent()->SendMessage(UM_DATA_CHANGED); //refresh notification for FileDetailDialog + } } } diff --git a/srchybrid/FileDetailDialogName.h b/srchybrid/FileDetailDialogName.h index 548f9e89..45d848e2 100644 --- a/srchybrid/FileDetailDialogName.h +++ b/srchybrid/FileDetailDialogName.h @@ -34,7 +34,6 @@ class CFileDetailDialogName : public CResizablePage public: CFileDetailDialogName(); // standard constructor - virtual ~CFileDetailDialogName() = default; virtual BOOL OnInitDialog(); void SetFiles(const CSimpleArray *paFiles) { m_paFiles = paFiles; m_bDataChanged = true; } diff --git a/srchybrid/FileDetailDlgStatistics.cpp b/srchybrid/FileDetailDlgStatistics.cpp index 4148693d..c306b495 100644 --- a/srchybrid/FileDetailDlgStatistics.cpp +++ b/srchybrid/FileDetailDlgStatistics.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -287,7 +287,8 @@ void CFileDetailDlgStatistics::OnSysColorChange() void CFileDetailDlgStatistics::OnTimer(UINT_PTR nIDEvent) { if (nIDEvent == m_hRefreshTimer) { - if (theApp.IsClosing() || !GetParent()->IsWindowVisible() + if (theApp.IsClosing() + || !GetParent()->IsWindowVisible() || theApp.emuledlg->GetActiveDialog() != (CWnd*)theApp.emuledlg->sharedfileswnd) { KillTimer(m_hRefreshTimer); diff --git a/srchybrid/FileDetailDlgStatistics.h b/srchybrid/FileDetailDlgStatistics.h index 9c9cf4d4..5db8dd0d 100644 --- a/srchybrid/FileDetailDlgStatistics.h +++ b/srchybrid/FileDetailDlgStatistics.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -31,7 +31,6 @@ class CFileDetailDlgStatistics : public CResizablePage public: CFileDetailDlgStatistics(); - virtual ~CFileDetailDlgStatistics() = default; virtual BOOL OnInitDialog(); void SetFiles(const CSimpleArray *paFiles) { m_paFiles = paFiles; m_bDataChanged = true; } diff --git a/srchybrid/FileIdentifier.cpp b/srchybrid/FileIdentifier.cpp index af7ce958..81b99307 100644 --- a/srchybrid/FileIdentifier.cpp +++ b/srchybrid/FileIdentifier.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -62,9 +62,9 @@ void CFileIdentifierBase::SetMD4Hash(const uchar *pucFileHash) md4cpy(m_abyMD4Hash, pucFileHash); } -void CFileIdentifierBase::SetMD4Hash(CFileDataIO *pFile) +void CFileIdentifierBase::SetMD4Hash(CFileDataIO &file) { - pFile->ReadHash16(m_abyMD4Hash); + file.ReadHash16(m_abyMD4Hash); } void CFileIdentifierBase::SetAICHHash(const CAICHHash &Hash) @@ -92,7 +92,7 @@ bool CFileIdentifierBase::CompareStrict(const CFileIdentifierBase &rFileIdentifi && m_AICHFileHash == rFileIdentifier.m_AICHFileHash; } -void CFileIdentifierBase::WriteIdentifier(CFileDataIO *pFile, bool bKadExcludeMD4) const +void CFileIdentifierBase::WriteIdentifier(CFileDataIO &file, bool bKadExcludeMD4) const { ASSERT(!isnulmd4(m_abyMD4Hash)); ASSERT(GetFileSize() != 0ull); @@ -109,13 +109,13 @@ void CFileIdentifierBase::WriteIdentifier(CFileDataIO *pFile, bool bKadExcludeMD (uIncludesSize << 1) | (uIncludesMD4 << 0)); //DebugLog(_T("Write IdentifierDesc: %u"), byIdentifierDesc); - pFile->WriteUInt8(byIdentifierDesc); + file.WriteUInt8(byIdentifierDesc); if (!bKadExcludeMD4) - pFile->WriteHash16(m_abyMD4Hash); + file.WriteHash16(m_abyMD4Hash); if (GetFileSize() != 0ull) - pFile->WriteUInt64(GetFileSize()); + file.WriteUInt64(GetFileSize()); if (HasAICHHash()) - m_AICHFileHash.Write(pFile); + m_AICHFileHash.Write(file); } CString CFileIdentifierBase::DbgInfo() const @@ -154,11 +154,12 @@ bool CFileIdentifier::CalculateMD4HashByHashSet(bool bVerifyOnly, bool bDeleteOn ASSERT(0); return false; } - uchar *buffer = new uchar[m_aMD4HashSet.GetCount() * MDX_DIGEST_SIZE]; - for (INT_PTR i = m_aMD4HashSet.GetCount(); --i >= 0;) - md4cpy(buffer + (i * MDX_DIGEST_SIZE), m_aMD4HashSet[i]); + const INT_PTR iCnt = m_aMD4HashSet.GetCount(); + uchar *buffer = new uchar[iCnt * MDX_DIGEST_SIZE]; + for (INT_PTR i = iCnt; --i >= 0;) + md4cpy(&buffer[i * MDX_DIGEST_SIZE], m_aMD4HashSet[i]); uchar aucResult[MDX_DIGEST_SIZE]; - CKnownFile::CreateHash(buffer, (uint32)m_aMD4HashSet.GetCount() * MDX_DIGEST_SIZE, aucResult); + CKnownFile::CreateHash(buffer, (uint32)(iCnt * MDX_DIGEST_SIZE), aucResult); delete[] buffer; if (bVerifyOnly) { if (!md4equ(aucResult, m_abyMD4Hash)) { @@ -171,23 +172,23 @@ bool CFileIdentifier::CalculateMD4HashByHashSet(bool bVerifyOnly, bool bDeleteOn return true; } -bool CFileIdentifier::LoadMD4HashsetFromFile(CFileDataIO *file, bool bVerifyExistingHash) +bool CFileIdentifier::LoadMD4HashsetFromFile(CFileDataIO &file, bool bVerifyExistingHash) { uchar checkid[MDX_DIGEST_SIZE]; - file->ReadHash16(checkid); + file.ReadHash16(checkid); //TRACE("File size: %u (%u full parts + %u bytes)\n", GetFileSize(), GetFileSize()/PARTSIZE, GetFileSize()%PARTSIZE); //TRACE("File hash: %s\n", (LPCTSTR)md4str(checkid)); ASSERT(m_aMD4HashSet.IsEmpty()); ASSERT(!isnulmd4(m_abyMD4Hash) || !bVerifyExistingHash); DeleteMD4Hashset(); - uint16 parts = file->ReadUInt16(); + uint16 parts = file.ReadUInt16(); //TRACE("Nr. hashes: %u\n", (UINT)parts); if (bVerifyExistingHash && (!md4equ(m_abyMD4Hash, checkid) || parts != GetTheoreticalMD4PartHashCount())) return false; - for (uint16 i = 0; i < parts; ++i) { + for (UINT i = 0; i < parts; ++i) { uchar *cur_hash = new uchar[MDX_DIGEST_SIZE]; - file->ReadHash16(cur_hash); + file.ReadHash16(cur_hash); //TRACE("Hash[%3u]: %s\n", i, (LPCTSTR)md4str(cur_hash)); m_aMD4HashSet.Add(cur_hash); } @@ -217,9 +218,7 @@ bool CFileIdentifier::SetMD4HashSet(const CArray &aHashset) uchar* CFileIdentifier::GetMD4PartHash(UINT part) const { - if (part >= (UINT)m_aMD4HashSet.GetCount()) - return NULL; - return m_aMD4HashSet[part]; + return (part < (UINT)m_aMD4HashSet.GetCount()) ? m_aMD4HashSet[part] : NULL; } // nr. of part hashes according the file size wrt ED2K protocol @@ -234,17 +233,17 @@ uint16 CFileIdentifier::GetTheoreticalMD4PartHashCount() const return uResult + static_cast(uResult > 0); } -void CFileIdentifier::WriteMD4HashsetToFile(CFileDataIO *pFile) const +void CFileIdentifier::WriteMD4HashsetToFile(CFileDataIO &file) const { ASSERT(!isnulmd4(m_abyMD4Hash)); - pFile->WriteHash16(m_abyMD4Hash); + file.WriteHash16(m_abyMD4Hash); UINT uParts = (UINT)m_aMD4HashSet.GetCount(); - pFile->WriteUInt16((uint16)uParts); + file.WriteUInt16((uint16)uParts); for (UINT i = 0; i < uParts; ++i) - pFile->WriteHash16(m_aMD4HashSet[i]); + file.WriteHash16(m_aMD4HashSet[i]); } -void CFileIdentifier::WriteHashSetsToPacket(CFileDataIO *pFile, bool bMD4, bool bAICH) const +void CFileIdentifier::WriteHashSetsToPacket(CFileDataIO &file, bool bMD4, bool bAICH) const { // 6 Options - RESERVED // 1 AICH HashSet @@ -272,17 +271,17 @@ void CFileIdentifier::WriteHashSetsToPacket(CFileDataIO *pFile, bool bMD4, bool DEBUG_ONLY(DebugLog(_T("CFileIdentifier::WriteHashSetsToPacket - unable to write AICH HashSet"))); } } - pFile->WriteUInt8(byOptions); + file.WriteUInt8(byOptions); if (bMD4) - WriteMD4HashsetToFile(pFile); + WriteMD4HashsetToFile(file); if (bAICH) - WriteAICHHashsetToFile(pFile); + WriteAICHHashsetToFile(file); } -bool CFileIdentifier::ReadHashSetsFromPacket(CFileDataIO *pFile, bool &rbMD4, bool &rbAICH) +bool CFileIdentifier::ReadHashSetsFromPacket(CFileDataIO &file, bool &rbMD4, bool &rbAICH) { ASSERT(rbMD4 || rbAICH); - uint8 byOptions = pFile->ReadUInt8(); + uint8 byOptions = file.ReadUInt8(); bool bMD4Present = (byOptions & 0x01) > 0; bool bAICHPresent = (byOptions & 0x02) > 0; // We don't abort on unknown option, because even if there is another unknown hashset, there is no data @@ -296,13 +295,13 @@ bool CFileIdentifier::ReadHashSetsFromPacket(CFileDataIO *pFile, bool &rbMD4, bo DebugLogWarning(_T("CFileIdentifier::ReadHashSetsFromPacket: MD4 HashSet present but unrequested")); // Even if we don't want it, we still have to read the file to skip it uchar tmpHash[MDX_DIGEST_SIZE]; - pFile->ReadHash16(tmpHash); - for (int i = pFile->ReadUInt16(); --i >= 0;) - pFile->ReadHash16(tmpHash); + file.ReadHash16(tmpHash); + for (int i = file.ReadUInt16(); --i >= 0;) + file.ReadHash16(tmpHash); } else if (!bMD4Present) rbMD4 = false; else if (/*bMD4Present && */rbMD4) { - if (!LoadMD4HashsetFromFile(pFile, true)) { // corrupt + if (!LoadMD4HashsetFromFile(file, true)) { // corrupt rbMD4 = false; rbAICH = false; return false; @@ -310,16 +309,14 @@ bool CFileIdentifier::ReadHashSetsFromPacket(CFileDataIO *pFile, bool &rbMD4, bo } if (bAICHPresent && !rbAICH) { - DebugLogWarning(_T("CFileIdentifier::ReadHashSetsFromPacket: AICH HashSet present but unrequested")); - // Even if we don't want it, we still have to read the file to skip it - CAICHHash tmpHash(pFile); - for (int i = pFile->ReadUInt16(); --i >= 0;) - tmpHash.Read(pFile); + DebugLogWarning(_T("CFileIdentifier::ReadHashSetsFromPacket: unrequested AICH HashSet was present")); + // Skip AICH hashes + file.Seek(file.ReadUInt16() * HASHSIZE, CFile::current); } else if (!bAICHPresent || !HasAICHHash()) { ASSERT(!bAICHPresent); rbAICH = false; } else if (/*bAICHPresent && */rbAICH) { - if (!LoadAICHHashsetFromFile(pFile, true)) { // corrupt + if (!LoadAICHHashsetFromFile(file, true)) { // corrupt if (rbMD4) { DeleteMD4Hashset(); rbMD4 = false; @@ -333,7 +330,7 @@ bool CFileIdentifier::ReadHashSetsFromPacket(CFileDataIO *pFile, bool &rbMD4, bo void CFileIdentifier::DeleteMD4Hashset() { - for (int i = (int)m_aMD4HashSet.GetCount(); --i >= 0;) + for (INT_PTR i = m_aMD4HashSet.GetCount(); --i >= 0;) delete[] m_aMD4HashSet[i]; m_aMD4HashSet.RemoveAll(); } @@ -361,39 +358,38 @@ bool CFileIdentifier::SetAICHHashSet(const CFileIdentifier &rSourceHashSet) return false; } m_aAICHPartHashSet.RemoveAll(); - for (int i = 0; i < rSourceHashSet.m_aAICHPartHashSet.GetCount(); ++i) + for (INT_PTR i = 0; i < rSourceHashSet.m_aAICHPartHashSet.GetCount(); ++i) m_aAICHPartHashSet.Add(rSourceHashSet.m_aAICHPartHashSet[i]); ASSERT(HasExpectedAICHHashCount()); return HasExpectedAICHHashCount(); } -bool CFileIdentifier::LoadAICHHashsetFromFile(CFileDataIO *pFile, bool bVerify) +bool CFileIdentifier::LoadAICHHashsetFromFile(CFileDataIO &file, bool bVerify) { ASSERT(m_aAICHPartHashSet.IsEmpty()); m_aAICHPartHashSet.RemoveAll(); - CAICHHash masterHash(pFile); + CAICHHash masterHash(file); if (HasAICHHash() && masterHash != m_AICHFileHash) { ASSERT(0); - DebugLogError(_T("Loading AICH Part Hashset error: HashSet Masterhash doesn't matches with existing masterhash - hashset not loaded")); + DebugLogError(_T("Loading AICH Part Hashset error: HashSet Masterhash doesn't match with existing masterhash - hashset not loaded")); return false; } - uint16 nCount = pFile->ReadUInt16(); - for (int i = 0; i < nCount; ++i) - m_aAICHPartHashSet.Add(CAICHHash(pFile)); + for (int i = file.ReadUInt16(); --i >= 0;) + m_aAICHPartHashSet.Add(CAICHHash(file)); if (bVerify) return VerifyAICHHashSet(); return true; } -void CFileIdentifier::WriteAICHHashsetToFile(CFileDataIO *pFile) const +void CFileIdentifier::WriteAICHHashsetToFile(CFileDataIO &file) const { ASSERT(HasAICHHash()); ASSERT(HasExpectedAICHHashCount()); - m_AICHFileHash.Write(pFile); - UINT uParts = (UINT)m_aAICHPartHashSet.GetCount(); - pFile->WriteUInt16((uint16)uParts); - for (UINT i = 0; i < uParts; ++i) - m_aAICHPartHashSet[i].Write(pFile); + m_AICHFileHash.Write(file); + INT_PTR uParts = m_aAICHPartHashSet.GetCount(); + file.WriteUInt16((uint16)uParts); + for (INT_PTR i = 0; i < uParts; ++i) + m_aAICHPartHashSet[i].Write(file); } bool CFileIdentifier::VerifyAICHHashSet() @@ -411,16 +407,15 @@ bool CFileIdentifier::VerifyAICHHashSet() if (uPartCount <= 1) return true; // No AICH Part Hashes for (uint32 nPart = 0; nPart < uPartCount; ++nPart) { - uint64 nPartStartPos = (uint64)nPart * PARTSIZE; + uint64 nPartStartPos = nPart * PARTSIZE; uint32 nPartSize = (uint32)min(PARTSIZE, (uint64)GetFileSize() - nPartStartPos); CAICHHashTree *pPartHashTree = tmpAICHHashSet.m_pHashTree.FindHash(nPartStartPos, nPartSize); - if (pPartHashTree != NULL) { - pPartHashTree->m_Hash = m_aAICHPartHashSet[nPart]; - pPartHashTree->m_bHashValid = true; - } else { + if (pPartHashTree == NULL) { ASSERT(0); return false; } + pPartHashTree->m_Hash = m_aAICHPartHashSet[nPart]; + pPartHashTree->m_bHashValid = true; } if (!tmpAICHHashSet.VerifyHashTree(false)) { m_aAICHPartHashSet.RemoveAll(); @@ -445,9 +440,9 @@ CFileIdentifierSA::CFileIdentifierSA(const uchar *pucFileHash, EMFileSize nFileS SetAICHHash(rHash); } -bool CFileIdentifierSA::ReadIdentifier(CFileDataIO *pFile, bool bKadValidWithoutMd4) +bool CFileIdentifierSA::ReadIdentifier(CFileDataIO &file, bool bKadValidWithoutMd4) { - uint8 byIdentifierDesc = pFile->ReadUInt8(); + uint8 byIdentifierDesc = file.ReadUInt8(); //DebugLog(_T("Read IdentifierDesc: %u"), byIdentifierDesc); bool bMD4 = ((byIdentifierDesc >> 0) & 0x01) > 0; bool bSize = ((byIdentifierDesc >> 1) & 0x01) > 0; @@ -468,11 +463,11 @@ bool CFileIdentifierSA::ReadIdentifier(CFileDataIO *pFile, bool bKadValidWithout DebugLogWarning(_T("Size not included on reading file identifier")); if (bMD4) - pFile->ReadHash16(m_abyMD4Hash); + file.ReadHash16(m_abyMD4Hash); if (bSize) - m_nFileSize = pFile->ReadUInt64(); + m_nFileSize = file.ReadUInt64(); if (bAICH) { - m_AICHFileHash.Read(pFile); + m_AICHFileHash.Read(file); m_bHasValidAICHHash = true; } return true; diff --git a/srchybrid/FileIdentifier.h b/srchybrid/FileIdentifier.h index c213f92d..011fde5a 100644 --- a/srchybrid/FileIdentifier.h +++ b/srchybrid/FileIdentifier.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -28,7 +28,7 @@ class CFileIdentifierBase virtual EMFileSize GetFileSize() const; - void WriteIdentifier(CFileDataIO *pFile, bool bKadExcludeMD4 = false) const; + void WriteIdentifier(CFileDataIO &file, bool bKadExcludeMD4 = false) const; bool CompareRelaxed(const CFileIdentifierBase &rFileIdentifier) const; bool CompareStrict(const CFileIdentifierBase &rFileIdentifier) const; @@ -36,7 +36,7 @@ class CFileIdentifierBase //******************** MD4 Related void SetMD4Hash(const uchar *pucFileHash); - void SetMD4Hash(CFileDataIO *pFile); + void SetMD4Hash(CFileDataIO &file); const uchar* GetMD4Hash() const { return m_abyMD4Hash; } //******************** AICH Related @@ -66,14 +66,14 @@ class CFileIdentifier : public CFileIdentifierBase virtual ~CFileIdentifier(); //******************** Common - void WriteHashSetsToPacket(CFileDataIO *pFile, bool bMD4, bool bAICH) const; // not compatible with old single md4 hashset - bool ReadHashSetsFromPacket(CFileDataIO *pFile, bool &rbMD4, bool &rbAICH); // not compatible with old single md4 hashset + void WriteHashSetsToPacket(CFileDataIO &file, bool bMD4, bool bAICH) const; // not compatible with old single md4 hashset + bool ReadHashSetsFromPacket(CFileDataIO &file, bool &rbMD4, bool &rbAICH); // not compatible with old single md4 hashset virtual EMFileSize GetFileSize() const { return m_rFileSize; } //******************** MD4 Related bool CalculateMD4HashByHashSet(bool bVerifyOnly, bool bDeleteOnVerifyFail = true); - bool LoadMD4HashsetFromFile(CFileDataIO *file, bool bVerifyExistingHash); - void WriteMD4HashsetToFile(CFileDataIO *pFile) const; + bool LoadMD4HashsetFromFile(CFileDataIO &file, bool bVerifyExistingHash); + void WriteMD4HashsetToFile(CFileDataIO &file) const; bool SetMD4HashSet(const CArray &aHashset); uchar* GetMD4PartHash(UINT part) const; @@ -87,8 +87,8 @@ class CFileIdentifier : public CFileIdentifierBase CArray& GetRawMD4HashSet() { return m_aMD4HashSet; } //******************** AICH Related - bool LoadAICHHashsetFromFile(CFileDataIO *pFile, bool bVerify = true); // bVerify=false means you must call VerifyAICHHashSet immediately after this method - void WriteAICHHashsetToFile(CFileDataIO *pFile) const; + bool LoadAICHHashsetFromFile(CFileDataIO &file, bool bVerify = true); // bVerify=false means you must call VerifyAICHHashSet immediately after this method + void WriteAICHHashsetToFile(CFileDataIO &file) const; bool SetAICHHashSet(const CAICHRecoveryHashSet &sourceHashSet); bool SetAICHHashSet(const CFileIdentifier &rSourceHashSet); @@ -114,10 +114,9 @@ class CFileIdentifierSA : public CFileIdentifierBase CFileIdentifierSA(const uchar *pucFileHash, EMFileSize nFileSize, const CAICHHash &rHash, bool bAICHHashValid); CFileIdentifierSA(); - virtual ~CFileIdentifierSA() = default; virtual EMFileSize GetFileSize() const { return m_nFileSize; } - bool ReadIdentifier(CFileDataIO *pFile, bool bKadValidWithoutMd4 = false); + bool ReadIdentifier(CFileDataIO &file, bool bKadValidWithoutMd4 = false); private: EMFileSize m_nFileSize; diff --git a/srchybrid/FileInfoDialog.cpp b/srchybrid/FileInfoDialog.cpp index 9b4ed972..c86f6631 100644 --- a/srchybrid/FileInfoDialog.cpp +++ b/srchybrid/FileInfoDialog.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -26,33 +26,35 @@ #include "id3/tag.h" #include "id3/misc_support.h" +#include // MediaInfoDLL /** @brief Kinds of Stream */ -typedef enum _stream_t +typedef enum MediaInfo_stream_t { - Stream_General, - Stream_Video, - Stream_Audio, - Stream_Text, - Stream_Chapters, - Stream_Image, - Stream_Max -} stream_t_C; + MediaInfo_Stream_General, + MediaInfo_Stream_Video, + MediaInfo_Stream_Audio, + MediaInfo_Stream_Text, + MediaInfo_Stream_Other, + MediaInfo_Stream_Image, + MediaInfo_Stream_Menu, + MediaInfo_Stream_Max +} MediaInfo_stream_C; /** @brief Kinds of Info */ -typedef enum _info_t +typedef enum MediaInfo_info_t { - Info_Name, - Info_Text, - Info_Measure, - Info_Options, - Info_Name_Text, - Info_Measure_Text, - Info_Info, - Info_HowTo, - Info_Max -} info_t_C; + MediaInfo_Info_Name, + MediaInfo_Info_Text, + MediaInfo_Info_Measure, + MediaInfo_Info_Options, + MediaInfo_Info_Name_Text, + MediaInfo_Info_Measure_Text, + MediaInfo_Info_Info, + MediaInfo_Info_HowTo, + MediaInfo_Info_Max +} MediaInfo_info_C; #ifdef _DEBUG @@ -62,54 +64,6 @@ static char THIS_FILE[] = __FILE__; #endif -///////////////////////////////////////////////////////////////////////////// -// SMediaInfoThreadResult - -struct SMediaInfoThreadResult -{ - ~SMediaInfoThreadResult() - { - delete paMediaInfo; - } - CArray *paMediaInfo; - CStringA strInfo; -}; - -///////////////////////////////////////////////////////////////////////////// -// CGetMediaInfoThread - -class CGetMediaInfoThread : public CWinThread -{ - DECLARE_DYNCREATE(CGetMediaInfoThread) - -protected: - CGetMediaInfoThread() - : m_hWndOwner() - , m_hFont() - { - } - -public: - virtual BOOL InitInstance(); - virtual int Run(); - void SetValues(HWND hWnd, const CSimpleArray *paFiles, HFONT hFont) - { - m_hWndOwner = hWnd; - for (int i = 0; i < paFiles->GetSize(); ++i) - m_aFiles.Add(static_cast((*paFiles)[i])); - m_hFont = hFont; - } - -private: - bool GetMediaInfo(HWND hWndOwner, const CShareableFile *pFile, SMediaInfo *mi, bool bSingleFile); - void WarnAboutWrongFileExtension(SMediaInfo *mi, LPCTSTR pszFileName, LPCTSTR pszExtensions); - - HWND m_hWndOwner; - CSimpleArray m_aFiles; - HFONT m_hFont; -}; - - ///////////////////////////////////////////////////////////////////////////// // CMediaInfoDLL @@ -120,17 +74,12 @@ class CMediaInfoDLL : m_ullVersion() , m_hLib() , m_bInitialized() - , m_pfnMediaInfo4_Open() // MediaInfoLib - v0.4.0.1 - , m_pfnMediaInfo4_Close() - , m_pfnMediaInfo4_Get() - , m_pfnMediaInfo4_Count_Get() - , m_pfnMediaInfo5_Open() // MediaInfoLib - v0.5 - v0.6.1 - , m_pfnMediaInfo_Close() // MediaInfoLib - v0.7+ - , m_pfnMediaInfo_Get() - , m_pfnMediaInfo_Count_Get() - , m_pfnMediaInfo_Open() , m_pfnMediaInfo_New() + , m_pfnMediaInfo_Open() + , m_pfnMediaInfo_Close() , m_pfnMediaInfo_Delete() + , m_pfnMediaInfo_Get() + , m_pfnMediaInfo_GetI() { } @@ -155,7 +104,7 @@ class CMediaInfoDLL TCHAR szPath[MAX_PATH]; ULONG ulChars = _countof(szPath); if (key.QueryStringValue(_T("Path"), szPath, &ulChars) == ERROR_SUCCESS) { - LPTSTR pszResult = PathCombine(strPath.GetBuffer(MAX_PATH), szPath, _T("MEDIAINFO.DLL")); + LPTSTR pszResult = ::PathCombine(strPath.GetBuffer(MAX_PATH), szPath, _T("MEDIAINFO.DLL")); strPath.ReleaseBuffer(); if (pszResult) m_hLib = LoadLibrary(strPath); @@ -165,12 +114,16 @@ class CMediaInfoDLL if (m_hLib == NULL) { CString strProgramFiles = ShellGetFolderPath(CSIDL_PROGRAM_FILES); if (!strProgramFiles.IsEmpty()) { - LPTSTR pszResult = PathCombine(strPath.GetBuffer(MAX_PATH), strProgramFiles, _T("MediaInfo\\MEDIAINFO.DLL")); + LPTSTR pszResult = ::PathCombine(strPath.GetBuffer(MAX_PATH), strProgramFiles, _T("MediaInfo\\MEDIAINFO.DLL")); strPath.ReleaseBuffer(); if (pszResult) m_hLib = LoadLibrary(strPath); } } + + // Support of very old versions at some point becomes difficult, and even unreasonable. + // For example, in 2020 it was hard to find MediaInfo v0.4.* and v0.5.* in the net. + // Currently the oldest allowed version would be v0.7.13 (released in April, 2009). if (m_hLib != NULL) { // Note from MediaInfo developer // ----------------------------- @@ -180,52 +133,26 @@ class CMediaInfoDLL // So you should test the version of the DLL, and if one of the 2 first numbers change, not load it. // --- ULONGLONG ullVersion = GetModuleVersion(m_hLib); - if (ullVersion == 0) { // MediaInfoLib - v0.4.0.1 does not have a Win32 version info resource record - char* (__stdcall *fpMediaInfo4_Info_Version)(); - (FARPROC &)fpMediaInfo4_Info_Version = GetProcAddress(m_hLib, "MediaInfo_Info_Version"); - if (fpMediaInfo4_Info_Version) { - char *pszVersion = (*fpMediaInfo4_Info_Version)(); - if (pszVersion && strcmp(pszVersion, "MediaInfoLib - v0.4.0.1 - http://mediainfo.sourceforge.net") == 0) { - (FARPROC &)m_pfnMediaInfo4_Open = GetProcAddress(m_hLib, "MediaInfo_Open"); - (FARPROC &)m_pfnMediaInfo4_Close = GetProcAddress(m_hLib, "MediaInfo_Close"); - (FARPROC &)m_pfnMediaInfo4_Get = GetProcAddress(m_hLib, "MediaInfo_Get"); - (FARPROC &)m_pfnMediaInfo4_Count_Get = GetProcAddress(m_hLib, "MediaInfo_Count_Get"); - if (m_pfnMediaInfo4_Open && m_pfnMediaInfo4_Close && m_pfnMediaInfo4_Get) - m_ullVersion = MAKEDLLVERULL(0, 4, 0, 1); - } - } - } else if (ullVersion >= MAKEDLLVERULL(0, 5, 0, 0) && ullVersion < MAKEDLLVERULL(0, 7, 0, 0)) { - // eMule currently handles v0.5.1.0, v0.6.0.0, v0.6.1.0 - // Don't use 'MediaInfo_Info_Version' with versions v0.5+. This function is exported, - // can be called, but does not return a valid version string. - - (FARPROC &)m_pfnMediaInfo5_Open = GetProcAddress(m_hLib, "MediaInfo_Open"); - (FARPROC &)m_pfnMediaInfo_Close = GetProcAddress(m_hLib, "MediaInfo_Close"); - (FARPROC &)m_pfnMediaInfo_Get = GetProcAddress(m_hLib, "MediaInfo_Get"); - (FARPROC &)m_pfnMediaInfo_Count_Get = GetProcAddress(m_hLib, "MediaInfo_Count_Get"); - if (m_pfnMediaInfo5_Open && m_pfnMediaInfo_Close && m_pfnMediaInfo_Get) - m_ullVersion = ullVersion; - } else if (ullVersion < MAKEDLLVERULL(21, 10, 0, 0)) { //here ullVersion >= 7.0 + if (ullVersion >= MAKEDLLVERULL(0, 7, 13, 0) + && ((thePrefs.GetWindowsVersion() == _WINVER_XP_ && ullVersion < MAKEDLLVERULL(21, 4, 0, 0)) + || ullVersion < MAKEDLLVERULL(23, 11, 0, 0))) + { (FARPROC &)m_pfnMediaInfo_New = GetProcAddress(m_hLib, "MediaInfo_New"); (FARPROC &)m_pfnMediaInfo_Delete = GetProcAddress(m_hLib, "MediaInfo_Delete"); (FARPROC &)m_pfnMediaInfo_Open = GetProcAddress(m_hLib, "MediaInfo_Open"); (FARPROC &)m_pfnMediaInfo_Close = GetProcAddress(m_hLib, "MediaInfo_Close"); (FARPROC &)m_pfnMediaInfo_Get = GetProcAddress(m_hLib, "MediaInfo_Get"); - (FARPROC &)m_pfnMediaInfo_Count_Get = GetProcAddress(m_hLib, "MediaInfo_Count_Get"); + (FARPROC &)m_pfnMediaInfo_GetI = GetProcAddress(m_hLib, "MediaInfo_GetI"); if (m_pfnMediaInfo_New && m_pfnMediaInfo_Delete && m_pfnMediaInfo_Open && m_pfnMediaInfo_Close && m_pfnMediaInfo_Get) m_ullVersion = ullVersion; } if (!m_ullVersion) { - m_pfnMediaInfo4_Open = NULL; - m_pfnMediaInfo4_Close = NULL; - m_pfnMediaInfo4_Get = NULL; - m_pfnMediaInfo4_Count_Get = NULL; m_pfnMediaInfo_New = NULL; m_pfnMediaInfo_Delete = NULL; m_pfnMediaInfo_Open = NULL; m_pfnMediaInfo_Close = NULL; m_pfnMediaInfo_Get = NULL; - m_pfnMediaInfo_Count_Get = NULL; + m_pfnMediaInfo_GetI = NULL; FreeLibrary(m_hLib); m_hLib = NULL; } @@ -241,55 +168,32 @@ class CMediaInfoDLL void* Open(LPCTSTR File) { - if (m_pfnMediaInfo4_Open) - return (*m_pfnMediaInfo4_Open)(const_cast((LPCSTR)CStringA(File))); - if (m_pfnMediaInfo5_Open) - return (*m_pfnMediaInfo5_Open)(File); - if (m_pfnMediaInfo_New) { - void *Handle = (*m_pfnMediaInfo_New)(); - if (Handle) - (*m_pfnMediaInfo_Open)(Handle, File); - return Handle; - } - return NULL; + if (!m_pfnMediaInfo_New) + return NULL; + void *Handle = (*m_pfnMediaInfo_New)(); + if (Handle) + (*m_pfnMediaInfo_Open)(Handle, File); + return Handle; } void Close(void *Handle) { if (m_pfnMediaInfo_Delete) - (*m_pfnMediaInfo_Delete)(Handle); // File is automatically closed - else if (m_pfnMediaInfo4_Close) - (*m_pfnMediaInfo4_Close)(Handle); + (*m_pfnMediaInfo_Delete)(Handle); // File is closed automatically else if (m_pfnMediaInfo_Close) (*m_pfnMediaInfo_Close)(Handle); } - CString Get(void *Handle, stream_t_C StreamKind, int StreamNumber, LPCTSTR Parameter, info_t_C KindOfInfo, info_t_C KindOfSearch) + CString Get(void *Handle, MediaInfo_stream_C StreamKind, int StreamNumber, LPCTSTR Parameter, MediaInfo_info_C KindOfInfo, MediaInfo_info_C KindOfSearch) { - if (m_pfnMediaInfo4_Get) - return CString((*m_pfnMediaInfo4_Get)(Handle, StreamKind, StreamNumber, (LPSTR)(LPCSTR)CStringA(Parameter), KindOfInfo, KindOfSearch)); - if (m_pfnMediaInfo_Get) { - CString strNewParameter(Parameter); - if (m_ullVersion >= MAKEDLLVERULL(0, 7, 1, 0)) { - // Convert old tags to new tags - strNewParameter.Replace(_T('_'), _T('/')); - - // Workaround for a bug in MediaInfoLib - if (strNewParameter == _T("Channels")) - strNewParameter = _T("Channel(s)"); - } - return (*m_pfnMediaInfo_Get)(Handle, StreamKind, StreamNumber, strNewParameter, KindOfInfo, KindOfSearch); - } - return CString(); + if (!m_pfnMediaInfo_Get) + return CString(); + return (*m_pfnMediaInfo_Get)(Handle, StreamKind, StreamNumber, Parameter, KindOfInfo, KindOfSearch); } - int Count_Get(void *Handle, stream_t_C StreamKind, int StreamNumber) const + CString GetI(void *Handle, MediaInfo_stream_C StreamKind, size_t StreamNumber, size_t iParameter, MediaInfo_info_C KindOfInfo) { - if (m_pfnMediaInfo4_Get) - return (*m_pfnMediaInfo4_Count_Get)(Handle, StreamKind, StreamNumber); - if (m_pfnMediaInfo_Count_Get) - return (*m_pfnMediaInfo_Count_Get)(Handle, StreamKind, StreamNumber); - return 0; + return CString((*m_pfnMediaInfo_GetI)(Handle, StreamKind, StreamNumber, iParameter, KindOfInfo)); } protected: @@ -297,26 +201,74 @@ class CMediaInfoDLL HINSTANCE m_hLib; bool m_bInitialized; - // MediaInfoLib - v0.4.0.1 - void* (__stdcall *m_pfnMediaInfo4_Open)(char *File) throw(...); - void (__stdcall *m_pfnMediaInfo4_Close)(void *Handle) throw(...); - char* (__stdcall *m_pfnMediaInfo4_Get)(void *Handle, stream_t_C StreamKind, int StreamNumber, char *Parameter, info_t_C KindOfInfo, info_t_C KindOfSearch) throw(...); - int (__stdcall *m_pfnMediaInfo4_Count_Get)(void *Handle, stream_t_C StreamKind, int StreamNumber) throw(...); - - // MediaInfoLib - v0.5+ - void* (__stdcall *m_pfnMediaInfo5_Open)(const wchar_t *File) throw(...); - void (__stdcall *m_pfnMediaInfo_Close)(void *Handle) throw(...); - const wchar_t* (__stdcall *m_pfnMediaInfo_Get)(void *Handle, stream_t_C StreamKind, int StreamNumber, const wchar_t *Parameter, info_t_C KindOfInfo, info_t_C KindOfSearch) throw(...); - int (__stdcall *m_pfnMediaInfo_Count_Get)(void *Handle, stream_t_C StreamKind, int StreamNumber) throw(...); - - // MediaInfoLib - v0.7.*, 17.* - int (__stdcall *m_pfnMediaInfo_Open)(void *Handle, const wchar_t *File); //throw(...); - void* (__stdcall *m_pfnMediaInfo_New)(); // throw(...); - void (__stdcall *m_pfnMediaInfo_Delete)(void *Handle); // throw(...); + // MediaInfoLib: 0.7.13-0.7.99, 17.10-20.08 + void* (__stdcall *m_pfnMediaInfo_New)(); + int(__stdcall *m_pfnMediaInfo_Open)(void *Handle, const wchar_t *File); + void(__stdcall *m_pfnMediaInfo_Close)(void *Handle); + void(__stdcall *m_pfnMediaInfo_Delete)(void *Handle); + const wchar_t* (__stdcall *m_pfnMediaInfo_Get)(void *Handle, MediaInfo_stream_C StreamKind, size_t StreamNumber, const wchar_t *Parameter, MediaInfo_info_C KindOfInfo, MediaInfo_info_C KindOfSearch); + const wchar_t* (__stdcall *m_pfnMediaInfo_GetI)(void *Handle, MediaInfo_stream_C StreamKind, size_t StreamNumber, size_t Parameter, MediaInfo_info_C KindOfInfo); }; CMediaInfoDLL theMediaInfoDLL; +///////////////////////////////////////////////////////////////////////////// +// SMediaInfoThreadResult + +struct SMediaInfoThreadResult +{ + ~SMediaInfoThreadResult() + { + delete paMediaInfo; + } + CArray *paMediaInfo = NULL; + CStringA strInfo; +}; + +///////////////////////////////////////////////////////////////////////////// +// CGetMediaInfoThread + +class CGetMediaInfoThread : public CWinThread +{ + DECLARE_DYNCREATE(CGetMediaInfoThread) + +protected: + CGetMediaInfoThread() + : m_hWndOwner() + , m_hFont() + , m_handle() + { + } + +public: + virtual BOOL InitInstance(); + virtual int Run(); + void SetValues(HWND hWnd, const CSimpleArray *paFiles, HFONT hFont) + { + m_hWndOwner = hWnd; + for (int i = 0; i < paFiles->GetSize(); ++i) + m_aFiles.Add(static_cast((*paFiles)[i])); + m_hFont = hFont; + } + +private: + bool GetMediaInfo(HWND hWndOwner, const CShareableFile *pFile, SMediaInfo *mi, bool bSingleFile); + void WarnAboutWrongFileExtension(SMediaInfo *mi, LPCTSTR pszFileName, LPCTSTR pszExtensions); + + CString InfoGet(MediaInfo_stream_C StreamKind, int StreamNumber, LPCTSTR Parameter) + { + return theMediaInfoDLL.Get(m_handle, StreamKind, StreamNumber, Parameter, MediaInfo_Info_Text, MediaInfo_Info_Name); + } + CString InfoGetI(MediaInfo_stream_C StreamKind, int StreamNumber, size_t Parameter, MediaInfo_info_C KindOfInfo) + { + return theMediaInfoDLL.GetI(m_handle, StreamKind, StreamNumber, Parameter, KindOfInfo); + } + CSimpleArray m_aFiles; + HWND m_hWndOwner; + HFONT m_hFont; + HANDLE m_handle; +}; + ///////////////////////////////////////////////////////////////////////////// // CFileInfoDialog dialog @@ -435,31 +387,17 @@ BOOL CFileInfoDialog::OnSetActive() if (!CResizablePage::OnSetActive()) return FALSE; if (m_bDataChanged) { - const CString &strWait = GetResString(IDS_FSTAT_WAITING); - SetDlgItemText(IDC_FORMAT, strWait); - SetDlgItemText(IDC_FILESIZE, strWait); - SetDlgItemText(IDC_LENGTH, strWait); - SetDlgItemText(IDC_VCODEC, strWait); - SetDlgItemText(IDC_VBITRATE, strWait); - SetDlgItemText(IDC_VWIDTH, strWait); - SetDlgItemText(IDC_VASPECT, strWait); - SetDlgItemText(IDC_VFPS, strWait); - SetDlgItemText(IDC_ACODEC, strWait); - SetDlgItemText(IDC_ACHANNEL, strWait); - SetDlgItemText(IDC_ASAMPLERATE, strWait); - SetDlgItemText(IDC_ABITRATE, strWait); - SetDlgItemText(IDC_ALANGUAGE, strWait); - SetDlgItemText(IDC_FULL_FILE_INFO, strWait); + InitDisplay(GetResString(IDS_FSTAT_WAITING)); CGetMediaInfoThread *pThread = (CGetMediaInfoThread*)AfxBeginThread(RUNTIME_CLASS(CGetMediaInfoThread), THREAD_PRIORITY_LOWEST, 0, CREATE_SUSPENDED); if (pThread) { pThread->SetValues(m_hWnd, m_paFiles, (HFONT)GetDlgItem(IDC_FD_XI1)->GetFont()->m_hObject); pThread->ResumeThread(); } - m_bDataChanged = false; m_pFiles.RemoveAll(); for (int i = m_paFiles->GetSize(); --i >= 0;) m_pFiles.Add((*m_paFiles)[i]); + m_bDataChanged = false; } return TRUE; } @@ -483,7 +421,7 @@ int CGetMediaInfoThread::Run() { (void)CoInitialize(NULL); - HWND hwndRE = ::CreateWindow(RICHEDIT_CLASS, _T(""), ES_MULTILINE | ES_READONLY | WS_DISABLED, 0, 0, 200, 200, NULL, NULL, NULL, NULL); + HWND hwndRE = ::CreateWindow(RICHEDIT_CLASS, NULL, ES_MULTILINE | ES_READONLY | WS_DISABLED, 0, 0, 200, 200, NULL, NULL, NULL, NULL); ASSERT(hwndRE); if (hwndRE && m_hFont) ::SendMessage(hwndRE, WM_SETFONT, (WPARAM)m_hFont, 0); @@ -502,7 +440,7 @@ int CGetMediaInfoThread::Run() re.SetParaFormat(pf); } re.Detach(); - + const int arcnt = m_aFiles.GetSize(); paMediaInfo = new CArray; for (int i = 0; i < arcnt; ++i) { @@ -560,24 +498,30 @@ int CGetMediaInfoThread::Run() return 0; } +void CFileInfoDialog::InitDisplay(LPCTSTR pStr) +{ + SetDlgItemText(IDC_FORMAT, pStr); + SetDlgItemText(IDC_FILESIZE, pStr); + SetDlgItemText(IDC_LENGTH, pStr); + SetDlgItemText(IDC_VCODEC, pStr); + SetDlgItemText(IDC_VBITRATE, pStr); + SetDlgItemText(IDC_VWIDTH, pStr); + SetDlgItemText(IDC_VASPECT, pStr); + SetDlgItemText(IDC_VFPS, pStr); + SetDlgItemText(IDC_ACODEC, pStr); + SetDlgItemText(IDC_ACHANNEL, pStr); + SetDlgItemText(IDC_ASAMPLERATE, pStr); + SetDlgItemText(IDC_ABITRATE, pStr); + SetDlgItemText(IDC_ALANGUAGE, pStr); + SetDlgItemText(IDC_FULL_FILE_INFO, _T("")); + +} + LRESULT CFileInfoDialog::OnMediaInfoResult(WPARAM, LPARAM lParam) { SetDlgItemText(IDC_FD_XI3, GetResString(IDS_VIDEO)); SetDlgItemText(IDC_FD_XI4, GetResString(IDS_AUDIO)); - SetDlgItemText(IDC_FORMAT, _T("-")); - SetDlgItemText(IDC_FILESIZE, _T("-")); - SetDlgItemText(IDC_LENGTH, _T("-")); - SetDlgItemText(IDC_VCODEC, _T("-")); - SetDlgItemText(IDC_VBITRATE, _T("-")); - SetDlgItemText(IDC_VWIDTH, _T("-")); - SetDlgItemText(IDC_VASPECT, _T("-")); - SetDlgItemText(IDC_VFPS, _T("-")); - SetDlgItemText(IDC_ACODEC, _T("-")); - SetDlgItemText(IDC_ACHANNEL, _T("-")); - SetDlgItemText(IDC_ASAMPLERATE, _T("-")); - SetDlgItemText(IDC_ABITRATE, _T("-")); - SetDlgItemText(IDC_ALANGUAGE, _T("-")); - SetDlgItemText(IDC_FULL_FILE_INFO, _T("")); + InitDisplay(_T("-")); SMediaInfoThreadResult *pThreadRes = (SMediaInfoThreadResult*)lParam; if (pThreadRes == NULL) @@ -589,20 +533,7 @@ LRESULT CFileInfoDialog::OnMediaInfoResult(WPARAM, LPARAM lParam) } if (paMediaInfo->GetSize() != m_paFiles->GetSize()) { - SetDlgItemText(IDC_FORMAT, _T("")); - SetDlgItemText(IDC_FILESIZE, _T("")); - SetDlgItemText(IDC_LENGTH, _T("")); - SetDlgItemText(IDC_VCODEC, _T("")); - SetDlgItemText(IDC_VBITRATE, _T("")); - SetDlgItemText(IDC_VWIDTH, _T("")); - SetDlgItemText(IDC_VASPECT, _T("")); - SetDlgItemText(IDC_VFPS, _T("")); - SetDlgItemText(IDC_ACODEC, _T("")); - SetDlgItemText(IDC_ACHANNEL, _T("")); - SetDlgItemText(IDC_ASAMPLERATE, _T("")); - SetDlgItemText(IDC_ABITRATE, _T("")); - SetDlgItemText(IDC_ALANGUAGE, _T("")); - SetDlgItemText(IDC_FULL_FILE_INFO, _T("")); + InitDisplay(_T("")); delete pThreadRes; return 1; } @@ -637,12 +568,10 @@ LRESULT CFileInfoDialog::OnMediaInfoResult(WPARAM, LPARAM lParam) ami.strMimeType.Empty(); ami.fFileLengthSec += mi.fFileLengthSec; - if (mi.bFileLengthEstimated) - ami.bFileLengthEstimated = true; + ami.bFileLengthEstimated |= mi.bFileLengthEstimated; ami.fVideoLengthSec += mi.fVideoLengthSec; - if (mi.bVideoLengthEstimated) - ami.bVideoLengthEstimated = true; + ami.bVideoLengthEstimated |= mi.bVideoLengthEstimated; if (ami.iVideoStreams == 0 && mi.iVideoStreams > 0 || ami.iVideoStreams > 0 && mi.iVideoStreams == 0) { if (ami.iVideoStreams == 0) ami.iVideoStreams = mi.iVideoStreams; @@ -654,25 +583,17 @@ LRESULT CFileInfoDialog::OnMediaInfoResult(WPARAM, LPARAM lParam) bDiffVideoBitRate = true; bDiffVideoAspectRatio = true; } else { - if (ami.iVideoStreams != mi.iVideoStreams) - bDiffVideoStreamCount = true; - if (ami.strVideoFormat != mi.strVideoFormat) - bDiffVideoCompression = true; - if (ami.video.bmiHeader.biWidth != mi.video.bmiHeader.biWidth) - bDiffVideoWidth = true; - if (ami.video.bmiHeader.biHeight != mi.video.bmiHeader.biHeight) - bDiffVideoHeight = true; - if (ami.fVideoFrameRate != mi.fVideoFrameRate) - bDiffVideoFrameRate = true; - if (ami.video.dwBitRate != mi.video.dwBitRate) - bDiffVideoBitRate = true; - if (ami.fVideoAspectRatio != mi.fVideoAspectRatio) - bDiffVideoAspectRatio = true; + bDiffVideoStreamCount |= (ami.iVideoStreams != mi.iVideoStreams); + bDiffVideoCompression |= (ami.strVideoFormat != mi.strVideoFormat); + bDiffVideoWidth |= (ami.video.bmiHeader.biWidth != mi.video.bmiHeader.biWidth); + bDiffVideoHeight |= (ami.video.bmiHeader.biHeight != mi.video.bmiHeader.biHeight); + bDiffVideoFrameRate |= (ami.fVideoFrameRate != mi.fVideoFrameRate); + bDiffVideoBitRate |= (ami.video.dwBitRate != mi.video.dwBitRate); + bDiffVideoAspectRatio |= (ami.fVideoAspectRatio != mi.fVideoAspectRatio); } ami.fAudioLengthSec += mi.fAudioLengthSec; - if (mi.bAudioLengthEstimated) - ami.bAudioLengthEstimated = true; + ami.bAudioLengthEstimated |= mi.bAudioLengthEstimated; if (ami.iAudioStreams == 0 && mi.iAudioStreams > 0 || ami.iAudioStreams > 0 && mi.iAudioStreams == 0) { if (ami.iAudioStreams == 0) ami.iAudioStreams = mi.iAudioStreams; @@ -683,18 +604,12 @@ LRESULT CFileInfoDialog::OnMediaInfoResult(WPARAM, LPARAM lParam) bDiffAudioAvgBytesPerSec = true; bDiffAudioLanguage = true; } else { - if (ami.iAudioStreams != mi.iAudioStreams) - bDiffAudioStreamCount = true; - if (ami.strAudioFormat != mi.strAudioFormat) - bDiffAudioCompression = true; - if (ami.audio.nChannels != mi.audio.nChannels) - bDiffAudioChannels = true; - if (ami.audio.nSamplesPerSec != mi.audio.nSamplesPerSec) - bDiffAudioSamplesPerSec = true; - if (ami.audio.nAvgBytesPerSec != mi.audio.nAvgBytesPerSec) - bDiffAudioAvgBytesPerSec = true; - if (ami.strAudioLanguage.CompareNoCase(mi.strAudioLanguage) != 0) - bDiffAudioLanguage = true; + bDiffAudioStreamCount |= (ami.iAudioStreams != mi.iAudioStreams); + bDiffAudioCompression |= (ami.strAudioFormat != mi.strAudioFormat); + bDiffAudioChannels |= (ami.audio.nChannels != mi.audio.nChannels); + bDiffAudioSamplesPerSec |= (ami.audio.nSamplesPerSec != mi.audio.nSamplesPerSec); + bDiffAudioAvgBytesPerSec |= (ami.audio.nAvgBytesPerSec != mi.audio.nAvgBytesPerSec); + bDiffAudioLanguage |= (ami.strAudioLanguage.CompareNoCase(mi.strAudioLanguage) != 0); } } } @@ -711,22 +626,17 @@ LRESULT CFileInfoDialog::OnMediaInfoResult(WPARAM, LPARAM lParam) SetDlgItemText(IDC_FILESIZE, CastItoXBytes(uTotalFileSize)); if (ami.fFileLengthSec) { - CString strLength(CastSecondsToHM((time_t)ami.fFileLengthSec)); + buffer = CastSecondsToHM((time_t)ami.fFileLengthSec); if (ami.bFileLengthEstimated) - strLength.AppendFormat(_T(" (%s)"), (LPCTSTR)GetResString(IDS_ESTIMATED)); - SetDlgItemText(IDC_LENGTH, strLength); + buffer.AppendFormat(_T(" (%s)"), (LPCTSTR)GetResString(IDS_ESTIMATED)); + SetDlgItemText(IDC_LENGTH, buffer); } if (ami.iVideoStreams) { if (!bDiffVideoStreamCount && ami.iVideoStreams > 1) SetDlgItemText(IDC_FD_XI3, GetResString(IDS_VIDEO) + _T(" #1")); - else - SetDlgItemText(IDC_FD_XI3, GetResString(IDS_VIDEO)); - if (!bDiffVideoCompression && !ami.strVideoFormat.IsEmpty()) - SetDlgItemText(IDC_VCODEC, ami.strVideoFormat); - else - SetDlgItemText(IDC_VCODEC, _T("")); + SetDlgItemText(IDC_VCODEC, bDiffVideoCompression ? _T("") : ami.strVideoFormat); if (!bDiffVideoBitRate && ami.video.dwBitRate) { if (ami.video.dwBitRate == _UI32_MAX) @@ -737,16 +647,15 @@ LRESULT CFileInfoDialog::OnMediaInfoResult(WPARAM, LPARAM lParam) } else SetDlgItemText(IDC_VBITRATE, _T("")); - buffer.Empty(); if (!bDiffVideoWidth && ami.video.bmiHeader.biWidth && !bDiffVideoHeight && ami.video.bmiHeader.biHeight) { - buffer.AppendFormat(_T("%i x %i"), abs(ami.video.bmiHeader.biWidth), abs(ami.video.bmiHeader.biHeight)); + buffer.Format(_T("%i x %i"), abs(ami.video.bmiHeader.biWidth), abs(ami.video.bmiHeader.biHeight)); SetDlgItemText(IDC_VWIDTH, buffer); } else SetDlgItemText(IDC_VWIDTH, _T("")); if (!bDiffVideoAspectRatio && ami.fVideoAspectRatio) { buffer.Format(_T("%.3f"), ami.fVideoAspectRatio); - const CString &strAR = GetKnownAspectRatioDisplayString((float)ami.fVideoAspectRatio); + const CString &strAR(GetKnownAspectRatioDisplayString((float)ami.fVideoAspectRatio)); if (!strAR.IsEmpty()) buffer.AppendFormat(_T(" (%s)"), (LPCTSTR)strAR); SetDlgItemText(IDC_VASPECT, buffer); @@ -763,30 +672,29 @@ LRESULT CFileInfoDialog::OnMediaInfoResult(WPARAM, LPARAM lParam) if (ami.iAudioStreams) { if (!bDiffAudioStreamCount && ami.iAudioStreams > 1) SetDlgItemText(IDC_FD_XI4, GetResString(IDS_AUDIO) + _T(" #1")); - else - SetDlgItemText(IDC_FD_XI4, GetResString(IDS_AUDIO)); - if (!bDiffAudioCompression && !ami.strAudioFormat.IsEmpty()) - SetDlgItemText(IDC_ACODEC, ami.strAudioFormat); - else - SetDlgItemText(IDC_ACODEC, _T("")); + SetDlgItemText(IDC_ACODEC, bDiffAudioCompression ? _T("") : ami.strAudioFormat); + LPCTSTR pChan; if (!bDiffAudioChannels && ami.audio.nChannels) { switch (ami.audio.nChannels) { case 1: - SetDlgItemText(IDC_ACHANNEL, _T("1 (Mono)")); + pChan = _T("1 (Mono)"); break; case 2: - SetDlgItemText(IDC_ACHANNEL, _T("2 (Stereo)")); + pChan = _T("2 (Stereo)"); break; case 5: - SetDlgItemText(IDC_ACHANNEL, _T("5.1 (Surround)")); + pChan = _T("5.1 (Surround)"); break; default: + pChan = NULL; SetDlgItemInt(IDC_ACHANNEL, ami.audio.nChannels, FALSE); } } else - SetDlgItemText(IDC_ACHANNEL, _T("")); + pChan = _T(""); + if (pChan) + SetDlgItemText(IDC_ACHANNEL, pChan); if (!bDiffAudioSamplesPerSec && ami.audio.nSamplesPerSec) { buffer.Format(_T("%.3f kHz"), ami.audio.nSamplesPerSec / 1000.0); @@ -798,20 +706,17 @@ LRESULT CFileInfoDialog::OnMediaInfoResult(WPARAM, LPARAM lParam) if (ami.audio.nAvgBytesPerSec == _UI32_MAX) buffer = _T("Variable"); else - buffer.Format(_T("%u %s"), (UINT)((ami.audio.nAvgBytesPerSec * 8) / 1000.0 + 0.5), (LPCTSTR)GetResString(IDS_KBITSSEC)); + buffer.Format(_T("%u %s"), (UINT)(ami.audio.nAvgBytesPerSec * 8.0f / 1000.0f + 0.5f), (LPCTSTR)GetResString(IDS_KBITSSEC)); SetDlgItemText(IDC_ABITRATE, buffer); } else SetDlgItemText(IDC_ABITRATE, _T("")); - if (!bDiffAudioLanguage && !ami.strAudioLanguage.IsEmpty()) - SetDlgItemText(IDC_ALANGUAGE, ami.strAudioLanguage); - else - SetDlgItemText(IDC_ALANGUAGE, _T("")); + SetDlgItemText(IDC_ALANGUAGE, bDiffAudioLanguage ? _T("") : ami.strAudioLanguage); } if (!m_bReducedDlg) { m_fi.SetRTFText(pThreadRes->strInfo); - m_fi.SetSel(0, 0); + DisableAutoSelect(m_fi); } delete pThreadRes; @@ -834,18 +739,18 @@ wchar_t* ID3_GetStringW(const ID3_Frame *frame, ID3_FieldID fldName) // ID3LIB BUG: Use the Unicode support of id3lib only if the tag is already // in Unicode format, thus avoiding couple of bugs with character conversion in // id3lib to get triggered. - ID3_Field *fld; - if (NULL != frame && NULL != (fld = frame->GetField(fldName)) - && fld->GetEncoding() == ID3TE_UTF16) - { - unicode_t *text = NULL; - size_t nText = fld->Size(); - text = new unicode_t[nText / sizeof(unicode_t) + 1]; - fld->Get(text, nText / sizeof(unicode_t)); - text[nText / sizeof(unicode_t)] = L'\0'; - for (unsigned int i = 0; i < nText / sizeof(unicode_t); ++i) - text[i] = _byteswap_ushort(text[i]); - return (wchar_t*)text; + if (frame) { + ID3_Field *fld = frame->GetField(fldName); + if (fld && fld->GetEncoding() == ID3TE_UTF16) { + unicode_t *text = NULL; + size_t nText = fld->Size(); + text = new unicode_t[nText / sizeof(unicode_t) + 1]; + fld->Get(text, nText / sizeof(unicode_t)); + text[nText / sizeof(unicode_t)] = L'\0'; + for (unsigned int i = 0; i < nText / sizeof(unicode_t); ++i) + text[i] = _byteswap_ushort(text[i]); + return (wchar_t*)text; + } } char *text = ID3_GetString(frame, fldName); @@ -870,7 +775,7 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi ASSERT(!pFile->GetFilePath().IsEmpty()); bool bHasDRM = false; - if (!pFile->IsPartFile() || static_cast(pFile)->IsComplete(0, 1024, true)) { + if (!pFile->IsPartFile() || static_cast(pFile)->IsCompleteBDSafe(0, 1024)) { GetMimeType(pFile->GetFilePath(), mi->strMimeType); bHasDRM = GetDRM(pFile->GetFilePath()); if (bHasDRM) { @@ -893,7 +798,7 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi // - The RIFF reading code will not work without the file header. // // - Most (if not all) other code also will not work without the beginning of the file available. - if (!static_cast(pFile)->IsComplete(0, 16 * 1024, true)) + if (!static_cast(pFile)->IsCompleteSafe(0, 16 * 1024)) return bFoundHeader || !mi->strMimeType.IsEmpty(); } @@ -907,7 +812,7 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi if (theApp.GetProfileInt(_T("eMule"), _T("MediaInfo_RIFF"), 1)) { try { if (GetRIFFHeaders(pFile->GetFilePath(), mi, bIsAVI, true)) { - if (bIsAVI && szExt.Compare(_T(".avi")) != 0) + if (bIsAVI && szExt != _T(".avi")) WarnAboutWrongFileExtension(mi, pFile->GetFileName(), _T("avi")); return true; } @@ -926,7 +831,7 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi try { bool bIsRM = false; if (GetRMHeaders(pFile->GetFilePath(), mi, bIsRM, true)) { - if (bIsRM && (szExt.Compare(_T(".rm")) != 0 && szExt.Compare(_T(".rmvb")) != 0 && szExt.Compare(_T(".ra")) != 0)) + if (bIsRM && szExt != _T(".rm") && szExt != _T(".rmvb") && szExt != _T(".ra")) WarnAboutWrongFileExtension(mi, pFile->GetFileName(), _T("rm rmvb ra")); return true; } @@ -1034,7 +939,7 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi mi->strInfo << _T(" ") << GetResString(IDS_SAMPLERATE) << _T(":\t") << mp3info->frequency / 1000.0 << _T(" kHz\n"); } - mi->iAudioStreams++; + ++mi->iAudioStreams; //no vbr bit rate //mi->audio.nAvgBytesPerSec = mp3info->vbr_bitrate ? mp3info->vbr_bitrate/8 : mp3info->bitrate/8; mi->audio.nAvgBytesPerSec = mp3info->bitrate / 8; @@ -1069,9 +974,7 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi // length if (mp3info->time) { if (!bSingleFile) { - CString strLength; - SecToTimeLength(mp3info->time, strLength); - mi->strInfo << _T(" ") << GetResString(IDS_LENGTH) << _T(":\t") << strLength; + mi->strInfo << _T(" ") << GetResString(IDS_LENGTH) << _T(":\t") << SecToTimeLength(mp3info->time); if (pFile->IsPartFile()) { mi->strInfo.SetSelectionCharFormat(mi->strInfo.m_cfRed); mi->strInfo << _T(" (") << GetResString(IDS_ESTIMATED) << _T(")"); @@ -1080,8 +983,7 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi mi->strInfo << _T("\n"); } mi->fAudioLengthSec = mp3info->time; - if (pFile->IsPartFile()) - mi->bAudioLengthEstimated = true; + mi->bAudioLengthEstimated |= pFile->IsPartFile(); } bFoundHeader = true; @@ -1153,7 +1055,7 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi { wchar_t *sText = ID3_GetStringW(frame, ID3FN_TEXT); long lLength = _wtol(sText); - if (lLength) // check for != "0" + if (lLength > 0) // check for != "0" strFidInfo << sText; delete[] sText; } @@ -1162,45 +1064,45 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi { wchar_t *sText = ID3_GetStringW(frame, ID3FN_TEXT); long lLength = _wtol(sText) / 1000; - if (lLength) { - CString strLength; - SecToTimeLength(lLength, strLength); - strFidInfo << strLength; - } + if (lLength > 0) + strFidInfo << SecToTimeLength(lLength); delete[] sText; } break; case ID3FID_USERTEXT: { wchar_t *sText = ID3_GetStringW(frame, ID3FN_TEXT); - wchar_t *sDesc = ID3_GetStringW(frame, ID3FN_DESCRIPTION); CString strText(sText); + delete[] sText; if (!strText.Trim().IsEmpty()) { + wchar_t *sDesc = ID3_GetStringW(frame, ID3FN_DESCRIPTION); CString strDesc(sDesc); + delete[] sDesc; if (!strDesc.Trim().IsEmpty()) strFidInfo << _T("(") << strDesc << _T("): "); strFidInfo << strText; } - delete[] sText; - delete[] sDesc; } break; case ID3FID_COMMENT: case ID3FID_UNSYNCEDLYRICS: { wchar_t *sText = ID3_GetStringW(frame, ID3FN_TEXT); - wchar_t *sDesc = ID3_GetStringW(frame, ID3FN_DESCRIPTION); - wchar_t *sLang = ID3_GetStringW(frame, ID3FN_LANGUAGE); CString strText(sText); + delete[] sText; if (!strText.Trim().IsEmpty()) { + wchar_t *sDesc = ID3_GetStringW(frame, ID3FN_DESCRIPTION); CString strDesc(sDesc); + delete[] sDesc; if (strDesc.Trim() == _T("ID3v1 Comment")) strDesc.Empty(); else if (!strDesc.IsEmpty()) strFidInfo << _T("(") << strDesc << _T(")"); + wchar_t *sLang = ID3_GetStringW(frame, ID3FN_LANGUAGE); CString strLang(sLang); + delete[] sLang; if (!strLang.Trim().IsEmpty()) strFidInfo << _T("[") << strLang << _T("]"); @@ -1208,9 +1110,6 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi strFidInfo << _T(": "); strFidInfo << strText; } - delete[] sText; - delete[] sDesc; - delete[] sLang; } break; case ID3FID_WWWAUDIOFILE: @@ -1231,16 +1130,16 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi { wchar_t *sURL = ID3_GetStringW(frame, ID3FN_URL); CString strURL(sURL); + delete[] sURL; if (!strURL.Trim().IsEmpty()) { - wchar_t* sDesc = ID3_GetStringW(frame, ID3FN_DESCRIPTION); + wchar_t *sDesc = ID3_GetStringW(frame, ID3FN_DESCRIPTION); CString strDesc(sDesc); + delete[] sDesc; if (!strDesc.Trim().IsEmpty()) strFidInfo << _T("(") << strDesc << _T("): "); strFidInfo << strURL; - delete[] sDesc; } - delete[] sURL; } break; case ID3FID_INVOLVEDPEOPLE: @@ -1260,11 +1159,11 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi wchar_t *sMimeType = ID3_GetStringW(frame, ID3FN_MIMETYPE); wchar_t *sDesc = ID3_GetStringW(frame, ID3FN_DESCRIPTION); wchar_t *sFormat = ID3_GetStringW(frame, ID3FN_IMAGEFORMAT); - size_t - nPicType = frame->GetField(ID3FN_PICTURETYPE)->Get(), - nDataSize = frame->GetField(ID3FN_DATA)->Size(); + size_t nPicType = frame->GetField(ID3FN_PICTURETYPE)->Get(); + size_t nDataSize = frame->GetField(ID3FN_DATA)->Size(); strFidInfo << _T("(") << sDesc << _T(")[") << sFormat << _T(", ") - << static_cast(nPicType) << _T("]: ") << sMimeType << _T(", ") << static_cast(nDataSize) << _T(" bytes"); + << static_cast(nPicType) << _T("]: ") << sMimeType << _T(", ") + << static_cast(nDataSize) << _T(" bytes"); delete[] sMimeType; delete[] sDesc; delete[] sFormat; @@ -1301,9 +1200,8 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi case ID3FID_POPULARIMETER: { wchar_t *sEmail = ID3_GetStringW(frame, ID3FN_EMAIL); - size_t - nCounter = frame->GetField(ID3FN_COUNTER)->Get(), - nRating = frame->GetField(ID3FN_RATING)->Get(); + size_t nCounter = frame->GetField(ID3FN_COUNTER)->Get(); + size_t nRating = frame->GetField(ID3FN_RATING)->Get(); strFidInfo << sEmail << _T(", counter=") << static_cast(nCounter) << _T(" rating=") << static_cast(nRating); delete[] sEmail; } @@ -1426,28 +1324,27 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi if (!bIsAVI) { try { if (theMediaInfoDLL.Initialize()) { - void *Handle = theMediaInfoDLL.Open(pFile->GetFilePath()); - if (Handle) { + m_handle = theMediaInfoDLL.Open(pFile->GetFilePath()); + if (m_handle) { LPCTSTR pCodec, pCodecInfo, pCodecString, pLanguageInfo; if (theMediaInfoDLL.GetVersion() < MAKEDLLVERULL(18, 6, 0, 0)) { pCodec = _T("Codec"); //deprecated - pCodecInfo = _T("Codec_Info"); - pCodecString = _T("Codec_String"); - pLanguageInfo = _T("Language_Info"); + pCodecInfo = _T("Codec/Info"); + pCodecString = _T("Codec/String"); + pLanguageInfo = _T("Language/Info"); } else { pCodec = _T("Format"); pCodecInfo = _T("Format/Info"); pCodecString = _T("Format/String"); pLanguageInfo = _T("Language_More"); } - - mi->strFileFormat = theMediaInfoDLL.Get(Handle, Stream_General, 0, _T("Format"), Info_Text, Info_Name); - CString str = theMediaInfoDLL.Get(Handle, Stream_General, 0, _T("Format_String"), Info_Text, Info_Name); - if (!str.IsEmpty() && str.Compare(mi->strFileFormat) != 0) + mi->strFileFormat = InfoGet(MediaInfo_Stream_General, 0, _T("Format")); + CString str(InfoGet(MediaInfo_Stream_General, 0, _T("Format/String"))); + if (!str.IsEmpty() && str != mi->strFileFormat) mi->strFileFormat.AppendFormat(_T(" (%s)"), (LPCTSTR)str); if (szExt[0] == _T('.') && szExt[1] != _T('\0')) { - str = theMediaInfoDLL.Get(Handle, Stream_General, 0, _T("Format_Extensions"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_General, 0, _T("Format/Extensions")); if (!str.IsEmpty()) { // minor bug in MediaInfo lib: some file extension lists have a ')' character in there. str.Remove(_T(')')); @@ -1457,50 +1354,35 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi bool bFoundExt = false; for (int iPos = 0; iPos >= 0;) { const CString &strFmtExt(str.Tokenize(_T(" "), iPos)); - if (!strFmtExt.IsEmpty() && strFmtExt.Compare((LPCTSTR)szExt + 1) == 0) { + if (!strFmtExt.IsEmpty() && strFmtExt == CPTR(szExt, 1)) { bFoundExt = true; break; } } - if (!bFoundExt) WarnAboutWrongFileExtension(mi, pFile->GetFileName(), str); } } - CString strTitle = theMediaInfoDLL.Get(Handle, Stream_General, 0, _T("Title"), Info_Text, Info_Name); - const CString &strTitleMore = theMediaInfoDLL.Get(Handle, Stream_General, 0, _T("Title_More"), Info_Text, Info_Name); + CString strTitle(InfoGet(MediaInfo_Stream_General, 0, _T("Title"))); + const CString &strTitleMore(InfoGet(MediaInfo_Stream_General, 0, _T("Title_More"))); if (!strTitleMore.IsEmpty() && !strTitle.IsEmpty() && strTitleMore != strTitle) strTitle.AppendFormat(_T("; %s"), (LPCTSTR)strTitleMore); - const CString &strAuthor = theMediaInfoDLL.Get(Handle, Stream_General, 0, _T("Author"), Info_Text, Info_Name); - const CString &strCopyright = theMediaInfoDLL.Get(Handle, Stream_General, 0, _T("Copyright"), Info_Text, Info_Name); - CString strComments = theMediaInfoDLL.Get(Handle, Stream_General, 0, _T("Comments"), Info_Text, Info_Name); + CString strAuthor(InfoGet(MediaInfo_Stream_General, 0, _T("Performer"))); + if (strAuthor.IsEmpty()) + strAuthor = InfoGet(MediaInfo_Stream_General, 0, _T("Author")); + const CString &strCopyright(InfoGet(MediaInfo_Stream_General, 0, _T("Copyright"))); + CString strComments(InfoGet(MediaInfo_Stream_General, 0, _T("Comments"))); if (strComments.IsEmpty()) - strComments = theMediaInfoDLL.Get(Handle, Stream_General, 0, _T("Comment"), Info_Text, Info_Name); - CString strDate = theMediaInfoDLL.Get(Handle, Stream_General, 0, _T("Date"), Info_Text, Info_Name); + strComments = InfoGet(MediaInfo_Stream_General, 0, _T("Comment")); + CString strDate(InfoGet(MediaInfo_Stream_General, 0, _T("Date"))); if (strDate.IsEmpty()) - strDate = theMediaInfoDLL.Get(Handle, Stream_General, 0, _T("Encoded_Date"), Info_Text, Info_Name); - struct tm tmUtc = {}; - if (_stscanf(strDate, _T("UTC %i-%i-%i %i:%i:%i"), &tmUtc.tm_year, &tmUtc.tm_mon, &tmUtc.tm_mday, &tmUtc.tm_hour, &tmUtc.tm_min, &tmUtc.tm_sec) == 6) { - tmUtc.tm_mon -= 1; - tmUtc.tm_year -= 1900; - tmUtc.tm_isdst = -1; - time_t tLocal = mktime(&tmUtc); // convert UTC to local time - if (tLocal != -1) { - // convert local time to UTC - time_t tUtc = tLocal - _timezone; - if (tmUtc.tm_isdst == 1) - tUtc -= _dstbias; - - // output 'date+time' or just 'date' - struct tm *tmLoc = localtime(&tUtc); - if (tmLoc && tmLoc->tm_hour == 0 && tmLoc->tm_min == 0 && tmLoc->tm_sec == 0) - strDate = CTime(tUtc).Format(_T("%x")); - else - strDate = CTime(tUtc).Format(_T("%c")); - } - } - + strDate = InfoGet(MediaInfo_Stream_General, 0, _T("Encoded_Date")); + /* + * Removed conversion of UTC time to local: + * 1) _stscanf fails on strings such as "2000-09-08" (8 and 9 are not octal); + * 2) the original time zone is unknown. + */ if (!strTitle.IsEmpty() || !strAuthor.IsEmpty() || !strCopyright.IsEmpty() || !strComments.IsEmpty() || !strDate.IsEmpty()) { if (!mi->strInfo.IsEmpty()) mi->strInfo << _T("\n"); @@ -1519,42 +1401,44 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi mi->strInfo << _T(" ") << GetResString(IDS_DATE) << _T(":\t") << strDate << _T("\n"); } - str = theMediaInfoDLL.Get(Handle, Stream_General, 0, _T("PlayTime"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_General, 0, _T("Duration")); + if (str.IsEmpty()) + str = InfoGet(MediaInfo_Stream_General, 0, _T("PlayTime")); //deprecated float fFileLengthSec = _tstoi(str) / 1000.0F; UINT uAllBitrates = 0; - str = theMediaInfoDLL.Get(Handle, Stream_General, 0, _T("VideoCount"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_General, 0, _T("VideoCount")); int iVideoStreams = _tstoi(str); if (iVideoStreams > 0) { mi->iVideoStreams = iVideoStreams; mi->fVideoLengthSec = fFileLengthSec; - const CString &strCodec = theMediaInfoDLL.Get(Handle, Stream_Video, 0, pCodec, Info_Text, Info_Name); - mi->strVideoFormat = strCodec; - if (!strCodec.IsEmpty()) { - CStringA strCodecA(strCodec); + str = InfoGet(MediaInfo_Stream_Video, 0, pCodec); + mi->strVideoFormat = str; + if (!str.IsEmpty()) { + CStringA strCodecA(str); if (!strCodecA.IsEmpty()) mi->video.bmiHeader.biCompression = *(LPDWORD)(LPCSTR)strCodecA; } - str = theMediaInfoDLL.Get(Handle, Stream_Video, 0, pCodecString, Info_Text, Info_Name); - if (!str.IsEmpty() && str.Compare(mi->strVideoFormat) != 0) + str = InfoGet(MediaInfo_Stream_Video, 0, pCodecString); + if (!str.IsEmpty() && str != mi->strVideoFormat) mi->strVideoFormat.AppendFormat(_T(" (%s)"), (LPCTSTR)str); - str = theMediaInfoDLL.Get(Handle, Stream_Video, 0, _T("Width"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Video, 0, _T("Width")); mi->video.bmiHeader.biWidth = _tstoi(str); - str = theMediaInfoDLL.Get(Handle, Stream_Video, 0, _T("Height"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Video, 0, _T("Height")); mi->video.bmiHeader.biHeight = _tstoi(str); - str = theMediaInfoDLL.Get(Handle, Stream_Video, 0, _T("FrameRate"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Video, 0, _T("FrameRate")); mi->fVideoFrameRate = _tstof(str); - str = theMediaInfoDLL.Get(Handle, Stream_Video, 0, _T("BitRate_Mode"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Video, 0, _T("BitRate_Mode")); if (str.CompareNoCase(_T("VBR")) == 0) { mi->video.dwBitRate = _UI32_MAX; uAllBitrates = _UI32_MAX; } else { - str = theMediaInfoDLL.Get(Handle, Stream_Video, 0, _T("BitRate"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Video, 0, _T("BitRate")); int iBitrate = _tstoi(str); mi->video.dwBitRate = iBitrate == -1 ? -1 : iBitrate; if (iBitrate == -1) @@ -1563,7 +1447,7 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi uAllBitrates += iBitrate; } - str = theMediaInfoDLL.Get(Handle, Stream_Video, 0, _T("AspectRatio"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Video, 0, _T("AspectRatio")); mi->fVideoAspectRatio = _tstof(str); for (int s = 1; s < iVideoStreams; ++s) { @@ -1573,20 +1457,20 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi mi->strInfo.SetSelectionCharFormat(mi->strInfo.m_cfBold); mi->strInfo << GetResString(IDS_VIDEO) << _T(" #") << s + 1 << _T("\n"); - CString strVideoFormat = theMediaInfoDLL.Get(Handle, Stream_Video, s, pCodec, Info_Text, Info_Name); - str = theMediaInfoDLL.Get(Handle, Stream_Video, s, pCodecString, Info_Text, Info_Name); - if (!str.IsEmpty() && str.Compare(strVideoFormat) != 0) + CString strVideoFormat(InfoGet(MediaInfo_Stream_Video, s, pCodec)); + str = InfoGet(MediaInfo_Stream_Video, s, pCodecString); + if (!str.IsEmpty() && str != strVideoFormat) strVideoFormat.AppendFormat(_T(" (%s)"), (LPCTSTR)str); if (!strVideoFormat.IsEmpty()) mi->strInfo << _T(" ") << GetResString(IDS_CODEC) << _T(":\t") << strVideoFormat << _T("\n"); CString strBitrate; - str = theMediaInfoDLL.Get(Handle, Stream_Video, s, _T("BitRate_Mode"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Video, s, _T("BitRate_Mode")); if (str.CompareNoCase(_T("VBR")) == 0) { strBitrate = _T("Variable"); uAllBitrates = _UI32_MAX; } else { - str = theMediaInfoDLL.Get(Handle, Stream_Video, s, _T("BitRate"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Video, s, _T("BitRate")); int iBitrate = _tstoi(str); if (iBitrate != 0) { if (iBitrate == -1) { @@ -1602,16 +1486,16 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi if (!strBitrate.IsEmpty()) mi->strInfo << _T(" ") << GetResString(IDS_BITRATE) << _T(":\t") << strBitrate << _T("\n"); - const CString &strWidth = theMediaInfoDLL.Get(Handle, Stream_Video, s, _T("Width"), Info_Text, Info_Name); - const CString &strHeight = theMediaInfoDLL.Get(Handle, Stream_Video, s, _T("Height"), Info_Text, Info_Name); + const CString &strWidth(InfoGet(MediaInfo_Stream_Video, s, _T("Width"))); + const CString &strHeight(InfoGet(MediaInfo_Stream_Video, s, _T("Height"))); if (!strWidth.IsEmpty() && !strHeight.IsEmpty()) mi->strInfo << _T(" ") << GetResString(IDS_WIDTH) << _T(" x ") << GetResString(IDS_HEIGHT) << _T(":\t") << strWidth << _T(" x ") << strHeight << _T("\n"); - str = theMediaInfoDLL.Get(Handle, Stream_Video, s, _T("AspectRatio"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Video, s, _T("AspectRatio")); if (!str.IsEmpty()) mi->strInfo << _T(" ") << GetResString(IDS_ASPECTRATIO) << _T(":\t") << str << _T(" (") << GetKnownAspectRatioDisplayString((float)_tstof(str)) << _T(")\n"); - str = theMediaInfoDLL.Get(Handle, Stream_Video, s, _T("FrameRate"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Video, s, _T("FrameRate")); if (!str.IsEmpty()) mi->strInfo << _T(" ") << GetResString(IDS_FPS) << _T(":\t") << str << _T("\n"); } @@ -1619,35 +1503,35 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi bFoundHeader = true; } - str = theMediaInfoDLL.Get(Handle, Stream_General, 0, _T("AudioCount"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_General, 0, _T("AudioCount")); int iAudioStreams = _tstoi(str); if (iAudioStreams > 0) { mi->iAudioStreams = iAudioStreams; mi->fAudioLengthSec = fFileLengthSec; - str = theMediaInfoDLL.Get(Handle, Stream_Audio, 0, pCodec, Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Audio, 0, pCodec); if (_stscanf(str, _T("%hx"), &mi->audio.wFormatTag) != 1) { mi->strAudioFormat = str; - str = theMediaInfoDLL.Get(Handle, Stream_Audio, 0, pCodecString, Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Audio, 0, pCodecString); } else { - mi->strAudioFormat = theMediaInfoDLL.Get(Handle, Stream_Audio, 0, pCodecString, Info_Text, Info_Name); - str = theMediaInfoDLL.Get(Handle, Stream_Audio, 0, pCodecInfo, Info_Text, Info_Name); + mi->strAudioFormat = InfoGet(MediaInfo_Stream_Audio, 0, pCodecString); + str = InfoGet(MediaInfo_Stream_Audio, 0, pCodecInfo); } - if (!str.IsEmpty() && str.Compare(mi->strAudioFormat) != 0) + if (!str.IsEmpty() && str != mi->strAudioFormat) mi->strAudioFormat.AppendFormat(_T(" (%s)"), (LPCTSTR)str); - str = theMediaInfoDLL.Get(Handle, Stream_Audio, 0, _T("Channels"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Audio, 0, _T("Channel(s)")); mi->audio.nChannels = (WORD)_tstoi(str); - str = theMediaInfoDLL.Get(Handle, Stream_Audio, 0, _T("SamplingRate"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Audio, 0, _T("SamplingRate")); mi->audio.nSamplesPerSec = _tstoi(str); - str = theMediaInfoDLL.Get(Handle, Stream_Audio, 0, _T("BitRate_Mode"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Audio, 0, _T("BitRate_Mode")); if (str.CompareNoCase(_T("VBR")) == 0) { mi->audio.nAvgBytesPerSec = _UI32_MAX; uAllBitrates = _UI32_MAX; } else { - str = theMediaInfoDLL.Get(Handle, Stream_Audio, 0, _T("BitRate"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Audio, 0, _T("BitRate")); int iBitrate = _tstoi(str); mi->audio.nAvgBytesPerSec = iBitrate == -1 ? -1 : iBitrate / 8; if (iBitrate == -1) @@ -1656,9 +1540,9 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi uAllBitrates += iBitrate; } - mi->strAudioLanguage = theMediaInfoDLL.Get(Handle, Stream_Audio, 0, _T("Language_String"), Info_Text, Info_Name); + mi->strAudioLanguage = InfoGet(MediaInfo_Stream_Audio, 0, _T("Language/String")); if (mi->strAudioLanguage.IsEmpty()) - mi->strAudioLanguage = theMediaInfoDLL.Get(Handle, Stream_Audio, 0, _T("Language"), Info_Text, Info_Name); + mi->strAudioLanguage = InfoGet(MediaInfo_Stream_Audio, 0, _T("Language")); for (int s = 1; s < iAudioStreams; ++s) { if (!mi->strInfo.IsEmpty()) @@ -1667,30 +1551,25 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi mi->strInfo.SetSelectionCharFormat(mi->strInfo.m_cfBold); mi->strInfo << GetResString(IDS_AUDIO) << _T(" #") << s + 1 << _T("\n"); - str = theMediaInfoDLL.Get(Handle, Stream_Audio, s, pCodec, Info_Text, Info_Name); + CString strAudioFormat(InfoGet(MediaInfo_Stream_Audio, s, pCodec)); + str = InfoGet(MediaInfo_Stream_Audio, s, pCodecString); WORD wFormatTag; - CString strAudioFormat; - if (_stscanf(str, _T("%hx"), &wFormatTag) != 1) { + if (_stscanf(str, _T("%hx"), &wFormatTag) == 1) { strAudioFormat = str; - str = theMediaInfoDLL.Get(Handle, Stream_Audio, s, pCodecString, Info_Text, Info_Name); - if (!str.IsEmpty() && str.Compare(strAudioFormat) != 0) - strAudioFormat.AppendFormat(_T(" (%s)"), (LPCTSTR)str); - } else { - strAudioFormat = theMediaInfoDLL.Get(Handle, Stream_Audio, s, pCodecString, Info_Text, Info_Name); - str = theMediaInfoDLL.Get(Handle, Stream_Audio, s, pCodecInfo, Info_Text, Info_Name); - if (!str.IsEmpty() && str.Compare(strAudioFormat) != 0) - strAudioFormat.AppendFormat(_T(" (%s)"), (LPCTSTR)str); + str = InfoGet(MediaInfo_Stream_Audio, s, pCodecInfo); } + if (!str.IsEmpty() && str != strAudioFormat) + strAudioFormat.AppendFormat(_T(" (%s)"), (LPCTSTR)str); if (!strAudioFormat.IsEmpty()) mi->strInfo << _T(" ") << GetResString(IDS_CODEC) << _T(":\t") << strAudioFormat << _T("\n"); CString strBitrate; - str = theMediaInfoDLL.Get(Handle, Stream_Audio, s, _T("BitRate_Mode"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Audio, s, _T("BitRate_Mode")); if (str.CompareNoCase(_T("VBR")) == 0) { strBitrate = _T("Variable"); uAllBitrates = _UI32_MAX; } else { - str = theMediaInfoDLL.Get(Handle, Stream_Audio, s, _T("BitRate"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Audio, s, _T("BitRate")); int iBitrate = _tstoi(str); if (iBitrate != 0) { if (iBitrate == -1) { @@ -1706,7 +1585,7 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi if (!strBitrate.IsEmpty()) mi->strInfo << _T(" ") << GetResString(IDS_BITRATE) << _T(":\t") << strBitrate << _T("\n"); - str = theMediaInfoDLL.Get(Handle, Stream_Audio, s, _T("Channels"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Audio, s, _T("Channel(s)")); if (!str.IsEmpty()) { int iChannels = _tstoi(str); mi->strInfo << _T(" ") << GetResString(IDS_CHANNELS) << _T(":\t"); @@ -1721,17 +1600,17 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi mi->strInfo << _T("\n"); } - str = theMediaInfoDLL.Get(Handle, Stream_Audio, s, _T("SamplingRate"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Audio, s, _T("SamplingRate")); if (!str.IsEmpty()) mi->strInfo << _T(" ") << GetResString(IDS_SAMPLERATE) << _T(":\t") << _tstoi(str) / 1000.0 << _T(" kHz\n"); - str = theMediaInfoDLL.Get(Handle, Stream_Audio, s, _T("Language_String"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Audio, s, _T("Language/String")); if (str.IsEmpty()) - str = theMediaInfoDLL.Get(Handle, Stream_Audio, s, _T("Language"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Audio, s, _T("Language")); if (!str.IsEmpty()) mi->strInfo << _T(" ") << GetResString(IDS_PW_LANG) << _T(":\t") << str << _T("\n"); - str = theMediaInfoDLL.Get(Handle, Stream_Audio, s, pLanguageInfo, Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Audio, s, pLanguageInfo); if (!str.IsEmpty()) mi->strInfo << _T(" ") << GetResString(IDS_PW_LANG) << _T(":\t") << str << _T("\n"); } @@ -1739,7 +1618,7 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi bFoundHeader = true; } - str = theMediaInfoDLL.Get(Handle, Stream_General, 0, _T("TextCount"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_General, 0, _T("TextCount")); int iTextStreams = _tstoi(str); for (int s = 0; s < iTextStreams; ++s) { if (!mi->strInfo.IsEmpty()) @@ -1748,44 +1627,51 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi mi->strInfo.SetSelectionCharFormat(mi->strInfo.m_cfBold); mi->strInfo << _T("Subtitle") << _T(" #") << s + 1 << _T("\n"); - str = theMediaInfoDLL.Get(Handle, Stream_Text, s, pCodec, Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Text, s, pCodec); if (!str.IsEmpty()) mi->strInfo << _T(" ") << GetResString(IDS_CODEC) << _T(":\t") << str << _T("\n"); - str = theMediaInfoDLL.Get(Handle, Stream_Text, s, _T("Language_String"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Text, s, _T("Language/String")); if (str.IsEmpty()) - str = theMediaInfoDLL.Get(Handle, Stream_Text, s, _T("Language"), Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Text, s, _T("Language")); if (!str.IsEmpty()) mi->strInfo << _T(" ") << GetResString(IDS_PW_LANG) << _T(":\t") << str << _T("\n"); - str = theMediaInfoDLL.Get(Handle, Stream_Text, s, pLanguageInfo, Info_Text, Info_Name); + str = InfoGet(MediaInfo_Stream_Text, s, pLanguageInfo); if (!str.IsEmpty()) mi->strInfo << _T(" ") << GetResString(IDS_PW_LANG) << _T(":\t") << str << _T("\n"); } - str = theMediaInfoDLL.Get(Handle, Stream_General, 0, _T("ChaptersCount"), Info_Text, Info_Name); - int iChapterStreams = _tstoi(str); - for (int s = 0; s < iChapterStreams; ++s) { + str = InfoGet(MediaInfo_Stream_General, 0, _T("MenuCount")); + int iMenuStreams = _tstoi(str); + for (int m = 0; m < iMenuStreams; ++m) { if (!mi->strInfo.IsEmpty()) mi->strInfo << _T("\n"); mi->OutputFileName(); mi->strInfo.SetSelectionCharFormat(mi->strInfo.m_cfBold); - mi->strInfo << _T("Chapter") << _T(" #") << s + 1 << _T("\n"); + mi->strInfo << _T("Menu") << _T(" #") << m + 1 << _T("\n"); - str = theMediaInfoDLL.Get(Handle, Stream_Chapters, s, pCodec, Info_Text, Info_Name); - if (!str.IsEmpty()) - mi->strInfo << _T(" ") << GetResString(IDS_CODEC) << _T(":\t") << str << _T("\n"); + str = InfoGet(MediaInfo_Stream_Menu, m, _T("Chapters_Pos_Begin")); + int iBegin = _tstoi(str); + str = InfoGet(MediaInfo_Stream_Menu, m, _T("Chapters_Pos_End")); + int iEnd = _tstoi(str); + for (int s = iBegin; s < iEnd; ++s) { + if (!mi->strInfo.IsEmpty()) + mi->strInfo << _T("\n"); + mi->OutputFileName(); - str = theMediaInfoDLL.Get(Handle, Stream_Chapters, s, _T("Language_String"), Info_Text, Info_Name); - if (!str.IsEmpty()) - mi->strInfo << _T(" ") << GetResString(IDS_PW_LANG) << _T(":\t") << str << _T("\n"); + mi->strInfo.SetSelectionCharFormat(mi->strInfo.m_cfBold); + mi->strInfo << _T(" Chapter") << _T(" #") << s - iBegin + 1 << _T("\n"); - str = theMediaInfoDLL.Get(Handle, Stream_Chapters, s, pLanguageInfo, Info_Text, Info_Name); - if (!str.IsEmpty()) - mi->strInfo << _T(" ") << GetResString(IDS_PW_LANG) << _T(":\t") << str << _T("\n"); + str = InfoGetI(MediaInfo_Stream_Menu, m, s, MediaInfo_Info_Name); + mi->strInfo << _T(" ") << str << _T("\t"); + str = InfoGetI(MediaInfo_Stream_Menu, m, s, MediaInfo_Info_Text); + mi->strInfo << str << _T("\n"); + } } - theMediaInfoDLL.Close(Handle); + theMediaInfoDLL.Close(m_handle); + m_handle = NULL; // MediaInfoLib does not handle MPEG files correctly in regards of // play length property -- even for completed files (applies also for @@ -1801,33 +1687,27 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi if (uAllBitrates != 0 /* do we have any bit rates? */ && uAllBitrates != _UI32_MAX) /* do we have CBR only? */ { - // Though, its not that easy to calculate the real play length + // Though, it's not that easy to calculate the real play length // without including the container's overhead. The value we // calculate with this simple formula is slightly too large! // But, its still better than using GOP-derived values which are // sometimes completely wrong. - fFileLengthSec = ((uint64)pFile->GetFileSize() * 8.0f / uAllBitrates); + fFileLengthSec = (uint64)pFile->GetFileSize() * 8.0f / uAllBitrates; if (mi->iVideoStreams > 0) { // Try to compensate the error from above by estimating the overhead if (mi->fVideoFrameRate > 0) { ULONGLONG uFrames = (ULONGLONG)(fFileLengthSec * mi->fVideoFrameRate); - fFileLengthSec = (((uint64)pFile->GetFileSize() - uFrames * 24) * 8.0f / uAllBitrates); + fFileLengthSec = ((uint64)pFile->GetFileSize() - uFrames * 24) * 8.0f / uAllBitrates; } mi->fVideoLengthSec = fFileLengthSec; - mi->bVideoLengthEstimated = true; - } - if (mi->iAudioStreams > 0) { - mi->fAudioLengthSec = fFileLengthSec; - mi->bAudioLengthEstimated = true; } - } else { - // set the 'estimated' flags in case we any VBR stream - if (mi->iVideoStreams > 0) - mi->bVideoLengthEstimated = true; if (mi->iAudioStreams > 0) - mi->bAudioLengthEstimated = true; + mi->fAudioLengthSec = fFileLengthSec; } + // set the 'estimated' flags in case of any VBR stream + mi->bVideoLengthEstimated |= (mi->iVideoStreams > 0); + mi->bAudioLengthEstimated |= (mi->iAudioStreams > 0); } if (bFoundHeader) { @@ -1836,9 +1716,8 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi } } } else { - EED2KFileType eED2KFileType = GetED2KFileTypeID(pFile->GetFilePath()); - if (eED2KFileType == ED2KFT_AUDIO || eED2KFileType == ED2KFT_VIDEO) - bGiveMediaInfoLibHint = true; + EED2KFileType FileType = GetED2KFileTypeID(pFile->GetFilePath()); + bGiveMediaInfoLibHint |= (FileType == ED2KFT_AUDIO || FileType == ED2KFT_VIDEO); } } catch (...) { ASSERT(0); @@ -1870,7 +1749,7 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi GUID major_type; if (SUCCEEDED(pMediaDet->get_StreamType(&major_type))) { if (major_type == MEDIATYPE_Video) { - mi->iVideoStreams++; + ++mi->iVideoStreams; if (mi->iVideoStreams > 1) { if (!mi->strInfo.IsEmpty()) @@ -1914,9 +1793,7 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi if (mi->iVideoStreams == 1) mi->fVideoLengthSec = fLength; else { - CString strLength; - SecToTimeLength((ULONG)fLength, strLength); - mi->strInfo << _T(" ") << GetResString(IDS_LENGTH) << _T(":\t") << strLength; + mi->strInfo << _T(" ") << GetResString(IDS_LENGTH) << _T(":\t") << SecToTimeLength((UINT)fLength); if (pFile->IsPartFile()) { mi->strInfo.SetSelectionCharFormat(mi->strInfo.m_cfRed); mi->strInfo << _T(" (") << GetResString(IDS_ESTIMATED) << _T(")"); @@ -1928,10 +1805,9 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi if (mt.pUnk != NULL) mt.pUnk->Release(); - if (mt.pbFormat != NULL) - CoTaskMemFree(mt.pbFormat); + ::CoTaskMemFree(mt.pbFormat); } else if (major_type == MEDIATYPE_Audio) { - mi->iAudioStreams++; + ++mi->iAudioStreams; if (mi->iAudioStreams > 1) { if (!mi->strInfo.IsEmpty()) @@ -2001,9 +1877,7 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi if (mi->iAudioStreams == 1) mi->fAudioLengthSec = fLength; else { - CString strLength; - SecToTimeLength((ULONG)fLength, strLength); - mi->strInfo << _T(" ") << GetResString(IDS_LENGTH) << _T(":\t") << strLength; + mi->strInfo << _T(" ") << GetResString(IDS_LENGTH) << _T(":\t") << SecToTimeLength((UINT)fLength); if (pFile->IsPartFile()) { mi->strInfo.SetSelectionCharFormat(mi->strInfo.m_cfRed); mi->strInfo << _T(" (") << GetResString(IDS_ESTIMATED) << _T(")"); @@ -2015,8 +1889,7 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi if (mt.pUnk != NULL) mt.pUnk->Release(); - if (mt.pbFormat != NULL) - CoTaskMemFree(mt.pbFormat); + ::CoTaskMemFree(mt.pbFormat); } else { if (!mi->strInfo.IsEmpty()) mi->strInfo << _T("\n"); @@ -2026,9 +1899,7 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi double fLength; if (SUCCEEDED(pMediaDet->get_StreamLength(&fLength)) && fLength) { - CString strLength; - SecToTimeLength((ULONG)fLength, strLength); - mi->strInfo << _T(" ") << GetResString(IDS_LENGTH) << _T(":\t") << strLength; + mi->strInfo << _T(" ") << GetResString(IDS_LENGTH) << _T(":\t") << SecToTimeLength((UINT)fLength); if (pFile->IsPartFile()) { mi->strInfo.SetSelectionCharFormat(mi->strInfo.m_cfRed); mi->strInfo << _T(" (") << GetResString(IDS_ESTIMATED) << _T(")"); @@ -2062,7 +1933,7 @@ bool CGetMediaInfoThread::GetMediaInfo(HWND hWndOwner, const CShareableFile *pFi if (dwModPathLen == 0 || dwModPathLen == _countof(szBuff)) szBuff[0] = _T('\0'); CString strInstFolder(szBuff); - PathRemoveFileSpec(strInstFolder.GetBuffer(strInstFolder.GetLength())); + ::PathRemoveFileSpec(strInstFolder.GetBuffer(strInstFolder.GetLength())); strInstFolder.ReleaseBuffer(); CString strHint; strHint.Format(GetResString(IDS_MEDIAINFO_DLLMISSING), (LPCTSTR)strInstFolder); @@ -2105,18 +1976,4 @@ void CFileInfoDialog::Localize() SetDlgItemText(IDC_STATIC_LANGUAGE, GetResString(IDS_PW_LANG) + _T(':')); if (!m_bReducedDlg) SetDlgItemText(IDC_FD_XI1, GetResString(IDS_FD_SIZE)); -} -/* -void CFileInfoDialog::AddFileInfo(LPCTSTR pszFmt, ...) -{ - if (m_bReducedDlg) - return; - va_list pArgp; - va_start(pArgp, pszFmt); - CString strInfo; - strInfo.FormatV(pszFmt, pArgp); - va_end(pArgp); - - m_fi.SetSel(m_fi.GetWindowTextLength(), m_fi.GetWindowTextLength()); - m_fi.ReplaceSel(strInfo); -}*/ \ No newline at end of file +} \ No newline at end of file diff --git a/srchybrid/FileInfoDialog.h b/srchybrid/FileInfoDialog.h index dff5e980..8702679f 100644 --- a/srchybrid/FileInfoDialog.h +++ b/srchybrid/FileInfoDialog.h @@ -31,10 +31,10 @@ class CFileInfoDialog : public CResizablePage { IDD = IDD_FILEINFO }; + void InitDisplay(LPCTSTR pStr); CSimpleArray m_pFiles; public: CFileInfoDialog(); // standard constructor - virtual ~CFileInfoDialog() = default; virtual BOOL OnInitDialog(); void SetFiles(const CSimpleArray *paFiles) { m_paFiles = paFiles; m_bDataChanged = true; } @@ -46,12 +46,6 @@ class CFileInfoDialog : public CResizablePage bool m_bDataChanged; CRichEditCtrlX m_fi; bool m_bReducedDlg; - //CHARFORMAT m_cfDef; - //CHARFORMAT m_cfBold; - //CHARFORMAT m_cfRed; - - //bool GetMediaInfo(const CKnownFile *file, SMediaInfo *mi, bool bSingleFile); - //void AddFileInfo(LPCTSTR pszFmt, ...); virtual void DoDataExchange(CDataExchange *pDX); // DDX/DDV support virtual BOOL OnSetActive(); diff --git a/srchybrid/FirewallOpener.cpp b/srchybrid/FirewallOpener.cpp index 4bf0347a..e753d6eb 100644 --- a/srchybrid/FirewallOpener.cpp +++ b/srchybrid/FirewallOpener.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -188,11 +188,12 @@ bool CFirewallOpener::AddRule(const CICSRuleInfo &riPortRule, const INetSharingC , &pNSPM); CComBSTR bstrName; pNCP->get_Name(&bstrName); + const CString sName(bstrName); if (SUCCEEDED(hr) && SUCCEEDED(pNSPM->Enable())) { - theApp.QueueDebugLogLine(false, _T("Succeeded to add Rule '%s' for Port '%u' on Connection '%s'"), (LPCTSTR)riPortRule.m_strRuleName, riPortRule.m_nPortNumber, (LPCTSTR)CString(bstrName)); + theApp.QueueDebugLogLine(false, _T("Succeeded to add Rule '%s' for Port '%u' on Connection '%s'"), (LPCTSTR)riPortRule.m_strRuleName, riPortRule.m_nPortNumber, (LPCTSTR)sName); return true; } - theApp.QueueDebugLogLine(false, _T("Failed to add Rule '%s' for Port '%u' on Connection '%s'"), (LPCTSTR)riPortRule.m_strRuleName, riPortRule.m_nPortNumber, (LPCTSTR)CString(bstrName)); + theApp.QueueDebugLogLine(false, _T("Failed to add Rule '%s' for Port '%u' on Connection '%s'"), (LPCTSTR)riPortRule.m_strRuleName, riPortRule.m_nPortNumber, (LPCTSTR)sName); return false; } diff --git a/srchybrid/FirewallOpener.h b/srchybrid/FirewallOpener.h index 960b5c62..edc97af2 100644 --- a/srchybrid/FirewallOpener.h +++ b/srchybrid/FirewallOpener.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/Flex.skl b/srchybrid/Flex.skl index 58b2da52..0dad0f7f 100644 --- a/srchybrid/Flex.skl +++ b/srchybrid/Flex.skl @@ -27,8 +27,8 @@ %+ #include class istream; -using std::cin; -using std::cout; +using std::cin; +using std::cout; using std::cerr; %* #ifndef _WIN32 diff --git a/srchybrid/FrameGrabThread.cpp b/srchybrid/FrameGrabThread.cpp index b68e1fff..86c51ea7 100644 --- a/srchybrid/FrameGrabThread.cpp +++ b/srchybrid/FrameGrabThread.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2003 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2003-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -16,10 +16,10 @@ //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "stdafx.h" #include "emule.h" -#include "FrameGrabThread.h" #include "CxImage/xImage.h" -#include "OtherFunctions.h" #include "quantize.h" +#include "FrameGrabThread.h" +#include "OtherFunctions.h" #ifndef HAVE_QEDIT_H // This is a remote feature and not optional, in order to keep to working properly for other clients who want to use it // Check emule_site_config.h to fix it @@ -91,7 +91,7 @@ BOOL CFrameGrabThread::InitInstance() BOOL CFrameGrabThread::Run() { - imgResults = new CxImage*[nFramesToGrab]; + imgResults = new CxImage*[nFramesToGrab]{}; FrameGrabResult_Struct *result = new FrameGrabResult_Struct; (void)CoInitialize(NULL); result->nImagesGrabbed = (uint8)GrabFrames(); @@ -110,8 +110,6 @@ BOOL CFrameGrabThread::Run() UINT CFrameGrabThread::GrabFrames() { #define TIMEBETWEENFRAMES 50.0 // could be a param later, if needed - for (int i = nFramesToGrab; --i >= 0;) - imgResults[i] = NULL; try { HRESULT hr; CComPtr pDet; @@ -160,7 +158,7 @@ UINT CFrameGrabThread::GrabFrames() /*FreeMediaType(mt); = */ if (mt.cbFormat != 0) { - CoTaskMemFree((PVOID)mt.pbFormat); + ::CoTaskMemFree((PVOID)mt.pbFormat); mt.cbFormat = 0; mt.pbFormat = NULL; } @@ -173,63 +171,62 @@ UINT CFrameGrabThread::GrabFrames() uint32 nFramesGrabbed; for (nFramesGrabbed = 0; nFramesGrabbed < nFramesToGrab; ++nFramesGrabbed) { long size; - hr = pDet->GetBitmapBits(dStartTime + (nFramesGrabbed*TIMEBETWEENFRAMES), &size, NULL, width, height); + hr = pDet->GetBitmapBits(dStartTime + (nFramesGrabbed * TIMEBETWEENFRAMES), &size, NULL, width, height); if (SUCCEEDED(hr)) { // we could also directly create a Bitmap in memory, however this caused problems/failed with *some* movie files // when I tried it for the MMPreview, while this method works always - so I'll continue to use this one - long nFullBufferLen = sizeof(BITMAPFILEHEADER) + size; + uint32_t nFullBufferLen = static_cast(sizeof(BITMAPFILEHEADER) + size); char *buffer = new char[nFullBufferLen]; - BITMAPFILEHEADER bfh = {}; - bfh.bfType = 'MB'; - bfh.bfSize = nFullBufferLen; - bfh.bfOffBits = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER); - memcpy(buffer, &bfh, sizeof bfh); + BITMAPFILEHEADER *pHdr = reinterpret_cast(buffer); + memset(buffer, 0, sizeof(BITMAPFILEHEADER)); + pHdr->bfType = 'MB'; + pHdr->bfSize = nFullBufferLen; + pHdr->bfOffBits = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER); try { - hr = pDet->GetBitmapBits(dStartTime + (nFramesGrabbed*TIMEBETWEENFRAMES), NULL, buffer + sizeof bfh, width, height); + hr = pDet->GetBitmapBits(dStartTime + nFramesGrabbed * TIMEBETWEENFRAMES, NULL, &buffer[sizeof(BITMAPFILEHEADER)], width, height); } catch (...) { ASSERT(0); hr = E_FAIL; } - if (SUCCEEDED(hr)) { - // decode - CxImage *imgResult = new CxImage(); - imgResult->Decode((BYTE*)buffer, nFullBufferLen, CXIMAGE_FORMAT_BMP); - delete[] buffer; - if (!imgResult->IsValid()) { - delete imgResult; - break; - } - - // resize if needed - if (nMaxWidth > 0 && nMaxWidth < width) { - float scale = (float)nMaxWidth / imgResult->GetWidth(); - int nMaxHeigth = (int)(imgResult->GetHeight() * scale); - imgResult->Resample(nMaxWidth, nMaxHeigth, 0); - } - - // decrease bpp if needed - if (bReduceColor) { - RGBQUAD *ppal = (RGBQUAD*)malloc(256 * sizeof(RGBQUAD)); - if (ppal) { - CQuantizer q(256, 8); - q.ProcessImage(imgResult->GetDIB()); - q.SetColorTable(ppal); - imgResult->DecreaseBpp(8, true, ppal); - free(ppal); - } - } - - //CString TestName; - //TestName.Format("G:\\testframe%i.png",nFramesGrabbed); - //imgResult->Save(TestName,CXIMAGE_FORMAT_PNG); - // done - imgResults[nFramesGrabbed] = imgResult; - } else { + + if (FAILED(hr)) { delete[] buffer; break; } + + // decode + CxImage *imgResult = new CxImage(); + imgResult->Decode((uint8_t*)buffer, nFullBufferLen, CXIMAGE_FORMAT_BMP); + delete[] buffer; + if (!imgResult->IsValid()) { + delete imgResult; + break; + } + + // resize if needed + if (nMaxWidth > 0 && nMaxWidth < width) { + float scale = (float)nMaxWidth / imgResult->GetWidth(); + int32_t nMaxHeigth = (int32_t)(imgResult->GetHeight() * scale); + imgResult->Resample(nMaxWidth, nMaxHeigth, 0); + } + + // decrease bpp if needed + if (bReduceColor) { + RGBQUAD pal[256]; + CQuantizer q(_countof(pal), 8); + q.ProcessImage(imgResult->GetDIB()); + q.SetColorTable(pal); + imgResult->DecreaseBpp(8, true, pal); + } +#if TEST_FRAMEGRABBER //see also "case MP_OPEN" in CSharedFilesCtrl::OnContextMenu + CString TestName; + TestName.Format(_T("G:\\em\\testframe%i.png"), nFramesGrabbed); + imgResult->Save(TestName, CXIMAGE_FORMAT_PNG); //Save grabbed images for inspection +#endif + // done + imgResults[nFramesGrabbed] = imgResult; } } return nFramesGrabbed; diff --git a/srchybrid/FrameGrabThread.h b/srchybrid/FrameGrabThread.h index a7330e35..cf3bec90 100644 --- a/srchybrid/FrameGrabThread.h +++ b/srchybrid/FrameGrabThread.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2003 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2003-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -34,7 +34,7 @@ class CFrameGrabThread : public CWinThread protected: CFrameGrabThread(); // protected constructor used by dynamic creation - virtual ~CFrameGrabThread() = default; + DECLARE_MESSAGE_MAP() UINT GrabFrames(); public: @@ -48,7 +48,7 @@ class CFrameGrabThread : public CWinThread const CKnownFile *pOwner; void *pSender; double dStartTime; - uint16 nMaxWidth; + int32_t nMaxWidth; uint8 nFramesToGrab; bool bReduceColor; }; \ No newline at end of file diff --git a/srchybrid/Friend.cpp b/srchybrid/Friend.cpp index 2fa43e48..89f970af 100644 --- a/srchybrid/Friend.cpp +++ b/srchybrid/Friend.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -16,11 +16,10 @@ //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "stdafx.h" #include "emule.h" -#include "Friend.h" -#include "FriendList.h" -#include "OtherFunctions.h" #include "UpDownClient.h" #include "Packets.h" +#include "Friend.h" +#include "FriendList.h" #include "SafeFile.h" #include "clientlist.h" #include "ListenSocket.h" @@ -93,15 +92,15 @@ CFriend::~CFriend() Kademlia::CKademlia::CancelClientSearch(*this); } -void CFriend::LoadFromFile(CFileDataIO *file) +void CFriend::LoadFromFile(CFileDataIO &file) { - file->ReadHash16(m_abyUserhash); - m_dwLastUsedIP = file->ReadUInt32(); - m_nLastUsedPort = file->ReadUInt16(); - m_dwLastSeen = file->ReadUInt32(); - m_dwLastChatted = file->ReadUInt32(); + file.ReadHash16(m_abyUserhash); + m_dwLastUsedIP = file.ReadUInt32(); + m_nLastUsedPort = file.ReadUInt16(); + m_dwLastSeen = file.ReadUInt32(); + m_dwLastChatted = file.ReadUInt32(); - for (uint32 tagcount = file->ReadUInt32(); tagcount > 0; --tagcount) { + for (uint32 tagcount = file.ReadUInt32(); tagcount > 0; --tagcount) { const CTag *newtag = new CTag(file, false); switch (newtag->GetNameID()) { case FF_NAME: @@ -118,17 +117,17 @@ void CFriend::LoadFromFile(CFileDataIO *file) } } -void CFriend::WriteToFile(CFileDataIO *file) +void CFriend::WriteToFile(CFileDataIO &file) { - file->WriteHash16(m_abyUserhash); - file->WriteUInt32(m_dwLastUsedIP); - file->WriteUInt16(m_nLastUsedPort); - file->WriteUInt32((uint32)m_dwLastSeen); - file->WriteUInt32((uint32)m_dwLastChatted); + file.WriteHash16(m_abyUserhash); + file.WriteUInt32(m_dwLastUsedIP); + file.WriteUInt16(m_nLastUsedPort); + file.WriteUInt32((uint32)m_dwLastSeen); + file.WriteUInt32((uint32)m_dwLastChatted); uint32 uTagCount = 0; - ULONGLONG uTagCountFilePos = file->GetPosition(); - file->WriteUInt32(0); + ULONGLONG uTagCountFilePos = file.GetPosition(); + file.WriteUInt32(0); if (!m_strName.IsEmpty()) { CTag nametag(FF_NAME, m_strName); @@ -141,9 +140,9 @@ void CFriend::WriteToFile(CFileDataIO *file) ++uTagCount; } - file->Seek(uTagCountFilePos, CFile::begin); - file->WriteUInt32(uTagCount); - file->Seek(0, CFile::end); + file.Seek(uTagCountFilePos, CFile::begin); + file.WriteUInt32(uTagCount); + file.Seek(0, CFile::end); } bool CFriend::HasUserhash() const @@ -240,7 +239,7 @@ bool CFriend::TryToConnect(CFriendConnectionListener *pConnectionReport) m_liConnectionReport.AddTail(pConnectionReport); if (GetLinkedClient(true) == NULL) { - //ASSERT( pConnectionReport != &theApp.emuledlg->chatwnd->chatselector ); // shouldn't happen, if the chat connector calls, we he always should have a client for the session already + //ASSERT(pConnectionReport != &theApp.emuledlg->chatwnd->chatselector); // shouldn't happen, if the chat connector calls, we he always should have a client for the session already ASSERT(0); GetClientForChatSession(); } diff --git a/srchybrid/Friend.h b/srchybrid/Friend.h index 973fd162..054a7f6b 100644 --- a/srchybrid/Friend.h +++ b/srchybrid/Friend.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -66,20 +66,12 @@ class CFriend : public Kademlia::CKadClientSearcher , uint32 dwLastChatted, LPCTSTR pszName, uint32 dwHasHash); ~CFriend(); - uchar m_abyUserhash[16]; - - time_t m_dwLastSeen; - time_t m_dwLastChatted; - CString m_strName; - uint32 m_dwLastUsedIP; - uint16 m_nLastUsedPort; - CUpDownClient* GetClientForChatSession(); CUpDownClient* GetLinkedClient(bool bValidCheck = false) const; void SetLinkedClient(CUpDownClient *linkedClient); - void LoadFromFile(CFileDataIO *file); - void WriteToFile(CFileDataIO *file); + void LoadFromFile(CFileDataIO &file); + void WriteToFile(CFileDataIO &file); bool TryToConnect(CFriendConnectionListener *pConnectionReport); void UpdateFriendConnectionState(EFriendConnectReport eEvent); @@ -97,13 +89,20 @@ class CFriend : public Kademlia::CKadClientSearcher bool HasUserhash() const; bool HasKadID() const; + uchar m_abyUserhash[MDX_DIGEST_SIZE]; + + time_t m_dwLastSeen; + time_t m_dwLastChatted; + CString m_strName; + uint32 m_dwLastUsedIP; + uint16 m_nLastUsedPort; private: - uchar m_abyKadID[16]; + void init(); + + uchar m_abyKadID[MDX_DIGEST_SIZE]; CTypedPtrList m_liConnectionReport; CUpDownClient *m_LinkedClient; + DWORD m_dwLastKadSearch; EFriendConnectState m_FriendConnectState; - uint32 m_dwLastKadSearch; bool m_friendSlot; - - void init(); }; \ No newline at end of file diff --git a/srchybrid/FriendList.cpp b/srchybrid/FriendList.cpp index 730db9f9..d22a0703 100644 --- a/srchybrid/FriendList.cpp +++ b/srchybrid/FriendList.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -17,12 +17,11 @@ #include "stdafx.h" #include #include "emule.h" -#include "FriendList.h" #include "UpDownClient.h" #include "Friend.h" +#include "FriendList.h" #include "Preferences.h" #include "SafeFile.h" -#include "OtherFunctions.h" #include "opcodes.h" #include "emuledlg.h" #include "FriendListCtrl.h" @@ -53,7 +52,7 @@ CFriendList::~CFriendList() bool CFriendList::LoadList() { - CString strFileName(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + EMFRIENDS_MET_FILENAME); + const CString &strFileName(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + EMFRIENDS_MET_FILENAME); CSafeBufferedFile file; CFileException fexp; if (!file.Open(strFileName, CFile::modeRead | CFile::osSequentialScan | CFile::typeBinary | CFile::shareDenyWrite, &fexp)) { @@ -76,7 +75,7 @@ bool CFriendList::LoadList() for (uint32 i = file.ReadUInt32(); i > 0; --i) { //number of records CFriend *Record = new CFriend(); - Record->LoadFromFile(&file); + Record->LoadFromFile(file); m_listFriends.AddTail(Record); } file.Close(); @@ -100,7 +99,7 @@ void CFriendList::SaveList() AddDebugLogLine(false, _T("Saving friends list file \"%s\""), EMFRIENDS_MET_FILENAME); m_nLastSaved = ::GetTickCount(); - CString strFileName(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + EMFRIENDS_MET_FILENAME); + const CString &strFileName(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + EMFRIENDS_MET_FILENAME); CSafeBufferedFile file; CFileException fexp; if (!file.Open(strFileName, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary | CFile::shareDenyWrite, &fexp)) { @@ -111,14 +110,14 @@ void CFriendList::SaveList() LogError(LOG_STATUSBAR, _T("%s"), (LPCTSTR)strError); return; } - setvbuf(file.m_pStream, NULL, _IOFBF, 16384); + ::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); try { file.WriteUInt8(MET_HEADER); file.WriteUInt32((uint32)m_listFriends.GetCount()); for (POSITION pos = m_listFriends.GetHeadPosition(); pos != NULL;) - m_listFriends.GetNext(pos)->WriteToFile(&file); - if ((theApp.IsClosing() && thePrefs.GetCommitFiles() >= 1) || thePrefs.GetCommitFiles() >= 2) { + m_listFriends.GetNext(pos)->WriteToFile(file); + if (thePrefs.GetCommitFiles() >= 2 || (thePrefs.GetCommitFiles() >= 1 && theApp.IsClosing())) { file.Flush(); // flush file stream buffers to disk buffers if (_commit(_fileno(file.m_pStream)) != 0) // commit disk buffers to disk AfxThrowFileException(CFileException::hardIO, ::GetLastError(), file.GetFileName()); @@ -216,7 +215,7 @@ bool CFriendList::AddFriend(CUpDownClient *toadd) m_wndOutput->UpdateList(); } SaveList(); - NewFriend->FindKadID(); // fetch the kadid of this friend if we don't have it already + NewFriend->FindKadID(); // fetch the Kad ID of this friend if we don't have it already return true; } diff --git a/srchybrid/FriendList.h b/srchybrid/FriendList.h index eb48e121..8e0a178e 100644 --- a/srchybrid/FriendList.h +++ b/srchybrid/FriendList.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -45,5 +45,5 @@ class CFriendList private: CTypedPtrList m_listFriends; CFriendListCtrl *m_wndOutput; - uint32 m_nLastSaved; + DWORD m_nLastSaved; }; \ No newline at end of file diff --git a/srchybrid/FriendListCtrl.cpp b/srchybrid/FriendListCtrl.cpp index b557bc79..ed49f729 100644 --- a/srchybrid/FriendListCtrl.cpp +++ b/srchybrid/FriendListCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -16,14 +16,13 @@ //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "stdafx.h" #include "emule.h" -#include "FriendListCtrl.h" -#include "friend.h" #include "ClientDetailDialog.h" -#include "Addfriend.h" -#include "FriendList.h" #include "emuledlg.h" #include "ClientList.h" #include "OtherFunctions.h" +#include "Addfriend.h" +#include "FriendList.h" +#include "FriendListCtrl.h" #include "UpDownClient.h" #include "ListenSocket.h" #include "MenuCmds.h" @@ -59,7 +58,7 @@ void CFriendListCtrl::Init() CRect rcWindow; GetWindowRect(rcWindow); - InsertColumn(0, GetResString(IDS_QL_USERNAME), LVCFMT_LEFT, rcWindow.Width() - 4); + InsertColumn(0, _T(""), LVCFMT_LEFT, rcWindow.Width() - 4); //IDS_QL_USERNAME SetAllIcons(); theApp.friendlist->SetWindow(this); @@ -88,12 +87,11 @@ void CFriendListCtrl::SetAllIcons() void CFriendListCtrl::Localize() { - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); - CString strRes(GetResString(IDS_QL_USERNAME)); - HDITEM hdi; - hdi.mask = HDI_TEXT; - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(0, &hdi); + static const UINT uids[1] = + { + IDS_QL_USERNAME + }; + LocaliseHeaderCtrl(uids, _countof(uids)); for (int i = GetItemCount(); --i >= 0;) UpdateFriend(i, reinterpret_cast(GetItemData(i))); @@ -228,7 +226,7 @@ BOOL CFriendListCtrl::OnCommand(WPARAM wParam, LPARAM) case MP_FIND: OnFindStart(); } - return true; + return TRUE; } void CFriendListCtrl::OnNmDblClk(LPNMHDR, LRESULT *pResult) @@ -265,20 +263,16 @@ BOOL CFriendListCtrl::PreTranslateMessage(MSG *pMsg) void CFriendListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) { - NMLISTVIEW *pNMListView = reinterpret_cast(pNMHDR); - + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); // Determine ascending based on whether already sorted on this column - int iSortItem = GetSortItem(); - bool bOldSortAscending = GetSortAscending(); - bool bSortAscending = (iSortItem != pNMListView->iSubItem) ? true : !bOldSortAscending; + bool bSortAscending = (GetSortItem() != pNMLV->iSubItem || !GetSortAscending()); // Item is column clicked - iSortItem = pNMListView->iSubItem; + int iSortItem = pNMLV->iSubItem; // Sort table SetSortArrow(iSortItem, bSortAscending); - SortItems(SortProc, MAKELONG(iSortItem, (bSortAscending ? 0 : 0x0001))); - + SortItems(SortProc, MAKELONG(iSortItem, !bSortAscending)); *pResult = 0; } @@ -291,7 +285,7 @@ int CALLBACK CFriendListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lP int iResult; switch (LOWORD(lParamSort)) { - case 0: + case 0: //friend's name iResult = CompareLocaleStringNoCase(item1->m_strName, item2->m_strName); break; default: @@ -303,5 +297,5 @@ int CALLBACK CFriendListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lP void CFriendListCtrl::UpdateList() { theApp.emuledlg->chatwnd->UpdateFriendlistCount(theApp.friendlist->GetCount()); - SortItems(SortProc, MAKELONG(GetSortItem(), static_cast(!GetSortAscending()))); + SortItems(SortProc, MAKELONG(GetSortItem(), !GetSortAscending())); } \ No newline at end of file diff --git a/srchybrid/FriendListCtrl.h b/srchybrid/FriendListCtrl.h index 10fa3951..7a2d01db 100644 --- a/srchybrid/FriendListCtrl.h +++ b/srchybrid/FriendListCtrl.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -26,7 +26,6 @@ class CFriendListCtrl : public CMuleListCtrl public: CFriendListCtrl(); - virtual ~CFriendListCtrl() = default; void Init(); void Localize(); diff --git a/srchybrid/GDIThread.cpp b/srchybrid/GDIThread.cpp index bdd4ef93..5e0e0399 100644 --- a/srchybrid/GDIThread.cpp +++ b/srchybrid/GDIThread.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/GZipFile.cpp b/srchybrid/GZipFile.cpp index 33c26a12..5cb1e746 100644 --- a/srchybrid/GZipFile.cpp +++ b/srchybrid/GZipFile.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -62,10 +62,10 @@ void CGZIPFile::Close() CString CGZIPFile::GetUncompressedFilePath() const { // return path of input file without ".gz" extension - LPCTSTR pszExt = PathFindExtension(m_strGzFilePath); - if (_tcsicmp(pszExt, _T(".gz")) != 0) - pszExt = m_strGzFilePath; - return CString(m_strGzFilePath, (int)((LPCTSTR)m_strGzFilePath - pszExt)); + LPCTSTR pDot = ::PathFindExtension(m_strGzFilePath); + if (_tcsicmp(pDot, _T(".gz")) != 0) + pDot = m_strGzFilePath; //empty string if not .gz + return m_strGzFilePath.Left((int)((LPCTSTR)m_strGzFilePath - pDot)); } CString CGZIPFile::GetUncompressedFileName() const @@ -74,7 +74,7 @@ CString CGZIPFile::GetUncompressedFileName() const const CString &strUncompressedFileName = GetUncompressedFilePath(); if (!strUncompressedFileName.IsEmpty()) { // skip any possible available directories - LPCTSTR pszFileName = PathFindFileName(strUncompressedFileName); + LPCTSTR pszFileName = ::PathFindFileName(strUncompressedFileName); if (pszFileName) return CString(pszFileName); } diff --git a/srchybrid/GZipFile.h b/srchybrid/GZipFile.h index a5f53220..6f74a422 100644 --- a/srchybrid/GZipFile.h +++ b/srchybrid/GZipFile.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/GradientStatic.cpp b/srchybrid/GradientStatic.cpp index eb456a1b..68b2cb1b 100644 --- a/srchybrid/GradientStatic.cpp +++ b/srchybrid/GradientStatic.cpp @@ -147,18 +147,16 @@ void CGradientStatic::DrawHorizontalText(CRect *pRect) m_Mem.dc.SelectObject(pOldFont); } -void DrawRotatedText(HDC hdc, LPCTSTR str, LPRECT rect, double angle, UINT nOptions = 0) +void DrawRotatedText(HDC hdc, LPCTSTR str, LPCRECT rect, double angle, UINT nOptions = 0) { // convert angle to radian - double radian = M_PI * 2 / 360 * angle; + double radian = M_PI / 180 * angle; // get the center of a not-rotated text SIZE TextSize; GetTextExtentPoint32(hdc, str, (int)_tcslen(str), &TextSize); - POINT center; - center.x = TextSize.cx / 2; - center.y = TextSize.cy / 2; + const POINT center{ TextSize.cx / 2, TextSize.cy / 2 }; // now calculate the center of the rotated text POINT rcenter; @@ -168,7 +166,7 @@ void DrawRotatedText(HDC hdc, LPCTSTR str, LPRECT rect, double angle, UINT nOpti // finally draw the text and move it to the center of the rectangle ::SetTextAlign(hdc, TA_BOTTOM); ::SetBkMode(hdc, TRANSPARENT); - ::ExtTextOut(hdc, rect->left + (rect->right - rect->left) / 2 - rcenter.x, + ::ExtTextOut(hdc, (rect->left + rect->right) / 2 - rcenter.x, rect->bottom, nOptions, rect, str, (UINT)_tcslen(str), NULL); } diff --git a/srchybrid/HTRichEditCtrl.cpp b/srchybrid/HTRichEditCtrl.cpp index 66b3c8e5..732d0ae9 100644 --- a/srchybrid/HTRichEditCtrl.cpp +++ b/srchybrid/HTRichEditCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -203,7 +203,7 @@ void CHTRichEditCtrl::FlushBuffer() { if (!m_astrBuff.IsEmpty()) { // flush buffer for (int i = 0; i < m_astrBuff.GetCount(); ++i) { - const CString &rstrLine = m_astrBuff[i]; + const CString &rstrLine(m_astrBuff[i]); if (!rstrLine.IsEmpty()) { if ((UINT)rstrLine[0] < 8) AddLine((LPCTSTR)rstrLine + 1, rstrLine.GetLength() - 1, false, GetLogLineColor((UINT)rstrLine[0])); @@ -371,7 +371,7 @@ void CHTRichEditCtrl::AddString(int nPos, LPCTSTR pszString, bool bLink, COLORRE cf.dwEffects |= CFE_AUTOBACKCOLOR; //} //else { - // ASSERT( m_crBackground != CLR_DEFAULT ); + // ASSERT(m_crBackground != CLR_DEFAULT); // cf.dwEffects &= ~CFE_AUTOBACKCOLOR; // cf.crBackColor = m_crBackground; //} @@ -575,13 +575,13 @@ BOOL CHTRichEditCtrl::OnCommand(WPARAM wParam, LPARAM) bool CHTRichEditCtrl::SaveLog(LPCTSTR pszDefName) { bool bResult = false; - const CString &fname(pszDefName ? CString(pszDefName) : m_strTitle); + const CString &fname(pszDefName ? pszDefName : m_strTitle); CFileDialog dlg(FALSE, _T("log"), (LPCTSTR)ValidFilename(fname), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("Log Files (*.log)|*.log||"), this, 0); if (dlg.DoModal() == IDOK) { FILE *fp = _tfsopen(dlg.GetPathName(), _T("wb"), _SH_DENYWR); if (fp) { // write Unicode byte order mark 0xFEFF - fputwc(0xFEFFui16, fp); + fputwc(u'\xFEFF', fp); CString strText; GetWindowText(strText); @@ -648,30 +648,27 @@ void CHTRichEditCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) CRichEditCtrl::OnKeyDown(nChar, nRepCnt, nFlags); } -void CHTRichEditCtrl::AppendText(const CString &sText) +void CHTRichEditCtrl::AppendText(LPCTSTR sText) { LPCTSTR psz = sText; LPCTSTR pszStart = psz; while (*psz != _T('\0')) { bool bFoundScheme = false; - for (unsigned i = 0; i < _countof(s_apszSchemes); ++i) { + for (unsigned i = 0; s_apszSchemes[i].pszScheme; ++i) { if (_tcsncmp(psz, s_apszSchemes[i].pszScheme, s_apszSchemes[i].iLen) == 0) { // output everything before the URL - if (psz - pszStart > 0) { - CString str(pszStart, (int)(psz - pszStart)); - AddLine(str, str.GetLength()); - } + int iLen = (int)(psz - pszStart); + if (iLen > 0) + AddLine(pszStart, iLen); // search next space or EOL - int iLen = (int)_tcscspn(psz, _T(" \t\r\n")); - if (iLen == 0) { - AddLine(psz, -1, true); + iLen = (int)_tcscspn(psz, _T(" \t\r\n")); + if (iLen <= 0) { + iLen = -1; psz += _tcslen(psz); - } else { - CString str(psz, iLen); - AddLine(str, str.GetLength(), true); + } else psz += iLen; - } + AddLine(psz, iLen, true); pszStart = psz; bFoundScheme = true; break; @@ -685,14 +682,14 @@ void CHTRichEditCtrl::AppendText(const CString &sText) AddLine(pszStart, -1); } -void CHTRichEditCtrl::AppendHyperLink(const CString &sText, const CString &sTitle, const CString &sCommand, const CString &sDirectory) +void CHTRichEditCtrl::AppendHyperLink(LPCTSTR pszText, LPCTSTR pszTitle, const CString &sCommand, LPCTSTR pszDirectory) { - UNREFERENCED_PARAMETER(sText); - UNREFERENCED_PARAMETER(sTitle); - UNREFERENCED_PARAMETER(sDirectory); - ASSERT(sText.IsEmpty()); - ASSERT(sTitle.IsEmpty()); - ASSERT(sDirectory.IsEmpty()); + UNREFERENCED_PARAMETER(pszText); + UNREFERENCED_PARAMETER(pszTitle); + UNREFERENCED_PARAMETER(pszDirectory); + ASSERT(!pszText || !*pszText); + ASSERT(!pszTitle || !*pszTitle); + ASSERT(!pszDirectory || !*pszDirectory); AddLine(sCommand, sCommand.GetLength(), true); } @@ -701,7 +698,7 @@ void CHTRichEditCtrl::AppendColoredText(LPCTSTR pszText, COLORREF cr, COLORREF b AddLine(pszText, -1, false, cr, bk, mask); } -void CHTRichEditCtrl::AppendKeyWord(const CString &str, COLORREF cr) +void CHTRichEditCtrl::AppendKeyWord(LPCTSTR str, COLORREF cr) { AppendColoredText(str, cr); } @@ -715,7 +712,7 @@ BOOL CHTRichEditCtrl::OnEnLink(LPNMHDR pNMHDR, LRESULT *pResult) // check if that "URL" has a valid URL scheme. if it has not, pass that notification up to the // parent window which may interpret that "URL" in some other way. - for (unsigned i = 0; i < _countof(s_apszSchemes); ++i) + for (unsigned i = 0; s_apszSchemes[i].pszScheme; ++i) if (_tcsncmp(strUrl, s_apszSchemes[i].pszScheme, s_apszSchemes[i].iLen) == 0) { BrowserOpen(strUrl, NULL); return (BOOL)(*pResult = 1); // do not pass this message to any parent @@ -899,12 +896,12 @@ class CBitmapDataObject : public CCmdTarget { public: explicit CBitmapDataObject(HBITMAP hBitmap); - virtual ~CBitmapDataObject() = default; protected: DECLARE_INTERFACE_MAP(); BEGIN_INTERFACE_PART(DataObject, IDataObject) + virtual ~XDataObject() = default; STDMETHOD(GetData)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium); STDMETHOD(GetDataHere)(FORMATETC *pformatetc, STGMEDIUM *pmedium); STDMETHOD(QueryGetData)(FORMATETC *pformatetc); @@ -932,19 +929,19 @@ CBitmapDataObject::CBitmapDataObject(HBITMAP hBitmap) #pragma warning(disable:4100) // unreferenced parameter #pragma warning(disable:4555) // expression has no effect; expected expression with side-effect (because of the 'METHOD_PROLOGUE' macro) -STDMETHODIMP CBitmapDataObject::XDataObject::QueryInterface(REFIID riid, void **ppvObj) noexcept +STDMETHODIMP CBitmapDataObject::XDataObject::QueryInterface(REFIID iid, LPVOID *ppvObj) XP_NOEXCEPT { METHOD_PROLOGUE(CBitmapDataObject, DataObject); - return (HRESULT)pThis->ExternalQueryInterface(&riid, ppvObj); + return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj); } -STDMETHODIMP_(ULONG) CBitmapDataObject::XDataObject::AddRef() noexcept +STDMETHODIMP_(ULONG) CBitmapDataObject::XDataObject::AddRef() XP_NOEXCEPT { METHOD_PROLOGUE(CBitmapDataObject, DataObject); return pThis->ExternalAddRef(); } -STDMETHODIMP_(ULONG) CBitmapDataObject::XDataObject::Release() noexcept +STDMETHODIMP_(ULONG) CBitmapDataObject::XDataObject::Release() XP_NOEXCEPT { METHOD_PROLOGUE(CBitmapDataObject, DataObject); return pThis->ExternalRelease(); @@ -1257,7 +1254,7 @@ HBITMAP CHTRichEditCtrl::GetSmileyBitmap(LPCTSTR pszSmileyID, COLORREF bk) // icons (which can also be GIF images) can have any size. HBITMAP hBitmap = IconToBitmap(hIcon, bk, 0, 0); if (hBitmap != NULL) - sm_aSmileyBitmaps.SetAt(sSmileyID, hBitmap); + sm_aSmileyBitmaps[sSmileyID] = hBitmap; return hBitmap; } @@ -1305,7 +1302,7 @@ bool CHTRichEditCtrl::InsertSmiley(LPCTSTR pszSmileyID, COLORREF bk) #endif CComPtr pIOleObject; - if (OleCreateStaticFromData(pIDataObject, __uuidof(pIOleObject), OLERENDER_FORMAT, &FormatEtc, pIOleClientSite, sm_pIStorageSmileys, (void **)&pIOleObject) != S_OK) + if (S_OK != OleCreateStaticFromData(pIDataObject, __uuidof(pIOleObject), OLERENDER_FORMAT, &FormatEtc, pIOleClientSite, sm_pIStorageSmileys, (void **)&pIOleObject)) return false; OleSetContainedObject(pIOleObject, TRUE); @@ -1345,9 +1342,9 @@ bool CHTRichEditCtrl::AddCaptcha(HBITMAP hbmp) if (m_pIStorageCaptchas == NULL) { CComPtr pILockBytes; - if (CreateILockBytesOnHGlobal(NULL, TRUE, &pILockBytes) != S_OK) + if (S_OK != CreateILockBytesOnHGlobal(NULL, TRUE, &pILockBytes)) return false; - if (StgCreateDocfileOnILockBytes(pILockBytes, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &m_pIStorageCaptchas) != S_OK) + if (S_OK != StgCreateDocfileOnILockBytes(pILockBytes, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &m_pIStorageCaptchas)) return false; } diff --git a/srchybrid/HTRichEditCtrl.h b/srchybrid/HTRichEditCtrl.h index 616a6f17..27c62495 100644 --- a/srchybrid/HTRichEditCtrl.h +++ b/srchybrid/HTRichEditCtrl.h @@ -28,9 +28,9 @@ class CHTRichEditCtrl : public CRichEditCtrl CString GetAllLogEntries(); bool SaveLog(LPCTSTR pszDefName = NULL); - void AppendText(const CString &sText); - void AppendHyperLink(const CString &sText, const CString &sTitle, const CString &sCommand, const CString &sDirectory); - void AppendKeyWord(const CString &str, COLORREF cr); + void AppendText(LPCTSTR sText); + void AppendHyperLink(LPCTSTR pszText, LPCTSTR pszTitle, const CString &sCommand, LPCTSTR pszDirectory); + void AppendKeyWord(LPCTSTR str, COLORREF cr); void AppendColoredText(LPCTSTR pszText, COLORREF cr, COLORREF bk = CLR_DEFAULT, DWORD mask = 0); COLORREF GetForegroundColor() const { return m_crForeground; } COLORREF GetBackgroundColor() const { return m_crBackground; } diff --git a/srchybrid/HttpClientReqSocket.cpp b/srchybrid/HttpClientReqSocket.cpp index 7292aca4..908a6aa6 100644 --- a/srchybrid/HttpClientReqSocket.cpp +++ b/srchybrid/HttpClientReqSocket.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -82,22 +82,18 @@ void CHttpClientReqSocket::DataReceived(const BYTE *pucData, UINT uSize) try { bResult = ProcessHttpPacket(pucData, uSize); } catch (CMemoryException *ex) { - strError.Format(_T("Error: HTTP socket: Memory exception; %s"), (LPCTSTR)DbgGetClientInfo()); - if (thePrefs.GetVerbose()) - AddDebugLogLine(false, _T("%s"), (LPCTSTR)strError); + strError.Format(_T("Memory exception; %s"), (LPCTSTR)DbgGetClientInfo()); ex->Delete(); } catch (CFileException *ex) { TCHAR szError[MAX_CFEXP_ERRORMSG]; GetExceptionMessage(*ex, szError, _countof(szError)); - strError.Format(_T("Error: HTTP socket: File exception - %s"), szError); - if (thePrefs.GetVerbose()) - AddDebugLogLine(false, _T("%s"), (LPCTSTR)strError); + strError.Format(_T("File exception - %s"), szError); ex->Delete(); } catch (const CString &ex) { - strError.Format(_T("Error: HTTP socket: %s; %s"), (LPCTSTR)ex, (LPCTSTR)DbgGetClientInfo()); - if (thePrefs.GetVerbose()) - AddDebugLogLine(false, _T("%s"), (LPCTSTR)strError); + strError.Format(_T("%s; %s"), (LPCTSTR)ex, (LPCTSTR)DbgGetClientInfo()); } + if (thePrefs.GetVerbose() && !strError.IsEmpty()) + AddDebugLogLine(false, _T("Error: HTTP socket: %s"), (LPCTSTR)strError); if (!bResult && !deletethis) { if (thePrefs.GetVerbose() && thePrefs.GetDebugClientTCPLevel() <= 0) @@ -143,9 +139,9 @@ bool CHttpClientReqSocket::ProcessHttpPacket(const BYTE *pucData, UINT uSize) theStats.AddDownDataOverheadFileRequest(iSizeHeader); if (iSizeBody < 0) - throw CString(_T("Internal HTTP header/body parsing error")); + throwCStr(_T("Internal HTTP header/body parsing error")); - if (m_astrHttpHeaders[0].GetLength() >= 4 && memcmp((LPCSTR)m_astrHttpHeaders[0], "HTTP", 4) == 0) { + if (strncmp(m_astrHttpHeaders[0], "HTTP", 4) == 0) { if (!ProcessHttpResponse()) return false; @@ -158,22 +154,22 @@ bool CHttpClientReqSocket::ProcessHttpPacket(const BYTE *pucData, UINT uSize) // body will be processed because of HTTP state 'HttpStateRecvBody' with next recv ; } - } else if (m_astrHttpHeaders[0].GetLength() >= 3 && memcmp((LPCSTR)m_astrHttpHeaders[0], "GET", 3) == 0) { + } else if (strncmp(m_astrHttpHeaders[0], "GET", 3) == 0) { if (!ProcessHttpRequest()) return false; if (iSizeBody != 0) { - ASSERT(0); // no body for GET requests allowed yet + ASSERT(0); // no body allowed for GET requests return false; } } else - throw CString(_T("Invalid HTTP header received")); + throwCStr(_T("Invalid HTTP header received")); } else TRACE("+++ Received partial HTTP header packet\n"); } else if (GetHttpState() == HttpStateRecvBody) ProcessHttpResponseBody(pucData, uSize); else { theStats.AddDownDataOverheadFileRequest(uSize); - throw CString(_T("Invalid HTTP socket state")); + throwCStr(_T("Invalid HTTP socket state")); } return true; @@ -209,8 +205,7 @@ void SplitHeaders(LPCSTR pszHeaders, CStringArray &astrHeaders) if (iLineLen <= 0) break; - CString strHdr(pLine, iLineLen); - astrHeaders.Add(strHdr); + astrHeaders.Add(CString(pLine, iLineLen)); } } @@ -251,7 +246,7 @@ void CHttpClientReqSocket::ProcessHttpHeaderPacket(const char *packet, UINT size // safety check if (m_iHttpHeadersSize > MAX_HTTP_HEADERS_SIZE) - throw CString(_T("Received HTTP headers exceed limit")); + throwCStr(_T("Received HTTP headers exceed limit")); } } else { // partial line, add to according buffer @@ -260,7 +255,7 @@ void CHttpClientReqSocket::ProcessHttpHeaderPacket(const char *packet, UINT size // safety check if (m_strHttpCurHdrLine.GetLength() > MAX_HTTP_HEADER_LINE_SIZE) - throw CString(_T("Received HTTP header line exceeds limit")); + throwCStr(_T("Received HTTP header line exceeds limit")); } } } diff --git a/srchybrid/HttpClientReqSocket.h b/srchybrid/HttpClientReqSocket.h index 5323bf46..51b31166 100644 --- a/srchybrid/HttpClientReqSocket.h +++ b/srchybrid/HttpClientReqSocket.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -46,7 +46,6 @@ class CHttpClientReqSocket : public CClientReqSocket protected: explicit CHttpClientReqSocket(CUpDownClient *pclient = NULL); - virtual ~CHttpClientReqSocket() = default; virtual void DataReceived(const BYTE *pucData, UINT uSize); @@ -75,8 +74,6 @@ class CHttpClientDownSocket : public CHttpClientReqSocket explicit CHttpClientDownSocket(CUpDownClient *pclient = NULL); protected: - virtual ~CHttpClientDownSocket() = default; - virtual bool ProcessHttpResponse(); virtual bool ProcessHttpResponseBody(const BYTE *pucData, UINT size); virtual bool ProcessHttpRequest(); diff --git a/srchybrid/HttpDownloadDlg.cpp b/srchybrid/HttpDownloadDlg.cpp index 7e91e831..24978f64 100644 --- a/srchybrid/HttpDownloadDlg.cpp +++ b/srchybrid/HttpDownloadDlg.cpp @@ -121,13 +121,13 @@ static int check_header(z_stream *stream, HINTERNET m_hHttpFile) /*check for gzip or x-gzip stream*/ \ TCHAR szContentEncoding[32]; \ DWORD dwEncodeStringSize = _countof(szContentEncoding); \ - if(HttpQueryInfo(m_hHttpFile, HTTP_QUERY_CONTENT_ENCODING, \ + if(HttpQueryInfo(m_hHttpFile, HTTP_QUERY_CONTENT_ENCODING, \ szContentEncoding, &dwEncodeStringSize, NULL)) { \ - if(szContentEncoding[0] == 'x' && szContentEncoding[1] == '-') \ - szContentEncoding += 2; \ - if(!stricmp(szContentEncoding, "gzip") \ - bEncodedWithGZIP = TRUE; \ - } \ + if(szContentEncoding[0] == 'x' && szContentEncoding[1] == '-') \ + szContentEncoding += 2; \ + if(!stricmp(szContentEncoding, "gzip") \ + bEncodedWithGZIP = TRUE; \ + } \ } #define PREPARE_DECODER \ @@ -278,7 +278,7 @@ BOOL CHttpDownloadDlg::OnInitDialog() // Check to see if the file we will be downloading into, exists // if it does, then ask the user if they allow to overwrite - // edited: we always overwrite old language dlls and server.met + // edited: we always overwrite old language DLLs and server.met /*CFileStatus fs; ASSERT(m_sFileToDownloadInto.GetLength()); if (CFile::GetStatus(m_sFileToDownloadInto, fs)) { @@ -648,18 +648,18 @@ void CHttpDownloadDlg::UpdateControlsDuringTransfer(DWORD dwStartTicks, DWORD &d } //Update the transfer rate and estimated time left every second - DWORD dwNowTicks = ::GetTickCount(); - DWORD dwTimeTaken = dwNowTicks - dwCurrentTicks; + const DWORD curTick = ::GetTickCount(); + DWORD dwTimeTaken = curTick - dwCurrentTicks; if (dwTimeTaken > SEC2MS(1)) { double KbPerSecond = (dwTotalBytesRead - dwLastTotalBytes) / (double)dwTimeTaken; SetTransferRate(KbPerSecond); //Setup for the next time around the loop - dwCurrentTicks = dwNowTicks; + dwCurrentTicks = curTick; dwLastTotalBytes = dwTotalBytesRead; if (bGotFileSize && dwTotalBytesRead) { //Update the estimated time left - DWORD dwSecondsLeft = (DWORD)((dwNowTicks - dwStartTicks) / (double)dwTotalBytesRead + DWORD dwSecondsLeft = (DWORD)((curTick - dwStartTicks) / (double)dwTotalBytesRead * (dwFileSize - dwTotalBytesRead) / 1000.0); SetTimeLeft(dwSecondsLeft, dwTotalBytesRead, dwFileSize); } diff --git a/srchybrid/I18n.cpp b/srchybrid/I18n.cpp index eb738680..711de213 100644 --- a/srchybrid/I18n.cpp +++ b/srchybrid/I18n.cpp @@ -27,9 +27,9 @@ CString GetResString(UINT uStringID) { CString resString; if (s_hLangDLL) - resString.LoadString(s_hLangDLL, uStringID); + (void)resString.LoadString(s_hLangDLL, uStringID); if (resString.IsEmpty()) - resString.LoadString(GetModuleHandle(NULL), uStringID); + (void)resString.LoadString(GetModuleHandle(NULL), uStringID); return resString; } @@ -41,15 +41,14 @@ int LocMessageBox(UINT uId, UINT nType, UINT nIDHelp) struct SLanguage { LANGID lid; - LPCTSTR pszLocale; - BOOL bSupported; - LPCTSTR pszISOLocale; + bool bSupported; UINT uCodepage; + LPCTSTR pszISOLocale; LPCTSTR pszHtmlCharset; }; -// Codepages (Windows) +// Code pages (Windows) // --------------------------------------------------------------------- // 1250 ANSI - Central European // 1251 ANSI - Cyrillic @@ -95,60 +94,59 @@ struct SLanguage static SLanguage s_aLanguages[] = { - {LANGID_AR_AE, _T(""), FALSE, _T("ar_AE"), 1256, _T("windows-1256")}, // Arabic (UAE) - {LANGID_BA_BA, _T(""), FALSE, _T("ba_BA"), 1252, _T("windows-1252")}, // Basque - {LANGID_BG_BG, _T("hun"), FALSE, _T("bg_BG"), 1251, _T("windows-1251")}, // Bulgarian - {LANGID_CA_ES, _T(""), FALSE, _T("ca_ES"), 1252, _T("windows-1252")}, // Catalan - {LANGID_CZ_CZ, _T("czech"), FALSE, _T("cz_CZ"), 1250, _T("windows-1250")}, // Czech - {LANGID_DA_DK, _T("danish"), FALSE, _T("da_DK"), 1252, _T("windows-1252")}, // Danish - {LANGID_DE_DE, _T("german"), FALSE, _T("de_DE"), 1252, _T("windows-1252")}, // German (Germany) - {LANGID_EL_GR, _T("greek"), FALSE, _T("el_GR"), 1253, _T("windows-1253")}, // Greek - {LANGID_EN_US, _T("english"), TRUE, _T("en_US"), 1252, _T("windows-1252")}, // English - {LANGID_ES_ES_T,_T("spanish"), FALSE, _T("es_ES_T"), 1252, _T("windows-1252")}, // Spanish (Castilian) - {LANGID_ES_AS, _T("spanish"), FALSE, _T("es_AS"), 1252, _T("windows-1252")}, // Asturian - {LANGID_VA_ES, _T(""), FALSE, _T("va_ES"), 1252, _T("windows-1252")}, // Valencian AVL - {LANGID_VA_ES_RACV, _T(""), FALSE, _T("va_ES_RACV"), 1252, _T("windows-1252")},// Valencian RACV - {LANGID_ET_EE, _T(""), FALSE, _T("et_EE"), 1257, _T("windows-1257")}, // Estonian - {LANGID_FA_IR, _T("farsi"), FALSE, _T("fa_IR"), 1256, _T("windows-1256")}, // Farsi - {LANGID_FI_FI, _T("finnish"), FALSE, _T("fi_FI"), 1252, _T("windows-1252")}, // Finnish - {LANGID_FR_FR, _T("french"), FALSE, _T("fr_FR"), 1252, _T("windows-1252")}, // French (France) - {LANGID_FR_BR, _T("french"), FALSE, _T("fr_BR"), 1252, _T("windows-1252")}, // French (Breton) - {LANGID_GL_ES, _T(""), FALSE, _T("gl_ES"), 1252, _T("windows-1252")}, // Galician - {LANGID_HE_IL, _T(""), FALSE, _T("he_IL"), 1255, _T("windows-1255")}, // Hebrew - {LANGID_HU_HU, _T("hungarian"), FALSE, _T("hu_HU"), 1250, _T("windows-1250")}, // Hungarian - {LANGID_IT_IT, _T("italian"), FALSE, _T("it_IT"), 1252, _T("windows-1252")}, // Italian (Italy) - {LANGID_JP_JP, _T("japanese"), FALSE, _T("jp_JP"), 932, _T("shift_jis")}, // Japanese - {LANGID_KO_KR, _T("korean"), FALSE, _T("ko_KR"), 949, _T("euc-kr")}, // Korean - {LANGID_LT_LT, _T(""), FALSE, _T("lt_LT"), 1257, _T("windows-1257")}, // Lithuanian - {LANGID_LV_LV, _T(""), FALSE, _T("lv_LV"), 1257, _T("windows-1257")}, // Latvian - {LANGID_MT_MT, _T("mt"), FALSE, _T("mt_MT"), 1254, _T("windows-1254")}, // Maltese - {LANGID_NB_NO, _T("nor"), FALSE, _T("nb_NO"), 1252, _T("windows-1252")}, // Norwegian (Bokmal) - {LANGID_NN_NO, _T("non"), FALSE, _T("nn_NO"), 1252, _T("windows-1252")}, // Norwegian (Nynorsk) - {LANGID_NL_NL, _T("dutch"), FALSE, _T("nl_NL"), 1252, _T("windows-1252")}, // Dutch (Netherlands) - {LANGID_PL_PL, _T("polish"), FALSE, _T("pl_PL"), 1250, _T("windows-1250")}, // Polish - {LANGID_PT_BR, _T("ptb"), FALSE, _T("pt_BR"), 1252, _T("windows-1252")}, // Portuguese (Brazil) - {LANGID_PT_PT, _T("ptg"), FALSE, _T("pt_PT"), 1252, _T("windows-1252")}, // Portuguese (Portugal) - {LANGID_RO_RO, _T(""), FALSE, _T("ro_RO"), 1250, _T("windows-1250")}, // Romanian - {LANGID_RU_RU, _T("russian"), FALSE, _T("ru_RU"), 1251, _T("windows-1251")}, // Russian - {LANGID_SL_SI, _T("slovak"), FALSE, _T("sl_SI"), 1250, _T("windows-1250")}, // Slovenian - {LANGID_SQ_AL, _T(""), FALSE, _T("sq_AL"), 1252, _T("windows-1252")}, // Albanian (Albania) - {LANGID_SV_SE, _T("swedish"), FALSE, _T("sv_SE"), 1252, _T("windows-1252")}, // Swedish - {LANGID_TR_TR, _T("turkish"), FALSE, _T("tr_TR"), 1254, _T("windows-1254")}, // Turkish - {LANGID_UA_UA, _T(""), FALSE, _T("ua_UA"), 1251, _T("windows-1251")}, // Ukrainian - {LANGID_ZH_CN, _T("chs"), FALSE, _T("zh_CN"), 936, _T("gb2312")}, // Chinese (P.R.C.) - {LANGID_ZH_TW, _T("cht"), FALSE, _T("zh_TW"), 950, _T("big5")}, // Chinese (Taiwan) - {LANGID_VI_VN, _T(""), FALSE, _T("vi_VN"), 1258, _T("windows-1258")}, // Vietnamese - {LANGID_UG_CN, _T(""), FALSE, _T("ug_CN"), 1256, _T("windows-1256")}, // Uighur - {0, NULL, 0, 0} + {LANGID_AR_AE, false, 1256, _T("ar_AE"), _T("windows-1256")}, // Arabic (UAE) + {LANGID_BA_BA, false, 1252, _T("ba_BA"), _T("windows-1252")}, // Basque + {LANGID_BG_BG, false, 1251, _T("bg_BG"), _T("windows-1251")}, // Bulgarian + {LANGID_CA_ES, false, 1252, _T("ca_ES"), _T("windows-1252")}, // Catalan + {LANGID_CZ_CZ, false, 1250, _T("cz_CZ"), _T("windows-1250")}, // Czech + {LANGID_DA_DK, false, 1252, _T("da_DK"), _T("windows-1252")}, // Danish + {LANGID_DE_DE, false, 1252, _T("de_DE"), _T("windows-1252")}, // German (Germany) + {LANGID_EL_GR, false, 1253, _T("el_GR"), _T("windows-1253")}, // Greek + {LANGID_EN_US, true, 1252, _T("en_US"), _T("windows-1252")}, // English + {LANGID_ES_AS, false, 1252, _T("es_AS"), _T("windows-1252")}, // Asturian + {LANGID_ES_ES_T, false, 1252, _T("es_ES_T"), _T("windows-1252")}, // Spanish (Castilian) + {LANGID_ET_EE, false, 1257, _T("et_EE"), _T("windows-1257")}, // Estonian + {LANGID_FA_IR, false, 1256, _T("fa_IR"), _T("windows-1256")}, // Farsi + {LANGID_FI_FI, false, 1252, _T("fi_FI"), _T("windows-1252")}, // Finnish + {LANGID_FR_BR, false, 1252, _T("fr_BR"), _T("windows-1252")}, // French (Breton) + {LANGID_FR_FR, false, 1252, _T("fr_FR"), _T("windows-1252")}, // French (France) + {LANGID_GL_ES, false, 1252, _T("gl_ES"), _T("windows-1252")}, // Galician + {LANGID_HE_IL, false, 1255, _T("he_IL"), _T("windows-1255")}, // Hebrew + {LANGID_HU_HU, false, 1250, _T("hu_HU"), _T("windows-1250")}, // Hungarian + {LANGID_IT_IT, false, 1252, _T("it_IT"), _T("windows-1252")}, // Italian (Italy) + {LANGID_JP_JP, false, 932, _T("jp_JP"), _T("shift_jis")}, // Japanese + {LANGID_KO_KR, false, 949, _T("ko_KR"), _T("euc-kr")}, // Korean + {LANGID_LT_LT, false, 1257, _T("lt_LT"), _T("windows-1257")}, // Lithuanian + {LANGID_LV_LV, false, 1257, _T("lv_LV"), _T("windows-1257")}, // Latvian + {LANGID_MT_MT, false, 1254, _T("mt_MT"), _T("windows-1254")}, // Maltese + {LANGID_NB_NO, false, 1252, _T("nb_NO"), _T("windows-1252")}, // Norwegian (Bokmal) + {LANGID_NL_NL, false, 1252, _T("nl_NL"), _T("windows-1252")}, // Dutch (Netherlands) + {LANGID_NN_NO, false, 1252, _T("nn_NO"), _T("windows-1252")}, // Norwegian (Nynorsk) + {LANGID_PL_PL, false, 1250, _T("pl_PL"), _T("windows-1250")}, // Polish + {LANGID_PT_BR, false, 1252, _T("pt_BR"), _T("windows-1252")}, // Portuguese (Brazil) + {LANGID_PT_PT, false, 1252, _T("pt_PT"), _T("windows-1252")}, // Portuguese (Portugal) + {LANGID_RO_RO, false, 1250, _T("ro_RO"), _T("windows-1250")}, // Romanian + {LANGID_RU_RU, false, 1251, _T("ru_RU"), _T("windows-1251")}, // Russian + {LANGID_SL_SI, false, 1250, _T("sl_SI"), _T("windows-1250")}, // Slovenian + {LANGID_SQ_AL, false, 1252, _T("sq_AL"), _T("windows-1252")}, // Albanian (Albania) + {LANGID_SV_SE, false, 1252, _T("sv_SE"), _T("windows-1252")}, // Swedish + {LANGID_TR_TR, false, 1254, _T("tr_TR"), _T("windows-1254")}, // Turkish + {LANGID_UA_UA, false, 1251, _T("ua_UA"), _T("windows-1251")}, // Ukrainian + {LANGID_UG_CN, false, 1256, _T("ug_CN"), _T("windows-1256")}, // Uighur + {LANGID_VA_ES, false, 1252, _T("va_ES"), _T("windows-1252")}, // Valencian AVL + {LANGID_VA_ES_RACV, false, 1252, _T("va_ES_RACV"), _T("windows-1252")}, // Valencian RACV + {LANGID_VI_VN, false, 1258, _T("vi_VN"), _T("windows-1258")}, // Vietnamese + {LANGID_ZH_CN, false, 936, _T("zh_CN"), _T("gb2312")}, // Chinese (P.R.C.) + {LANGID_ZH_TW, false, 950, _T("zh_TW"), _T("big5")}, // Chinese (Taiwan) + {0} }; static void InitLanguages(const CString &rstrLangDir1, const CString &rstrLangDir2) { bool bFirstDir = rstrLangDir1.CompareNoCase(rstrLangDir2) != 0; CFileFind ff; - bool bEnd = !ff.FindFile(rstrLangDir1 + _T("*.dll"), 0); - while (!bEnd) { - bEnd = !ff.FindNextFile(); + for (BOOL bFound = ff.FindFile(rstrLangDir1 + _T("*.dll")); bFound;) { + bFound = ff.FindNextFile(); if (ff.IsDirectory()) continue; TCHAR szLandDLLFileName[_MAX_FNAME]; @@ -156,17 +154,15 @@ static void InitLanguages(const CString &rstrLangDir1, const CString &rstrLangDi for (SLanguage *pLang = s_aLanguages; pLang->lid; ++pLang) if (_tcsicmp(pLang->pszISOLocale, szLandDLLFileName) == 0) { - pLang->bSupported = TRUE; + pLang->bSupported = true; break; } - if (bEnd && bFirstDir) { - ff.Close(); - bEnd = !ff.FindFile(rstrLangDir2 + _T("*.dll"), 0); + if (!bFound && bFirstDir) { + bFound = ff.FindFile(rstrLangDir2 + _T("*.dll")); bFirstDir = false; } } - ff.Close(); } static void FreeLangDLL() @@ -181,7 +177,7 @@ void CPreferences::GetLanguages(CWordArray &aLanguageIDs) { for (const SLanguage *pLang = s_aLanguages; pLang->lid; ++pLang) { //if (pLang->bSupported) - //show all languages, offer download if not supported ones later + //show all languages, offer download for non-supported ones later aLanguageIDs.Add(pLang->lid); } } @@ -323,7 +319,7 @@ void CPreferences::SetRtlLocale(LCID lcid) void CPreferences::InitThreadLocale() { - ASSERT(m_wLanguageID != 0); + ASSERT(m_wLanguageID); // NOTE: This function is for testing multi language support only. // NOTE: This function is *NOT* to be enabled in release builds nor to be offered by any Mod! @@ -367,10 +363,8 @@ CString GetCodePageNameForLocale(LCID lcid) if (iResult > 0 && !strCodePage.IsEmpty()) { UINT uCodePage = _tcstoul(strCodePage, NULL, 10); if (uCodePage != ULONG_MAX) { - CPINFOEXW CPInfoEx = {}; - BOOL(WINAPI *pfnGetCPInfoEx)(UINT, DWORD, LPCPINFOEXW); - (FARPROC&)pfnGetCPInfoEx = GetProcAddress(GetModuleHandle(_T("kernel32")), "GetCPInfoExW"); - if (pfnGetCPInfoEx && (*pfnGetCPInfoEx)(uCodePage, 0, &CPInfoEx)) + CPINFOEXW CPInfoEx; + if (::GetCPInfoExW(uCodePage, 0, &CPInfoEx)) strCodePage = CPInfoEx.CodePageName; } } @@ -379,7 +373,7 @@ CString GetCodePageNameForLocale(LCID lcid) CString CPreferences::GetHtmlCharset() { - ASSERT(m_wLanguageID != 0); + ASSERT(m_wLanguageID); LPCTSTR pszHtmlCharset = NULL; for (const SLanguage *pLang = s_aLanguages; pLang->lid; ++pLang) @@ -388,15 +382,15 @@ CString CPreferences::GetHtmlCharset() break; } - if (pszHtmlCharset == NULL || pszHtmlCharset[0] == _T('\0')) { + if (pszHtmlCharset == NULL || *pszHtmlCharset == _T('\0')) { ASSERT(0); // should never come here // try to get charset from code page LPCTSTR pszLcLocale = _tsetlocale(LC_CTYPE, NULL); if (pszLcLocale) { TCHAR szLocaleID[128]; - UINT uCodepage = 0; - if (_stscanf_s(pszLcLocale, _T("%[a-zA-Z_].%u"), szLocaleID, (unsigned)_countof(szLocaleID), &uCodepage) == 2 && uCodepage != 0) { + UINT uCodepage; + if (_stscanf_s(pszLcLocale, _T("%[a-zA-Z_].%u"), szLocaleID, (unsigned)_countof(szLocaleID), &uCodepage) == 2 && uCodepage > 0) { CString strHtmlCodepage; strHtmlCodepage.Format(_T("windows-%u"), uCodepage); return strHtmlCodepage; @@ -425,12 +419,9 @@ LRESULT CALLBACK RTLWindowsLayoutCbtFilterHook(int code, WPARAM wParam, LPARAM l void CemuleApp::EnableRTLWindowsLayout() { - BOOL(WINAPI *pfnSetProcessDefaultLayout)(DWORD dwFlags); - (FARPROC&)pfnSetProcessDefaultLayout = GetProcAddress(GetModuleHandle(_T("user32")), "SetProcessDefaultLayout"); - if (pfnSetProcessDefaultLayout) - (*pfnSetProcessDefaultLayout)(LAYOUT_RTL); + ::SetProcessDefaultLayout(LAYOUT_RTL); - s_hRTLWindowsLayoutOldCbtFilterHook = SetWindowsHookEx(WH_CBT, RTLWindowsLayoutCbtFilterHook, NULL, GetCurrentThreadId()); + s_hRTLWindowsLayoutOldCbtFilterHook = ::SetWindowsHookEx(WH_CBT, RTLWindowsLayoutCbtFilterHook, NULL, GetCurrentThreadId()); } void CemuleApp::DisableRTLWindowsLayout() @@ -439,9 +430,6 @@ void CemuleApp::DisableRTLWindowsLayout() VERIFY(UnhookWindowsHookEx(s_hRTLWindowsLayoutOldCbtFilterHook)); s_hRTLWindowsLayoutOldCbtFilterHook = NULL; - BOOL(WINAPI *pfnSetProcessDefaultLayout)(DWORD dwFlags); - (FARPROC&)pfnSetProcessDefaultLayout = GetProcAddress(GetModuleHandle(_T("user32")), "SetProcessDefaultLayout"); - if (pfnSetProcessDefaultLayout) - (*pfnSetProcessDefaultLayout)(0); + ::SetProcessDefaultLayout(0); } } \ No newline at end of file diff --git a/srchybrid/IESecurity.cpp b/srchybrid/IESecurity.cpp index 8663b130..101a7b12 100644 --- a/srchybrid/IESecurity.cpp +++ b/srchybrid/IESecurity.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -55,14 +55,14 @@ CMuleBrowserControlSite::CMuleBrowserControlSite(COleControlContainer *pCtrlCont char c; __int64 ll; }; - ASSERT( offsetof(S1, ll) == 8 ); + ASSERT(offsetof(S1, ll) == 8); InitInternetSecurityZone(); } void CMuleBrowserControlSite::InitInternetSecurityZone() { - const CString &strZone = AfxGetApp()->GetProfileString(_T("eMule"), _T("InternetSecurityZone"), _T("Untrusted")); + const CString &strZone(AfxGetApp()->GetProfileString(_T("eMule"), _T("InternetSecurityZone"), _T("Untrusted"))); if (strZone.CompareNoCase(_T("LocalMachine")) == 0) m_eUrlZone = URLZONE_LOCAL_MACHINE; else if (strZone.CompareNoCase(_T("Intranet")) == 0) @@ -125,7 +125,7 @@ void DumpIID(REFIID iid, LPCTSTR pszClassName) if (!bFound) OutputDebugString(pszGUID); OutputDebugString(_T("\n")); - CoTaskMemFree(pszGUID); + ::CoTaskMemFree(pszGUID); } #endif @@ -136,19 +136,19 @@ void DumpIID(REFIID iid, LPCTSTR pszClassName) #pragma warning(push) #pragma warning(disable:4555) // expression has no effect; expected expression with side-effect (because of the 'METHOD_PROLOGUE' macro) -STDMETHODIMP CMuleBrowserControlSite::XInternetSecurityManager::QueryInterface(REFIID riid, void **ppvObj) noexcept +STDMETHODIMP CMuleBrowserControlSite::XInternetSecurityManager::QueryInterface(REFIID iid, LPVOID *ppvObj) XP_NOEXCEPT { METHOD_PROLOGUE(CMuleBrowserControlSite, InternetSecurityManager); - return (HRESULT)pThis->ExternalQueryInterface(&riid, ppvObj); + return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj); } -STDMETHODIMP_(ULONG) CMuleBrowserControlSite::XInternetSecurityManager::AddRef() noexcept +STDMETHODIMP_(ULONG) CMuleBrowserControlSite::XInternetSecurityManager::AddRef() XP_NOEXCEPT { METHOD_PROLOGUE(CMuleBrowserControlSite, InternetSecurityManager); return pThis->ExternalAddRef(); } -STDMETHODIMP_(ULONG) CMuleBrowserControlSite::XInternetSecurityManager::Release() noexcept +STDMETHODIMP_(ULONG) CMuleBrowserControlSite::XInternetSecurityManager::Release() XP_NOEXCEPT { METHOD_PROLOGUE(CMuleBrowserControlSite, InternetSecurityManager); return pThis->ExternalRelease(); @@ -157,14 +157,14 @@ STDMETHODIMP_(ULONG) CMuleBrowserControlSite::XInternetSecurityManager::Release( STDMETHODIMP CMuleBrowserControlSite::XInternetSecurityManager::SetSecuritySite(IInternetSecurityMgrSite* /*pSite*/) noexcept { METHOD_PROLOGUE(CMuleBrowserControlSite, InternetSecurityManager); - TRACE(_T("%hs\n"), "SetSecuritySite"); + TRACE(_T("%s\n"), _T("SetSecuritySite")); return INET_E_DEFAULT_ACTION; } STDMETHODIMP CMuleBrowserControlSite::XInternetSecurityManager::GetSecuritySite(IInternetSecurityMgrSite** /*ppSite*/) noexcept { METHOD_PROLOGUE(CMuleBrowserControlSite, InternetSecurityManager); - TRACE(_T("%hs\n"), "GetSecuritySite"); + TRACE(_T("%s\n"), _T("GetSecuritySite")); return INET_E_DEFAULT_ACTION; } @@ -176,7 +176,7 @@ STDMETHODIMP CMuleBrowserControlSite::XInternetSecurityManager::MapUrlToZone( UNREFERENCED_PARAMETER(pwszUrl); UNREFERENCED_PARAMETER(dwFlags); METHOD_PROLOGUE(CMuleBrowserControlSite, InternetSecurityManager); - TRACE(_T("%hs: URL=%ls, Zone=%d, Flags=0x%x\n"), "MapUrlToZone", pwszUrl, pdwZone ? *pdwZone : 0, dwFlags); + TRACE(_T("%s: URL=%ls, Zone=%lu, Flags=0x%lx\n"), _T("MapUrlToZone"), pwszUrl, pdwZone ? *pdwZone : 0, dwFlags); if (pdwZone != NULL) { *pdwZone = (DWORD)pThis->m_eUrlZone; return S_OK; @@ -192,7 +192,7 @@ STDMETHODIMP CMuleBrowserControlSite::XInternetSecurityManager::GetSecurityId( UNREFERENCED_PARAMETER(pwszUrl); UNREFERENCED_PARAMETER(dwReserved); METHOD_PROLOGUE(CMuleBrowserControlSite, InternetSecurityManager); - TRACE(_T("%hs: URL=%ls, Reserved=%u\n"), "GetSecurityId", pwszUrl, dwReserved); + TRACE(_T("%s: URL=%ls, Reserved=%lu\n"), _T("GetSecurityId"), pwszUrl, dwReserved); return INET_E_DEFAULT_ACTION; } @@ -208,7 +208,7 @@ STDMETHODIMP CMuleBrowserControlSite::XInternetSecurityManager::ProcessUrlAction UNREFERENCED_PARAMETER(dwFlags); UNREFERENCED_PARAMETER(dwReserved); METHOD_PROLOGUE(CMuleBrowserControlSite, InternetSecurityManager); - TRACE(_T("%hs: URL=%ls, Action=%u, Flags=0x%x, Reserved=%u\n"), "ProcessUrlAction", pwszUrl, dwAction, dwFlags, dwReserved); + TRACE(_T("%s: URL=%ls, Action=%lu, Flags=0x%lx, Reserved=%lu\n"), _T("ProcessUrlAction"), pwszUrl, dwAction, dwFlags, dwReserved); #if 0 DWORD dwPolicy = URLPOLICY_DISALLOW; @@ -233,7 +233,7 @@ STDMETHODIMP CMuleBrowserControlSite::XInternetSecurityManager::QueryCustomPolic { UNREFERENCED_PARAMETER(pwszUrl); METHOD_PROLOGUE(CMuleBrowserControlSite, InternetSecurityManager); - TRACE(_T("%hs: URL=%ls\n"), "QueryCustomPolicy", pwszUrl); + TRACE(_T("%s: URL=%ls\n"), _T("QueryCustomPolicy"), pwszUrl); return INET_E_DEFAULT_ACTION; } @@ -246,7 +246,7 @@ STDMETHODIMP CMuleBrowserControlSite::XInternetSecurityManager::SetZoneMapping( UNREFERENCED_PARAMETER(lpszPattern); UNREFERENCED_PARAMETER(dwFlags); METHOD_PROLOGUE(CMuleBrowserControlSite, InternetSecurityManager); - TRACE(_T("%hs: Zone=%d, Pattern=%ls, Flags=0x%x\n"), "SetZoneMapping", dwZone, lpszPattern, dwFlags); + TRACE(_T("%s: Zone=%lu, Pattern=%ls, Flags=0x%lx\n"), _T("SetZoneMapping"), dwZone, lpszPattern, dwFlags); return INET_E_DEFAULT_ACTION; } @@ -258,7 +258,7 @@ STDMETHODIMP CMuleBrowserControlSite::XInternetSecurityManager::GetZoneMappings( UNREFERENCED_PARAMETER(dwZone); UNREFERENCED_PARAMETER(dwFlags); METHOD_PROLOGUE(CMuleBrowserControlSite, InternetSecurityManager); - TRACE(_T("%hs: Zone=%d, Flags=0x%s\n"), "GetZoneMappings", dwZone, dwFlags); + TRACE(_T("%s: Zone=%lu, Flags=0x%lx\n"), _T("GetZoneMappings"), dwZone, dwFlags); return INET_E_DEFAULT_ACTION; } @@ -267,32 +267,32 @@ STDMETHODIMP CMuleBrowserControlSite::XInternetSecurityManager::GetZoneMappings( // IServiceProvider // -STDMETHODIMP_(ULONG) CMuleBrowserControlSite::XServiceProvider::AddRef() noexcept +STDMETHODIMP_(ULONG) CMuleBrowserControlSite::XServiceProvider::AddRef() XP_NOEXCEPT { METHOD_PROLOGUE(CMuleBrowserControlSite, ServiceProvider); return pThis->ExternalAddRef(); } -STDMETHODIMP_(ULONG) CMuleBrowserControlSite::XServiceProvider::Release() noexcept +STDMETHODIMP_(ULONG) CMuleBrowserControlSite::XServiceProvider::Release() XP_NOEXCEPT { METHOD_PROLOGUE(CMuleBrowserControlSite, ServiceProvider); return pThis->ExternalRelease(); } -STDMETHODIMP CMuleBrowserControlSite::XServiceProvider::QueryInterface(REFIID riid, void **ppvObj) noexcept +STDMETHODIMP CMuleBrowserControlSite::XServiceProvider::QueryInterface(REFIID iid, LPVOID *ppvObj) XP_NOEXCEPT { METHOD_PROLOGUE(CMuleBrowserControlSite, ServiceProvider); - return (HRESULT)pThis->ExternalQueryInterface(&riid, ppvObj); + return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj); } -STDMETHODIMP CMuleBrowserControlSite::XServiceProvider::QueryService(REFGUID guidService, REFIID riid, void **ppvObject) noexcept +STDMETHODIMP CMuleBrowserControlSite::XServiceProvider::QueryService(REFGUID guidService, REFIID iid, void **ppvObject) noexcept { METHOD_PROLOGUE(CMuleBrowserControlSite, ServiceProvider); //DUMPIID(guidService, _T("guidService")); - //DUMPIID(riid, _T("riid")); - if (guidService == SID_SInternetSecurityManager && riid == IID_IInternetSecurityManager) { - TRACE(_T("%hs\n"), "QueryService"); - return (HRESULT)pThis->ExternalQueryInterface(&riid, ppvObject); + //DUMPIID(iid, _T("iid")); + if (guidService == SID_SInternetSecurityManager && iid == IID_IInternetSecurityManager) { + TRACE(_T("%s\n"), _T("QueryService")); + return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObject); } *ppvObject = NULL; return E_NOINTERFACE; diff --git a/srchybrid/IESecurity.h b/srchybrid/IESecurity.h index ae07ff49..a864fdc6 100644 --- a/srchybrid/IESecurity.h +++ b/srchybrid/IESecurity.h @@ -12,6 +12,7 @@ class CMuleBrowserControlSite : public CBrowserControlSite DECLARE_INTERFACE_MAP(); BEGIN_INTERFACE_PART(InternetSecurityManager, IInternetSecurityManager) + virtual ~XInternetSecurityManager() = default; STDMETHOD(SetSecuritySite)(IInternetSecurityMgrSite*); STDMETHOD(GetSecuritySite)(IInternetSecurityMgrSite**); STDMETHOD(MapUrlToZone)(LPCWSTR, DWORD*, DWORD); @@ -23,6 +24,7 @@ class CMuleBrowserControlSite : public CBrowserControlSite END_INTERFACE_PART(InternetSecurityManager) BEGIN_INTERFACE_PART(ServiceProvider, IServiceProvider) + virtual ~XServiceProvider() = default; STDMETHOD(QueryService)(REFGUID, REFIID, void**); END_INTERFACE_PART(ServiceProvider) }; \ No newline at end of file diff --git a/srchybrid/IPFilter.cpp b/srchybrid/IPFilter.cpp index 8965cd7a..0f98f70a 100644 --- a/srchybrid/IPFilter.cpp +++ b/srchybrid/IPFilter.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -37,7 +37,6 @@ static char THIS_FILE[] = __FILE__; CIPFilter::CIPFilter() : m_pLastHit() - , m_bModified() { LoadFromDefaultFile(false); } @@ -53,11 +52,9 @@ CIPFilter::~CIPFilter() RemoveAllIPFilters(); } -static int __cdecl CmpSIPFilterByStartAddr(const void *p1, const void *p2) noexcept +static int __cdecl CompareByStartIP(const void *p1, const void *p2) noexcept { - const SIPFilter *rng1 = *(SIPFilter**)p1; - const SIPFilter *rng2 = *(SIPFilter**)p2; - return CompareUnsigned(rng1->start, rng2->start); + return CompareUnsigned((*(SIPFilter**)p1)->start, (*(SIPFilter**)p2)->start); } CString CIPFilter::GetDefaultFilePath() @@ -68,12 +65,13 @@ CString CIPFilter::GetDefaultFilePath() INT_PTR CIPFilter::LoadFromDefaultFile(bool bShowResponse) { RemoveAllIPFilters(); + m_bModified = false; return AddFromFile(GetDefaultFilePath(), bShowResponse); } INT_PTR CIPFilter::AddFromFile(LPCTSTR pszFilePath, bool bShowResponse) { - DWORD dwStart = ::GetTickCount(); + const DWORD dwStart = ::GetTickCount(); FILE *readFile = _tfsopen(pszFilePath, _T("r"), _SH_DENYWR); if (readFile != NULL) { int iFoundRanges = 0; @@ -86,7 +84,7 @@ INT_PTR CIPFilter::AddFromFile(LPCTSTR pszFilePath, bool bShowResponse) PeerGuardian = 2, // PeerGuardian text format PeerGuardian2 = 3 // PeerGuardian binary format } eFileType = Unknown; - setvbuf(readFile, NULL, _IOFBF, 32768); + ::setvbuf(readFile, NULL, _IOFBF, 32768); TCHAR szNam[_MAX_FNAME]; TCHAR szExt[_MAX_EXT]; @@ -170,30 +168,28 @@ INT_PTR CIPFilter::AddFromFile(LPCTSTR pszFilePath, bool bShowResponse) else { // check for ':' '-' int iColon = sbuffer.Find(':'); - if (iColon > -1) { - const CStringA &strIPRange(sbuffer.Mid(iColon + 1)); - if (sscanf(strIPRange, "%3u.%3u.%3u.%3u - %3u.%3u.%3u.%3u", &u1, &u2, &u3, &u4, &u5, &u6, &u7, &u8) == 8) + if (iColon >= 0) { + if (sscanf(CPTRA(sbuffer, iColon + 1), "%3u.%3u.%3u.%3u - %3u.%3u.%3u.%3u", &u1, &u2, &u3, &u4, &u5, &u6, &u7, &u8) == 8) eFileType = PeerGuardian; } } } - bool bValid = false; - uint32 start = 0; - uint32 end = 0; - UINT level = 0; + bool bValid; + uint32 start, end, level; CStringA desc; if (eFileType == FilterDat) bValid = ParseFilterLine1(sbuffer, start, end, level, desc); else if (eFileType == PeerGuardian) bValid = ParseFilterLine2(sbuffer, start, end, level, desc); - + else + bValid = false; // add a filter if (bValid) { AddIPRange(start, end, level, desc); ++iFoundRanges; } else - DEBUG_ONLY((!sbuffer.IsEmpty()) ? TRACE("IP filter: ignored line %u\n", iLine) : (void)0); + DEBUG_ONLY(sbuffer.IsEmpty() ? 0 : TRACE("IP filter: ignored line %u\n", iLine)); } } } catch (...) { @@ -203,8 +199,8 @@ INT_PTR CIPFilter::AddFromFile(LPCTSTR pszFilePath, bool bShowResponse) } fclose(readFile); - // sort the IP filter list by IP range start addresses - qsort(m_iplist.GetData(), m_iplist.GetCount(), sizeof(m_iplist[0]), CmpSIPFilterByStartAddr); + // sort the filter list by starting address of IP ranges + qsort(m_iplist.GetData(), m_iplist.GetCount(), sizeof(m_iplist[0]), CompareByStartIP); // merge overlapping and adjacent filter ranges int iDuplicate = 0; @@ -217,7 +213,7 @@ INT_PTR CIPFilter::AddFromFile(LPCTSTR pszFilePath, bool bShowResponse) // Reserve a byte array (its used as a boolean array actually) as large as the current // IP-filter list, so we can set a 'to delete' flag for each entry in the current IP-filter list. - char *pcToDelete = new char[m_iplist.GetCount()](); + char *pcToDelete = new char[m_iplist.GetCount()]{}; int iNumToDelete = 0; SIPFilter *pPrv = m_iplist[0]; @@ -230,7 +226,7 @@ INT_PTR CIPFilter::AddFromFile(LPCTSTR pszFilePath, bool bShowResponse) //TODO: not yet handled, overlapping entries with different 'level' if (pCur->end > pPrv->end) pPrv->end = pCur->end; - //pPrv->desc.AppendFormat("; %s", (LPCSTR)pCur->desc); // this may create a very very long description string... + //pPrv->desc.AppendFormat("; %s", (LPCSTR)pCur->desc); // this may create a very, very long description string... ++iMerged; } else { // if we have identical entries, use the lowest 'level' @@ -268,9 +264,8 @@ INT_PTR CIPFilter::AddFromFile(LPCTSTR pszFilePath, bool bShowResponse) } if (thePrefs.GetVerbose()) { - DWORD dwEnd = ::GetTickCount(); AddDebugLogLine(false, _T("Loaded IP filters from \"%s\""), pszFilePath); - AddDebugLogLine(false, _T("Parsed lines/entries:%u Found IP ranges:%u Duplicate:%u Merged:%u Time:%s"), iLine, iFoundRanges, iDuplicate, iMerged, (LPCTSTR)CastSecondsToHM((dwEnd - dwStart + 500) / 1000)); + AddDebugLogLine(false, _T("Parsed lines/entries:%u Found IP ranges:%u Duplicate:%u Merged:%u Time:%s"), iLine, iFoundRanges, iDuplicate, iMerged, (LPCTSTR)CastSecondsToHM((::GetTickCount() - dwStart + 500) / 1000)); } AddLogLine(bShowResponse, GetResString(IDS_IPFILTERLOADED), m_iplist.GetCount()); } @@ -279,7 +274,7 @@ INT_PTR CIPFilter::AddFromFile(LPCTSTR pszFilePath, bool bShowResponse) void CIPFilter::SaveToDefaultFile() { - const CString strFilePath(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + DFLT_IPFILTER_FILENAME); + const CString &strFilePath(GetDefaultFilePath()); FILE *fp = _tfsopen(strFilePath, _T("wt"), _SH_DENYWR); if (fp != NULL) { for (int i = 0; i < m_iplist.GetCount(); ++i) { @@ -291,7 +286,7 @@ void CIPFilter::SaveToDefaultFile() CHAR szEnd[16]; ipstrA(szEnd, _countof(szEnd), htonl(flt->end)); - if (fprintf(fp, "%-15s - %-15s , %03u , %s\n", szStart, szEnd, flt->level, (LPCSTR)flt->desc) == 0 || ferror(fp)) { + if (fprintf(fp, "%-15s - %-15s , %3u , %s\n", szStart, szEnd, flt->level, (LPCSTR)flt->desc) == 0 || ferror(fp)) { CString strError; strError.Format(_T("Failed to save IP filter to file \"%s\" - %s"), (LPCTSTR)strFilePath, _tcserror(errno)); fclose(fp); @@ -307,7 +302,7 @@ void CIPFilter::SaveToDefaultFile() } } -bool CIPFilter::ParseFilterLine1(const CStringA &sbuffer, uint32 &ip1, uint32 &ip2, UINT &level, CStringA &desc) +bool CIPFilter::ParseFilterLine1(const CStringA &sbuffer, uint32 &ip1, uint32 &ip2, uint32 &level, CStringA &desc) { UINT u1, u2, u3, u4, u5, u6, u7, u8, uLevel = DFLT_FILTER_LEVEL; int iDescStart = 0; @@ -333,19 +328,17 @@ bool CIPFilter::ParseFilterLine1(const CStringA &sbuffer, uint32 &ip1, uint32 &i level = uLevel; if (iDescStart > 0) { - LPCSTR pszDescStart = (LPCSTR)sbuffer + iDescStart; + LPCSTR pszDescStart = CPTRA(sbuffer, iDescStart); int iDescLen = sbuffer.GetLength() - iDescStart; - if (iDescLen > 0 && pszDescStart[iDescLen - 1] == '\n') + while (iDescLen > 0 && pszDescStart[iDescLen - 1] < ' ') //any control characters --iDescLen; - - memcpy(desc.GetBuffer(iDescLen), pszDescStart, iDescLen * (sizeof pszDescStart[0])); - desc.ReleaseBuffer(iDescLen); + desc = CStringA(pszDescStart, iDescLen); } return true; } -bool CIPFilter::ParseFilterLine2(const CStringA &sbuffer, uint32 &ip1, uint32 &ip2, UINT &level, CStringA &desc) +bool CIPFilter::ParseFilterLine2(const CStringA &sbuffer, uint32 &ip1, uint32 &ip2, uint32 &level, CStringA &desc) { int iPos = sbuffer.ReverseFind(':'); if (iPos < 0) @@ -355,9 +348,8 @@ bool CIPFilter::ParseFilterLine2(const CStringA &sbuffer, uint32 &ip1, uint32 &i desc.Replace("PGIPDB", ""); desc.Trim(); - CStringA strIPRange = sbuffer.Mid(iPos + 1, sbuffer.GetLength() - iPos); unsigned u1, u2, u3, u4, u5, u6, u7, u8; - if (sscanf(strIPRange, "%3u.%3u.%3u.%3u - %3u.%3u.%3u.%3u", &u1, &u2, &u3, &u4, &u5, &u6, &u7, &u8) != 8) + if (sscanf(CPTRA(sbuffer, iPos + 1), "%3u.%3u.%3u.%3u - %3u.%3u.%3u.%3u", &u1, &u2, &u3, &u4, &u5, &u6, &u7, &u8) != 8) return false; ((BYTE*)&ip1)[0] = (BYTE)u4; @@ -400,7 +392,7 @@ static int __cdecl CmpSIPFilterByAddr(const void *pvKey, const void *pvElement) return 0; } -bool CIPFilter::IsFiltered(uint32 ip, UINT level) /*const*/ +bool CIPFilter::IsFiltered(uint32 ip, uint32 level) /*const*/ { if (m_iplist.IsEmpty() || ip == 0) return false; @@ -414,7 +406,7 @@ bool CIPFilter::IsFiltered(uint32 ip, UINT level) /*const*/ // *) the filter 'level' is ignored during the binary search and is evaluated only for the found element // // TODO: this can still be improved even more: - // *) use a pre assembled list of IP ranges which contains only the IP ranges for the currently used filter level + // *) use a pre-assembled list of IP ranges which contains only the IP ranges for the currently used filter level // *) use a dumb plain array for storing the IP range structures. this will give more cache hits when processing // the list. but(!) this would require to also use a dumb SIPFilter structure (don't use data items with ctors). // otherwise the creation of the array would be rather slow. diff --git a/srchybrid/IPFilter.h b/srchybrid/IPFilter.h index 1f6d82ec..9932fed7 100644 --- a/srchybrid/IPFilter.h +++ b/srchybrid/IPFilter.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -18,7 +18,7 @@ struct SIPFilter { - SIPFilter(uint32 newStart, uint32 newEnd, UINT newLevel, const CStringA &newDesc) + SIPFilter(uint32 newStart, uint32 newEnd, uint32 newLevel, const CStringA &newDesc) : start(newStart) , end(newEnd) , level(newLevel) @@ -29,7 +29,7 @@ struct SIPFilter uint32 start; uint32 end; - UINT level; + uint32 level; UINT hits; CStringA desc; }; @@ -49,7 +49,7 @@ class CIPFilter static CString GetDefaultFilePath(); - void AddIPRange(uint32 start, uint32 end, UINT level, const CStringA &rstrDesc) + void AddIPRange(uint32 start, uint32 end, uint32 level, const CStringA &rstrDesc) { m_iplist.Add(new SIPFilter(start, end, level, rstrDesc)); } @@ -65,7 +65,7 @@ class CIPFilter void SaveToDefaultFile(); bool IsFiltered(uint32 ip) /*const*/; - bool IsFiltered(uint32 ip, UINT level) /*const*/; + bool IsFiltered(uint32 ip, uint32 level) /*const*/; CString GetLastHit() const; const CIPFilterArray& GetIPFilter() const; @@ -74,6 +74,6 @@ class CIPFilter CIPFilterArray m_iplist; bool m_bModified; - static bool ParseFilterLine1(const CStringA &sbuffer, uint32 &ip1, uint32 &ip2, UINT &level, CStringA &desc); - static bool ParseFilterLine2(const CStringA &sbuffer, uint32 &ip1, uint32 &ip2, UINT &level, CStringA &desc); + static bool ParseFilterLine1(const CStringA &sbuffer, uint32 &ip1, uint32 &ip2, uint32 &level, CStringA &desc); + static bool ParseFilterLine2(const CStringA &sbuffer, uint32 &ip1, uint32 &ip2, uint32 &level, CStringA &desc); }; \ No newline at end of file diff --git a/srchybrid/IPFilterDlg.cpp b/srchybrid/IPFilterDlg.cpp index e7053956..c1799563 100644 --- a/srchybrid/IPFilterDlg.cpp +++ b/srchybrid/IPFilterDlg.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -53,7 +53,7 @@ static LCX_COLUMN_INIT s_aColumns[] = { IPFILTER_COL_END, _T("End"), IDS_IP_END, LVCFMT_LEFT, -1, 1, ASCENDING, NONE, _T("255.255.255.255")}, { IPFILTER_COL_LEVEL, _T("Level"), IDS_IP_LEVEL, LVCFMT_RIGHT, -1, 2, ASCENDING, NONE, _T("999") }, { IPFILTER_COL_HITS, _T("Hits"), IDS_IP_HITS, LVCFMT_RIGHT, -1, 3, DESCENDING, NONE, _T("99999") }, - { IPFILTER_COL_DESC, _T("Description"), IDS_IP_DESC, LVCFMT_LEFT, -1, 4, ASCENDING, NONE, _T("long long long long long long long long file name") }, + { IPFILTER_COL_DESC, _T("Description"), IDS_IP_DESC, LVCFMT_LEFT, -1, 4, ASCENDING, NONE, _T("long long long long long long long long text line") }, }; #define PREF_INI_SECTION _T("IPFilterDlg") @@ -111,36 +111,28 @@ static int s_lParamSort = 0; int __cdecl CompareIPFilterItems(const void *lParam1, const void *lParam2) noexcept { -#define COMPARE_NUM(a,b) ((a) < (b)) \ - ? -1 \ - : ( ((b) < (a)) \ - ? 1 \ - : 0 \ - ) - int iResult; switch (s_lParamSort) { case IPFILTER_COL_START: - iResult = COMPARE_NUM((*((SIPFilter**)lParam1))->start, (*((SIPFilter**)lParam2))->start); + iResult = CompareUnsigned((*((SIPFilter**)lParam1))->start, (*((SIPFilter**)lParam2))->start); break; case IPFILTER_COL_END: - iResult = COMPARE_NUM((*((SIPFilter**)lParam1))->end, (*((SIPFilter**)lParam2))->end); + iResult = CompareUnsigned((*((SIPFilter**)lParam1))->end, (*((SIPFilter**)lParam2))->end); break; case IPFILTER_COL_LEVEL: - iResult = COMPARE_NUM((*((SIPFilter**)lParam1))->level, (*((SIPFilter**)lParam2))->level); + iResult = CompareUnsigned((*((SIPFilter**)lParam1))->level, (*((SIPFilter**)lParam2))->level); break; case IPFILTER_COL_HITS: - iResult = COMPARE_NUM((*((SIPFilter**)lParam1))->hits, (*((SIPFilter**)lParam2))->hits); + iResult = CompareUnsigned((*((SIPFilter**)lParam1))->hits, (*((SIPFilter**)lParam2))->hits); break; case IPFILTER_COL_DESC: - iResult = _stricmp/*CompareLocaleStringNoCase*/((*((SIPFilter**)lParam1))->desc, (*((SIPFilter**)lParam2))->desc); + iResult = _stricmp((*((SIPFilter**)lParam1))->desc, (*((SIPFilter**)lParam2))->desc); break; default: ASSERT(0); return 0; } -#undef COMPARE_NUM return (s_aColumns[s_lParamSort].eSortOrder == DESCENDING) ? -iResult : iResult; } @@ -156,7 +148,7 @@ void CIPFilterDlg::SortIPFilterItems() void CIPFilterDlg::OnLvnColumnClickIPFilter(LPNMHDR pNMHDR, LRESULT *pResult) { - LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); m_ipfilter.UpdateSortOrder(pNMLV, _countof(s_aColumns), s_aColumns); SortIPFilterItems(); m_ipfilter.Invalidate(); @@ -318,21 +310,22 @@ void CIPFilterDlg::OnBnClickedAppend() { // Save/Restore the current directory TCHAR szCurDir[MAX_PATH]; - DWORD dwCurDirLen = GetCurrentDirectory(_countof(szCurDir), szCurDir); + DWORD dwCurDirLen = ::GetCurrentDirectory(_countof(szCurDir), szCurDir); if (dwCurDirLen == 0 || dwCurDirLen >= _countof(szCurDir)) szCurDir[0] = _T('\0'); - CString strFilePath; // Do NOT localize that string + CString strFilePath; // Do NOT localize that string if (DialogBrowseFile(strFilePath, _T("All IP Filter Files (*ipfilter.dat;*ip.prefix;*.p2b;*.p2p;*.p2p.txt;*.zip;*.gz;*.rar)|*ipfilter.dat;*ip.prefix;*.p2b;*.p2p;*.p2p.txt;*.zip;*.gz;*.rar|eMule IP Filter Files (*ipfilter.dat;*ip.prefix)|*ipfilter.dat;*ip.prefix|Peer Guardian Files (*.p2b;*.p2p;*.p2p.txt)|*.p2b;*.p2p;*.p2p.txt|Text Files (*.txt)|*.txt|ZIP Files (*.zip;*.gz)|*.zip;*.gz|RAR Files (*.rar)|*.rar|All Files (*.*)|*.*||"))) { CWaitCursor curWait; - CString szExt(PathFindExtension(strFilePath)); + const CString &sConfDir(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); + CString szExt(::PathFindExtension(strFilePath)); szExt.MakeLower(); - bool bIsArchiveFile = szExt.Compare(_T(".zip")) == 0 || szExt.Compare(_T(".rar")) == 0 || szExt.Compare(_T(".gz")) == 0; + bool bIsArchiveFile = (szExt == _T(".zip") || szExt == _T(".rar") || szExt == _T(".gz")); bool bExtractedArchive = false; CString strTempUnzipFilePath; - if (szExt.Compare(_T(".zip")) == 0) { + if (szExt == _T(".zip")) { CZIPFile zip; if (zip.Open(strFilePath)) { CZIPFile::File *zfile = zip.GetFile(_T("ipfilter.dat")); @@ -341,7 +334,7 @@ void CIPFilterDlg::OnBnClickedAppend() if (zfile == NULL) zfile = zip.GetFile(_T("guardian.p2p")); if (zfile) { - _tmakepathlimit(strTempUnzipFilePath.GetBuffer(MAX_PATH), NULL, thePrefs.GetMuleDirectory(EMULE_CONFIGDIR), DFLT_IPFILTER_FILENAME, _T(".unzip.tmp")); + _tmakepathlimit(strTempUnzipFilePath.GetBuffer(MAX_PATH), NULL, sConfDir, DFLT_IPFILTER_FILENAME, _T(".unzip.tmp")); strTempUnzipFilePath.ReleaseBuffer(); if (zfile->Extract(strTempUnzipFilePath)) { strFilePath = strTempUnzipFilePath; @@ -362,7 +355,7 @@ void CIPFilterDlg::OnBnClickedAppend() strError.Format(_T("Failed to open file \"%s\".\r\n\r\nInvalid file format?"), (LPCTSTR)strFilePath); AfxMessageBox(strError, MB_ICONERROR); } - } else if (szExt.Compare(_T(".rar")) == 0) { + } else if (szExt == _T(".rar")) { CRARFile rar; if (rar.Open(strFilePath)) { CString strFile; @@ -371,7 +364,7 @@ void CIPFilterDlg::OnBnClickedAppend() || strFile.CompareNoCase(_T("guarding.p2p")) == 0 || strFile.CompareNoCase(_T("guardian.p2p")) == 0)) { - _tmakepathlimit(strTempUnzipFilePath.GetBuffer(MAX_PATH), NULL, thePrefs.GetMuleDirectory(EMULE_CONFIGDIR), DFLT_IPFILTER_FILENAME, _T(".unzip.tmp")); + _tmakepathlimit(strTempUnzipFilePath.GetBuffer(MAX_PATH), NULL, sConfDir, DFLT_IPFILTER_FILENAME, _T(".unzip.tmp")); strTempUnzipFilePath.ReleaseBuffer(); if (rar.Extract(strTempUnzipFilePath)) { strFilePath = strTempUnzipFilePath; @@ -392,10 +385,10 @@ void CIPFilterDlg::OnBnClickedAppend() strError.Format(_T("Failed to open file \"%s\".\r\n\r\nInvalid file format?\r\n\r\nDownload latest version of UNRAR.DLL from http://www.rarlab.com and copy UNRAR.DLL into eMule installation folder."), (LPCTSTR)strFilePath); AfxMessageBox(strError, MB_ICONERROR); } - } else if (szExt.Compare(_T(".gz")) == 0) { + } else if (szExt == _T(".gz")) { CGZIPFile gz; if (gz.Open(strFilePath)) { - _tmakepathlimit(strTempUnzipFilePath.GetBuffer(MAX_PATH), NULL, thePrefs.GetMuleDirectory(EMULE_CONFIGDIR), DFLT_IPFILTER_FILENAME, _T(".unzip.tmp")); + _tmakepathlimit(strTempUnzipFilePath.GetBuffer(MAX_PATH), NULL, sConfDir, DFLT_IPFILTER_FILENAME, _T(".unzip.tmp")); strTempUnzipFilePath.ReleaseBuffer(); // add filename and extension of uncompressed file to temporary file @@ -432,7 +425,7 @@ void CIPFilterDlg::OnBnClickedAppend() void CIPFilterDlg::OnLvnDeleteItemIPFilter(LPNMHDR pNMHDR, LRESULT *pResult) { - LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); ASSERT(m_uIPFilterItems > 0); if (m_uIPFilterItems > 0) { diff --git a/srchybrid/IconStatic.cpp b/srchybrid/IconStatic.cpp index 75d1de6f..e9798b04 100644 --- a/srchybrid/IconStatic.cpp +++ b/srchybrid/IconStatic.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/Ini2.cpp b/srchybrid/Ini2.cpp index 9011cf00..6053ea78 100644 --- a/srchybrid/Ini2.cpp +++ b/srchybrid/Ini2.cpp @@ -25,7 +25,7 @@ void CIni::AddModulePath(CString &rstrFileName, bool bModulPath) DWORD dwModPathLen = ::GetModuleFileName(NULL, strModule.GetBuffer(MAX_PATH), MAX_PATH); strModule.ReleaseBuffer((dwModPathLen == 0 || dwModPathLen == MAX_PATH) ? 0 : -1); } else { - DWORD dwCurDirLen = GetCurrentDirectory(MAX_PATH, strModule.GetBuffer(MAX_PATH)); + DWORD dwCurDirLen = ::GetCurrentDirectory(MAX_PATH, strModule.GetBuffer(MAX_PATH)); strModule.ReleaseBuffer((dwCurDirLen == 0 || dwCurDirLen >= MAX_PATH) ? 0 : -1); // fix by "cpp@world-online.no" strModule.TrimRight(_T("\\/")); @@ -37,11 +37,6 @@ void CIni::AddModulePath(CString &rstrFileName, bool bModulPath) } } -CString CIni::GetDefaultSection() -{ - return AfxGetAppName(); -} - CString CIni::GetDefaultIniFile(bool bModulPath) { TCHAR drive[_MAX_DRIVE]; @@ -58,7 +53,7 @@ CString CIni::GetDefaultIniFile(bool bModulPath) if (bModulPath) strApplName.Format(_T("%s%s%s"), drive, dir, (LPCTSTR)strTemp); else { - DWORD dwCurDirLen = GetCurrentDirectory(MAX_PATH, strApplName.GetBuffer(MAX_PATH)); + DWORD dwCurDirLen = ::GetCurrentDirectory(MAX_PATH, strApplName.GetBuffer(MAX_PATH)); strApplName.ReleaseBuffer((dwCurDirLen == 0 || dwCurDirLen >= MAX_PATH) ? 0 : -1); strApplName.TrimRight(_T('\\')); strApplName.TrimRight(_T('/')); @@ -86,9 +81,9 @@ CIni::CIni(const CIni &Ini) m_strSection = GetDefaultSection(); } -CIni::CIni(const CString &rstrFileName) +CIni::CIni(LPCTSTR const pstrFileName) : m_bModulePath(true) - , m_strFileName(rstrFileName) + , m_strFileName(pstrFileName) { if (m_strFileName.IsEmpty()) m_strFileName = GetDefaultIniFile(m_bModulePath); @@ -96,10 +91,10 @@ CIni::CIni(const CString &rstrFileName) m_strSection = GetDefaultSection(); } -CIni::CIni(const CString &rstrFileName, const CString &rstrSection) +CIni::CIni(LPCTSTR const pstrFileName, LPCTSTR const pstrSection) : m_bModulePath(true) - , m_strFileName(rstrFileName) - , m_strSection(rstrSection) + , m_strFileName(pstrFileName) + , m_strSection(pstrSection) { if (m_strFileName.IsEmpty()) m_strFileName = GetDefaultIniFile(m_bModulePath); @@ -116,27 +111,6 @@ CIni& CIni::operator=(const CIni &Ini) return *this; } -void CIni::SetFileName(const CString &rstrFileName) -{ - m_strFileName = rstrFileName; - AddModulePath(m_strFileName); -} - -void CIni::SetSection(const CString &rstrSection) -{ - m_strSection = rstrSection; -} - -const CString& CIni::GetFileName() const -{ - return m_strFileName; -} - -const CString& CIni::GetSection() const -{ - return m_strSection; -} - CString CIni::GetString(LPCTSTR lpszEntry, LPCTSTR lpszDefault, LPCTSTR lpszSection) { if (lpszSection != NULL) @@ -146,17 +120,17 @@ CString CIni::GetString(LPCTSTR lpszEntry, LPCTSTR lpszDefault, LPCTSTR lpszSect CString CIni::GetStringLong(LPCTSTR lpszEntry, LPCTSTR lpszDefault, LPCTSTR lpszSection) { - CString ret; unsigned maxstrlen = MAX_INI_BUFFER; if (lpszSection != NULL) m_strSection = lpszSection; + CString ret; do { - GetPrivateProfileString(m_strSection, lpszEntry, (lpszDefault == NULL) ? _T("") : lpszDefault, - ret.GetBuffer(maxstrlen), maxstrlen, m_strFileName); + GetPrivateProfileString(m_strSection, lpszEntry, (lpszDefault ? lpszDefault : _T("")) + , ret.GetBuffer(maxstrlen), maxstrlen, m_strFileName); ret.ReleaseBuffer(); - if ((unsigned)ret.GetLength() < maxstrlen - 2u) + if ((unsigned)ret.GetLength() < maxstrlen - 2) break; maxstrlen += MAX_INI_BUFFER; } while (maxstrlen < _UI16_MAX); @@ -170,8 +144,8 @@ CString CIni::GetStringUTF8(LPCTSTR lpszEntry, LPCTSTR lpszDefault, LPCTSTR lpsz m_strSection = lpszSection; CStringA strUTF8; - GetPrivateProfileStringA(CStringA(m_strSection), CStringA(lpszEntry), CStringA(lpszDefault), - strUTF8.GetBuffer(MAX_INI_BUFFER), MAX_INI_BUFFER, CStringA(m_strFileName)); + GetPrivateProfileStringA(CStringA(m_strSection), CStringA(lpszEntry), CStringA(lpszDefault) + , strUTF8.GetBuffer(MAX_INI_BUFFER), MAX_INI_BUFFER, CStringA(m_strFileName)); strUTF8.ReleaseBuffer(); return OptUtf8ToStr(strUTF8); } @@ -728,7 +702,7 @@ bool CIni::GetBinary(LPCTSTR lpszEntry, BYTE **ppData, UINT *pBytes, LPCTSTR psz *ppData = NULL; *pBytes = 0; - const CString &str = GetString(lpszEntry, NULL, pszSection); + const CString &str(GetString(lpszEntry, NULL, pszSection)); int nLen = str.GetLength(); ASSERT(nLen % 2 == 0); if (nLen <= 1) @@ -741,12 +715,12 @@ bool CIni::GetBinary(LPCTSTR lpszEntry, BYTE **ppData, UINT *pBytes, LPCTSTR psz return true; } -bool CIni::WriteBinary(LPCTSTR lpszEntry, LPBYTE pData, UINT nBytes, LPCTSTR lpszSection) +bool CIni::WriteBinary(LPCTSTR lpszEntry, LPBYTE pData, size_t nBytes, LPCTSTR lpszSection) { // convert to string and write out LPTSTR lpsz = new TCHAR[nBytes * 2 + 1]; LPTSTR p = lpsz; - for (UINT i = 0; i < nBytes; ++i) { + for (; nBytes; --nBytes) { *p++ = (TCHAR)((*pData & 0x0F) + 'A'); //low nibble *p++ = (TCHAR)(((*pData++ >> 4) & 0x0F) + 'A'); //high nibble } diff --git a/srchybrid/Ini2.h b/srchybrid/Ini2.h index 18537a3a..f7a034a4 100644 --- a/srchybrid/Ini2.h +++ b/srchybrid/Ini2.h @@ -37,34 +37,34 @@ class CIni // the module's directory will be added to the FileName, // bModulePath=true: ModuleDir, bModulePath=false: CurrentDir static void AddModulePath(CString &rstrFileName, bool bModulPath = true); - static CString GetDefaultSection(); + static CString GetDefaultSection() { return AfxGetAppName(); }; static CString GetDefaultIniFile(bool bModulPath = true); CIni(); explicit CIni(const CIni &Ini); - explicit CIni(const CString &rstrFileName); - CIni(const CString &rstrFileName, const CString &rstrSection); + explicit CIni(LPCTSTR const pstrFileName); + CIni(LPCTSTR const pstrFileName, LPCTSTR const pstrSection); CIni& operator=(const CIni &Ini); virtual ~CIni() = default; - void SetFileName(const CString &rstrFileName); - void SetSection(const CString &rstrSection); - const CString& GetFileName() const; - const CString& GetSection() const; - - CString GetStringUTF8(LPCTSTR lpszEntry,LPCTSTR lpszDefault = NULL, LPCTSTR lpszSection = NULL); - CString GetStringLong(LPCTSTR lpszEntry,LPCTSTR lpszDefault = NULL, LPCTSTR lpszSection = NULL); - double GetDouble(LPCTSTR lpszEntry, double fDefault = 0.0, LPCTSTR lpszSection = NULL); - CString GetString(LPCTSTR lpszEntry, LPCTSTR lpszDefault = NULL, LPCTSTR lpszSection = NULL); - float GetFloat(LPCTSTR lpszEntry, float fDefault = 0.0F, LPCTSTR lpszSection = NULL); - int GetInt(LPCTSTR lpszEntry, int nDefault = 0, LPCTSTR lpszSection = NULL); - ULONGLONG GetUInt64(LPCTSTR lpszEntry, ULONGLONG nDefault = 0, LPCTSTR lpszSection = NULL); - WORD GetWORD(LPCTSTR lpszEntry, WORD nDefault = 0, LPCTSTR lpszSection = NULL); - bool GetBool(LPCTSTR lpszEntry, bool bDefault = false, LPCTSTR lpszSection = NULL); - CPoint GetPoint(LPCTSTR lpszEntry, const CPoint &ptDefault = CPoint(), LPCTSTR lpszSection = NULL); - CRect GetRect(LPCTSTR lpszEntry, const CRect &rcDefault = CRect(), LPCTSTR lpszSection = NULL); - COLORREF GetColRef(LPCTSTR lpszEntry, COLORREF crDefault = RGB(128,128,128),LPCTSTR lpszSection = NULL); - bool GetBinary(LPCTSTR lpszEntry, BYTE **ppData, UINT *pBytes, LPCTSTR pszSection = NULL); + void SetFileName(const CString &rstrFileName) { m_strFileName = rstrFileName; }; + void SetSection(const CString &rstrSection) { m_strSection = rstrSection; }; + const CString& GetFileName() const { return m_strFileName; }; + const CString& GetSection() const { return m_strSection;}; + + CString GetStringUTF8(LPCTSTR lpszEntry,LPCTSTR lpszDefault = NULL, LPCTSTR lpszSection = NULL); + CString GetStringLong(LPCTSTR lpszEntry,LPCTSTR lpszDefault = NULL, LPCTSTR lpszSection = NULL); + double GetDouble(LPCTSTR lpszEntry, double fDefault = 0.0, LPCTSTR lpszSection = NULL); + CString GetString(LPCTSTR lpszEntry, LPCTSTR lpszDefault = NULL, LPCTSTR lpszSection = NULL); + float GetFloat(LPCTSTR lpszEntry, float fDefault = 0.0f, LPCTSTR lpszSection = NULL); + int GetInt(LPCTSTR lpszEntry, int nDefault = 0, LPCTSTR lpszSection = NULL); + ULONGLONG GetUInt64(LPCTSTR lpszEntry, ULONGLONG nDefault = 0, LPCTSTR lpszSection = NULL); + WORD GetWORD(LPCTSTR lpszEntry, WORD nDefault = 0, LPCTSTR lpszSection = NULL); + bool GetBool(LPCTSTR lpszEntry, bool bDefault = false, LPCTSTR lpszSection = NULL); + CPoint GetPoint(LPCTSTR lpszEntry, const CPoint &ptDefault = CPoint(), LPCTSTR lpszSection = NULL); + CRect GetRect(LPCTSTR lpszEntry, const CRect &rcDefault = CRect(), LPCTSTR lpszSection = NULL); + COLORREF GetColRef(LPCTSTR lpszEntry, COLORREF crDefault = RGB(128,128,128), LPCTSTR lpszSection = NULL); + bool GetBinary(LPCTSTR lpszEntry, BYTE **ppData, UINT *pBytes, LPCTSTR pszSection = NULL); void WriteString(LPCTSTR lpszEntry, LPCTSTR lpsz, LPCTSTR lpszSection = NULL); void WriteStringUTF8(LPCTSTR lpszEntry,LPCTSTR lpsz, LPCTSTR lpszSection = NULL); @@ -77,7 +77,7 @@ class CIni void WritePoint(LPCTSTR lpszEntry, const CPoint &pt, LPCTSTR lpszSection = NULL); void WriteRect(LPCTSTR lpszEntry, const CRect &rect, LPCTSTR lpszSection = NULL); void WriteColRef(LPCTSTR lpszEntry, COLORREF cr, LPCTSTR lpszSection = NULL); - bool WriteBinary(LPCTSTR lpszEntry, LPBYTE pData, UINT nBytes,LPCTSTR lpszSection = NULL); + bool WriteBinary(LPCTSTR lpszEntry, LPBYTE pData, size_t nBytes, LPCTSTR lpszSection = NULL); void SerGetString( bool bGet, CString &rstr, LPCTSTR lpszEntry, LPCTSTR lpszSection = NULL, LPCTSTR lpszDefault = NULL); void SerGetDouble( bool bGet, double &f, LPCTSTR lpszEntry, LPCTSTR lpszSection = NULL, double fDefault = 0.0); diff --git a/srchybrid/InputBox.cpp b/srchybrid/InputBox.cpp index 97684bda..da5046f8 100644 --- a/srchybrid/InputBox.cpp +++ b/srchybrid/InputBox.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/InputBox.h b/srchybrid/InputBox.h index 2553f733..b8c5effc 100644 --- a/srchybrid/InputBox.h +++ b/srchybrid/InputBox.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/IrcChannelListCtrl.cpp b/srchybrid/IrcChannelListCtrl.cpp index 54e43bc2..4e88ada7 100644 --- a/srchybrid/IrcChannelListCtrl.cpp +++ b/srchybrid/IrcChannelListCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -34,12 +34,15 @@ static char THIS_FILE[] = __FILE__; struct ChannelName { ChannelName(const CString &sName, UINT uUsers, const CString &sDesc) - : m_sName(sName), m_uUsers(uUsers), m_sDesc(sDesc) + : m_sName(sName) + , m_sDesc(sDesc) + , m_uUsers(uUsers) { } + CString m_sName; - UINT m_uUsers; CString m_sDesc; + UINT m_uUsers; }; IMPLEMENT_DYNAMIC(CIrcChannelListCtrl, CMuleListCtrl) @@ -67,32 +70,22 @@ void CIrcChannelListCtrl::Init() SetPrefsKey(_T("IrcChannelListCtrl")); SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP); - InsertColumn(0, GetResString(IDS_IRC_NAME), LVCFMT_LEFT, 200); - InsertColumn(1, GetResString(IDS_UUSERS), LVCFMT_RIGHT, 50); - InsertColumn(2, GetResString(IDS_DESCRIPTION), LVCFMT_LEFT, 350); + InsertColumn(0, _T(""), LVCFMT_LEFT, 200); //IDS_IRC_NAME + InsertColumn(1, _T(""), LVCFMT_RIGHT, 50); //IDS_UUSERS + InsertColumn(2, _T(""), LVCFMT_LEFT, 350); //IDS_DESCRIPTION LoadSettings(); SetSortArrow(); - SortItems(&SortProc, GetSortItem() + (GetSortAscending() ? 0 : 10)); + SortItems(&SortProc, MAKELONG(GetSortItem(), !GetSortAscending())); } void CIrcChannelListCtrl::Localize() { - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); - HDITEM hdi; - hdi.mask = HDI_TEXT; - - CString strRes = GetResString(IDS_IRC_NAME); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(0, &hdi); - - strRes = GetResString(IDS_UUSERS); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(1, &hdi); - - strRes = GetResString(IDS_DESCRIPTION); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(2, &hdi); + static const UINT uids[3] = + { + IDS_IRC_NAME, IDS_UUSERS, IDS_DESCRIPTION + }; + LocaliseHeaderCtrl(uids, _countof(uids)); } CString CIrcChannelListCtrl::GetItemDisplayText(const ChannelName *pChannel, int iSubItem) const @@ -114,16 +107,16 @@ CString CIrcChannelListCtrl::GetItemDisplayText(const ChannelName *pChannel, int void CIrcChannelListCtrl::OnLvnGetDispInfo(LPNMHDR pNMHDR, LRESULT *pResult) { if (!theApp.IsClosing()) { - // Although we have an owner drawn listview control we store the text for the primary item in the listview, to be - // capable of quick searching those items via the keyboard. Because our listview items may change their contents, - // we do this via a text callback function. The listview control will send us the LVN_DISPINFO notification if - // it needs to know the contents of the primary item. + // Although we have an owner drawn listview control we store the text for the primary item in the + // listview, to be capable of quick searching those items via the keyboard. Because our listview + // items may change their contents, we do this via a text callback function. The listview control + // will send us the LVN_DISPINFO notification if it needs to know the contents of the primary item. // - // But, the listview control sends this notification all the time, even if we do not search for an item. At least - // this notification is only sent for the visible items and not for all items in the list. Though, because this - // function is invoked *very* often, do *NOT* put any time consuming code in here. + // But, the listview control sends this notification all the time, even if we do not search for an item. + // At least this notification is only sent for the visible items and not for all items in the list. + // Though, because this function is invoked *very* often, do *NOT* put any time consuming code in here. // - // Vista: That callback is used to get the strings for the label tips for the sub(!) items. + // Vista: That callback is used to get the strings for the label tips for the sub(!)-items. // const LVITEMW &rItem = reinterpret_cast(pNMHDR)->item; if (rItem.mask & LVIF_TEXT) { @@ -137,12 +130,11 @@ void CIrcChannelListCtrl::OnLvnGetDispInfo(LPNMHDR pNMHDR, LRESULT *pResult) void CIrcChannelListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) { - LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); + bool bSortAscending = (GetSortItem() != pNMLV->iSubItem || !GetSortAscending()); - bool bSortAscending = (GetSortItem() != pNMLV->iSubItem) ? true : !GetSortAscending(); SetSortArrow(pNMLV->iSubItem, bSortAscending); - SortItems(&SortProc, pNMLV->iSubItem + (bSortAscending ? 0 : 10)); - + SortItems(SortProc, MAKELONG(pNMLV->iSubItem, !bSortAscending)); *pResult = 0; } @@ -150,9 +142,9 @@ int CALLBACK CIrcChannelListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARA { const ChannelName *pItem1 = reinterpret_cast(lParam1); const ChannelName *pItem2 = reinterpret_cast(lParam2); - LPARAM iColumn = lParamSort >= 10 ? lParamSort - 10 : lParamSort; + int iResult = 0; - switch (iColumn) { + switch (LOWORD(lParamSort)) { case 0: iResult = pItem1->m_sName.CompareNoCase(pItem2->m_sName); break; @@ -165,7 +157,7 @@ int CALLBACK CIrcChannelListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARA default: return 0; } - return (lParamSort >= 10) ? -iResult : iResult; + return HIWORD(lParamSort) ? -iResult : iResult; } void CIrcChannelListCtrl::OnNmDblClk(LPNMHDR, LRESULT *pResult) diff --git a/srchybrid/IrcChannelListCtrl.h b/srchybrid/IrcChannelListCtrl.h index ca8baca4..6260942b 100644 --- a/srchybrid/IrcChannelListCtrl.h +++ b/srchybrid/IrcChannelListCtrl.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/IrcChannelTabCtrl.cpp b/srchybrid/IrcChannelTabCtrl.cpp index 3def90dd..70ccd3c6 100644 --- a/srchybrid/IrcChannelTabCtrl.cpp +++ b/srchybrid/IrcChannelTabCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -94,23 +94,18 @@ void CIrcChannelTabCtrl::AutoComplete() m_pCurrentChannel->m_sTyped = sSend; m_pCurrentChannel->m_sTabd.Empty(); //restart autocompletion } - int i = m_pCurrentChannel->m_sTyped.ReverseFind(_T(' ')); //find the last word - CString sName, sPrev; - if (i < 0) { - sName = m_pCurrentChannel->m_sTyped; //all input is one word - sPrev = m_pCurrentChannel->m_sTabd; - sSend.Empty(); - } else { - sName = m_pCurrentChannel->m_sTyped.Mid(++i); //word to complete - sPrev = m_pCurrentChannel->m_sTabd.Mid(i); //the latest auto-completed value - sSend.Truncate(i); //the rest of the string - } + + int i = m_pCurrentChannel->m_sTyped.ReverseFind(_T(' ')) + 1; //find the last word + const CString &sName(m_pCurrentChannel->m_sTyped.Mid(i)); //word to complete + const CString &sPrev(m_pCurrentChannel->m_sTabd.Mid(i)); //the latest auto-completed value + sSend.Truncate(i); //beginning part of the string including space + i = sName.GetLength(); CString sFirst; //to wrap around after the last value CString sNext; //next value for (POSITION pos = m_pCurrentChannel->m_lstNicks.GetHeadPosition(); pos != NULL;) { const Nick *pNick = m_pCurrentChannel->m_lstNicks.GetNext(pos); - if (pNick->m_sNick.Left(i).CompareNoCase(sName) == 0) { + if (_tcsnicmp(pNick->m_sNick, sName, i) == 0) { if (sFirst.IsEmpty() || sFirst.CompareNoCase(pNick->m_sNick) > 0) sFirst = pNick->m_sNick; if (sPrev.CompareNoCase(pNick->m_sNick) < 0 && (sNext.IsEmpty() || sNext.CompareNoCase(pNick->m_sNick) > 0)) @@ -118,10 +113,10 @@ void CIrcChannelTabCtrl::AutoComplete() } } if (!sNext.IsEmpty()) - m_pCurrentChannel->m_sTabd = sSend + sNext; + m_pCurrentChannel->m_sTabd.Format(_T("%s%s"), (LPCTSTR)sSend, (LPCTSTR)sNext); else if (!sFirst.IsEmpty()) - m_pCurrentChannel->m_sTabd = sSend + sFirst; - m_pCurrentChannel->m_sTyped = sSend + sName; + m_pCurrentChannel->m_sTabd.Format(_T("%s%s"), (LPCTSTR)sSend, (LPCTSTR)sFirst); + m_pCurrentChannel->m_sTyped.Format(_T("%s%s"), (LPCTSTR)sSend, (LPCTSTR)sName); if (!m_pCurrentChannel->m_sTyped.IsEmpty() && m_pCurrentChannel->m_sTabd.IsEmpty()) m_pCurrentChannel->m_sTabd = m_pCurrentChannel->m_sTyped; SetInput(m_pCurrentChannel->m_sTabd); @@ -274,7 +269,7 @@ Channel* CIrcChannelTabCtrl::NewChannel(const CString &sChannel, Channel::EType szLine[nLen++] = L'\r'; szLine[nLen++] = L'\n'; //TRACE(_T("%u: %s\n"), i, szLine); - CString strLine(szLine, nLen); + const CString &strLine(szLine, nLen); m_pParent->AddColorLine(strLine, pChannel->m_wndLog); } fclose(fp); @@ -288,7 +283,7 @@ Channel* CIrcChannelTabCtrl::NewChannel(const CString &sChannel, Channel::EType newitem.mask = TCIF_PARAM | TCIF_TEXT | TCIF_IMAGE; newitem.lParam = (LPARAM)pChannel; CString strTcLabel(sChannel); - strTcLabel.Replace(_T("&"), _T("&&")); + DupAmpersand(strTcLabel); newitem.pszText = const_cast((LPCTSTR)strTcLabel); if (eType == Channel::ctStatus) newitem.iImage = 0; @@ -482,7 +477,7 @@ void CIrcChannelTabCtrl::OnTcnSelChange(LPNMHDR, LRESULT *pResult) //Make sure channelList is hidden. m_pParent->m_wndChanList.ShowWindow(SW_HIDE); - //Update nicklist to the new channel. + //Update nick list to the new channel. m_pParent->m_wndNicks.RefreshNickList(m_pCurrentChannel); //Push focus back to the input box. SetInput(m_pCurrentChannel->m_sTabd.IsEmpty() ? m_pCurrentChannel->m_sTyped : m_pCurrentChannel->m_sTabd); @@ -549,8 +544,10 @@ void CIrcChannelTabCtrl::ChatSend(CString sSend) m_pCurrentChannel->m_astrHistory.Add(sSend); m_pCurrentChannel->m_iHistoryPos = (int)m_pCurrentChannel->m_astrHistory.GetCount(); - if (sSend.Left(1) == _T("/")) { - if (sSend.Left(4).CompareNoCase(_T("/hop")) == 0) { + bool bMe; + bool bSound; + if (sSend[0] == _T('/')) { + if (_tcsnicmp(sSend, _T("/hop"), 4) == 0) { if (m_pCurrentChannel->m_eType == Channel::ctNormal) { m_pParent->m_pIrcMain->SendString(_T("PART ") + m_pCurrentChannel->m_sName); m_pParent->m_pIrcMain->SendString(_T("JOIN ") + m_pCurrentChannel->m_sName); @@ -558,42 +555,46 @@ void CIrcChannelTabCtrl::ChatSend(CString sSend) return; } - if (sSend.Left(3).CompareNoCase(_T("/me")) != 0 && sSend.Left(6).CompareNoCase(_T("/sound")) != 0) { - if (sSend.Left(4).CompareNoCase(_T("/msg")) == 0) { + bMe = (_tcsnicmp(sSend, _T("/me"), 3) == 0); + bSound = (_tcsnicmp(sSend, _T("/sound"), 6) == 0); + if (!bMe && ! bSound) { + if (_tcsnicmp(sSend, _T("/msg"), 4) == 0) { int i = 5; const CString &cs(sSend.Tokenize(_T(" "), i)); if (m_pCurrentChannel->m_eType < Channel::ctNormal || m_pCurrentChannel->m_bDetached) - m_pParent->AddStatusF(_T(" -> *%s* %s"), (LPCTSTR)cs, (LPCTSTR)sSend.Mid(i)); + m_pParent->AddStatusF(_T(" -> *%s* %s"), (LPCTSTR)cs, CPTR(sSend, i)); else - m_pParent->AddInfoMessageF(m_pCurrentChannel->m_sName, _T(" -> *%s* %s"), (LPCTSTR)cs, (LPCTSTR)sSend.Mid(i)); - sSend = _T("/PRIVMSG") + sSend.Mid(4); - } else if (sSend.Left(7).CompareNoCase(_T("/notice")) == 0) { + m_pParent->AddInfoMessageF(m_pCurrentChannel->m_sName, _T(" -> *%s* %s"), (LPCTSTR)cs, CPTR(sSend, i)); + sSend.Insert(1, _T("priv")); //msg -> privmsg + } else if (_tcsnicmp(sSend, _T("/notice"), 7) == 0) { int i = 8; const CString &cs(sSend.Tokenize(_T(" "), i)); if (m_pCurrentChannel->m_eType < Channel::ctNormal || m_pCurrentChannel->m_bDetached) - m_pParent->AddStatusF(_T(" -> *%s* %s"), (LPCTSTR)cs, (LPCTSTR)sSend.Mid(i)); + m_pParent->AddStatusF(_T(" -> *%s* %s"), (LPCTSTR)cs, CPTR(sSend, i)); else - m_pParent->AddInfoMessageF(m_pCurrentChannel->m_sName, _T(" -> *%s* %s"), (LPCTSTR)cs, (LPCTSTR)sSend.Mid(i)); + m_pParent->AddInfoMessageF(m_pCurrentChannel->m_sName, _T(" -> *%s* %s"), (LPCTSTR)cs, CPTR(sSend, i)); } - if (sSend.Left(17).CompareNoCase(_T("/PRIVMSG nickserv")) == 0) - sSend.Format(_T("/ns%s"), (LPCTSTR)sSend.Mid(17)); - else if (sSend.Left(17).CompareNoCase(_T("/PRIVMSG chanserv")) == 0) - sSend.Format(_T("/cs%s"), (LPCTSTR)sSend.Mid(17)); - else if (sSend.Left(5).CompareNoCase(_T("/part")) == 0) { + if (_tcsnicmp(sSend, _T("/privmsg nickserv"), 17) == 0) + sSend.Format(_T("/ns%s"), CPTR(sSend, 17)); + else if (_tcsnicmp(sSend, _T("/privmsg chanserv"), 17) == 0) + sSend.Format(_T("/cs%s"), CPTR(sSend, 17)); + else if (_tcsnicmp(sSend, _T("/part"), 5) == 0) { if (sSend.TrimRight().GetLength() == 5 && m_pCurrentChannel->m_eType == Channel::ctNormal) sSend.AppendFormat(_T(" %s"), (LPCTSTR)m_pCurrentChannel->m_sName); - } else if (sSend.Left(8).CompareNoCase(_T("/PRIVMSG")) == 0) { + } else if (_tcsnicmp(sSend, _T("/privmsg"), 8) == 0) { int iIndex = sSend.Find(_T(' '), sSend.Find(_T(' ')) + 1); sSend.Insert(iIndex + 1, _T(":")); - } else if (sSend.Left(6).CompareNoCase(_T("/TOPIC")) == 0) { + } else if (_tcsnicmp(sSend, _T("/topic"), 6) == 0) { int iIndex = sSend.Find(_T(' '), sSend.Find(_T(' ')) + 1); sSend.Insert(iIndex + 1, _T(":")); } - m_pParent->m_pIrcMain->SendString(sSend.Mid(1)); + sSend.Delete(0, 1); + m_pParent->m_pIrcMain->SendString(sSend); return; } - } + } else + bMe = bSound = false; if (m_pCurrentChannel->m_eType < Channel::ctNormal || m_pCurrentChannel->m_bDetached) { m_pParent->m_pIrcMain->SendString(sSend); @@ -601,16 +602,16 @@ void CIrcChannelTabCtrl::ChatSend(CString sSend) } CString sBuild; - if (sSend.Left(3).CompareNoCase(_T("/me")) == 0) { - sBuild.Format(_T("PRIVMSG %s :\001ACTION %s\001"), (LPCTSTR)m_pCurrentChannel->m_sName, (LPCTSTR)sSend.Mid(4)); - m_pParent->AddInfoMessageCF(m_pCurrentChannel->m_sName, RGB(156, 0, 156), _T("* %s %s"), (LPCTSTR)m_pParent->m_pIrcMain->GetNick(), (LPCTSTR)sSend.Mid(4)); + if (bMe) { + sBuild.Format(_T("PRIVMSG %s :\001ACTION %s\001"), (LPCTSTR)m_pCurrentChannel->m_sName, CPTR(sSend, 4)); + m_pParent->AddInfoMessageCF(m_pCurrentChannel->m_sName, RGB(156, 0, 156), _T("* %s %s"), (LPCTSTR)m_pParent->m_pIrcMain->GetNick(), CPTR(sSend, 4)); m_pParent->m_pIrcMain->SendString(sBuild); return; } - if (sSend.Left(6).CompareNoCase(_T("/sound")) == 0) { + if (bSound) { CString sound; - sBuild.Format(_T("PRIVMSG %s :\001SOUND %s\001"), (LPCTSTR)m_pCurrentChannel->m_sName, (LPCTSTR)sSend.Mid(7)); + sBuild.Format(_T("PRIVMSG %s :\001SOUND %s\001"), (LPCTSTR)m_pCurrentChannel->m_sName, CPTR(sSend, 7)); m_pParent->m_pIrcMain->SendString(sBuild); sSend.Delete(0, 7); int soundlen = sSend.Find(_T(' ')); @@ -644,7 +645,7 @@ void CIrcChannelTabCtrl::Localize() pChannel->m_sTitle = GetResString(pChannel->m_eType == Channel::ctStatus ? IDS_STATUS : IDS_IRC_CHANNELLIST); item.mask = TCIF_TEXT; CString strTcLabel(pChannel->m_sTitle); - strTcLabel.Replace(_T("&"), _T("&&")); + DupAmpersand(strTcLabel); item.pszText = const_cast((LPCTSTR)strTcLabel); SetItem(iIndex, &item); } diff --git a/srchybrid/IrcChannelTabCtrl.h b/srchybrid/IrcChannelTabCtrl.h index cd6888c5..e548b6c3 100644 --- a/srchybrid/IrcChannelTabCtrl.h +++ b/srchybrid/IrcChannelTabCtrl.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/IrcMain.cpp b/srchybrid/IrcMain.cpp index 8dbe7623..cba15da9 100644 --- a/srchybrid/IrcMain.cpp +++ b/srchybrid/IrcMain.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -33,7 +33,6 @@ #include #include "IrcMain.h" #include "emule.h" -#include "otherfunctions.h" #include "ED2KLink.h" #include "DownloadQueue.h" #include "server.h" @@ -61,7 +60,6 @@ CIrcMain::CIrcMain() { m_pIRCSocket = NULL; m_pwndIRC = NULL; - srand((unsigned)time(NULL)); SetVerify(); m_dwLastRequest = 0; } @@ -88,7 +86,7 @@ void CIrcMain::PreParseMessage(const char *pszBufferA) } } CATCH_DFLT_EXCEPTIONS(_T(__FUNCTION__)) - CATCH_DFLT_ALL(_T(__FUNCTION__)) + CATCH_DFLT_ALL(_T(__FUNCTION__)) } void CIrcMain::ProcessLink(const CString &sED2KLink) @@ -96,19 +94,19 @@ void CIrcMain::ProcessLink(const CString &sED2KLink) try { const CString &sLink(OptUtf8ToStr(URLDecode(sED2KLink))); CED2KLink *pLink = CED2KLink::CreateLinkFromUrl(sLink); - _ASSERT(pLink != 0); + ASSERT(pLink); switch (pLink->GetKind()) { case CED2KLink::kFile: { CED2KFileLink *pFileLink = pLink->GetFileLink(); - _ASSERT(pFileLink != 0); - theApp.downloadqueue->AddFileLinkToDownload(pFileLink); + ASSERT(pFileLink); + theApp.downloadqueue->AddFileLinkToDownload(*pFileLink); } break; case CED2KLink::kServerList: { CED2KServerListLink *pListLink = pLink->GetServerListLink(); - _ASSERT(pListLink != 0); + ASSERT(pListLink); const CString &sAddress(pListLink->GetAddress()); if (!sAddress.IsEmpty()) theApp.emuledlg->serverwnd->UpdateServerMetFromURL(sAddress); @@ -116,11 +114,11 @@ void CIrcMain::ProcessLink(const CString &sED2KLink) break; case CED2KLink::kServer: { - CString sDefName; CED2KServerLink *pSrvLink = pLink->GetServerLink(); - _ASSERT(pSrvLink != 0); + ASSERT(pSrvLink); CServer *pSrv = new CServer(pSrvLink->GetPort(), pSrvLink->GetAddress()); - _ASSERT(pSrv != 0); + ASSERT(pSrv); + CString sDefName; pSrvLink->GetDefaultName(sDefName); pSrv->SetListName(sDefName); @@ -188,31 +186,31 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) } if (sCommand.IsEmpty()) - throw CString(_T("SMIRC Error: Received a message with no command.")); + throwCStr(_T("SMIRC Error: Received a message with no command.")); if (sRawMessage.IsEmpty()) - throw CString(_T("SMIRC Error: Received a message with no target or empty.")); + throwCStr(_T("SMIRC Error: Received a message with no target or empty.")); if (sCommand == _T("PRIVMSG")) { - CString sTarget = sRawMessage.Tokenize(_T(" "), iIndex); + CString sTarget(sRawMessage.Tokenize(_T(" "), iIndex)); // Channel and Private message were merged into this one if statement, this check allows that to happen. if (sTarget[0] != _T('#')) sTarget = sNickname; //If this is a special message. Find out what kind. - if (sRawMessage.Mid(iIndex, 2) == _T(":\001")) { + if (_tcsncmp(CPTR(sRawMessage, iIndex), _T(":\001"), 2) == 0) { //Check if this is an ACTION message. - if (sRawMessage.Mid(iIndex, 9) == _T(":\001ACTION ")) { + if (_tcsnicmp(CPTR(sRawMessage, iIndex + 2), _T("ACTION "), 7) == 0) { iIndex += 9; - CString sMessage = sRawMessage.Mid(iIndex); + CString sMessage(sRawMessage.Mid(iIndex)); sMessage.Remove(_T('\001')); //Channel Action. m_pwndIRC->AddInfoMessageCF(sTarget, RGB(156, 0, 156), _T("* %s %s"), (LPCTSTR)sNickname, (LPCTSTR)sMessage); return; } //Check if this is a SOUND message. - if (sRawMessage.Mid(iIndex, 7) == _T(":\001SOUND")) { + if (_tcsnicmp(CPTR(sRawMessage, iIndex + 2), _T("SOUND"), 5) == 0) { if (!thePrefs.GetIRCPlaySoundEvents()) return; iIndex += 7; @@ -228,49 +226,51 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) sMessage.Remove(_T('\001')); if (sMessage.IsEmpty()) sMessage = _T("[SOUND]"); - PlaySound(thePrefs.GetMuleDirectory(EMULE_EXECUTABLEDIR) + _T("Sounds\\IRC\\") + sSound - , NULL - , SND_FILENAME | SND_NODEFAULT | SND_NOSTOP | SND_NOWAIT | SND_ASYNC); + sSound.Insert(0, _T("Sounds\\IRC\\")); + sSound.Insert(0, thePrefs.GetMuleDirectory(EMULE_EXECUTABLEDIR)); + PlaySound(sSound, NULL, SND_FILENAME | SND_NODEFAULT | SND_NOSTOP | SND_NOWAIT | SND_ASYNC); m_pwndIRC->AddInfoMessageF(sTarget, _T("* %s %s"), (LPCTSTR)sNickname, (LPCTSTR)sMessage); } return; } //Check if this was a VERSION message. - if (sRawMessage.Mid(iIndex, 9) == _T(":\001VERSION")) { - if (::GetTickCount() < m_dwLastRequest + SEC2MS(1)) { // excess flood protection - m_dwLastRequest = ::GetTickCount(); + if (_tcsnicmp(CPTR(sRawMessage, iIndex + 2), _T("VERSION"), 7) == 0) { + const DWORD curTick = ::GetTickCount(); + if (curTick < m_dwLastRequest + SEC2MS(1)) { // excess flood protection + m_dwLastRequest = curTick; return; } - m_dwLastRequest = ::GetTickCount(); + m_dwLastRequest = curTick; //Get client version. iIndex += 9; - m_sVersion = _T("eMule") + theApp.m_strCurVersionLong + Irc_Version; - CString sBuild; + CString sBuild; //version should be filled on connect sBuild.Format(_T("NOTICE %s :\001VERSION %s\001"), (LPCTSTR)sNickname, (LPCTSTR)m_sVersion); m_pIRCSocket->SendString(sBuild); return; } - if (sRawMessage.Mid(iIndex, 6) == _T(":\001PING")) { - if (::GetTickCount() < m_dwLastRequest + SEC2MS(1)) { // excess flood protection - m_dwLastRequest = ::GetTickCount(); + if (_tcsnicmp(CPTR(sRawMessage, iIndex + 2), _T("PING"), 4) == 0) { + const DWORD curTick = ::GetTickCount(); + if (curTick < m_dwLastRequest + SEC2MS(1)) { // excess flood protection + m_dwLastRequest = curTick; return; } - m_dwLastRequest = ::GetTickCount(); + m_dwLastRequest = curTick; iIndex += 6; - CString sVerify = sRawMessage.Tokenize(_T(" "), iIndex); + CString sVerify(sRawMessage.Tokenize(_T(" "), iIndex)); sVerify.Remove(_T('\001')); CString sBuild; sBuild.Format(_T("NOTICE %s :\001PING %s\001"), (LPCTSTR)sNickname, (LPCTSTR)sVerify); m_pIRCSocket->SendString(sBuild); return; } - if (sRawMessage.Mid(iIndex, 11) == _T(":\001RQSFRIEND")) { - if (::GetTickCount() < m_dwLastRequest + SEC2MS(1)) { // excess flood protection - m_dwLastRequest = ::GetTickCount(); + if (_tcsnicmp(CPTR(sRawMessage, iIndex + 2), _T("RQSFRIEND"), 9) == 0) { + const DWORD curTick = ::GetTickCount(); + if (curTick < m_dwLastRequest + SEC2MS(1)) { // excess flood protection + m_dwLastRequest = curTick; return; } - m_dwLastRequest = ::GetTickCount(); + m_dwLastRequest = curTick; //eMule user requested to add you as friend. if (!thePrefs.GetIRCAllowEmuleAddFriend()) @@ -297,7 +297,7 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) m_pwndIRC->NoticeMessage(_T("*EmuleProto*"), _T(""), sBuild); return; } - if (sRawMessage.Mid(iIndex, 11) == _T(":\001REPFRIEND")) { + if (_tcsnicmp(CPTR(sRawMessage, iIndex + 2), _T("REPFRIEND"), 9) == 0) { iIndex += 11; (void)sRawMessage.Tokenize(_T("|"), iIndex); //skip sVersion const CString &sVerify(sRawMessage.Tokenize(_T("|"), iIndex)); @@ -314,12 +314,12 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) if (!theApp.friendlist->IsAlreadyFriend(sHash)) { uchar ucharUserID[MDX_DIGEST_SIZE]; if (!strmd4(sHash, ucharUserID)) - throw CString(_T("SMIRC Error: Received invalid friend reply")); + throwCStr(_T("SMIRC Error: Received invalid friend reply")); theApp.friendlist->AddFriend(ucharUserID, 0, uNewClientID, uNewClientPort, 0, sTarget, 1); } return; } - if (sRawMessage.Mid(iIndex, 10) == _T(":\001SENDLINK")) { + if (_tcsnicmp(CPTR(sRawMessage, iIndex + 2), _T("SENDLINK"), 8) == 0) { //Received an ED2K link from someone. iIndex += 10; if (!thePrefs.GetIRCAcceptLinks()) { @@ -333,7 +333,7 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) m_pwndIRC->NoticeMessage(_T("*EmuleProto*"), _T(""), sTarget + _T(" attempted to send you a file. If you wanted to accept the files from this person, add him as a friend or change your IRC Preferences.")); return; } - CString sLink = sRawMessage.Mid(iIndex); + CString sLink(sRawMessage.Mid(iIndex)); sLink.Remove(_T('\001')); if (!sLink.IsEmpty()) { if (!thePrefs.GetIRCIgnoreEmuleSendLinkMsgs()) { @@ -347,7 +347,7 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) } } else { //This is a normal channel message. - if (iIndex < sRawMessage.GetLength() && sRawMessage.Mid(iIndex, 1) == _T(":")) + if (iIndex < sRawMessage.GetLength() && sRawMessage[iIndex] == _T(':')) ++iIndex; m_pwndIRC->AddMessage(sTarget, sNickname, sRawMessage.Mid(iIndex)); } @@ -384,7 +384,7 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) return; } if (!thePrefs.GetIRCIgnorePartMessages()) - m_pwndIRC->AddInfoMessageF(sChannel, GetResString(IDS_IRC_HASPARTED), (LPCTSTR)sNickname, (LPCTSTR)sChannel, (LPCTSTR)sRawMessage.Mid(iIndex)); + m_pwndIRC->AddInfoMessageF(sChannel, GetResString(IDS_IRC_HASPARTED), (LPCTSTR)sNickname, (LPCTSTR)sChannel, CPTR(sRawMessage, iIndex)); //Remove nick from your channel. m_pwndIRC->m_wndNicks.RemoveNick(sChannel, sNickname); return; @@ -392,16 +392,16 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) if (sCommand == _T("TOPIC")) { const CString &sChannel(sRawMessage.Tokenize(_T(" "), iIndex)); - if (sRawMessage.Mid(iIndex, 1) == _T(":")) + if (iIndex >= 0 && sRawMessage[iIndex] == _T(':')) ++iIndex; - const CString &sMessage(sRawMessage.Mid(iIndex)); - m_pwndIRC->AddInfoMessageF(sChannel, _T("* %s changes topic to '%s'"), (LPCTSTR)sNickname, (LPCTSTR)sMessage); - m_pwndIRC->SetTopic(sChannel, sMessage); + + m_pwndIRC->AddInfoMessageF(sChannel, _T("* %s changes topic to '%s'"), (LPCTSTR)sNickname, CPTR(sRawMessage, iIndex)); + m_pwndIRC->SetTopic(sChannel, CPTR(sRawMessage, iIndex)); return; } if (sCommand == _T("QUIT")) { - if (sRawMessage.Mid(iIndex, 1) == _T(":")) + if (iIndex >= 0 && sRawMessage[iIndex] == _T(':')) ++iIndex; const CString &sMessage(sRawMessage.Mid(iIndex)); //This user left the network. Remove from all Channels. @@ -437,9 +437,9 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) if (!thePrefs.GetIRCIgnoreMiscMessages() || sNick == m_sNick) { if (sNick == m_sNick) { //It was you! m_pwndIRC->m_wndChanSel.DetachChannel(sChannel); - m_pwndIRC->AddStatusF(GetResString(IDS_IRC_WASKICKEDBY), (LPCTSTR)sNick, (LPCTSTR)sNickname, (LPCTSTR)sRawMessage.Mid(iIndex)); //is it needed? + m_pwndIRC->AddStatusF(GetResString(IDS_IRC_WASKICKEDBY), (LPCTSTR)sNick, (LPCTSTR)sNickname, CPTR(sRawMessage, iIndex)); //is it needed? } - m_pwndIRC->AddInfoMessageF(sChannel, GetResString(IDS_IRC_WASKICKEDBY), (LPCTSTR)sNick, (LPCTSTR)sNickname, (LPCTSTR)sRawMessage.Mid(iIndex)); + m_pwndIRC->AddInfoMessageF(sChannel, GetResString(IDS_IRC_WASKICKEDBY), (LPCTSTR)sNick, (LPCTSTR)sNickname, CPTR(sRawMessage, iIndex)); } //Remove nick from your channel. if (sNick != m_sNick) @@ -453,7 +453,7 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) const CString &sCommands(sRawMessage.Tokenize(_T(" "), iIndex)); if (sCommand.IsEmpty()) - throw CString(_T("SMIRC Error: Received Invalid Mode change.")); + throwCStr(_T("SMIRC Error: Received Invalid Mode change.")); const CString &sParams(sRawMessage.Mid(iIndex)); if (sNickname.IsEmpty()) @@ -467,7 +467,7 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) } if (sCommand == _T("NOTICE")) { const CString &sTarget(sRawMessage.Tokenize(_T(" "), iIndex)); - if (sRawMessage.Mid(iIndex, 1) == _T(":")) + if (sRawMessage.GetLength() < iIndex && sRawMessage[iIndex] == _T(':')) ++iIndex; if (!sNickname.IsEmpty()) m_pwndIRC->NoticeMessage(sNickname, sTarget, sRawMessage.Mid(iIndex)); @@ -570,7 +570,7 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) //433 ERR_NICKNAMEINUSE //" :Nickname is already in use" case 433: - if (sRawMessage.Mid(iIndex, 1) == _T(":")) + if (sRawMessage.GetLength() < iIndex && sRawMessage[iIndex] == _T(':')) ++iIndex; m_pwndIRC->AddStatus(sRawMessage.Mid(iIndex), true, uCommand); // clear nick and enter the IRC-nick message box on next connect @@ -616,7 +616,7 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) case 301: case 305: case 306: - if (sRawMessage.Mid(iIndex, 1) == _T(":")) + if (sRawMessage.GetLength() < iIndex && sRawMessage[iIndex] == _T(':')) ++iIndex; m_pwndIRC->AddStatus((uCommand == 303 ? _T("ison: ") : _T("")) + sRawMessage.Mid(iIndex)); return; @@ -683,7 +683,7 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) //" :End of WHOWAS" case 314: case 369: - if (sRawMessage.Mid(iIndex, 1) == _T(":")) + if (sRawMessage.GetLength() < iIndex && sRawMessage[iIndex] == _T(':')) ++iIndex; m_pwndIRC->AddCurrent(sRawMessage.Mid(iIndex)); return; @@ -733,7 +733,7 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) //" :" case 325: case 331: - if (sRawMessage.Mid(iIndex, 1) == _T(":")) + if (sRawMessage.GetLength() < iIndex && sRawMessage[iIndex] == _T(':')) ++iIndex; m_pwndIRC->AddStatus(sRawMessage.Mid(iIndex)); return; @@ -750,10 +750,10 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) //Set Channel Topic const CString &sChannel(sRawMessage.Tokenize(_T(" "), iIndex)); if (sChannel[0] == _T('#')) { - if (sRawMessage.Mid(iIndex, 1) == _T(":")) + if (iIndex >= 0 && sRawMessage[iIndex] == _T(':')) ++iIndex; m_pwndIRC->SetTopic(sChannel, sRawMessage.Mid(iIndex)); - m_pwndIRC->AddInfoMessageF(sChannel, _T("* Channel Topic: %s"), (LPCTSTR)sRawMessage.Mid(iIndex)); + m_pwndIRC->AddInfoMessageF(sChannel, _T("* Channel Topic: %s"), CPTR(sRawMessage, iIndex)); } } return; @@ -823,7 +823,7 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) //" :End of WHO list" case 352: case 315: - if (sRawMessage.Mid(iIndex, 1) == _T(":")) + if (sRawMessage.GetLength() < iIndex && sRawMessage[iIndex] == _T(':')) ++iIndex; m_pwndIRC->AddStatus(sRawMessage.Mid(iIndex)); return; @@ -883,8 +883,8 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) //- When listing the active 'bans' for a given channel, //a server is required to send the list back using the //RPL_BANLIST and RPL_ENDOFBANLIST messages. A separate - //RPL_BANLIST is sent for each active banmask. After the - //banmasks have been listed (or if none present) a + //RPL_BANLIST is sent for each active ban mask. After the + //ban masks have been listed (or if none present) a //RPL_ENDOFBANLIST MUST be sent. //367 RPL_BANLIST //" " @@ -1186,7 +1186,7 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) //- Returned to a client which trying to send a //PRIVMSG/NOTICE to too many recipients. //- Returned to a client which is attempting to JOIN a safe - //channel using the shortname when there are more than one + //channel using the short name when there are more than one //such channel. //407 ERR_TOOMANYTARGETS //" : recipients. " @@ -1213,9 +1213,9 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) //412 ERR_NOTEXTTOSEND //":No text to send" //413 ERR_NOTOPLEVEL - //" :No toplevel domain specified" + //" :No top level domain specified" //414 ERR_WILDTOPLEVEL - //" :Wildcard in toplevel domain" + //" :Wild card in toplevel domain" //415 ERR_BADMASK //" :Bad Server/host mask" case 411: @@ -1434,7 +1434,7 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) //- Returned by the server to indicate that a MODE //message was sent with a nickname parameter and that - //the a mode flag sent was not recognized. + //the a mode flag sent was not recognised. //501 ERR_UMODEUNKNOWNFLAG //":Unknown MODE flag" case 501: @@ -1444,14 +1444,14 @@ void CIrcMain::ParseMessage(const CString &sRawMessage) //502 ERR_USERSDONTMATCH //":Cannot change mode for other users" case 502: - if (sRawMessage.Mid(iIndex, 1) == _T(":")) + if (sRawMessage.GetLength() < iIndex && sRawMessage[iIndex] == _T(':')) ++iIndex; m_pwndIRC->AddStatus(sRawMessage.Mid(iIndex), true, uCommand); return; } } } CATCH_MFC_EXCEPTION(_T(__FUNCTION__)) - catch (const CString &e) { + catch (const CString &e) { m_pwndIRC->AddStatus(e); } CATCH_DFLT_ALL(_T(__FUNCTION__)) } @@ -1557,12 +1557,15 @@ void CIrcMain::PerformString(const CString &sPerform) continue; if (sCommand[0] == _T('/')) sCommand.Delete(0, 1); - if (sCommand.Left(3) == _T("msg")) - sCommand = _T("PRIVMSG") + sCommand.Mid(3); - if (sCommand.Left(16).CompareNoCase(_T("PRIVMSG nickserv")) == 0) - sCommand = _T("ns") + sCommand.Mid(16); - else if (sCommand.Left(16).CompareNoCase(_T("PRIVMSG chanserv")) == 0) - sCommand = _T("cs") + sCommand.Mid(16); + if (_tcsnicmp(sCommand, _T("msg"), 3) == 0) + sCommand.Insert(0, _T("priv")); + if (_tcsnicmp(sCommand, _T("privmsg nickserv"), 16) == 0) { + sCommand.Delete(0, 16); + sCommand.Insert(0, _T("ns")); + } else if (_tcsnicmp(sCommand, _T("privmsg chanserv"), 16) == 0) { + sCommand.Delete(0, 16); + sCommand.Insert(0, _T("cs")); + } m_pIRCSocket->SendString(sCommand); } } CATCH_DFLT_EXCEPTIONS(_T(__FUNCTION__)) diff --git a/srchybrid/IrcMain.h b/srchybrid/IrcMain.h index 1345ce0d..7d5b9e0e 100644 --- a/srchybrid/IrcMain.h +++ b/srchybrid/IrcMain.h @@ -44,5 +44,5 @@ class CIrcMain CString m_sNick; CString m_sVersion; uint32 m_uVerify; - uint32 m_dwLastRequest; + DWORD m_dwLastRequest; }; \ No newline at end of file diff --git a/srchybrid/IrcNickListCtrl.cpp b/srchybrid/IrcNickListCtrl.cpp index 32dafe25..84bcc20d 100644 --- a/srchybrid/IrcNickListCtrl.cpp +++ b/srchybrid/IrcNickListCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -51,16 +51,16 @@ void CIrcNickListCtrl::Init() LoadSettings(); SetSortArrow(); - SortItems(&SortProc, GetSortItem() + (GetSortAscending() ? 0 : 10)); + SortItems(SortProc, MAKELONG(GetSortItem(), !GetSortAscending())); } int CALLBACK CIrcNickListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) { - LPARAM iColumn = lParamSort >= 10 ? lParamSort - 10 : lParamSort; - if (iColumn) + if (LOWORD(lParamSort)) return 0; const Nick *pItem1 = reinterpret_cast(lParam1); const Nick *pItem2 = reinterpret_cast(lParam2); + if (pItem1->m_iLevel != pItem2->m_iLevel) { if (pItem1->m_iLevel == -1) return 1; @@ -69,17 +69,16 @@ int CALLBACK CIrcNickListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM l return pItem1->m_iLevel - pItem2->m_iLevel; } int iResult = pItem1->m_sNick.CompareNoCase(pItem2->m_sNick); - return (lParamSort >= 10) ? -iResult : iResult; + return HIWORD(lParamSort) ? -iResult : iResult; } void CIrcNickListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) { const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); + bool bSortAscending = (GetSortItem() != pNMLV->iSubItem) || !GetSortAscending(); - bool bSortAscending = (GetSortItem() != pNMLV->iSubItem) ? true : !GetSortAscending(); SetSortArrow(pNMLV->iSubItem, bSortAscending); - SortItems(&SortProc, pNMLV->iSubItem + (bSortAscending ? 0 : 10)); - + SortItems(&SortProc, MAKELONG(pNMLV->iSubItem, !bSortAscending)); *pResult = 0; } @@ -116,7 +115,7 @@ void CIrcNickListCtrl::OpenPrivateChannel(const Nick *pNick) { if (!pNick) return; - const CString &sNick = pNick->m_sNick; + const CString &sNick(pNick->m_sNick); if (sNick.CompareNoCase(m_pParent->m_pIrcMain->GetNick()) == 0 && !m_pParent->m_wndChanSel.FindChannelByName(sNick)) m_pParent->m_wndChanSel.NewChannel(sNick, Channel::ctPrivate); m_pParent->AddInfoMessage(sNick, GetResString(IDS_IRC_PRIVATECHANSTART), true); @@ -270,7 +269,7 @@ bool CIrcNickListCtrl::ChangeNick(const CString &sChannel, const CString &sOldNi return false; } -bool CIrcNickListCtrl::ChangeNickMode(const CString &sChannel, const CString &sNick, const TCHAR cDir, const TCHAR &cMode) +bool CIrcNickListCtrl::ChangeNickMode(const CString &sChannel, const CString &sNick, const TCHAR cDir, const TCHAR cMode) { if (sChannel[0] != _T('#') || sNick.IsEmpty()) return true; @@ -314,7 +313,9 @@ bool CIrcNickListCtrl::ChangeAllNick(const CString &sOldNick, const CString &sNe { bool bChanged = false; //Change the nick in ALL channels. - Channel *pChannel = m_pParent->m_wndChanSel.FindChannelByName(sOldNick); + CIrcChannelTabCtrl& ChanSel = m_pParent->m_wndChanSel; + Channel *pChannel = ChanSel.FindChannelByName(sOldNick); + if (pChannel) { //We had a private room opened with this nick. Update the title of the channel! pChannel->m_sName = sNewNick; @@ -322,23 +323,21 @@ bool CIrcNickListCtrl::ChangeAllNick(const CString &sOldNick, const CString &sNe TCITEM item; item.mask = TCIF_PARAM; item.lParam = -1; - for (int iItem = 0; iItem < m_pParent->m_wndChanSel.GetItemCount(); ++iItem) { - m_pParent->m_wndChanSel.GetItem(iItem, &item); - if (reinterpret_cast(item.lParam) == pChannel) { + for (int iItem = ChanSel.GetItemCount(); --iItem >= 0;) + if (ChanSel.GetItem(iItem, &item) && reinterpret_cast(item.lParam) == pChannel) { item.mask = TCIF_TEXT; CString strTcLabel(sNewNick); - strTcLabel.Replace(_T("&"), _T("&&")); + DupAmpersand(strTcLabel); item.pszText = const_cast((LPCTSTR)strTcLabel); - m_pParent->m_wndChanSel.SetItem(iItem, &item); + ChanSel.SetItem(iItem, &item); bChanged = true; break; } - } } // Go through all other channel nicklists. - for (POSITION pos = m_pParent->m_wndChanSel.m_lstChannels.GetHeadPosition(); pos != NULL;) { - pChannel = m_pParent->m_wndChanSel.m_lstChannels.GetNext(pos); + for (POSITION pos = ChanSel.m_lstChannels.GetHeadPosition(); pos != NULL;) { + pChannel = ChanSel.m_lstChannels.GetNext(pos); if (ChangeNick(pChannel->m_sName, sOldNick, sNewNick)) { if (!thePrefs.GetIRCIgnoreMiscMessages()) m_pParent->AddInfoMessageF(pChannel->m_sName, GetResString(IDS_IRC_NOWKNOWNAS), (LPCTSTR)sOldNick, (LPCTSTR)sNewNick); @@ -362,7 +361,7 @@ void CIrcNickListCtrl::UpdateNickCount() void CIrcNickListCtrl::Localize() { - CString strRes(GetResString(IDS_STATUS)); + const CString &strRes(GetResString(IDS_STATUS)); HDITEM hdi; hdi.pszText = const_cast((LPCTSTR)strRes); hdi.mask = HDI_TEXT; @@ -394,7 +393,7 @@ BOOL CIrcNickListCtrl::OnCommand(WPARAM wParam, LPARAM) case Irc_Ban: if (pNick && pChannel) { CString sSend; -// sSend.Format(_T("cs ban %s %s"), (LPCTSTR)pChannel->m_sName, (LPCTSTR)pNick->m_sNick); + //sSend.Format(_T("cs ban %s %s"), (LPCTSTR)pChannel->m_sName, (LPCTSTR)pNick->m_sNick); sSend.Format(_T("MODE %s +b %s"), (LPCTSTR)pChannel->m_sName, (LPCTSTR)pNick->m_sNick); m_pParent->m_pIrcMain->SendString(sSend); } diff --git a/srchybrid/IrcNickListCtrl.h b/srchybrid/IrcNickListCtrl.h index 8e80da2b..ec2f688f 100644 --- a/srchybrid/IrcNickListCtrl.h +++ b/srchybrid/IrcNickListCtrl.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -45,7 +45,7 @@ class CIrcNickListCtrl : public CMuleListCtrl void DeleteAllNick(Channel *pChannel); void DeleteNickInAll(const CString &sNick, const CString &sMessage); bool ChangeNick(const CString &sChannel, const CString &sOldNick, const CString &sNewNick); - bool ChangeNickMode(const CString &sChannel, const CString &sNick, const TCHAR cDir, const TCHAR &cMode); + bool ChangeNickMode(const CString &sChannel, const CString &sNick, const TCHAR cDir, const TCHAR cMode); bool ChangeAllNick(const CString &sOldNick, const CString &sNewNick); void OpenPrivateChannel(const Nick *pNick); void UpdateNickCount(); diff --git a/srchybrid/IrcSocket.cpp b/srchybrid/IrcSocket.cpp index ff0a8f20..535f31bd 100644 --- a/srchybrid/IrcSocket.cpp +++ b/srchybrid/IrcSocket.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -73,10 +73,10 @@ BOOL CIrcSocket::Create(UINT uSocketPort, int iSocketType, long lEvent, const CS void CIrcSocket::Connect() { int iPort; - CString strServer = thePrefs.GetIRCServer(); + CString strServer(thePrefs.GetIRCServer()); int iIndex = strServer.Find(_T(':')); if (iIndex >= 0) { - iPort = _tstoi(strServer.Mid(iIndex + 1)); + iPort = _tstoi(CPTR(strServer, iIndex + 1)); if (iPort <= 0 || iPort > 65535) iPort = 6667; strServer.Truncate(iIndex); @@ -154,7 +154,7 @@ int CIrcSocket::SendString(const CString &sMessage) theStats.AddUpDataOverheadOther(iSize); return Send(sMessageA + "\r\n", iSize); //int iResult = Send(sMessageA + "\r\n", iSize); - //ASSERT( iResult == iSize ); //too much noise from minor network errors + //ASSERT(iResult == iSize); //too much noise from minor network errors //return iResult; } @@ -165,9 +165,9 @@ void CIrcSocket::RemoveAllLayers() m_pProxyLayer = NULL; } -int CIrcSocket::OnLayerCallback(std::list &callbacks) +int CIrcSocket::OnLayerCallback(std::vector &callbacks) { - for (std::list::const_iterator iter = callbacks.begin(); iter != callbacks.end(); ++iter) { + for (std::vector::const_iterator iter = callbacks.begin(); iter != callbacks.end(); ++iter) { if (iter->nType == LAYERCALLBACK_LAYERSPECIFIC) { ASSERT(iter->pLayer); if (iter->pLayer == m_pProxyLayer) { diff --git a/srchybrid/IrcSocket.h b/srchybrid/IrcSocket.h index 0d3190cb..9ab351ba 100644 --- a/srchybrid/IrcSocket.h +++ b/srchybrid/IrcSocket.h @@ -41,5 +41,5 @@ class CIrcSocket : public CAsyncSocketEx CAsyncProxySocketLayer *m_pProxyLayer; CIrcMain *m_pIrcMain; - virtual int OnLayerCallback(std::list &callbacks); + virtual int OnLayerCallback(std::vector &callbacks); }; diff --git a/srchybrid/IrcWnd.cpp b/srchybrid/IrcWnd.cpp index f791fedb..86e534c7 100644 --- a/srchybrid/IrcWnd.cpp +++ b/srchybrid/IrcWnd.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -182,7 +182,7 @@ BOOL CIrcWnd::OnInitDialog() m_wndFormat.SetExtendedStyle(m_wndFormat.GetExtendedStyle() | TBSTYLE_EX_MIXEDBUTTONS); TBBUTTON atb[6] = {}; - atb[0].iBitmap = 0; + //atb[0].iBitmap = 0; atb[0].idCommand = IDC_SMILEY; atb[0].fsState = TBSTATE_ENABLED; atb[0].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; @@ -244,7 +244,7 @@ BOOL CIrcWnd::OnInitDialog() GetDlgItem(IDC_CLOSECHAT)->EnableWindow(false); OnChatTextChange(); - return true; + return TRUE; } void CIrcWnd::DoResize(int iDelta) @@ -531,7 +531,7 @@ void CIrcWnd::OnBnClickedCloseChannel(int iItem) bool CIrcWnd::UpdateModes(const CString &sAllModes, CString &sModes, TCHAR cDir, TCHAR cCommand) { if (sAllModes.Find(cCommand) < 0) - return false; //mode not in the list + return false; //not in the mode list //Remove the setting. This takes care of "-" and makes sure we don't add the same symbol twice. sModes.Remove(cCommand); @@ -598,7 +598,7 @@ void CIrcWnd::AddStatusF(LPCTSTR sLine, ...) void CIrcWnd::AddInfoMessage(Channel *pChannel, const CString &sLine) { - CString cs = make_time_stamp() + sLine; + const CString &cs(make_time_stamp() + sLine); if (sLine[0] == _T('*')) AddColorLine(cs, pChannel->m_wndLog, STATUS_MSG_COLOR); else if (sLine[0] == _T('-') && sLine.Find(_T('-'), 1) >= 0) @@ -619,23 +619,23 @@ void CIrcWnd::AddInfoMessage(const CString &sChannel, const CString &sLine, cons } } -void CIrcWnd::AddInfoMessageC(Channel *pChannel, const COLORREF &msgcolour, LPCTSTR sLine) +void CIrcWnd::AddInfoMessageC(Channel *pChannel, const COLORREF msgcolour, LPCTSTR sLine) { if (pChannel) { - CString cs; - cs.Format(_T("%s%s\r\n"), (LPCTSTR)make_time_stamp(), (LPCTSTR)sLine); + CString cs(make_time_stamp()); + cs.AppendFormat(_T("%s\r\n"), (LPCTSTR)sLine); AddColorLine(cs, pChannel->m_wndLog, msgcolour); if (pChannel != m_wndChanSel.m_pCurrentChannel) m_wndChanSel.SetActivity(pChannel, true); } } -void CIrcWnd::AddInfoMessageC(const CString &sChannel, const COLORREF &msgcolour, LPCTSTR sLine) +void CIrcWnd::AddInfoMessageC(const CString &sChannel, const COLORREF msgcolour, LPCTSTR sLine) { AddInfoMessageC(m_wndChanSel.FindOrCreateChannel(sChannel), msgcolour, sLine); } -void CIrcWnd::AddInfoMessageCF(const CString &sChannel, const COLORREF &msgcolour, LPCTSTR sLine, ...) +void CIrcWnd::AddInfoMessageCF(const CString &sChannel, const COLORREF msgcolour, LPCTSTR sLine, ...) { if (!sChannel.IsEmpty()) { va_list argptr; @@ -738,7 +738,7 @@ void CIrcWnd::AddColorLine(const CString &line, CHTRichEditCtrl &wnd, COLORREF c // find any hyperlinks and send them to AppendColoredText if (index == linkfoundat) { //only run the link finding code once in a line with no links - for (unsigned iScheme = 0; iScheme < _countof(s_apszSchemes);) { + for (unsigned iScheme = 0; s_apszSchemes[iScheme].pszScheme;) { const CString &strLeft = line.Right(line.GetLength() - index); //make a string of what we have left int foundat = strLeft.Find(s_apszSchemes[iScheme].pszScheme); //get position of link; -1 if not found if (foundat == 0) { //link starts at this character @@ -747,10 +747,10 @@ void CIrcWnd::AddColorLine(const CString &line, CHTRichEditCtrl &wnd, COLORREF c text.Empty(); } - // search next space or EOL or control code + // search for next white space or EOL or control code int iLen = strLeft.FindOneOf(_T(" \t\r\n\x02\x03\x0F\x11\x16\x1d\x1F")); if (iLen == -1) { - // truncate some special chars from end of URL (and only from end) + // truncate some special chars from the end of URL iLen = strLeft.GetLength(); while (iLen > 0 && !IsValidURLTerminationChar(strLeft[iLen - 1])) --iLen; @@ -762,7 +762,7 @@ void CIrcWnd::AddColorLine(const CString &line, CHTRichEditCtrl &wnd, COLORREF c aChar = line[index]; // get a new char break; } - // truncate some special chars from end of URL (and only from end) + // truncate some special chars from the end of URL while (iLen > 0 && !IsValidURLTerminationChar(strLeft[iLen - 1])) --iLen; wnd.AddLine(strLeft.Left(iLen), iLen, true); @@ -771,12 +771,13 @@ void CIrcWnd::AddColorLine(const CString &line, CHTRichEditCtrl &wnd, COLORREF c return; iScheme = 0; // search from the new position - foundat = -1; // do not record this processed location as a future target location + //foundat = -1; // do not record this processed location as a future target location linkfoundat = index; // reset previous finds as iScheme=0 we re-search aChar = line[index]; // get a new char } else { - ++iScheme; //only increment if not found at this position so if we find http at this position we check for further http occurrences + ++iScheme; //only increment if not found at this position + //so if we find http at this position we check for further http occurrences //foundat is a valid position && (no valid position recorded || a farther position previously recorded) if (foundat > 0 && (linkfoundat == index || (index + foundat) < linkfoundat)) linkfoundat = index + foundat; //set the next closest link to process @@ -848,7 +849,7 @@ void CIrcWnd::AddColorLine(const CString &line, CHTRichEditCtrl &wnd, COLORREF c cr = foregroundColour; bgcr = backgroundColour; break; - case 0x16: // Reverse (as per Mirc) toggle + case 0x16: // Reverse (as per mIRC) toggle // NOTE:This does not reset the bold/underline (dwMask) attributes, but does reset colours 'As per mIRC 6.16!!' if (!text.IsEmpty()) { wnd.AppendColoredText(text, cr, bgcr, dwMask); @@ -931,8 +932,8 @@ void CIrcWnd::NoticeMessage(const CString &sSource, const CString &sTarget, cons } } if (!bFlag) { - CString cs; - cs.Format(_T("%s-%s- %s\r\n"), (LPCTSTR)make_time_stamp(), (LPCTSTR)sSource, (LPCTSTR)sMessage); + CString cs(make_time_stamp()); + cs.AppendFormat(_T("-%s- %s\r\n"), (LPCTSTR)sSource, (LPCTSTR)sMessage); Channel *pStatusChannel = m_wndChanSel.m_lstChannels.GetHead(); if (pStatusChannel) AddColorLine(cs, pStatusChannel->m_wndLog, INFO_MSG_COLOR); @@ -942,14 +943,12 @@ void CIrcWnd::NoticeMessage(const CString &sSource, const CString &sTarget, cons CString CIrcWnd::StripMessageOfColorCodes(const CString &sTemp) { - if (!sTemp.IsEmpty()) { - int iTest = sTemp.Find(_T('\003')); - if (iTest >= 0) { - int iTestLength = sTemp.GetLength() - iTest; - if (iTestLength < 2) - return sTemp; - CString sTemp1 = sTemp.Left(iTest); - CString sTemp2 = sTemp.Mid(iTest + 2); + int iTest = sTemp.Find(_T('\003')); + if (iTest >= 0) { + int iTestLength = sTemp.GetLength() - iTest; + if (iTestLength >= 2) { + CString sTemp1(sTemp, iTest); + CString sTemp2(sTemp.Mid(iTest + 2)); if (iTestLength < 4) return sTemp1 + sTemp2; if (sTemp2[0] == _T(',') && sTemp2.GetLength() > 2) { @@ -1120,31 +1119,6 @@ LRESULT CIrcWnd::OnQueryTab(WPARAM wParam, LPARAM) return !pPartChannel || pPartChannel->m_eType < Channel::ctChannelList; } -bool CIrcWnd::GetLoggedIn() const -{ - return m_bLoggedIn; -} - -void CIrcWnd::SetLoggedIn(bool bFlag) -{ - m_bLoggedIn = bFlag; -} - -void CIrcWnd::SetSendFileString(const CString &sInFile) -{ - m_sSendString = sInFile; -} - -const CString& CIrcWnd::GetSendFileString() const -{ - return m_sSendString; -} - -bool CIrcWnd::IsConnected() const -{ - return m_bConnected; -} - void CIrcWnd::OnBnClickedColour() { int iColor = 0; diff --git a/srchybrid/IrcWnd.h b/srchybrid/IrcWnd.h index 0784567c..fb0bb150 100644 --- a/srchybrid/IrcWnd.h +++ b/srchybrid/IrcWnd.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -42,11 +42,11 @@ class CIrcWnd : public CResizableDialog virtual ~CIrcWnd(); void Localize(); - bool GetLoggedIn() const; - void SetLoggedIn(bool bFlag); - void SetSendFileString(const CString &sInFile); - const CString& GetSendFileString() const; - bool IsConnected() const; + bool GetLoggedIn() const { return m_bLoggedIn; }; + void SetLoggedIn(bool bFlag) { m_bLoggedIn = bFlag; }; + void SetSendFileString(const CString &sInFile) { m_sSendString = sInFile; }; + const CString& GetSendFileString() const { return m_sSendString; }; + bool IsConnected() const { return m_bConnected; }; void UpdateFonts(CFont *pFont); void ParseChangeMode(const CString &sChannel, const CString &sChanger, CString sCommands, const CString &sParams); void AddCurrent(const CString &sLine, bool bShowActivity = true, UINT uStatusCode = 0); @@ -54,9 +54,9 @@ class CIrcWnd : public CResizableDialog void AddStatusF(LPCTSTR sLine, ...); //to pass sLine by reference would be an 'undefined behaviour' void AddInfoMessage(Channel *pChannel, const CString &sLine); void AddInfoMessage(const CString &sChannel, const CString &sLine, const bool bShowChannel = false); - void AddInfoMessageC(Channel *pChannel, const COLORREF &msgcolour, LPCTSTR sLine); - void AddInfoMessageC(const CString &sChannel, const COLORREF &msgcolour, LPCTSTR sLine); - void AddInfoMessageCF(const CString &sChannel, const COLORREF &msgcolour, LPCTSTR sLine, ...); + void AddInfoMessageC(Channel *pChannel, const COLORREF msgcolour, LPCTSTR sLine); + void AddInfoMessageC(const CString &sChannel, const COLORREF msgcolour, LPCTSTR sLine); + void AddInfoMessageCF(const CString &sChannel, const COLORREF msgcolour, LPCTSTR sLine, ...); void AddInfoMessageF(const CString &sChannel, LPCTSTR sLine, ...); void AddMessage(const CString &sChannel, const CString &sTargetName, const CString &sLine); void AddMessageF(const CString &sChannel, const CString &sTargetName, LPCTSTR sLine, ...); diff --git a/srchybrid/KadContactHistogramCtrl.cpp b/srchybrid/KadContactHistogramCtrl.cpp index 5cc004df..c87dc4e5 100644 --- a/srchybrid/KadContactHistogramCtrl.cpp +++ b/srchybrid/KadContactHistogramCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -71,9 +71,9 @@ inline UINT GetHistSlot(const Kademlia::CUInt128 &KadUint128) bool CKadContactHistogramCtrl::ContactAdd(const Kademlia::CContact *contact) { Kademlia::CUInt128 distance; - contact->GetClientID(&distance); + contact->GetClientID(distance); UINT uHistSlot = GetHistSlot(distance); - m_aHist[uHistSlot]++; + ++m_aHist[uHistSlot]; Invalidate(); return true; } @@ -81,11 +81,11 @@ bool CKadContactHistogramCtrl::ContactAdd(const Kademlia::CContact *contact) void CKadContactHistogramCtrl::ContactRem(const Kademlia::CContact *contact) { Kademlia::CUInt128 distance; - contact->GetClientID(&distance); + contact->GetClientID(distance); UINT uHistSlot = GetHistSlot(distance); ASSERT(m_aHist[uHistSlot] > 0); if (m_aHist[uHistSlot] > 0) { - m_aHist[uHistSlot]--; + --m_aHist[uHistSlot]; Invalidate(); } } @@ -145,7 +145,7 @@ void CKadContactHistogramCtrl::OnPaint() uMax = m_aHist[i]; //Lets take the average. This will keep the cluster of closest contacts from - //streching the graph too far. + //stretching the graph too far. uMax /= _countof(m_aHist); if (uMax < 15) uMax = 15/*uHistHeight*/; diff --git a/srchybrid/KadContactHistogramCtrl.h b/srchybrid/KadContactHistogramCtrl.h index 63c59e63..b961a8ce 100644 --- a/srchybrid/KadContactHistogramCtrl.h +++ b/srchybrid/KadContactHistogramCtrl.h @@ -7,7 +7,6 @@ class CKadContactHistogramCtrl : public CWnd { public: CKadContactHistogramCtrl(); - virtual ~CKadContactHistogramCtrl() = default; void Localize(); diff --git a/srchybrid/KadContactListCtrl.cpp b/srchybrid/KadContactListCtrl.cpp index 32e68157..a46ff627 100644 --- a/srchybrid/KadContactListCtrl.cpp +++ b/srchybrid/KadContactListCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -50,9 +50,9 @@ void CKadContactListCtrl::Init() SetPrefsKey(_T("ONContactListCtrl")); SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP); - InsertColumn(colID, GetResString(IDS_ID), LVCFMT_LEFT, 16 + DFLT_HASH_COL_WIDTH); - InsertColumn(colType, GetResString(IDS_TYPE), LVCFMT_LEFT, 50); - InsertColumn(colDistance, GetResString(IDS_KADDISTANCE),LVCFMT_LEFT, 600); + InsertColumn(colID, _T(""), LVCFMT_LEFT, 16 + DFLT_HASH_COL_WIDTH); //IDS_ID + InsertColumn(colType, _T(""), LVCFMT_LEFT, 50); //IDS_TYPE + InsertColumn(colDistance, _T(""), LVCFMT_LEFT, 600); //IDS_KADDISTANCE SetAllIcons(); Localize(); @@ -62,7 +62,7 @@ void CKadContactListCtrl::Init() bool bSortAscending = GetSortAscending(); SetSortArrow(iSortItem, bSortAscending); - SortItems(SortProc, MAKELONG(iSortItem, (bSortAscending ? 0 : 0x0001))); + SortItems(SortProc, MAKELONG(iSortItem, !bSortAscending)); } void CKadContactListCtrl::SaveAllSettings() @@ -94,44 +94,24 @@ void CKadContactListCtrl::SetAllIcons() void CKadContactListCtrl::Localize() { - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); - HDITEM hdi; - hdi.mask = HDI_TEXT; - CString strRes; + static const UINT uids[3] = + { + IDS_ID, IDS_TYPE, IDS_KADDISTANCE + }; - for (int icol = pHeaderCtrl->GetItemCount(); --icol >= 0;) { - UINT uid; - switch (icol) { - case colID: - uid = IDS_ID; - break; - case colType: - uid = IDS_TYPE; - break; - case colDistance: - uid = IDS_KADDISTANCE; - break; - default: - uid = 0; - strRes.Empty(); - } - if (uid) - strRes = GetResString(uid); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(icol, &hdi); - } + LocaliseHeaderCtrl(uids, _countof(uids)); } void CKadContactListCtrl::UpdateContact(int iItem, const Kademlia::CContact *contact) { CString id; - contact->GetClientID(&id); + contact->GetClientID(id); SetItemText(iItem, colID, id); id.Format(_T("%i(%u)"), contact->GetType(), contact->GetVersion()); SetItemText(iItem, colType, id); - contact->GetDistance(&id); + contact->GetDistance(id); SetItemText(iItem, colDistance, id); UINT nImageShown; @@ -154,7 +134,7 @@ bool CKadContactListCtrl::ContactAdd(const Kademlia::CContact *contact) { try { ASSERT(contact != NULL); - int iItem = InsertItem(LVIF_TEXT | LVIF_PARAM, GetItemCount(), NULL, 0, 0, 0, (LPARAM)contact); + int iItem = InsertItem(LVIF_TEXT | LVIF_PARAM, GetItemCount(), _T(""), 0, 0, 0, (LPARAM)contact); if (iItem >= 0) { UpdateContact(iItem, contact); UpdateKadContactCount(); @@ -206,21 +186,17 @@ BOOL CKadContactListCtrl::OnCommand(WPARAM, LPARAM) void CKadContactListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) { - NMLISTVIEW *pNMListView = reinterpret_cast(pNMHDR); - + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); // Determine ascending based on whether already sorted on this column - int iSortItem = GetSortItem(); - bool bOldSortAscending = GetSortAscending(); - bool bSortAscending = (iSortItem != pNMListView->iSubItem) ? true : !bOldSortAscending; + bool bSortAscending = (GetSortItem() != pNMLV->iSubItem || !GetSortAscending()); // Item is column clicked - iSortItem = pNMListView->iSubItem; + int iSortItem = pNMLV->iSubItem; // Sort table - UpdateSortHistory(MAKELONG(iSortItem, (bSortAscending ? 0 : 0x0001))); + UpdateSortHistory(MAKELONG(iSortItem, !bSortAscending)); SetSortArrow(iSortItem, bSortAscending); - SortItems(SortProc, MAKELONG(iSortItem, (bSortAscending ? 0 : 0x0001))); - + SortItems(SortProc, MAKELONG(iSortItem, !bSortAscending)); *pResult = 0; } @@ -237,8 +213,8 @@ int CALLBACK CKadContactListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARA { Kademlia::CUInt128 i1; Kademlia::CUInt128 i2; - item1->GetClientID(&i1); - item2->GetClientID(&i2); + item1->GetClientID(i1); + item2->GetClientID(i2); iResult = i1.CompareTo(i2); } break; @@ -250,8 +226,8 @@ int CALLBACK CKadContactListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARA case colDistance: { Kademlia::CUInt128 distance1, distance2; - item1->GetDistance(&distance1); - item2->GetDistance(&distance2); + item1->GetDistance(distance1); + item2->GetDistance(distance2); iResult = distance1.CompareTo(distance2); } break; diff --git a/srchybrid/KadContactListCtrl.h b/srchybrid/KadContactListCtrl.h index 4c62f45f..0596e58e 100644 --- a/srchybrid/KadContactListCtrl.h +++ b/srchybrid/KadContactListCtrl.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -27,7 +27,6 @@ class CKadContactListCtrl : public CMuleListCtrl public: CKadContactListCtrl(); - virtual ~CKadContactListCtrl() = default; private: enum ECols diff --git a/srchybrid/KadLookupGraph.cpp b/srchybrid/KadLookupGraph.cpp index 143d4ad3..5a10e0a3 100644 --- a/srchybrid/KadLookupGraph.cpp +++ b/srchybrid/KadLookupGraph.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2010-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -22,7 +22,6 @@ #include "opcodes.h" #include "kademlia/utils/LookupHistory.h" #include "kademlia/kademlia/Search.h" -//#include "log.h" #include #include "MemDC.h" #include "ToolTipCtrlX.h" @@ -96,9 +95,9 @@ void CKadLookupGraph::Init() m_iml.SetOverlayImage(m_iml.Add(CTempIconLoader(_T("NoAccessFolderOvl"))), 2); m_pToolTip = new CToolTipCtrlX(); m_pToolTip->Create(this); - m_pToolTip->SetDelayTime(TTDT_AUTOPOP, 5000); - m_pToolTip->SetDelayTime(TTDT_INITIAL, 3000); - m_pToolTip->SetDelayTime(TTDT_RESHOW, 2000); + m_pToolTip->SetDelayTime(TTDT_AUTOPOP, SEC2MS(5)); + m_pToolTip->SetDelayTime(TTDT_INITIAL, SEC2MS(3)); + m_pToolTip->SetDelayTime(TTDT_RESHOW, SEC2MS(2)); EnableToolTips(); m_pToolTip->AddTool(this); m_pToolTip->Activate(FALSE); @@ -223,7 +222,7 @@ void CKadLookupGraph::OnPaint() // Set the scaling. 3 times the highest distance of the 1/3 closest nodes is the max distance CArray aClosest; - INT_PTR k = (INT_PTR)(iVisibleNodes / 3u); + INT_PTR k = (INT_PTR)(iVisibleNodes / 3); if (!k) k = 1; for (uint32 i = 1; i <= iVisibleNodes; ++i) { @@ -312,7 +311,7 @@ void CKadLookupGraph::OnPaint() m_pToolTip->Activate(static_cast(m_iHotItemIdx >= 0)); UpdateToolTip(); - CArray abHotItemConnected; + CArray abHotItemConnected; if (m_iHotItemIdx >= 0) { abHotItemConnected.SetSize(iVisibleNodes); for (INT_PTR i = (INT_PTR)iVisibleNodes; --i >= 0;) @@ -320,10 +319,10 @@ void CKadLookupGraph::OnPaint() } // start drawing, beginning with the arrowClines connecting the nodes // if possible use GDI+ for Anti Aliasing - extern bool g_bGdiPlusInstalled; + // NOTE: Do *NOT* forget to specify /DELAYLOAD:gdiplus.dll as link parameter. ULONG_PTR gdiplusToken = 0; Gdiplus::GdiplusStartupInput gdiplusStartupInput; - if (g_bGdiPlusInstalled && Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) == Gdiplus::Ok) { + if (Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) == Gdiplus::Ok) { { Gdiplus::Graphics gdipGraphic(dc); gdipGraphic.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); @@ -335,10 +334,10 @@ void CKadLookupGraph::OnPaint() Gdiplus::Pen gdipPenRed(Gdiplus::Color(255, 32, 32), 0.8f); gdipPenRed.SetCustomEndCap(&gdipArrow); - for (int i = 0; i < (int)iVisibleNodes; ++i) { + for (INT_PTR i = 0; i < (INT_PTR)iVisibleNodes; ++i) { const CLookupHistory::SLookupHistoryEntry *sEntry = he[hecount - (i + 1)]; - for (int j = 0; j < sEntry->m_liReceivedFromIdx.GetCount(); ++j) { - int iIdx = sEntry->m_liReceivedFromIdx[j]; + for (INT_PTR j = 0; j < sEntry->m_liReceivedFromIdx.GetCount(); ++j) { + INT_PTR iIdx = sEntry->m_liReceivedFromIdx[j]; if (iIdx >= (int)(hecount - iVisibleNodes)) { CPoint pFrom = m_aNodesDrawRects[hecount - (iIdx + 1)].CenterPoint(); CPoint pointTo = m_aNodesDrawRects[i].CenterPoint(); @@ -360,16 +359,16 @@ void CKadLookupGraph::OnPaint() } Gdiplus::GdiplusShutdown(gdiplusToken); } else { - for (int i = 0; i < (int)iVisibleNodes; ++i) { + for (INT_PTR i = 0; i < (INT_PTR)iVisibleNodes; ++i) { const CLookupHistory::SLookupHistoryEntry *sEntry = he[hecount - (i + 1)]; - for (int j = 0; j < sEntry->m_liReceivedFromIdx.GetCount(); ++j) { - int iIdx = sEntry->m_liReceivedFromIdx[j]; - if (iIdx >= (int)(hecount - iVisibleNodes)) { + for (INT_PTR j = 0; j < sEntry->m_liReceivedFromIdx.GetCount(); ++j) { + INT_PTR iIdx = sEntry->m_liReceivedFromIdx[j]; + if (iIdx >= (INT_PTR)(hecount - iVisibleNodes)) { CPoint pFrom = m_aNodesDrawRects[hecount - (iIdx + 1)].CenterPoint(); CPoint pointTo = m_aNodesDrawRects[i].CenterPoint(); - if ((int)hecount - (iIdx + 1) == m_iHotItemIdx) { + if ((INT_PTR)hecount - (iIdx + 1) == m_iHotItemIdx) { abHotItemConnected[i] = true; dc.SelectObject(&m_penRed); } else { @@ -379,37 +378,32 @@ void CKadLookupGraph::OnPaint() } POINT aptPoly[3]; - POINT pBase; - float vecLine[2]; - float vecLeft[2]; int nWidth = 4; // set to point - aptPoly[0].x = pointTo.x; - aptPoly[0].y = pointTo.y; + aptPoly[0] = pointTo; // build the line vector - vecLine[0] = (float)aptPoly[0].x - pFrom.x; - vecLine[1] = (float)aptPoly[0].y - pFrom.y; + float vecLine[2] = { (float)aptPoly[0].x - pFrom.x, (float)aptPoly[0].y - pFrom.y }; // build the arrow base vector - normal to the line - vecLeft[0] = -vecLine[1]; - vecLeft[1] = vecLine[0]; + const float vecLeft[2] = { -vecLine[1], vecLine[0] }; // setup length parameters - float fLength = (float)sqrt(vecLine[0] * vecLine[0] + vecLine[1] * vecLine[1]); + float fLength = sqrt(vecLine[0] * vecLine[0] + vecLine[1] * vecLine[1]); float th = nWidth / (2.0f * fLength); - float ta = nWidth / (2.0f * (tanf(0.3f) / 2.0f) * fLength); + float ta = nWidth / (tanf(0.3f) * fLength); // find the base of the arrow - pBase.x = (int)(aptPoly[0].x + -ta * vecLine[0]); - pBase.y = (int)(aptPoly[0].y + -ta * vecLine[1]); + POINT pBase; + pBase.x = (LONG)(aptPoly[0].x - ta * vecLine[0]); + pBase.y = (LONG)(aptPoly[0].y - ta * vecLine[1]); // build the points on the sides of the arrow - aptPoly[1].x = (int)(pBase.x + th * vecLeft[0]); - aptPoly[1].y = (int)(pBase.y + th * vecLeft[1]); - aptPoly[2].x = (int)(pBase.x + -th * vecLeft[0]); - aptPoly[2].y = (int)(pBase.y + -th * vecLeft[1]); + aptPoly[1].x = (LONG)(pBase.x + th * vecLeft[0]); + aptPoly[1].y = (LONG)(pBase.y + th * vecLeft[1]); + aptPoly[2].x = (LONG)(pBase.x + -th * vecLeft[0]); + aptPoly[2].y = (LONG)(pBase.y + -th * vecLeft[1]); dc.MoveTo(pFrom); dc.LineTo(aptPoly[0].x, aptPoly[0].y); dc.Polygon(aptPoly, 3); @@ -419,7 +413,7 @@ void CKadLookupGraph::OnPaint() } // draw the nodes images - for (int i = 0; i < (int)iVisibleNodes; ++i) { + for (INT_PTR i = 0; i < (INT_PTR)iVisibleNodes; ++i) { CPoint pointNode = m_aNodesDrawRects[i].CenterPoint(); pointNode.x -= 8; pointNode.y -= 8; @@ -529,8 +523,7 @@ void CKadLookupGraph::UpdateToolTip() uint32 iUseful = 0; for (int i = 0; i < hecount; ++i) for (int j = 0; j < he[i]->m_liReceivedFromIdx.GetCount(); ++j) - if (he[i]->m_liReceivedFromIdx[j] == iHotItemRealIdx) - ++iUseful; + iUseful += static_cast(he[i]->m_liReceivedFromIdx[j] == iHotItemRealIdx); strFoundNodes.Format(_T("%u (%u)"), sEntry->m_uRespondedContact, iUseful); } @@ -571,9 +564,8 @@ CString CKadLookupGraph::GetCurrentLookupTitle() const { if (m_pLookupHistory == NULL) return CString(); - if (!m_pLookupHistory->GetGUIName().IsEmpty()) - return _T('\"') + m_pLookupHistory->GetGUIName() + _T('\"'); + return _T('"') + (CString)m_pLookupHistory->GetGUIName() + _T('"'); return CSearch::GetTypeName(m_pLookupHistory->GetType()); } diff --git a/srchybrid/KadLookupGraph.h b/srchybrid/KadLookupGraph.h index d43ab0ca..093761fc 100644 --- a/srchybrid/KadLookupGraph.h +++ b/srchybrid/KadLookupGraph.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2010-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/KadSearchListCtrl.cpp b/srchybrid/KadSearchListCtrl.cpp index 7cd8e4aa..fd289860 100644 --- a/srchybrid/KadSearchListCtrl.cpp +++ b/srchybrid/KadSearchListCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -54,27 +54,27 @@ void CKadSearchListCtrl::Init() SetPrefsKey(_T("KadSearchListCtrl")); SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP); - InsertColumn(colNum, GetResString(IDS_NUMBER), LVCFMT_LEFT, 60); - InsertColumn(colKey, GetResString(IDS_KEY), LVCFMT_LEFT, DFLT_HASH_COL_WIDTH); - InsertColumn(colType, GetResString(IDS_TYPE), LVCFMT_LEFT, 100); - InsertColumn(colName, GetResString(IDS_SW_NAME), LVCFMT_LEFT, DFLT_FILENAME_COL_WIDTH); - InsertColumn(colStop, GetResString(IDS_STATUS), LVCFMT_LEFT, 100); - InsertColumn(colLoad, GetResString(IDS_THELOAD), LVCFMT_LEFT, 100); - InsertColumn(colPacketsSent, GetResString(IDS_PACKSENT), LVCFMT_LEFT, 100); - InsertColumn(colResponses, GetResString(IDS_RESPONSES), LVCFMT_LEFT, 100); + InsertColumn(colNum, _T(""), LVCFMT_LEFT, 60); //IDS_NUMBER + InsertColumn(colKey, _T(""), LVCFMT_LEFT, DFLT_HASH_COL_WIDTH); //IDS_KEY + InsertColumn(colType, _T(""), LVCFMT_LEFT, 100); //IDS_TYPE + InsertColumn(colName, _T(""), LVCFMT_LEFT, DFLT_FILENAME_COL_WIDTH); //IDS_SW_NAME + InsertColumn(colStop, _T(""), LVCFMT_LEFT, 100); //IDS_STATUS + InsertColumn(colLoad, _T(""), LVCFMT_LEFT, 100); //IDS_THELOAD + InsertColumn(colPacketsSent, _T(""), LVCFMT_LEFT, 100); //(IDS_PACKSENT + InsertColumn(colResponses, _T(""), LVCFMT_LEFT, 100); //IDS_RESPONSES SetAllIcons(); Localize(); LoadSettings(); SetSortArrow(); - SortItems(SortProc, MAKELONG(GetSortItem(), (GetSortAscending() ? 0 : 0x0001))); + SortItems(SortProc, MAKELONG(GetSortItem(), !GetSortAscending())); } void CKadSearchListCtrl::UpdateKadSearchCount() { - CString id; - id.Format(_T("%s (%i)"), (LPCTSTR)GetResString(IDS_KADSEARCHLAB), GetItemCount()); + CString id(GetResString(IDS_KADSEARCHLAB)); + id.AppendFormat(_T(" (%i)"), GetItemCount()); theApp.emuledlg->kademliawnd->SetDlgItemText(IDC_KADSEARCHLAB, id); } @@ -101,47 +101,13 @@ void CKadSearchListCtrl::SetAllIcons() void CKadSearchListCtrl::Localize() { - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); - HDITEM hdi; - hdi.mask = HDI_TEXT; - CString strRes; - - for (int icol = pHeaderCtrl->GetItemCount(); --icol >= 0;) { - UINT uid; - switch (icol) { - case colNum: - uid = IDS_NUMBER; - break; - case colKey: - uid = IDS_KEY; - break; - case colType: - uid = IDS_TYPE; - break; - case colName: - uid = IDS_SW_NAME; - break; - case colStop: - uid = IDS_STATUS; - break; - case colResponses: - uid = IDS_RESPONSES; - break; - case colLoad: - uid = IDS_THELOAD; - break; - case colPacketsSent: - uid = IDS_PACKSENT; - break; - default: - uid = 0; - strRes.Empty(); - } - if (uid) - strRes = GetResString(uid); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(icol, &hdi); - } + static const UINT uids[8] = + { + IDS_NUMBER, IDS_KEY, IDS_TYPE, IDS_SW_NAME, IDS_STATUS, + IDS_THELOAD, IDS_PACKSENT, IDS_RESPONSES + }; + + LocaliseHeaderCtrl(uids, _countof(uids)); for (int i = GetItemCount(); --i >= 0;) SearchRef(reinterpret_cast(GetItemData(i))); @@ -193,7 +159,7 @@ void CKadSearchListCtrl::UpdateSearch(int iItem, const Kademlia::CSearch *search SetItemText(iItem, colName, (CString)search->GetGUIName()); if (search->GetTarget() != NULL) { - search->GetTarget().ToHexString(&id); + search->GetTarget().ToHexString(id); SetItemText(iItem, colKey, id); } @@ -213,7 +179,7 @@ void CKadSearchListCtrl::SearchAdd(const Kademlia::CSearch *search) { try { ASSERT(search != NULL); - int iItem = InsertItem(LVIF_TEXT | LVIF_PARAM, GetItemCount(), NULL, 0, 0, 0, (LPARAM)search); + int iItem = InsertItem(LVIF_TEXT | LVIF_PARAM, GetItemCount(), _T(""), 0, 0, 0, (LPARAM)search); if (iItem >= 0) { UpdateSearch(iItem, search); UpdateKadSearchCount(); @@ -263,20 +229,17 @@ BOOL CKadSearchListCtrl::OnCommand(WPARAM, LPARAM) void CKadSearchListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) { - NMLISTVIEW *pNMListView = reinterpret_cast(pNMHDR); - + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); // Determine ascending based on whether already sorted on this column - int iSortItem = GetSortItem(); - bool bSortAscending = (iSortItem != pNMListView->iSubItem) || !GetSortAscending(); + bool bSortAscending = (GetSortItem() != pNMLV->iSubItem) || !GetSortAscending(); // Item is the clicked column - iSortItem = pNMListView->iSubItem; + int iSortItem = pNMLV->iSubItem; // Sort table - UpdateSortHistory(MAKELONG(iSortItem, (bSortAscending ? 0 : 0x0001))); + UpdateSortHistory(MAKELONG(iSortItem, !bSortAscending)); SetSortArrow(iSortItem, bSortAscending); - SortItems(SortProc, MAKELONG(iSortItem, (bSortAscending ? 0 : 0x0001))); - + SortItems(SortProc, MAKELONG(iSortItem, !bSortAscending)); *pResult = 0; } @@ -292,7 +255,6 @@ int CALLBACK CKadSearchListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM case colNum: iResult = CompareUnsigned(item1->GetSearchID(), item2->GetSearchID()); break; - case colKey: if (item1->GetTarget() == NULL && item2->GetTarget() == NULL) iResult = 0; @@ -324,9 +286,7 @@ int CALLBACK CKadSearchListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM default: return 0; } - if (HIWORD(lParamSort)) - iResult = -iResult; - return iResult; + return HIWORD(lParamSort) ? -iResult : iResult; } Kademlia::CLookupHistory* CKadSearchListCtrl::FetchAndSelectActiveSearch(bool bMark) diff --git a/srchybrid/KadSearchListCtrl.h b/srchybrid/KadSearchListCtrl.h index bd0b9026..a4245284 100644 --- a/srchybrid/KadSearchListCtrl.h +++ b/srchybrid/KadSearchListCtrl.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -30,7 +30,6 @@ class CKadSearchListCtrl : public CMuleListCtrl public: CKadSearchListCtrl(); - virtual ~CKadSearchListCtrl() = default; void SearchAdd(const Kademlia::CSearch *search); void SearchRem(const Kademlia::CSearch *search); diff --git a/srchybrid/KademliaWnd.cpp b/srchybrid/KademliaWnd.cpp index 6f21ae68..9bdfcc9c 100644 --- a/srchybrid/KademliaWnd.cpp +++ b/srchybrid/KademliaWnd.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -76,8 +76,8 @@ BEGIN_MESSAGE_MAP(CKademliaWnd, CResizableDialog) ON_BN_CLICKED(IDC_RADIP, UpdateControlsState) ON_BN_CLICKED(IDC_RADNODESURL, UpdateControlsState) ON_WM_HELPINFO() - ON_NOTIFY(NM_DBLCLK, IDC_SEARCHLIST, OnNMDblclkSearchlist) - ON_NOTIFY(LVN_ITEMCHANGED, IDC_SEARCHLIST, OnListModifiedSearchlist) + ON_NOTIFY(NM_DBLCLK, IDC_KADSEARCHLIST, OnNMDblclkSearchlist) + ON_NOTIFY(LVN_ITEMCHANGED, IDC_KADSEARCHLIST, OnListModifiedSearchlist) END_MESSAGE_MAP() CKademliaWnd::CKademliaWnd(CWnd *pParent /*=NULL*/) @@ -141,13 +141,13 @@ BOOL CKademliaWnd::OnInitDialog() m_pbtnWnd->SetExtendedStyle(m_pbtnWnd->GetExtendedStyle() | TBSTYLE_EX_MIXEDBUTTONS); TBBUTTON atb1[1 + WND1_NUM_BUTTONS] = {}; - atb1[0].iBitmap = 0; + //atb1[0].iBitmap = 0; atb1[0].idCommand = IDC_KADICO1; atb1[0].fsState = TBSTATE_ENABLED; atb1[0].fsStyle = BTNS_BUTTON | BTNS_SHOWTEXT; atb1[0].iString = -1; - atb1[1].iBitmap = 0; + //atb1[1].iBitmap = 0; atb1[1].idCommand = MP_VIEW_KADCONTACTS; atb1[1].fsState = TBSTATE_ENABLED; atb1[1].fsStyle = BTNS_BUTTON | BTNS_CHECKGROUP | BTNS_AUTOSIZE; @@ -192,7 +192,7 @@ BOOL CKademliaWnd::OnInitDialog() AddAnchor(IDC_KAD_LOOKUPGRAPH, TOP_LEFT, MIDDLE_RIGHT); AddAnchor(IDC_KAD_HISTOGRAM, TOP_RIGHT, MIDDLE_RIGHT); AddAnchor(IDC_KADICO2, MIDDLE_LEFT); - AddAnchor(IDC_SEARCHLIST, MIDDLE_LEFT, BOTTOM_RIGHT); + AddAnchor(IDC_KADSEARCHLIST, MIDDLE_LEFT, BOTTOM_RIGHT); AddAnchor(IDC_KADSEARCHLAB, MIDDLE_LEFT); AddAllOtherAnchors(TOP_RIGHT); @@ -210,7 +210,7 @@ BOOL CKademliaWnd::OnInitDialog() CheckDlgButton(IDC_RADCLIENTS, 1); ShowLookupGraph(false); - return true; + return TRUE; } void CKademliaWnd::DoDataExchange(CDataExchange *pDX) @@ -219,7 +219,7 @@ void CKademliaWnd::DoDataExchange(CDataExchange *pDX) DDX_Control(pDX, IDC_CONTACTLIST, *m_contactListCtrl); DDX_Control(pDX, IDC_KAD_HISTOGRAM, *m_contactHistogramCtrl); DDX_Control(pDX, IDC_KAD_LOOKUPGRAPH, *m_kadLookupGraph); - DDX_Control(pDX, IDC_SEARCHLIST, *searchList); + DDX_Control(pDX, IDC_KADSEARCHLIST, *searchList); DDX_Control(pDX, IDC_BSSTATIC, m_ctrlBootstrap); DDX_Control(pDX, IDC_KADICO1, *m_pbtnWnd); } @@ -262,15 +262,14 @@ void CKademliaWnd::OnBnClickedBootstrapbutton() // auto-handle ip:port int iPos = strIP.Trim().Find(_T(':')); if (iPos >= 0) { - SetDlgItemText(IDC_BOOTSTRAPPORT, strIP.Mid(iPos + 1)); + SetDlgItemText(IDC_BOOTSTRAPPORT, CPTR(strIP, iPos + 1)); strIP.Truncate(iPos); SetDlgItemText(IDC_BOOTSTRAPIP, strIP); } CString strPort; GetDlgItemText(IDC_BOOTSTRAPPORT, strPort); - strPort.Trim(); - uint16 nPort = (uint16)_ttoi(strPort); + uint16 nPort = (uint16)_ttoi(strPort.Trim()); // invalid IP/Port if (strIP.GetLength() < 7 || nPort == 0) { @@ -403,15 +402,15 @@ void CKademliaWnd::UpdateKadContactCount() void CKademliaWnd::StartUpdateContacts() { - m_contactHistogramCtrl->SetRedraw(TRUE); + m_contactHistogramCtrl->SetRedraw(true); m_contactHistogramCtrl->Invalidate(); - m_contactListCtrl->SetRedraw(TRUE); + m_contactListCtrl->SetRedraw(true); } void CKademliaWnd::StopUpdateContacts() { - m_contactHistogramCtrl->SetRedraw(FALSE); - m_contactListCtrl->SetRedraw(FALSE); + m_contactHistogramCtrl->SetRedraw(false); + m_contactListCtrl->SetRedraw(false); } bool CKademliaWnd::ContactAdd(const Kademlia::CContact *contact) @@ -447,8 +446,8 @@ void CKademliaWnd::ContactRef(const Kademlia::CContact *contact) void CKademliaWnd::UpdateNodesDatFromURL(const CString &strURL) { - CString strTempFilename; - strTempFilename.Format(_T("%stemp-%lu-nodes.dat"), (LPCTSTR)thePrefs.GetMuleDirectory(EMULE_CONFIGDIR), ::GetTickCount()); + CString strTempFilename(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); + strTempFilename.AppendFormat(_T("temp-%lu-nodes.dat"), ::GetTickCount()); // try to download nodes.dat Log(GetResString(IDS_DOWNLOADING_NODESDAT_FROM), (LPCTSTR)strURL); @@ -532,7 +531,7 @@ void CKademliaWnd::ShowLookupGraph(bool bShow) { int iIcon = static_cast(bShow); m_pbtnWnd->CheckButton(bShow ? MP_VIEW_KADLOOKUP : MP_VIEW_KADCONTACTS); - TBBUTTONINFO tbbi = {}; + TBBUTTONINFO tbbi; tbbi.cbSize = (UINT)sizeof tbbi; tbbi.dwMask = TBIF_IMAGE; tbbi.iImage = iIcon; diff --git a/srchybrid/KnownFile.cpp b/srchybrid/KnownFile.cpp index 6dfda495..851bc821 100644 --- a/srchybrid/KnownFile.cpp +++ b/srchybrid/KnownFile.cpp @@ -1,6 +1,6 @@ // parts of this file are based on work from pan One (http://home-3.tiscali.nl/~meost/pms/) //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -32,7 +32,6 @@ #include "ini2.h" #include "FrameGrabThread.h" #include "CxImage/xImage.h" -#include "OtherFunctions.h" #include "Preferences.h" #include "PartFile.h" #include "Packets.h" @@ -49,6 +48,7 @@ #include "MediaInfo.h" #include "id3/tag.h" #include "id3/misc_support.h" +#include "uploaddiskiothread.h" extern wchar_t* ID3_GetStringW(const ID3_Frame *frame, ID3_FieldID fldName); #ifdef _DEBUG @@ -67,12 +67,16 @@ static char THIS_FILE[] = __FILE__; IMPLEMENT_DYNAMIC(CKnownFile, CShareableFile) CKnownFile::CKnownFile() - :m_tUtcLastModified((time_t)-1) + : m_tUtcLastModified((time_t)-1) , m_nCompleteSourcesTime() //(time(NULL)) , m_nCompleteSourcesCount(1) , m_nCompleteSourcesCountLo(1) , m_nCompleteSourcesCountHi(1) , m_pCollection() + , m_hRead(INVALID_HANDLE_VALUE) + , nInUse() + , bCompress() + , bNoNewReads() , m_timeLastSeen() , m_lastPublishTimeKadSrc() , m_lastPublishTimeKadNotes() @@ -85,7 +89,6 @@ CKnownFile::CKnownFile() , m_bAutoUpPriority(thePrefs.GetNewAutoUp()) , m_PublishedED2K() , m_bAICHRecoverHashSetAvailable() - { m_iUpPriority = m_bAutoUpPriority ? PR_HIGH : PR_NORMAL; statistic.fileParent = this; @@ -94,6 +97,8 @@ CKnownFile::CKnownFile() CKnownFile::~CKnownFile() { + ASSERT(!nInUse); + CUploadDiskIOThread::DissociateFile(this); delete m_pCollection; } @@ -136,8 +141,7 @@ CBarShader CKnownFile::s_ShareStatusBar(16); void CKnownFile::DrawShareStatusBar(CDC *dc, LPCRECT rect, bool onlygreyrect, bool bFlat) const { s_ShareStatusBar.SetFileSize(GetFileSize()); - s_ShareStatusBar.SetHeight(rect->bottom - rect->top); - s_ShareStatusBar.SetWidth(rect->right - rect->left); + s_ShareStatusBar.SetRect(rect); if (!m_ClientUploadList.IsEmpty() || m_nCompleteSourcesCountHi > 1) { // We have info about chunk frequency in the net, so we will color the chunks we have after perceived availability. @@ -147,7 +151,7 @@ void CKnownFile::DrawShareStatusBar(CDC *dc, LPCRECT rect, bool onlygreyrect, bo if (!onlygreyrect) { uint32 tempCompleteSources = m_nCompleteSourcesCountLo ? m_nCompleteSourcesCountLo - 1 : 0; - for (UINT i = 0; i < GetPartCount(); ++i) { + for (INT_PTR i = GetPartCount(); --i >= 0;) { uint32 frequency = tempCompleteSources; if (!m_AvailPartFrequency.IsEmpty()) frequency = max(m_AvailPartFrequency[i], tempCompleteSources); @@ -215,8 +219,8 @@ void CKnownFile::UpdatePartsInfo() CUpDownClient *cur_src = m_ClientUploadList.GetNext(pos); //This could be a partfile that just completed. Many of these clients will not have this information. if (cur_src->m_abyUpPartStatus && cur_src->GetUpPartCount() == GetPartCount()) { - for (uint16 i = GetPartCount(); i-- > 0;) - m_AvailPartFrequency[i] += static_cast(cur_src->IsUpPartAvailable(i)); + for (INT_PTR i = GetPartCount(); --i > 0;) + m_AvailPartFrequency[i] += static_cast(cur_src->IsUpPartAvailable((UINT)i)); if (bRefresh) acount.Add(cur_src->GetUpCompleteSourcesCount()); @@ -228,7 +232,7 @@ void CKnownFile::UpdatePartsInfo() if (GetPartCount() > 0) { m_nCompleteSourcesCount = m_AvailPartFrequency[0]; - for (uint16 i = GetPartCount(); i-- > 0;) + for (INT_PTR i = GetPartCount(); --i >= 0;) if (m_nCompleteSourcesCount > m_AvailPartFrequency[i]) m_nCompleteSourcesCount = m_AvailPartFrequency[i]; } else @@ -238,9 +242,9 @@ void CKnownFile::UpdatePartsInfo() int n = (int)acount.GetCount(); if (n > 0) { // SLUGFILLER: heapsortCompletesrc - for (int r = n / 2; r--; ) + for (int r = n / 2; r--;) HeapSort(acount, r, n - 1); - for (int r = n; --r; ) { + for (int r = n; --r;) { uint16 t = acount[r]; acount[r] = acount[0]; acount[0] = t; @@ -294,8 +298,7 @@ void CKnownFile::UpdatePartsInfo() void CKnownFile::AddUploadingClient(CUpDownClient *client) { - POSITION pos = m_ClientUploadList.Find(client); // to be sure - if (pos == NULL) { + if (m_ClientUploadList.Find(client) == NULL) { // to be sure m_ClientUploadList.AddTail(client); UpdateAutoUpPriority(); } @@ -303,18 +306,22 @@ void CKnownFile::AddUploadingClient(CUpDownClient *client) void CKnownFile::RemoveUploadingClient(CUpDownClient *client) { - POSITION pos = m_ClientUploadList.Find(client); // to be sure + POSITION pos = m_ClientUploadList.Find(client); if (pos != NULL) { m_ClientUploadList.RemoveAt(pos); UpdateAutoUpPriority(); } + if (m_ClientUploadList.IsEmpty()) { + ASSERT(!nInUse); + CUploadDiskIOThread::DissociateFile(this); + } } #ifdef _DEBUG void Dump(const Kademlia::WordList &wordlist) { for (Kademlia::WordList::const_iterator it = wordlist.begin(); it != wordlist.end(); ++it) { - const CStringW &rstrKeyword = *it; + const CStringW &rstrKeyword(*it); TRACE(" %ls\n", (LPCWSTR)rstrKeyword); } } @@ -335,11 +342,11 @@ void CKnownFile::SetFileName(LPCTSTR pszFileName, bool bReplaceInvalidFileSystem wordlist.clear(); if (m_pCollection) { - CStringW sKeyWords; - sKeyWords.Format(_T("%s %s"), (LPCTSTR)m_pCollection->GetCollectionAuthorKeyString(), (LPCTSTR)GetFileName()); - Kademlia::CSearchManager::GetWords(sKeyWords, &wordlist); + CStringW sKeyWords(m_pCollection->GetCollectionAuthorKeyString()); + sKeyWords.AppendFormat(_T(" %s"), (LPCTSTR)GetFileName()); + Kademlia::CSearchManager::GetWords(sKeyWords, wordlist); } else - Kademlia::CSearchManager::GetWords((CStringW)GetFileName(), &wordlist); //make sure that it is a CStringW + Kademlia::CSearchManager::GetWords((CStringW)GetFileName(), wordlist); //make sure that it is a CStringW if (pFile == this) theApp.sharedfiles->AddKeywords(this); @@ -364,7 +371,7 @@ bool CKnownFile::CreateFromFile(LPCTSTR in_directory, LPCTSTR in_filename, LPVOI return false; } - // set file size + // set file size. Zero size is valid for .part files __int64 llFileSize = _filelengthi64(_fileno(file)); if ((uint64)llFileSize > MAX_EMULE_FILE_SIZE) { if (llFileSize <= 0) @@ -377,7 +384,7 @@ bool CKnownFile::CreateFromFile(LPCTSTR in_directory, LPCTSTR in_filename, LPVOI SetFileSize((EMFileSize)(uint64)llFileSize); // we are reading the file data later in 8K blocks, adjust the internal file stream buffer accordingly - setvbuf(file, NULL, _IOFBF, 1024 * 8 * 2); + ::setvbuf(file, NULL, _IOFBF, 1024 * 8 * 2); m_AvailPartFrequency.SetSize(GetPartCount()); if (GetPartCount()) @@ -387,12 +394,17 @@ bool CKnownFile::CreateFromFile(LPCTSTR in_directory, LPCTSTR in_filename, LPVOI CAICHRecoveryHashSet cAICHHashSet(this, m_nFileSize); uint64 togo = (uint64)m_nFileSize; UINT hashcount; - for (hashcount = 0; togo >= PARTSIZE; ++hashcount) { - CAICHHashTree *pBlockAICHHashTree = cAICHHashSet.m_pHashTree.FindHash(hashcount * PARTSIZE, PARTSIZE); - ASSERT(pBlockAICHHashTree != NULL); + for (hashcount = 0; ; ++hashcount) { + UINT uSize = (UINT)min(togo, PARTSIZE); + CAICHHashTree *pBlockAICHHashTree; + if (togo) { + pBlockAICHHashTree = cAICHHashSet.m_pHashTree.FindHash(hashcount * PARTSIZE, uSize); + ASSERT(pBlockAICHHashTree != NULL); + } else + pBlockAICHHashTree = NULL; // SHA hash tree doesn't take hash of zero-sized data uchar *newhash = new uchar[MDX_DIGEST_SIZE]; - if (!CreateHash(file, PARTSIZE, newhash, pBlockAICHHashTree)) { + if (!CreateHash(file, uSize, newhash, pBlockAICHHashTree)) { LogError(_T("Failed to hash file \"%s\" - %s"), (LPCTSTR)strFilePath, _tcserror(errno)); fclose(file); delete[] newhash; @@ -405,8 +417,14 @@ bool CKnownFile::CreateFromFile(LPCTSTR in_directory, LPCTSTR in_filename, LPVOI return false; } - m_FileIdentifier.GetRawMD4HashSet().Add(newhash); - togo -= PARTSIZE; + if (!hashcount && uSize < PARTSIZE) { + m_FileIdentifier.SetMD4Hash(newhash); //one and only part + delete[] newhash; + } else + m_FileIdentifier.GetRawMD4HashSet().Add(newhash); + togo -= uSize; + if (!togo) + break; if (pvProgressParam) { if (theApp.IsClosing()) { @@ -429,21 +447,8 @@ bool CKnownFile::CreateFromFile(LPCTSTR in_directory, LPCTSTR in_filename, LPVOI } } - CAICHHashTree *pBlockAICHHashTree; - if (togo == 0) - pBlockAICHHashTree = NULL; // sha hashtree doesn't takes hash of 0-sized data - else { - pBlockAICHHashTree = cAICHHashSet.m_pHashTree.FindHash(hashcount * PARTSIZE, togo); - ASSERT(pBlockAICHHashTree != NULL); - } - - uchar *lasthash = new uchar[MDX_DIGEST_SIZE]; - if (!CreateHash(file, togo, lasthash, pBlockAICHHashTree)) { - LogError(_T("Failed to hash file \"%s\" - %s"), (LPCTSTR)strFilePath, _tcserror(errno)); - fclose(file); - delete[] lasthash; - return false; - } + if (hashcount) + m_FileIdentifier.CalculateMD4HashByHashSet(false); cAICHHashSet.ReCalculateHash(false); if (cAICHHashSet.VerifyHashTree(true)) { @@ -461,15 +466,7 @@ bool CKnownFile::CreateFromFile(LPCTSTR in_directory, LPCTSTR in_filename, LPVOI // now something went pretty wrong DebugLogError(LOG_STATUSBAR, _T("Failed to calculate AICH Hashset from file %s"), (LPCTSTR)GetFileName()); - if (!hashcount) { - m_FileIdentifier.SetMD4Hash(lasthash); - delete[] lasthash; - } else { - m_FileIdentifier.GetRawMD4HashSet().Add(lasthash); - m_FileIdentifier.CalculateMD4HashByHashSet(false); - } - - if (!theApp.IsClosing() && pvProgressParam) { + if (pvProgressParam && !theApp.IsClosing()) { ASSERT(reinterpret_cast(pvProgressParam)->IsKindOf(RUNTIME_CLASS(CKnownFile))); ASSERT(reinterpret_cast(pvProgressParam)->GetFileSize() == GetFileSize()); WPARAM uProgress = 100; @@ -477,10 +474,10 @@ bool CKnownFile::CreateFromFile(LPCTSTR in_directory, LPCTSTR in_filename, LPVOI VERIFY(theApp.emuledlg->PostMessage(TM_FILEOPPROGRESS, uProgress, (LPARAM)pvProgressParam)); } - // set lastwrite date - struct _stat64 fileinfo; - if (statUTC(_fileno(file), fileinfo) == 0) { - m_tUtcLastModified = (time_t)fileinfo.st_mtime; + // set last write date + struct _stat64 st; + if (statUTC((HANDLE)_get_osfhandle(_fileno(file)), st) == 0) { + m_tUtcLastModified = (time_t)st.st_mtime; AdjustNTFSDaylightFileTime(m_tUtcLastModified, (LPCTSTR)strFilePath); } @@ -504,16 +501,16 @@ bool CKnownFile::CreateAICHHashSetOnly() return false; } // we are reading the file data later in 8K blocks, adjust the internal file stream buffer accordingly - setvbuf(file, NULL, _IOFBF, 1024 * 8 * 2); + ::setvbuf(file, NULL, _IOFBF, 1024 * 8 * 2); // create aich hashset CAICHRecoveryHashSet cAICHHashSet(this, m_nFileSize); - uint64 togo = m_nFileSize; - UINT hashcount; - for (hashcount = 0; togo >= PARTSIZE; ++hashcount) { - CAICHHashTree *pBlockAICHHashTree = cAICHHashSet.m_pHashTree.FindHash(hashcount * PARTSIZE, PARTSIZE); + uint64 togo = (uint64)m_nFileSize; + for (UINT hashcount = 0; togo; ++hashcount) { + uint64 uSize = min(togo, PARTSIZE); + CAICHHashTree *pBlockAICHHashTree = cAICHHashSet.m_pHashTree.FindHash(hashcount * PARTSIZE, uSize); ASSERT(pBlockAICHHashTree != NULL); - if (!CreateHash(file, PARTSIZE, NULL, pBlockAICHHashTree)) { + if (!CreateHash(file, uSize, NULL, pBlockAICHHashTree)) { LogError(_T("Failed to hash file \"%s\" - %s"), (LPCTSTR)GetFilePath(), _tcserror(errno)); fclose(file); return false; @@ -522,17 +519,7 @@ bool CKnownFile::CreateAICHHashSetOnly() fclose(file); return false; } - togo -= PARTSIZE; - } - - if (togo > 0) { - CAICHHashTree *pBlockAICHHashTree = cAICHHashSet.m_pHashTree.FindHash(hashcount * PARTSIZE, togo); - ASSERT(pBlockAICHHashTree != NULL); - if (!CreateHash(file, togo, NULL, pBlockAICHHashTree)) { - LogError(_T("Failed to hash file \"%s\" - %s"), (LPCTSTR)GetFilePath(), _tcserror(errno)); - fclose(file); - return false; - } + togo -= uSize; } fclose(file); @@ -620,7 +607,7 @@ void CKnownFile::SetFileSize(EMFileSize nFileSize) // PARTSIZE*2 2 3(!) 3(!) 2 // PARTSIZE*2+1 3 3 3 3 - if (nFileSize == 0ull) { + if ((uint64)nFileSize == 0) { ASSERT(0); m_iPartCount = 0; m_iED2KPartCount = 0; @@ -635,18 +622,16 @@ void CKnownFile::SetFileSize(EMFileSize nFileSize) m_iED2KPartCount = (uint16)((uint64)nFileSize / PARTSIZE + 1); } -bool CKnownFile::LoadTagsFromFile(CFileDataIO *file) +bool CKnownFile::LoadTagsFromFile(CFileDataIO &file) { bool bHadAICHHashSetTag = false; - for (uint32 j = file->ReadUInt32(); j > 0; --j) { + for (uint32 j = file.ReadUInt32(); j > 0; --j) { CTag *newtag = new CTag(file, false); switch (newtag->GetNameID()) { case FT_FILENAME: ASSERT(newtag->IsStr()); - if (newtag->IsStr()) { - if (GetFileName().IsEmpty()) - SetFileName(newtag->GetStr()); - } + if (newtag->IsStr() && GetFileName().IsEmpty()) + SetFileName(newtag->GetStr()); break; case FT_FILESIZE: ASSERT(newtag->IsInt64(true)); @@ -696,8 +681,8 @@ bool CKnownFile::LoadTagsFromFile(CFileDataIO *file) if (newtag->IsInt()) SetLastPublishTimeKadSrc(newtag->GetInt(), 0); if (GetLastPublishTimeKadSrc() > time(NULL) + KADEMLIAREPUBLISHTIMES) { - //There may be a possibility of an older client that saved a random number here. This will check for that. - SetLastPublishTimeKadSrc(0, 0); + //There is a possibility of an older client that saved a random number here. + SetLastPublishTimeKadSrc(0, 0); //the fix } break; case FT_KADLASTPUBLISHNOTES: @@ -717,24 +702,20 @@ bool CKnownFile::LoadTagsFromFile(CFileDataIO *file) if (newtag->IsInt()) m_uMetaDataVer = newtag->GetInt() & 0x0F; break; - // old tags: as long as they are not needed, take the chance to purge them - case FT_PERMISSIONS: + case FT_PERMISSIONS: // old tags: as they are not needed, take a chance to purge case FT_KADLASTPUBLISHKEY: ASSERT(newtag->IsInt()); break; case FT_AICH_HASH: - { - if (!newtag->IsStr()) { - //ASSERT(0); uncomment later - break; - } + if (newtag->IsStr()) { CAICHHash hash; if (DecodeBase32(newtag->GetStr(), hash) == CAICHHash::GetHashSize()) m_FileIdentifier.SetAICHHash(hash); else ASSERT(0); - break; - } + } else + ASSERT(0); + break; case FT_LASTSHARED: if (newtag->IsInt()) m_timeLastSeen = newtag->GetInt(); @@ -744,7 +725,7 @@ bool CKnownFile::LoadTagsFromFile(CFileDataIO *file) case FT_AICHHASHSET: if (newtag->IsBlob()) { CSafeMemFile aichHashSetFile(newtag->GetBlob(), newtag->GetBlobSize()); - m_FileIdentifier.LoadAICHHashsetFromFile(&aichHashSetFile, false); + m_FileIdentifier.LoadAICHHashsetFromFile(aichHashSetFile, false); aichHashSetFile.Detach(); bHadAICHHashSetTag = true; } else @@ -782,13 +763,13 @@ bool CKnownFile::LoadTagsFromFile(CFileDataIO *file) return true; } -bool CKnownFile::LoadDateFromFile(CFileDataIO *file) +bool CKnownFile::LoadDateFromFile(CFileDataIO &file) { - m_tUtcLastModified = (time_t)file->ReadUInt32(); + m_tUtcLastModified = (time_t)file.ReadUInt32(); return true; } -bool CKnownFile::LoadFromFile(CFileDataIO *file) +bool CKnownFile::LoadFromFile(CFileDataIO &file) { // SLUGFILLER: SafeHash - load first, verify later bool ret = LoadDateFromFile(file); @@ -799,17 +780,17 @@ bool CKnownFile::LoadFromFile(CFileDataIO *file) // SLUGFILLER: SafeHash } -bool CKnownFile::WriteToFile(CFileDataIO *file) +bool CKnownFile::WriteToFile(CFileDataIO &file) { // date - file->WriteUInt32((uint32)m_tUtcLastModified); + file.WriteUInt32((uint32)m_tUtcLastModified); // hashset m_FileIdentifier.WriteMD4HashsetToFile(file); uint32 uTagCount = 0; - ULONGLONG uTagCountFilePos = file->GetPosition(); - file->WriteUInt32(uTagCount); + ULONGLONG uTagCountFilePos = file.GetPosition(); + file.WriteUInt32(uTagCount); CTag nametag(FT_FILENAME, GetFileName()); nametag.WriteTagToFile(file, UTF8strOptBOM); @@ -827,31 +808,31 @@ bool CKnownFile::WriteToFile(CFileDataIO *file) } // last shared - static bool sDbgWarnedOnZero = false; - if (!sDbgWarnedOnZero && m_timeLastSeen == 0) { + static bool bDbgWarnedOnZero = false; + if (!bDbgWarnedOnZero && m_timeLastSeen == 0) { DebugLog(_T("Unknown last seen date on stored file(s), upgrading from old version?")); - sDbgWarnedOnZero = true; + bDbgWarnedOnZero = true; } - ASSERT(m_timeLastSeen <= time(NULL)); - time_t timeLastShared = (m_timeLastSeen > 0 && m_timeLastSeen <= time(NULL)) ? m_timeLastSeen : time(NULL); + time_t tNow = time(NULL); + ASSERT(m_timeLastSeen <= tNow); + time_t timeLastShared = (m_timeLastSeen > 0 && m_timeLastSeen <= tNow) ? m_timeLastSeen : tNow; CTag lastSharedTag(FT_LASTSHARED, (uint32)timeLastShared); lastSharedTag.WriteTagToFile(file); ++uTagCount; + // to tidy up known.met and known2.met do not store the tags for long time not seen/shared known files bool keep = !ShouldPartiallyPurgeFile(); - if (keep) { - // those tags are no longer stored for long time not seen (shared) known files to tidy up known.met and known2.met - + if (keep) { //"may be purged" tags // AICH Part HashSet // no point in permanently storing the AICH part hashset if we need to rehash the file anyway to fetch the full recovery hashset - // the tag will make the known.met incompatible with emule version prior 0.44a - but that one is nearly 6 years old + // Also the tag will make the known.met incompatible with emule version prior 0.44a - but that one is nearly 6 years old if (m_FileIdentifier.HasAICHHash() && m_FileIdentifier.HasExpectedAICHHashCount()) { uint32 nAICHHashSetSize = (CAICHHash::GetHashSize() * (m_FileIdentifier.GetAvailableAICHPartHashCount() + 1)) + 2; BYTE *pHashBuffer = new BYTE[nAICHHashSetSize]; CSafeMemFile hashSetFile(pHashBuffer, nAICHHashSetSize); bool bWriteHashSet = false; try { - m_FileIdentifier.WriteAICHHashsetToFile(&hashSetFile); + m_FileIdentifier.WriteAICHHashsetToFile(hashSetFile); bWriteHashSet = true; } catch (CFileException *pError) { ASSERT(0); @@ -867,7 +848,7 @@ bool CKnownFile::WriteToFile(CFileDataIO *file) } } - // statistics + // statistics - never purge if (statistic.GetAllTimeTransferred()) { CTag attag1(FT_ATTRANSFERRED, (uint32)statistic.GetAllTimeTransferred()); attag1.WriteTagToFile(file); @@ -890,6 +871,7 @@ bool CKnownFile::WriteToFile(CFileDataIO *file) ++uTagCount; } + // "may be purged" tags, part 2 if (keep) { // priority N permission CTag priotag(FT_ULPRIORITY, IsAutoUpPriority() ? PR_AUTO : m_iUpPriority); @@ -933,72 +915,51 @@ bool CKnownFile::WriteToFile(CFileDataIO *file) } } - file->Seek(uTagCountFilePos, CFile::begin); - file->WriteUInt32(uTagCount); - file->Seek(0, CFile::end); + file.Seek(uTagCountFilePos, CFile::begin); + file.WriteUInt32(uTagCount); + file.Seek(0, CFile::end); return true; } void CKnownFile::CreateHash(CFile *pFile, uint64 Length, uchar *pMd4HashOut, CAICHHashTree *pShaHashOut) { - ASSERT(pFile != NULL); ASSERT(pMd4HashOut != NULL || pShaHashOut != NULL); - uint64 Required = Length; uchar X[64 * 128]; uint64 posCurrentEMBlock = 0; uint64 nIACHPos = 0; CMD4 md4; CAICHHashAlgo *pHashAlg = (pShaHashOut != NULL) ? CAICHRecoveryHashSet::GetNewHashAlgo() : NULL; - while (Required >= 64) { - uint32 len = (uint32)((Required > _countof(X) ? (uint64)_countof(X) : Required) / 64); - pFile->Read(X, len * 64); + for (uint64 Required = Length; Required;) { + UINT len = (UINT)(min(Required, (uint64)_countof(X)) / 64); + UINT uRead = len ? len * 64 : (UINT)Required; + VERIFY(pFile->Read(X, uRead) == uRead); // SHA hash needs 180KB blocks if (pShaHashOut != NULL) { // && pHashAlg != NULL - do not check again - if (nIACHPos + len * 64ull >= EMBLOCKSIZE) { - uint32 nToComplete = (uint32)(EMBLOCKSIZE - nIACHPos); - pHashAlg->Add(X, nToComplete); + if (nIACHPos + uRead >= EMBLOCKSIZE) { + uint64 nToComplete = EMBLOCKSIZE - nIACHPos; + pHashAlg->Add(X, (DWORD)nToComplete); ASSERT(nIACHPos + nToComplete == EMBLOCKSIZE); pShaHashOut->SetBlockHash(EMBLOCKSIZE, posCurrentEMBlock, pHashAlg); posCurrentEMBlock += EMBLOCKSIZE; pHashAlg->Reset(); - pHashAlg->Add(X + nToComplete, (len * 64) - nToComplete); - nIACHPos = (len * 64ull) - nToComplete; + nIACHPos = uRead - nToComplete; + pHashAlg->Add(X + nToComplete, (DWORD)nIACHPos); } else { - pHashAlg->Add(X, len * 64ull); - nIACHPos += len * 64ull; + pHashAlg->Add(X, uRead); + nIACHPos += uRead; } } if (pMd4HashOut != NULL) - md4.Add(X, len * 64ull); + md4.Add(X, uRead); - Required -= len * 64ull; + Required -= uRead; } - Required = Length % 64; - if (Required != 0) { - pFile->Read(X, (uint32)Required); - - if (pShaHashOut != NULL) { - if (nIACHPos + Required >= EMBLOCKSIZE) { - uint32 nToComplete = (uint32)(EMBLOCKSIZE - nIACHPos); - pHashAlg->Add(X, nToComplete); - ASSERT(nIACHPos + nToComplete == EMBLOCKSIZE); - pShaHashOut->SetBlockHash(EMBLOCKSIZE, posCurrentEMBlock, pHashAlg); - posCurrentEMBlock += EMBLOCKSIZE; - pHashAlg->Reset(); - pHashAlg->Add(X + nToComplete, (uint32)(Required - nToComplete)); - nIACHPos = Required - nToComplete; - } else { - pHashAlg->Add(X, (uint32)Required); - nIACHPos += Required; - } - } - } if (pShaHashOut != NULL) { if (nIACHPos > 0) { pShaHashOut->SetBlockHash(nIACHPos, posCurrentEMBlock, pHashAlg); @@ -1006,15 +967,13 @@ void CKnownFile::CreateHash(CFile *pFile, uint64 Length, uchar *pMd4HashOut, CAI } ASSERT(posCurrentEMBlock == Length); VERIFY(pShaHashOut->ReCalculateHash(pHashAlg, false)); + delete pHashAlg; } if (pMd4HashOut != NULL) { - md4.Add(X, (uint32)Required); md4.Finish(); md4cpy(pMd4HashOut, md4.GetHash()); } - - delete pHashAlg; } bool CKnownFile::CreateHash(FILE *fp, uint64 uSize, uchar *pucHash, CAICHHashTree *pShaHashOut) @@ -1091,7 +1050,7 @@ Packet* CKnownFile::CreateSrcInfoPacket(const CUpDownClient *forClient, uint8 by for (POSITION pos = m_ClientUploadList.GetHeadPosition(); pos != NULL;) { const CUpDownClient *cur_src = m_ClientUploadList.GetNext(pos); /* - // some rare issue seen in a crashdumps, hopefully fixed already, but to be sure we double check here + // some rare issue seen in crash dumps, hopefully fixed already, but to be sure we double check here // TODO: remove check next version, as it uses resources and shouldn't be necessary if (!theApp.clientlist->IsValidClient(cur_src)) { #if defined(_BETA) || defined(_DEVBUILD) @@ -1115,7 +1074,7 @@ Packet* CKnownFile::CreateSrcInfoPacket(const CUpDownClient *forClient, uint8 by if (srcstatus) { ASSERT(cur_src->GetUpPartCount() == GetPartCount()); if (cur_src->GetUpPartCount() == forClient->GetUpPartCount()) { - for (UINT x = GetPartCount(); x > 0; --x) + for (INT_PTR x = GetPartCount(); --x >= 0;) if (srcstatus[x] && !rcvstatus[x]) { // We know the receiving client needs a chunk from this client. bNeeded = true; @@ -1140,7 +1099,7 @@ Packet* CKnownFile::CreateSrcInfoPacket(const CUpDownClient *forClient, uint8 by const uint8 *srcstatus = cur_src->GetUpPartStatus(); if (srcstatus) { ASSERT(cur_src->GetUpPartCount() == GetPartCount()); - for (UINT x = GetPartCount(); x-- > 0;) + for (INT_PTR x = GetPartCount(); --x >= 0;) if (srcstatus[x]) { // this client has at least one chunk bNeeded = true; @@ -1171,7 +1130,7 @@ Packet* CKnownFile::CreateSrcInfoPacket(const CUpDownClient *forClient, uint8 by const uint8 uSupportsCryptLayer = static_cast(cur_src->SupportsCryptLayer()); const uint8 uRequestsCryptLayer = static_cast(cur_src->RequestsCryptLayer()); const uint8 uRequiresCryptLayer = static_cast(cur_src->RequiresCryptLayer()); - //const uint8 uDirectUDPCallback = static_cast(cur_src->SupportsDirectUDPCallback()); + //const uint8 uDirectUDPCallback = static_cast(cur_src->SupportsDirectUDPCallback()); const uint8 byCryptOptions = /*(uDirectUDPCallback << 3) |*/ (uRequiresCryptLayer << 2) | (uRequestsCryptLayer << 1) | (uSupportsCryptLayer << 0); data.WriteUInt8(byCryptOptions); } @@ -1182,10 +1141,10 @@ Packet* CKnownFile::CreateSrcInfoPacket(const CUpDownClient *forClient, uint8 by TRACE(_T("%hs: Out of %u clients, %u had no valid chunk status\n"), __FUNCTION__, m_ClientUploadList.GetCount(), cDbgNoSrc); if (!nCount) return 0; - data.Seek(bIsSX2Packet ? 17 : 16, SEEK_SET); + data.Seek(bIsSX2Packet ? 17 : 16, CFile::begin); data.WriteUInt16((uint16)nCount); - Packet *result = new Packet(&data, OP_EMULEPROT); + Packet *result = new Packet(data, OP_EMULEPROT); result->opcode = bIsSX2Packet ? OP_ANSWERSOURCES2 : OP_ANSWERSOURCES; // (1+)16+2+501*(4+2+4+2+16+1) = 14547 (14548) bytes max. if (result->size > 354) @@ -1248,38 +1207,6 @@ void CKnownFile::SetUpPriority(uint8 iNewUpPriority, bool bSave) static_cast(this)->SavePartFile(); } -void SecToTimeLength(unsigned long ulSec, CStringA &rstrTimeLength) -{ - // this function creates the content for the "length" ed2k meta tag which was introduced by eDonkeyHybrid - // with the data type 'string' :/ to save some bytes we do not format the duration with leading zeros - if (ulSec >= HR2S(1)) { - UINT uHours = ulSec / HR2S(1); - UINT uMin = (ulSec - HR2S(uHours)) / MIN2S(1); - UINT uSec = ulSec - HR2S(uHours) - MIN2S(uMin); - rstrTimeLength.Format("%u:%02u:%02u", uHours, uMin, uSec); - } else { - UINT uMin = ulSec / MIN2S(1); - UINT uSec = ulSec - MIN2S(uMin); - rstrTimeLength.Format("%u:%02u", uMin, uSec); - } -} - -void SecToTimeLength(unsigned long ulSec, CStringW &rstrTimeLength) -{ - // this function creates the content for the "length" ed2k meta tag which was introduced by eDonkeyHybrid - // with the data type 'string' :/ to save some bytes we do not format the duration with leading zeros - if (ulSec >= HR2S(1)) { - UINT uHours = ulSec / HR2S(1); - UINT uMin = (ulSec - HR2S(uHours)) / MIN2S(1); - UINT uSec = ulSec - HR2S(uHours) - MIN2S(uMin); - rstrTimeLength.Format(L"%u:%02u:%02u", uHours, uMin, uSec); - } else { - UINT uMin = ulSec / MIN2S(1); - UINT uSec = ulSec - MIN2S(uMin); - rstrTimeLength.Format(L"%u:%02u", uMin, uSec); - } -} - void CKnownFile::RemoveMetaDataTags(UINT uTagType) { static const struct @@ -1296,8 +1223,8 @@ void CKnownFile::RemoveMetaDataTags(UINT uTagType) { FT_MEDIA_CODEC, TAGTYPE_STRING } }; - // 05-Jn-2004 [bc]: ed2k and Kad are already full of totally wrong and/or not properly attached meta data. Take - // the chance to clean any available meta data tags and provide only tags which were determined by us. + // 05-Jn-2004 [bc]: ed2k and Kad are already full of totally wrong and/or not properly attached meta data. + // Take the chance to clean any available meta data tags and provide only tags which were determined by us. // Remove all meta tags. Never ever trust the meta tags received from other clients or servers. for (unsigned j = 0; j < _countof(_aEmuleMetaTags); ++j) if (uTagType == 0 || (uTagType == _aEmuleMetaTags[j].nType)) @@ -1452,7 +1379,7 @@ void CKnownFile::UpdateMetaDataTags() if (thePrefs.GetExtractMetaData() == 0) return; - CString szExt(PathFindExtension(GetFileName())); + CString szExt(::PathFindExtension(GetFileName())); szExt.MakeLower(); if (szExt == _T(".mp3") || szExt == _T(".mp2") || szExt == _T(".mp1") || szExt == _T(".mpa")) { TCHAR szFullPath[MAX_PATH]; @@ -1620,18 +1547,16 @@ void CKnownFile::SetPublishedED2K(bool val) bool CKnownFile::PublishNotes() { time_t tNow = time(NULL); - if (tNow >= m_lastPublishTimeKadNotes) - if (!GetFileComment().IsEmpty() || GetFileRating() != 0) { - m_lastPublishTimeKadNotes = tNow + KADEMLIAREPUBLISHTIMEN; - return true; - } - + if (tNow >= m_lastPublishTimeKadNotes && (!GetFileComment().IsEmpty() || GetFileRating() > 0)) { + m_lastPublishTimeKadNotes = tNow + KADEMLIAREPUBLISHTIMEN; + return true; + } return false; } bool CKnownFile::PublishSrc() { - uint32 lastBuddyIP = 0; + uint32 lastBuddyIP; time_t tNow = time(NULL); if (theApp.IsFirewalled() && (Kademlia::CUDPFirewallTester::IsFirewalledUDP(true) || !Kademlia::CUDPFirewallTester::IsVerified())) @@ -1644,7 +1569,8 @@ bool CKnownFile::PublishSrc() SetLastPublishTimeKadSrc(tNow + KADEMLIAREPUBLISHTIMES, lastBuddyIP); return true; } - } + } else + lastBuddyIP = 0; if (tNow < m_lastPublishTimeKadSrc) return false; @@ -1661,16 +1587,14 @@ bool CKnownFile::IsMovie() const // function assumes that this file is shared and that any needed permission to preview exists. checks have to be done before calling! bool CKnownFile::GrabImage(uint8 nFramesToGrab, double dStartTime, bool bReduceColor, uint16 nMaxWidth, void *pSender) { - CString sImg; - sImg.Format(_T("%s\\%s"), (LPCTSTR)GetPath(), (LPCTSTR)GetFileName()); - return GrabImage(sImg, nFramesToGrab, dStartTime, bReduceColor, nMaxWidth, pSender); + return GrabImage(GetFilePath(), nFramesToGrab, dStartTime, bReduceColor, nMaxWidth, pSender); } bool CKnownFile::GrabImage(const CString &strFileName, uint8 nFramesToGrab, double dStartTime, bool bReduceColor, uint16 nMaxWidth, void *pSender) { if (!IsMovie()) return false; - CFrameGrabThread *framegrabthread = static_cast(AfxBeginThread(RUNTIME_CLASS(CFrameGrabThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED)); + CFrameGrabThread *framegrabthread = static_cast(AfxBeginThread(RUNTIME_CLASS(CFrameGrabThread), THREAD_PRIORITY_BELOW_NORMAL, 0, CREATE_SUSPENDED)); framegrabthread->SetValues(this, strFileName, nFramesToGrab, dStartTime, bReduceColor, nMaxWidth, pSender); framegrabthread->ResumeThread(); return true; @@ -1682,10 +1606,8 @@ void CKnownFile::GrabbingFinished(CxImage **imgResults, uint8 nFramesGrabbed, vo // continue processing if (theApp.clientlist->IsValidClient(reinterpret_cast(pSender))) reinterpret_cast(pSender)->SendPreviewAnswer(this, imgResults, nFramesGrabbed); - else - //probably a client which got deleted while grabbing the frames for some reason - if (thePrefs.GetVerbose()) - AddDebugLogLine(false, _T("Couldn't find Sender of FrameGrabbing Request")); + else if (thePrefs.GetVerbose()) //probably the client got deleted while grabbing the frames + AddDebugLogLine(false, _T("Couldn't find Sender of FrameGrabbing Request")); //cleanup for (int i = nFramesGrabbed; --i >= 0;) @@ -1731,15 +1653,15 @@ bool CKnownFile::ImportParts() CString CKnownFile::GetInfoSummary(bool bNoFormatCommands) const { - CString strFolder = GetPath(); - PathRemoveBackslash(strFolder.GetBuffer()); - strFolder.ReleaseBuffer(); + CString strFolder(GetPath()); + unslosh(strFolder); - CString strAccepts, strRequests, strTransferred; + CString strAccepts, strRequests; strRequests.Format(_T("%u (%u)"), statistic.GetRequests(), statistic.GetAllTimeRequests()); strAccepts.Format(_T("%u (%u)"), statistic.GetAccepts(), statistic.GetAllTimeAccepts()); - strTransferred.Format(_T("%s (%s)"), (LPCTSTR)CastItoXBytes(statistic.GetTransferred()), (LPCTSTR)CastItoXBytes(statistic.GetAllTimeTransferred())); - CString strType = GetFileTypeDisplayStr(); + CString strTransferred(CastItoXBytes(statistic.GetTransferred())); + strTransferred.AppendFormat(_T(" (%s)"), (LPCTSTR)CastItoXBytes(statistic.GetAllTimeTransferred())); + CString strType(GetFileTypeDisplayStr()); if (strType.IsEmpty()) strType += _T('-'); CString dbgInfo; @@ -1748,9 +1670,8 @@ CString CKnownFile::GetInfoSummary(bool bNoFormatCommands) const , IsAICHRecoverHashSetAvailable() ? _T("Yes") : _T("No")); #endif - CString strHeadFormatCommand(bNoFormatCommands ? _T("") : _T("")); - CString info; - info.Format(_T("%s\n") + CString info(GetFileName()); + info.AppendFormat(_T("\n") _T("eD2K %s %s\n") _T("%s: %s\n") _T("%s %s\n") @@ -1761,11 +1682,10 @@ CString CKnownFile::GetInfoSummary(bool bNoFormatCommands) const _T("%s: %s\n") _T("%s: %s\n") _T("%s: %s%s") - , (LPCTSTR)GetFileName() , (LPCTSTR)GetResString(IDS_FD_HASH), (LPCTSTR)md4str(GetFileHash()) , (LPCTSTR)GetResString(IDS_AICHHASH), (LPCTSTR)m_FileIdentifier.GetAICHHash().GetString() , (LPCTSTR)GetResString(IDS_FD_SIZE), (LPCTSTR)CastItoXBytes(GetFileSize()) - , (LPCTSTR)strHeadFormatCommand + , bNoFormatCommands ? _T("") : _T("") , (LPCTSTR)GetResString(IDS_TYPE), (LPCTSTR)strType , (LPCTSTR)GetResString(IDS_FOLDER), (LPCTSTR)strFolder , (LPCTSTR)GetResString(IDS_PRIORITY), (LPCTSTR)GetUpPriorityDisplayString() @@ -1803,6 +1723,7 @@ CString CKnownFile::GetUpPriorityDisplayString() const bool CKnownFile::ShouldPartiallyPurgeFile() const { - return thePrefs.DoPartiallyPurgeOldKnownFiles() && m_timeLastSeen > 0 + return thePrefs.DoPartiallyPurgeOldKnownFiles() + && m_timeLastSeen > 0 && time(NULL) >= m_timeLastSeen + OLDFILES_PARTIALLYPURGE; } \ No newline at end of file diff --git a/srchybrid/KnownFile.h b/srchybrid/KnownFile.h index 12e5c8de..5ea3ee57 100644 --- a/srchybrid/KnownFile.h +++ b/srchybrid/KnownFile.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -18,7 +18,6 @@ #include "BarShader.h" #include "StatisticFile.h" #include "ShareableFile.h" -#include class CxImage; class CUpDownClient; @@ -42,8 +41,8 @@ class CKnownFile : public CShareableFile virtual void SetFileName(LPCTSTR pszFileName, bool bReplaceInvalidFileSystemChars = false, bool bRemoveControlChars = false); // 'bReplaceInvalidFileSystemChars' is set to 'false' for backward compatibility! bool CreateFromFile(LPCTSTR directory, LPCTSTR filename, LPVOID pvProgressParam); // create date, hashset and tags from a file - bool LoadFromFile(CFileDataIO *file); //load date, hashset and tags from a .met file - bool WriteToFile(CFileDataIO *file); + bool LoadFromFile(CFileDataIO &file); //load date, hashset and tags from a .met file + bool WriteToFile(CFileDataIO &file); bool CreateAICHHashSetOnly(); // last file modification time in (DST corrected, if NTFS) real UTC format @@ -128,11 +127,11 @@ class CKnownFile : public CShareableFile static bool CreateHash(const uchar *pucData, uint32 uSize, uchar *pucHash, CAICHHashTree *pShaHashOut = NULL); + CStatisticFile statistic; // last file modification time in (DST corrected, if NTFS) real UTC format // NOTE: this value can *not* be compared with NT's version of the UTC time time_t m_tUtcLastModified; - CStatisticFile statistic; time_t m_nCompleteSourcesTime; uint16 m_nCompleteSourcesCount; uint16 m_nCompleteSourcesCountLo; @@ -140,7 +139,11 @@ class CKnownFile : public CShareableFile CUpDownClientPtrList m_ClientUploadList; CArray m_AvailPartFrequency; CCollection *m_pCollection; - + //overlapped disk reads + HANDLE m_hRead; + int nInUse; //count outstanding I/O (reads) to know if the file is in use + bool bCompress; + bool bNoNewReads; //blocks new overlapped reads #ifdef _DEBUG // Diagnostic Support virtual void AssertValid() const; @@ -150,8 +153,8 @@ class CKnownFile : public CShareableFile protected: //preview bool GrabImage(const CString &strFileName, uint8 nFramesToGrab, double dStartTime, bool bReduceColor, uint16 nMaxWidth, void *pSender); - bool LoadTagsFromFile(CFileDataIO *file); - bool LoadDateFromFile(CFileDataIO *file); + bool LoadTagsFromFile(CFileDataIO &file); + bool LoadDateFromFile(CFileDataIO &file); static void CreateHash(CFile *pFile, uint64 Length, uchar *pucHash, CAICHHashTree *pShaHashOut = NULL); static bool CreateHash(FILE *fp, uint64 uSize, uchar *pucHash, CAICHHashTree *pShaHashOut = NULL); diff --git a/srchybrid/KnownFileList.cpp b/srchybrid/KnownFileList.cpp index ed922776..73811d46 100644 --- a/srchybrid/KnownFileList.cpp +++ b/srchybrid/KnownFileList.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -23,7 +23,6 @@ #include "opcodes.h" #include "Preferences.h" #include "SafeFile.h" -#include "OtherFunctions.h" #include "UpDownClient.h" #include "DownloadQueue.h" #include "emuledlg.h" @@ -75,7 +74,7 @@ bool CKnownFileList::Init() bool CKnownFileList::LoadKnownFiles() { - CString fullpath(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + KNOWN_MET_FILENAME); + const CString &fullpath(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + KNOWN_MET_FILENAME); CSafeBufferedFile file; CFileException fexp; if (!file.Open(fullpath, CFile::modeRead | CFile::osSequentialScan | CFile::typeBinary | CFile::shareDenyWrite, &fexp)) { @@ -88,7 +87,7 @@ bool CKnownFileList::LoadKnownFiles() } return false; } - setvbuf(file.m_pStream, NULL, _IOFBF, 16384); + ::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); CKnownFile *pRecord = NULL; try { @@ -103,7 +102,7 @@ bool CKnownFileList::LoadKnownFiles() uint32 RecordsNumber = file.ReadUInt32(); for (uint32 i = 0; i < RecordsNumber; ++i) { pRecord = new CKnownFile(); - if (!pRecord->LoadFromFile(&file)) { + if (!pRecord->LoadFromFile(file)) { TRACE(_T("*** Failed to load entry %u (name=%s hash=%s size=%I64u parthashes=%u expected parthashes=%u) from known.met\n") , i, (LPCTSTR)pRecord->GetFileName(), (LPCTSTR)md4str(pRecord->GetFileHash()), (uint64)pRecord->GetFileSize() , pRecord->GetFileIdentifier().GetAvailableMD4PartHashCount(), pRecord->GetFileIdentifier().GetTheoreticalMD4PartHashCount()); @@ -134,7 +133,7 @@ bool CKnownFileList::LoadCancelledFiles() // cancelled.met Format:
[[Tags TagCount] Count] if (!thePrefs.IsRememberingCancelledFiles()) return true; - CString fullpath(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + CANCELLED_MET_FILENAME); + const CString &fullpath(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + CANCELLED_MET_FILENAME); CSafeBufferedFile file; CFileException fexp; if (!file.Open(fullpath, CFile::modeRead | CFile::osSequentialScan | CFile::typeBinary | CFile::shareDenyWrite, &fexp)) { @@ -147,7 +146,7 @@ bool CKnownFileList::LoadCancelledFiles() } return false; } - setvbuf(file.m_pStream, NULL, _IOFBF, 16384); + ::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); try { bool bOldVersion = false; uint8 header = file.ReadUInt8(); @@ -173,12 +172,12 @@ bool CKnownFileList::LoadCancelledFiles() m_dwCancelledFilesSeed = (GetRandomUInt32() % 0xFFFFFFFEu) + 1; } - uchar ucHash[16]; + uchar ucHash[MD5_DIGEST_SIZE]; for (uint32 i = file.ReadUInt32(); i > 0; --i) { //number of records file.ReadHash16(ucHash); // for compatibility with future versions which may add more data than just the hash for (uint8 j = file.ReadUInt8(); j > 0; --j) //number of tags - CTag tag(&file, false); + CTag tag(file, false); if (bOldVersion) { // convert old real hash to new hash @@ -188,7 +187,7 @@ bool CKnownFileList::LoadCancelledFiles() MD5Sum md5(pachSeedHash, sizeof pachSeedHash); md4cpy(ucHash, md5.GetRawHash()); } - m_mapCancelledFiles.SetAt(CSKey(ucHash), 1); + m_mapCancelledFiles[CSKey(ucHash)] = 1; } file.Close(); return true; @@ -210,39 +209,38 @@ void CKnownFileList::Save() if (thePrefs.GetLogFileSaving()) AddDebugLogLine(false, _T("Saving known files list file \"%s\""), KNOWN_MET_FILENAME); m_nLastSaved = ::GetTickCount(); - CString fullpath(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + KNOWN_MET_FILENAME); + const CString &sConfDir(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); CSafeBufferedFile file; CFileException fexp; - if (!file.Open(fullpath, CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyWrite, &fexp)) { + if (!file.Open(sConfDir + KNOWN_MET_FILENAME, CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyWrite, &fexp)) { CString strError(_T("Failed to save ") KNOWN_MET_FILENAME _T(" file")); TCHAR szError[MAX_CFEXP_ERRORMSG]; if (GetExceptionMessage(fexp, szError, _countof(szError))) strError.AppendFormat(_T(" - %s"), szError); LogError(LOG_STATUSBAR, _T("%s"), (LPCTSTR)strError); } else { - setvbuf(file.m_pStream, NULL, _IOFBF, 16384); + ::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); try { file.WriteUInt8(0); // we will write the version tag later depending if any large files are on the list UINT nRecordsNumber = 0; bool bContainsAnyLargeFiles = false; file.WriteUInt32(nRecordsNumber); - CCKey key; - for (POSITION pos = m_Files_map.GetStartPosition(); pos != NULL;) { - CKnownFile *pFile; - m_Files_map.GetNextAssoc(pos, key, pFile); + + for (const CKnownFilesMap::CPair *pair = m_Files_map.PGetFirstAssoc(); pair != NULL; pair = m_Files_map.PGetNextAssoc(pair)) { + CKnownFile *pFile = pair->value; if (thePrefs.IsRememberingDownloadedFiles() || theApp.sharedfiles->IsFilePtrInList(pFile)) { - pFile->WriteToFile(&file); + pFile->WriteToFile(file); ++nRecordsNumber; - if (pFile->IsLargeFile()) - bContainsAnyLargeFiles = true; + bContainsAnyLargeFiles |= pFile->IsLargeFile(); } } + file.SeekToBegin(); file.WriteUInt8(bContainsAnyLargeFiles ? MET_HEADER_I64TAGS : MET_HEADER); file.WriteUInt32(nRecordsNumber); - if ((theApp.IsClosing() && thePrefs.GetCommitFiles() >= 1) || thePrefs.GetCommitFiles() >= 2) { + if (thePrefs.GetCommitFiles() >= 2 || (thePrefs.GetCommitFiles() >= 1 && theApp.IsClosing())) { file.Flush(); // flush file stream buffers to disk buffers if (_commit(_fileno(file.m_pStream)) != 0) // commit disk buffers to disk AfxThrowFileException(CFileException::hardIO, ::GetLastError(), file.GetFileName()); @@ -261,16 +259,14 @@ void CKnownFileList::Save() if (thePrefs.GetLogFileSaving()) AddDebugLogLine(false, _T("Saving known files list file \"%s\""), CANCELLED_MET_FILENAME); - fullpath = thePrefs.GetMuleDirectory(EMULE_CONFIGDIR); - fullpath += CANCELLED_MET_FILENAME; - if (!file.Open(fullpath, CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyWrite, &fexp)) { + if (!file.Open(sConfDir + CANCELLED_MET_FILENAME, CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyWrite, &fexp)) { CString strError(_T("Failed to save ") CANCELLED_MET_FILENAME _T(" file")); TCHAR szError[MAX_CFEXP_ERRORMSG]; if (GetExceptionMessage(fexp, szError, _countof(szError))) strError.AppendFormat(_T(" - %s"), szError); LogError(LOG_STATUSBAR, _T("%s"), (LPCTSTR)strError); } else { - setvbuf(file.m_pStream, NULL, _IOFBF, 16384); + ::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); try { file.WriteUInt8(CANCELLED_HEADER); @@ -280,16 +276,13 @@ void CKnownFileList::Save() file.WriteUInt32(0); else { file.WriteUInt32((uint32)m_mapCancelledFiles.GetCount()); - CSKey key; - for (POSITION pos = m_mapCancelledFiles.GetStartPosition(); pos != NULL;) { - int dwDummy; - m_mapCancelledFiles.GetNextAssoc(pos, key, dwDummy); - file.WriteHash16(key.m_key); + for (const CancelledFilesMap::CPair *pair = m_mapCancelledFiles.PGetFirstAssoc(); pair != NULL; pair = m_mapCancelledFiles.PGetNextAssoc(pair)) { + file.WriteHash16(pair->key.m_key); file.WriteUInt8(0); } } - if ((theApp.IsClosing() && thePrefs.GetCommitFiles() >= 1) || thePrefs.GetCommitFiles() >= 2) { + if (thePrefs.GetCommitFiles() >= 2 || (thePrefs.GetCommitFiles() >= 1 && theApp.IsClosing())) { file.Flush(); // flush file stream buffers to disk buffers if (_commit(_fileno(file.m_pStream)) != 0) // commit disk buffers to disk AfxThrowFileException(CFileException::hardIO, ::GetLastError(), file.GetFileName()); @@ -368,55 +361,48 @@ bool CKnownFileList::SafeAddKFile(CKnownFile *toadd) ASSERT(theApp.sharedfiles == NULL || !theApp.sharedfiles->IsFilePtrInList(pFileInMap)); ASSERT(theApp.downloadqueue == NULL || !theApp.downloadqueue->IsPartFile(pFileInMap)); - // Quick fix: If we downloaded already downloaded files again and if those files all had the same - // file names and were renamed during file completion, we have a pending ptr in transfer window. + // Quick fix: If we downloaded already downloaded files again, and if those files had the same + // file names, and were renamed during file completion, we have a pending ptr in transfer window. if (theApp.emuledlg->transferwnd && theApp.emuledlg->transferwnd->GetDownloadList()->m_hWnd) theApp.emuledlg->transferwnd->GetDownloadList()->RemoveFile(reinterpret_cast(pFileInMap)); - // Make sure the file is not used in out sharedfilesctrl any more + // Make sure the file is not used in our sharedfilesctrl any more if (theApp.emuledlg->sharedfileswnd && theApp.emuledlg->sharedfileswnd->sharedfilesctrl.m_hWnd) theApp.emuledlg->sharedfileswnd->sharedfilesctrl.RemoveFile(pFileInMap, true); delete pFileInMap; } - m_Files_map.SetAt(key, toadd); + m_Files_map[key] = toadd; if (bRemovedDuplicateSharedFile) theApp.sharedfiles->SafeAddKFile(toadd); if (toadd->GetFileIdentifier().HasAICHHash()) - m_mapKnownFilesByAICH.SetAt(toadd->GetFileIdentifier().GetAICHHash(), toadd); + m_mapKnownFilesByAICH[toadd->GetFileIdentifier().GetAICHHash()] = toadd; return true; } CKnownFile* CKnownFileList::FindKnownFile(LPCTSTR filename, time_t date, uint64 size) const { - CCKey key; - for (POSITION pos = m_Files_map.GetStartPosition(); pos != NULL;) { - CKnownFile *cur_file; - m_Files_map.GetNextAssoc(pos, key, cur_file); - if (cur_file->GetUtcFileDate() == date && (uint64)cur_file->GetFileSize() == size && filename == cur_file->GetFileName()) - return cur_file; - } + for (const CKnownFilesMap::CPair *pair = m_Files_map.PGetFirstAssoc(); pair != NULL; pair = m_Files_map.PGetNextAssoc(pair)) + if (pair->value->GetUtcFileDate() == date && (uint64)pair->value->GetFileSize() == size && pair->value->GetFileName() == filename) + return pair->value; + return NULL; } CKnownFile* CKnownFileList::FindKnownFileByPath(const CString &sFilePath) const { - CCKey key; - for (POSITION pos = m_Files_map.GetStartPosition(); pos != NULL;) { - CKnownFile *cur_file; - m_Files_map.GetNextAssoc(pos, key, cur_file); - if (!cur_file->GetFilePath().CompareNoCase(sFilePath)) - return cur_file; - } + for (const CKnownFilesMap::CPair *pair = m_Files_map.PGetFirstAssoc(); pair != NULL; pair = m_Files_map.PGetNextAssoc(pair)) + if (pair->value->GetFilePath().CompareNoCase(sFilePath) == 0) + return pair->value; + return NULL; } CKnownFile* CKnownFileList::FindKnownFileByID(const uchar *hash) const { if (hash) { - CKnownFile *found_file; - CCKey key(hash); - if (m_Files_map.Lookup(key, found_file)) - return found_file; + const CKnownFilesMap::CPair *pair = m_Files_map.PLookup(CCKey(hash)); + if (pair) + return pair->value; } return NULL; } @@ -428,15 +414,11 @@ bool CKnownFileList::IsKnownFile(const CKnownFile *file) const bool CKnownFileList::IsFilePtrInList(const CKnownFile *file) const { - if (file) { - CCKey key; - for (POSITION pos = m_Files_map.GetStartPosition(); pos != NULL;) { - CKnownFile *cur_file; - m_Files_map.GetNextAssoc(pos, key, cur_file); - if (file == cur_file) + if (file) + for (const CKnownFilesMap::CPair *pair = m_Files_map.PGetFirstAssoc(); pair != NULL; pair = m_Files_map.PGetNextAssoc(pair)) + if (file == pair->value) return true; - } - } + return false; } @@ -451,7 +433,7 @@ void CKnownFileList::AddCancelledFileID(const uchar *hash) md4cpy(pachSeedHash + 4, hash); MD5Sum md5(pachSeedHash, sizeof pachSeedHash); md4cpy(pachSeedHash, md5.GetRawHash()); - m_mapCancelledFiles.SetAt(CSKey(pachSeedHash), 1); + m_mapCancelledFiles[CSKey(pachSeedHash)] = 1; } } @@ -464,37 +446,27 @@ bool CKnownFileList::IsCancelledFileByID(const uchar *hash) const MD5Sum md5(pachSeedHash, sizeof pachSeedHash); md4cpy(pachSeedHash, md5.GetRawHash()); - int dwDummy; - if (m_mapCancelledFiles.Lookup(CSKey(pachSeedHash), dwDummy)) - return true; + return m_mapCancelledFiles.PLookup(CSKey(pachSeedHash)) != NULL; } return false; } -void CKnownFileList::CopyKnownFileMap(CMap &Files_Map) +void CKnownFileList::CopyKnownFileMap(CKnownFilesMap &Files_Map) { - CCKey key; - for (POSITION pos = m_Files_map.GetStartPosition(); pos != NULL;) { - CKnownFile *cur_file; - m_Files_map.GetNextAssoc(pos, key, cur_file); - Files_Map.SetAt(key, cur_file); - } + for (const CKnownFilesMap::CPair *pair = m_Files_map.PGetFirstAssoc(); pair != NULL; pair = m_Files_map.PGetNextAssoc(pair)) + Files_Map[pair->key] = pair->value; } bool CKnownFileList::ShouldPurgeAICHHashset(const CAICHHash &rAICHHash) const { - const CKnownFile *pFile; - if (m_mapKnownFilesByAICH.Lookup(rAICHHash, pFile)) { - if (!pFile->ShouldPartiallyPurgeFile()) - return false; - } else - ASSERT(0); - return true; + const KnonwFilesByAICHMap::CPair *pair = m_mapKnownFilesByAICH.PLookup(rAICHHash); + ASSERT(pair); + return !pair || pair->value->ShouldPartiallyPurgeFile(); } void CKnownFileList::AICHHashChanged(const CAICHHash *pOldAICHHash, const CAICHHash &rNewAICHHash, CKnownFile *pFile) { if (pOldAICHHash != NULL) m_mapKnownFilesByAICH.RemoveKey(*pOldAICHHash); - m_mapKnownFilesByAICH.SetAt(rNewAICHHash, pFile); + m_mapKnownFilesByAICH[rNewAICHHash] = pFile; } \ No newline at end of file diff --git a/srchybrid/KnownFileList.h b/srchybrid/KnownFileList.h index bf9ec63f..879f44d0 100644 --- a/srchybrid/KnownFileList.h +++ b/srchybrid/KnownFileList.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -47,7 +47,7 @@ class CKnownFileList bool IsCancelledFileByID(const uchar *hash) const; const CKnownFilesMap &GetKnownFiles() const { return m_Files_map; } - void CopyKnownFileMap(CMap &Files_Map); + void CopyKnownFileMap(CKnownFilesMap &Files_Map); bool ShouldPurgeAICHHashset(const CAICHHash &rAICHHash) const; void AICHHashChanged(const CAICHHash *pOldAICHHash, const CAICHHash &rNewAICHHash, CKnownFile *pFile); @@ -69,7 +69,7 @@ class CKnownFileList // make sure to change this if needed) KnonwFilesByAICHMap m_mapKnownFilesByAICH; uint32 m_dwCancelledFilesSeed; - uint32 m_nLastSaved; + DWORD m_nLastSaved; uint16 requested; uint16 accepted; }; \ No newline at end of file diff --git a/srchybrid/LastCommonRouteFinder.cpp b/srchybrid/LastCommonRouteFinder.cpp index ec70d969..050a9dcb 100644 --- a/srchybrid/LastCommonRouteFinder.cpp +++ b/srchybrid/LastCommonRouteFinder.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -19,7 +19,6 @@ #include "Opcodes.h" #include "LastCommonRouteFinder.h" #include "Server.h" -#include "OtherFunctions.h" #include "UpDownClient.h" #include "Preferences.h" #include "Pinger.h" @@ -34,35 +33,28 @@ static char THIS_FILE[] = __FILE__; LastCommonRouteFinder::LastCommonRouteFinder() - : pingDelaysTotal() + : m_eventThreadEnded(FALSE, TRUE) + , m_eventNewTraceRouteHost(FALSE) + , m_eventPrefs(FALSE) + , m_pingDelaysTotal() , m_LowestInitialPingAllowed(20) - , minUpload(1) - , maxUpload(_UI32_MAX) - , m_CurUpload(1) - , m_upload(_UI32_MAX) + , m_minUpload(1024) + , m_maxUpload(UNLIMITED) + , m_CurUpload(1024) + , m_upload(UNLIMITED) , m_iPingToleranceMilliseconds(200) , m_iNumberOfPingsForAverage() , m_pingAverage() , m_lowestPing() , m_uState() - , doRun(true) - , m_enabled() , m_initiateFastReactionPeriod() + , m_bRun(true) + , m_enabled() , m_bUseMillisecondPingTolerance() , needMoreHosts() { - threadEndedEvent = new CEvent(FALSE, TRUE); - newTraceRouteHostEvent = new CEvent(FALSE); - prefsEvent = new CEvent(FALSE); - - AfxBeginThread(RunProc, (LPVOID)this); -} -LastCommonRouteFinder::~LastCommonRouteFinder() -{ - delete threadEndedEvent; - delete newTraceRouteHostEvent; - delete prefsEvent; + AfxBeginThread(RunProc, (LPVOID)this); } bool LastCommonRouteFinder::AddHostToCheck(uint32 ip) @@ -85,13 +77,13 @@ bool LastCommonRouteFinder::AddHostToCheckNoLock(uint32 ip) { if (needMoreHosts && IsGoodIP(ip, true)) { //hostsToTraceRoute.AddTail(ip); - hostsToTraceRoute.SetAt(ip, 0); + hostsToTraceRoute[ip] = 0; if (hostsToTraceRoute.GetCount() >= 10) { needMoreHosts = false; - // Signal that there's hosts to fetch. - newTraceRouteHostEvent->SetEvent(); + // Signal that there are hosts to fetch. + m_eventNewTraceRouteHost.SetEvent(); } } @@ -108,7 +100,7 @@ bool LastCommonRouteFinder::AddHostsToCheck(CTypedPtrList &l if (needMoreHosts) { INT_PTR cnt = list.GetCount(); //index must be in the range [0, cnt-1] if (cnt > 0) { - POSITION pos = list.FindIndex(rand() / (RAND_MAX / min(cnt, 100))); + POSITION pos = list.FindIndex(rand() % min(cnt, 100)); if (pos == NULL) pos = list.GetHeadPosition(); while (needMoreHosts && --cnt >= 0) { @@ -137,7 +129,7 @@ bool LastCommonRouteFinder::AddHostsToCheck(CUpDownClientPtrList &list) if (needMoreHosts) { int cnt = (int)list.GetCount(); //index must be in the range [0, count-1] if (cnt > 0) { - POSITION pos = list.FindIndex(rand() / (RAND_MAX / min(cnt, 100))); + POSITION pos = list.FindIndex(rand() % min(cnt, 100)); if (pos == NULL) pos = list.GetHeadPosition(); for (cnt = 0; needMoreHosts && cnt < list.GetCount(); ++cnt) { @@ -182,74 +174,51 @@ bool LastCommonRouteFinder::AcceptNewClient() return acceptNewClient || !m_enabled; // if enabled, then return acceptNewClient, otherwise return true } -void LastCommonRouteFinder::SetPrefs(bool pEnabled, uint32 pCurUpload, uint32 pMinUpload, uint32 pMaxUpload, bool pUseMillisecondPingTolerance, double pPingTolerance, uint32 pPingToleranceMilliseconds, uint32 pGoingUpDivider, uint32 pGoingDownDivider, uint32 pNumberOfPingsForAverage, uint64 pLowestInitialPingAllowed) +bool LastCommonRouteFinder::SetPrefs(const CurrentParamStruct &cur) { - bool sendEvent = false; - prefsLocker.Lock(); - minUpload = max(1024, pMinUpload); + m_minUpload = cur.uMinUpload ? cur.uMinUpload * 1024 : 1024; - if (pMaxUpload != 0) { - maxUpload = pMaxUpload; - if (minUpload > maxUpload) - minUpload = maxUpload; - } else - maxUpload = pCurUpload + 10 * 1024; //_UI32_MAX; - - if (pEnabled && m_enabled) { - sendEvent = true; - // this will show the area for ping info in status bar. - theApp.emuledlg->SetStatusBarPartsSize(); - } else if (!pEnabled) { - if (m_enabled) { - // this will remove the area for ping info in status bar. - theApp.emuledlg->SetStatusBarPartsSize(); + if (cur.uMaxUpload) { + m_maxUpload = cur.uMaxUpload; + if (m_maxUpload != UNLIMITED) { + m_maxUpload *= 1024; + if (m_maxUpload < m_minUpload) + m_minUpload = m_maxUpload; } - //prefsEvent->ResetEvent(); - sendEvent = true; - } - - // this will resize the area for ping info in status bar. - if (m_bUseMillisecondPingTolerance != pUseMillisecondPingTolerance) - theApp.emuledlg->SetStatusBarPartsSize(); - - m_enabled = pEnabled; - m_bUseMillisecondPingTolerance = pUseMillisecondPingTolerance; - m_pingTolerance = pPingTolerance; - m_iPingToleranceMilliseconds = pPingToleranceMilliseconds; - m_goingUpDivider = pGoingUpDivider; - m_goingDownDivider = pGoingDownDivider; - m_CurUpload = pCurUpload; - m_iNumberOfPingsForAverage = pNumberOfPingsForAverage; - m_LowestInitialPingAllowed = pLowestInitialPingAllowed; + } else + m_maxUpload = m_upload + 10 * 1024; //_UI32_MAX; - prefsLocker.Unlock(); + m_pingTolerance = cur.dPingTolerance; + m_CurUpload = cur.uCurUpload; + m_iPingToleranceMilliseconds = cur.uPingToleranceMilliseconds; + m_goingUpDivider = cur.uGoingUpDivider; + m_goingDownDivider = cur.uGoingDownDivider; + m_iNumberOfPingsForAverage = cur.uNumberOfPingsForAverage; + m_LowestInitialPingAllowed = cur.uLowestInitialPingAllowed; - if (m_upload > maxUpload || !pEnabled) - m_upload = maxUpload; + // this would show, resize or hide the ping info area in status bar + bool bSetStatusBar = m_enabled || m_bUseMillisecondPingTolerance != cur.bUseMillisecondPingTolerance; - if (sendEvent) - prefsEvent->SetEvent(); -} + bool bSetEvent = !cur.bEnabled || m_enabled; -void LastCommonRouteFinder::InitiateFastReactionPeriod() -{ - prefsLocker.Lock(); - - m_initiateFastReactionPeriod = true; + m_bUseMillisecondPingTolerance = cur.bUseMillisecondPingTolerance; + m_enabled = cur.bEnabled; prefsLocker.Unlock(); -} -uint32 LastCommonRouteFinder::GetUpload() const -{ - return m_upload; + if (m_upload > m_maxUpload || !m_enabled) + m_upload = m_maxUpload; + + if (bSetEvent) + m_eventPrefs.SetEvent(); + return bSetStatusBar; } -void LastCommonRouteFinder::SetUpload(uint32 newValue) +void LastCommonRouteFinder::InitiateFastReactionPeriod() { - m_upload = newValue; + ::InterlockedExchange8(&m_initiateFastReactionPeriod, 1); } /** @@ -259,14 +228,14 @@ void LastCommonRouteFinder::SetUpload(uint32 newValue) void LastCommonRouteFinder::EndThread() { // signal the thread to stop looping and exit. - doRun = false; + m_bRun = false; needMoreHosts = false; - prefsEvent->SetEvent(); - newTraceRouteHostEvent->SetEvent(); + m_eventPrefs.SetEvent(); + m_eventNewTraceRouteHost.SetEvent(); // wait for the thread to signal that it has stopped looping. - threadEndedEvent->Lock(); + m_eventThreadEnded.Lock(); } /** @@ -280,6 +249,7 @@ UINT AFX_CDECL LastCommonRouteFinder::RunProc(LPVOID pParam) { DbgSetThreadName("LastCommonRouteFinder"); InitThreadLocale(); + srand((unsigned)time(NULL)); LastCommonRouteFinder *lastCommonRouteFinder = static_cast(pParam); return lastCommonRouteFinder->RunInternal(); } @@ -291,25 +261,26 @@ UINT LastCommonRouteFinder::RunInternal() { Pinger pinger; bool hasSucceededAtLeastOnce = false; + CString sErr; - while (doRun) { + while (m_bRun) { // wait for updated prefs - prefsEvent->Lock(); + m_eventPrefs.Lock(); bool enabled = m_enabled; // retry loop. enabled will be set to false in the end of this loop, if too many failures (too many tries) - while (doRun && enabled) { - bool foundLastCommonHost = false; + while (m_bRun && enabled) { uint32 lastCommonHost = 0; uint32 lastCommonTTL = 0; uint32 hostToPing = 0; + bool foundLastCommonHost = false; bool useUdp = false; hostsToTraceRoute.RemoveAll(); pingDelays.RemoveAll(); - pingDelaysTotal = 0; + m_pingDelaysTotal = 0; pingLocker.Lock(); m_pingAverage = 0; @@ -317,12 +288,14 @@ UINT LastCommonRouteFinder::RunInternal() m_uState = IDS_USS_STATE_PREPARING; pingLocker.Unlock(); - // Calculate a good starting value for the upload control. If the user has entered a max upload value, we use that. Otherwise 10 kByte/s - int startUpload = (maxUpload != _UI32_MAX) ? maxUpload : 10 * 1024; + // Calculate a good starting value for the upload control. + // If the user has entered a max upload value, we use that. + // Otherwise choose the highest of 10 KB/s and the current upload + uint32 startUpload = (m_maxUpload != UNLIMITED) ? m_maxUpload : max(m_CurUpload, 10 * 1024); - while (doRun && enabled && !foundLastCommonHost) { + while (m_bRun && enabled && !foundLastCommonHost) { uint32 traceRouteTries = 0; - while (doRun && enabled && !foundLastCommonHost && (traceRouteTries < 5 || (hasSucceededAtLeastOnce && traceRouteTries < _UI32_MAX)) && (hostsToTraceRoute.GetCount() < 10 || hasSucceededAtLeastOnce)) { + while (m_bRun && enabled && !foundLastCommonHost && (traceRouteTries < 5 || (hasSucceededAtLeastOnce && traceRouteTries < _UI32_MAX)) && (hostsToTraceRoute.GetCount() < 10 || hasSucceededAtLeastOnce)) { ++traceRouteTries; lastCommonHost = 0; @@ -330,30 +303,26 @@ UINT LastCommonRouteFinder::RunInternal() theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Try #%i. Collecting hosts..."), traceRouteTries); addHostLocker.Lock(); - needMoreHosts = doRun; + needMoreHosts = m_bRun; addHostLocker.Unlock(); // wait for hosts to traceroute - newTraceRouteHostEvent->Lock(); + m_eventNewTraceRouteHost.Lock(); theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Got enough hosts. Listing the hosts that will be tracerouted:")); int counter = 0; - for (POSITION pos = hostsToTraceRoute.GetStartPosition(); pos != NULL;) { - uint32 hostToTraceRoute, dummy; - hostsToTraceRoute.GetNextAssoc(pos, hostToTraceRoute, dummy); - IN_ADDR stDestAddr; - stDestAddr.s_addr = hostToTraceRoute; - - theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Host #%i: %s"), ++counter, (LPCTSTR)ipstr(stDestAddr)); - } + for (const CHostsToTraceRouteMap::CPair *pair = hostsToTraceRoute.PGetFirstAssoc(); pair != NULL; pair = hostsToTraceRoute.PGetNextAssoc(pair)) + theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Host #%i: %s"), ++counter, (LPCTSTR)ipstr(pair->key)); // find the last common host, using traceroute theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Starting traceroutes to find last common host.")); // for the tracerouting phase (preparing...) we need to disable uploads so we get a faster traceroute and better ping values. - SetUpload(2 * 1024); + m_upload = 2 * 1024; //expecting this to be always below m_maxUpload ::Sleep(SEC2MS(1)); + //Disabled upload might be fine immediately after start. + //When eMule was running and uploading, this severely disrupts upload if (!m_enabled) enabled = false; @@ -361,7 +330,7 @@ UINT LastCommonRouteFinder::RunInternal() bool failed = false; uint32 curHost = 0; - for (uint32 ttl = 1; doRun && enabled && (curHost != 0 && ttl <= 64 || curHost == 0 && ttl < 5) && !foundLastCommonHost && !failed; ++ttl) { + for (uint32 ttl = 1; m_bRun && enabled && (curHost != 0 && ttl <= 64 || curHost == 0 && ttl < 5) && !foundLastCommonHost && !failed; ++ttl) { theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Pinging for TTL %i..."), ttl); useUdp = false; // PENDING: Get default value from prefs? @@ -370,84 +339,79 @@ UINT LastCommonRouteFinder::RunInternal() if (!m_enabled) enabled = false; - uint32 lastSuccedingPingAddress = 0; + uint32 lastSuccessfulPingAddress = 0; uint32 lastDestinationAddress = 0; uint32 hostsToTraceRouteCounter = 0; bool failedThisTtl = false; - for (POSITION pos = hostsToTraceRoute.GetStartPosition(); - doRun && enabled && !failed && !failedThisTtl && pos != NULL && (lastDestinationAddress == 0 || lastDestinationAddress == curHost);) // || !pingStatus.success && pingStatus.error == IP_REQ_TIMED_OUT )) + for (const CHostsToTraceRouteMap::CPair *pair = hostsToTraceRoute.PGetFirstAssoc(); + m_bRun && enabled && !failed && !failedThisTtl && pair != NULL + && (lastDestinationAddress == 0 || lastDestinationAddress == curHost);) // || !pingStatus.success && pingStatus.error == IP_REQ_TIMED_OUT )) { - PingStatus pingStatus = {}; - + PingStatus pingStatus{}; ++hostsToTraceRouteCounter; - // this is the current address we send ping to, in loop below. - // PENDING: Don't confuse this with curHost, which is unfortunately almost - // the same name. Will rename one of these variables as soon as possible, to - // get more different names. - uint32 curAddress, dummy; - hostsToTraceRoute.GetNextAssoc(pos, curAddress, dummy); - - pingStatus.success = false; - for (int cnt = 0; doRun && enabled && cnt < 2 && (!pingStatus.success || (pingStatus.status != IP_SUCCESS && pingStatus.status != IP_TTL_EXPIRED_TRANSIT)); ++cnt) { - pingStatus = pinger.Ping(curAddress, ttl, true, useUdp); - if (doRun && enabled - && (!pingStatus.success || (pingStatus.status != IP_SUCCESS && pingStatus.status != IP_TTL_EXPIRED_TRANSIT)) - && cnt < 3 - 1) - { - IN_ADDR stDestAddr; - stDestAddr.s_addr = curAddress; - theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Failure #%i to ping host! (TTL: %i IP: %s error: %i). Sleeping 1 sec before retry. Error info follows."), cnt + 1, ttl, (LPCTSTR)ipstr(stDestAddr), (pingStatus.success) ? pingStatus.status : pingStatus.error); - pinger.PIcmpErr(pingStatus.success ? pingStatus.status : pingStatus.error); + // this is the current address to be pinged in the loop below. + uint32 uAddressToPing = pair->key; + const CHostsToTraceRouteMap::CPair *pair2 = hostsToTraceRoute.PGetNextAssoc(pair); + for (int cnt = 0; m_bRun && enabled && cnt < 2; ++cnt) { + pingStatus = pinger.Ping(uAddressToPing, ttl, true, useUdp); + if (!m_bRun || !enabled + || (pingStatus.bSuccess && (pingStatus.status == IP_SUCCESS || pingStatus.status == IP_TTL_EXPIRED_TRANSIT))) + { + break; + } + sErr.Format(_T("UploadSpeedSense: Failure #%i to ping host! (TTL: %u IP: %s).%s Error: %lu ") + , cnt + 1 + , ttl + , cnt ? _T("") : _T(" Sleeping 1 s before retry.") + , (LPCTSTR)ipstr(uAddressToPing) + , (pingStatus.bSuccess ? pingStatus.status : pingStatus.error)); + pinger.PIcmpErr(sErr, pingStatus.bSuccess ? pingStatus.status : pingStatus.error); + if (!cnt) ::Sleep(SEC2MS(1)); - if (!m_enabled) - enabled = false; + if (!m_enabled) + enabled = false; - // trying other ping method - useUdp = !useUdp; - } + // trying other ping method + useUdp = !useUdp; } - if (pingStatus.success && pingStatus.status == IP_TTL_EXPIRED_TRANSIT) { - if (curHost == 0) - curHost = pingStatus.destinationAddress; - lastSuccedingPingAddress = curAddress; - lastDestinationAddress = pingStatus.destinationAddress; - } else { - // failed to ping this host for some reason. - // Or we reached the actual host we are pinging. We don't want that, since it is too close. - // Remove it. - IN_ADDR stDestAddr; - stDestAddr.s_addr = curAddress; - if (pingStatus.success && pingStatus.status == IP_SUCCESS) { - theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Host was too close! Removing this host. (TTL: %i IP: %s status: %i). Removing this host and restarting host collection."), ttl, (LPCTSTR)ipstr(stDestAddr), pingStatus.status); - - hostsToTraceRoute.RemoveKey(curAddress); - } else if (pingStatus.success && pingStatus.status == IP_DEST_HOST_UNREACHABLE) { - theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Host unreachable! (TTL: %i IP: %s status: %i). Removing this host. Status info follows."), ttl, (LPCTSTR)ipstr(stDestAddr), pingStatus.status); - pinger.PIcmpErr(pingStatus.status); - - hostsToTraceRoute.RemoveKey(curAddress); - } else if (pingStatus.success) { - theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Unknown ping status! (TTL: %i IP: %s status: %i). Reason follows. Changing ping method to see if it helps."), ttl, (LPCTSTR)ipstr(stDestAddr), pingStatus.status); - pinger.PIcmpErr(pingStatus.status); + if (pingStatus.bSuccess) { + switch (pingStatus.status) { + case IP_TTL_EXPIRED_TRANSIT: + if (curHost == 0) + curHost = pingStatus.destinationAddress; + lastSuccessfulPingAddress = uAddressToPing; + lastDestinationAddress = pingStatus.destinationAddress; + break; + case IP_SUCCESS: + theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Host was too close! Removing this host. (TTL: %u IP: %s status: %lu). Removing this host and restarting host collection."), ttl, (LPCTSTR)ipstr(uAddressToPing), pingStatus.status); + hostsToTraceRoute.RemoveKey(uAddressToPing); + break; + case IP_DEST_HOST_UNREACHABLE: + sErr.Format(_T("UploadSpeedSense: Host unreachable! (TTL: %u IP: %s status: %lu). Removing this host. "), ttl, (LPCTSTR)ipstr(uAddressToPing), pingStatus.status); + pinger.PIcmpErr(sErr, pingStatus.status); + hostsToTraceRoute.RemoveKey(uAddressToPing); + break; + default: + sErr.Format(_T("UploadSpeedSense: Unknown ping status! (TTL: %u IP: %s status: %lu). Changing ping method. "), ttl, (LPCTSTR)ipstr(uAddressToPing), pingStatus.status); + pinger.PIcmpErr(sErr, pingStatus.status); useUdp = !useUdp; + } + } else { + if (pingStatus.error == IP_REQ_TIMED_OUT) { + sErr.Format(_T("UploadSpeedSense: Timeout when pinging a host! (TTL: %u IP: %s Error: %lu). Keeping host. "), ttl, (LPCTSTR)ipstr(uAddressToPing), pingStatus.error); + pinger.PIcmpErr(sErr, pingStatus.status); + + // several pings have timed out on this ttl. Probably we can't ping on this ttl at all + if (hostsToTraceRouteCounter > 2 && lastSuccessfulPingAddress == 0) + failedThisTtl = true; } else { - if (pingStatus.error == IP_REQ_TIMED_OUT) { - theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Timeout when pinging a host! (TTL: %i IP: %s Error: %i). Keeping host. Error info follows."), ttl, (LPCTSTR)ipstr(stDestAddr), pingStatus.error); - pinger.PIcmpErr(pingStatus.error); - - if (hostsToTraceRouteCounter > 2 && lastSuccedingPingAddress == 0) { - // several pings have timed out on this ttl. Probably we can't ping on this ttl at all - failedThisTtl = true; - } - } else { - theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Unknown pinging error! (TTL: %i IP: %s status: %i). Reason follows. Changing ping method to see if it helps."), ttl, (LPCTSTR)ipstr(stDestAddr), pingStatus.error); - pinger.PIcmpErr(pingStatus.error); - useUdp = !useUdp; - } + sErr.Format(_T("UploadSpeedSense: Unknown pinging error! (TTL: %u IP: %s status: %lu). Changing ping method."), ttl, (LPCTSTR)ipstr(uAddressToPing), pingStatus.error); + pinger.PIcmpErr(sErr, pingStatus.status); + useUdp = !useUdp; } if (hostsToTraceRoute.GetCount() <= 8) { @@ -455,38 +419,37 @@ UINT LastCommonRouteFinder::RunInternal() failed = true; } } + pair = pair2; } if (!failed) { if (curHost != 0 && lastDestinationAddress != 0) { if (lastDestinationAddress == curHost) { - IN_ADDR stDestAddr; - stDestAddr.s_addr = curHost; - theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Host at TTL %i: %s"), ttl, (LPCTSTR)ipstr(stDestAddr)); + theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Host at TTL %i: %s"), ttl, (LPCTSTR)ipstr(curHost)); lastCommonHost = curHost; lastCommonTTL = ttl; - } else /*if(lastSuccedingPingAddress != 0)*/ { + } else { //lastSuccedingPingAddress != 0 foundLastCommonHost = true; - hostToPing = lastSuccedingPingAddress; + hostToPing = lastSuccessfulPingAddress; - const CString &hostToPingString = ipstr(hostToPing); + const CString &hostToPingString(ipstr(hostToPing)); if (lastCommonHost != 0) theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Found differing host at TTL %i: %s. This will be the host to ping."), ttl, (LPCTSTR)hostToPingString); else { - const CString &lastCommonHostString = ipstr(lastDestinationAddress); + const CString &lastCommonHostString(ipstr(lastDestinationAddress)); lastCommonHost = lastDestinationAddress; lastCommonTTL = ttl; - theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Found differing host at TTL %i, but last ttl couldn't be pinged so we don't know last common host. Taking a chance and using first differing ip as last commonhost. Host to ping: %s. Faked LastCommonHost: %s"), ttl, (LPCTSTR)hostToPingString, (LPCTSTR)lastCommonHostString); + theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Found differing host at TTL %i, but last ttl couldn't be pinged so we don't know last common host. Taking a chance and using first differing ip as last common host. Host to ping: %s. Faked LastCommonHost: %s"), ttl, (LPCTSTR)hostToPingString, (LPCTSTR)lastCommonHostString); } } } else { if (ttl < 4) - theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Could perform no ping at all at TTL %i. Trying next ttl."), ttl); + theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Could not ping at TTL %i. Trying next ttl."), ttl); else - theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Could perform no ping at all at TTL %i. Giving up."), ttl); + theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Could not ping at TTL %i. Giving up."), ttl); lastCommonHost = 0; } @@ -496,13 +459,13 @@ UINT LastCommonRouteFinder::RunInternal() if (!foundLastCommonHost && traceRouteTries >= 3) { theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Tracerouting failed several times. Waiting a few minutes before trying again.")); - SetUpload(maxUpload); + m_upload = m_maxUpload; pingLocker.Lock(); m_uState = IDS_USS_STATE_WAITING; pingLocker.Unlock(); - prefsEvent->Lock(MIN2MS(3)); + m_eventPrefs.Lock(MIN2MS(3)); pingLocker.Lock(); m_uState = IDS_USS_STATE_PREPARING; @@ -517,15 +480,9 @@ UINT LastCommonRouteFinder::RunInternal() theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Done tracerouting. Evaluating results.")); if (foundLastCommonHost) { - IN_ADDR stLastCommonHostAddr; - stLastCommonHostAddr.s_addr = lastCommonHost; - // log result - theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Found last common host. LastCommonHost: %s @ TTL: %i"), (LPCTSTR)ipstr(stLastCommonHostAddr), lastCommonTTL); - - IN_ADDR stHostToPingAddr; - stHostToPingAddr.s_addr = hostToPing; - theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Found last common host. HostToPing: %s"), (LPCTSTR)ipstr(stHostToPingAddr)); + theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Found last common host. LastCommonHost: %s @ TTL: %i"), (LPCTSTR)ipstr(lastCommonHost), lastCommonTTL); + theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Found last common host. HostToPing: %s"), (LPCTSTR)ipstr(hostToPing)); } else { theApp.QueueDebugLogLine(false, GetResString(IDS_USS_TRACEROUTEOFTENFAILED)); theApp.QueueLogLine(true, GetResString(IDS_USS_TRACEROUTEOFTENFAILED)); @@ -535,7 +492,7 @@ UINT LastCommonRouteFinder::RunInternal() m_uState = IDS_USS_STATE_ERROR; pingLocker.Unlock(); - // PENDING: this may not be thread safe + // PENDING: this may be not thread safe thePrefs.SetDynUpEnabled(false); } } @@ -543,35 +500,34 @@ UINT LastCommonRouteFinder::RunInternal() if (!m_enabled) enabled = false; - - if (doRun && enabled) + else if (m_bRun && enabled) theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Finding a start value for lowest ping...")); // PENDING: prefsLocker.Lock(); - uint64 lowestInitialPingAllowed = m_LowestInitialPingAllowed; + uint32 lowestInitialPingAllowed = m_LowestInitialPingAllowed; prefsLocker.Unlock(); uint32 initial_ping = _I32_MAX; bool foundWorkingPingMethod = false; // finding lowest ping - for (int initialPingCounter = 10; doRun && enabled && --initialPingCounter >= 0;) { + for (int initialPingCounter = 10; m_bRun && enabled && --initialPingCounter >= 0;) { ::Sleep(200); PingStatus pingStatus = pinger.Ping(hostToPing, lastCommonTTL, true, useUdp); - if (pingStatus.success && pingStatus.status == IP_TTL_EXPIRED_TRANSIT) { + if (pingStatus.bSuccess && pingStatus.status == IP_TTL_EXPIRED_TRANSIT) { foundWorkingPingMethod = true; - if (pingStatus.delay > 0 && pingStatus.delay < initial_ping) - initial_ping = (uint32)max(pingStatus.delay, lowestInitialPingAllowed); + if (pingStatus.fDelay > 0 && pingStatus.fDelay < initial_ping) + initial_ping = max((uint32)pingStatus.fDelay, lowestInitialPingAllowed); } else { - theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: %s-Ping #%i failed. Reason follows"), useUdp ? _T("UDP") : _T("ICMP"), initialPingCounter); - pinger.PIcmpErr(pingStatus.error); + sErr.Format(_T("UploadSpeedSense: %s-Ping #%i failed. "), useUdp ? _T("UDP") : _T("ICMP"), initialPingCounter); + pinger.PIcmpErr(sErr, pingStatus.status); // trying other ping method - if (!pingStatus.success && !foundWorkingPingMethod) + if (!pingStatus.bSuccess && !foundWorkingPingMethod) useUdp = !useUdp; } @@ -579,41 +535,35 @@ UINT LastCommonRouteFinder::RunInternal() enabled = false; } - // Set the upload to a good starting point - SetUpload(startUpload); + // Set the upload to the starting point + m_upload = startUpload; ::Sleep(SEC2MS(1)); DWORD initTime = ::GetTickCount(); - // if all pings returned 0, initial_ping will not have been changed from default value. + // if all pings returned 0, initial_ping will not be changed from default value. // then set initial_ping to lowestInitialPingAllowed if (initial_ping == _I32_MAX) - initial_ping = (uint32)lowestInitialPingAllowed; - - uint32 upload = 0; + initial_ping = lowestInitialPingAllowed; hasSucceededAtLeastOnce = true; - if (doRun && enabled) { + uint32 upload; + if (m_bRun && enabled) { if (initial_ping > lowestInitialPingAllowed) theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Lowest ping: %i ms"), initial_ping); else theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Lowest ping: %i ms. (Filtered lower values. Lowest ping is never allowed to go under %i ms)"), initial_ping, lowestInitialPingAllowed); prefsLocker.Lock(); - - upload = m_CurUpload; - if (upload < minUpload) - upload = minUpload; - if (upload > maxUpload) - upload = maxUpload; - + upload = max(m_CurUpload, m_minUpload); + upload = min(upload, m_maxUpload); prefsLocker.Unlock(); - } + } else + upload = 0; if (!m_enabled) enabled = false; - - if (doRun && enabled) { + else if (m_bRun && enabled) { theApp.QueueDebugLogLine(false, GetResString(IDS_USS_STARTING)); theApp.QueueLogLine(true, GetResString(IDS_USS_STARTING)); } @@ -629,20 +579,20 @@ UINT LastCommonRouteFinder::RunInternal() DWORD lastLoopTick = ::GetTickCount(); - while (doRun && enabled && !restart) { + while (m_bRun && enabled && !restart) { DWORD ticksBetweenPings; if (upload > 0) { - // ping packages being 64 bytes, this should use 1% of bandwidth (one hundredth of bw). + // ping packages being 64 bytes, should use 1% of bandwidth or less (one hundredth of bw). ticksBetweenPings = SEC2MS(64 * 100) / upload; if (ticksBetweenPings < 125) - ticksBetweenPings = 125; // never ping more than 8 packages a second + ticksBetweenPings = 125; // never ping more than 8 times a second else if (ticksBetweenPings > SEC2MS(1)) ticksBetweenPings = SEC2MS(1); } else ticksBetweenPings = SEC2MS(1); - DWORD curTick = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); DWORD timeSinceLastLoop = curTick - lastLoopTick; if (timeSinceLastLoop < ticksBetweenPings) { @@ -659,39 +609,40 @@ UINT LastCommonRouteFinder::RunInternal() uint32 goingUpDivider = m_goingUpDivider; uint32 goingDownDivider = m_goingDownDivider; uint32 numberOfPingsForAverage = m_iNumberOfPingsForAverage; - lowestInitialPingAllowed = m_LowestInitialPingAllowed; // PENDING uint32 curUpload = m_CurUpload; - - bool initiateFastReactionPeriod = m_initiateFastReactionPeriod; - m_initiateFastReactionPeriod = false; + lowestInitialPingAllowed = m_LowestInitialPingAllowed; // PENDING prefsLocker.Unlock(); - if (initiateFastReactionPeriod) { + DWORD diffTick = ::GetTickCount(); + if (::InterlockedExchange8(&m_initiateFastReactionPeriod, 0)) { theApp.QueueDebugLogLine(false, GetResString(IDS_USS_MANUALUPLOADLIMITDETECTED)); theApp.QueueLogLine(true, GetResString(IDS_USS_MANUALUPLOADLIMITDETECTED)); // the first 60 seconds will use hardcoded up/down slowness that is faster - initTime = ::GetTickCount(); - } - - DWORD diffTick = ::GetTickCount() - initTime; - - if (diffTick < SEC2MS(20)) { - goingUpDivider = 1; - goingDownDivider = 1; - } else if (diffTick < SEC2MS(30)) { - goingUpDivider = (uint32)(goingUpDivider * 0.25); - goingDownDivider = (uint32)(goingDownDivider * 0.25); - } else if (diffTick < SEC2MS(40)) { - goingUpDivider = (uint32)(goingUpDivider * 0.5); - goingDownDivider = (uint32)(goingDownDivider * 0.5); - } else if (diffTick < SEC2MS(60)) { - goingUpDivider = (uint32)(goingUpDivider * 0.75); - goingDownDivider = (uint32)(goingDownDivider * 0.75); - } else if (diffTick < SEC2MS(61)) { + initTime = diffTick; + diffTick = 0; + } else + diffTick -= initTime; + + uint32 mul; // = 0; + if (diffTick < SEC2MS(20)) + mul = 4; + else if (diffTick < SEC2MS(30)) + mul = 1; + else if (diffTick < SEC2MS(40)) + mul = 2; + else if (diffTick < SEC2MS(60)) + mul = 3; + else + mul = 0; + /*if (diffTick < SEC2MS(61)) { prefsLocker.Lock(); - upload = m_CurUpload; + upload = m_CurUpload; //that might set a low value for no reason prefsLocker.Unlock(); + }*/ + if (mul) { //25%, 50%, 75% and 100% + goingUpDivider = goingUpDivider * mul / 4; + goingDownDivider = goingDownDivider * mul / 4; } goingDownDivider = max(goingDownDivider, 1); @@ -706,48 +657,40 @@ UINT LastCommonRouteFinder::RunInternal() uint32 raw_ping = soll_ping; // this value will cause the upload speed not to change at all. bool pingFailure = false; - for (uint64 pingTries = 0; doRun && enabled && (pingTries == 0 || pingFailure) && pingTries < 60; ++pingTries) { - if (!m_enabled) + for (int pingTries = 0; m_bRun && enabled && (pingTries == 0 || pingFailure) && pingTries < 60; ++pingTries) { + if (!m_enabled) { enabled = false; - + break; + } // ping the hostToPing PingStatus pingStatus = pinger.Ping(hostToPing, lastCommonTTL, false, useUdp); - if (pingStatus.success && pingStatus.status == IP_TTL_EXPIRED_TRANSIT) { + if (pingStatus.bSuccess && pingStatus.status == IP_TTL_EXPIRED_TRANSIT) { if (pingStatus.destinationAddress != lastCommonHost) { - // something has changed about the topology! We got another ip back from this ttl than expected. + // something has changed about the topology! We got other ip from this ttl, not the pinged one. // Do the tracerouting again to figure out new topology - const CString &lastCommonHostAddressString = ipstr(lastCommonHost); - const CString &destinationAddressString = ipstr(pingStatus.destinationAddress); + const CString &lastCommonHostAddressString(ipstr(lastCommonHost)); + const CString &destinationAddressString(ipstr(pingStatus.destinationAddress)); theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: Network topology has changed. TTL: %i Expected ip: %s Got ip: %s Will do a new traceroute."), lastCommonTTL, (LPCTSTR)lastCommonHostAddressString, (LPCTSTR)destinationAddressString); restart = true; } - raw_ping = (uint32)pingStatus.delay; - - if (pingFailure) { - // only several pings in row should fails, the total doesn't count, so reset for each successful ping - pingFailure = false; - - //theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Ping #%i successful. Continuing."), pingTries); - } + raw_ping = (uint32)pingStatus.fDelay; + // several pings in a row may fail, but the count doesn't matter + // so reset after every successful ping + pingFailure = false; } else { raw_ping = (soll_ping + initial_ping) * 3; // this value will cause the upload speed to be lowered pingFailure = true; - if (!m_enabled) - enabled = false; - else if (pingTries > 3) - prefsEvent->Lock(SEC2MS(1)); + if (m_enabled && pingTries > 3) + m_eventPrefs.Lock(SEC2MS(1)); //theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: %s-Ping #%i failed. Reason follows"), useUdp?_T("UDP"):_T("ICMP"), pingTries); //pinger.PIcmpErr(pingStatus.error); } - - if (!m_enabled) - enabled = false; } if (pingFailure) { @@ -759,13 +702,13 @@ UINT LastCommonRouteFinder::RunInternal() if (!restart) { if (raw_ping > 0 && raw_ping < initial_ping && initial_ping > lowestInitialPingAllowed) { theApp.QueueDebugLogLine(false, _T("UploadSpeedSense: New lowest ping: %i ms. Old: %i ms"), max(raw_ping, lowestInitialPingAllowed), initial_ping); - initial_ping = (uint32)max(raw_ping, lowestInitialPingAllowed); + initial_ping = max(raw_ping, lowestInitialPingAllowed); } - pingDelaysTotal += raw_ping; + m_pingDelaysTotal += raw_ping; pingDelays.AddTail(raw_ping); while (!pingDelays.IsEmpty() && (uint32)pingDelays.GetCount() > numberOfPingsForAverage) - pingDelaysTotal -= pingDelays.RemoveHead(); + m_pingDelaysTotal -= pingDelays.RemoveHead(); uint32 pingAverage = Median(pingDelays); //(pingDelaysTotal/pingDelays.GetCount()); int normalized_ping = pingAverage - initial_ping; @@ -791,7 +734,7 @@ UINT LastCommonRouteFinder::RunInternal() acceptNewClient = false; // lower the speed - sint64 ulDiff = hping * 1024 * 10 / (goingDownDivider * (sint64)initial_ping); + sint64 ulDiff = hping * 1024 * 10 / goingDownDivider / initial_ping; //theApp.QueueDebugLogLine(false,_T("UploadSpeedSense: Down! Ping cur %i ms. Ave %I64i ms %i values. New Upload %i + %I64i = %I64i"), raw_ping, pingDelaysTotal/pingDelays.GetCount(), pingDelays.GetCount(), upload, ulDiff, upload+ulDiff); // prevent underflow @@ -811,15 +754,13 @@ UINT LastCommonRouteFinder::RunInternal() } } prefsLocker.Lock(); - if (upload < minUpload) { - upload = minUpload; + if (upload < m_minUpload) { + upload = m_minUpload; acceptNewClient = true; } - if (upload > maxUpload) - upload = maxUpload; - + m_upload = upload = min(upload, m_maxUpload); prefsLocker.Unlock(); - SetUpload(upload); + if (!m_enabled) enabled = false; } @@ -828,7 +769,7 @@ UINT LastCommonRouteFinder::RunInternal() } // Signal that we have ended. - threadEndedEvent->SetEvent(); + m_eventThreadEnded.SetEvent(); return 0; } diff --git a/srchybrid/LastCommonRouteFinder.h b/srchybrid/LastCommonRouteFinder.h index aa75f5a8..17daf7ad 100644 --- a/srchybrid/LastCommonRouteFinder.h +++ b/srchybrid/LastCommonRouteFinder.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -22,18 +22,32 @@ typedef CTypedPtrList CUpDownClientPtrList; struct CurrentPingStruct { - //uint32 datalen; CString state; uint32 latency; uint32 lowest; uint32 currentLimit; }; +struct CurrentParamStruct +{ + double dPingTolerance; + uint32 uCurUpload; //bytes + uint32 uMinUpload; //kilobytes + uint32 uMaxUpload; //kilobytes + uint32 uPingToleranceMilliseconds; + uint32 uGoingUpDivider; + uint32 uGoingDownDivider; + uint32 uNumberOfPingsForAverage; + uint32 uLowestInitialPingAllowed; + bool bUseMillisecondPingTolerance; + bool bEnabled; +}; + class LastCommonRouteFinder : public CWinThread { public: LastCommonRouteFinder(); - ~LastCommonRouteFinder(); + ~LastCommonRouteFinder() = default; LastCommonRouteFinder(const LastCommonRouteFinder&) = delete; LastCommonRouteFinder& operator=(const LastCommonRouteFinder&) = delete; @@ -46,15 +60,14 @@ class LastCommonRouteFinder : public CWinThread CurrentPingStruct GetCurrentPing(); bool AcceptNewClient(); - void SetPrefs(bool pEnabled, uint32 pCurUpload, uint32 pMinUpload, uint32 pMaxUpload, bool pUseMillisecondPingTolerance, double pPingTolerance, uint32 pPingToleranceMilliseconds, uint32 pGoingUpDivider, uint32 pGoingDownDivider, uint32 pNumberOfPingsForAverage, uint64 pLowestInitialPingAllowed); + bool SetPrefs(const CurrentParamStruct &cur); void InitiateFastReactionPeriod(); - uint32 GetUpload() const; + uint32 GetUpload() const { return m_upload; } private: static UINT AFX_CDECL RunProc(LPVOID pParam); UINT RunInternal(); - void SetUpload(uint32 newValue); bool AddHostToCheck(uint32 ip); bool AddHostToCheckNoLock(uint32 ip); @@ -65,20 +78,22 @@ class LastCommonRouteFinder : public CWinThread CCriticalSection prefsLocker; CCriticalSection pingLocker; - CEvent *threadEndedEvent; - CEvent *newTraceRouteHostEvent; - CEvent *prefsEvent; + CEvent m_eventThreadEnded; + CEvent m_eventNewTraceRouteHost; + CEvent m_eventPrefs; - CMap hostsToTraceRoute; + typedef CMap CHostsToTraceRouteMap; + CHostsToTraceRouteMap hostsToTraceRoute; UInt32Clist pingDelays; double m_pingTolerance; - uint64 pingDelaysTotal; - uint64 m_LowestInitialPingAllowed; + uint64 m_pingDelaysTotal; + uint32 m_LowestInitialPingAllowed; - uint32 minUpload; - uint32 maxUpload; + // all values in bytes + uint32 m_minUpload; + uint32 m_maxUpload; uint32 m_CurUpload; uint32 m_upload; @@ -89,11 +104,11 @@ class LastCommonRouteFinder : public CWinThread uint32 m_pingAverage; uint32 m_lowestPing; - UINT m_uState; + UINT m_uState; - volatile bool doRun; + volatile CHAR m_initiateFastReactionPeriod; + volatile bool m_bRun; bool m_enabled; - bool m_initiateFastReactionPeriod; bool m_bUseMillisecondPingTolerance; bool acceptNewClient; bool needMoreHosts; diff --git a/srchybrid/LayeredWindowHelperST.cpp b/srchybrid/LayeredWindowHelperST.cpp index f540f34b..dbad9f4a 100644 --- a/srchybrid/LayeredWindowHelperST.cpp +++ b/srchybrid/LayeredWindowHelperST.cpp @@ -8,11 +8,6 @@ static char THIS_FILE[] = __FILE__; #endif -CLayeredWindowHelperST::CLayeredWindowHelperST() -{ - m_hDll = GetModuleHandle(_T("user32")); -} - // This function adds the WS_EX_LAYERED style to the specified window. // // Parameters: @@ -51,40 +46,6 @@ LONG_PTR CLayeredWindowHelperST::RemoveLayeredStyle(HWND hWnd) return ::SetWindowLongPtr(hWnd, GWL_EXSTYLE, ::GetWindowLongPtr(hWnd, GWL_EXSTYLE) & ~WS_EX_LAYERED); } // End of RemoveLayeredStyle -// This function sets the opacity and transparency color key of a layered window. -// -// Parameters: -// [IN] hWnd -// Handle to the layered window. -// [IN] crKey -// A COLORREF value that specifies the transparency color key to be used when -// composing the layered window. All pixels painted by the window in this color will be transparent. -// To generate a COLORREF, use the RGB() macro. -// [IN] bAlpha -// Alpha value used to describe the opacity of the layered window. -// When bAlpha is 0, the window is completely transparent. -// When bAlpha is 255, the window is opaque. -// [IN] dwFlags -// Specifies an action to take. This parameter can be one or more of the following values: -// LWA_COLORKEY Use crKey as the transparency color. -// LWA_ALPHA Use bAlpha to determine the opacity of the layered window. -// -// Return value: -// TRUE -// Function executed successfully. -// FALSE -// Function failed. To get extended error information, call ::GetLastError(). -// -BOOL CLayeredWindowHelperST::SetLayeredWindowAttributes(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags) -{ - if (m_hDll) { - lpfnSetLayeredWindowAttributes pFn = (lpfnSetLayeredWindowAttributes)GetProcAddress(m_hDll, "SetLayeredWindowAttributes"); - if (pFn) - return pFn(hWnd, crKey, bAlpha, dwFlags); - } - return FALSE; -} // End of SetLayeredWindowAttributes - // This function sets the percentage of opacity or transparency of a layered window. // // Parameters: @@ -102,7 +63,8 @@ BOOL CLayeredWindowHelperST::SetLayeredWindowAttributes(HWND hWnd, COLORREF crKe BOOL CLayeredWindowHelperST::SetTransparentPercentage(HWND hWnd, UINT byPercentage) { // Do not accept values greater than 100% - if (byPercentage > 100) byPercentage = 100; + if (byPercentage > 100) + byPercentage = 100; - return SetLayeredWindowAttributes(hWnd, 0, (BYTE)(255 * byPercentage / 100), LWA_ALPHA); + return ::SetLayeredWindowAttributes(hWnd, 0, (BYTE)(255 * byPercentage / 100), LWA_ALPHA); } // End of SetTransparentPercentage \ No newline at end of file diff --git a/srchybrid/LayeredWindowHelperST.h b/srchybrid/LayeredWindowHelperST.h index b03aba46..74164e49 100644 --- a/srchybrid/LayeredWindowHelperST.h +++ b/srchybrid/LayeredWindowHelperST.h @@ -35,19 +35,13 @@ class CLayeredWindowHelperST { public: - CLayeredWindowHelperST(); - virtual ~CLayeredWindowHelperST() = default; + CLayeredWindowHelperST() = default; + ~CLayeredWindowHelperST() = default; static LONG_PTR AddLayeredStyle(HWND hWnd); static LONG_PTR RemoveLayeredStyle(HWND hWnd); - BOOL SetLayeredWindowAttributes(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags); - BOOL SetTransparentPercentage(HWND hWnd, UINT byPercentage); + static BOOL SetTransparentPercentage(HWND hWnd, UINT byPercentage); static short GetVersionI() { return 11; } static LPCTSTR GetVersionC() { return (LPCTSTR)_T("1.1"); } - -private: - typedef BOOL(WINAPI *lpfnSetLayeredWindowAttributes)(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags); - - HMODULE m_hDll; }; \ No newline at end of file diff --git a/srchybrid/ListBoxST.cpp b/srchybrid/ListBoxST.cpp index f7a7a69f..1d0597a6 100644 --- a/srchybrid/ListBoxST.cpp +++ b/srchybrid/ListBoxST.cpp @@ -18,12 +18,10 @@ static char THIS_FILE[] = __FILE__; #define LBST_CY_BORDER 2 CListBoxST::CListBoxST() + : m_pImageList() // No image list associated + , m_szImage() { - // No image list associated - m_pImageList = NULL; - memset(&m_szImage, 0, sizeof m_szImage); - - // By default, highlight full list box item + // By default, highlight the whole list box item SetRowSelect(ST_FULLROWSELECT, FALSE); } diff --git a/srchybrid/ListBoxST.h b/srchybrid/ListBoxST.h index 3e9eb08f..d06be56e 100644 --- a/srchybrid/ListBoxST.h +++ b/srchybrid/ListBoxST.h @@ -36,7 +36,6 @@ class CListBoxST : public CListBox { public: CListBoxST(); - virtual ~CListBoxST() = default; enum { @@ -87,9 +86,9 @@ class CListBoxST : public CListBox virtual DWORD OnDrawIconBackground(int nIndex, CDC *pDC, const CRect &prcItem, const CRect &prcIcon, BOOL bIsDisabled, BOOL bIsSelected, COLORREF crSuggestedColor); virtual DWORD OnDrawIcon(int /*nIndex*/, CDC *pDC, LPCRECT /*prcItem*/, LPCRECT prcIcon, int nImage, BOOL bIsDisabled, BOOL bIsSelected); - BYTE m_byRowSelect; CImageList *m_pImageList; SIZE m_szImage; // Size of each image in image list + BYTE m_byRowSelect; private: virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct); diff --git a/srchybrid/ListCtrlItemWalk.h b/srchybrid/ListCtrlItemWalk.h index 64a577a5..9232c9b7 100644 --- a/srchybrid/ListCtrlItemWalk.h +++ b/srchybrid/ListCtrlItemWalk.h @@ -11,6 +11,6 @@ class CListCtrlItemWalk CListCtrl* GetListCtrl() const { return m_pListCtrl; } protected: - virtual ~CListCtrlItemWalk() = default; //just in case... + virtual ~CListCtrlItemWalk() = default; CListCtrl *m_pListCtrl; }; \ No newline at end of file diff --git a/srchybrid/ListCtrlX.cpp b/srchybrid/ListCtrlX.cpp index 1c95cc00..6216d9da 100644 --- a/srchybrid/ListCtrlX.cpp +++ b/srchybrid/ListCtrlX.cpp @@ -41,7 +41,7 @@ CListCtrlX::CListCtrlX() , m_hAccel() , m_uIDHdrImgList(UINT_MAX) , m_iHdrImgListImages() - , m_iFindDirection(1) + , m_iFindDirection(1) //1 - down, -1 - up , m_iFindColumn() , m_iSortColumn(-1) , m_bUseHdrCtrlSortBitmaps() @@ -74,8 +74,10 @@ void CListCtrlX::ReadColumnStats(int iColumns, LCX_COLUMN_INIT *pColumns, LPCTST void ReadColumnStats(int iColumns, LCX_COLUMN_INIT *pColumns, LPCTSTR pszSection, LPCTSTR pszPrefix) { + CString sKeyName; for (int iCol = 0; iCol < iColumns; ++iCol) { - DWORD dwVal = theApp.GetProfileInt(pszSection, CString(pszPrefix) + pColumns[iCol].pszHeading, -1); + sKeyName.Format(_T("%s%s"), pszPrefix, pColumns[iCol].pszHeading); + DWORD dwVal = theApp.GetProfileInt(pszSection, sKeyName, -1); if (dwVal != _UI32_MAX) { pColumns[iCol].iWidth = (short)LOWORD(dwVal); if ((pColumns[iCol].iOrder = (short)HIWORD(dwVal)) < 0) @@ -100,12 +102,14 @@ void CListCtrlX::WriteColumnStats(int iColumns, const LCX_COLUMN_INIT *pColumns, void WriteColumnStats(CListCtrl &lv, int iColumns, const LCX_COLUMN_INIT *pColumns, LPCTSTR pszSection, LPCTSTR pszPrefix) { + CString sKeyName; for (int iCol = 0; iCol < iColumns; ++iCol) { LVCOLUMN lvc; lvc.mask = LVCF_WIDTH | LVCF_ORDER; if (lv.GetColumn(iCol, &lvc) && (lvc.cx != pColumns[iCol].iWidth || lvc.iOrder != pColumns[iCol].iOrder)) { + sKeyName.Format(_T("%s%s"), pszPrefix, pColumns[iCol].pszHeading); DWORD dwVal = MAKELONG(lvc.cx, lvc.iOrder); - theApp.WriteProfileInt(pszSection, CString(pszPrefix) + pColumns[iCol].pszHeading, dwVal); + theApp.WriteProfileInt(pszSection, sKeyName, dwVal); } } } @@ -528,7 +532,7 @@ void CreateItemReport(CListCtrl &lv, CString &rstrReport) // Get max. chars per column int *paiColWidths; try { - paiColWidths = new int[iCols](); + paiColWidths = new int[iCols]{}; } catch (...) { return; } @@ -673,7 +677,7 @@ bool CListCtrlX::FindItem(const CListCtrlX &lv, int iItem, DWORD_PTR) return false; } -void CListCtrlX::DoFind(int iStartItem, int iDirection /*1=down, 0 = up*/, BOOL bShowError) +void CListCtrlX::DoFind(int iStartItem, int iDirection /*1 = down, -1 = up*/, BOOL bShowError) { CWaitCursor curHourglass; @@ -682,9 +686,9 @@ void CListCtrlX::DoFind(int iStartItem, int iDirection /*1=down, 0 = up*/, BOOL return; } - int iNumItems = iDirection ? GetItemCount() : 0; + int iNumItems = (iDirection > 0) ? GetItemCount() : 0; int iItem = iStartItem; - while (iDirection ? iItem < iNumItems : iItem >= 0) { + while ((iDirection > 0) ? iItem < iNumItems : iItem >= 0) { if ((*m_pfnFindItem)(*this, iItem, m_lFindItemParam)) { // Deselect all listview entries DeselectAllItems(); @@ -698,10 +702,7 @@ void CListCtrlX::DoFind(int iStartItem, int iDirection /*1=down, 0 = up*/, BOOL return; } - if (iDirection) - ++iItem; - else - --iItem; + iItem += iDirection; } if (bShowError) @@ -732,20 +733,20 @@ void CListCtrlX::OnFindNext() void CListCtrlX::DoFindNext(BOOL bShowError) { int iStartItem = GetNextItem(-1, LVNI_SELECTED | LVNI_FOCUSED); - if (iStartItem == -1) + if (iStartItem < 0) iStartItem = 0; else - iStartItem += (m_iFindDirection ? 1 : -1); + iStartItem += m_iFindDirection; DoFind(iStartItem, m_iFindDirection, bShowError); } void CListCtrlX::OnFindPrev() { int iStartItem = GetNextItem(-1, LVNI_SELECTED | LVNI_FOCUSED); - if (iStartItem == -1) + if (iStartItem < 0) iStartItem = 0; else - iStartItem += (!m_iFindDirection ? 1 : -1); + iStartItem -= m_iFindDirection; - DoFind(iStartItem, !m_iFindDirection, FALSE/*bShowError*/); -} + DoFind(iStartItem, -m_iFindDirection, FALSE/*bShowError*/); +} \ No newline at end of file diff --git a/srchybrid/ListCtrlX.h b/srchybrid/ListCtrlX.h index cfbd5c75..aa1f6ac5 100644 --- a/srchybrid/ListCtrlX.h +++ b/srchybrid/ListCtrlX.h @@ -59,7 +59,6 @@ class CListCtrlX : public CListCtrl // Construction public: CListCtrlX(); - virtual ~CListCtrlX() = default; // Attributes public: diff --git a/srchybrid/ListViewSearchDlg.cpp b/srchybrid/ListViewSearchDlg.cpp index a8b5298b..c02011e7 100644 --- a/srchybrid/ListViewSearchDlg.cpp +++ b/srchybrid/ListViewSearchDlg.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -90,7 +90,7 @@ BOOL CListViewSearchDlg::OnInitDialog() int iCol = 0; while (m_pListView->GetColumn(iCol++, &lvc)) { szColTitle[_countof(szColTitle) - 1] = _T('\0'); - m_ctlSearchCol.AddString(lvc.pszText); + m_ctlSearchCol.AddString(szColTitle); if (!m_bCanSearchInAllColumns) break; } diff --git a/srchybrid/ListViewWalkerPropertySheet.cpp b/srchybrid/ListViewWalkerPropertySheet.cpp index 50d5c3d2..523f1a09 100644 --- a/srchybrid/ListViewWalkerPropertySheet.cpp +++ b/srchybrid/ListViewWalkerPropertySheet.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -158,7 +158,7 @@ BOOL CListViewWalkerPropertySheet::OnInitDialog() for (unsigned i = 0; i < _countof(aCtrls); ++i) { RECT rc; - rc.left = rcOk.left - (8 + iNaviBtnWidth) * (_countof(aCtrls) - i); + rc.left = (LONG)(rcOk.left - (8 + iNaviBtnWidth) * (_countof(aCtrls) - i)); rc.top = rcOk.top; rc.right = rc.left + iNaviBtnWidth; rc.bottom = rc.top + rcOk.Height(); diff --git a/srchybrid/ListenSocket.cpp b/srchybrid/ListenSocket.cpp index 8feb2ed0..9a2c5ff5 100644 --- a/srchybrid/ListenSocket.cpp +++ b/srchybrid/ListenSocket.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -22,7 +22,6 @@ #include "opcodes.h" #include "UpDownClient.h" #include "ClientList.h" -#include "OtherFunctions.h" #include "DownloadQueue.h" #include "Statistics.h" #include "IPFilter.h" @@ -73,23 +72,23 @@ void CClientReqSocket::SetConState(SocketState val) //If no change, do nothing. if ((uint32)val == m_nOnConnect) return; - //Decrease count of old state. + //Decrease count for the old state switch (m_nOnConnect) { case SS_Half: - theApp.listensocket->m_nHalfOpen--; + --theApp.listensocket->m_nHalfOpen; break; case SS_Complete: - theApp.listensocket->m_nComp--; + --theApp.listensocket->m_nComp; } - //Set state to new state. + //Set the new state m_nOnConnect = val; - //Increase count of new state. + //Increase count for the new state switch (m_nOnConnect) { case SS_Half: - theApp.listensocket->m_nHalfOpen++; + ++theApp.listensocket->m_nHalfOpen; break; case SS_Complete: - theApp.listensocket->m_nComp++; + ++theApp.listensocket->m_nComp; } } @@ -144,15 +143,15 @@ DWORD CClientReqSocket::GetTimeOut() const bool CClientReqSocket::CheckTimeOut() { - DWORD tNow = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); if (m_nOnConnect == SS_Half) { //This socket is still in a half connection state. Because of SP2, we don't know //if this socket is actually failing, or if this socket is just queued in SP2's new //protection queue. Therefore we give the socket a chance to either finally report //the connection error, or finally make it through SP2's new queued socket system. - if (tNow < timeout_timer + CEMSocket::GetTimeOut() * 4) + if (curTick < timeout_timer + CEMSocket::GetTimeOut() * 4) return false; - timeout_timer = tNow; + timeout_timer = curTick; CString str; str.Format(_T("Timeout: State:%u = SS_Half"), m_nOnConnect); Disconnect(str); @@ -162,16 +161,16 @@ bool CClientReqSocket::CheckTimeOut() if (client) if (client->GetKadState() == KS_CONNECTED_BUDDY) uTimeout += MIN2MS(15); - else if (client->IsDownloading() && tNow < client->GetUpStartTime() + 4 * CONNECTION_TIMEOUT) + else if (client->IsDownloading() && curTick < client->GetUpStartTime() + 4 * CONNECTION_TIMEOUT) //TCP flow control might need more time to begin throttling for slow peers uTimeout += 4 * CONNECTION_TIMEOUT; //2'30" or slightly more else if (client->GetChatState() != MS_NONE) //We extend the timeout time here to avoid chatting people from disconnecting too fast. uTimeout += CONNECTION_TIMEOUT; - if (tNow < timeout_timer + uTimeout) + if (curTick < timeout_timer + uTimeout) return false; - timeout_timer = tNow; + timeout_timer = curTick; CString str; str.Format(_T("Timeout: State:%u (0 = SS_Other, 1 = SS_Half, 2 = SS_Complete)"), m_nOnConnect); Disconnect(str); @@ -233,1608 +232,1528 @@ void CClientReqSocket::Safe_Delete() bool CClientReqSocket::ProcessPacket(const BYTE *packet, uint32 size, UINT opcode) { - try { - try { - if (client) { - if (opcode != OP_HELLO && opcode != OP_HELLOANSWER) - client->CheckHandshakeFinished(); - } else if (opcode != OP_HELLO) { - theStats.AddDownDataOverheadOther(size); - throw GetResString(IDS_ERR_NOHELLO); - } + switch (opcode) { + case OP_HELLOANSWER: + theStats.AddDownDataOverheadOther(size); + client->ProcessHelloAnswer(packet, size); + if (thePrefs.GetDebugClientTCPLevel() > 0) { + DebugRecv("OP_HelloAnswer", client); + Debug(_T(" %s\n"), (LPCTSTR)client->DbgGetClientInfo()); + } - switch (opcode) { - case OP_HELLOANSWER: - theStats.AddDownDataOverheadOther(size); - client->ProcessHelloAnswer(packet, size); - if (thePrefs.GetDebugClientTCPLevel() > 0) { - DebugRecv("OP_HelloAnswer", client); - Debug(_T(" %s\n"), (LPCTSTR)client->DbgGetClientInfo()); - } + // start secure identification, if + // - we have received OP_EMULEINFO and OP_HELLOANSWER (old eMule) + // - we have received eMule-OP_HELLOANSWER (new eMule) + if (client->GetInfoPacketsReceived() == IP_BOTH) + client->InfoPacketsReceived(); - // start secure identification, if - // - we have received OP_EMULEINFO and OP_HELLOANSWER (old eMule) - // - we have received eMule-OP_HELLOANSWER (new eMule) - if (client->GetInfoPacketsReceived() == IP_BOTH) - client->InfoPacketsReceived(); - - if (client) { - client->ConnectionEstablished(); - theApp.emuledlg->transferwnd->GetClientList()->RefreshClient(client); + if (client) { + client->ConnectionEstablished(); + theApp.emuledlg->transferwnd->GetClientList()->RefreshClient(client); + } + break; + case OP_HELLO: + { + theStats.AddDownDataOverheadOther(size); + + bool bNewClient = !client; + if (bNewClient) + // create new client to save standard information + client = new CUpDownClient(this); + + bool bIsMuleHello; + try { + bIsMuleHello = client->ProcessHelloPacket(packet, size); + } catch (...) { + if (bNewClient) { + // Don't let CUpDownClient::Disconnected process a client which is not in the list of clients. + delete client; + client = NULL; } - break; - case OP_HELLO: - { - theStats.AddDownDataOverheadOther(size); - - bool bNewClient = !client; - if (bNewClient) - // create new client to save standard information - client = new CUpDownClient(this); - - bool bIsMuleHello; - try { - bIsMuleHello = client->ProcessHelloPacket(packet, size); - } catch (...) { - if (bNewClient) { - // Don't let CUpDownClient::Disconnected be processed for a client which is not in the list of clients. - delete client; - client = NULL; - } - throw; - } + throw; + } - if (thePrefs.GetDebugClientTCPLevel() > 0) { - DebugRecv("OP_Hello", client); - Debug(_T(" %s\n"), (LPCTSTR)client->DbgGetClientInfo()); - } + if (thePrefs.GetDebugClientTCPLevel() > 0) { + DebugRecv("OP_Hello", client); + Debug(_T(" %s\n"), (LPCTSTR)client->DbgGetClientInfo()); + } - // now we check if we know this client already. if yes this socket will - // be attached to the known client, the new client will be deleted - // and the var. "client" will point to the known client. - // if not we keep our new-constructed client ;) - if (theApp.clientlist->AttachToAlreadyKnown(&client, this)) - // update the old client informations - bIsMuleHello = client->ProcessHelloPacket(packet, size); - else { - theApp.clientlist->AddClient(client); - client->SetCommentDirty(); - } + // now we check if we know this client already. if yes this socket will + // be attached to the known client, the new client will be deleted + // and the var. "client" will point to the known client. + // if not we keep our new-constructed client ;) + if (theApp.clientlist->AttachToAlreadyKnown(&client, this)) + // update the old client informations + bIsMuleHello = client->ProcessHelloPacket(packet, size); + else { + theApp.clientlist->AddClient(client); + client->SetCommentDirty(); + } - theApp.emuledlg->transferwnd->GetClientList()->RefreshClient(client); + theApp.emuledlg->transferwnd->GetClientList()->RefreshClient(client); - // send a response packet with standard informations - if (client->GetHashType() == SO_EMULE && !bIsMuleHello) - client->SendMuleInfoPacket(false); + // send a response packet with standard informations + if (client->GetHashType() == SO_EMULE && !bIsMuleHello) + client->SendMuleInfoPacket(false); - client->SendHelloAnswer(); + client->SendHelloAnswer(); - if (client) - client->ConnectionEstablished(); + if (client) + client->ConnectionEstablished(); - ASSERT(client); - if (client) { - // start secure identification, if - // - we have received eMule-OP_HELLO (new eMule) - if (client->GetInfoPacketsReceived() == IP_BOTH) - client->InfoPacketsReceived(); + ASSERT(client); + if (client) { + // start secure identification, if + // - we have received eMule-OP_HELLO (new eMule) + if (client->GetInfoPacketsReceived() == IP_BOTH) + client->InfoPacketsReceived(); - if (client->GetKadPort() && client->GetKadVersion() >= KADEMLIA_VERSION2_47a) - Kademlia::CKademlia::Bootstrap(ntohl(client->GetIP()), client->GetKadPort()); + if (client->GetKadPort() && client->GetKadVersion() >= KADEMLIA_VERSION2_47a) + Kademlia::CKademlia::Bootstrap(ntohl(client->GetIP()), client->GetKadPort()); + } + } + break; + case OP_REQUESTFILENAME: + { + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_FileRequest", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadFileRequest(size); + + if (size >= 16) { + if (!client->GetWaitStartTime()) + client->SetWaitStartTime(); + + CSafeMemFile data_in(packet, size); + uchar reqfilehash[MDX_DIGEST_SIZE]; + data_in.ReadHash16(reqfilehash); + + CKnownFile *reqfile = theApp.sharedfiles->GetFileByID(reqfilehash); + if (reqfile == NULL) { + reqfile = theApp.downloadqueue->GetFileByID(reqfilehash); + if (reqfile == NULL || (uint64)((CPartFile*)reqfile)->GetCompletedSize() < PARTSIZE) { + client->CheckFailedFileIdReqs(reqfilehash); + break; } } - break; - case OP_REQUESTFILENAME: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_FileRequest", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadFileRequest(size); - - if (size >= 16) { - if (!client->GetWaitStartTime()) - client->SetWaitStartTime(); - - CSafeMemFile data_in(packet, size); - uchar reqfilehash[MDX_DIGEST_SIZE]; - data_in.ReadHash16(reqfilehash); - - CKnownFile *reqfile = theApp.sharedfiles->GetFileByID(reqfilehash); - if (reqfile == NULL) { - reqfile = theApp.downloadqueue->GetFileByID(reqfilehash); - if (reqfile == NULL || (uint64)((CPartFile*)reqfile)->GetCompletedSize() < PARTSIZE) { - client->CheckFailedFileIdReqs(reqfilehash); - break; - } - } - - if (reqfile->IsLargeFile() && !client->SupportsLargeFiles()) { - DebugLogWarning(_T("Client without 64bit file support requested large file; %s, File=\"%s\""), (LPCTSTR)client->DbgGetClientInfo(), (LPCTSTR)reqfile->GetFileName()); - break; - } - - // check to see if this is a new file they are asking for - if (!md4equ(client->GetUploadFileID(), reqfilehash)) - client->SetCommentDirty(); - client->SetUploadFileID(reqfile); - - if (!client->ProcessExtendedInfo(&data_in, reqfile)) { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_FileReqAnsNoFil", client, packet); - Packet *replypacket = new Packet(OP_FILEREQANSNOFIL, 16); - md4cpy(replypacket->pBuffer, reqfile->GetFileHash()); - theStats.AddUpDataOverheadFileRequest(replypacket->size); - SendPacket(replypacket); - DebugLogWarning(_T("Partcount mismatch on requested file, sending FNF; %s, File=\"%s\""), (LPCTSTR)client->DbgGetClientInfo(), (LPCTSTR)reqfile->GetFileName()); - break; - } - // if we are downloading this file, this could be a new source - // no passive adding of files with only one part - if (reqfile->IsPartFile() && (uint64)reqfile->GetFileSize() > PARTSIZE) - if (static_cast(reqfile)->GetMaxSources() > static_cast(reqfile)->GetSourceCount()) - theApp.downloadqueue->CheckAndAddKnownSource(static_cast(reqfile), client, true); + if (reqfile->IsLargeFile() && !client->SupportsLargeFiles()) { + DebugLogWarning(_T("Client without 64bit file support requested large file; %s, File=\"%s\""), (LPCTSTR)client->DbgGetClientInfo(), (LPCTSTR)reqfile->GetFileName()); + break; + } - // send filename etc - CSafeMemFile data_out(128); - data_out.WriteHash16(reqfile->GetFileHash()); - data_out.WriteString(reqfile->GetFileName(), client->GetUnicodeSupport()); - Packet *packet1 = new Packet(&data_out); - packet1->opcode = OP_REQFILENAMEANSWER; - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_FileReqAnswer", client, reqfile->GetFileHash()); - theStats.AddUpDataOverheadFileRequest(packet1->size); - SendPacket(packet1); + // check to see if this is a new file they are asking for + if (!md4equ(client->GetUploadFileID(), reqfilehash)) + client->SetCommentDirty(); + client->SetUploadFileID(reqfile); - client->SendCommentInfo(reqfile); - break; - } - } - throw GetResString(IDS_ERR_WRONGPACKETSIZE); - case OP_SETREQFILEID: - { + if (!client->ProcessExtendedInfo(&data_in, reqfile)) { if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_SetReqFileID", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadFileRequest(size); - - if (size == 16) { - if (!client->GetWaitStartTime()) - client->SetWaitStartTime(); - - CKnownFile *reqfile = theApp.sharedfiles->GetFileByID(packet); - if (reqfile == NULL) { - reqfile = theApp.downloadqueue->GetFileByID(packet); - if (reqfile == NULL) - break; - if (reqfile->GetFileSize() > PARTSIZE) { - // send file request no such file packet (0x48) - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_FileReqAnsNoFil", client, packet); - Packet *replypacket = new Packet(OP_FILEREQANSNOFIL, 16); - md4cpy(replypacket->pBuffer, packet); - theStats.AddUpDataOverheadFileRequest(replypacket->size); - SendPacket(replypacket); - client->CheckFailedFileIdReqs(packet); - break; - } - } - if (reqfile->IsLargeFile() && !client->SupportsLargeFiles()) { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_FileReqAnsNoFil", client, packet); - Packet *replypacket = new Packet(OP_FILEREQANSNOFIL, 16); - md4cpy(replypacket->pBuffer, packet); - theStats.AddUpDataOverheadFileRequest(replypacket->size); - SendPacket(replypacket); - DebugLogWarning(_T("Client without 64bit file support requested large file; %s, File=\"%s\""), (LPCTSTR)client->DbgGetClientInfo(), (LPCTSTR)reqfile->GetFileName()); - break; - } + DebugSend("OP_FileReqAnsNoFil", client, packet); + Packet *replypacket = new Packet(OP_FILEREQANSNOFIL, 16); + md4cpy(replypacket->pBuffer, reqfile->GetFileHash()); + theStats.AddUpDataOverheadFileRequest(replypacket->size); + SendPacket(replypacket); + DebugLogWarning(_T("Partcount mismatch on requested file, sending FNF; %s, File=\"%s\""), (LPCTSTR)client->DbgGetClientInfo(), (LPCTSTR)reqfile->GetFileName()); + break; + } - // check to see if this is a new file they are asking for - if (!md4equ(client->GetUploadFileID(), packet)) - client->SetCommentDirty(); + // if we are downloading this file, this could be a new source + // no passive adding of files with only one part + if (reqfile->IsPartFile() && (uint64)reqfile->GetFileSize() > PARTSIZE) + if (static_cast(reqfile)->GetMaxSources() > static_cast(reqfile)->GetSourceCount()) + theApp.downloadqueue->CheckAndAddKnownSource(static_cast(reqfile), client, true); + + // send filename etc + CSafeMemFile data_out(128); + data_out.WriteHash16(reqfile->GetFileHash()); + data_out.WriteString(reqfile->GetFileName(), client->GetUnicodeSupport()); + Packet *packet1 = new Packet(data_out); + packet1->opcode = OP_REQFILENAMEANSWER; + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugSend("OP_FileReqAnswer", client, reqfile->GetFileHash()); + theStats.AddUpDataOverheadFileRequest(packet1->size); + SendPacket(packet1); - client->SetUploadFileID(reqfile); + client->SendCommentInfo(reqfile); + break; + } + } + throw GetResString(IDS_ERR_WRONGPACKETSIZE); + case OP_SETREQFILEID: + { + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_SetReqFileID", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadFileRequest(size); - // send file status - CSafeMemFile data(16 + 16); - data.WriteHash16(reqfile->GetFileHash()); - if (reqfile->IsPartFile()) - static_cast(reqfile)->WritePartStatus(&data); - else - data.WriteUInt16(0); - Packet *packet2 = new Packet(&data); - packet2->opcode = OP_FILESTATUS; - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_FileStatus", client, reqfile->GetFileHash()); - theStats.AddUpDataOverheadFileRequest(packet2->size); - SendPacket(packet2); + if (size == 16) { + if (!client->GetWaitStartTime()) + client->SetWaitStartTime(); + + CKnownFile *reqfile = theApp.sharedfiles->GetFileByID(packet); + if (reqfile == NULL) { + reqfile = theApp.downloadqueue->GetFileByID(packet); + if (reqfile == NULL) break; - } - } - throw GetResString(IDS_ERR_WRONGPACKETSIZE); - case OP_FILEREQANSNOFIL: - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_FileReqAnsNoFil", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadFileRequest(size); - if (size == 16) { - CPartFile *rqfile = theApp.downloadqueue->GetFileByID(packet); - if (!rqfile) { + if (reqfile->GetFileSize() > PARTSIZE) { + // send file request no such file packet (0x48) + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugSend("OP_FileReqAnsNoFil", client, packet); + Packet *replypacket = new Packet(OP_FILEREQANSNOFIL, 16); + md4cpy(replypacket->pBuffer, packet); + theStats.AddUpDataOverheadFileRequest(replypacket->size); + SendPacket(replypacket); client->CheckFailedFileIdReqs(packet); break; } - rqfile->m_DeadSourceList.AddDeadSource(client); - // if that client does not have my file maybe has another different - // we try to swap to another file ignoring no needed parts files - switch (client->GetDownloadState()) { - case DS_CONNECTED: - case DS_ONQUEUE: - case DS_NONEEDEDPARTS: - client->DontSwapTo(rqfile); // ZZ:DownloadManager - if (!client->SwapToAnotherFile(_T("Source says it doesn't have the file. CClientReqSocket::ProcessPacket()"), true, true, true, NULL, false, false)) // ZZ:DownloadManager - theApp.downloadqueue->RemoveSource(client); - } - break; } - throw GetResString(IDS_ERR_WRONGPACKETSIZE); - case OP_REQFILENAMEANSWER: - { + if (reqfile->IsLargeFile() && !client->SupportsLargeFiles()) { if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_FileReqAnswer", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadFileRequest(size); - - CSafeMemFile data(packet, size); - uchar cfilehash[MDX_DIGEST_SIZE]; - data.ReadHash16(cfilehash); - CPartFile *file = theApp.downloadqueue->GetFileByID(cfilehash); - if (file == NULL) - client->CheckFailedFileIdReqs(cfilehash); - client->ProcessFileInfo(&data, file); - } - break; - case OP_FILESTATUS: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_FileStatus", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadFileRequest(size); - - CSafeMemFile data(packet, size); - uchar cfilehash[MDX_DIGEST_SIZE]; - data.ReadHash16(cfilehash); - CPartFile *file = theApp.downloadqueue->GetFileByID(cfilehash); - if (file == NULL) - client->CheckFailedFileIdReqs(cfilehash); - client->ProcessFileStatus(false, &data, file); - } - break; - case OP_STARTUPLOADREQ: - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_StartUpLoadReq", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadFileRequest(size); - - if (!client->CheckHandshakeFinished()) + DebugSend("OP_FileReqAnsNoFil", client, packet); + Packet *replypacket = new Packet(OP_FILEREQANSNOFIL, 16); + md4cpy(replypacket->pBuffer, packet); + theStats.AddUpDataOverheadFileRequest(replypacket->size); + SendPacket(replypacket); + DebugLogWarning(_T("Client without 64bit file support requested large file; %s, File=\"%s\""), (LPCTSTR)client->DbgGetClientInfo(), (LPCTSTR)reqfile->GetFileName()); break; - if (size == 16) { - CKnownFile *reqfile = theApp.sharedfiles->GetFileByID(packet); - if (reqfile) { - if (!md4equ(client->GetUploadFileID(), packet)) - client->SetCommentDirty(); - client->SetUploadFileID(reqfile); - client->SendCommentInfo(reqfile); - theApp.uploadqueue->AddClientToQueue(client); - } else - client->CheckFailedFileIdReqs(packet); } - break; - case OP_QUEUERANK: - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_QueueRank", client); - theStats.AddDownDataOverheadFileRequest(size); - client->ProcessEdonkeyQueueRank(packet, size); - break; - case OP_ACCEPTUPLOADREQ: - if (thePrefs.GetDebugClientTCPLevel() > 0) { - DebugRecv("OP_AcceptUploadReq", client, (size >= 16) ? packet : NULL); - if (size > 0) - Debug(_T(" ***NOTE: Packet contains %u additional bytes\n"), size); - Debug(_T(" QR=%d\n"), client->IsRemoteQueueFull() ? UINT_MAX : client->GetRemoteQueueRank()); - } - theStats.AddDownDataOverheadFileRequest(size); - client->ProcessAcceptUpload(); - break; - case OP_REQUESTPARTS: - { - // see also OP_REQUESTPARTS_I64 - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_RequestParts", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadFileRequest(size); - - CSafeMemFile data(packet, size); - uchar reqfilehash[MDX_DIGEST_SIZE]; - data.ReadHash16(reqfilehash); - - uint32 auStartOffsets[3]; - auStartOffsets[0] = data.ReadUInt32(); - auStartOffsets[1] = data.ReadUInt32(); - auStartOffsets[2] = data.ReadUInt32(); - - uint32 auEndOffsets[3]; - auEndOffsets[0] = data.ReadUInt32(); - auEndOffsets[1] = data.ReadUInt32(); - auEndOffsets[2] = data.ReadUInt32(); - - if (thePrefs.GetDebugClientTCPLevel() > 0) { - Debug(_T(" Start1=%u End1=%u Size=%u\n"), auStartOffsets[0], auEndOffsets[0], auEndOffsets[0] - auStartOffsets[0]); - Debug(_T(" Start2=%u End2=%u Size=%u\n"), auStartOffsets[1], auEndOffsets[1], auEndOffsets[1] - auStartOffsets[1]); - Debug(_T(" Start3=%u End3=%u Size=%u\n"), auStartOffsets[2], auEndOffsets[2], auEndOffsets[2] - auStartOffsets[2]); - } + // check to see if this is a new file they are asking for + if (!md4equ(client->GetUploadFileID(), packet)) + client->SetCommentDirty(); - for (unsigned i = 0; i < _countof(auStartOffsets); ++i) - if (auEndOffsets[i] > auStartOffsets[i]) { - Requested_Block_Struct *reqblock = new Requested_Block_Struct; - reqblock->StartOffset = auStartOffsets[i]; - reqblock->EndOffset = auEndOffsets[i]; - md4cpy(reqblock->FileID, reqfilehash); - reqblock->transferred = 0; - client->AddReqBlock(reqblock, false); - } else if (thePrefs.GetVerbose() && (auEndOffsets[i] != 0 || auStartOffsets[i] != 0)) - DebugLogWarning(_T("Client requests invalid %u. file block %u-%u (%d bytes): %s"), i, auStartOffsets[i], auEndOffsets[i], auEndOffsets[i] - auStartOffsets[i], (LPCTSTR)client->DbgGetClientInfo()); + client->SetUploadFileID(reqfile); - client->AddReqBlock(NULL, true); - } - break; - case OP_CANCELTRANSFER: - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_CancelTransfer", client); - theStats.AddDownDataOverheadFileRequest(size); - theApp.uploadqueue->RemoveFromUploadQueue(client, _T("Remote client cancelled transfer.")); - break; - case OP_END_OF_DOWNLOAD: - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_EndOfDownload", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadFileRequest(size); - if (size >= 16 && md4equ(client->GetUploadFileID(), packet)) - theApp.uploadqueue->RemoveFromUploadQueue(client, _T("Remote client ended transfer.")); + // send file status + CSafeMemFile data(16 + 16); + data.WriteHash16(reqfile->GetFileHash()); + if (reqfile->IsPartFile()) + static_cast(reqfile)->WritePartStatus(data); else - client->CheckFailedFileIdReqs(packet); - break; - case OP_HASHSETREQUEST: - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_HashSetReq", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadFileRequest(size); - - if (size != 16) - throw GetResString(IDS_ERR_WRONGHPACKETSIZE); - client->SendHashsetPacket(packet, 16, false); - break; - case OP_HASHSETANSWER: + data.WriteUInt16(0); + Packet *packet2 = new Packet(data); + packet2->opcode = OP_FILESTATUS; if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_HashSetAnswer", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadFileRequest(size); - client->ProcessHashSet(packet, size, false); - break; - case OP_SENDINGPART: - { - // see also OP_SENDINGPART_I64 - if (thePrefs.GetDebugClientTCPLevel() > 1) - DebugRecv("OP_SendingPart", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadFileRequest(24); - CPartFile *creqfile = client->GetRequestFile(); - if (creqfile && !creqfile->IsStopped() && (creqfile->GetStatus() == PS_READY || creqfile->GetStatus() == PS_EMPTY)) { - client->ProcessBlockPacket(packet, size, false, false); - if (creqfile->IsStopped() || creqfile->GetStatus() == PS_PAUSED || creqfile->GetStatus() == PS_ERROR) { - client->SendCancelTransfer(); - client->SetDownloadState(creqfile->IsStopped() ? DS_NONE : DS_ONQUEUE); - } - } else { - client->SendCancelTransfer(); - client->SetDownloadState((creqfile == NULL || creqfile->IsStopped()) ? DS_NONE : DS_ONQUEUE); - } - } + DebugSend("OP_FileStatus", client, reqfile->GetFileHash()); + theStats.AddUpDataOverheadFileRequest(packet2->size); + SendPacket(packet2); break; - case OP_OUTOFPARTREQS: - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_OutOfPartReqs", client); - theStats.AddDownDataOverheadFileRequest(size); - if (client->GetDownloadState() == DS_DOWNLOADING) - client->SetDownloadState(DS_ONQUEUE, _T("The remote client decided to stop/complete the transfer (got OP_OutOfPartReqs).")); + } + } + throw GetResString(IDS_ERR_WRONGPACKETSIZE); + case OP_FILEREQANSNOFIL: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_FileReqAnsNoFil", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadFileRequest(size); + if (size == 16) { + CPartFile *rqfile = theApp.downloadqueue->GetFileByID(packet); + if (!rqfile) { + client->CheckFailedFileIdReqs(packet); break; - case OP_CHANGE_CLIENT_ID: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_ChangedClientID", client); - theStats.AddDownDataOverheadOther(size); + } + rqfile->m_DeadSourceList.AddDeadSource(*client); + // if that client does not have my file maybe has another different + // we try to swap to another file ignoring no needed parts files + switch (client->GetDownloadState()) { + case DS_CONNECTED: + case DS_ONQUEUE: + case DS_NONEEDEDPARTS: + client->DontSwapTo(rqfile); // ZZ:DownloadManager + if (!client->SwapToAnotherFile(_T("Source says it doesn't have the file. CClientReqSocket::ProcessPacket()"), true, true, true, NULL, false, false)) // ZZ:DownloadManager + theApp.downloadqueue->RemoveSource(client); + } + break; + } + throw GetResString(IDS_ERR_WRONGPACKETSIZE); + case OP_REQFILENAMEANSWER: + { + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_FileReqAnswer", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadFileRequest(size); + + CSafeMemFile data(packet, size); + uchar cfilehash[MDX_DIGEST_SIZE]; + data.ReadHash16(cfilehash); + CPartFile *file = theApp.downloadqueue->GetFileByID(cfilehash); + if (file == NULL) + client->CheckFailedFileIdReqs(cfilehash); + client->ProcessFileInfo(&data, file); + } + break; + case OP_FILESTATUS: + { + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_FileStatus", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadFileRequest(size); + + CSafeMemFile data(packet, size); + uchar cfilehash[MDX_DIGEST_SIZE]; + data.ReadHash16(cfilehash); + CPartFile *file = theApp.downloadqueue->GetFileByID(cfilehash); + if (file == NULL) + client->CheckFailedFileIdReqs(cfilehash); + client->ProcessFileStatus(false, &data, file); + } + break; + case OP_STARTUPLOADREQ: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_StartUpLoadReq", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadFileRequest(size); - CSafeMemFile data(packet, size); - uint32 nNewUserID = data.ReadUInt32(); - uint32 nNewServerIP = data.ReadUInt32(); - if (thePrefs.GetDebugClientTCPLevel() > 0) - Debug(_T(" NewUserID=%u (%08x, %s) NewServerIP=%u (%08x, %s)\n"), nNewUserID, nNewUserID, (LPCTSTR)ipstr(nNewUserID), nNewServerIP, nNewServerIP, (LPCTSTR)ipstr(nNewServerIP)); - if (::IsLowID(nNewUserID)) { // client changed server and has a LowID - CServer *pNewServer = theApp.serverlist->GetServerByIP(nNewServerIP); - if (pNewServer != NULL) { - client->SetUserIDHybrid(nNewUserID); // update UserID only if we know the server - client->SetServerIP(nNewServerIP); - client->SetServerPort(pNewServer->GetPort()); - } - } else if (nNewUserID == client->GetIP()) { // client changed server and has a HighID(IP) - client->SetUserIDHybrid(ntohl(nNewUserID)); - CServer *pNewServer = theApp.serverlist->GetServerByIP(nNewServerIP); - if (pNewServer != NULL) { - client->SetServerIP(nNewServerIP); - client->SetServerPort(pNewServer->GetPort()); - } - } else if (thePrefs.GetDebugClientTCPLevel() > 0) - Debug(_T("***NOTE: OP_ChangedClientID unknown contents\n")); + if (!client->CheckHandshakeFinished()) + break; + if (size == 16) { + CKnownFile *reqfile = theApp.sharedfiles->GetFileByID(packet); + if (reqfile) { + if (!md4equ(client->GetUploadFileID(), packet)) + client->SetCommentDirty(); + client->SetUploadFileID(reqfile); + client->SendCommentInfo(reqfile); + theApp.uploadqueue->AddClientToQueue(client); + } else + client->CheckFailedFileIdReqs(packet); + } + break; + case OP_QUEUERANK: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_QueueRank", client); + theStats.AddDownDataOverheadFileRequest(size); + client->ProcessEdonkeyQueueRank(packet, size); + break; + case OP_ACCEPTUPLOADREQ: + if (thePrefs.GetDebugClientTCPLevel() > 0) { + DebugRecv("OP_AcceptUploadReq", client, (size >= 16) ? packet : NULL); + if (size > 0) + Debug(_T(" ***NOTE: Packet contains %u additional bytes\n"), size); + Debug(_T(" QR=%d\n"), client->IsRemoteQueueFull() ? UINT_MAX : client->GetRemoteQueueRank()); + } + theStats.AddDownDataOverheadFileRequest(size); + client->ProcessAcceptUpload(); + break; + case OP_REQUESTPARTS: + { + // see also OP_REQUESTPARTS_I64 + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_RequestParts", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadFileRequest(size); - UINT uAddData = (UINT)(data.GetLength() - data.GetPosition()); - if (uAddData > 0 && thePrefs.GetDebugClientTCPLevel() > 0) - Debug(_T("***NOTE: OP_ChangedClientID contains add. data %s\n"), (LPCTSTR)DbgGetHexDump(packet + data.GetPosition(), uAddData)); - } - break; - case OP_CHANGE_SLOT: - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_ChangeSlot", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadFileRequest(size); + CSafeMemFile data(packet, size); + uchar reqfilehash[MDX_DIGEST_SIZE]; + data.ReadHash16(reqfilehash); - // sometimes sent by Hybrid - break; - case OP_MESSAGE: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_Message", client); - theStats.AddDownDataOverheadOther(size); - - if (size < 2) - throw CString(_T("invalid message packet")); - CSafeMemFile data(packet, size); - UINT length = data.ReadUInt16(); - if (length + 2 != size) - throw CString(_T("invalid message packet")); - - if (length > MAX_CLIENT_MSG_LEN) { - if (thePrefs.GetVerbose()) - AddDebugLogLine(false, _T("Message from '%s' (IP:%s) exceeds limit by %u chars, truncated."), client->GetUserName(), (LPCTSTR)ipstr(client->GetConnectIP()), length - MAX_CLIENT_MSG_LEN); - length = MAX_CLIENT_MSG_LEN; - } + uint32 aOffset[3 * 2]; //3 starts, then 3 ends + for (unsigned i = 0; i < 3 * 2; ++i) + aOffset[i] = data.ReadUInt32(); - client->ProcessChatMessage(&data, length); + if (thePrefs.GetDebugClientTCPLevel() > 0) + for (unsigned i = 0; i < 3; ++i) + Debug(_T(" Start[%u]=%u End[%u]=%u Size=%u\n"), i, aOffset[i], i, aOffset[i + 3], aOffset[i + 3] - aOffset[i]); + + for (unsigned i = 0; i < 3; ++i) + if (aOffset[i] < aOffset[i + 3]) { + Requested_Block_Struct *reqblock = new Requested_Block_Struct; + reqblock->StartOffset = aOffset[i]; + reqblock->EndOffset = aOffset[i + 3]; + md4cpy(reqblock->FileID, reqfilehash); + reqblock->transferred = 0; + client->AddReqBlock(reqblock, false); + } else if (thePrefs.GetVerbose() && (aOffset[i + 3] != 0 || aOffset[i] != 0)) + DebugLogWarning(_T("Client requests invalid %u. file block %u-%u (%d bytes): %s"), i, aOffset[i], aOffset[i + 3], aOffset[i + 3] - aOffset[i], (LPCTSTR)client->DbgGetClientInfo()); + + client->AddReqBlock(NULL, true); + } + break; + case OP_CANCELTRANSFER: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_CancelTransfer", client); + theStats.AddDownDataOverheadFileRequest(size); + theApp.uploadqueue->RemoveFromUploadQueue(client, _T("Remote client cancelled transfer.")); + break; + case OP_END_OF_DOWNLOAD: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_EndOfDownload", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadFileRequest(size); + if (size >= 16 && md4equ(client->GetUploadFileID(), packet)) + theApp.uploadqueue->RemoveFromUploadQueue(client, _T("Remote client ended transfer.")); + else + client->CheckFailedFileIdReqs(packet); + break; + case OP_HASHSETREQUEST: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_HashSetReq", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadFileRequest(size); + + if (size != 16) + throw GetResString(IDS_ERR_WRONGHPACKETSIZE); + client->SendHashsetPacket(packet, 16, false); + break; + case OP_HASHSETANSWER: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_HashSetAnswer", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadFileRequest(size); + client->ProcessHashSet(packet, size, false); + break; + case OP_SENDINGPART: + { + // see also OP_SENDINGPART_I64 + if (thePrefs.GetDebugClientTCPLevel() > 1) + DebugRecv("OP_SendingPart", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadFileRequest(16 + 2 * 4); + client->CheckHandshakeFinished(); + EDownloadState newDS = DS_NONE; + const CPartFile *creqfile = client->GetRequestFile(); + if (creqfile) { + if (!creqfile->IsStopped() && (creqfile->GetStatus() == PS_READY || creqfile->GetStatus() == PS_EMPTY)) { + client->ProcessBlockPacket(packet, size, false, false); + if (!creqfile->IsStopped() && creqfile->GetStatus() == PS_PAUSED || creqfile->GetStatus() == PS_ERROR) + newDS = DS_ONQUEUE; + else + newDS = DS_CONNECTED; //anything but DS_NONE or DS_ONQUEUE } - break; - case OP_ASKSHAREDFILES: - { - // client wants to know what we have in share, let's see if we allow him to know that - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_AskSharedFiles", client); - theStats.AddDownDataOverheadOther(size); - - CPtrList list; - if (thePrefs.CanSeeShares() == vsfaEverybody || (thePrefs.CanSeeShares() == vsfaFriends && client->IsFriend())) { - CCKey bufKey; - CKnownFile *cur_file; - for (POSITION pos = theApp.sharedfiles->m_Files_map.GetStartPosition(); pos != NULL;) { - theApp.sharedfiles->m_Files_map.GetNextAssoc(pos, bufKey, cur_file); - if (!cur_file->IsLargeFile() || client->SupportsLargeFiles()) - list.AddTail((void*)cur_file); - } - AddLogLine(true, GetResString(IDS_REQ_SHAREDFILES), (LPCTSTR)client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)GetResString(IDS_ACCEPTED)); - } else - DebugLog(GetResString(IDS_REQ_SHAREDFILES), client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)GetResString(IDS_DENIED)); - - // now create the memfile for the packet - CSafeMemFile tempfile(80); - tempfile.WriteUInt32((uint32)list.GetCount()); - while (!list.IsEmpty()) - theApp.sharedfiles->CreateOfferedFilePacket(reinterpret_cast(list.RemoveHead()), &tempfile, NULL, client); + } + if (newDS != DS_CONNECTED && client) { //could be deleted while debugging + client->SendCancelTransfer(); + client->SetDownloadState(newDS); + } + } + break; + case OP_OUTOFPARTREQS: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_OutOfPartReqs", client); + theStats.AddDownDataOverheadFileRequest(size); + if (client->GetDownloadState() == DS_DOWNLOADING) + client->SetDownloadState(DS_ONQUEUE, _T("The remote client decided to stop/complete the transfer (got OP_OutOfPartReqs).")); + break; + case OP_CHANGE_CLIENT_ID: + { + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_ChangedClientID", client); + theStats.AddDownDataOverheadOther(size); - // create a packet and send it - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_AskSharedFilesAnswer", client); - Packet *replypacket = new Packet(&tempfile); - replypacket->opcode = OP_ASKSHAREDFILESANSWER; - theStats.AddUpDataOverheadOther(replypacket->size); - SendPacket(replypacket, true); + CSafeMemFile data(packet, size); + uint32 nNewUserID = data.ReadUInt32(); + uint32 nNewServerIP = data.ReadUInt32(); + if (thePrefs.GetDebugClientTCPLevel() > 0) + Debug(_T(" NewUserID=%u (%08x, %s) NewServerIP=%u (%08x, %s)\n"), nNewUserID, nNewUserID, (LPCTSTR)ipstr(nNewUserID), nNewServerIP, nNewServerIP, (LPCTSTR)ipstr(nNewServerIP)); + if (::IsLowID(nNewUserID)) { // client changed server and has a LowID + CServer *pNewServer = theApp.serverlist->GetServerByIP(nNewServerIP); + if (pNewServer != NULL) { + client->SetUserIDHybrid(nNewUserID); // update UserID only if we know the server + client->SetServerIP(nNewServerIP); + client->SetServerPort(pNewServer->GetPort()); } - break; - case OP_ASKSHAREDFILESANSWER: - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_AskSharedFilesAnswer", client); - theStats.AddDownDataOverheadOther(size); - client->ProcessSharedFileList(packet, size); - break; - case OP_ASKSHAREDDIRS: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_AskSharedDirectories", client); - theStats.AddDownDataOverheadOther(size); - - if (thePrefs.CanSeeShares() == vsfaEverybody || (thePrefs.CanSeeShares() == vsfaFriends && client->IsFriend())) { - AddLogLine(true, GetResString(IDS_SHAREDREQ1), client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)GetResString(IDS_ACCEPTED)); - client->SendSharedDirectories(); - } else { - DebugLog(GetResString(IDS_SHAREDREQ1), client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)GetResString(IDS_DENIED)); - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_AskSharedDeniedAnswer", client); - Packet *replypacket = new Packet(OP_ASKSHAREDDENIEDANS, 0); - theStats.AddUpDataOverheadOther(replypacket->size); - SendPacket(replypacket, true); - } + } else if (nNewUserID == client->GetIP()) { // client changed server and has a HighID(IP) + client->SetUserIDHybrid(ntohl(nNewUserID)); + CServer *pNewServer = theApp.serverlist->GetServerByIP(nNewServerIP); + if (pNewServer != NULL) { + client->SetServerIP(nNewServerIP); + client->SetServerPort(pNewServer->GetPort()); } - break; - case OP_ASKSHAREDFILESDIR: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_AskSharedFilesInDirectory", client); - theStats.AddDownDataOverheadOther(size); - - CSafeMemFile data(packet, size); - CString strReqDir = data.ReadString(client->GetUnicodeSupport() != UTF8strNone); - if (thePrefs.CanSeeShares() == vsfaEverybody || (thePrefs.CanSeeShares() == vsfaFriends && client->IsFriend())) { - AddLogLine(true, GetResString(IDS_SHAREDREQ2), (LPCTSTR)client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)strReqDir, (LPCTSTR)GetResString(IDS_ACCEPTED)); - ASSERT(data.GetPosition() == data.GetLength()); - CTypedPtrList list; - CString strOrgReqDir = strReqDir; - if (strReqDir == OP_INCOMPLETE_SHARED_FILES) { - // get all shared files from download queue - for (POSITION pos = NULL; ;) { - CPartFile *pFile = theApp.downloadqueue->GetFileNext(pos); - if (pFile && pFile->GetStatus(true) == PS_READY && (!pFile->IsLargeFile() || client->SupportsLargeFiles())) - list.AddTail(pFile); - if (pos == NULL) - break; - } - } else { - bool bSingleSharedFiles = strReqDir == OP_OTHER_SHARED_FILES; - if (!bSingleSharedFiles) - strReqDir = theApp.sharedfiles->GetDirNameByPseudo(strReqDir); - if (!strReqDir.IsEmpty()) { - // get all shared files from requested directory - CCKey bufKey; - for (POSITION pos = theApp.sharedfiles->m_Files_map.GetStartPosition(); pos != NULL;) { - CKnownFile *cur_file; - theApp.sharedfiles->m_Files_map.GetNextAssoc(pos, bufKey, cur_file); - - // all files which are not within a shared directory have to be single shared files - if (((!bSingleSharedFiles && CompareDirectory(strReqDir, cur_file->GetSharedDirectory()) == 0) || (bSingleSharedFiles && !theApp.sharedfiles->ShouldBeShared(cur_file->GetSharedDirectory(), _T(""), false))) - && (!cur_file->IsLargeFile() || client->SupportsLargeFiles())) - { - list.AddTail(cur_file); - } + } else if (thePrefs.GetDebugClientTCPLevel() > 0) + Debug(_T("***NOTE: OP_ChangedClientID unknown contents\n")); - } - } else - DebugLogError(_T("View shared files: Pseudonym for requested Directory (%s) was not found - sending empty result"), (LPCTSTR)strOrgReqDir); - } + UINT uAddData = (UINT)(data.GetLength() - data.GetPosition()); + if (uAddData > 0 && thePrefs.GetDebugClientTCPLevel() > 0) + Debug(_T("***NOTE: OP_ChangedClientID contains add. data %s\n"), (LPCTSTR)DbgGetHexDump(packet + data.GetPosition(), uAddData)); + } + break; + case OP_CHANGE_SLOT: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_ChangeSlot", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadFileRequest(size); + // sometimes sent by Hybrid + break; + case OP_MESSAGE: + { + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_Message", client); + theStats.AddDownDataOverheadOther(size); + + if (size < 2) + throwCStr(_T("invalid message packet")); + CSafeMemFile data(packet, size); + UINT length = data.ReadUInt16(); + if (length + 2 != size) + throwCStr(_T("invalid message packet")); + + if (length > MAX_CLIENT_MSG_LEN) { + if (thePrefs.GetVerbose()) + AddDebugLogLine(false, _T("Message from '%s' (IP:%s) exceeds limit by %u chars, truncated."), client->GetUserName(), (LPCTSTR)ipstr(client->GetConnectIP()), length - MAX_CLIENT_MSG_LEN); + length = MAX_CLIENT_MSG_LEN; + } - // Currently we are sending each shared directory, even if it does not contain any files. - // Because of this we also have to send an empty shared files list. - CSafeMemFile tempfile(80); - tempfile.WriteString(strOrgReqDir, client->GetUnicodeSupport()); - tempfile.WriteUInt32((uint32)list.GetCount()); - while (!list.IsEmpty()) - theApp.sharedfiles->CreateOfferedFilePacket(list.RemoveHead(), &tempfile, NULL, client); + client->ProcessChatMessage(data, length); + } + break; + case OP_ASKSHAREDFILES: + { + // client wants to know what we have in share, let's see if we allow him to know that + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_AskSharedFiles", client); + theStats.AddDownDataOverheadOther(size); + + CPtrList list; + if (thePrefs.CanSeeShares() == vsfaEverybody || (thePrefs.CanSeeShares() == vsfaFriends && client->IsFriend())) { + for (const CKnownFilesMap::CPair *pair = theApp.sharedfiles->m_Files_map.PGetFirstAssoc(); pair != NULL; pair = theApp.sharedfiles->m_Files_map.PGetNextAssoc(pair)) + if (!pair->value->IsLargeFile() || client->SupportsLargeFiles()) + list.AddTail((void*)pair->value); + + AddLogLine(true, GetResString(IDS_REQ_SHAREDFILES), (LPCTSTR)client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)GetResString(IDS_ACCEPTED)); + } else + DebugLog(GetResString(IDS_REQ_SHAREDFILES), client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)GetResString(IDS_DENIED)); + + // now create the memfile for the packet + CSafeMemFile tempfile(80); + tempfile.WriteUInt32((uint32)list.GetCount()); + while (!list.IsEmpty()) + theApp.sharedfiles->CreateOfferedFilePacket(reinterpret_cast(list.RemoveHead()), tempfile, NULL, client); + + // create a packet and send it + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugSend("OP_AskSharedFilesAnswer", client); + Packet *replypacket = new Packet(tempfile); + replypacket->opcode = OP_ASKSHAREDFILESANSWER; + theStats.AddUpDataOverheadOther(replypacket->size); + SendPacket(replypacket, true); + } + break; + case OP_ASKSHAREDFILESANSWER: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_AskSharedFilesAnswer", client); + theStats.AddDownDataOverheadOther(size); + client->ProcessSharedFileList(packet, size); + break; + case OP_ASKSHAREDDIRS: + { + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_AskSharedDirectories", client); + theStats.AddDownDataOverheadOther(size); - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_AskSharedFilesInDirectoryAnswer", client); - Packet *replypacket = new Packet(&tempfile); - replypacket->opcode = OP_ASKSHAREDFILESDIRANS; - theStats.AddUpDataOverheadOther(replypacket->size); - SendPacket(replypacket, true); - } else { - DebugLog(GetResString(IDS_SHAREDREQ2), client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)strReqDir, (LPCTSTR)GetResString(IDS_DENIED)); - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_AskSharedDeniedAnswer", client); - Packet *replypacket = new Packet(OP_ASKSHAREDDENIEDANS, 0); - theStats.AddUpDataOverheadOther(replypacket->size); - SendPacket(replypacket, true); + if (thePrefs.CanSeeShares() == vsfaEverybody || (thePrefs.CanSeeShares() == vsfaFriends && client->IsFriend())) { + AddLogLine(true, GetResString(IDS_SHAREDREQ1), client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)GetResString(IDS_ACCEPTED)); + client->SendSharedDirectories(); + } else { + DebugLog(GetResString(IDS_SHAREDREQ1), client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)GetResString(IDS_DENIED)); + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugSend("OP_AskSharedDeniedAnswer", client); + Packet *replypacket = new Packet(OP_ASKSHAREDDENIEDANS, 0); + theStats.AddUpDataOverheadOther(replypacket->size); + SendPacket(replypacket, true); + } + } + break; + case OP_ASKSHAREDFILESDIR: + { + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_AskSharedFilesInDirectory", client); + theStats.AddDownDataOverheadOther(size); + + Packet *replypacket; + CSafeMemFile data(packet, size); + CString strReqDir(data.ReadString(client->GetUnicodeSupport() != UTF8strNone)); + if (thePrefs.CanSeeShares() == vsfaEverybody || (thePrefs.CanSeeShares() == vsfaFriends && client->IsFriend())) { + AddLogLine(true, GetResString(IDS_SHAREDREQ2), (LPCTSTR)client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)strReqDir, (LPCTSTR)GetResString(IDS_ACCEPTED)); + ASSERT(data.GetPosition() == data.GetLength()); + CTypedPtrList list; + const CString strOrgReqDir(strReqDir); + if (strReqDir == OP_INCOMPLETE_SHARED_FILES) { + for (POSITION pos = NULL; ;) { // get all shared files from download queue + CPartFile *pFile = theApp.downloadqueue->GetFileNext(pos); + if (pFile && pFile->GetStatus(true) == PS_READY && (!pFile->IsLargeFile() || client->SupportsLargeFiles())) + list.AddTail(pFile); + if (pos == NULL) + break; } - } - break; - case OP_ASKSHAREDDIRSANS: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_AskSharedDirectoriesAnswer", client); - theStats.AddDownDataOverheadOther(size); - if (client->GetFileListRequested() == 1) { - CSafeMemFile data(packet, size); - uint32 uDirs = data.ReadUInt32(); - for (uint32 i = 0; i < uDirs; ++i) { - const CString &strDir = data.ReadString(client->GetUnicodeSupport() != UTF8strNone); - // Better send the received and untouched directory string back to that client - //PathRemoveBackslash(strDir.GetBuffer()); - //strDir.ReleaseBuffer(); - AddLogLine(true, GetResString(IDS_SHAREDANSW), client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)strDir); - - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_AskSharedFilesInDirectory", client); - CSafeMemFile tempfile(80); - tempfile.WriteString(strDir, client->GetUnicodeSupport()); - Packet *replypacket = new Packet(&tempfile); - replypacket->opcode = OP_ASKSHAREDFILESDIR; - theStats.AddUpDataOverheadOther(replypacket->size); - SendPacket(replypacket, true); + } else { + bool bSingleSharedFiles = (strReqDir == OP_OTHER_SHARED_FILES); + if (!bSingleSharedFiles) + strReqDir = theApp.sharedfiles->GetDirNameByPseudo(strReqDir); + if (!strReqDir.IsEmpty()) { + // get all shared files from requested directory + for (const CKnownFilesMap::CPair *pair = theApp.sharedfiles->m_Files_map.PGetFirstAssoc(); pair != NULL; pair = theApp.sharedfiles->m_Files_map.PGetNextAssoc(pair)) { + CKnownFile *cur_file = pair->value; + // all files not in shared directories have to be single shared files + if (((!bSingleSharedFiles && EqualPaths(strReqDir, cur_file->GetSharedDirectory())) + || (bSingleSharedFiles && !theApp.sharedfiles->ShouldBeShared(cur_file->GetSharedDirectory(), NULL, false)) + ) + && (!cur_file->IsLargeFile() || client->SupportsLargeFiles())) + { + list.AddTail(cur_file); + } } - ASSERT(data.GetPosition() == data.GetLength()); - client->SetFileListRequested(uDirs); } else - AddLogLine(true, GetResString(IDS_SHAREDANSW2), client->GetUserName(), client->GetUserIDHybrid()); + DebugLogError(_T("View shared files: Pseudonym for requested Directory (%s) was not found - sending empty result"), (LPCTSTR)strOrgReqDir); } - break; - case OP_ASKSHAREDFILESDIRANS: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_AskSharedFilesInDirectoryAnswer", client); - theStats.AddDownDataOverheadOther(size); - - CSafeMemFile data(packet, size); - CString strDir = data.ReadString(client->GetUnicodeSupport() != UTF8strNone); - PathRemoveBackslash(strDir.GetBuffer()); - strDir.ReleaseBuffer(); - if (client->GetFileListRequested() > 0) { - AddLogLine(true, GetResString(IDS_SHAREDINFO1), client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)strDir); - client->ProcessSharedFileList(packet + data.GetPosition(), (uint32)(size - data.GetPosition()), strDir); - if (client->GetFileListRequested() == 0) - AddLogLine(true, GetResString(IDS_SHAREDINFO2), client->GetUserName(), client->GetUserIDHybrid()); - } else - AddLogLine(true, GetResString(IDS_SHAREDANSW3), client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)strDir); - } - break; - case OP_ASKSHAREDDENIEDANS: - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_AskSharedDeniedAnswer", client); - theStats.AddDownDataOverheadOther(size); - AddLogLine(true, GetResString(IDS_SHAREDREQDENIED), client->GetUserName(), client->GetUserIDHybrid()); - client->SetFileListRequested(0); - break; + // Currently we are sending each shared directory, even if it does not contain any files. + // Because of this we also have to send an empty shared files list. + CSafeMemFile tempfile(80); + tempfile.WriteString(strOrgReqDir, client->GetUnicodeSupport()); + tempfile.WriteUInt32((uint32)list.GetCount()); + while (!list.IsEmpty()) + theApp.sharedfiles->CreateOfferedFilePacket(list.RemoveHead(), tempfile, NULL, client); - default: - theStats.AddDownDataOverheadOther(size); - PacketToDebugLogLine(_T("eDonkey"), packet, size, opcode); + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugSend("OP_AskSharedFilesInDirectoryAnswer", client); + replypacket = new Packet(tempfile); + replypacket->opcode = OP_ASKSHAREDFILESDIRANS; + } else { + DebugLog(GetResString(IDS_SHAREDREQ2), client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)strReqDir, (LPCTSTR)GetResString(IDS_DENIED)); + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugSend("OP_AskSharedDeniedAnswer", client); + replypacket = new Packet(OP_ASKSHAREDDENIEDANS, 0); } - } catch (CFileException *error) { - error->Delete(); - throw GetResString(IDS_ERR_INVALIDPACKET); - } catch (CMemoryException *error) { - error->Delete(); - throw CString(_T("Memory exception")); + theStats.AddUpDataOverheadOther(replypacket->size); + SendPacket(replypacket, true); } - return true; - } catch (CClientException *ex) { // nearly the same as the 'CString' exception but with optional deleting of the client - if (thePrefs.GetVerbose() && !ex->m_strMsg.IsEmpty()) - DebugLogWarning(_T("Error: %s - while processing eDonkey packet: opcode=%s size=%u; %s"), (LPCTSTR)ex->m_strMsg, (LPCTSTR)DbgGetDonkeyClientTCPOpcode(opcode), size, (LPCTSTR)DbgGetClientInfo()); - if (client && ex->m_bDelete) - client->SetDownloadState(DS_ERROR, _T("Error while processing eDonkey packet (CClientException): ") + ex->m_strMsg); - Disconnect(ex->m_strMsg); - ex->Delete(); - } catch (const CString &error) { - if (thePrefs.GetVerbose() && !error.IsEmpty()) - DebugLogWarning(_T("Error: %s - while processing eDonkey packet: opcode=%s size=%u; %s"), (LPCTSTR)error, (LPCTSTR)DbgGetDonkeyClientTCPOpcode(opcode), size, (LPCTSTR)DbgGetClientInfo()); - if (client) - client->SetDownloadState(DS_ERROR, _T("Error while processing eDonkey packet (CString exception): ") + error); - Disconnect(_T("Error when processing packet.") + error); + break; + case OP_ASKSHAREDDIRSANS: + { + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_AskSharedDirectoriesAnswer", client); + theStats.AddDownDataOverheadOther(size); + if (client->GetFileListRequested() == 1) { + CSafeMemFile data(packet, size); + uint32 uDirs = data.ReadUInt32(); + for (uint32 i = uDirs; i > 0; --i) { + const CString &strDir(data.ReadString(client->GetUnicodeSupport() != UTF8strNone)); + // Better send the received and untouched directory string back to that client + AddLogLine(true, GetResString(IDS_SHAREDANSW), client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)strDir); + + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugSend("OP_AskSharedFilesInDirectory", client); + CSafeMemFile tempfile(80); + tempfile.WriteString(strDir, client->GetUnicodeSupport()); + Packet *replypacket = new Packet(tempfile); + replypacket->opcode = OP_ASKSHAREDFILESDIR; + theStats.AddUpDataOverheadOther(replypacket->size); + SendPacket(replypacket, true); + } + ASSERT(data.GetPosition() == data.GetLength()); + client->SetFileListRequested(uDirs); + } else + AddLogLine(true, GetResString(IDS_SHAREDANSW2), client->GetUserName(), client->GetUserIDHybrid()); + } + break; + case OP_ASKSHAREDFILESDIRANS: + { + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_AskSharedFilesInDirectoryAnswer", client); + theStats.AddDownDataOverheadOther(size); + + CSafeMemFile data(packet, size); + CString strDir(data.ReadString(client->GetUnicodeSupport() != UTF8strNone)); + + if (client->GetFileListRequested() > 0) { + AddLogLine(true, GetResString(IDS_SHAREDINFO1), client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)strDir); + client->ProcessSharedFileList(packet + data.GetPosition(), (uint32)(size - data.GetPosition()), strDir); + if (client->GetFileListRequested() == 0) + AddLogLine(true, GetResString(IDS_SHAREDINFO2), client->GetUserName(), client->GetUserIDHybrid()); + } else + AddLogLine(true, GetResString(IDS_SHAREDANSW3), client->GetUserName(), client->GetUserIDHybrid(), (LPCTSTR)strDir); + } + break; + case OP_ASKSHAREDDENIEDANS: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_AskSharedDeniedAnswer", client); + theStats.AddDownDataOverheadOther(size); + + AddLogLine(true, GetResString(IDS_SHAREDREQDENIED), client->GetUserName(), client->GetUserIDHybrid()); + client->SetFileListRequested(0); + break; + default: + theStats.AddDownDataOverheadOther(size); + PacketToDebugLogLine(_T("eDonkey"), packet, size, opcode); } - return false; + return true; } bool CClientReqSocket::ProcessExtPacket(const BYTE *packet, uint32 size, UINT opcode, UINT uRawSize) { try { - try { - if (!client && opcode != OP_PORTTEST) { - theStats.AddDownDataOverheadOther(uRawSize); - throw GetResString(IDS_ERR_UNKNOWNCLIENTACTION); - } - if (thePrefs.m_iDbgHeap >= 2 && opcode != OP_PORTTEST) - ASSERT_VALID(client); - switch (opcode) { - case OP_MULTIPACKET: // deprecated - case OP_MULTIPACKET_EXT: // deprecated - case OP_MULTIPACKET_EXT2: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - if (opcode == OP_MULTIPACKET_EXT) - DebugRecv("OP_MultiPacket_Ext", client, (size >= 24) ? packet : NULL); - else - DebugRecv("OP_MultiPacket", client, (size >= 16) ? packet : NULL); - - theStats.AddDownDataOverheadFileRequest(uRawSize); - client->CheckHandshakeFinished(); + switch (opcode) { + case OP_MULTIPACKET: // deprecated + case OP_MULTIPACKET_EXT: // deprecated + case OP_MULTIPACKET_EXT2: + { + if (thePrefs.GetDebugClientTCPLevel() > 0) + if (opcode == OP_MULTIPACKET) + DebugRecv("OP_MultiPacket", client, (size >= 16) ? packet : NULL); + else + DebugRecv((opcode == OP_MULTIPACKET_EXT2 ? "OP_MultiPacket_Ext2" : "OP_MultiPacket_Ext"), client, (size >= 24) ? packet : NULL); - if (client->GetKadPort() && client->GetKadVersion() >= KADEMLIA_VERSION2_47a) - Kademlia::CKademlia::Bootstrap(ntohl(client->GetIP()), client->GetKadPort()); + theStats.AddDownDataOverheadFileRequest(uRawSize); + client->CheckHandshakeFinished(); - CSafeMemFile data_in(packet, size); - CKnownFile *reqfile; - bool bNotFound = false; - uchar reqfilehash[MDX_DIGEST_SIZE]; - if (opcode == OP_MULTIPACKET_EXT2) { // file identifier support - CFileIdentifierSA fileIdent; - if (!fileIdent.ReadIdentifier(&data_in)) { - DebugLogWarning(_T("Error while reading file identifier from MultiPacket_Ext2 - %s"), (LPCTSTR)client->DbgGetClientInfo()); - break; - } - md4cpy(reqfilehash, fileIdent.GetMD4Hash()); // need this in case we want to sent a FNF - reqfile = theApp.sharedfiles->GetFileByID(fileIdent.GetMD4Hash()); - if (reqfile == NULL) { - reqfile = theApp.downloadqueue->GetFileByID(fileIdent.GetMD4Hash()); - if (reqfile == NULL || (uint64)((CPartFile*)reqfile)->GetCompletedSize() < PARTSIZE) { - bNotFound = true; - client->CheckFailedFileIdReqs(fileIdent.GetMD4Hash()); - } - } - if (!bNotFound && !reqfile->GetFileIdentifier().CompareRelaxed(fileIdent)) { + if (client->GetKadPort() && client->GetKadVersion() >= KADEMLIA_VERSION2_47a) + Kademlia::CKademlia::Bootstrap(ntohl(client->GetIP()), client->GetKadPort()); + + CSafeMemFile data_in(packet, size); + CKnownFile *reqfile; + bool bNotFound = false; + uchar reqfilehash[MDX_DIGEST_SIZE]; + if (opcode == OP_MULTIPACKET_EXT2) { // file identifier support + CFileIdentifierSA fileIdent; + if (!fileIdent.ReadIdentifier(data_in)) { + DebugLogWarning(_T("Error while reading file identifier from MultiPacket_Ext2 - %s"), (LPCTSTR)client->DbgGetClientInfo()); + break; + } + md4cpy(reqfilehash, fileIdent.GetMD4Hash()); // need this in case we want to sent a FNF + reqfile = theApp.sharedfiles->GetFileByID(fileIdent.GetMD4Hash()); + if (reqfile == NULL) { + reqfile = theApp.downloadqueue->GetFileByID(fileIdent.GetMD4Hash()); + if (reqfile == NULL || (uint64)((CPartFile*)reqfile)->GetCompletedSize() < PARTSIZE) { bNotFound = true; - DebugLogWarning(_T("FileIdentifier Mismatch on requested file, sending FNF; %s, File=\"%s\", Local Ident: %s, Received Ident: %s"), (LPCTSTR)client->DbgGetClientInfo() - , (LPCTSTR)reqfile->GetFileName(), (LPCTSTR)reqfile->GetFileIdentifier().DbgInfo(), (LPCTSTR)fileIdent.DbgInfo()); - } - } else { // no file identifier - data_in.ReadHash16(reqfilehash); - uint64 nSize = (opcode == OP_MULTIPACKET_EXT) ? data_in.ReadUInt64() : 0; - reqfile = theApp.sharedfiles->GetFileByID(reqfilehash); - if (reqfile == NULL) { - reqfile = theApp.downloadqueue->GetFileByID(reqfilehash); - if (reqfile == NULL || (uint64)((CPartFile*)reqfile)->GetCompletedSize() < PARTSIZE) { - bNotFound = true; - client->CheckFailedFileIdReqs(reqfilehash); - } + client->CheckFailedFileIdReqs(fileIdent.GetMD4Hash()); } - if (!bNotFound && nSize != 0 && nSize != reqfile->GetFileSize()) { + } + if (!bNotFound && !reqfile->GetFileIdentifier().CompareRelaxed(fileIdent)) { + bNotFound = true; + DebugLogWarning(_T("FileIdentifier Mismatch on requested file, sending FNF; %s, File=\"%s\", Local Ident: %s, Received Ident: %s"), (LPCTSTR)client->DbgGetClientInfo() + , (LPCTSTR)reqfile->GetFileName(), (LPCTSTR)reqfile->GetFileIdentifier().DbgInfo(), (LPCTSTR)fileIdent.DbgInfo()); + } + } else { // no file identifier + data_in.ReadHash16(reqfilehash); + uint64 nSize = (opcode == OP_MULTIPACKET_EXT) ? data_in.ReadUInt64() : 0; + reqfile = theApp.sharedfiles->GetFileByID(reqfilehash); + if (reqfile == NULL) { + reqfile = theApp.downloadqueue->GetFileByID(reqfilehash); + if (reqfile == NULL || (uint64)((CPartFile*)reqfile)->GetCompletedSize() < PARTSIZE) { bNotFound = true; - DebugLogWarning(_T("Size Mismatch on requested file, sending FNF; %s, File=\"%s\""), (LPCTSTR)client->DbgGetClientInfo(), (LPCTSTR)reqfile->GetFileName()); + client->CheckFailedFileIdReqs(reqfilehash); } } - - if (!bNotFound && reqfile->IsLargeFile() && !client->SupportsLargeFiles()) { + if (!bNotFound && nSize != 0 && nSize != reqfile->GetFileSize()) { bNotFound = true; - DebugLogWarning(_T("Client without 64bit file support requested large file; %s, File=\"%s\""), (LPCTSTR)client->DbgGetClientInfo(), (LPCTSTR)reqfile->GetFileName()); - } - if (bNotFound) { - // send file request no such file packet (0x48) - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_FileReqAnsNoFil", client, packet); - Packet *replypacket = new Packet(OP_FILEREQANSNOFIL, 16); - md4cpy(replypacket->pBuffer, reqfilehash); - theStats.AddUpDataOverheadFileRequest(replypacket->size); - SendPacket(replypacket); - break; + DebugLogWarning(_T("Size Mismatch on requested file, sending FNF; %s, File=\"%s\""), (LPCTSTR)client->DbgGetClientInfo(), (LPCTSTR)reqfile->GetFileName()); } + } - if (!client->GetWaitStartTime()) - client->SetWaitStartTime(); + if (!bNotFound && reqfile->IsLargeFile() && !client->SupportsLargeFiles()) { + bNotFound = true; + DebugLogWarning(_T("Client without 64bit file support requested large file; %s, File=\"%s\""), (LPCTSTR)client->DbgGetClientInfo(), (LPCTSTR)reqfile->GetFileName()); + } + if (bNotFound) { + // send file request answer - no such file packet (0x48) + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugSend("OP_FileReqAnsNoFil", client, packet); + Packet *replypacket = new Packet(OP_FILEREQANSNOFIL, 16); + md4cpy(replypacket->pBuffer, reqfilehash); + theStats.AddUpDataOverheadFileRequest(replypacket->size); + SendPacket(replypacket); + break; + } - // if we are downloading this file, this could be a new source - // no passive adding of files with only one part - if (reqfile->IsPartFile() && (uint64)reqfile->GetFileSize() > PARTSIZE) - if (static_cast(reqfile)->GetMaxSources() > static_cast(reqfile)->GetSourceCount()) - theApp.downloadqueue->CheckAndAddKnownSource(static_cast(reqfile), client, true); + if (!client->GetWaitStartTime()) + client->SetWaitStartTime(); - // check to see if this is a new file they are asking for - if (!md4equ(client->GetUploadFileID(), reqfile->GetFileHash())) - client->SetCommentDirty(); + // if we are downloading this file, this could be a new source + // no passive adding of files with only one part + if (reqfile->IsPartFile() && (uint64)reqfile->GetFileSize() > PARTSIZE) + if (static_cast(reqfile)->GetMaxSources() > static_cast(reqfile)->GetSourceCount()) + theApp.downloadqueue->CheckAndAddKnownSource(static_cast(reqfile), client, true); - client->SetUploadFileID(reqfile); + // check to see if this is a new file they are asking for + if (!md4equ(client->GetUploadFileID(), reqfile->GetFileHash())) + client->SetCommentDirty(); - CSafeMemFile data_out(128); - if (opcode == OP_MULTIPACKET_EXT2) // file identifier support - reqfile->GetFileIdentifierC().WriteIdentifier(&data_out); - else - data_out.WriteHash16(reqfile->GetFileHash()); - bool bAnswerFNF = false; - while (data_in.GetLength() > data_in.GetPosition() && !bAnswerFNF) { - uint8 opcode_in = data_in.ReadUInt8(); - switch (opcode_in) { - case OP_REQUESTFILENAME: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_MPReqFileName", client, packet); - - if (!client->ProcessExtendedInfo(&data_in, reqfile)) { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_FileReqAnsNoFil", client, packet); - Packet *replypacket = new Packet(OP_FILEREQANSNOFIL, 16); - md4cpy(replypacket->pBuffer, reqfile->GetFileHash()); - theStats.AddUpDataOverheadFileRequest(replypacket->size); - SendPacket(replypacket); - DebugLogWarning(_T("Partcount mismatch on requested file, sending FNF; %s, File=\"%s\""), (LPCTSTR)client->DbgGetClientInfo(), (LPCTSTR)reqfile->GetFileName()); - bAnswerFNF = true; - } else { - data_out.WriteUInt8(OP_REQFILENAMEANSWER); - data_out.WriteString(reqfile->GetFileName(), client->GetUnicodeSupport()); - } - } - break; - case OP_AICHFILEHASHREQ: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_MPAichFileHashReq", client, packet); - - if (client->SupportsFileIdentifiers() || opcode == OP_MULTIPACKET_EXT2) // not allowed any more with file idents supported - DebugLogWarning(_T("Client requested AICH Hash packet, but supports FileIdentifiers, ignored - %s"), (LPCTSTR)client->DbgGetClientInfo()); - else if (client->IsSupportingAICH() && reqfile->GetFileIdentifier().HasAICHHash()) { - data_out.WriteUInt8(OP_AICHFILEHASHANS); - reqfile->GetFileIdentifier().GetAICHHash().Write(&data_out); - } - } - break; - case OP_SETREQFILEID: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_MPSetReqFileID", client, packet); + client->SetUploadFileID(reqfile); - data_out.WriteUInt8(OP_FILESTATUS); - if (reqfile->IsPartFile()) - static_cast(reqfile)->WritePartStatus(&data_out); - else - data_out.WriteUInt16(0); - } - break; - //We still send the source packet separately. - case OP_REQUESTSOURCES2: - case OP_REQUESTSOURCES: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv(opcode_in == OP_REQUESTSOURCES2 ? "OP_MPReqSources2" : "OP_MPReqSources", client, packet); - - if (thePrefs.GetDebugSourceExchange()) - AddDebugLogLine(false, _T("SXRecv: Client source request; %s, File=\"%s\""), (LPCTSTR)client->DbgGetClientInfo(), (LPCTSTR)reqfile->GetFileName()); - - uint8 byRequestedVersion = 0; - uint16 byRequestedOptions = 0; - if (opcode_in == OP_REQUESTSOURCES2) { // SX2 requests contains additional data - byRequestedVersion = data_in.ReadUInt8(); - byRequestedOptions = data_in.ReadUInt16(); - } - //Although this shouldn't happen, it's just in case for any Mods that mess with version numbers. - if (byRequestedVersion > 0 || client->GetSourceExchange1Version() > 1) { - DWORD dwTimePassed = ::GetTickCount() - client->GetLastSrcReqTime() + CONNECTION_LATENCY; - bool bNeverAskedBefore = client->GetLastSrcReqTime() == 0; - if ( //if not complete and file is rare - (reqfile->IsPartFile() - && (bNeverAskedBefore || dwTimePassed > SOURCECLIENTREASKS) - && static_cast(reqfile)->GetSourceCount() <= RARE_FILE - ) - //OR if file is not rare or if file is complete - || bNeverAskedBefore || dwTimePassed > SOURCECLIENTREASKS * MINCOMMONPENALTY - ) - { - client->SetLastSrcReqTime(); - Packet *tosend = reqfile->CreateSrcInfoPacket(client, byRequestedVersion, byRequestedOptions); - if (tosend) { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_AnswerSources", client, reqfile->GetFileHash()); - theStats.AddUpDataOverheadSourceExchange(tosend->size); - SendPacket(tosend); - } - }/* else if (thePrefs.GetVerbose()) - AddDebugLogLine(false, _T("RCV: Source Request to fast. (This is testing the new timers to see how much older client will not receive this)")); - */ - } + CSafeMemFile data_out(128); + if (opcode == OP_MULTIPACKET_EXT2) // file identifier support + reqfile->GetFileIdentifierC().WriteIdentifier(data_out); + else + data_out.WriteHash16(reqfile->GetFileHash()); + bool bAnswerFNF = false; + while (data_in.GetLength() > data_in.GetPosition() && !bAnswerFNF) { + uint8 opcode_in = data_in.ReadUInt8(); + switch (opcode_in) { + case OP_REQUESTFILENAME: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_MPReqFileName", client, packet); + + if (!client->ProcessExtendedInfo(&data_in, reqfile)) { + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugSend("OP_FileReqAnsNoFil", client, packet); + Packet *replypacket = new Packet(OP_FILEREQANSNOFIL, 16); + md4cpy(replypacket->pBuffer, reqfile->GetFileHash()); + theStats.AddUpDataOverheadFileRequest(replypacket->size); + SendPacket(replypacket); + DebugLogWarning(_T("Partcount mismatch on requested file, sending FNF; %s, File=\"%s\""), (LPCTSTR)client->DbgGetClientInfo(), (LPCTSTR)reqfile->GetFileName()); + bAnswerFNF = true; + } else { + data_out.WriteUInt8(OP_REQFILENAMEANSWER); + data_out.WriteString(reqfile->GetFileName(), client->GetUnicodeSupport()); + } + break; + case OP_AICHFILEHASHREQ: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_MPAichFileHashReq", client, packet); + + if (client->SupportsFileIdentifiers() || opcode == OP_MULTIPACKET_EXT2) // not allowed any more with file idents supported + DebugLogWarning(_T("Client requested AICH Hash packet, but supports FileIdentifiers, ignored - %s"), (LPCTSTR)client->DbgGetClientInfo()); + else if (client->IsSupportingAICH() && reqfile->GetFileIdentifier().HasAICHHash()) { + data_out.WriteUInt8(OP_AICHFILEHASHANS); + reqfile->GetFileIdentifier().GetAICHHash().Write(data_out); + } + break; + case OP_SETREQFILEID: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_MPSetReqFileID", client, packet); + + data_out.WriteUInt8(OP_FILESTATUS); + if (reqfile->IsPartFile()) + static_cast(reqfile)->WritePartStatus(data_out); + else + data_out.WriteUInt16(0); + break; + //We still send the source packet separately. + case OP_REQUESTSOURCES2: + case OP_REQUESTSOURCES: + { + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv(opcode_in == OP_REQUESTSOURCES ? "OP_MPReqSources2" : "OP_MPReqSources", client, packet); + + if (thePrefs.GetDebugSourceExchange()) + AddDebugLogLine(false, _T("SXRecv: Client source request; %s, File=\"%s\""), (LPCTSTR)client->DbgGetClientInfo(), (LPCTSTR)reqfile->GetFileName()); + + uint8 byRequestedVersion = 0; + uint16 byRequestedOptions = 0; + if (opcode_in == OP_REQUESTSOURCES2) { // SX2 requests contains additional data + byRequestedVersion = data_in.ReadUInt8(); + byRequestedOptions = data_in.ReadUInt16(); } - break; - default: - { - CString strError; - strError.Format(_T("Invalid sub opcode 0x%02x received"), opcode_in); - throw strError; + //Although this shouldn't happen, it's just in case for any Mods that mess with version numbers. + if (byRequestedVersion > 0 || client->GetSourceExchange1Version() > 1) { + DWORD dwTimePassed = ::GetTickCount() - client->GetLastSrcReqTime() + CONNECTION_LATENCY; + bool bNeverAskedBefore = client->GetLastSrcReqTime() == 0; + if ( //if not complete and file is rare + (reqfile->IsPartFile() + && (bNeverAskedBefore || dwTimePassed > SOURCECLIENTREASKS) + && static_cast(reqfile)->GetSourceCount() <= RARE_FILE + ) + //OR if file is not rare or is complete + || bNeverAskedBefore || dwTimePassed > SOURCECLIENTREASKS * MINCOMMONPENALTY + ) + { + client->SetLastSrcReqTime(); + Packet *tosend = reqfile->CreateSrcInfoPacket(client, byRequestedVersion, byRequestedOptions); + if (tosend) { + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugSend("OP_AnswerSources", client, reqfile->GetFileHash()); + theStats.AddUpDataOverheadSourceExchange(tosend->size); + SendPacket(tosend); + } + }/* else if (thePrefs.GetVerbose()) + AddDebugLogLine(false, _T("RCV: Source Request too fast. (This is testing the new timers to see how much older client will not receive this)")); + */ } } - } - if (data_out.GetLength() > 16 && !bAnswerFNF) { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_MultiPacketAns", client, reqfile->GetFileHash()); - Packet *reply = new Packet(&data_out, OP_EMULEPROT); - reply->opcode = (opcode == OP_MULTIPACKET_EXT2) ? OP_MULTIPACKETANSWER_EXT2 : OP_MULTIPACKETANSWER; - theStats.AddUpDataOverheadFileRequest(reply->size); - SendPacket(reply); + break; + default: + { + CString strError; + strError.Format(_T("Invalid sub opcode 0x%02x received"), opcode_in); + throw strError; + } } } - break; - case OP_MULTIPACKETANSWER: - case OP_MULTIPACKETANSWER_EXT2: - { + if (data_out.GetLength() > 16 && !bAnswerFNF) { if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_MultiPacketAns", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadFileRequest(uRawSize); - client->CheckHandshakeFinished(); + DebugSend("OP_MultiPacketAns", client, reqfile->GetFileHash()); + Packet *reply = new Packet(data_out, OP_EMULEPROT); + reply->opcode = (opcode == OP_MULTIPACKET_EXT2) ? OP_MULTIPACKETANSWER_EXT2 : OP_MULTIPACKETANSWER; + theStats.AddUpDataOverheadFileRequest(reply->size); + SendPacket(reply); + } + } + break; + case OP_MULTIPACKETANSWER: + case OP_MULTIPACKETANSWER_EXT2: + { + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_MultiPacketAns", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadFileRequest(uRawSize); + client->CheckHandshakeFinished(); - if (client->GetKadPort() && client->GetKadVersion() >= KADEMLIA_VERSION2_47a) - Kademlia::CKademlia::Bootstrap(ntohl(client->GetIP()), client->GetKadPort()); + if (client->GetKadPort() && client->GetKadVersion() >= KADEMLIA_VERSION2_47a) + Kademlia::CKademlia::Bootstrap(ntohl(client->GetIP()), client->GetKadPort()); - CSafeMemFile data_in(packet, size); + CSafeMemFile data_in(packet, size); - CPartFile *reqfile = NULL; - if (opcode == OP_MULTIPACKETANSWER_EXT2) { - CFileIdentifierSA fileIdent; - if (!fileIdent.ReadIdentifier(&data_in)) - throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (OP_MULTIPACKETANSWER_EXT2; ReadIdentifier() failed)"); - reqfile = theApp.downloadqueue->GetFileByID(fileIdent.GetMD4Hash()); - if (reqfile == NULL) { - client->CheckFailedFileIdReqs(fileIdent.GetMD4Hash()); - throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (OP_MULTIPACKETANSWER_EXT2; reqfile==NULL)"); - } - if (!reqfile->GetFileIdentifier().CompareRelaxed(fileIdent)) - throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (OP_MULTIPACKETANSWER_EXT2; FileIdentifier mistmatch)"); - if (fileIdent.HasAICHHash()) - client->ProcessAICHFileHash(NULL, reqfile, &fileIdent.GetAICHHash()); - } else { - uchar reqfilehash[MDX_DIGEST_SIZE]; - data_in.ReadHash16(reqfilehash); - reqfile = theApp.downloadqueue->GetFileByID(reqfilehash); - //Make sure we are downloading this file. - if (reqfile == NULL) { - client->CheckFailedFileIdReqs(reqfilehash); - throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (OP_MULTIPACKETANSWER; reqfile==NULL)"); + CPartFile *reqfile = NULL; + if (opcode == OP_MULTIPACKETANSWER_EXT2) { + CFileIdentifierSA fileIdent; + if (!fileIdent.ReadIdentifier(data_in)) + throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (OP_MULTIPACKETANSWER_EXT2; ReadIdentifier() failed)"); + reqfile = theApp.downloadqueue->GetFileByID(fileIdent.GetMD4Hash()); + if (reqfile == NULL) { + client->CheckFailedFileIdReqs(fileIdent.GetMD4Hash()); + throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (OP_MULTIPACKETANSWER_EXT2; reqfile==NULL)"); + } + if (!reqfile->GetFileIdentifier().CompareRelaxed(fileIdent)) + throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (OP_MULTIPACKETANSWER_EXT2; FileIdentifier mismatch)"); + if (fileIdent.HasAICHHash()) + client->ProcessAICHFileHash(NULL, reqfile, &fileIdent.GetAICHHash()); + } else { + uchar reqfilehash[MDX_DIGEST_SIZE]; + data_in.ReadHash16(reqfilehash); + reqfile = theApp.downloadqueue->GetFileByID(reqfilehash); + //Make sure we are downloading this file. + if (reqfile == NULL) { + client->CheckFailedFileIdReqs(reqfilehash); + throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (OP_MULTIPACKETANSWER; reqfile==NULL)"); + } + } + if (client->GetRequestFile() == NULL) + throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (OP_MULTIPACKETANSWER; client->GetRequestFile()==NULL)"); + if (reqfile != client->GetRequestFile()) + throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (OP_MULTIPACKETANSWER; reqfile!=client->GetRequestFile())"); + while (data_in.GetLength() > data_in.GetPosition()) { + uint8 opcode_in = data_in.ReadUInt8(); + switch (opcode_in) { + case OP_REQFILENAMEANSWER: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_MPReqFileNameAns", client, packet); + + client->ProcessFileInfo(&data_in, reqfile); + break; + case OP_FILESTATUS: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_MPFileStatus", client, packet); + + client->ProcessFileStatus(false, &data_in, reqfile); + break; + case OP_AICHFILEHASHANS: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_MPAichFileHashAns", client); + + client->ProcessAICHFileHash(&data_in, reqfile, NULL); + break; + default: + { + CString strError; + strError.Format(_T("Invalid sub opcode 0x%02x received"), opcode_in); + throw strError; } } - if (client->GetRequestFile() == NULL) - throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (OP_MULTIPACKETANSWER; client->GetRequestFile()==NULL)"); - if (reqfile != client->GetRequestFile()) - throw GetResString(IDS_ERR_WRONGFILEID) + _T(" (OP_MULTIPACKETANSWER; reqfile!=client->GetRequestFile())"); - while (data_in.GetLength() > data_in.GetPosition()) { - uint8 opcode_in = data_in.ReadUInt8(); - switch (opcode_in) { - case OP_REQFILENAMEANSWER: - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_MPReqFileNameAns", client, packet); + } + } + break; + case OP_EMULEINFO: + theStats.AddDownDataOverheadOther(uRawSize); + client->ProcessMuleInfoPacket(packet, size); + if (thePrefs.GetDebugClientTCPLevel() > 0) { + DebugRecv("OP_EmuleInfo", client); + Debug(_T(" %s\n"), (LPCTSTR)client->DbgGetMuleInfo()); + } - client->ProcessFileInfo(&data_in, reqfile); - break; - case OP_FILESTATUS: - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_MPFileStatus", client, packet); + // start secure identification, if + // - we have received eD2K and eMule info (old eMule) + if (client->GetInfoPacketsReceived() == IP_BOTH) + client->InfoPacketsReceived(); - client->ProcessFileStatus(false, &data_in, reqfile); - break; - case OP_AICHFILEHASHANS: - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_MPAichFileHashAns", client); + client->SendMuleInfoPacket(true); + break; + case OP_EMULEINFOANSWER: + theStats.AddDownDataOverheadOther(uRawSize); + client->ProcessMuleInfoPacket(packet, size); + if (thePrefs.GetDebugClientTCPLevel() > 0) { + DebugRecv("OP_EmuleInfoAnswer", client); + Debug(_T(" %s\n"), (LPCTSTR)client->DbgGetMuleInfo()); + } - client->ProcessAICHFileHash(&data_in, reqfile, NULL); - break; - default: - { - CString strError; - strError.Format(_T("Invalid sub opcode 0x%02x received"), opcode_in); - throw strError; + // start secure identification, if + // - we have received eD2K and eMule info (old eMule) + if (client->GetInfoPacketsReceived() == IP_BOTH) + client->InfoPacketsReceived(); + break; + case OP_SECIDENTSTATE: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_SecIdentState", client); + theStats.AddDownDataOverheadOther(uRawSize); + + client->ProcessSecIdentStatePacket(packet, size); + if (client->GetSecureIdentState() == IS_SIGNATURENEEDED) + client->SendSignaturePacket(); + else if (client->GetSecureIdentState() == IS_KEYANDSIGNEEDED) { + client->SendPublicKeyPacket(); + client->SendSignaturePacket(); + } + break; + case OP_PUBLICKEY: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_PublicKey", client); + theStats.AddDownDataOverheadOther(uRawSize); + + client->ProcessPublicKeyPacket(packet, size); + break; + case OP_SIGNATURE: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_Signature", client); + theStats.AddDownDataOverheadOther(uRawSize); + + client->ProcessSignaturePacket(packet, size); + break; + case OP_QUEUERANKING: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_QueueRanking", client); + theStats.AddDownDataOverheadFileRequest(uRawSize); + client->CheckHandshakeFinished(); + + client->ProcessEmuleQueueRank(packet, size); + break; + case OP_REQUESTSOURCES: + case OP_REQUESTSOURCES2: + { + CSafeMemFile data(packet, size); + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv(opcode == OP_REQUESTSOURCES2 ? "OP_MPReqSources2" : "OP_MPReqSources", client, (size >= 16) ? packet : NULL); + + theStats.AddDownDataOverheadSourceExchange(uRawSize); + client->CheckHandshakeFinished(); + + uint8 byRequestedVersion = 0; + uint16 byRequestedOptions = 0; + if (opcode == OP_REQUESTSOURCES2) { // SX2 requests contains additional data + byRequestedVersion = data.ReadUInt8(); + byRequestedOptions = data.ReadUInt16(); + } + //Although this shouldn't happen, it's just in case to any Mods that mess with version numbers. + if (byRequestedVersion > 0 || client->GetSourceExchange1Version() > 1) { + if (size < 16) + throw GetResString(IDS_ERR_BADSIZE); + + if (thePrefs.GetDebugSourceExchange()) + AddDebugLogLine(false, _T("SXRecv: Client source request; %s, %s"), (LPCTSTR)client->DbgGetClientInfo(), (LPCTSTR)DbgGetFileInfo(packet)); + + //first check shared file list, then download list + uchar ucHash[MDX_DIGEST_SIZE]; + data.ReadHash16(ucHash); + CKnownFile *reqfile = theApp.sharedfiles->GetFileByID(ucHash); + if (!reqfile) + reqfile = theApp.downloadqueue->GetFileByID(ucHash); + if (reqfile) { + // There are some clients which do not follow the correct protocol procedure of sending + // the sequence OP_REQUESTFILENAME, OP_SETREQFILEID, OP_REQUESTSOURCES. If those clients + // are doing this, they will not get the optimal set of sources which we could offer if + // the would follow the above noted protocol sequence. They better to it the right way + // or they will get just a random set of sources because we do not know their download + // part status which may get cleared with the call of 'SetUploadFileID'. + client->SetUploadFileID(reqfile); + + DWORD dwTimePassed = ::GetTickCount() - client->GetLastSrcReqTime() + CONNECTION_LATENCY; + bool bNeverAskedBefore = (client->GetLastSrcReqTime() == 0); + if ( //if not complete and file is rare + (reqfile->IsPartFile() + && (bNeverAskedBefore || dwTimePassed > SOURCECLIENTREASKS) + && static_cast(reqfile)->GetSourceCount() <= RARE_FILE + ) + //OR if file is not rare or is complete + || bNeverAskedBefore || dwTimePassed > SOURCECLIENTREASKS * MINCOMMONPENALTY + ) + { + client->SetLastSrcReqTime(); + Packet *tosend = reqfile->CreateSrcInfoPacket(client, byRequestedVersion, byRequestedOptions); + if (tosend) { + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugSend("OP_AnswerSources", client, reqfile->GetFileHash()); + theStats.AddUpDataOverheadSourceExchange(tosend->size); + SendPacket(tosend, true); } } - } + } else + client->CheckFailedFileIdReqs(ucHash); } - break; - case OP_EMULEINFO: - theStats.AddDownDataOverheadOther(uRawSize); - client->ProcessMuleInfoPacket(packet, size); - if (thePrefs.GetDebugClientTCPLevel() > 0) { - DebugRecv("OP_EmuleInfo", client); - Debug(_T(" %s\n"), (LPCTSTR)client->DbgGetMuleInfo()); + } + break; + case OP_ANSWERSOURCES: + { + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_AnswerSources", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadSourceExchange(uRawSize); + client->CheckHandshakeFinished(); + + CSafeMemFile data(packet, size); + uchar hash[MDX_DIGEST_SIZE]; + data.ReadHash16(hash); + CKnownFile *file = theApp.downloadqueue->GetFileByID(hash); + if (file == NULL) + client->CheckFailedFileIdReqs(hash); + else if (file->IsPartFile()) { + //set the client's answer time + client->SetLastSrcAnswerTime(); + //and set the file's last answer time + static_cast(file)->SetLastAnsweredTime(); + static_cast(file)->AddClientSources(&data, client->GetSourceExchange1Version(), false, client); + } + } + break; + case OP_ANSWERSOURCES2: + { + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_AnswerSources2", client, (size >= 17) ? packet : NULL); + theStats.AddDownDataOverheadSourceExchange(uRawSize); + client->CheckHandshakeFinished(); + + CSafeMemFile data(packet, size); + uint8 byVersion = data.ReadUInt8(); + uchar hash[MDX_DIGEST_SIZE]; + data.ReadHash16(hash); + CKnownFile *file = theApp.downloadqueue->GetFileByID(hash); + if (file == NULL) + client->CheckFailedFileIdReqs(hash); + else if (file->IsPartFile()) { + //set the client's answer time + client->SetLastSrcAnswerTime(); + //and set the file's last answer time + static_cast(file)->SetLastAnsweredTime(); + static_cast(file)->AddClientSources(&data, byVersion, true, client); } + } + break; + case OP_FILEDESC: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_FileDesc", client); + theStats.AddDownDataOverheadFileRequest(uRawSize); + client->CheckHandshakeFinished(); - // start secure identification, if - // - we have received eD2K and eMule info (old eMule) - if (client->GetInfoPacketsReceived() == IP_BOTH) - client->InfoPacketsReceived(); + client->ProcessMuleCommentPacket(packet, size); + break; + case OP_REQUESTPREVIEW: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_RequestPreView", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadOther(uRawSize); + client->CheckHandshakeFinished(); + + if (thePrefs.CanSeeShares() == vsfaEverybody || (thePrefs.CanSeeShares() == vsfaFriends && client->IsFriend())) { + if (thePrefs.GetVerbose()) + AddDebugLogLine(true, _T("Client '%s' (%s) requested Preview - accepted"), client->GetUserName(), (LPCTSTR)ipstr(client->GetConnectIP())); + client->ProcessPreviewReq(packet, size); + } else { + // we don't send any answer here, because the client should know that he was not allowed to ask + if (thePrefs.GetVerbose()) + AddDebugLogLine(true, _T("Client '%s' (%s) requested Preview - denied"), client->GetUserName(), (LPCTSTR)ipstr(client->GetConnectIP())); + } + break; + case OP_PREVIEWANSWER: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_PreviewAnswer", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadOther(uRawSize); + client->CheckHandshakeFinished(); - client->SendMuleInfoPacket(true); - break; - case OP_EMULEINFOANSWER: - theStats.AddDownDataOverheadOther(uRawSize); - client->ProcessMuleInfoPacket(packet, size); + client->ProcessPreviewAnswer(packet, size); + break; + case OP_PEERCACHE_QUERY: + theStats.AddDownDataOverheadFileRequest(uRawSize); + if (!client->ProcessPeerCacheQuery(packet, size)) { + CSafeMemFile dataSend(128); + dataSend.WriteUInt8(PCPCK_VERSION); + dataSend.WriteUInt8(PCOP_NONE); if (thePrefs.GetDebugClientTCPLevel() > 0) { - DebugRecv("OP_EmuleInfoAnswer", client); - Debug(_T(" %s\n"), (LPCTSTR)client->DbgGetMuleInfo()); + DebugSend("OP_PeerCacheAnswer", client); + Debug(_T(" %s\n"), _T("Not supported")); } + Packet *pEd2kPacket = new Packet(dataSend, OP_EMULEPROT, OP_PEERCACHE_ANSWER); + theStats.AddUpDataOverheadFileRequest(pEd2kPacket->size); + SendPacket(pEd2kPacket); + } + break; + case OP_PEERCACHE_ANSWER: + theStats.AddDownDataOverheadFileRequest(uRawSize); + if ((!client->ProcessPeerCacheAnswer(packet, size)) && client->GetDownloadState() != DS_NONEEDEDPARTS) { + // We have sent a PeerCache Query to the remote client, for any reason the remote client + // can not process it -> fall back to ed2k download. + client->SetPeerCacheDownState(PCDS_NONE); + ASSERT(client->m_pPCDownSocket == NULL); + + // PC-TODO: Check client state. + ASSERT(client->GetDownloadState() == DS_DOWNLOADING); + client->SetDownloadState(DS_ONQUEUE, _T("Peer cache query trouble")); // clear block requests + if (client) + client->StartDownload(); + } + break; + case OP_PEERCACHE_ACK: + theStats.AddDownDataOverheadFileRequest(uRawSize); + client->ProcessPeerCacheAcknowledge(packet, size); + break; + case OP_PUBLICIP_ANSWER: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_PublicIPAns", client); + theStats.AddDownDataOverheadOther(uRawSize); - // start secure identification, if - // - we have received eD2K and eMule info (old eMule) - if (client->GetInfoPacketsReceived() == IP_BOTH) - client->InfoPacketsReceived(); - break; - case OP_SECIDENTSTATE: + client->ProcessPublicIPAnswer(packet, size); + break; + case OP_PUBLICIP_REQ: + { if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_SecIdentState", client); + DebugRecv("OP_PublicIPReq", client); theStats.AddDownDataOverheadOther(uRawSize); - client->ProcessSecIdentStatePacket(packet, size); - if (client->GetSecureIdentState() == IS_SIGNATURENEEDED) - client->SendSignaturePacket(); - else if (client->GetSecureIdentState() == IS_KEYANDSIGNEEDED) { - client->SendPublicKeyPacket(); - client->SendSignaturePacket(); - } - break; - case OP_PUBLICKEY: if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_PublicKey", client); - theStats.AddDownDataOverheadOther(uRawSize); - - client->ProcessPublicKeyPacket(packet, size); - break; - case OP_SIGNATURE: + DebugSend("OP_PublicIPAns", client); + Packet *pPacket = new Packet(OP_PUBLICIP_ANSWER, 4, OP_EMULEPROT); + PokeUInt32(pPacket->pBuffer, client->GetIP()); + theStats.AddUpDataOverheadOther(pPacket->size); + SendPacket(pPacket); + } + break; + case OP_PORTTEST: + { if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_Signature", client); + DebugRecv("OP_PortTest", client); theStats.AddDownDataOverheadOther(uRawSize); - client->ProcessSignaturePacket(packet, size); - break; - case OP_QUEUERANKING: + m_bPortTestCon = true; + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugSend("OP_PortTest", client); + Packet *replypacket = new Packet(OP_PORTTEST, 1); + replypacket->pBuffer[0] = 0x12; + theStats.AddUpDataOverheadOther(replypacket->size); + SendPacket(replypacket); + } + break; + case OP_CALLBACK: + { if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_QueueRanking", client); + DebugRecv("OP_Callback", client); theStats.AddDownDataOverheadFileRequest(uRawSize); - client->CheckHandshakeFinished(); - - client->ProcessEmuleQueueRank(packet, size); - break; - case OP_REQUESTSOURCES: - case OP_REQUESTSOURCES2: - { - CSafeMemFile data(packet, size); - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv(opcode == OP_REQUESTSOURCES2 ? "OP_MPReqSources2" : "OP_MPReqSources", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadSourceExchange(uRawSize); - client->CheckHandshakeFinished(); - - uint8 byRequestedVersion = 0; - uint16 byRequestedOptions = 0; - if (opcode == OP_REQUESTSOURCES2) { // SX2 requests contains additional data - byRequestedVersion = data.ReadUInt8(); - byRequestedOptions = data.ReadUInt16(); - } - //Although this shouldn't happen, it's just in case to any Mods that mess with version numbers. - if (byRequestedVersion > 0 || client->GetSourceExchange1Version() > 1) { - if (size < 16) - throw GetResString(IDS_ERR_BADSIZE); - - if (thePrefs.GetDebugSourceExchange()) - AddDebugLogLine(false, _T("SXRecv: Client source request; %s, %s"), (LPCTSTR)client->DbgGetClientInfo(), (LPCTSTR)DbgGetFileInfo(packet)); - - //first check shared file list, then download list - uchar ucHash[MDX_DIGEST_SIZE]; - data.ReadHash16(ucHash); - CKnownFile *reqfile = theApp.sharedfiles->GetFileByID(ucHash); - if (!reqfile) - reqfile = theApp.downloadqueue->GetFileByID(ucHash); - if (reqfile) { - // There are some clients which do not follow the correct protocol procedure of sending - // the sequence OP_REQUESTFILENAME, OP_SETREQFILEID, OP_REQUESTSOURCES. If those clients - // are doing this, they will not get the optimal set of sources which we could offer if - // the would follow the above noted protocol sequence. They better to it the right way - // or they will get just a random set of sources because we do not know their download - // part status which may get cleared with the call of 'SetUploadFileID'. - client->SetUploadFileID(reqfile); - - DWORD dwTimePassed = ::GetTickCount() - client->GetLastSrcReqTime() + CONNECTION_LATENCY; - bool bNeverAskedBefore = client->GetLastSrcReqTime() == 0; - if ( - //if not complete and file is rare - (reqfile->IsPartFile() - && (bNeverAskedBefore || dwTimePassed > SOURCECLIENTREASKS) - && static_cast(reqfile)->GetSourceCount() <= RARE_FILE - ) || - //OR if file is not rare or if file is complete - (bNeverAskedBefore || dwTimePassed > SOURCECLIENTREASKS * MINCOMMONPENALTY) - ) - { - client->SetLastSrcReqTime(); - Packet *tosend = reqfile->CreateSrcInfoPacket(client, byRequestedVersion, byRequestedOptions); - if (tosend) { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_AnswerSources", client, reqfile->GetFileHash()); - theStats.AddUpDataOverheadSourceExchange(tosend->size); - SendPacket(tosend, true); - } - } - } else - client->CheckFailedFileIdReqs(ucHash); - } - } - break; - case OP_ANSWERSOURCES: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_AnswerSources", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadSourceExchange(uRawSize); - client->CheckHandshakeFinished(); - - CSafeMemFile data(packet, size); - uchar hash[MDX_DIGEST_SIZE]; - data.ReadHash16(hash); - CKnownFile *file = theApp.downloadqueue->GetFileByID(hash); - if (file == NULL) - client->CheckFailedFileIdReqs(hash); - else if (file->IsPartFile()) { - //set the client's answer time - client->SetLastSrcAnswerTime(); - //and set the file's last answer time - static_cast(file)->SetLastAnsweredTime(); - static_cast(file)->AddClientSources(&data, client->GetSourceExchange1Version(), false, client); - } - } - break; - case OP_ANSWERSOURCES2: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_AnswerSources2", client, (size >= 17) ? packet : NULL); - theStats.AddDownDataOverheadSourceExchange(uRawSize); - client->CheckHandshakeFinished(); - - CSafeMemFile data(packet, size); - uint8 byVersion = data.ReadUInt8(); - uchar hash[MDX_DIGEST_SIZE]; - data.ReadHash16(hash); - CKnownFile *file = theApp.downloadqueue->GetFileByID(hash); - if (file == NULL) - client->CheckFailedFileIdReqs(hash); - else if (file->IsPartFile()) { - //set the client's answer time - client->SetLastSrcAnswerTime(); - //and set the file's last answer time - static_cast(file)->SetLastAnsweredTime(); - static_cast(file)->AddClientSources(&data, byVersion, true, client); + if (!Kademlia::CKademlia::IsRunning()) + break; + CSafeMemFile data(packet, size); + Kademlia::CUInt128 check; + data.ReadUInt128(check); + check.Xor(Kademlia::CUInt128(true)); + if (check == Kademlia::CKademlia::GetPrefs()->GetKadID()) { + Kademlia::CUInt128 fileid; + data.ReadUInt128(fileid); + uchar fileid2[MDX_DIGEST_SIZE]; + fileid.ToByteArray(fileid2); + if (theApp.sharedfiles->GetFileByID(fileid2) == NULL) { + if (theApp.downloadqueue->GetFileByID(fileid2) == NULL) { + client->CheckFailedFileIdReqs(fileid2); + break; + } } - } - break; - case OP_FILEDESC: - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_FileDesc", client); - theStats.AddDownDataOverheadFileRequest(uRawSize); - client->CheckHandshakeFinished(); - client->ProcessMuleCommentPacket(packet, size); - break; - case OP_REQUESTPREVIEW: - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_RequestPreView", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadOther(uRawSize); - client->CheckHandshakeFinished(); + uint32 ip = data.ReadUInt32(); + uint16 tcp = data.ReadUInt16(); + CUpDownClient *callback = theApp.clientlist->FindClientByConnIP(ntohl(ip), tcp); + if (callback == NULL) { + callback = new CUpDownClient(NULL, tcp, ip, 0, 0); + theApp.clientlist->AddClient(callback); + } - if (thePrefs.CanSeeShares() == vsfaEverybody || (thePrefs.CanSeeShares() == vsfaFriends && client->IsFriend())) { - if (thePrefs.GetVerbose()) - AddDebugLogLine(true, _T("Client '%s' (%s) requested Preview - accepted"), client->GetUserName(), (LPCTSTR)ipstr(client->GetConnectIP())); - client->ProcessPreviewReq(packet, size); - } else { - // we don't send any answer here, because the client should know that he was not allowed to ask - if (thePrefs.GetVerbose()) - AddDebugLogLine(true, _T("Client '%s' (%s) requested Preview - denied"), client->GetUserName(), (LPCTSTR)ipstr(client->GetConnectIP())); + callback->TryToConnect(true); } - break; - case OP_PREVIEWANSWER: + } + break; + case OP_BUDDYPING: + { if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_PreviewAnswer", client, (size >= 16) ? packet : NULL); + DebugRecv("OP_BuddyPing", client); theStats.AddDownDataOverheadOther(uRawSize); - client->CheckHandshakeFinished(); - client->ProcessPreviewAnswer(packet, size); - break; - case OP_PEERCACHE_QUERY: - theStats.AddDownDataOverheadFileRequest(uRawSize); - if (!client->ProcessPeerCacheQuery(packet, size)) { - CSafeMemFile dataSend(128); - dataSend.WriteUInt8(PCPCK_VERSION); - dataSend.WriteUInt8(PCOP_NONE); - if (thePrefs.GetDebugClientTCPLevel() > 0) { - DebugSend("OP_PeerCacheAnswer", client); - Debug(_T(" %s\n"), _T("Not supported")); - } - Packet *pEd2kPacket = new Packet(&dataSend, OP_EMULEPROT, OP_PEERCACHE_ANSWER); - theStats.AddUpDataOverheadFileRequest(pEd2kPacket->size); - SendPacket(pEd2kPacket); - } - break; - case OP_PEERCACHE_ANSWER: - theStats.AddDownDataOverheadFileRequest(uRawSize); - if ((!client->ProcessPeerCacheAnswer(packet, size)) && client->GetDownloadState() != DS_NONEEDEDPARTS) { - // We have sent a PeerCache Query to the remote client, for any reason the remote client - // can not process it -> fall back to ed2k download. - client->SetPeerCacheDownState(PCDS_NONE); - ASSERT(client->m_pPCDownSocket == NULL); - - // PC-TODO: Check client state. - ASSERT(client->GetDownloadState() == DS_DOWNLOADING); - client->SetDownloadState(DS_ONQUEUE, _T("Peer cache query trouble")); // clear block requests - if (client) - client->StartDownload(); - } - break; - case OP_PEERCACHE_ACK: - theStats.AddDownDataOverheadFileRequest(uRawSize); - client->ProcessPeerCacheAcknowledge(packet, size); - break; - case OP_PUBLICIP_ANSWER: + CUpDownClient *buddy = theApp.clientlist->GetBuddy(); + //Check that ping was from our buddy, correct version, and not too soon + if (buddy != client || !client->GetKadVersion() || !client->AllowIncomeingBuddyPingPong()) + break; // ignore otherwise + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugSend("OP_BuddyPong", client); + Packet *replypacket = new Packet(OP_BUDDYPONG, 0, OP_EMULEPROT); + theStats.AddDownDataOverheadOther(replypacket->size); + SendPacket(replypacket); + client->SetLastBuddyPingPongTime(); + } + break; + case OP_BUDDYPONG: + { if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_PublicIPAns", client); + DebugRecv("OP_BuddyPong", client); theStats.AddDownDataOverheadOther(uRawSize); - client->ProcessPublicIPAnswer(packet, size); - break; - case OP_PUBLICIP_REQ: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_PublicIPReq", client); - theStats.AddDownDataOverheadOther(uRawSize); - + CUpDownClient *buddy = theApp.clientlist->GetBuddy(); + if (buddy != client || !client->GetKadVersion()) + //This pong was not from our buddy or wrong version. Ignore + break; + client->SetLastBuddyPingPongTime(); + //All this is for is to reset our socket timeout. + } + break; + case OP_REASKCALLBACKTCP: + { + theStats.AddDownDataOverheadFileRequest(uRawSize); + CUpDownClient *buddy = theApp.clientlist->GetBuddy(); + if (buddy != client) { if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_PublicIPAns", client); - Packet *pPacket = new Packet(OP_PUBLICIP_ANSWER, 4, OP_EMULEPROT); - PokeUInt32(pPacket->pBuffer, client->GetIP()); - theStats.AddUpDataOverheadOther(pPacket->size); - SendPacket(pPacket); + DebugRecv("OP_ReaskCallbackTCP", client, NULL); + //This callback was not from our buddy. Ignore. + break; } - break; - case OP_PORTTEST: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_PortTest", client); - theStats.AddDownDataOverheadOther(uRawSize); - - m_bPortTestCon = true; - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_PortTest", client); - Packet *replypacket = new Packet(OP_PORTTEST, 1); - replypacket->pBuffer[0] = 0x12; - theStats.AddUpDataOverheadOther(replypacket->size); - SendPacket(replypacket); + CSafeMemFile data_in(packet, size); + uint32 destip = data_in.ReadUInt32(); + uint16 destport = data_in.ReadUInt16(); + uchar reqfilehash[MDX_DIGEST_SIZE]; + data_in.ReadHash16(reqfilehash); + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_ReaskCallbackTCP", client, reqfilehash); + CKnownFile *reqfile = theApp.sharedfiles->GetFileByID(reqfilehash); + + bool bSenderMultipleIpUnknown = false; + CUpDownClient *sender = theApp.uploadqueue->GetWaitingClientByIP_UDP(destip, destport, true, &bSenderMultipleIpUnknown); + if (!reqfile) { + if (thePrefs.GetDebugClientUDPLevel() > 0) + DebugSend("OP_FileNotFound", NULL); + Packet *response = new Packet(OP_FILENOTFOUND, 0, OP_EMULEPROT); + theStats.AddUpDataOverheadFileRequest(response->size); + if (sender != NULL) + theApp.clientudp->SendPacket(response, destip, destport, sender->ShouldReceiveCryptUDPPackets(), sender->GetUserHash(), false, 0); + else + theApp.clientudp->SendPacket(response, destip, destport, false, NULL, false, 0); + break; } - break; - case OP_CALLBACK: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_Callback", client); - theStats.AddDownDataOverheadFileRequest(uRawSize); - - if (!Kademlia::CKademlia::IsRunning()) - break; - CSafeMemFile data(packet, size); - Kademlia::CUInt128 check; - data.ReadUInt128(&check); - check.Xor(Kademlia::CUInt128(true)); - if (check == Kademlia::CKademlia::GetPrefs()->GetKadID()) { - Kademlia::CUInt128 fileid; - data.ReadUInt128(&fileid); - uchar fileid2[MDX_DIGEST_SIZE]; - fileid.ToByteArray(fileid2); - if (theApp.sharedfiles->GetFileByID(fileid2) == NULL) { - if (theApp.downloadqueue->GetFileByID(fileid2) == NULL) { - client->CheckFailedFileIdReqs(fileid2); - break; - } - } - uint32 ip = data.ReadUInt32(); - uint16 tcp = data.ReadUInt16(); - CUpDownClient *callback = theApp.clientlist->FindClientByConnIP(ntohl(ip), tcp); - if (callback == NULL) { - callback = new CUpDownClient(NULL, tcp, ip, 0, 0); - theApp.clientlist->AddClient(callback); + if (sender) { + //Make sure we are still thinking about the same file + if (md4equ(reqfilehash, sender->GetUploadFileID())) { + sender->IncrementAskedCount(); + sender->SetLastUpRequest(); + //I messed up when I first added extended info to UDP + //I should have originally used the entire ProcessExtenedInfo the first time. + //So now I am forced to check UDPVersion to see if we are sending all the extended info. + //For now on, we should not have to change anything here if we change + //anything to the extended info data as this will be taken care of in ProcessExtendedInfo() + //Update extended info. + if (sender->GetUDPVersion() > 3) + sender->ProcessExtendedInfo(&data_in, reqfile); + //Update our complete source counts. + else if (sender->GetUDPVersion() > 2) { + uint16 nCompleteCountLast = sender->GetUpCompleteSourcesCount(); + uint16 nCompleteCountNew = data_in.ReadUInt16(); + sender->SetUpCompleteSourcesCount(nCompleteCountNew); + if (nCompleteCountLast != nCompleteCountNew) + reqfile->UpdatePartsInfo(); } + CSafeMemFile data_out(128); + if (sender->GetUDPVersion() > 3) + if (reqfile->IsPartFile()) + static_cast(reqfile)->WritePartStatus(data_out); + else + data_out.WriteUInt16(0); - callback->TryToConnect(true); - } - } - break; - case OP_BUDDYPING: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_BuddyPing", client); - theStats.AddDownDataOverheadOther(uRawSize); - - CUpDownClient *buddy = theApp.clientlist->GetBuddy(); - if (buddy != client || !client->GetKadVersion() || !client->AllowIncomeingBuddyPingPong()) - //This ping was not from our buddy or wrong version or packet sent to fast. Ignore - break; - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_BuddyPong", client); - Packet *replypacket = new Packet(OP_BUDDYPONG, 0, OP_EMULEPROT); - theStats.AddDownDataOverheadOther(replypacket->size); - SendPacket(replypacket); - client->SetLastBuddyPingPongTime(); - } - break; - case OP_BUDDYPONG: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_BuddyPong", client); - theStats.AddDownDataOverheadOther(uRawSize); - - CUpDownClient *buddy = theApp.clientlist->GetBuddy(); - if (buddy != client || !client->GetKadVersion()) - //This pong was not from our buddy or wrong version. Ignore - break; - client->SetLastBuddyPingPongTime(); - //All this is for is to reset our socket timeout. - } - break; - case OP_REASKCALLBACKTCP: - { - theStats.AddDownDataOverheadFileRequest(uRawSize); - CUpDownClient *buddy = theApp.clientlist->GetBuddy(); - if (buddy != client) { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_ReaskCallbackTCP", client, NULL); - //This callback was not from our buddy. Ignore. - break; - } - CSafeMemFile data_in(packet, size); - uint32 destip = data_in.ReadUInt32(); - uint16 destport = data_in.ReadUInt16(); - uchar reqfilehash[MDX_DIGEST_SIZE]; - data_in.ReadHash16(reqfilehash); - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_ReaskCallbackTCP", client, reqfilehash); - CKnownFile *reqfile = theApp.sharedfiles->GetFileByID(reqfilehash); - - bool bSenderMultipleIpUnknown = false; - CUpDownClient *sender = theApp.uploadqueue->GetWaitingClientByIP_UDP(destip, destport, true, &bSenderMultipleIpUnknown); - if (!reqfile) { + data_out.WriteUInt16((uint16)theApp.uploadqueue->GetWaitingPosition(sender)); if (thePrefs.GetDebugClientUDPLevel() > 0) - DebugSend("OP_FileNotFound", NULL); - Packet *response = new Packet(OP_FILENOTFOUND, 0, OP_EMULEPROT); + DebugSend("OP_ReaskAck", sender); + Packet *response = new Packet(data_out, OP_EMULEPROT); + response->opcode = OP_REASKACK; theStats.AddUpDataOverheadFileRequest(response->size); - if (sender != NULL) - theApp.clientudp->SendPacket(response, destip, destport, sender->ShouldReceiveCryptUDPPackets(), sender->GetUserHash(), false, 0); - else - theApp.clientudp->SendPacket(response, destip, destport, false, NULL, false, 0); - break; + theApp.clientudp->SendPacket(response, destip, destport, sender->ShouldReceiveCryptUDPPackets(), sender->GetUserHash(), false, 0); + } else { + DebugLogWarning(_T("Client UDP socket; OP_REASKCALLBACKTCP; reqfile does not match")); + TRACE(_T("reqfile: %s\n"), (LPCTSTR)DbgGetFileInfo(reqfile->GetFileHash())); + TRACE(_T("sender->GetRequestFile(): %s\n"), sender->GetRequestFile() ? (LPCTSTR)DbgGetFileInfo(sender->GetRequestFile()->GetFileHash()) : _T("(null)")); } - - if (sender) { - //Make sure we are still thinking about the same file - if (md4equ(reqfilehash, sender->GetUploadFileID())) { - sender->AddAskedCount(); - sender->SetLastUpRequest(); - //I messed up when I first added extended info to UDP - //I should have originally used the entire ProcessExtenedInfo the first time. - //So now I am forced to check UDPVersion to see if we are sending all the extended info. - //For now on, we should not have to change anything here if we change - //anything to the extended info data as this will be taken care of in ProcessExtendedInfo() - //Update extended info. - if (sender->GetUDPVersion() > 3) - sender->ProcessExtendedInfo(&data_in, reqfile); - //Update our complete source counts. - else if (sender->GetUDPVersion() > 2) { - uint16 nCompleteCountLast = sender->GetUpCompleteSourcesCount(); - uint16 nCompleteCountNew = data_in.ReadUInt16(); - sender->SetUpCompleteSourcesCount(nCompleteCountNew); - if (nCompleteCountLast != nCompleteCountNew) - reqfile->UpdatePartsInfo(); - } - CSafeMemFile data_out(128); - if (sender->GetUDPVersion() > 3) - if (reqfile->IsPartFile()) - static_cast(reqfile)->WritePartStatus(&data_out); - else - data_out.WriteUInt16(0); - - data_out.WriteUInt16((uint16)theApp.uploadqueue->GetWaitingPosition(sender)); + } else { + if (!bSenderMultipleIpUnknown) { + if (theApp.uploadqueue->GetWaitingUserCount() + 50 > thePrefs.GetQueueSize()) { if (thePrefs.GetDebugClientUDPLevel() > 0) - DebugSend("OP_ReaskAck", sender); - Packet *response = new Packet(&data_out, OP_EMULEPROT); - response->opcode = OP_REASKACK; + DebugSend("OP_QueueFull", NULL); + Packet *response = new Packet(OP_QUEUEFULL, 0, OP_EMULEPROT); theStats.AddUpDataOverheadFileRequest(response->size); - theApp.clientudp->SendPacket(response, destip, destport, sender->ShouldReceiveCryptUDPPackets(), sender->GetUserHash(), false, 0); - } else { - DebugLogWarning(_T("Client UDP socket; OP_REASKCALLBACKTCP; reqfile does not match")); - TRACE(_T("reqfile: %s\n"), (LPCTSTR)DbgGetFileInfo(reqfile->GetFileHash())); - TRACE(_T("sender->GetRequestFile(): %s\n"), sender->GetRequestFile() ? (LPCTSTR)DbgGetFileInfo(sender->GetRequestFile()->GetFileHash()) : _T("(null)")); + theApp.clientudp->SendPacket(response, destip, destport, false, NULL, false, 0); } - } else { - if (!bSenderMultipleIpUnknown) { - if (theApp.uploadqueue->GetWaitingUserCount() + 50 > thePrefs.GetQueueSize()) { - if (thePrefs.GetDebugClientUDPLevel() > 0) - DebugSend("OP_QueueFull", NULL); - Packet *response = new Packet(OP_QUEUEFULL, 0, OP_EMULEPROT); - theStats.AddUpDataOverheadFileRequest(response->size); - theApp.clientudp->SendPacket(response, destip, destport, false, NULL, false, 0); - } - } else - DebugLogWarning(_T("OP_REASKCALLBACKTCP Packet received - multiple clients with the same IP but different UDP port found. Possible UDP Port mapping problem, enforcing TCP connection. IP: %s, Port: %u"), (LPCTSTR)ipstr(destip), destport); - } + } else + DebugLogWarning(_T("OP_REASKCALLBACKTCP Packet received - multiple clients with the same IP but different UDP port found. Possible UDP Port mapping problem, enforcing TCP connection. IP: %s, Port: %u"), (LPCTSTR)ipstr(destip), destport); } - break; - case OP_AICHANSWER: + } + break; + case OP_AICHANSWER: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_AichAnswer", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadFileRequest(uRawSize); + + client->ProcessAICHAnswer(packet, size); + break; + case OP_AICHREQUEST: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_AichRequest", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadFileRequest(uRawSize); + + client->ProcessAICHRequest(packet, size); + break; + case OP_AICHFILEHASHANS: + { + // those should not be received normally, since we should only get those in MULTIPACKET if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_AichAnswer", client, (size >= 16) ? packet : NULL); + DebugRecv("OP_AichFileHashAns", client, (size >= 16) ? packet : NULL); theStats.AddDownDataOverheadFileRequest(uRawSize); - client->ProcessAICHAnswer(packet, size); - break; - case OP_AICHREQUEST: + CSafeMemFile data(packet, size); + client->ProcessAICHFileHash(&data, NULL, NULL); + } + break; + case OP_AICHFILEHASHREQ: + { if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_AichRequest", client, (size >= 16) ? packet : NULL); + DebugRecv("OP_AichFileHashReq", client, (size >= 16) ? packet : NULL); theStats.AddDownDataOverheadFileRequest(uRawSize); - client->ProcessAICHRequest(packet, size); - break; - case OP_AICHFILEHASHANS: - { - // those should not be received normally, since we should only get those in MULTIPACKET - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_AichFileHashAns", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadFileRequest(uRawSize); - - CSafeMemFile data(packet, size); - client->ProcessAICHFileHash(&data, NULL, NULL); + // those should not be received normally, since we should only get those in MULTIPACKET + CSafeMemFile data(packet, size); + uchar abyHash[MDX_DIGEST_SIZE]; + data.ReadHash16(abyHash); + CKnownFile *pPartFile = theApp.sharedfiles->GetFileByID(abyHash); + if (pPartFile == NULL) { + client->CheckFailedFileIdReqs(abyHash); + break; } - break; - case OP_AICHFILEHASHREQ: - { + if (client->IsSupportingAICH() && pPartFile->GetFileIdentifier().HasAICHHash()) { if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_AichFileHashReq", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadFileRequest(uRawSize); - - // those should not be received normally, since we should only get those in MULTIPACKET - CSafeMemFile data(packet, size); - uchar abyHash[MDX_DIGEST_SIZE]; - data.ReadHash16(abyHash); - CKnownFile *pPartFile = theApp.sharedfiles->GetFileByID(abyHash); - if (pPartFile == NULL) { - client->CheckFailedFileIdReqs(abyHash); - break; - } - if (client->IsSupportingAICH() && pPartFile->GetFileIdentifier().HasAICHHash()) { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugSend("OP_AichFileHashAns", client, abyHash); - CSafeMemFile data_out; - data_out.WriteHash16(abyHash); - pPartFile->GetFileIdentifier().GetAICHHash().Write(&data_out); - Packet *response = new Packet(&data_out, OP_EMULEPROT, OP_AICHFILEHASHANS); - theStats.AddUpDataOverheadFileRequest(response->size); - SendPacket(response); - } + DebugSend("OP_AichFileHashAns", client, abyHash); + CSafeMemFile data_out; + data_out.WriteHash16(abyHash); + pPartFile->GetFileIdentifier().GetAICHHash().Write(data_out); + Packet *response = new Packet(data_out, OP_EMULEPROT, OP_AICHFILEHASHANS); + theStats.AddUpDataOverheadFileRequest(response->size); + SendPacket(response); } - break; - case OP_REQUESTPARTS_I64: - { - // see also OP_REQUESTPARTS - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_RequestParts_I64", client, (size >= 16) ? packet : NULL); - theStats.AddDownDataOverheadFileRequest(size); + } + break; + case OP_REQUESTPARTS_I64: + { + // see also OP_REQUESTPARTS + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_RequestParts_I64", client, (size >= 16) ? packet : NULL); + theStats.AddDownDataOverheadFileRequest(size); - CSafeMemFile data(packet, size); - uchar reqfilehash[MDX_DIGEST_SIZE]; - data.ReadHash16(reqfilehash); - - uint64 auStartOffsets[3]; - auStartOffsets[0] = data.ReadUInt64(); - auStartOffsets[1] = data.ReadUInt64(); - auStartOffsets[2] = data.ReadUInt64(); - - uint64 auEndOffsets[3]; - auEndOffsets[0] = data.ReadUInt64(); - auEndOffsets[1] = data.ReadUInt64(); - auEndOffsets[2] = data.ReadUInt64(); - - if (thePrefs.GetDebugClientTCPLevel() > 0) { - Debug(_T(" Start1=%I64u End1=%I64u Size=%I64u\n"), auStartOffsets[0], auEndOffsets[0], auEndOffsets[0] - auStartOffsets[0]); - Debug(_T(" Start2=%I64u End2=%I64u Size=%I64u\n"), auStartOffsets[1], auEndOffsets[1], auEndOffsets[1] - auStartOffsets[1]); - Debug(_T(" Start3=%I64u End3=%I64u Size=%I64u\n"), auStartOffsets[2], auEndOffsets[2], auEndOffsets[2] - auStartOffsets[2]); - } + CSafeMemFile data(packet, size); + uchar reqfilehash[MDX_DIGEST_SIZE]; + data.ReadHash16(reqfilehash); - for (unsigned i = 0; i < _countof(auStartOffsets); ++i) - if (auEndOffsets[i] > auStartOffsets[i]) { - Requested_Block_Struct *reqblock = new Requested_Block_Struct; - reqblock->StartOffset = auStartOffsets[i]; - reqblock->EndOffset = auEndOffsets[i]; - md4cpy(reqblock->FileID, reqfilehash); - reqblock->transferred = 0; - client->AddReqBlock(reqblock, false); - } else if (thePrefs.GetVerbose() && (auEndOffsets[i] || auStartOffsets[i])) - DebugLogWarning(_T("Client requests invalid %u. file block %I64u-%I64u (%I64d bytes): %s"), i, auStartOffsets[i], auEndOffsets[i], auEndOffsets[i] - auStartOffsets[i], (LPCTSTR)client->DbgGetClientInfo()); + uint64 aOffset[3 * 2]; //3 starts, then 3 ends + for (unsigned i = 0; i < 3 * 2; ++i) + aOffset[i] = data.ReadUInt64(); + if (thePrefs.GetDebugClientTCPLevel() > 0) + for (unsigned i = 0; i < 3; ++i) + Debug(_T(" Start[%u]=%I64u End[%u]=%I64u Size=%I64u\n"), i, aOffset[i], i, aOffset[i + 3], aOffset[i + 3] - aOffset[i]); + + for (unsigned i = 0; i < 3; ++i) + if (aOffset[i] < aOffset[i + 3]) { + Requested_Block_Struct *reqblock = new Requested_Block_Struct; + reqblock->StartOffset = aOffset[i]; + reqblock->EndOffset = aOffset[i + 3]; + md4cpy(reqblock->FileID, reqfilehash); + reqblock->transferred = 0; + client->AddReqBlock(reqblock, false); + } else if (thePrefs.GetVerbose() && (aOffset[i + 3] != 0 || aOffset[i] != 0)) + DebugLogWarning(_T("Client requests invalid %u. file block %I64u-%I64u (%I64d bytes): %s"), i, aOffset[i], aOffset[i + 3], aOffset[i + 3] - aOffset[i], (LPCTSTR)client->DbgGetClientInfo()); client->AddReqBlock(NULL, true); - } - break; - case OP_COMPRESSEDPART: - case OP_SENDINGPART_I64: - case OP_COMPRESSEDPART_I64: - { - // see also OP_SENDINGPART - if (thePrefs.GetDebugClientTCPLevel() > 1) { - LPCSTR sOp; - switch (opcode) { - case OP_COMPRESSEDPART: - sOp = "OP_CompressedPart"; - break; - case OP_SENDINGPART_I64: - sOp = "OP_SendingPart_I64"; - break; - default: - sOp = "OP_CompressedPart_I64"; - } - DebugRecv(sOp, client, (size >= 16) ? packet : NULL); + } + break; + case OP_COMPRESSEDPART: + case OP_SENDINGPART_I64: + case OP_COMPRESSEDPART_I64: + { + // see also OP_SENDINGPART + if (thePrefs.GetDebugClientTCPLevel() > 1) { + LPCSTR sOp; + switch (opcode) { + case OP_COMPRESSEDPART: + sOp = "OP_CompressedPart"; + break; + case OP_SENDINGPART_I64: + sOp = "OP_SendingPart_I64"; + break; + default: //OP_COMPRESSEDPART_I64 + sOp = "OP_CompressedPart_I64"; } + DebugRecv(sOp, client, (size >= 16) ? packet : NULL); + } - theStats.AddDownDataOverheadFileRequest(16 + (opcode == OP_COMPRESSEDPART ? 4 : 8) + (opcode == OP_SENDINGPART_I64 ? 8 : 4)); - client->CheckHandshakeFinished(); - const CPartFile *creqfile = client->GetRequestFile(); - if (creqfile && !creqfile->IsStopped() && (creqfile->GetStatus() == PS_READY || creqfile->GetStatus() == PS_EMPTY)) { - client->ProcessBlockPacket(packet, size, (opcode == OP_COMPRESSEDPART || opcode == OP_COMPRESSEDPART_I64), (opcode == OP_SENDINGPART_I64 || opcode == OP_COMPRESSEDPART_I64)); - if (creqfile->IsStopped() || creqfile->GetStatus() == PS_PAUSED || creqfile->GetStatus() == PS_ERROR) { - client->SendCancelTransfer(); - client->SetDownloadState(creqfile->IsStopped() ? DS_NONE : DS_ONQUEUE); - } - } else { - client->SendCancelTransfer(); - client->SetDownloadState((creqfile == NULL || creqfile->IsStopped()) ? DS_NONE : DS_ONQUEUE); + bool bCompress = (opcode != OP_SENDINGPART_I64); + bool b64 = (opcode != OP_COMPRESSEDPART); + theStats.AddDownDataOverheadFileRequest(16 + (b64 ? 8 : 4) + (bCompress ? 4 : 8)); + client->CheckHandshakeFinished(); + EDownloadState newDS = DS_NONE; + const CPartFile *creqfile = client->GetRequestFile(); + if (creqfile) { + if (!creqfile->IsStopped() && (creqfile->GetStatus() == PS_READY || creqfile->GetStatus() == PS_EMPTY)) { + client->ProcessBlockPacket(packet, size, bCompress, b64); + if (!creqfile->IsStopped() && creqfile->GetStatus() == PS_PAUSED || creqfile->GetStatus() == PS_ERROR) + newDS = DS_ONQUEUE; + else + newDS = DS_CONNECTED; //anything but DS_NONE or DS_ONQUEUE } } - break; - case OP_CHATCAPTCHAREQ: - { - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_CHATCAPTCHAREQ", client); - theStats.AddDownDataOverheadOther(uRawSize); - CSafeMemFile data(packet, size); - client->ProcessCaptchaRequest(&data); + if (newDS != DS_CONNECTED) { + client->SendCancelTransfer(); + client->SetDownloadState(newDS); } - break; - case OP_CHATCAPTCHARES: + } + break; + case OP_CHATCAPTCHAREQ: + { if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_CHATCAPTCHARES", client); + DebugRecv("OP_CHATCAPTCHAREQ", client); theStats.AddDownDataOverheadOther(uRawSize); - if (size < 1) - throw GetResString(IDS_ERR_BADSIZE); - client->ProcessCaptchaReqRes(packet[0]); - break; - case OP_FWCHECKUDPREQ: //*Support required for Kad version >= 6 - { - // Kad related packet - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_FWCHECKUDPREQ", client); - theStats.AddDownDataOverheadOther(uRawSize); - CSafeMemFile data(packet, size); - client->ProcessFirewallCheckUDPRequest(&data); - } - break; - case OP_KAD_FWTCPCHECK_ACK: //*Support required for Kad version >= 7 - // Kad related packet, replaces KADEMLIA_FIREWALLED_ACK_RES - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_KAD_FWTCPCHECK_ACK", client); - if (theApp.clientlist->IsKadFirewallCheckIP(client->GetIP())) { - if (Kademlia::CKademlia::IsRunning()) - Kademlia::CKademlia::GetPrefs()->IncFirewalled(); - } else - DebugLogWarning(_T("Unrequested OP_KAD_FWTCPCHECK_ACK packet from client %s"), (LPCTSTR)client->DbgGetClientInfo()); - break; - case OP_HASHSETANSWER2: - if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_HashSetAnswer2", client); - theStats.AddDownDataOverheadFileRequest(size); - client->ProcessHashSet(packet, size, true); - break; - case OP_HASHSETREQUEST2: + CSafeMemFile data(packet, size); + client->ProcessCaptchaRequest(data); + } + break; + case OP_CHATCAPTCHARES: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_CHATCAPTCHARES", client); + theStats.AddDownDataOverheadOther(uRawSize); + if (size < 1) + throw GetResString(IDS_ERR_BADSIZE); + client->ProcessCaptchaReqRes(packet[0]); + break; + case OP_FWCHECKUDPREQ: //*Support required for Kad version >= 6 + { + // Kad related packet if (thePrefs.GetDebugClientTCPLevel() > 0) - DebugRecv("OP_HashSetReq2", client); - theStats.AddDownDataOverheadFileRequest(size); - client->SendHashsetPacket(packet, size, true); - break; - default: + DebugRecv("OP_FWCHECKUDPREQ", client); theStats.AddDownDataOverheadOther(uRawSize); - PacketToDebugLogLine(_T("eMule"), packet, size, opcode); + CSafeMemFile data(packet, size); + client->ProcessFirewallCheckUDPRequest(data); } - } catch (CFileException *error) { - error->Delete(); - throw GetResString(IDS_ERR_INVALIDPACKET); - } catch (CMemoryException *error) { - error->Delete(); - throw CString(_T("Memory exception")); + break; + case OP_KAD_FWTCPCHECK_ACK: //*Support required for Kad version >= 7 + // Kad related packet, replaces KADEMLIA_FIREWALLED_ACK_RES + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_KAD_FWTCPCHECK_ACK", client); + if (theApp.clientlist->IsKadFirewallCheckIP(client->GetIP())) { + if (Kademlia::CKademlia::IsRunning()) + Kademlia::CKademlia::GetPrefs()->IncFirewalled(); + } else + DebugLogWarning(_T("Unrequested OP_KAD_FWTCPCHECK_ACK packet from client %s"), (LPCTSTR)client->DbgGetClientInfo()); + break; + case OP_HASHSETANSWER2: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_HashSetAnswer2", client); + theStats.AddDownDataOverheadFileRequest(size); + client->ProcessHashSet(packet, size, true); + break; + case OP_HASHSETREQUEST2: + if (thePrefs.GetDebugClientTCPLevel() > 0) + DebugRecv("OP_HashSetReq2", client); + theStats.AddDownDataOverheadFileRequest(size); + client->SendHashsetPacket(packet, size, true); + break; + default: + theStats.AddDownDataOverheadOther(uRawSize); + PacketToDebugLogLine(_T("eMule"), packet, size, opcode); } - return true; - } catch (CClientException *ex) { // nearly the same as the 'CString' exception but optionally deletes the client - if (thePrefs.GetVerbose() && !ex->m_strMsg.IsEmpty()) - DebugLogWarning(_T("Error: %s - while processing eMule packet: opcode=%s size=%u; %s"), (LPCTSTR)ex->m_strMsg, (LPCTSTR)DbgGetMuleClientTCPOpcode(opcode), size, (LPCTSTR)DbgGetClientInfo()); - if (client && ex->m_bDelete) - client->SetDownloadState(DS_ERROR, _T("Error while processing eMule packet: ") + ex->m_strMsg); - Disconnect(ex->m_strMsg); - ex->Delete(); - } catch (const CString &error) { - if (thePrefs.GetVerbose() && !error.IsEmpty()) - DebugLogWarning(_T("Error: %s - while processing eMule packet: opcode=%s size=%u; %s"), (LPCTSTR)error, (LPCTSTR)DbgGetMuleClientTCPOpcode(opcode), size, (LPCTSTR)DbgGetClientInfo()); - if (client) - client->SetDownloadState(DS_ERROR, _T("ProcessExtPacket error. ") + error); - Disconnect(_T("ProcessExtPacket error. ") + error); + } catch(CFileException *error) { + error->Delete(); + throw GetResString(IDS_ERR_INVALIDPACKET); + } catch(CMemoryException *error) { + error->Delete(); + throwCStr(_T("Memory exception")); } - return false; + return true; } void CClientReqSocket::PacketToDebugLogLine(LPCTSTR protocol, const uchar *packet, uint32 size, UINT opcode) @@ -1844,9 +1763,9 @@ void CClientReqSocket::PacketToDebugLogLine(LPCTSTR protocol, const uchar *packe buffer.Format(_T("Unknown %s Protocol Opcode: 0x%02x, Size=%u, Data=["), protocol, opcode, size); UINT i; for (i = 0; i < size && i < 50; ++i) - buffer.AppendFormat(i ? _T("%02x") : _T(" %02x"), packet[i]); + buffer.AppendFormat(*(&_T(" %02x")[static_cast(i > 0)]), packet[i]); - buffer += (i < size) ? _T("]") : _T("...]"); + buffer += (i < size) ? _T("... ]") : _T(" ]"); DbgAppendClientInfo(buffer); DebugLogWarning(_T("%s"), (LPCTSTR)buffer); } @@ -1877,13 +1796,13 @@ void CClientReqSocket::OnConnect(int nErrorCode) SetConState(SS_Complete); CEMSocket::OnConnect(nErrorCode); if (nErrorCode) { - CString strTCPError; if (thePrefs.GetVerbose()) { - strTCPError = GetFullErrorMessage(nErrorCode); + const CString &strTCPError(GetFullErrorMessage(nErrorCode)); if ((nErrorCode != WSAECONNREFUSED && nErrorCode != WSAETIMEDOUT) || !GetLastProxyError().IsEmpty()) DebugLogError(_T("Client TCP socket (OnConnect): %s; %s"), (LPCTSTR)strTCPError, (LPCTSTR)DbgGetClientInfo()); - } - Disconnect(strTCPError); + Disconnect(strTCPError); + } else + Disconnect(_T("")); } else //This socket may have been delayed by SP2 protection, lets make sure it doesn't time out instantly. ResetTimeOutTimer(); @@ -1916,27 +1835,84 @@ void CClientReqSocket::OnError(int nErrorCode) bool CClientReqSocket::PacketReceived(Packet *packet) { - UINT uRawSize = packet->size; - switch (packet->prot) { - case OP_EDONKEYPROT: - return ProcessPacket((BYTE*)packet->pBuffer, uRawSize, packet->opcode); - case OP_PACKEDPROT: - if (!packet->UnPackPacket()) { - if (thePrefs.GetVerbose()) - DebugLogError(_T("Failed to decompress client TCP packet; %s; %s"), (LPCTSTR)DbgGetClientTCPPacket(packet->prot, packet->opcode, packet->size), (LPCTSTR)DbgGetClientInfo()); - break; - } - case OP_EMULEPROT: - return ProcessExtPacket((BYTE*)packet->pBuffer, packet->size, packet->opcode, uRawSize); - default: - theStats.AddDownDataOverheadOther(uRawSize); - if (thePrefs.GetVerbose()) - DebugLogWarning(_T("Received unknown client TCP packet; %s; %s"), (LPCTSTR)DbgGetClientTCPPacket(packet->prot, packet->opcode, packet->size), (LPCTSTR)DbgGetClientInfo()); + CString *sErr; + bool bDelClient; + const uint8 opcode = packet->opcode; + const UINT uRawSize = packet->size; + try { + try { + switch (packet->prot) { + case OP_EDONKEYPROT: + if (client) { + if (opcode != OP_HELLO && opcode != OP_HELLOANSWER) + client->CheckHandshakeFinished(); + } else if (opcode != OP_HELLO) { + theStats.AddDownDataOverheadOther(packet->size); + throw GetResString(IDS_ERR_NOHELLO); + } + + return ProcessPacket((BYTE*)packet->pBuffer, uRawSize, opcode); + case OP_PACKEDPROT: + if (!packet->UnPackPacket()) { + if (thePrefs.GetVerbose()) + DebugLogError(_T("Failed to decompress client TCP packet; %s; %s"), (LPCTSTR)DbgGetClientTCPPacket(packet->prot, packet->opcode, packet->size), (LPCTSTR)DbgGetClientInfo()); + break; + } + case OP_EMULEPROT: + if (opcode != OP_PORTTEST) { + if (!client) { + theStats.AddDownDataOverheadOther(uRawSize); + throw GetResString(IDS_ERR_UNKNOWNCLIENTACTION); + } + if (thePrefs.m_iDbgHeap >= 2) + ASSERT_VALID(client); + } + + return ProcessExtPacket((BYTE*)packet->pBuffer, packet->size, packet->opcode, uRawSize); + default: + theStats.AddDownDataOverheadOther(uRawSize); + if (thePrefs.GetVerbose()) + DebugLogWarning(_T("Received unknown client TCP packet; %s; %s"), (LPCTSTR)DbgGetClientTCPPacket(packet->prot, packet->opcode, packet->size), (LPCTSTR)DbgGetClientInfo()); - if (client) - client->SetDownloadState(DS_ERROR, _T("Unknown protocol")); - Disconnect(_T("Unknown protocol")); + if (client) + client->SetDownloadState(DS_ERROR, _T("Unknown protocol")); + Disconnect(_T("Unknown protocol")); + } + } catch (CFileException *error) { + error->Delete(); + throw GetResString(IDS_ERR_INVALIDPACKET); + } catch (CMemoryException *error) { + error->Delete(); + throwCStr(_T("Memory exception")); + } catch (...) { //trying to catch "Unspecified error" + throwCStr(_T("Unhandled exception")); + } + return true; + } catch (CClientException *ex) { // nearly the same as the 'CString' exception but with optional deleting of the client + bDelClient = ex->m_bDelete; + sErr = new CString(ex->m_strMsg); + ex->Delete(); + } catch (const CString &error) { + bDelClient = true; + sErr = new CString(error); } + //Error handling + bool bIsDonkey = (packet->prot == OP_EDONKEYPROT); + LPCTSTR sProtocol = bIsDonkey ? _T("eDonkey") : _T("eMule"); + if (thePrefs.GetVerbose()) + DebugLogWarning(_T("Error: '%s' while processing %s packet: opcode=%s size=%u; %s") + , (LPCTSTR)sErr + , sProtocol + , (LPCTSTR)(bIsDonkey ? DbgGetDonkeyClientTCPOpcode(opcode) : DbgGetMuleClientTCPOpcode(opcode)) + , uRawSize + , (LPCTSTR)DbgGetClientInfo()); + + CString sErr2; + sErr2.Format(_T("Error while processing %s packet: %s"), (LPCTSTR)sProtocol, (LPCTSTR)sErr); + if (bDelClient && client) + client->SetDownloadState(DS_ERROR, sErr2); + Disconnect(sErr2); + delete sErr; return false; } @@ -2033,7 +2009,7 @@ bool CListenSocket::StartListening() // Creating the socket with SO_REUSEADDR may solve LowID issues if emule was restarted // quickly or started after a crash, but(!) it will also create another problem. If the // socket is already used by some other application (e.g. a 2nd emule), we though bind - // to that socket leading to the situation that 2 applications are listening at the same + // to that socket leading to the situation that 2 applications are listening on the same // port! if (!Create(thePrefs.GetPort(), SOCK_STREAM, FD_ACCEPT, thePrefs.GetBindAddr(), AF_INET)) return false; @@ -2179,7 +2155,7 @@ void CListenSocket::OnAccept(int nErrorCode) break; } } else if (s_iAcceptConnectionCondRejected == 1) - theStats.filteredclients++; + ++theStats.filteredclients; continue; } @@ -2228,7 +2204,7 @@ void CListenSocket::OnAccept(int nErrorCode) if (thePrefs.GetLogFilteredIPs()) AddDebugLogLine(false, _T("Rejecting connection attempt (IP=%s) - IP filter (%s)"), (LPCTSTR)ipstr(SockAddr.sin_addr.s_addr), (LPCTSTR)theApp.ipfilter->GetLastHit()); newclient->Safe_Delete(); - theStats.filteredclients++; + ++theStats.filteredclients; continue; } @@ -2328,7 +2304,7 @@ void CListenSocket::Debug_ClientDeleted(CUpDownClient *deleted) { for (POSITION pos = socket_list.GetHeadPosition(); pos != NULL;) { CClientReqSocket *cur_sock = socket_list.GetNext(pos); - if (!AfxIsValidAddress(cur_sock, sizeof(CClientReqSocket))) + if (!cur_sock) AfxDebugBreak(); if (thePrefs.m_iDbgHeap >= 2) ASSERT_VALID(cur_sock); @@ -2371,13 +2347,8 @@ void CListenSocket::UpdateConnectionsStatus() float CListenSocket::GetMaxConperFiveModifier() { - float SpikeSize = GetOpenSockets() - averageconnections; - if (SpikeSize < 1.0F) - return 1.0f; - - float SpikeTolerance = 25.0F * (float)thePrefs.GetMaxConperFive() / 10.0F; - if (SpikeSize > SpikeTolerance) - return 0.0f; + float SpikeSize = max(1.0f, GetOpenSockets() - averageconnections); + float SpikeTolerance = 25.0f * thePrefs.GetMaxConperFive() / 10.0f; - return 1.0f - SpikeSize / SpikeTolerance; + return (SpikeSize > SpikeTolerance) ? 0.0f : 1.0f - SpikeSize / SpikeTolerance; } \ No newline at end of file diff --git a/srchybrid/ListenSocket.h b/srchybrid/ListenSocket.h index 809cc64e..7d1dc8f9 100644 --- a/srchybrid/ListenSocket.h +++ b/srchybrid/ListenSocket.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -74,7 +74,7 @@ class CClientReqSocket : public CEMSocket void SetConState(SocketState val); DWORD timeout_timer; - uint32 deltimer; + DWORD deltimer; uint32 m_nOnConnect; bool deletethis; bool m_bPortTestCon; diff --git a/srchybrid/Log.cpp b/srchybrid/Log.cpp index 93c6f8a7..8542c645 100644 --- a/srchybrid/Log.cpp +++ b/srchybrid/Log.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -300,7 +300,7 @@ bool CLogFile::Open() if (m_uBytesWritten == 0) { if (m_eFileFormat == Unicode) { // write Unicode byte order mark 0xFEFF - fputwc(0xFEFFui16, m_fp); + fputwc(u'\xFEFF', m_fp); } else { ASSERT(m_eFileFormat == Utf8); ; // could write UTF-8 header. @@ -309,15 +309,15 @@ bool CLogFile::Open() // check for Unicode byte order mark 0xFEFF WORD wBOM; if (fread(&wBOM, sizeof wBOM, 1, m_fp) == 1) { - if (wBOM == 0xFEFFui16 && m_eFileFormat == Unicode) { + if (wBOM == u'\xFEFF' && m_eFileFormat == Unicode) { // log file already in Unicode format (void)fseek(m_fp, 0, SEEK_END); // actually not needed because file is opened in 'Append' mode. - } else if (wBOM != 0xFEFFui16 && m_eFileFormat != Unicode) { + } else if (wBOM != u'\xFEFF' && m_eFileFormat != Unicode) { // log file already in UTF-8 format (void)fseek(m_fp, 0, SEEK_END); // actually not needed because file is opened in 'Append' mode. } else { // log file does not have the required format, create a new one (with the req. format) - ASSERT((m_eFileFormat == Unicode && wBOM != 0xFEFFui16) || (m_eFileFormat == Utf8 && wBOM == 0xFEFF)); + ASSERT((m_eFileFormat == Unicode && wBOM != u'\xFEFF') || (m_eFileFormat == Utf8 && wBOM == 0xFEFF)); ASSERT(!m_bInOpenCall); if (!m_bInOpenCall) { // just for safety diff --git a/srchybrid/MapKey.h b/srchybrid/MapKey.h index 3fd94c0a..3b36e627 100644 --- a/srchybrid/MapKey.h +++ b/srchybrid/MapKey.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -34,8 +34,8 @@ class CCKey : public CObject template<> inline UINT AFXAPI HashKey(const CCKey &key) { uint32 hash = 1; - for (int i = 0; i < 16; ++i) - hash += (key.m_key[i] + 1) * ((i * i) + 1); + for (int i = 0; i < MDX_DIGEST_SIZE; ++i) + hash += (key.m_key[i] + 1) * (i * i + 1); return hash; }; @@ -49,13 +49,13 @@ class CSKey : public CObject CSKey& operator=(const CSKey &k1) { md4cpy(m_key, k1.m_key); return *this; } friend bool operator==(const CSKey &k1, const CSKey &k2); - uchar m_key[16]; + uchar m_key[MDX_DIGEST_SIZE]; }; template<> inline UINT AFXAPI HashKey(const CSKey &key) { uint32 hash = 1; - for (int i = 0; i < 16; ++i) - hash += (key.m_key[i] + 1) * ((i * i) + 1); + for (int i = 0; i < MDX_DIGEST_SIZE; ++i) + hash += (key.m_key[i] + 1) * (i * i + 1); return hash; }; \ No newline at end of file diff --git a/srchybrid/Mdump.cpp b/srchybrid/Mdump.cpp index 8e6e38db..2aba3d03 100644 --- a/srchybrid/Mdump.cpp +++ b/srchybrid/Mdump.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -45,9 +45,9 @@ void CMiniDumper::Enable(LPCTSTR pszAppName, bool bShowErrors, LPCTSTR pszDumpDi // Need to pre-determine a valid directory. _tcsncpy(m_szDumpDir, pszDumpDir, _countof(m_szDumpDir) - 2); m_szDumpDir[_countof(m_szDumpDir) - 2] = _T('\0'); - PathAddBackslash(m_szDumpDir); + ::PathAddBackslash(m_szDumpDir); - MINIDUMPWRITEDUMP pfnMiniDumpWriteDump = NULL; + MINIDUMPWRITEDUMP pfnMiniDumpWriteDump; HMODULE hDbgHelpDll = GetDebugHelperDll((FARPROC*)&pfnMiniDumpWriteDump, bShowErrors); if (hDbgHelpDll) { if (pfnMiniDumpWriteDump) @@ -56,9 +56,9 @@ void CMiniDumper::Enable(LPCTSTR pszAppName, bool bShowErrors, LPCTSTR pszDumpDi } } -#define DBGHELP_HINT _T("You can get the required DBGHELP.DLL by downloading the \"User Mode Process Dumper\" from \"Microsoft Download Center\".\r\n\r\n") \ - _T("Extract the \"User Mode Process Dumper\" and locate the \"x86\" folder. ") \ - _T("Copy the DBGHELP.DLL from the \"x86\" folder into your eMule installation folder and/or into your Windows system/system32 folder.") +#define DBGHELP_HINT _T("The required DBGHELP.DLL may be obtained from \"Microsoft Download Center\" as a part of \"User Mode Process Dumper\".\r\n\r\n") \ + _T("DBGHELP.DLL should reside in Windows/System32 folder, and also 32-bit DLL in 64-bit OS in Windows/SysWOW64 folder.\r\n") \ + _T("Alternatively, DBGHELP.DLL may be copied to eMule executable's folder (DLL and executable must have the same bitness).") HMODULE CMiniDumper::GetDebugHelperDll(FARPROC *ppfnMiniDumpWriteDump, bool bShowErrors) { @@ -72,7 +72,7 @@ HMODULE CMiniDumper::GetDebugHelperDll(FARPROC *ppfnMiniDumpWriteDump, bool bSho *ppfnMiniDumpWriteDump = GetProcAddress(hDll, "MiniDumpWriteDump"); if (*ppfnMiniDumpWriteDump == NULL && bShowErrors) // Do *NOT* localize that string (in fact, do not use MFC to load it)! - MessageBox(NULL, _T("DBGHELP.DLL found is too old. Please upgrade to version 5.1 (or later) of DBGHELP.DLL.\r\n\r\n") DBGHELP_HINT, m_szAppName, MB_ICONSTOP | MB_OK); + MessageBox(NULL, _T("DBGHELP.DLL found is too old. Please upgrade to the current version of DBGHELP.DLL.\r\n\r\n") DBGHELP_HINT, m_szAppName, MB_ICONSTOP | MB_OK); } return hDll; } @@ -87,80 +87,82 @@ LONG WINAPI CMiniDumper::TopLevelFilter(struct _EXCEPTION_POINTERS *pExceptionIn #ifdef _DEBUG LONG lRetValue = EXCEPTION_CONTINUE_SEARCH; #endif - TCHAR szResult[MAX_PATH + 1024] = {}; - MINIDUMPWRITEDUMP pfnMiniDumpWriteDump = NULL; + MINIDUMPWRITEDUMP pfnMiniDumpWriteDump; HMODULE hDll = GetDebugHelperDll((FARPROC*)&pfnMiniDumpWriteDump, true); - if (hDll && pfnMiniDumpWriteDump) { - time_t tNow = time(NULL); //time of the crash - // Ask user if they want to save a dump file - // Do *NOT* localize that string (in fact, do not use MFC to load it)! - if (theCrashDumper.uCreateCrashDump == 2 || MessageBox(NULL, CRASHTEXT, m_szAppName, MB_ICONSTOP | MB_YESNO) == IDYES) { - // Create full path for DUMP file - TCHAR szDumpPath[MAX_PATH]; - _tcsncpy(szDumpPath, m_szDumpDir, _countof(szDumpPath) - 1); - szDumpPath[_countof(szDumpPath) - 1] = _T('\0'); - size_t uDumpPathLen = _tcslen(szDumpPath); - - TCHAR szBaseName[MAX_PATH]; - _tcsncpy(szBaseName, m_szAppName, _countof(szBaseName) - 1); - szBaseName[_countof(szBaseName) - 1] = _T('\0'); - size_t uBaseNameLen = _tcslen(szBaseName); - - _tcsftime(szBaseName + uBaseNameLen, _countof(szBaseName) - uBaseNameLen, _T("_%Y%m%d-%H%M%S"), localtime(&tNow)); - szBaseName[_countof(szBaseName) - 1] = _T('\0'); - - // Replace spaces and dots in file name. - LPTSTR psz = szBaseName; - while (*psz != _T('\0')) { - if (*psz == _T('.')) - *psz = _T('-'); - else if (*psz == _T(' ')) - *psz = _T('_'); - ++psz; - } - if (uDumpPathLen < _countof(szDumpPath) - 1) { - _tcsncat(szDumpPath, szBaseName, _countof(szDumpPath) - uDumpPathLen - 1); + if (hDll) { + if (pfnMiniDumpWriteDump) { + time_t tNow = time(NULL); //time of the crash + // Ask user if they want to save a dump file + // Do *NOT* localize that string (in fact, do not use MFC to load it)! + if (theCrashDumper.uCreateCrashDump == 2 || MessageBox(NULL, CRASHTEXT, m_szAppName, MB_ICONSTOP | MB_YESNO) == IDYES) { + // Create full path for DUMP file + TCHAR szDumpPath[MAX_PATH]; + _tcsncpy(szDumpPath, m_szDumpDir, _countof(szDumpPath) - 1); szDumpPath[_countof(szDumpPath) - 1] = _T('\0'); - uDumpPathLen = _tcslen(szDumpPath); + size_t uDumpPathLen = _tcslen(szDumpPath); + + TCHAR szBaseName[MAX_PATH]; + _tcsncpy(szBaseName, m_szAppName, _countof(szBaseName) - 1); + szBaseName[_countof(szBaseName) - 1] = _T('\0'); + size_t uBaseNameLen = _tcslen(szBaseName); + + _tcsftime(szBaseName + uBaseNameLen, _countof(szBaseName) - uBaseNameLen, _T("_%Y%m%d-%H%M%S"), localtime(&tNow)); + szBaseName[_countof(szBaseName) - 1] = _T('\0'); + + // Replace spaces and dots in file name. + LPTSTR psz = szBaseName; + while (*psz != _T('\0')) { + if (*psz == _T('.')) + *psz = _T('-'); + else if (*psz == _T(' ')) + *psz = _T('_'); + ++psz; + } if (uDumpPathLen < _countof(szDumpPath) - 1) { - _tcsncat(szDumpPath, _T(".dmp"), _countof(szDumpPath) - uDumpPathLen - 1); + _tcsncat(szDumpPath, szBaseName, _countof(szDumpPath) - uDumpPathLen - 1); szDumpPath[_countof(szDumpPath) - 1] = _T('\0'); + uDumpPathLen = _tcslen(szDumpPath); + if (uDumpPathLen < _countof(szDumpPath) - 1) { + _tcsncat(szDumpPath, _T(".dmp"), _countof(szDumpPath) - uDumpPathLen - 1); + szDumpPath[_countof(szDumpPath) - 1] = _T('\0'); + } } - } - HANDLE hFile = ::CreateFile(szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile != INVALID_HANDLE_VALUE) { - _MINIDUMP_EXCEPTION_INFORMATION ExInfo = {}; - ExInfo.ThreadId = GetCurrentThreadId(); - ExInfo.ExceptionPointers = pExceptionInfo; - ExInfo.ClientPointers = NULL; - - BOOL bOK = (*pfnMiniDumpWriteDump)(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL); - if (bOK) { - // Do *NOT* localize that string (in fact, do not use MFC to load it)! - _sntprintf(szResult, _countof(szResult) - 1, _T("Saved dump file to \"%s\".\r\n\r\nPlease send this file together with a detailed bug report to dumps@emule-project.net !\r\n\r\nThank you for helping to improve eMule."), szDumpPath); - szResult[_countof(szResult) - 1] = _T('\0'); + TCHAR szResult[MAX_PATH + 1024]; + *szResult = _T('\0'); + HANDLE hFile = ::CreateFile(szDumpPath, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile != INVALID_HANDLE_VALUE) { + _MINIDUMP_EXCEPTION_INFORMATION ExInfo = {}; + ExInfo.ThreadId = GetCurrentThreadId(); + ExInfo.ExceptionPointers = pExceptionInfo; + ExInfo.ClientPointers = NULL; + + BOOL bOK = (*pfnMiniDumpWriteDump)(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL); + if (bOK) { + // Do *NOT* localize that string (in fact, do not use MFC to load it)! + _sntprintf(szResult, _countof(szResult) - 1, _T("Saved dump file to \"%s\".\r\n\r\nPlease send this file together with a detailed bug report to dumps@emule-project.net !\r\n\r\nThank you for helping to improve eMule."), szDumpPath); + szResult[_countof(szResult) - 1] = _T('\0'); #ifdef _DEBUG - lRetValue = EXCEPTION_EXECUTE_HANDLER; + lRetValue = EXCEPTION_EXECUTE_HANDLER; #endif + } else { + // Do *NOT* localize that string (in fact, do not use MFC to load it)! + _sntprintf(szResult, _countof(szResult) - 1, _T("Failed to save dump file to \"%s\".\r\n\r\nError: %lu"), szDumpPath, ::GetLastError()); + szResult[_countof(szResult) - 1] = _T('\0'); + } + ::CloseHandle(hFile); } else { // Do *NOT* localize that string (in fact, do not use MFC to load it)! - _sntprintf(szResult, _countof(szResult) - 1, _T("Failed to save dump file to \"%s\".\r\n\r\nError: %lu"), szDumpPath, ::GetLastError()); + _sntprintf(szResult, _countof(szResult) - 1, _T("Failed to create dump file \"%s\".\r\n\r\nError: %lu"), szDumpPath, ::GetLastError()); szResult[_countof(szResult) - 1] = _T('\0'); } - ::CloseHandle(hFile); - } else { - // Do *NOT* localize that string (in fact, do not use MFC to load it)! - _sntprintf(szResult, _countof(szResult) - 1, _T("Failed to create dump file \"%s\".\r\n\r\nError: %lu"), szDumpPath, ::GetLastError()); - szResult[_countof(szResult) - 1] = _T('\0'); + if (*szResult != _T('\0')) + MessageBox(NULL, szResult, m_szAppName, MB_ICONINFORMATION | MB_OK); } } FreeLibrary(hDll); } - if (szResult[0] != _T('\0')) - MessageBox(NULL, szResult, m_szAppName, MB_ICONINFORMATION | MB_OK); - #ifndef _DEBUG // Exit the process only in release builds, so that in debug builds the exception // is passed to a possible installed debugger diff --git a/srchybrid/MediaInfo.cpp b/srchybrid/MediaInfo.cpp index de165643..7bfdf7c2 100644 --- a/srchybrid/MediaInfo.cpp +++ b/srchybrid/MediaInfo.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -257,7 +257,7 @@ CString GetAudioFormatName(WORD wFormatTag, CString &rstrComment) CString GetAudioFormatName(WORD wFormatTag) { CString strComment; - CString strFormat = GetAudioFormatName(wFormatTag, strComment); + CString strFormat(GetAudioFormatName(wFormatTag, strComment)); if (!strComment.IsEmpty()) strFormat.AppendFormat(_T(" (%s)"), (LPCTSTR)strComment); return strFormat; @@ -298,6 +298,7 @@ bool IsEqualFOURCC(FOURCC fccA, FOURCC fccB) CString GetVideoFormatDisplayName(DWORD biCompression) { + CString sName; LPCSTR pFormat; switch (biCompression) { case BI_RGB: @@ -320,8 +321,9 @@ CString GetVideoFormatDisplayName(DWORD biCompression) break; default: { - unsigned char *cp = (unsigned char*)&biCompression; + sName = CStringA((LPCSTR)&biCompression, 4); DWORD fcc; + unsigned char *cp = (unsigned char*)&biCompression; for (int i = 0; i < sizeof(DWORD); ++i) ((byte*)&fcc)[i] = (byte)toupper(*cp++); @@ -409,12 +411,13 @@ CString GetVideoFormatDisplayName(DWORD biCompression) pFormat = " (Microsoft Video 1)"; break; default: - return CString(); + pFormat = NULL; } - return CString(CStringA((LPCSTR)&biCompression, 4) + pFormat); } } - return CString(pFormat); + if (pFormat) + sName += pFormat;; + return sName; } CString GetVideoFormatName(DWORD biCompression) @@ -490,7 +493,7 @@ CString GetCodecDisplayName(const CString &strCodecId) strCodecDisplayName = strCodecId; strCodecDisplayName.MakeUpper(); } - s_mapCodecDisplayName.SetAt(strCodecId, strCodecDisplayName); + s_mapCodecDisplayName[strCodecId] = strCodecDisplayName; return strCodecDisplayName; } @@ -568,12 +571,12 @@ static bool ParseStreamHeader(int hAviFile, DWORD dwLengthLeft, STREAMHEADER *pS memset(&pStrmHdr->hdr, 0x00, sizeof pStrmHdr->hdr); if (_read(hAviFile, &pStrmHdr->hdr, dwLength) != (int)dwLength) return false; - if (dwLength & 1 && _lseek(hAviFile, 1, SEEK_CUR) == -1) + if (dwLength & 1 && _lseek(hAviFile, 1, SEEK_CUR) < 0) return false; } else { if (_read(hAviFile, &pStrmHdr->hdr, sizeof pStrmHdr->hdr) != sizeof pStrmHdr->hdr) return false; - if (_lseek(hAviFile, dwLength + (dwLength & 1) - sizeof pStrmHdr->hdr, SEEK_CUR) == -1) + if (_lseek(hAviFile, (long)(dwLength + (dwLength & 1) - sizeof pStrmHdr->hdr), SEEK_CUR) < 0) return false; } dwLength = 0; @@ -592,7 +595,7 @@ static bool ParseStreamHeader(int hAviFile, DWORD dwLengthLeft, STREAMHEADER *pS if (_read(hAviFile, pStrmHdr->fmt.dat, dwLength) != (int)dwLength) return false; if (dwLength & 1) { - if (_lseek(hAviFile, 1, SEEK_CUR) == -1) + if (_lseek(hAviFile, 1, SEEK_CUR) < 0) return false; } dwLength = 0; @@ -609,17 +612,17 @@ static bool ParseStreamHeader(int hAviFile, DWORD dwLengthLeft, STREAMHEADER *pS if (_read(hAviFile, pStrmHdr->nam, dwLength) != (int)dwLength) return false; pStrmHdr->nam[dwLength] = '\0'; - if (dwLength & 1 && _lseek(hAviFile, 1, SEEK_CUR) == -1) + if (dwLength & 1 && _lseek(hAviFile, 1, SEEK_CUR) < 0) return false; dwLength = 0; } - if (dwLength && _lseek(hAviFile, dwLength + (dwLength & 1), SEEK_CUR) == -1) + if (dwLength && _lseek(hAviFile, dwLength + (dwLength & 1), SEEK_CUR) < 0) return false; } - return !(dwLengthLeft && _lseek(hAviFile, dwLengthLeft, SEEK_CUR) == -1); + return !(dwLengthLeft && _lseek(hAviFile, dwLengthLeft, SEEK_CUR) < 0); } bool GetRIFFHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsAVI, bool bFullInfo) @@ -628,7 +631,7 @@ bool GetRIFFHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsAVI, bool bFu // Open AVI file int hAviFile = _topen(pszFileName, O_RDONLY | O_BINARY); - if (hAviFile == -1) + if (hAviFile < 0) return false; DWORD dwLengthLeft; @@ -718,7 +721,7 @@ bool GetRIFFHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsAVI, bool bFu double fSamplesSec = (strmhdr.hdr.dwScale != 0) ? strmhdr.hdr.dwRate / (double)strmhdr.hdr.dwScale : 0.0; double fLength = (fSamplesSec != 0.0) ? strmhdr.hdr.dwLength / (double)fSamplesSec : 0.0; if (strmhdr.hdr.fccType == streamtypeAUDIO) { - mi->iAudioStreams++; + ++mi->iAudioStreams; if (mi->iAudioStreams == 1) { mi->fAudioLengthSec = fLength; if (strmhdr.fmt.wav && strmhdr.dwFormatLen >= sizeof *strmhdr.fmt.wav) { @@ -772,15 +775,12 @@ bool GetRIFFHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsAVI, bool bFu if (strmhdr.fmt.wav->wBitsPerSample) mi->strInfo << _T(" Bit/sample:\t") << strmhdr.fmt.wav->wBitsPerSample << _T(" Bit\n"); } - if (fLength) { - CString strLength; - SecToTimeLength((ULONG)fLength, strLength); - mi->strInfo << _T(" ") << GetResString(IDS_LENGTH) << _T(":\t") << strLength << _T("\n"); - } + if (fLength) + mi->strInfo << _T(" ") << GetResString(IDS_LENGTH) << _T(":\t") << SecToTimeLength((UINT)fLength) << _T("\n"); } } } else if (strmhdr.hdr.fccType == streamtypeVIDEO) { - mi->iVideoStreams++; + ++mi->iVideoStreams; if (mi->iVideoStreams == 1) { uVideoFrames = strmhdr.hdr.dwLength; mi->fVideoLengthSec = fLength; @@ -789,7 +789,7 @@ bool GetRIFFHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsAVI, bool bFu mi->video.bmiHeader = *strmhdr.fmt.bmi; mi->strVideoFormat = GetVideoFormatName(strmhdr.fmt.bmi->biCompression); if (strmhdr.fmt.bmi->biWidth && strmhdr.fmt.bmi->biHeight) - mi->fVideoAspectRatio = abs(strmhdr.fmt.bmi->biWidth / (double)strmhdr.fmt.bmi->biHeight); + mi->fVideoAspectRatio = fabs(strmhdr.fmt.bmi->biWidth / (double)strmhdr.fmt.bmi->biHeight); } } else { if (bFullInfo && mi->strInfo.m_hWnd) { @@ -805,15 +805,12 @@ bool GetRIFFHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsAVI, bool bFu mi->strInfo << _T(" ") << GetResString(IDS_CODEC) << _T(":\t") << GetVideoFormatName(strmhdr.fmt.bmi->biCompression) << _T("\n"); if (strmhdr.fmt.bmi->biWidth && strmhdr.fmt.bmi->biHeight) { mi->strInfo << _T(" ") << GetResString(IDS_WIDTH) << _T(" x ") << GetResString(IDS_HEIGHT) << _T(":\t") << abs(strmhdr.fmt.bmi->biWidth) << _T(" x ") << abs(strmhdr.fmt.bmi->biHeight) << _T("\n"); - float fAspectRatio = abs(strmhdr.fmt.bmi->biWidth / (float)strmhdr.fmt.bmi->biHeight); + float fAspectRatio = fabsf(strmhdr.fmt.bmi->biWidth / (float)strmhdr.fmt.bmi->biHeight); mi->strInfo << _T(" ") << GetResString(IDS_ASPECTRATIO) << _T(":\t") << fAspectRatio << _T(" (") << GetKnownAspectRatioDisplayString(fAspectRatio) << _T(")\n"); } } - if (fLength) { - CString strLength; - SecToTimeLength((ULONG)fLength, strLength); - mi->strInfo << _T(" ") << GetResString(IDS_LENGTH) << _T(":\t") << strLength << _T("\n"); - } + if (fLength) + mi->strInfo << _T(" ") << GetResString(IDS_LENGTH) << _T(":\t") << SecToTimeLength((UINT)fLength) << _T("\n"); } } } else { @@ -824,14 +821,11 @@ bool GetRIFFHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsAVI, bool bFu mi->OutputFileName(); mi->strInfo.SetSelectionCharFormat(mi->strInfo.m_cfBold); mi->strInfo << _T("Unknown Stream #") << iStream; - if (strmhdr.nam && strmhdr.nam[0] != '\0') + if (strmhdr.nam && *strmhdr.nam) mi->strInfo << _T(": \"") << strmhdr.nam << _T("\""); mi->strInfo << _T("\n"); - if (fLength) { - CString strLength; - SecToTimeLength((ULONG)fLength, strLength); - mi->strInfo << _T(" ") << GetResString(IDS_LENGTH) << _T(":\t") << strLength << _T("\n"); - } + if (fLength) + mi->strInfo << _T(" ") << GetResString(IDS_LENGTH) << _T(":\t") << SecToTimeLength((UINT)fLength) << _T("\n"); } } } @@ -930,7 +924,7 @@ bool GetRIFFHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsAVI, bool bFu bHaveReadAllStreams = true; else { if (dwLength & 1) { - if (_lseek(hAviFile, 1, SEEK_CUR) == -1) + if (_lseek(hAviFile, 1, SEEK_CUR) < 0) bHaveReadAllStreams = true; } dwLength = 0; @@ -944,10 +938,9 @@ bool GetRIFFHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsAVI, bool bFu MainAVIHeader avihdr; if (_read(hAviFile, &avihdr, sizeof avihdr) != sizeof avihdr) goto inv_format_errno; - if (dwLength & 1) - if (_lseek(hAviFile, 1, SEEK_CUR) == -1) - goto inv_format_errno; - + ASSERT(!(dwLength & 1)); //MainAVIHeader length is even; or uncomment next lines + //if ((dwLength & 1) && _lseek(hAviFile, 1, SEEK_CUR) < 0) + // goto inv_format_errno; dwLength = 0; } break; @@ -969,14 +962,14 @@ bool GetRIFFHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsAVI, bool bFu if (_read(hAviFile, strmhdr.fmt.dat, dwLength) != (int)dwLength) goto inv_format_errno; if (dwLength & 1) { - if (_lseek(hAviFile, 1, SEEK_CUR) == -1) + if (_lseek(hAviFile, 1, SEEK_CUR) < 0) goto inv_format_errno; } dwLength = 0; strmhdr.hdr.fccType = streamtypeAUDIO; if (strmhdr.dwFormatLen) { - mi->iAudioStreams++; + ++mi->iAudioStreams; if (mi->iAudioStreams == 1) { if (strmhdr.fmt.wav && strmhdr.dwFormatLen >= sizeof *strmhdr.fmt.wav) { *(PCMWAVEFORMAT*)&mi->audio = *strmhdr.fmt.wav; @@ -1002,7 +995,7 @@ bool GetRIFFHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsAVI, bool bFu if (bHaveReadAllStreams) break; if (dwLength) { - if (_lseek(hAviFile, dwLength + (dwLength & 1), SEEK_CUR) == -1) + if (_lseek(hAviFile, dwLength + (dwLength & 1), SEEK_CUR) < 0) goto inv_format_errno; } } @@ -1012,7 +1005,7 @@ bool GetRIFFHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsAVI, bool bFu // NOTE: This video bit rate is published to ed2k servers and Kad, so, do everything to determine it right! if (mi->iVideoStreams == 1 /*&& mi->iAudioStreams <= 1*/ && iNonAVStreams == 0 && mi->fVideoLengthSec) { - DWORD dwVideoFramesOverhead = uVideoFrames * (sizeof(WORD) + sizeof(WORD) + sizeof(DWORD)); + DWORD dwVideoFramesOverhead = (DWORD)(uVideoFrames * (sizeof(WORD) + sizeof(WORD) + sizeof(DWORD))); mi->video.dwBitRate = (DWORD)(((dwMovieChunkSize - dwVideoFramesOverhead) / mi->fVideoLengthSec - dwAllNonVideoAvgBytesPerSec/*mi->audio.nAvgBytesPerSec*/) * 8); } } else //if (fccMain == mmioFOURCC('W', 'A', 'V', 'E')) @@ -1160,7 +1153,7 @@ bool GetRMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsRM, bool bFullI CSafeBufferedFile file; if (!file.Open(pszFileName, CFile::modeRead | CFile::osSequentialScan | CFile::typeBinary)) return false; - setvbuf(file.m_pStream, NULL, _IOFBF, 16384); + ::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); bool bReadPROP = false; bool bReadMDPR_Video = false; @@ -1219,254 +1212,249 @@ bool GetRMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsRM, bool bFullI break; // expect broken DATA-chunk headers created by 'mplayer' ullChunkEndFilePos = ullChunkStartFilePos + dwSize; dwSize -= sizeof rmChunkHdr; - if (dwSize > 0) { - switch (dwID) { - case 'PROP': - { // Properties Header - file.Read(&wVersion, sizeof wVersion); - wVersion = _byteswap_ushort(wVersion); - if (wVersion == 0) { - SRmPROP rmPROP; - file.Read(&rmPROP, sizeof rmPROP); - nFileBitrate = _byteswap_ulong(rmPROP.avg_bit_rate); - mi->fFileLengthSec = (_byteswap_ulong(rmPROP.duration) + 500.0) / 1000.0; - bReadPROP = true; - } - } - break; - case 'MDPR': - { // Media Properties Header - file.Read(&wVersion, sizeof wVersion); - wVersion = _byteswap_ushort(wVersion); - if (wVersion == 0) { - SRmMDPR rmMDPR; - file.Read(&rmMDPR, sizeof rmMDPR); - - // Read 'Stream Name' - BYTE ucLen; - CStringA strStreamName; - file.Read(&ucLen, sizeof ucLen); - file.Read(strStreamName.GetBuffer(ucLen), ucLen); - strStreamName.ReleaseBuffer(ucLen); - - // Read 'MIME Type' - CStringA strMimeType; - file.Read(&ucLen, sizeof ucLen); - file.Read(strMimeType.GetBuffer(ucLen), ucLen); - strMimeType.ReleaseBuffer(ucLen); - - DWORD dwTypeDataLen; - file.Read(&dwTypeDataLen, sizeof dwTypeDataLen); - dwTypeDataLen = _byteswap_ulong(dwTypeDataLen); - - if (strMimeType == "video/x-pn-realvideo") { - mi->iVideoStreams++; - if (mi->iVideoStreams == 1) { - mi->video.dwBitRate = _byteswap_ulong(rmMDPR.avg_bit_rate); - mi->fVideoLengthSec = _byteswap_ulong(rmMDPR.duration) / 1000.0; - - if (dwTypeDataLen >= 22 + 2 && dwTypeDataLen < 8192) { - BYTE *pucTypeData = new BYTE[dwTypeDataLen]; - try { - file.Read(pucTypeData, dwTypeDataLen); - if (_byteswap_ulong(*(DWORD*)(pucTypeData + 4)) == 'VIDO') { - mi->strVideoFormat = GetRealMediaCodecInfo((LPCSTR)(pucTypeData + 8)); - mi->video.bmiHeader.biCompression = *(DWORD*)(pucTypeData + 8); - mi->video.bmiHeader.biWidth = _byteswap_ushort(*(WORD*)(pucTypeData + 12)); - mi->video.bmiHeader.biHeight = _byteswap_ushort(*(WORD*)(pucTypeData + 14)); - mi->fVideoAspectRatio = abs(mi->video.bmiHeader.biWidth / (double)mi->video.bmiHeader.biHeight); - mi->fVideoFrameRate = _byteswap_ushort(*(WORD*)(pucTypeData + 22)); - bReadMDPR_Video = true; - } - } catch (CException *ex) { - ex->Delete(); - delete[] pucTypeData; - break; - } - delete[] pucTypeData; + if (dwSize <= 0) + continue; + + switch (dwID) { + case 'PROP': // Properties Header + file.Read(&wVersion, sizeof wVersion); + wVersion = _byteswap_ushort(wVersion); + if (wVersion == 0) { + SRmPROP rmPROP; + file.Read(&rmPROP, sizeof rmPROP); + nFileBitrate = _byteswap_ulong(rmPROP.avg_bit_rate); + mi->fFileLengthSec = (_byteswap_ulong(rmPROP.duration) + 500.0) / 1000.0; + bReadPROP = true; + } + break; + case 'MDPR': // Media Properties Header + file.Read(&wVersion, sizeof wVersion); + wVersion = _byteswap_ushort(wVersion); + if (wVersion == 0) { + SRmMDPR rmMDPR; + file.Read(&rmMDPR, sizeof rmMDPR); + + // Read 'Stream Name' + BYTE ucLen; + CStringA strStreamName; + file.Read(&ucLen, sizeof ucLen); + file.Read(strStreamName.GetBuffer(ucLen), ucLen); + strStreamName.ReleaseBuffer(ucLen); + + // Read 'MIME Type' + file.Read(&ucLen, sizeof ucLen); + CStringA strMimeType; + file.Read(strMimeType.GetBuffer(ucLen), ucLen); + strMimeType.ReleaseBuffer(ucLen); + + DWORD dwTypeDataLen; + file.Read(&dwTypeDataLen, sizeof dwTypeDataLen); + dwTypeDataLen = _byteswap_ulong(dwTypeDataLen); + + if (strMimeType == "video/x-pn-realvideo") { + ++mi->iVideoStreams; + if (mi->iVideoStreams == 1) { + mi->video.dwBitRate = _byteswap_ulong(rmMDPR.avg_bit_rate); + mi->fVideoLengthSec = _byteswap_ulong(rmMDPR.duration) / 1000.0; + + if (dwTypeDataLen >= 22 + 2 && dwTypeDataLen < 8192) { + BYTE *pucTypeData = new BYTE[dwTypeDataLen]; + try { + file.Read(pucTypeData, dwTypeDataLen); + if (_byteswap_ulong(*(DWORD*)(pucTypeData + 4)) == 'VIDO') { + mi->strVideoFormat = GetRealMediaCodecInfo((LPCSTR)(pucTypeData + 8)); + mi->video.bmiHeader.biCompression = *(DWORD*)(pucTypeData + 8); + mi->video.bmiHeader.biWidth = _byteswap_ushort(*(WORD*)(pucTypeData + 12)); + mi->video.bmiHeader.biHeight = _byteswap_ushort(*(WORD*)(pucTypeData + 14)); + mi->fVideoAspectRatio = fabs(mi->video.bmiHeader.biWidth / (double)mi->video.bmiHeader.biHeight); + mi->fVideoFrameRate = _byteswap_ushort(*(WORD*)(pucTypeData + 22)); + bReadMDPR_Video = true; } + } catch (CException *ex) { + ex->Delete(); + delete[] pucTypeData; + break; } - } else if (strMimeType == "audio/x-pn-realaudio") { - mi->iAudioStreams++; - if (mi->iAudioStreams == 1) { - mi->audio.nAvgBytesPerSec = _byteswap_ulong(rmMDPR.avg_bit_rate) / 8; - mi->fAudioLengthSec = _byteswap_ulong(rmMDPR.duration) / 1000.0; - - if (dwTypeDataLen >= 4 + 2 && dwTypeDataLen < 8192) { - BYTE *pucTypeData = new BYTE[dwTypeDataLen]; - try { - file.Read(pucTypeData, dwTypeDataLen); - DWORD dwFourCC = *(DWORD*)(pucTypeData + 0); - WORD wVer = _byteswap_ushort(*(WORD*)(pucTypeData + 4)); - if (dwFourCC == MAKEFOURCC('.', 'r', 'a', '\xFD')) { - if (wVer == 3) { - if (dwTypeDataLen >= 8 + 2) { - mi->audio.nSamplesPerSec = 8000; - mi->audio.nChannels = _byteswap_ushort(*(WORD*)(pucTypeData + 8)); - mi->strAudioFormat = _T(".ra3"); - bReadMDPR_Audio = true; - } - } else if (wVer == 4) { // RealAudio G2, RealAudio 8 - if (dwTypeDataLen >= 62 + 4) { - mi->audio.nSamplesPerSec = _byteswap_ushort(*(WORD*)(pucTypeData + 48)); - mi->audio.nChannels = _byteswap_ushort(*(WORD*)(pucTypeData + 54)); - if (strncmp((LPCSTR)(pucTypeData + 62), "sipr", 4) == 0) - mi->audio.wFormatTag = WAVE_FORMAT_SIPROLAB_ACEPLNET; - else if (strncmp((LPCSTR)(pucTypeData + 62), "cook", 4) == 0) - mi->audio.wFormatTag = 0x2004; - mi->strAudioFormat = GetRealMediaCodecInfo((LPCSTR)(pucTypeData + 62)); - bReadMDPR_Audio = true; - } - } else if (wVer == 5) { - if (dwTypeDataLen >= 66 + 4) { - mi->audio.nSamplesPerSec = _byteswap_ulong(*(DWORD*)(pucTypeData + 48)); - mi->audio.nChannels = _byteswap_ushort(*(WORD*)(pucTypeData + 60)); - if (strncmp((LPCSTR)(pucTypeData + 62), "sipr", 4) == 0) - mi->audio.wFormatTag = WAVE_FORMAT_SIPROLAB_ACEPLNET; - else if (strncmp((LPCSTR)(pucTypeData + 62), "cook", 4) == 0) - mi->audio.wFormatTag = 0x2004; - mi->strAudioFormat = GetRealMediaCodecInfo((LPCSTR)(pucTypeData + 66)); - bReadMDPR_Audio = true; - } - } + delete[] pucTypeData; + } + } + } else if (strMimeType == "audio/x-pn-realaudio") { + ++mi->iAudioStreams; + if (mi->iAudioStreams == 1) { + mi->audio.nAvgBytesPerSec = _byteswap_ulong(rmMDPR.avg_bit_rate) / 8; + mi->fAudioLengthSec = _byteswap_ulong(rmMDPR.duration) / 1000.0; + + if (dwTypeDataLen >= 4 + 2 && dwTypeDataLen < 8192) { + BYTE *pucTypeData = new BYTE[dwTypeDataLen]; + try { + file.Read(pucTypeData, dwTypeDataLen); + DWORD dwFourCC = *(DWORD*)(pucTypeData + 0); + WORD wVer = _byteswap_ushort(*(WORD*)(pucTypeData + 4)); + if (dwFourCC == MAKEFOURCC('.', 'r', 'a', '\xFD')) { + if (wVer == 3) { + if (dwTypeDataLen >= 8 + 2) { + mi->audio.nSamplesPerSec = 8000; + mi->audio.nChannels = _byteswap_ushort(*(WORD*)(pucTypeData + 8)); + mi->strAudioFormat = _T(".ra3"); + bReadMDPR_Audio = true; } - } catch (CException *ex) { - ex->Delete(); - delete[] pucTypeData; - break; - } - delete[] pucTypeData; - } - } - } else if (bFullInfo && strcmp(strMimeType, "logical-fileinfo") == 0) { - DWORD dwLogStreamLen; - file.Read(&dwLogStreamLen, sizeof dwLogStreamLen); - dwLogStreamLen = _byteswap_ulong(dwLogStreamLen); - - file.Read(&wVersion, sizeof wVersion); - wVersion = _byteswap_ushort(wVersion); - if (wVersion == 0) { - WORD wStreams; - file.Read(&wStreams, sizeof wStreams); - wStreams = _byteswap_ushort(wStreams); - - // Skip 'Physical Stream Numbers' - file.Seek(wStreams * sizeof(WORD), CFile::current); - - // Skip 'Data Offsets' - file.Seek(wStreams * sizeof(DWORD), CFile::current); - - WORD wRules; - file.Read(&wRules, sizeof wRules); - wRules = _byteswap_ushort(wRules); - - // Skip 'Rule to Physical Stream Number Map' - file.Seek(wRules * sizeof(WORD), CFile::current); - - WORD wProperties; - file.Read(&wProperties, sizeof wProperties); - wProperties = _byteswap_ushort(wProperties); - - while (wProperties) { - DWORD dwPropSize; - file.Read(&dwPropSize, sizeof dwPropSize); - dwPropSize = _byteswap_ulong(dwPropSize); - - WORD wPropVersion; - file.Read(&wPropVersion, sizeof wPropVersion); - wPropVersion = _byteswap_ushort(wPropVersion); - - if (wPropVersion == 0) { - BYTE ucLen1; - CStringA strPropNameA; - file.Read(&ucLen1, sizeof ucLen1); - file.Read(strPropNameA.GetBuffer(ucLen1), ucLen1); - strPropNameA.ReleaseBuffer(ucLen1); - - DWORD dwPropType; - file.Read(&dwPropType, sizeof dwPropType); - dwPropType = _byteswap_ulong(dwPropType); - - WORD wPropValueLen; - file.Read(&wPropValueLen, sizeof wPropValueLen); - wPropValueLen = _byteswap_ushort(wPropValueLen); - - CStringA strPropValueA; - if (dwPropType == 0 && wPropValueLen == sizeof(DWORD)) { - DWORD dwPropValue; - file.Read(&dwPropValue, sizeof dwPropValue); - dwPropValue = _byteswap_ulong(dwPropValue); - strPropValueA.Format("%u", dwPropValue); - } else if (dwPropType == 2) { - LPSTR pszA = strPropValueA.GetBuffer(wPropValueLen); - file.Read(pszA, wPropValueLen); - if (wPropValueLen > 0 && pszA[wPropValueLen - 1] == '\0') - --wPropValueLen; - strPropValueA.ReleaseBuffer(wPropValueLen); - } else { - file.Seek(wPropValueLen, CFile::current); - strPropValueA.Format("<%u bytes>", wPropValueLen); + } else if (wVer == 4) { // RealAudio G2, RealAudio 8 + if (dwTypeDataLen >= 62 + 4) { + mi->audio.nSamplesPerSec = _byteswap_ushort(*(WORD*)(pucTypeData + 48)); + mi->audio.nChannels = _byteswap_ushort(*(WORD*)(pucTypeData + 54)); + if (strncmp((LPCSTR)(pucTypeData + 62), "sipr", 4) == 0) + mi->audio.wFormatTag = WAVE_FORMAT_SIPROLAB_ACEPLNET; + else if (strncmp((LPCSTR)(pucTypeData + 62), "cook", 4) == 0) + mi->audio.wFormatTag = 0x2004; + mi->strAudioFormat = GetRealMediaCodecInfo((LPCSTR)(pucTypeData + 62)); + bReadMDPR_Audio = true; } - - aFileProps.Add(SRmFileProp(strPropNameA, strPropValueA)); - TRACE("Prop: %s, typ=%u, size=%u, value=%s\n", (LPCSTR)strPropNameA, dwPropType, wPropValueLen, (LPCSTR)strPropValueA); - } else - file.Seek(dwPropSize - sizeof(DWORD) - sizeof(WORD), CFile::current); - - --wProperties; + } else if (wVer == 5) { + if (dwTypeDataLen >= 66 + 4) { + mi->audio.nSamplesPerSec = _byteswap_ulong(*(DWORD*)(pucTypeData + 48)); + mi->audio.nChannels = _byteswap_ushort(*(WORD*)(pucTypeData + 60)); + if (strncmp((LPCSTR)(pucTypeData + 62), "sipr", 4) == 0) + mi->audio.wFormatTag = WAVE_FORMAT_SIPROLAB_ACEPLNET; + else if (strncmp((LPCSTR)(pucTypeData + 62), "cook", 4) == 0) + mi->audio.wFormatTag = 0x2004; + mi->strAudioFormat = GetRealMediaCodecInfo((LPCSTR)(pucTypeData + 66)); + bReadMDPR_Audio = true; + } + } } - bReadMDPR_File = true; + } catch (CException *ex) { + ex->Delete(); + delete[] pucTypeData; + break; } + delete[] pucTypeData; } } - } - break; - case 'CONT': - { // Content Description Header + } else if (bFullInfo && strcmp(strMimeType, "logical-fileinfo") == 0) { + DWORD dwLogStreamLen; + file.Read(&dwLogStreamLen, sizeof dwLogStreamLen); + dwLogStreamLen = _byteswap_ulong(dwLogStreamLen); + file.Read(&wVersion, sizeof wVersion); wVersion = _byteswap_ushort(wVersion); if (wVersion == 0) { - WORD wLen; - CStringA strA; - file.Read(&wLen, sizeof wLen); - wLen = _byteswap_ushort(wLen); - file.Read(strA.GetBuffer(wLen), wLen); - strA.ReleaseBuffer(wLen); - mi->strTitle = strA; - - file.Read(&wLen, sizeof wLen); - wLen = _byteswap_ushort(wLen); - file.Read(strA.GetBuffer(wLen), wLen); - strA.ReleaseBuffer(wLen); - mi->strAuthor = strA; - - file.Read(&wLen, sizeof wLen); - wLen = _byteswap_ushort(wLen); - file.Read(strA.GetBuffer(wLen), wLen); - strA.ReleaseBuffer(wLen); - strCopyright = strA; - - file.Read(&wLen, sizeof wLen); - wLen = _byteswap_ushort(wLen); - file.Read(strA.GetBuffer(wLen), wLen); - strA.ReleaseBuffer(wLen); - strComment = strA; - bReadCONT = true; + WORD wStreams; + file.Read(&wStreams, sizeof wStreams); + wStreams = _byteswap_ushort(wStreams); + + // Skip 'Physical Stream Numbers' + file.Seek(wStreams * sizeof(WORD), CFile::current); + + // Skip 'Data Offsets' + file.Seek(wStreams * sizeof(DWORD), CFile::current); + + WORD wRules; + file.Read(&wRules, sizeof wRules); + wRules = _byteswap_ushort(wRules); + + // Skip 'Rule to Physical Stream Number Map' + file.Seek(wRules * sizeof(WORD), CFile::current); + + WORD wProperties; + file.Read(&wProperties, sizeof wProperties); + wProperties = _byteswap_ushort(wProperties); + + while (wProperties) { + DWORD dwPropSize; + file.Read(&dwPropSize, sizeof dwPropSize); + dwPropSize = _byteswap_ulong(dwPropSize); + + WORD wPropVersion; + file.Read(&wPropVersion, sizeof wPropVersion); + wPropVersion = _byteswap_ushort(wPropVersion); + + if (wPropVersion == 0) { + BYTE ucLen1; + file.Read(&ucLen1, sizeof ucLen1); + CStringA strPropNameA; + file.Read(strPropNameA.GetBuffer(ucLen1), ucLen1); + strPropNameA.ReleaseBuffer(ucLen1); + + DWORD dwPropType; + file.Read(&dwPropType, sizeof dwPropType); + dwPropType = _byteswap_ulong(dwPropType); + + WORD wPropValueLen; + file.Read(&wPropValueLen, sizeof wPropValueLen); + wPropValueLen = _byteswap_ushort(wPropValueLen); + + CStringA strPropValueA; + if (dwPropType == 0 && wPropValueLen == sizeof(DWORD)) { + DWORD dwPropValue; + file.Read(&dwPropValue, sizeof dwPropValue); + dwPropValue = _byteswap_ulong(dwPropValue); + strPropValueA.Format("%u", dwPropValue); + } else if (dwPropType == 2) { + LPSTR pszA = strPropValueA.GetBuffer(wPropValueLen); + file.Read(pszA, wPropValueLen); + if (wPropValueLen > 0 && pszA[wPropValueLen - 1] == '\0') + --wPropValueLen; + strPropValueA.ReleaseBuffer(wPropValueLen); + } else { + file.Seek(wPropValueLen, CFile::current); + strPropValueA.Format("<%u bytes>", wPropValueLen); + } + + aFileProps.Add(SRmFileProp(strPropNameA, strPropValueA)); + TRACE("Prop: %s, typ=%u, size=%u, value=%s\n", (LPCSTR)strPropNameA, dwPropType, wPropValueLen, (LPCSTR)strPropValueA); + } else + file.Seek(dwPropSize - sizeof(DWORD) - sizeof(WORD), CFile::current); + + --wProperties; + } + bReadMDPR_File = true; } } - break; - case 'DATA': - case 'INDX': - case 'RMMD': - case 'RMJE': - // Expect broken DATA-chunk headers created by 'mplayer'. Thus catch - // all valid tags just to have chance to detect the broken ones. - break; - default: - // Expect broken DATA-chunk headers created by 'mplayer'. Stop reading - // the file on first broken chunk header. - bBrokenFile = true; } + break; + case 'CONT': // Content Description Header + file.Read(&wVersion, sizeof wVersion); + wVersion = _byteswap_ushort(wVersion); + if (wVersion == 0) { + WORD wLen; + file.Read(&wLen, sizeof wLen); + wLen = _byteswap_ushort(wLen); + CStringA strA; + file.Read(strA.GetBuffer(wLen), wLen); + strA.ReleaseBuffer(wLen); + mi->strTitle = strA; + + file.Read(&wLen, sizeof wLen); + wLen = _byteswap_ushort(wLen); + file.Read(strA.GetBuffer(wLen), wLen); + strA.ReleaseBuffer(wLen); + mi->strAuthor = strA; + + file.Read(&wLen, sizeof wLen); + wLen = _byteswap_ushort(wLen); + file.Read(strA.GetBuffer(wLen), wLen); + strA.ReleaseBuffer(wLen); + strCopyright = strA; + + file.Read(&wLen, sizeof wLen); + wLen = _byteswap_ushort(wLen); + file.Read(strA.GetBuffer(wLen), wLen); + strA.ReleaseBuffer(wLen); + strComment = strA; + bReadCONT = true; + } + break; + case 'DATA': + case 'INDX': + case 'RMMD': + case 'RMJE': + // Expect broken DATA-chunk headers created by 'mplayer'. Thus catch + // all valid tags just to have chance to detect the broken ones. + break; + default: + // Expect broken DATA-chunk headers created by 'mplayer'. Stop reading + // the file on first broken chunk header. + bBrokenFile = true; } } } catch (CException *ex) { @@ -1509,7 +1497,7 @@ bool GetRMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsRM, bool bFullI mi->strInfo << _T(" ") << GetResString(IDS_COMMENT) << _T(":\t") << strComment << _T("\n"); for (int i = 0; i < aFileProps.GetCount(); ++i) if (!aFileProps[i].strValue.IsEmpty()) - mi->strInfo << _T(" ") << CString(aFileProps[i].strName) << _T(":\t") << CString(aFileProps[i].strValue) << _T("\n"); + mi->strInfo << _T(" ") << (CString)aFileProps[i].strName << _T(":\t") << (CString)aFileProps[i].strValue << _T("\n"); } return true; @@ -1549,15 +1537,14 @@ bool GetAttribute(IWMHeaderInfo *pIWMHeaderInfo, WORD wStream, LPCWSTR pwszName, return GetAttributeT(pIWMHeaderInfo, wStream, pwszName, nData); } -bool GetAttribute(IWMHeaderInfo *pIWMHeaderInfo, WORD wStream, LPCWSTR pwszName, CString &strValue) +bool GetAttribute(IWMHeaderInfo *pIWMHeaderInfo, WORD wStream, LPCWSTR pwszName, CStringW &strValue) { + strValue.Empty(); //prepare for the worst WMT_ATTR_DATATYPE attrType; WORD wValueSize; HRESULT hr = pIWMHeaderInfo->GetAttributeByName(&wStream, pwszName, &attrType, NULL, &wValueSize); - if (hr == ASF_E_NOTFOUND) - return false; if (hr != S_OK || attrType != WMT_TYPE_STRING || wValueSize < sizeof(WCHAR) || (wValueSize % sizeof(WCHAR)) != 0) { - ASSERT(0); + ASSERT(hr == ASF_E_NOTFOUND || hr == E_INVALIDARG); //E_INVALIDARG returned if no "WM/Language" tag? return false; } @@ -1576,7 +1563,7 @@ bool GetAttribute(IWMHeaderInfo *pIWMHeaderInfo, WORD wStream, LPCWSTR pwszName, return false; // SDK states that MP3 files could contain a BOM - never seen - if (*(LPCWSTR)strValue == 0xFFFEui16 || *(LPCWSTR)strValue == 0xFEFFui16) { + if (strValue[0] == u'\xFFFE' || strValue[0] == u'\xFEFF') { ASSERT(0); strValue.Delete(0, 1); } @@ -1588,16 +1575,11 @@ bool GetAttributeIndices(IWMHeaderInfo3 *pIWMHeaderInfo, WORD wStream, LPCWSTR p { WORD wIndexCount; HRESULT hr = pIWMHeaderInfo->GetAttributeIndices(wStream, pwszName, &wLangIndex, NULL, &wIndexCount); - if (hr == ASF_E_NOTFOUND) - return false; - if (hr != S_OK) { - ASSERT(0); + if (hr != S_OK || wIndexCount == 0) { + ASSERT(hr == ASF_E_NOTFOUND); return false; } - if (wIndexCount == 0) - return false; - hr = pIWMHeaderInfo->GetAttributeIndices(wStream, pwszName, &wLangIndex, aIndices.Allocate(wIndexCount), &wIndexCount); if (hr != S_OK || wIndexCount == 0) { ASSERT(0); @@ -1695,8 +1677,9 @@ bool GetAttributeEx(IWMHeaderInfo3 *pIWMHeaderInfo, WORD wStream, LPCWSTR pwszNa return true; } -bool GetAttributeEx(IWMHeaderInfo3 *pIWMHeaderInfo, WORD wStream, LPCWSTR pwszName, CString &strValue) +bool GetAttributeEx(IWMHeaderInfo3 *pIWMHeaderInfo, WORD wStream, LPCWSTR pwszName, CStringW &strValue) { + strValue.Empty(); CTempBuffer aIndices; WORD wLangIndex = 0; if (!GetAttributeIndices(pIWMHeaderInfo, wStream, pwszName, aIndices, wLangIndex)) @@ -1722,7 +1705,7 @@ bool GetAttributeEx(IWMHeaderInfo3 *pIWMHeaderInfo, WORD wStream, LPCWSTR pwszNa if (dwValueSize == sizeof(WCHAR)) return false; - hr = pIWMHeaderInfo->GetAttributeByIndexEx(wStream, wIndex, wszName, &wNameSize, &attrType, &wLangIndex, (BYTE*)strValue.GetBuffer(dwValueSize / sizeof(WCHAR)), &dwValueSize); + hr = pIWMHeaderInfo->GetAttributeByIndexEx(wStream, wIndex, wszName, &wNameSize, &attrType, &wLangIndex, (BYTE*)strValue.GetBuffer((int)(dwValueSize / sizeof(WCHAR))), &dwValueSize); strValue.ReleaseBuffer(); if (hr != S_OK || attrType != WMT_TYPE_STRING) { ASSERT(0); @@ -1733,7 +1716,7 @@ bool GetAttributeEx(IWMHeaderInfo3 *pIWMHeaderInfo, WORD wStream, LPCWSTR pwszNa return false; // SDK states that MP3 files could contain a BOM - never seen - if (*(LPCWSTR)strValue == 0xFFFEui16 || *(LPCWSTR)strValue == 0xFEFFui16) { + if (strValue[0] == u'\xFFFE' || strValue[0] == u'\xFEFF') { ASSERT(0); strValue.Delete(0, 1); } @@ -1775,12 +1758,12 @@ class CFileStream : public IStream STDMETHODIMP_(ULONG) AddRef() { - return static_cast(InterlockedIncrement(&m_lRefCount)); + return static_cast(::InterlockedIncrement(&m_lRefCount)); } STDMETHODIMP_(ULONG) Release() { - LONG lRefCount = InterlockedDecrement(&m_lRefCount); + LONG lRefCount = ::InterlockedDecrement(&m_lRefCount); if (lRefCount == 0) delete this; return static_cast(lRefCount); @@ -2010,7 +1993,7 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI if (pIUnkReader == NULL) { CComPtr pIWMMetadataEditor; if (theWmvCoreDLL.m_pfnWMCreateEditor != NULL && (hr = (*theWmvCoreDLL.m_pfnWMCreateEditor)(&pIWMMetadataEditor)) == S_OK) { - CComQIPtr pIWMMetadataEditor2 = pIWMMetadataEditor; + CComQIPtr pIWMMetadataEditor2(pIWMMetadataEditor); if (pIWMMetadataEditor2 && (hr = pIWMMetadataEditor2->OpenEx(pszFileName, GENERIC_READ, FILE_SHARE_READ)) == S_OK) pIUnkReader = pIWMMetadataEditor2; //This Open() call unpacks files compressed with "compact /exe:lzx"; assumed to be obsolete @@ -2050,7 +2033,7 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI ); if (pIUnkReader) { - CComQIPtr pIWMHeaderInfo = pIUnkReader; + CComQIPtr pIWMHeaderInfo(pIUnkReader); if (pIWMHeaderInfo) { // Although it is not following any logic, using "IWMHeaderInfo3" instead of "IWMHeaderInfo" // gives a few more (important) stream properties !? @@ -2087,7 +2070,7 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI // WM/StreamTypeInfo: No! // Codec Info: Yes // - CComQIPtr pIWMHeaderInfo3 = pIUnkReader; + CComQIPtr pIWMHeaderInfo3(pIUnkReader); WORD wStream = 0; // 0 = file level, 0xffff = all attributes from file and all streams @@ -2106,7 +2089,7 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI // We do not want to announce non-MP3 files as MP3 files by accident. // if (!bFullInfo) { - LPCTSTR pszExt = PathFindExtension(pszFileName); + LPCTSTR pszExt = ::PathFindExtension(pszFileName); if (_tcsicmp(pszExt, _T(".mp3")) != 0 && _tcsicmp(pszExt, _T(".mpa")) != 0 && _tcsicmp(pszExt, _T(".wav")) != 0) throw new CNotSupportedException(); } @@ -2137,12 +2120,12 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI else ASSERT(0); - CString strValue; - if (GetAttribute(pIWMHeaderInfo, wStream, g_wszWMTitle, strValue) && !strValue.IsEmpty()) + CStringW strValue; + if (GetAttribute(pIWMHeaderInfo, wStream, g_wszWMTitle, strValue)) mi->strTitle = strValue; - if (GetAttribute(pIWMHeaderInfo, wStream, g_wszWMAuthor, strValue) && !strValue.IsEmpty()) + if (GetAttribute(pIWMHeaderInfo, wStream, g_wszWMAuthor, strValue)) mi->strAuthor = strValue; - if (GetAttribute(pIWMHeaderInfo, wStream, g_wszWMAlbumTitle, strValue) && !strValue.IsEmpty()) + if (GetAttribute(pIWMHeaderInfo, wStream, g_wszWMAlbumTitle, strValue)) mi->strAlbum = strValue; if (bFullInfo && mi->strInfo.m_hWnd) { @@ -2206,10 +2189,8 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI if (pIWMHeaderInfo3) { if (pIWMHeaderInfo3->GetAttributeCountEx(wStream, &wAttributes) != S_OK) break; - } else { - if (pIWMHeaderInfo->GetAttributeCount(wStream, &wAttributes) != S_OK) - break; - } + } else if (pIWMHeaderInfo->GetAttributeCount(wStream, &wAttributes) != S_OK) + break; if (bFullInfo && mi->strAudioLanguage.IsEmpty()) { CString strLanguage; @@ -2226,7 +2207,7 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI const WM_STREAM_TYPE_INFO *pStreamTypeInfo = (WM_STREAM_TYPE_INFO*)(BYTE*)aStreamInfo; if (pStreamTypeInfo->guidMajorType == WMMEDIATYPE_Video) { bHaveStreamInfo = true; - mi->iVideoStreams++; + ++mi->iVideoStreams; if (dwStreamInfoSize >= sizeof(WM_STREAM_TYPE_INFO) + sizeof(WMVIDEOINFOHEADER) && pStreamTypeInfo->cbFormat >= sizeof(WMVIDEOINFOHEADER)) { @@ -2236,7 +2217,7 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI if (mi->iVideoStreams == 1) { mi->video = *(VIDEOINFOHEADER*)pVideoInfo; if (mi->video.bmiHeader.biWidth && mi->video.bmiHeader.biHeight) - mi->fVideoAspectRatio = abs(mi->video.bmiHeader.biWidth / (double)mi->video.bmiHeader.biHeight); + mi->fVideoAspectRatio = fabs(mi->video.bmiHeader.biWidth / (double)mi->video.bmiHeader.biHeight); mi->strVideoFormat = GetVideoFormatName(pVideoInfo->bmiHeader.biCompression); if (pVideoInfo->bmiHeader.biCompression == MAKEFOURCC('D', 'V', 'R', ' ') @@ -2265,7 +2246,7 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI if (pMPEG2VideoInfo->hdr.dwPictAspectRatioX != 0 && pMPEG2VideoInfo->hdr.dwPictAspectRatioY != 0) mi->fVideoAspectRatio = pMPEG2VideoInfo->hdr.dwPictAspectRatioX / (double)pMPEG2VideoInfo->hdr.dwPictAspectRatioY; else if (mi->video.bmiHeader.biWidth && mi->video.bmiHeader.biHeight) - mi->fVideoAspectRatio = abs(mi->video.bmiHeader.biWidth / (double)mi->video.bmiHeader.biHeight); + mi->fVideoAspectRatio = fabs(mi->video.bmiHeader.biWidth / (double)mi->video.bmiHeader.biHeight); } } if (mi->fVideoFrameRate == 0.0 && mi->video.AvgTimePerFrame) @@ -2281,7 +2262,7 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI if (pVideoInfo->dwBitRate) mi->strInfo << _T(" ") << GetResString(IDS_BITRATE) << _T(":\t") << (UINT)((pVideoInfo->dwBitRate + 500) / 1000) << _T(" kbit/s\n"); mi->strInfo << _T(" ") << GetResString(IDS_WIDTH) << _T(" x ") << GetResString(IDS_HEIGHT) << _T(":\t") << abs(pVideoInfo->bmiHeader.biWidth) << _T(" x ") << abs(pVideoInfo->bmiHeader.biHeight) << _T("\n"); - float fAspectRatio = abs(pVideoInfo->bmiHeader.biWidth / (float)pVideoInfo->bmiHeader.biHeight); + float fAspectRatio = fabsf(pVideoInfo->bmiHeader.biWidth / (float)pVideoInfo->bmiHeader.biHeight); mi->strInfo << _T(" ") << GetResString(IDS_ASPECTRATIO) << _T(":\t") << fAspectRatio << _T(" (") << GetKnownAspectRatioDisplayString(fAspectRatio) << _T(")\n"); if (pVideoInfo->AvgTimePerFrame) { @@ -2300,7 +2281,7 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI } } else if (pStreamTypeInfo->guidMajorType == WMMEDIATYPE_Audio) { bHaveStreamInfo = true; - mi->iAudioStreams++; + ++mi->iAudioStreams; if (dwStreamInfoSize >= sizeof(WM_STREAM_TYPE_INFO) + sizeof(WAVEFORMATEX) && pStreamTypeInfo->cbFormat >= sizeof(WAVEFORMATEX)) { @@ -2450,11 +2431,11 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI } else if (strDevTempl == _T("I1")) { streamCodecType = WMT_CODECINFO_VIDEO; uStreamType = IDS_VIDEO; - strStreamInfo += _T("Video Image Level 1, <= 352 x 288, 192 kbit/s"); + strStreamInfo += _T("Video Image Level 1, <= 352 x 288, 192 Kbit/s"); } else if (strDevTempl == _T("I2")) { streamCodecType = WMT_CODECINFO_VIDEO; uStreamType = IDS_VIDEO; - strStreamInfo += _T("Video Image Level 2, <= 1024 x 768, 384 kbit/s"); + strStreamInfo += _T("Video Image Level 2, <= 1024 x 768, 384 Kbit/s"); } else if (strDevTempl == _T("I")) { streamCodecType = WMT_CODECINFO_VIDEO; uStreamType = IDS_VIDEO; @@ -2467,7 +2448,7 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI CString strCodecName; CString strCodecDesc; if (streamCodecType != WMT_CODECINFO_UNKNOWN) { - CComQIPtr pIWMHeaderInfo2 = pIUnkReader; + CComQIPtr pIWMHeaderInfo2(pIUnkReader); if (pIWMHeaderInfo2) { DWORD dwCodecInfos; if ((hr = pIWMHeaderInfo2->GetCodecInfoCount(&dwCodecInfos)) == S_OK) { @@ -2518,7 +2499,7 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI GetAttributeEx(pIWMHeaderInfo3, wStream, g_wszWMPeakBitrate, dwBitrate); if (streamCodecType == WMT_CODECINFO_VIDEO) { - mi->iVideoStreams++; + ++mi->iVideoStreams; if (mi->iVideoStreams == 1) { mi->video.bmiHeader.biCompression = dwCodecId; mi->strVideoFormat = GetVideoFormatName(dwCodecId); @@ -2550,10 +2531,10 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI if (!strStreamInfo.IsEmpty()) mi->strInfo << _T(" Device Conformance:\t") << strStreamInfo << _T("\n"); if (dwBitrate) - mi->strInfo << _T(" ") << GetResString(IDS_BITRATE) << _T(":\t") << (UINT)((dwBitrate + 500) / 1000) << _T(" kbit/s\n"); + mi->strInfo << _T(" ") << GetResString(IDS_BITRATE) << _T(":\t") << (UINT)((dwBitrate + 500) / 1000) << _T(" Kbit/s\n"); } } else if (streamCodecType == WMT_CODECINFO_AUDIO) { - mi->iAudioStreams++; + ++mi->iAudioStreams; if (mi->iAudioStreams == 1) { mi->audio.wFormatTag = (WORD)dwCodecId; mi->strAudioFormat = GetAudioFormatName((WORD)dwCodecId); @@ -2585,7 +2566,7 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI if (!strStreamInfo.IsEmpty()) mi->strInfo << _T(" Device Conformance:\t") << strStreamInfo << _T("\n"); if (dwBitrate) - mi->strInfo << _T(" ") << GetResString(IDS_BITRATE) << _T(":\t") << (UINT)((dwBitrate + 500) / 1000) << _T(" kbit/s\n"); + mi->strInfo << _T(" ") << GetResString(IDS_BITRATE) << _T(":\t") << (UINT)((dwBitrate + 500) / 1000) << _T(" Kbit/s\n"); } } else if (bFullInfo && mi->strInfo.m_hWnd) { mi->OutputFileName(); @@ -2596,7 +2577,7 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI if (!strStreamInfo.IsEmpty()) mi->strInfo << _T(" Device Conformance:\t") << strStreamInfo << _T("\n"); if (dwBitrate) - mi->strInfo << _T(" ") << GetResString(IDS_BITRATE) << _T(":\t") << (UINT)((dwBitrate + 500) / 1000) << _T(" kbit/s\n"); + mi->strInfo << _T(" ") << GetResString(IDS_BITRATE) << _T(":\t") << (UINT)((dwBitrate + 500) / 1000) << _T(" Kbit/s\n"); } } } @@ -2613,7 +2594,7 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI BOOL bHasVideo = FALSE; GetAttribute(pIWMHeaderInfo, 0, g_wszWMHasVideo, bHasVideo); if (bHasAudio || bHasVideo) { - CComQIPtr pIWMHeaderInfo2 = pIUnkReader; + CComQIPtr pIWMHeaderInfo2(pIUnkReader); if (pIWMHeaderInfo2) { DWORD dwCodecInfos; if ((hr = pIWMHeaderInfo2->GetCodecInfoCount(&dwCodecInfos)) == S_OK) { @@ -2629,10 +2610,10 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI CString strName; CString strDesc; CTempBuffer aCodecInfo; - hr = pIWMHeaderInfo2->GetCodecInfo(dwCodec, - &wNameSize, bFullInfo ? strName.GetBuffer(wNameSize) : NULL, - &wDescSize, bFullInfo ? strDesc.GetBuffer(wDescSize) : NULL, - &codecType, &wCodecInfoSize, aCodecInfo.Allocate(wCodecInfoSize)); + hr = pIWMHeaderInfo2->GetCodecInfo(dwCodec + , &wNameSize, bFullInfo ? strName.GetBuffer(wNameSize) : NULL + , &wDescSize, bFullInfo ? strDesc.GetBuffer(wDescSize) : NULL + , &codecType, &wCodecInfoSize, aCodecInfo.Allocate(wCodecInfoSize)); strName.ReleaseBuffer(); strName.Trim(); strDesc.ReleaseBuffer(); @@ -2642,7 +2623,7 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI if (wCodecInfoSize == sizeof(WORD)) { if (!bAddedBakedAudioStream) { bAddedBakedAudioStream = true; - mi->iAudioStreams++; + ++mi->iAudioStreams; mi->audio.wFormatTag = *(WORD*)(BYTE*)aCodecInfo; mi->strAudioFormat = GetAudioFormatName(mi->audio.wFormatTag); if (bFullInfo && mi->strInfo.m_hWnd && (!strName.IsEmpty() || !strDesc.IsEmpty())) { @@ -2662,7 +2643,7 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI // MP3 files: no codec info returned if (!bAddedBakedAudioStream) { bAddedBakedAudioStream = true; - mi->iAudioStreams++; + ++mi->iAudioStreams; mi->audio.wFormatTag = WAVE_FORMAT_MPEGLAYER3; mi->strAudioFormat = GetAudioFormatName(mi->audio.wFormatTag); if (bFullInfo && mi->strInfo.m_hWnd && (!strName.IsEmpty() || !strDesc.IsEmpty())) { @@ -2684,7 +2665,7 @@ bool GetWMHeaders(LPCTSTR pszFileName, SMediaInfo *mi, bool &rbIsWM, bool bFullI if (wCodecInfoSize == sizeof(DWORD)) { if (!bAddedBakedVideoStream) { bAddedBakedVideoStream = true; - mi->iVideoStreams++; + ++mi->iVideoStreams; mi->video.bmiHeader.biCompression = *(DWORD*)(BYTE*)aCodecInfo; mi->strVideoFormat = GetVideoFormatName(mi->video.bmiHeader.biCompression); if (bFullInfo && mi->strInfo.m_hWnd && (!strName.IsEmpty() || !strDesc.IsEmpty())) { @@ -2771,8 +2752,8 @@ bool GetMimeType(LPCTSTR pszFilePath, CString &rstrMimeType) { int fd = _topen(pszFilePath, O_RDONLY | O_BINARY); if (fd != -1) { - BYTE aucBuff[8192]; - int iRead = _read(fd, aucBuff, sizeof aucBuff); + BYTE buffer[8192]; + int iRead = _read(fd, buffer, sizeof buffer); _close(fd); @@ -2818,7 +2799,7 @@ bool GetMimeType(LPCTSTR pszFilePath, CString &rstrMimeType) // from sniffing the header data it will parse the passed file name's extension to guess the MIME type. // That's basically OK for browser mode, but we can't use that here. LPWSTR pwszMime = NULL; - HRESULT hr = FindMimeFromData(NULL, NULL/*pszFilePath*/, aucBuff, iRead, NULL, FMFD_ENABLEMIMESNIFFING | FMFD_IGNOREMIMETEXTPLAIN, &pwszMime, 0); + HRESULT hr = FindMimeFromData(NULL, NULL/*pszFilePath*/, buffer, iRead, NULL, FMFD_ENABLEMIMESNIFFING | FMFD_IGNOREMIMETEXTPLAIN, &pwszMime, 0); // "application/octet-stream" ... means general "binary" file // "text/plain" ... means general "text" file if (SUCCEEDED(hr) && pwszMime != NULL && wcscmp(pwszMime, L"application/octet-stream") != 0) { @@ -2829,9 +2810,9 @@ bool GetMimeType(LPCTSTR pszFilePath, CString &rstrMimeType) ::CoTaskMemFree(pwszMime); // RAR file type - if (iRead >= 7 && aucBuff[0] == 0x52) { - if ((aucBuff[1] == 0x45 && aucBuff[2] == 0x7e && aucBuff[3] == 0x5e) - || (aucBuff[1] == 0x61 && aucBuff[2] == 0x72 && aucBuff[3] == 0x21 && aucBuff[4] == 0x1a && aucBuff[5] == 0x07 && aucBuff[6] == 0x00)) + if (iRead >= 7 && buffer[0] == 0x52) { + if ((buffer[1] == 0x45 && buffer[2] == 0x7e && buffer[3] == 0x5e) + || (buffer[1] == 0x61 && buffer[2] == 0x72 && buffer[3] == 0x21 && buffer[4] == 0x1a && buffer[5] == 0x07 && buffer[6] == 0x00)) { rstrMimeType = _T("application/x-rar-compressed"); return true; @@ -2839,21 +2820,22 @@ bool GetMimeType(LPCTSTR pszFilePath, CString &rstrMimeType) } // bzip (BZ2) file type - if (aucBuff[0] == 'B' && aucBuff[1] == 'Z' && aucBuff[2] == 'h' && (aucBuff[3] >= '1' && aucBuff[3] <= '9')) { + static const char _cBZipheader[] = "BZh19"; + if (iRead >= (int)_countof(_cBZipheader) - 1 && memcmp(buffer, _cBZipheader, _countof(_cBZipheader) - 1) == 0) { rstrMimeType = _T("application/x-bzip-compressed"); return true; } // ACE file type static const char _cACEheader[] = "**ACE**"; - if ((unsigned)iRead >= 7 + _countof(_cACEheader) - 1 && memcmp(&aucBuff[7], _cACEheader, _countof(_cACEheader) - 1) == 0) { + if (iRead >= 7 + (int)_countof(_cACEheader) - 1 && memcmp(&buffer[7], _cACEheader, _countof(_cACEheader) - 1) == 0) { rstrMimeType = _T("application/x-ace-compressed"); return true; } // LHA/LZH file type static const char _cLZHheader[] = "-lh5-"; - if ((unsigned)iRead >= 2 + _countof(_cLZHheader) - 1 && memcmp(&aucBuff[2], _cLZHheader, _countof(_cLZHheader) - 1) == 0) { + if (iRead >= 2 + (int)_countof(_cLZHheader) - 1 && memcmp(&buffer[2], _cLZHheader, _countof(_cLZHheader) - 1) == 0) { rstrMimeType = _T("application/x-lha-compressed"); return true; } diff --git a/srchybrid/MediaInfo.h b/srchybrid/MediaInfo.h index 14e45b19..8c27bd93 100644 --- a/srchybrid/MediaInfo.h +++ b/srchybrid/MediaInfo.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/MetaDataDlg.cpp b/srchybrid/MetaDataDlg.cpp index 93186667..f57c0a94 100644 --- a/srchybrid/MetaDataDlg.cpp +++ b/srchybrid/MetaDataDlg.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -18,7 +18,6 @@ #include "emule.h" #include "kademlia/kademlia/tag.h" #include "MetaDataDlg.h" -#include "OtherFunctions.h" #include "Preferences.h" #include "MenuCmds.h" #include "Packets.h" @@ -284,19 +283,18 @@ CString GetTagNameByID(UINT id) uid = IDS_META_SRCTYPE; break; default: - uid = 0; + { + CString buffer; + buffer.Format(_T("Tag0x%02X"), id); + return buffer; + } } - if (uid) - return GetResString(uid); - - CString buffer; - buffer.Format(_T("Tag0x%02X"), id); - return buffer; + return GetResString(uid); } CString GetMetaTagName(UINT uTagID) { - CString strName = GetTagNameByID(uTagID); + CString strName(GetTagNameByID(uTagID)); StripTrailingColon(strName); return strName; } @@ -332,7 +330,7 @@ CString GetValue(const CTag *pTag) strValue = GetCodecDisplayName(strValue); } else if (pTag->IsInt()) { if (pTag->GetNameID() == FT_MEDIA_LENGTH || pTag->GetNameID() == FT_LASTSEENCOMPLETE) - SecToTimeLength(pTag->GetInt(), strValue); + strValue = SecToTimeLength(pTag->GetInt()); else if (pTag->GetNameID() == FT_FILERATING) strValue = GetRateString(pTag->GetInt()); else if (pTag->GetNameID() == 0x10 || pTag->GetNameID() >= 0xFA) @@ -359,7 +357,7 @@ CString GetValue(const Kademlia::CKadTag *pTag) // FIXME LARGE FILES strValue = GetCodecDisplayName(strValue); } else if (pTag->IsInt()) { if (pTag->m_name.Compare(TAG_MEDIA_LENGTH) == 0) - SecToTimeLength((unsigned long)pTag->GetInt(), strValue); + strValue = SecToTimeLength((UINT)pTag->GetInt()); else if (pTag->m_name.Compare(TAG_FILERATING) == 0) strValue = GetRateString((UINT)pTag->GetInt()); else if ((BYTE)pTag->m_name[0] == 0x10 || (BYTE)pTag->m_name[0] >= 0xFA) @@ -446,8 +444,8 @@ void CMetaDataDlg::RefreshData() m_tags.SetItem(&lvi); - strBuff = md4str(m_pFile->GetFileHash()); - lvi.pszText = const_cast((LPCTSTR)strBuff); + const CString &sMD4(md4str(m_pFile->GetFileHash())); + lvi.pszText = const_cast((LPCTSTR)sMD4); lvi.iSubItem = META_DATA_COL_VALUE; m_tags.SetItem(&lvi); } @@ -461,20 +459,20 @@ void CMetaDataDlg::RefreshData() lvi.mask = LVIF_TEXT; lvi.iItem = INT_MAX; lvi.iSubItem = META_DATA_COL_NAME; - strBuff = GetName(pTag); - lvi.pszText = const_cast((LPCTSTR)strBuff); + const CString &sName(GetName(pTag)); + lvi.pszText = const_cast((LPCTSTR)sName); int iItem = m_tags.InsertItem(&lvi); if (iItem >= 0) { //lvi.mask = LVIF_TEXT; lvi.iItem = iItem; - strBuff = GetType(pTag->GetType()); - lvi.pszText = const_cast((LPCTSTR)strBuff); + const CString &sType(GetType(pTag->GetType())); + lvi.pszText = const_cast((LPCTSTR)sType); lvi.iSubItem = META_DATA_COL_TYPE; m_tags.SetItem(&lvi); - strBuff = GetValue(pTag); - lvi.pszText = const_cast((LPCTSTR)strBuff); + const CString &sValue(GetValue(pTag)); + lvi.pszText = const_cast((LPCTSTR)sValue); lvi.iSubItem = META_DATA_COL_VALUE; m_tags.SetItem(&lvi); @@ -484,25 +482,24 @@ void CMetaDataDlg::RefreshData() } else if (m_taglist != NULL) { for (Kademlia::TagList::const_iterator it = m_taglist->begin(); it != m_taglist->end(); ++it) { const Kademlia::CKadTag *pTag = *it; - CString strBuff; LVITEM lvi; lvi.mask = LVIF_TEXT; lvi.iItem = INT_MAX; lvi.iSubItem = META_DATA_COL_NAME; - strBuff = GetName(pTag); - lvi.pszText = const_cast((LPCTSTR)strBuff); + const CString &sName(GetName(pTag)); + lvi.pszText = const_cast((LPCTSTR)sName); int iItem = m_tags.InsertItem(&lvi); if (iItem >= 0) { //lvi.mask = LVIF_TEXT; lvi.iItem = iItem; - strBuff = GetType(pTag->m_type); - lvi.pszText = const_cast((LPCTSTR)strBuff); + const CString &sType(GetType(pTag->m_type)); + lvi.pszText = const_cast((LPCTSTR)sType); lvi.iSubItem = META_DATA_COL_TYPE; m_tags.SetItem(&lvi); - strBuff = GetValue(pTag); - lvi.pszText = const_cast((LPCTSTR)strBuff); + const CString &sValue(GetValue(pTag)); + lvi.pszText = const_cast((LPCTSTR)sValue); lvi.iSubItem = META_DATA_COL_VALUE; m_tags.SetItem(&lvi); @@ -510,9 +507,9 @@ void CMetaDataDlg::RefreshData() } } } - CString strTmp; - strTmp.Format(_T("%s %i"), (LPCTSTR)GetResString(IDS_METATAGS), iMetaTags); - SetDlgItemText(IDC_TOTAL_TAGS, strTmp); + CString sTotal(GetResString(IDS_METATAGS)); + sTotal.AppendFormat(_T(" %i"), iMetaTags); + SetDlgItemText(IDC_TOTAL_TAGS, sTotal); m_tags.SetRedraw(); } @@ -523,8 +520,7 @@ void CMetaDataDlg::OnCopyTags() CString strData; for (POSITION pos = m_tags.GetFirstSelectedItemPosition(); pos != NULL;) { int iItem = m_tags.GetNextSelectedItem(pos); - const CString &strValue = m_tags.GetItemText(iItem, META_DATA_COL_VALUE); - + const CString &strValue(m_tags.GetItemText(iItem, META_DATA_COL_VALUE)); if (!strValue.IsEmpty()) { if (!strData.IsEmpty()) strData += _T("\r\n"); diff --git a/srchybrid/MetaDataDlg.h b/srchybrid/MetaDataDlg.h index d28a850b..517ff0c0 100644 --- a/srchybrid/MetaDataDlg.h +++ b/srchybrid/MetaDataDlg.h @@ -1,13 +1,13 @@ #pragma once #include "ResizableLib/ResizablePage.h" #include "ListCtrlX.h" -#include +#include class CAbstractFile; namespace Kademlia { class CKadTag; - typedef std::list TagList; + typedef std::vector TagList; }; class CMetaDataDlg : public CResizablePage diff --git a/srchybrid/MeterIcon.cpp b/srchybrid/MeterIcon.cpp index 474b4313..afd79c67 100644 --- a/srchybrid/MeterIcon.cpp +++ b/srchybrid/MeterIcon.cpp @@ -16,7 +16,7 @@ static char THIS_FILE[] = __FILE__; ////////////////////////////////////////////////////////////////////// CMeterIcon::CMeterIcon() - : m_sDimensions{16, 16} + : m_sDimensions{ 16, 16 } , m_hFrame() , m_pLimits() , m_pColors() diff --git a/srchybrid/MiniMule.cpp b/srchybrid/MiniMule.cpp index 6816908b..9ad181da 100644 --- a/srchybrid/MiniMule.cpp +++ b/srchybrid/MiniMule.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -214,23 +214,25 @@ CString CreateFilePathUrl(LPCTSTR pszFilePath, int nProtocol) // "c:\#dir\emule.exe". For any unknown reason the sequence "c:\#" causes troubles for // the IE control. It does not help to escape that sequence. It always fails. // - CString strEncodedFilePath; + LPCTSTR pszProtocol; if (nProtocol == INTERNET_SCHEME_RES) { // "res://" protocol has to be specified with 2 slashes ("res:///" does not work) - strEncodedFilePath = _T("res://"); + pszProtocol = _T("res://"); } else { ASSERT(nProtocol == INTERNET_SCHEME_FILE); // "file://" protocol has to be specified with 3 slashes - strEncodedFilePath = _T("file:///"); + pszProtocol = _T("file:///"); } - return strEncodedFilePath + pszFilePath; + CString strEncodedFilePath; + strEncodedFilePath.Format(_T("%s%s"), pszProtocol, pszFilePath); + return strEncodedFilePath; } BOOL CMiniMule::OnInitDialog() { ASSERT(GetCurrentThreadId() == g_uMainThreadId); ASSERT(m_iInCallback == 0); - const CString &strHtmlFile = theApp.GetSkinFileItem(_T("MiniMule"), _T("HTML")); + const CString &strHtmlFile(theApp.GetSkinFileItem(_T("MiniMule"), _T("HTML"))); if (!strHtmlFile.IsEmpty()) { if (_taccess(strHtmlFile, 0) == 0) { m_strCurrentUrl = CreateFilePathUrl(strHtmlFile, INTERNET_SCHEME_FILE); @@ -261,7 +263,6 @@ BOOL CMiniMule::OnInitDialog() // Otherwise, we may crash due to deleting the MiniMule and OCX control while it is being created. TRACE("%s before CDHtmlDialog::OnInitDialog()\n", __FUNCTION__); - ASSERT_VALID(this); ASSERT(m_iInInitDialog == 0); ++m_iInInitDialog; @@ -270,7 +271,6 @@ BOOL CMiniMule::OnInitDialog() --m_iInInitDialog; ASSERT(m_iInInitDialog == 0); TRACE("%s after CDHtmlDialog::OnInitDialog()\n", __FUNCTION__); - ASSERT_VALID(this); if (m_uWndTransparency) { m_layeredWnd.AddLayeredStyle(m_hWnd); @@ -285,26 +285,21 @@ BOOL CMiniMule::OnInitDialog() void CMiniMule::OnClose() { TRACE("%s\n", __FUNCTION__); - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); ASSERT(m_iInInitDialog == 0); ASSERT(m_iInCallback == 0); KillAutoCloseTimer(); - if (GetAutoClose()) { - BOOL(WINAPI *pfnAnimateWindow)(HWND hWnd, DWORD dwTime, DWORD dwFlags); - (FARPROC&)pfnAnimateWindow = GetProcAddress(GetModuleHandle(_T("user32")), "AnimateWindow"); - if (pfnAnimateWindow) - (*pfnAnimateWindow)(m_hWnd, 200, AW_HIDE | AW_BLEND | AW_CENTER); - } + if (GetAutoClose()) + ::AnimateWindow(m_hWnd, 200, AW_HIDE | AW_BLEND | AW_CENTER); CDHtmlDialog::OnClose(); /////////////////////////////////////////////////////////////////////////// // Destroy the MiniMule window - // Solution #1: Posting a close-message to main window (can not be done with 'SendMessage') may - // create message queue sync. problems when having high system load. + // Solution #1: Posting a close-message to the main window (can not be done with 'SendMessage') + // may create message queue sync. problems when having high system load. //theApp.emuledlg->PostMessage(UM_CLOSE_MINIMULE, (WPARAM)m_bRestoreMainWnd); // Solution #2: 'DestroyModeless' -- posts a 'destroy' message to 'this' which will have a very @@ -325,7 +320,6 @@ void CMiniMule::OnClose() void CMiniMule::OnDestroy() { TRACE("%s\n", __FUNCTION__); - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); ASSERT(m_iInInitDialog == 0); ASSERT(m_iInCallback == 0); @@ -336,7 +330,6 @@ void CMiniMule::OnDestroy() void CMiniMule::PostNcDestroy() { TRACE("%s\n", __FUNCTION__); - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); ASSERT(m_iInInitDialog == 0); CDHtmlDialog::PostNcDestroy(); @@ -390,7 +383,6 @@ void CMiniMule::Localize() void CMiniMule::UpdateContent(UINT uUpDatarate, UINT uDownDatarate) { - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); if (m_bResolveImages) { static LPCTSTR const _apszConnectedImgs[] = @@ -415,9 +407,8 @@ void CMiniMule::UpdateContent(UINT uUpDatarate, UINT uDownDatarate) CComPtr img; GetElementInterface(_T("connectedImg"), &img); if (img) { - CString strFilePathUrl(CreateFilePathUrl(szModulePath, INTERNET_SCHEME_RES)); - CString strResourceURL; - strResourceURL.Format(_T("%s/%s"), (LPCTSTR)strFilePathUrl, _apszConnectedImgs[uIconIdx]); + CString strResourceURL(CreateFilePathUrl(szModulePath, INTERNET_SCHEME_RES)); + strResourceURL.AppendFormat(_T("/%s"), _apszConnectedImgs[uIconIdx]); img->put_src(CComBSTR(strResourceURL)); } } @@ -439,7 +430,6 @@ void CMiniMule::UpdateContent(UINT uUpDatarate, UINT uDownDatarate) STDMETHODIMP CMiniMule::TranslateUrl(DWORD /*dwTranslate*/, OLECHAR *pchURLIn, OLECHAR **ppchURLOut) noexcept { - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); UNREFERENCED_PARAMETER(pchURLIn); TRACE(_T("%hs: %ls\n"), __FUNCTION__, pchURLIn); @@ -449,7 +439,6 @@ STDMETHODIMP CMiniMule::TranslateUrl(DWORD /*dwTranslate*/, OLECHAR *pchURLIn, O void CMiniMule::_OnBeforeNavigate2(LPDISPATCH pDisp, VARIANT *URL, VARIANT* /*Flags*/, VARIANT* /*TargetFrameName*/, VARIANT* /*PostData*/, VARIANT* /*Headers*/, BOOL *Cancel) { - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); CString strURL(V_BSTR(URL)); TRACE(_T("%hs: %s\n"), __FUNCTION__, (LPCTSTR)strURL); @@ -460,22 +449,22 @@ void CMiniMule::_OnBeforeNavigate2(LPDISPATCH pDisp, VARIANT *URL, VARIANT* /*Fl Url.dwStructSize = sizeof Url; Url.lpszScheme = szScheme; Url.dwSchemeLength = _countof(szScheme); - if (::InternetCrackUrl(strURL, 0, 0, &Url) && Url.dwSchemeLength) { - if (Url.nScheme != INTERNET_SCHEME_UNKNOWN // - && Url.nScheme != INTERNET_SCHEME_RES // res://... - && Url.nScheme != INTERNET_SCHEME_FILE) // file://... - { + if (::InternetCrackUrl(strURL, 0, 0, &Url) && Url.dwSchemeLength) + switch (Url.nScheme) { + case INTERNET_SCHEME_UNKNOWN: // + case INTERNET_SCHEME_RES: // res://... + case INTERNET_SCHEME_FILE: // file://... + break; + default: *Cancel = TRUE; return; } - } OnBeforeNavigate(pDisp, strURL); } void CMiniMule::OnBeforeNavigate(LPDISPATCH pDisp, LPCTSTR pszUrl) { - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); TRACE(_T("%hs: %s\n"), __FUNCTION__, pszUrl); CDHtmlDialog::OnBeforeNavigate(pDisp, pszUrl); @@ -483,7 +472,6 @@ void CMiniMule::OnBeforeNavigate(LPDISPATCH pDisp, LPCTSTR pszUrl) void CMiniMule::OnNavigateComplete(LPDISPATCH pDisp, LPCTSTR pszUrl) { - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); TRACE(_T("%hs: %s\n"), __FUNCTION__, pszUrl); // If the HTML file contains 'OnLoad' scripts, the HTML DOM is fully accessible @@ -493,11 +481,10 @@ void CMiniMule::OnNavigateComplete(LPDISPATCH pDisp, LPCTSTR pszUrl) void CMiniMule::OnDocumentComplete(LPDISPATCH pDisp, LPCTSTR pszUrl) { - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); if (theApp.emuledlg->m_pMiniMule == NULL) { // FIX ME - // apparently in some rare cases (high cpu load, fast double clicks) this function is called when the object was destroyed already + // apparently in some rare cases (high CPU load, fast double clicks) this function is called when the object was destroyed already ASSERT(0); return; } @@ -513,7 +500,7 @@ void CMiniMule::OnDocumentComplete(LPDISPATCH pDisp, LPCTSTR pszUrl) TCHAR szModulePath[MAX_PATH]; DWORD dwModPathLen = ::GetModuleFileName(AfxGetResourceHandle(), szModulePath, _countof(szModulePath)); if (dwModPathLen != 0 && dwModPathLen < _countof(szModulePath)) { - CString strFilePathUrl(CreateFilePathUrl(szModulePath, INTERNET_SCHEME_RES)); + const CString &strFilePathUrl(CreateFilePathUrl(szModulePath, INTERNET_SCHEME_RES)); static const struct { @@ -534,8 +521,8 @@ void CMiniMule::OnDocumentComplete(LPDISPATCH pDisp, LPCTSTR pszUrl) CComPtr elm; GetElementInterface(_aImg[i].pszImgId, &elm); if (elm) { - CString strResourceURL; - strResourceURL.Format(_T("%s/%s"), (LPCTSTR)strFilePathUrl, _aImg[i].pszResourceId); + CString strResourceURL(strFilePathUrl); + strResourceURL.AppendFormat(_T("/%s"), _aImg[i].pszResourceId); elm->put_src(CComBSTR(strResourceURL)); } } @@ -543,8 +530,8 @@ void CMiniMule::OnDocumentComplete(LPDISPATCH pDisp, LPCTSTR pszUrl) CComPtr elm; GetElementInterface(_T("table"), &elm); if (elm) { - CString strResourceURL; - strResourceURL.Format(_T("%s/%s"), (LPCTSTR)strFilePathUrl, _T("TABLEBACKGND.GIF")); + CString strResourceURL(strFilePathUrl); + strResourceURL.AppendFormat(_T("/%s"), _T("TABLEBACKGND.GIF")); elm->put_background(CComBSTR(strResourceURL)); elm.Release(); } @@ -562,7 +549,7 @@ void CMiniMule::OnDocumentComplete(LPDISPATCH pDisp, LPCTSTR pszUrl) // smaller than the size of that window. To have the auto-size working correctly even for // very small window sizes, the size of the dialog resource should therefore be kept very small! // TODO: Only in debug build: Check the size of the dialog resource right before 'OnInitDialog'. - CComQIPtr body2 = body; + CComQIPtr body2(body); long lScrollWidth; long lScrollHeight; if (body2->get_scrollWidth(&lScrollWidth) == S_OK && lScrollWidth > 0 && body2->get_scrollHeight(&lScrollHeight) == S_OK && lScrollHeight > 0) @@ -608,7 +595,6 @@ UINT GetTaskbarPos(HWND hwndTaskbar) void CMiniMule::AutoSizeAndPosition(CSize sizClient) { - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); TRACE("AutoSizeAndPosition: %dx%d\n", sizClient.cx, sizClient.cy); CSize sizDesktop(::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN)); @@ -630,7 +616,7 @@ void CMiniMule::AutoSizeAndPosition(CSize sizClient) HWND hWndTaskbar = ::FindWindow(_T("Shell_TrayWnd"), NULL); if (hWndTaskbar) ::GetWindowRect(hWndTaskbar, &rcTaskbar); - CPoint ptWnd; + UINT uTaskbarPos; #if 0 // Do *NOT* use 'GetTaskbarPos' (which will use 'SHAppBarMessage') -- it may cause us to crash due to internal @@ -638,29 +624,27 @@ void CMiniMule::AutoSizeAndPosition(CSize sizClient) uTaskbarPos = GetTaskbarPos(hWndTaskbar); #else if (rcTaskbar.left <= 0) { - if (rcTaskbar.top <= 0) { - if (rcTaskbar.Width() > rcTaskbar.Height()) - uTaskbarPos = ABE_TOP; - else - uTaskbarPos = ABE_LEFT; - } else + if (rcTaskbar.top <= 0) + uTaskbarPos = (rcTaskbar.Width() > rcTaskbar.Height()) ? ABE_TOP : ABE_LEFT; + else uTaskbarPos = ABE_BOTTOM; } else uTaskbarPos = ABE_RIGHT; #endif + POINT ptWnd; switch (uTaskbarPos) { case ABE_TOP: - ptWnd.SetPoint(sizDesktop.cx - 8 - rcWnd.Width(), rcTaskbar.Height() + 8); + ptWnd = POINT{ sizDesktop.cx - 8 - rcWnd.Width(), rcTaskbar.Height() + 8 }; break; case ABE_LEFT: - ptWnd.SetPoint(rcTaskbar.Width() + 8, sizDesktop.cy - 8 - rcWnd.Height()); + ptWnd = POINT{ rcTaskbar.Width() + 8, sizDesktop.cy - 8 - rcWnd.Height() }; break; case ABE_RIGHT: - ptWnd.SetPoint(sizDesktop.cx - rcTaskbar.Width() - 8 - rcWnd.Width(), sizDesktop.cy - 8 - rcWnd.Height()); + ptWnd = POINT{ sizDesktop.cx - rcTaskbar.Width() - 8 - rcWnd.Width(), sizDesktop.cy - 8 - rcWnd.Height() }; break; default: ASSERT(uTaskbarPos == ABE_BOTTOM); - ptWnd.SetPoint(sizDesktop.cx - 8 - rcWnd.Width(), sizDesktop.cy - rcTaskbar.Height() - 8 - rcWnd.Height()); + ptWnd = POINT{ sizDesktop.cx - 8 - rcWnd.Width(), sizDesktop.cy - rcTaskbar.Height() - 8 - rcWnd.Height() }; } SetWindowPos(NULL, ptWnd.x, ptWnd.y, rcWnd.Width(), rcWnd.Height(), SWP_NOZORDER | SWP_SHOWWINDOW); @@ -668,7 +652,6 @@ void CMiniMule::AutoSizeAndPosition(CSize sizClient) void CMiniMule::CreateAutoCloseTimer() { - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); if (m_uAutoCloseTimer == 0) m_uAutoCloseTimer = SetTimer(IDT_AUTO_CLOSE_TIMER, SEC2MS(3), NULL); @@ -676,7 +659,6 @@ void CMiniMule::CreateAutoCloseTimer() void CMiniMule::KillAutoCloseTimer() { - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); if (m_uAutoCloseTimer != 0) { VERIFY(KillTimer(m_uAutoCloseTimer)); @@ -686,7 +668,6 @@ void CMiniMule::KillAutoCloseTimer() void CMiniMule::OnTimer(UINT_PTR nIDEvent) { - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); if (m_bAutoClose && nIDEvent == m_uAutoCloseTimer) { ASSERT(m_iInInitDialog == 0); @@ -706,22 +687,19 @@ void CMiniMule::OnTimer(UINT_PTR nIDEvent) void CMiniMule::RestoreMainWindow() { - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); ASSERT(m_iInInitDialog == 0); - if (!theApp.IsClosing() && !theApp.emuledlg->IsWindowVisible()) { + if (!theApp.IsClosing() && !theApp.emuledlg->IsWindowVisible()) if (!theApp.emuledlg->IsPreferencesDlgOpen()) { KillAutoCloseTimer(); m_bRestoreMainWnd = true; PostMessage(WM_CLOSE); } else MessageBeep(MB_OK); - } } void CMiniMule::OnNcLButtonDblClk(UINT nHitTest, CPoint point) { - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); ASSERT(m_iInInitDialog == 0); CDHtmlDialog::OnNcLButtonDblClk(nHitTest, point); @@ -731,7 +709,6 @@ void CMiniMule::OnNcLButtonDblClk(UINT nHitTest, CPoint point) HRESULT CMiniMule::OnRestoreMainWindow(IHTMLElement* /*pElement*/) { - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); ASSERT(m_iInInitDialog == 0); CCounter cc(m_iInCallback); @@ -741,7 +718,6 @@ HRESULT CMiniMule::OnRestoreMainWindow(IHTMLElement* /*pElement*/) HRESULT CMiniMule::OnOpenIncomingFolder(IHTMLElement* /*pElement*/) { - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); ASSERT(m_iInInitDialog == 0); CCounter cc(m_iInCallback); @@ -755,7 +731,6 @@ HRESULT CMiniMule::OnOpenIncomingFolder(IHTMLElement* /*pElement*/) HRESULT CMiniMule::OnOptions(IHTMLElement* /*pElement*/) { - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); ASSERT(m_iInInitDialog == 0); CCounter cc(m_iInCallback); @@ -772,7 +747,6 @@ HRESULT CMiniMule::OnOptions(IHTMLElement* /*pElement*/) STDMETHODIMP CMiniMule::ShowContextMenu(DWORD /*dwID*/, POINT* /*ppt*/, IUnknown* /*pcmdtReserved*/, IDispatch* /*pdispReserved*/) noexcept { - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); ASSERT(m_iInInitDialog == 0); CCounter cc(m_iInCallback); @@ -782,13 +756,12 @@ STDMETHODIMP CMiniMule::ShowContextMenu(DWORD /*dwID*/, POINT* /*ppt*/, IUnknown STDMETHODIMP CMiniMule::TranslateAccelerator(LPMSG lpMsg, const GUID* /*pguidCmdGroup*/, DWORD /*nCmdID*/) noexcept { - ASSERT_VALID(this); ASSERT(GetCurrentThreadId() == g_uMainThreadId); ASSERT(m_iInInitDialog == 0); CCounter cc(m_iInCallback); // Allow only some basic keys // - //TODO: Allow the ESC key (for closing the window); does currently not work properly because + //TODO: Allow the ESC key (for closing the window); currently does not work properly because // we don't get a callback that the window was just hidden(!) by MSHTML. switch (lpMsg->message) { case WM_CHAR: diff --git a/srchybrid/MiniMule.h b/srchybrid/MiniMule.h index 0453436a..c052ef45 100644 --- a/srchybrid/MiniMule.h +++ b/srchybrid/MiniMule.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/MuleListCtrl.cpp b/srchybrid/MuleListCtrl.cpp index 58f64f0a..34587328 100644 --- a/srchybrid/MuleListCtrl.cpp +++ b/srchybrid/MuleListCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -82,9 +82,9 @@ BEGIN_MESSAGE_MAP(CMuleListCtrl, CListCtrl) ON_WM_SYSCOLORCHANGE() END_MESSAGE_MAP() -CMuleListCtrl::CMuleListCtrl(PFNLVCOMPARE pfnCompare, DWORD dwParamSort) +CMuleListCtrl::CMuleListCtrl(PFNLVCOMPARE pfnCompare, LPARAM iParamSort) : m_SortProc(pfnCompare) - , m_dwParamSort(dwParamSort) + , m_dwParamSort(iParamSort) , m_crWindow() , m_crWindowText() , m_crWindowTextBk(m_crWindow) @@ -162,14 +162,11 @@ int CMuleListCtrl::IndexToOrder(CHeaderCtrl *pHeader, int iIndex) int iCount = pHeader->GetItemCount(); int *piArray = new int[iCount]; Header_GetOrderArray(pHeader->m_hWnd, iCount, piArray); - for (int i = 0; i < iCount; ++i) - if (piArray[i] == iIndex) { - delete[] piArray; - return i; - } - + while (--iCount >= 0) + if (piArray[iCount] == iIndex) + break; delete[] piArray; - return -1; + return iCount; } void CMuleListCtrl::HideColumn(int iColumn) @@ -180,7 +177,7 @@ void CMuleListCtrl::HideColumn(int iColumn) return; //stop it from redrawing - SetRedraw(FALSE); + SetRedraw(false); //shrink width to 0 HDITEM item; @@ -208,7 +205,7 @@ void CMuleListCtrl::HideColumn(int iColumn) m_aColumns[iColumn].bHidden = true; //redraw - SetRedraw(TRUE); + SetRedraw(true); Invalidate(FALSE); } @@ -220,7 +217,7 @@ void CMuleListCtrl::ShowColumn(int iColumn) return; //stop it from redrawing - SetRedraw(FALSE); + SetRedraw(false); //restore position in list INT *piArray = new INT[m_iColumnsTracked]; @@ -248,7 +245,7 @@ void CMuleListCtrl::ShowColumn(int iColumn) m_aColumns[iColumn].bHidden = false; //redraw - SetRedraw(TRUE); + SetRedraw(true); Invalidate(FALSE); } @@ -265,25 +262,26 @@ void CMuleListCtrl::SaveSettings() ShowWindow(SW_HIDE); - int *piSortHist = new int[MAX_SORTORDERHISTORY]; + int iSortHist[MAX_SORTORDERHISTORY]; int i = 0; for (POSITION pos = m_liSortHistory.GetHeadPosition(); pos != NULL;) - piSortHist[i++] = m_liSortHistory.GetNext(pos) + 1; - ini.SerGet(false, piSortHist, i, m_Name + _T("SortHistory")); + iSortHist[i++] = m_liSortHistory.GetNext(pos) + 1; + ini.SerGet(false, iSortHist, i, m_Name + _T("SortHistory")); // store additional settings ini.WriteInt(m_Name + _T("TableSortItem"), GetSortItem()); ini.WriteInt(m_Name + _T("TableSortAscending"), GetSortType(m_atSortArrow)); int *piColWidths = new int[m_iColumnsTracked]; int *piColHidden = new int[m_iColumnsTracked]; - INT *piColOrders = new INT[m_iColumnsTracked]; for (i = 0; i < m_iColumnsTracked; ++i) { piColWidths[i] = GetColumnWidth(i); piColHidden[i] = IsColumnHidden(i); ShowColumn(i); } + int *piColOrders = new int[m_iColumnsTracked]; GetHeaderCtrl()->GetOrderArray(piColOrders, m_iColumnsTracked); + ini.SerGet(false, piColWidths, m_iColumnsTracked, m_Name + _T("ColumnWidths")); ini.SerGet(false, piColHidden, m_iColumnsTracked, m_Name + _T("ColumnHidden")); ini.SerGet(false, piColOrders, m_iColumnsTracked, m_Name + _T("ColumnOrders")); @@ -294,7 +292,6 @@ void CMuleListCtrl::SaveSettings() ShowWindow(SW_SHOW); - delete[] piSortHist; delete[] piColOrders; delete[] piColWidths; delete[] piColHidden; @@ -332,13 +329,13 @@ void CMuleListCtrl::LoadSettings() CIni ini(thePrefs.GetConfigFile(), _T("ListControlSetup")); // sort history - int *piSortHist = new int[MAX_SORTORDERHISTORY]; - ini.SerGet(true, piSortHist, MAX_SORTORDERHISTORY, m_Name + _T("SortHistory")); + int iSortHist[MAX_SORTORDERHISTORY]; + ini.SerGet(true, iSortHist, MAX_SORTORDERHISTORY, m_Name + _T("SortHistory")); m_liSortHistory.RemoveAll(); for (int i = 0; i < MAX_SORTORDERHISTORY; ++i) { - if (piSortHist[i] <= 0) + if (iSortHist[i] <= 0) break; - m_liSortHistory.AddTail(piSortHist[i] - 1); + m_liSortHistory.AddTail(iSortHist[i] - 1); } m_iCurrentSortItem = ini.GetInt(m_Name + _T("TableSortItem"), 0); @@ -349,13 +346,13 @@ void CMuleListCtrl::LoadSettings() // columns settings int *piColWidths = new int[m_iColumnsTracked]; int *piColHidden = new int[m_iColumnsTracked]; - INT *piColOrders = new int[m_iColumnsTracked]; + int *piColOrders = new int[m_iColumnsTracked]; ini.SerGet(true, piColWidths, m_iColumnsTracked, m_Name + _T("ColumnWidths")); ini.SerGet(true, piColHidden, m_iColumnsTracked, m_Name + _T("ColumnHidden"), 0, -1); ini.SerGet(true, piColOrders, m_iColumnsTracked, m_Name + _T("ColumnOrders")); - // apply columnwidths and verify sortorder - INT *piArray = new INT[m_iColumnsTracked]; + // apply column widths and verify sort order + int *piArray = new int[m_iColumnsTracked]; for (int i = 0; i < m_iColumnsTracked; ++i) { piArray[i] = i; @@ -373,23 +370,19 @@ void CMuleListCtrl::LoadSettings() m_aColumns[piArray[i]].iLocation = i; GetHeaderCtrl()->SetOrderArray(m_iColumnsTracked, piArray); - for (int i = 1; i < m_iColumnsTracked; ++i) { + for (int i = 1; i < m_iColumnsTracked; ++i) if (piColHidden[i] > 0 || (piColHidden[i] < 0 && m_liDefaultHiddenColumns.Find(i) != NULL)) HideColumn(i); - } delete[] piArray; delete[] piColOrders; delete[] piColWidths; delete[] piColHidden; - delete[] piSortHist; } HBITMAP LoadImageAsPARGB(LPCTSTR pszPath) { - extern bool g_bGdiPlusInstalled; - if (!g_bGdiPlusInstalled) - return NULL; + // NOTE: Do *NOT* forget to specify /DELAYLOAD:gdiplus.dll as link parameter. HBITMAP hbmPARGB = NULL; ULONG_PTR gdiplusToken = 0; Gdiplus::GdiplusStartupInput gdiplusStartupInput; @@ -436,11 +429,9 @@ void CMuleListCtrl::SetColors() COLORREF crHighlight = ::GetSysColor(COLOR_HIGHLIGHT); CString strBkImage; - LPCTSTR pszSkinProfile = thePrefs.GetSkinProfile(); - if (pszSkinProfile[0] != _T('\0')) { - CString strKey(m_strSkinKey); - if (strKey.IsEmpty()) - strKey = _T("DefLv"); + const CString &sSkinProfile(thePrefs.GetSkinProfile()); + if (!sSkinProfile.IsEmpty()) { + const CString strKey(m_strSkinKey.IsEmpty() ? _T("DefLv") : m_strSkinKey); if (theApp.LoadSkinColorAlt(strKey + _T("Bk"), _T("DefLvBk"), m_crWindow)) m_crWindowTextBk = m_crWindow; @@ -448,10 +439,10 @@ void CMuleListCtrl::SetColors() theApp.LoadSkinColorAlt(strKey + _T("Hl"), _T("DefLvHl"), crHighlight); TCHAR szColor[MAX_PATH]; - GetPrivateProfileString(_T("Colors"), strKey + _T("BkImg"), _T(""), szColor, _countof(szColor), pszSkinProfile); - if (szColor[0] == _T('\0')) - GetPrivateProfileString(_T("Colors"), _T("DefLvBkImg"), _T(""), szColor, _countof(szColor), pszSkinProfile); - if (szColor[0] != _T('\0')) + GetPrivateProfileString(_T("Colors"), strKey + _T("BkImg"), NULL, szColor, _countof(szColor), sSkinProfile); + if (*szColor == _T('\0')) + GetPrivateProfileString(_T("Colors"), _T("DefLvBkImg"), NULL, szColor, _countof(szColor), sSkinProfile); + if (*szColor != _T('\0')) strBkImage = szColor; } @@ -472,11 +463,11 @@ void CMuleListCtrl::SetColors() // create absolute path to icon resource file TCHAR szFullResPath[MAX_PATH]; - if (PathIsRelative(strBkImage)) { + if (::PathIsRelative(strBkImage)) { TCHAR szSkinResFolder[MAX_PATH]; - _tcsncpy(szSkinResFolder, pszSkinProfile, _countof(szSkinResFolder)); + _tcsncpy(szSkinResFolder, sSkinProfile, _countof(szSkinResFolder)); szSkinResFolder[_countof(szSkinResFolder) - 1] = _T('\0'); - PathRemoveFileSpec(szSkinResFolder); + ::PathRemoveFileSpec(szSkinResFolder); _tmakepathlimit(szFullResPath, NULL, szSkinResFolder, strBkImage, NULL); } else { _tcsncpy(szFullResPath, strBkImage, _countof(szFullResPath)); @@ -485,7 +476,7 @@ void CMuleListCtrl::SetColors() #if 0 // Explicitly check if the file exists, because 'SetBkImage' will return TRUE even if the file does not exist. - if (PathFileExists(szFullResPath)) { + if (::PathFileExists(szFullResPath)) { // This places the bitmap near the bottom-right border of the client area. But due to that // the position is specified via percentages, the bitmap is never exactly at the bottom // right border, it depends on the window's height. Apart from that, the bitmap gets @@ -635,7 +626,7 @@ int CMuleListCtrl::MoveItem(int iOldIndex, int iNewIndex) } // do the move - SetRedraw(FALSE); + SetRedraw(false); DeleteItem(iOldIndex); lvi.iItem = iNewIndex; iNewIndex = InsertItem(&lvi); @@ -658,7 +649,7 @@ int CMuleListCtrl::MoveItem(int iOldIndex, int iNewIndex) } } - SetRedraw(TRUE); + SetRedraw(true); return iNewIndex; } @@ -800,14 +791,14 @@ BOOL CMuleListCtrl::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT int iMin = iNewLoc; for (int i = 0; i < m_iColumnsTracked; ++i) { if (m_aColumns[i].iLocation >= iMin && m_aColumns[i].iLocation < iMax) - m_aColumns[i].iLocation++; + ++m_aColumns[i].iLocation; } } else { //iOldLoc < iNewLoc int iMin = iOldLoc; int iMax = iNewLoc; for (int i = 0; i < m_iColumnsTracked; ++i) { if (m_aColumns[i].iLocation > iMin && m_aColumns[i].iLocation <= iMax) - m_aColumns[i].iLocation--; + --m_aColumns[i].iLocation; } } m_aColumns[pHeader->iItem].iLocation = iNewLoc; @@ -925,7 +916,7 @@ BOOL CMuleListCtrl::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT } return *pResult != 0; case LVM_SORTITEMS: - m_dwParamSort = (DWORD)wParam; + m_dwParamSort = (LPARAM)wParam; m_SortProc = (PFNLVCOMPARE)lParam; for (POSITION pos = m_Params.GetHeadPosition(); pos != NULL; m_Params.GetNext(pos)) m_Params.SetAt(pos, MLC_MAGIC); @@ -1105,9 +1096,9 @@ BOOL CMuleListCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LR { if (message != WM_DRAWITEM) { //catch the prepaint and copy struct - if (message == WM_NOTIFY && reinterpret_cast(lParam)->code == NM_CUSTOMDRAW && - reinterpret_cast(lParam)->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) { - + if (message == WM_NOTIFY && reinterpret_cast(lParam)->code == NM_CUSTOMDRAW + && reinterpret_cast(lParam)->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) + { m_bCustomDraw = CListCtrl::OnChildNotify(message, wParam, lParam, pResult); if (m_bCustomDraw) m_lvcd = *reinterpret_cast(lParam); @@ -1164,14 +1155,26 @@ void CMuleListCtrl::InitItemMemDC(CMemoryDC *dc, LPDRAWITEMSTRUCT lpDrawItemStru dc->SetFont(GetFont()); } +void CMuleListCtrl::LocaliseHeaderCtrl(const UINT *const uids, size_t cnt) +{ + CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); + HDITEM hdi; + hdi.mask = HDI_TEXT; + for (size_t i = 0; i < cnt; ++i) + if (uids[i]) { + const CString &sText(GetResString(uids[i])); + hdi.pszText = const_cast((LPCTSTR)sText); + pHeaderCtrl->SetItem((int)i, &hdi); + } +} + void CMuleListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { //set up our flicker free drawing CRect rcItem(lpDrawItemStruct->rcItem); - CDC *oDC = CDC::FromHandle(lpDrawItemStruct->hDC); - CMemoryDC pDC(oDC, &rcItem, m_crWindow); + CMemoryDC pDC(CDC::FromHandle(lpDrawItemStruct->hDC), &rcItem, m_crWindow); CFont *pOldFont = pDC->SelectObject(GetFont()); - CRect rcClient; + RECT rcClient; GetClientRect(&rcClient); int iItem = lpDrawItemStruct->itemID; @@ -1184,7 +1187,7 @@ void CMuleListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) lvi.stateMask = LVIS_DROPHILITED | LVIS_FOCUSED | LVIS_SELECTED | LVIS_GLOW; GetItem(&lvi); - //see if the item be highlighted + //see if the item is highlighted BOOL bHighlight = ((lvi.state & LVIS_DROPHILITED) || (lvi.state & LVIS_SELECTED)); BOOL bCtrlFocused = ((GetFocus() == this) || (GetStyle() & LVS_SHOWSELALWAYS)); BOOL bGlowing = (lvi.state & LVIS_GLOW); @@ -1231,8 +1234,9 @@ void CMuleListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) //draw the item's icon CImageList *pImageList = GetImageList(LVSIL_SMALL); if (pImageList) { - int iIconPosY = max((rcItem.Height() - 16) / 2, 0); - pImageList->Draw(pDC, lvi.iImage, POINT{ rcIcon.left, rcIcon.top + iIconPosY }, ILD_TRANSPARENT); + int iIconY = max((rcItem.Height() - 16) / 2, 0); + const POINT point = { rcItem.left, rcItem.top + iIconY }; + pImageList->Draw(pDC, lvi.iImage, point, ILD_TRANSPARENT); } if (m_crWindowTextBk == CLR_NONE) @@ -1251,7 +1255,7 @@ void CMuleListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) LVCOLUMN lvc; lvc.mask = LVCF_FMT | LVCF_WIDTH; - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); + const CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); int iCount = pHeaderCtrl->GetItemCount(); for (int iCurrent = 1; iCurrent < iCount; ++iCurrent) { int iColumn = pHeaderCtrl->OrderToIndex(iCurrent); @@ -1267,7 +1271,7 @@ void CMuleListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) rcCol.left = rcCol.right; rcCol.right += lvc.cx; - if (rcCol.left < rcCol.right && HaveIntersection(rcClient, rcCol)) { + if (HaveIntersection(rcClient, rcCol)) { const CString &sLabel(GetItemText(iItem, iColumn)); if (sLabel.IsEmpty()) continue; @@ -1286,12 +1290,12 @@ void CMuleListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) nJustify = DT_LEFT; } - rcLabel = rcCol; - rcLabel.left += sm_iLabelOffset + sm_iSubItemInset; - rcLabel.right -= sm_iLabelOffset + sm_iSubItemInset; - - pDC->SetBkColor(clr); //FillSolidRect does this? - pDC->DrawText(sLabel, &rcLabel, MLC_DT_TEXT | nJustify); + //label text + rcCol.left += sm_iLabelOffset + sm_iSubItemInset; + rcCol.right -= sm_iLabelOffset + sm_iSubItemInset; + pDC->SetBkColor(clr); + pDC->DrawText(sLabel, &rcCol, MLC_DT_TEXT | nJustify); + rcCol.right += sm_iLabelOffset + sm_iSubItemInset; //restore the position } } @@ -1303,14 +1307,16 @@ void CMuleListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) void CMuleListCtrl::DrawFocusRect(CDC *pDC, LPCRECT rcItem, BOOL bItemFocused, BOOL bCtrlFocused, BOOL bItemSelected) { - //draw focus rectangle if item has focus - if (bItemFocused && (bCtrlFocused || bItemSelected)) - pDC->FrameRect(rcItem, &CBrush(bCtrlFocused && bItemSelected ? m_crFocusLine : m_crNoFocusLine)); + //draw focus rectangle if the item has focus + if (bItemFocused && (bCtrlFocused || bItemSelected)) { + CBrush brush(bCtrlFocused && bItemSelected ? m_crFocusLine : m_crNoFocusLine); + pDC->FrameRect(rcItem, &brush); + } } BOOL CMuleListCtrl::OnEraseBkgnd(CDC *pDC) { - //if (m_crWindowTextBk == CLR_NONE) // this creates a lot screen flickering + //if (m_crWindowTextBk == CLR_NONE) // this creates a lot of screen flickering // return CListCtrl::OnEraseBkgnd(pDC); int itemCount = GetItemCount(); @@ -1424,7 +1430,7 @@ HIMAGELIST CMuleListCtrl::ApplyImageList(HIMAGELIST himl) return himlOld; } -void CMuleListCtrl::DoFind(int iStartItem, int iDirection /*1 = down, 0 = up*/, BOOL bShowError) +void CMuleListCtrl::DoFind(int iStartItem, int iDirection /*1 = down, -1 = up*/, BOOL bShowError) { if (iStartItem < 0) { MessageBeep(MB_OK); @@ -1433,12 +1439,12 @@ void CMuleListCtrl::DoFind(int iStartItem, int iDirection /*1 = down, 0 = up*/, CWaitCursor curHourglass; - const int iNumItems = iDirection ? GetItemCount() : 0; - for (int iItem = iStartItem; (iDirection ? iItem < iNumItems : iItem >= 0);) { + const int iNumItems = (iDirection > 0) ? GetItemCount() : 0; + for (int iItem = iStartItem; ((iDirection > 0) ? iItem < iNumItems : iItem >= 0);) { const CString &strItemText(GetItemText(iItem, m_iFindColumn)); if (!strItemText.IsEmpty()) { if ((m_bFindMatchCase ? _tcsstr(strItemText, m_strFindText) : stristr(strItemText, m_strFindText)) != NULL) { - // Deselect all listview entries + // Deselect all listview entries SetItemState(-1, 0, LVIS_SELECTED); // Select the found listview entry @@ -1451,10 +1457,7 @@ void CMuleListCtrl::DoFind(int iStartItem, int iDirection /*1 = down, 0 = up*/, } } - if (iDirection) - ++iItem; - else - --iItem; + iItem += iDirection; } if (bShowError) @@ -1498,7 +1501,7 @@ void CMuleListCtrl::DoFindNext(BOOL bShowError) if (iStartItem < 0) iStartItem = 0; else - iStartItem += (m_iFindDirection ? 1 : -1); + iStartItem += m_iFindDirection; DoFind(iStartItem, m_iFindDirection, bShowError); } @@ -1513,9 +1516,9 @@ void CMuleListCtrl::OnFindPrev() if (iStartItem < 0) iStartItem = 0; else - iStartItem += (m_iFindDirection ? -1 : 1); + iStartItem -= m_iFindDirection; - DoFind(iStartItem, !m_iFindDirection, FALSE/*bShowError*/); + DoFind(iStartItem, -m_iFindDirection, FALSE/*bShowError*/); } BOOL CMuleListCtrl::PreTranslateMessage(MSG *pMsg) @@ -1548,32 +1551,33 @@ void CMuleListCtrl::AutoSelectItem() } } -void CMuleListCtrl::UpdateSortHistory(int dwNewOrder, int dwInverseValue) +// Parameter is used as a LONG value +// LOWORD(dwNewOrder) - sort item, HIWORD(dwNewOrder) - sort direction +// HIWORD(dwNewOrder) != 0 means inverse order (descending usually) +void CMuleListCtrl::UpdateSortHistory(LPARAM dwNewOrder) { - int dwInverse = (dwNewOrder > dwInverseValue) ? (dwNewOrder - dwInverseValue) : (dwNewOrder + dwInverseValue); - // delete the value (or its inverse sorting value) if it appears already in the list + // delete all history for the item, for both direct and inverse order for (POSITION pos = m_liSortHistory.GetHeadPosition(); pos != NULL;) { POSITION pos2 = pos; - int i = m_liSortHistory.GetNext(pos); - if (i == dwNewOrder || i == dwInverse) + if (LOWORD(m_liSortHistory.GetNext(pos)) == LOWORD(dwNewOrder)) m_liSortHistory.RemoveAt(pos2); } - m_liSortHistory.AddHead(dwNewOrder); + m_liSortHistory.AddHead((LONG)dwNewOrder); // limit it to MAX_SORTORDERHISTORY entries for now, just for performance if (m_liSortHistory.GetCount() > MAX_SORTORDERHISTORY) m_liSortHistory.RemoveTail(); } -int CMuleListCtrl::GetNextSortOrder(int dwCurrentSortOrder) const +LPARAM CMuleListCtrl::GetNextSortOrder(LPARAM iCurrentSortOrder) const { - POSITION pos = m_liSortHistory.Find(dwCurrentSortOrder); + POSITION pos = m_liSortHistory.Find((LONG)iCurrentSortOrder); if (pos) { m_liSortHistory.GetNext(pos); - if (pos != NULL) + if (pos) return m_liSortHistory.GetAt(pos); } - // else ASSERT( false ); // the current one not found - shouldn't happen - return -1; // there is no further sort orders stored + //ASSERT(0); // the current one not found - shouldn't happen + return -1; // there are no more stored sort orders } CMuleListCtrl::EUpdateMode CMuleListCtrl::SetUpdateMode(EUpdateMode eUpdateMode) diff --git a/srchybrid/MuleListCtrl.h b/srchybrid/MuleListCtrl.h index a3b40218..b1b81b5f 100644 --- a/srchybrid/MuleListCtrl.h +++ b/srchybrid/MuleListCtrl.h @@ -32,7 +32,7 @@ class CMuleListCtrl : public CListCtrl DECLARE_DYNAMIC(CMuleListCtrl) public: - CMuleListCtrl(PFNLVCOMPARE pfnCompare = SortProc, DWORD dwParamSort = 0); + CMuleListCtrl(PFNLVCOMPARE pfnCompare = SortProc, LPARAM iParamSort = 0); virtual ~CMuleListCtrl(); // Default sort proc, this does nothing @@ -56,12 +56,7 @@ class CMuleListCtrl : public CListCtrl void ShowColumn(int iColumn); // Check to see if the column is hidden - bool IsColumnHidden(int iColumn) const - { - if (iColumn < 1 || iColumn >= m_iColumnsTracked) - return false; - return m_aColumns[iColumn].bHidden; - } + bool IsColumnHidden(int iColumn) const { return iColumn >= 1 && iColumn < m_iColumnsTracked && m_aColumns[iColumn].bHidden; } // Get the correct column width even if column is hidden int GetColumnWidth(int iColumn) const @@ -102,7 +97,7 @@ class CMuleListCtrl : public CListCtrl } // Call SetRedraw to allow changes to be redrawn or to prevent changes from being redrawn. - void SetRedraw(BOOL bRedraw = TRUE) + void SetRedraw(bool bRedraw = true) { if (bRedraw) { if (m_iRedrawCount > 0 && --m_iRedrawCount == 0) @@ -114,7 +109,7 @@ class CMuleListCtrl : public CListCtrl } // Sorts the list - BOOL SortItems(PFNLVCOMPARE pfnCompare, DWORD_PTR dwData) + BOOL SortItems(PFNLVCOMPARE pfnCompare, DWORD dwData) { return CListCtrl::SortItems(pfnCompare, dwData); } @@ -178,8 +173,8 @@ class CMuleListCtrl : public CListCtrl { SetSortArrow(iColumn, bAscending ? arrowUp : arrowDown); } - int GetNextSortOrder(int dwCurrentSortOrder) const; - void UpdateSortHistory(int dwNewOrder, int dwInverseValue = 100); + LPARAM GetNextSortOrder(LPARAM iCurrentSortOrder) const; + void UpdateSortHistory(LPARAM dwNewOrder); // General purpose listview find dialog+functions (optional) void SetGeneralPurposeFind(bool bEnable, bool bCanSearchInAllColumns = true) @@ -203,14 +198,8 @@ class CMuleListCtrl : public CListCtrl HIMAGELIST ApplyImageList(HIMAGELIST himl); void AutoSelectItem(); - void SetSkinKey(LPCTSTR pszKey) - { - m_strSkinKey = pszKey; - } - const CString& GetSkinKey() const - { - return m_strSkinKey; - } + void SetSkinKey(LPCTSTR pszKey) { m_strSkinKey = pszKey; } + const CString& GetSkinKey() const { return m_strSkinKey; } protected: virtual void PreSubclassWindow(); @@ -232,8 +221,9 @@ class CMuleListCtrl : public CListCtrl void SetColors(); void DrawFocusRect(CDC *pDC, LPCRECT rcItem, BOOL bItemFocused, BOOL bCtrlFocused, BOOL bItemSelected); void InitItemMemDC(CMemoryDC *dc, LPDRAWITEMSTRUCT lpDrawItemStruct, BOOL &bCtrlFocused); + void LocaliseHeaderCtrl(const UINT *const uids, size_t cnt); - static inline bool HaveIntersection(const CRect &rc1, const CRect &rc2) + static inline bool HaveIntersection(const RECT &rc1, const RECT &rc2) { return (rc1.left < rc2.right && rc1.top < rc2.bottom @@ -243,7 +233,7 @@ class CMuleListCtrl : public CListCtrl CString m_Name; PFNLVCOMPARE m_SortProc; - DWORD m_dwParamSort; + LPARAM m_dwParamSort; CString m_strSkinKey; COLORREF m_crWindow; COLORREF m_crWindowText; @@ -257,7 +247,7 @@ class CMuleListCtrl : public CListCtrl NMLVCUSTOMDRAW m_lvcd; BOOL m_bCustomDraw; CImageList m_imlHeaderCtrl; - CList m_liSortHistory; + CList m_liSortHistory; UINT m_uIDAccel; HACCEL m_hAccel; enum EUpdateMode m_eUpdateMode; @@ -308,8 +298,10 @@ class CMuleListCtrl : public CListCtrl DWORD_PTR GetParamAt(POSITION pos, int iPos) { DWORD_PTR lParam = m_Params.GetAt(pos); - if (lParam == 0xFEEBDEEF) //same as MLC_MAGIC! - m_Params.SetAt(pos, lParam = CListCtrl::GetItemData(iPos)); + if (lParam == 0xFEEBDEEF) { //same as MLC_MAGIC! + lParam = CListCtrl::GetItemData(iPos); + m_Params.SetAt(pos, lParam); + } return lParam; } diff --git a/srchybrid/MuleStatusBarCtrl.cpp b/srchybrid/MuleStatusBarCtrl.cpp index a8bc846d..e9e6cdd5 100644 --- a/srchybrid/MuleStatusBarCtrl.cpp +++ b/srchybrid/MuleStatusBarCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -87,9 +87,9 @@ CString CMuleStatusBarCtrl::GetPaneToolTipText(EStatusBarPane iPane) const { CString strText; if (iPane == SBarConnected && theApp.serverconnect && theApp.serverconnect->IsConnected()) { - CServer *cur_server = theApp.serverconnect->GetCurrentServer(); + const CServer *cur_server = theApp.serverconnect->GetCurrentServer(); if (cur_server) { - CServer *srv = theApp.serverlist->GetServerByAddress(cur_server->GetAddress(), cur_server->GetPort()); + const CServer *srv = theApp.serverlist->GetServerByAddress(cur_server->GetAddress(), cur_server->GetPort()); // Can't add more info than just the server name, unfortunately the MFC tooltip which // we use here does not show more than one(!) line of text. if (srv) diff --git a/srchybrid/MuleStatusBarCtrl.h b/srchybrid/MuleStatusBarCtrl.h index d563e4c1..1772df78 100644 --- a/srchybrid/MuleStatusBarCtrl.h +++ b/srchybrid/MuleStatusBarCtrl.h @@ -16,7 +16,6 @@ class CMuleStatusBarCtrl : public CStatusBarCtrl public: CMuleStatusBarCtrl() = default; - virtual ~CMuleStatusBarCtrl() = default; void Init(); diff --git a/srchybrid/MuleSystrayDlg.cpp b/srchybrid/MuleSystrayDlg.cpp index ad0ae5b2..0c4cd0e5 100644 --- a/srchybrid/MuleSystrayDlg.cpp +++ b/srchybrid/MuleSystrayDlg.cpp @@ -100,7 +100,7 @@ void CMuleSystrayDlg::OnMouseMove(UINT nFlags, CPoint point) if (pWnd == this || pWnd == &m_ctrlSidebar) SetCapture(); // me, myself and i else - ReleaseCapture(); // sweet child of mine + ::ReleaseCapture(); // sweet child of mine } else SetCapture(); // I'm on the outside, I'm looking in... @@ -372,7 +372,7 @@ void CMuleSystrayDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar *pScrollBar) void CMuleSystrayDlg::OnLButtonUp(UINT nFlags, CPoint point) { - ReleaseCapture(); + ::ReleaseCapture(); EndDialog(m_nExitCode); m_bClosingDown = true; @@ -385,7 +385,7 @@ void CMuleSystrayDlg::OnRButtonDown(UINT nFlags, CPoint point) CRect systrayRect; GetClientRect(&systrayRect); if (!systrayRect.PtInRect(point)) { - ReleaseCapture(); + ::ReleaseCapture(); EndDialog(m_nExitCode); m_bClosingDown = true; } @@ -398,7 +398,7 @@ void CMuleSystrayDlg::OnKillFocus(CWnd *pNewWnd) CDialog::OnKillFocus(pNewWnd); if (!m_bClosingDown) { - ReleaseCapture(); + ::ReleaseCapture(); EndDialog(m_nExitCode); m_bClosingDown = true; } @@ -407,7 +407,7 @@ void CMuleSystrayDlg::OnKillFocus(CWnd *pNewWnd) void CMuleSystrayDlg::OnShowWindow(BOOL bShow, UINT nStatus) { if (!bShow && !m_bClosingDown) { - ReleaseCapture(); + ::ReleaseCapture(); EndDialog(m_nExitCode); m_bClosingDown = true; } @@ -427,11 +427,10 @@ void CMuleSystrayDlg::OnCaptureChanged(CWnd *pWnd) BOOL CMuleSystrayDlg::OnCommand(WPARAM wParam, LPARAM lParam) { if (HIWORD(wParam) == BN_CLICKED) { - ReleaseCapture(); + ::ReleaseCapture(); m_nExitCode = LOWORD(wParam); EndDialog(m_nExitCode); m_bClosingDown = true; } - return CDialog::OnCommand(wParam, lParam); } \ No newline at end of file diff --git a/srchybrid/MuleToolBarCtrl.cpp b/srchybrid/MuleToolBarCtrl.cpp index 9ae83f66..87ae2e0a 100644 --- a/srchybrid/MuleToolBarCtrl.cpp +++ b/srchybrid/MuleToolBarCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -168,13 +168,13 @@ void CMuleToolbarCtrl::Init() } TBBUTTON sepButton = {}; - sepButton.idCommand = 0; + //sepButton.idCommand = 0; sepButton.fsStyle = TBSTYLE_SEP; sepButton.fsState = TBSTATE_ENABLED; sepButton.iString = -1; sepButton.iBitmap = -1; - const CString &config = thePrefs.GetToolbarSettings(); + const CString &config(thePrefs.GetToolbarSettings()); for (int i = 0; i < config.GetLength(); i += 2) { int index = _tstoi(config.Mid(i, 2)); AddButtons(1, (index == 99) ? &sepButton : &TBButtons[index]); @@ -191,9 +191,9 @@ void CMuleToolbarCtrl::Init() void CMuleToolbarCtrl::SetAllButtonsStrings() { - TBBUTTONINFO tbi; - tbi.dwMask = TBIF_TEXT; - tbi.cbSize = (UINT)sizeof(TBBUTTONINFO); + TBBUTTONINFO tbbi; + tbbi.cbSize = (UINT)sizeof(TBBUTTONINFO); + tbbi.dwMask = TBIF_TEXT; UINT uid; if (theApp.serverconnect->IsConnected()) @@ -206,8 +206,8 @@ void CMuleToolbarCtrl::SetAllButtonsStrings() for (int i = 0; ; ++i) { const CString &str(GetResString(uid)); _tcsncpy_s(TBStrings[i], _countof(TBStrings[i]), str, _TRUNCATE); - tbi.pszText = TBStrings[i]; - SetButtonInfo(IDC_TOOLBARBUTTON + i, &tbi); + tbbi.pszText = TBStrings[i]; + SetButtonInfo(IDC_TOOLBARBUTTON + i, &tbbi); if (i >= _countof(TBStringIDs)) break; uid = TBStringIDs[i]; @@ -326,7 +326,7 @@ void CMuleToolbarCtrl::OnNmRClick(LPNMHDR, LRESULT *pResult) menuBitmaps.AppendMenu(MF_STRING, MP_TOOLBARBITMAP, GetResString(IDS_DEFAULT)); m_astrToolbarPaths.RemoveAll(); - const CString ¤tBitmapSettings = thePrefs.GetToolbarBitmapSettings(); + const CString ¤tBitmapSettings(thePrefs.GetToolbarBitmapSettings()); bool checked = currentBitmapSettings.IsEmpty(); if (checked) { menuBitmaps.CheckMenuItem(MP_TOOLBARBITMAP, MF_CHECKED); @@ -338,7 +338,7 @@ void CMuleToolbarCtrl::OnNmRClick(LPNMHDR, LRESULT *pResult) CStringArray astrToolbarFiles; for (unsigned f = 0; f < _countof(s_apszTBFiles); ++f) { WIN32_FIND_DATA FileData; - HANDLE hSearch = FindFirstFile(thePrefs.GetMuleDirectory(EMULE_TOOLBARDIR) + _T('\\') + s_apszTBFiles[f], &FileData); + HANDLE hSearch = FindFirstFile(thePrefs.GetMuleDirectory(EMULE_TOOLBARDIR) + s_apszTBFiles[f], &FileData); if (hSearch != INVALID_HANDLE_VALUE) { do astrToolbarFiles.Add(FileData.cFileName); @@ -350,15 +350,11 @@ void CMuleToolbarCtrl::OnNmRClick(LPNMHDR, LRESULT *pResult) if (!astrToolbarFiles.IsEmpty()) { Sort(astrToolbarFiles); for (int f = 0; f < astrToolbarFiles.GetCount(); ++f) { - const CString &bitmapFileName = astrToolbarFiles[f]; - CString bitmapBaseName; - LPCTSTR pszTbBaseExt = stristr(bitmapFileName, EMULTB_BASEEXT); - if (pszTbBaseExt) - bitmapBaseName = bitmapFileName.Left((int)(pszTbBaseExt - (LPCTSTR)bitmapFileName - 1)); - else - bitmapBaseName = bitmapFileName; - menuBitmaps.AppendMenu(MF_STRING, MP_TOOLBARBITMAP + i, bitmapBaseName); - m_astrToolbarPaths.Add(thePrefs.GetMuleDirectory(EMULE_TOOLBARDIR) + _T('\\') + bitmapFileName); + const CString &bitmapFileName(astrToolbarFiles[f]); + LPCTSTR pTbBaseExt = stristr(bitmapFileName, EMULTB_BASEEXT); + int iBaseLen = pTbBaseExt ? (int)(pTbBaseExt - (LPCTSTR)bitmapFileName - 1) : bitmapFileName.GetLength(); + menuBitmaps.AppendMenu(MF_STRING, MP_TOOLBARBITMAP + i, CString(bitmapFileName, iBaseLen)); + m_astrToolbarPaths.Add(thePrefs.GetMuleDirectory(EMULE_TOOLBARDIR) + bitmapFileName); if (!checked && currentBitmapSettings.CompareNoCase(m_astrToolbarPaths[i]) == 0) { menuBitmaps.CheckMenuItem(MP_TOOLBARBITMAP + i, MF_CHECKED); menuBitmaps.EnableMenuItem(MP_TOOLBARBITMAP + i, MF_DISABLED); @@ -388,7 +384,7 @@ void CMuleToolbarCtrl::OnNmRClick(LPNMHDR, LRESULT *pResult) menuSkins.AppendMenu(MF_STRING, MP_SKIN_PROFILE, GetResString(IDS_DEFAULT)); m_astrSkinPaths.RemoveAll(); - const CString ¤tSkin = thePrefs.GetSkinProfile(); + const CString ¤tSkin(thePrefs.GetSkinProfile()); checked = currentSkin.IsEmpty(); if (checked) { menuSkins.CheckMenuItem(MP_SKIN_PROFILE, MF_CHECKED); @@ -400,7 +396,7 @@ void CMuleToolbarCtrl::OnNmRClick(LPNMHDR, LRESULT *pResult) CStringArray astrSkinFiles; for (unsigned f = 0; f < _countof(s_apszSkinFiles); ++f) { WIN32_FIND_DATA FileData; - HANDLE hSearch = FindFirstFile(thePrefs.GetMuleDirectory(EMULE_SKINDIR, false) + _T('\\') + s_apszSkinFiles[f], &FileData); + HANDLE hSearch = FindFirstFile(thePrefs.GetMuleDirectory(EMULE_SKINDIR, false) + s_apszSkinFiles[f], &FileData); if (hSearch != INVALID_HANDLE_VALUE) { do astrSkinFiles.Add(FileData.cFileName); @@ -412,15 +408,11 @@ void CMuleToolbarCtrl::OnNmRClick(LPNMHDR, LRESULT *pResult) if (!astrSkinFiles.IsEmpty()) { Sort(astrSkinFiles); for (int f = 0; f < astrSkinFiles.GetCount(); ++f) { - const CString &skinFileName = astrSkinFiles[f]; - CString skinBaseName; - LPCTSTR pszSkinBaseExt = stristr(skinFileName, _T(".") EMULSKIN_BASEEXT _T(".ini")); - if (pszSkinBaseExt) - skinBaseName = skinFileName.Left((int)(pszSkinBaseExt - (LPCTSTR)skinFileName)); - else - skinBaseName = skinFileName; - menuSkins.AppendMenu(MF_STRING, MP_SKIN_PROFILE + i, skinBaseName); - m_astrSkinPaths.Add(thePrefs.GetMuleDirectory(EMULE_SKINDIR, false) + _T('\\') + skinFileName); + const CString &skinFileName(astrSkinFiles[f]); + LPCTSTR pSkinBaseExt = stristr(skinFileName, _T(".") EMULSKIN_BASEEXT _T(".ini")); + int iBaseLen = pSkinBaseExt ? (int)(pSkinBaseExt - (LPCTSTR)skinFileName - 1) : skinFileName.GetLength(); + menuSkins.AppendMenu(MF_STRING, MP_SKIN_PROFILE + i, CString(skinFileName, iBaseLen)); + m_astrSkinPaths.Add(thePrefs.GetMuleDirectory(EMULE_SKINDIR, false) + skinFileName); if (!checked && currentSkin.CompareNoCase(m_astrSkinPaths[i]) == 0) { menuSkins.CheckMenuItem(MP_SKIN_PROFILE + i, MF_CHECKED); menuSkins.EnableMenuItem(MP_SKIN_PROFILE + i, MF_DISABLED); @@ -613,7 +605,9 @@ BOOL CMuleToolbarCtrl::OnCommand(WPARAM wParam, LPARAM) strFilter += s_apszTBFiles[f]; } strFilter += _T("||"); - CFileDialog dialog(TRUE, EMULTB_BASEEXT _T(".bmp"), NULL, OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST, strFilter, NULL, 0); + + const CString &sInitialDir(thePrefs.GetMuleDirectory(EMULE_TOOLBARDIR, false)); + CFileDialog dialog(TRUE, EMULTB_BASEEXT _T(".bmp"), (sInitialDir.IsEmpty() ? NULL : sInitialDir), OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST, strFilter, NULL, 0); if (IDOK == dialog.DoModal()) if (thePrefs.GetToolbarBitmapSettings() != dialog.GetPathName()) { ChangeToolbarBitmap(dialog.GetPathName(), true); @@ -663,7 +657,9 @@ BOOL CMuleToolbarCtrl::OnCommand(WPARAM wParam, LPARAM) strFilter += s_apszSkinFiles[f]; } strFilter += _T("||"); - CFileDialog dialog(TRUE, EMULSKIN_BASEEXT _T(".ini"), NULL, OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST, strFilter, NULL, 0); + + const CString &sInitialDir(thePrefs.GetMuleDirectory(EMULE_SKINDIR, false)); + CFileDialog dialog(TRUE, EMULSKIN_BASEEXT _T(".ini"), (sInitialDir.IsEmpty() ? NULL : sInitialDir), OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST, strFilter, NULL, 0); if (dialog.DoModal() == IDOK) { if (thePrefs.GetSkinProfile().CompareNoCase(dialog.GetPathName()) != 0) theApp.ApplySkin(dialog.GetPathName()); @@ -682,7 +678,7 @@ BOOL CMuleToolbarCtrl::OnCommand(WPARAM wParam, LPARAM) } } - return true; + return TRUE; } void CMuleToolbarCtrl::ChangeTextLabelStyle(EToolbarLabelType eLabelType, bool bRefresh, bool bForceUpdateButtons) @@ -702,10 +698,10 @@ void CMuleToolbarCtrl::ChangeTextLabelStyle(EToolbarLabelType eLabelType, bool b SetMaxTextRows(1); } + TBBUTTONINFO tbbi; + tbbi.cbSize = (UINT)sizeof tbbi; + tbbi.dwMask = TBIF_STYLE; for (int i = 0; i < m_buttoncount; ++i) { - TBBUTTONINFO tbbi; - tbbi.cbSize = (UINT)sizeof tbbi; - tbbi.dwMask = TBIF_STYLE; if (GetButtonInfo(IDC_TOOLBARBUTTON + i, &tbbi)) { if (eLabelType == LabelsRight) tbbi.fsStyle |= TBSTYLE_AUTOSIZE; @@ -960,16 +956,18 @@ void CMuleToolbarCtrl::Dump() TRACE("\n"); TRACE("Info :"); + TBBUTTONINFO tbbi; + tbbi.cbSize = (UINT)sizeof tbbi; + tbbi.dwMask |= TBIF_BYINDEX | TBIF_COMMAND | TBIF_IMAGE | TBIF_LPARAM | TBIF_SIZE | TBIF_STATE | TBIF_STYLE | TBIF_TEXT; + for (int i = 0; i < iButtons; ++i) { TCHAR szLabel[256]; - TBBUTTONINFO tbi = {}; - tbi.cbSize = (UINT)sizeof tbi; - tbi.dwMask |= TBIF_BYINDEX | TBIF_COMMAND | TBIF_IMAGE | TBIF_LPARAM | TBIF_SIZE | TBIF_STATE | TBIF_STYLE | TBIF_TEXT; - tbi.cchText = _countof(szLabel); - tbi.pszText = szLabel; - GetButtonInfo(i, &tbi); - szLabel[_countof(szLabel) - 1] = _T('\0'); - TRACE(" %2d ", tbi.cx); + tbbi.cchText = _countof(szLabel); + tbbi.pszText = szLabel; + if (GetButtonInfo(i, &tbbi) >= 0) { + szLabel[_countof(szLabel) - 1] = _T('\0'); + TRACE(" %2d ", tbbi.cx); + } } TRACE("\n"); } diff --git a/srchybrid/NetworkInfoDlg.cpp b/srchybrid/NetworkInfoDlg.cpp index d68fc4ed..01f99b36 100644 --- a/srchybrid/NetworkInfoDlg.cpp +++ b/srchybrid/NetworkInfoDlg.cpp @@ -80,17 +80,12 @@ BOOL CNetworkInfoDlg::OnInitDialog() } CreateNetworkInfo(m_info, cfDef, cfBold, true); - m_info.SetSel(0, 0); - m_info.HideSelection(TRUE, FALSE); - m_info.SetOptions(ECOOP_OR, ECO_SAVESEL); - + DisableAutoSelect(m_info); return TRUE; } void CreateNetworkInfo(CRichEditCtrlX &rCtrl, CHARFORMAT &rcfDef, CHARFORMAT &rcfBold, bool bFullInfo) { - CString buffer; - if (bFullInfo) { /////////////////////////////////////////////////////////////////////////// // Ports Info @@ -134,6 +129,7 @@ void CreateNetworkInfo(CRichEditCtrlX &rCtrl, CHARFORMAT &rcfDef, CHARFORMAT &rc rCtrl << GetResString(IDS_PW_FILES) << _T(":\t") << GetFormatedUInt(uTotalFile) << _T("\r\n"); } + CString buffer; if (theApp.serverconnect->IsConnected()) { rCtrl << GetResString(IDS_IP) << _T(":") << GetResString(IDS_PORT) << _T(":"); if (theApp.serverconnect->IsLowID() && theApp.GetPublicIP(true) == 0) @@ -278,9 +274,8 @@ void CreateNetworkInfo(CRichEditCtrlX &rCtrl, CHARFORMAT &rcfDef, CHARFORMAT &rc } if (bFullInfo) { - CString sKadID; - Kademlia::CKademlia::GetPrefs()->GetKadID(&sKadID); + Kademlia::CKademlia::GetPrefs()->GetKadID(sKadID); rCtrl << GetResString(IDS_CD_UHASH) << _T("\t") << sKadID << _T("\r\n"); rCtrl << GetResString(IDS_UUSERS) << _T(":\t") << GetFormatedUInt(Kademlia::CKademlia::GetKademliaUsers()) << _T(" (Experimental: ") << GetFormatedUInt(Kademlia::CKademlia::GetKademliaUsers(true)) << _T(")\r\n"); @@ -310,15 +305,15 @@ void CreateNetworkInfo(CRichEditCtrlX &rCtrl, CHARFORMAT &rcfDef, CHARFORMAT &rc rCtrl << GetResString(IDS_STATUS) << _T(":\t"); rCtrl << GetResString(thePrefs.GetWSIsEnabled() ? IDS_ENABLED : IDS_DISABLED) << _T("\r\n"); if (thePrefs.GetWSIsEnabled()) { - CString count; - count.Format(_T("%d %s"), static_cast(theApp.webserver->GetSessionCount()), (LPCTSTR)GetResString(IDS_ACTSESSIONS)); - rCtrl << _T("\t") << count << _T("\r\n"); - CString strHostname; + CString sTemp; + sTemp.Format(_T("%d %s"), static_cast(theApp.webserver->GetSessionCount()), (LPCTSTR)GetResString(IDS_ACTSESSIONS)); + rCtrl << _T("\t") << sTemp << _T("\r\n"); //count + if (thePrefs.GetYourHostname().IsEmpty() || thePrefs.GetYourHostname().Find(_T('.')) < 0) - strHostname = ipstr(theApp.serverconnect->GetLocalIP()); + sTemp = ipstr(theApp.serverconnect->GetLocalIP()); else - strHostname = thePrefs.GetYourHostname(); + sTemp = thePrefs.GetYourHostname(); rCtrl << _T("URL:\t") << (thePrefs.GetWebUseHttps() ? _T("https://") : _T("http://")); - rCtrl << strHostname << _T(":") << thePrefs.GetWSPort() << _T("/\r\n"); + rCtrl << sTemp << _T(":") << thePrefs.GetWSPort() << _T("/\r\n"); //web interface host name } } \ No newline at end of file diff --git a/srchybrid/NetworkInfoDlg.h b/srchybrid/NetworkInfoDlg.h index ac31e8cd..9d455a0e 100644 --- a/srchybrid/NetworkInfoDlg.h +++ b/srchybrid/NetworkInfoDlg.h @@ -16,7 +16,6 @@ class CNetworkInfoDlg : public CResizableDialog public: explicit CNetworkInfoDlg(CWnd *pParent = NULL); // standard constructor - virtual ~CNetworkInfoDlg() = default; protected: CRichEditCtrlX m_info; diff --git a/srchybrid/OScopeCtrl.cpp b/srchybrid/OScopeCtrl.cpp index 24db349b..397fb1d6 100644 --- a/srchybrid/OScopeCtrl.cpp +++ b/srchybrid/OScopeCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -110,21 +110,19 @@ COScopeCtrl::COScopeCtrl(int NTrends) m_PlotData = new PlotData_t[NTrends]; m_NTrends = NTrends; for (int iTrend = 0; iTrend < m_NTrends; ++iTrend) { - if (iTrend < 15) - m_PlotData[iTrend].crPlotColor = PresetColor[iTrend]; // see also SetPlotColor - else - m_PlotData[iTrend].crPlotColor = RGB(255, 255, 255); // see also SetPlotColor - m_PlotData[iTrend].penPlot.CreatePen(PS_SOLID, 0, m_PlotData[iTrend].crPlotColor); - m_PlotData[iTrend].dPreviousPosition = 0.0; - m_PlotData[iTrend].nPrevY = -1; - m_PlotData[iTrend].dLowerLimit = -10.0; - m_PlotData[iTrend].dUpperLimit = 10.0; - m_PlotData[iTrend].dRange = m_PlotData[iTrend].dUpperLimit - m_PlotData[iTrend].dLowerLimit; - m_PlotData[iTrend].lstPoints.AddTail(0.0); + PlotData_t &plot = m_PlotData[iTrend]; + plot.crPlotColor = (iTrend < 15) ? PresetColor[iTrend] : RGB(255, 255, 255); // see also SetPlotColor + plot.penPlot.CreatePen(PS_SOLID, 0, plot.crPlotColor); + plot.dPreviousPosition = 0.0; + plot.nPrevY = -1; + plot.dLowerLimit = -10.0; + plot.dUpperLimit = 10.0; + plot.dRange = plot.dUpperLimit - plot.dLowerLimit; + plot.lstPoints.AddTail(0.0); // Initialize our new trend ratio variable to 1 - m_PlotData[iTrend].iTrendRatio = 1; - m_PlotData[iTrend].LegendLabel.Format(_T("Legend %i"), iTrend); - m_PlotData[iTrend].BarsPlot = false; + plot.iTrendRatio = 1; + plot.LegendLabel.Format(_T("Legend %i"), iTrend); + plot.BarsPlot = false; } // public variable for the number of decimal places on the y axis @@ -133,7 +131,7 @@ COScopeCtrl::COScopeCtrl(int NTrends) m_nYDecimals = 1; // set some initial values for the scaling until "SetRange" is called. - // these are protected varaibles and must be set with SetRange + // these are protected variables and must be set with SetRange // in order to ensure that m_dRange is updated accordingly // m_nShiftPixels determines how much the plot shifts (in terms of pixels) @@ -179,7 +177,7 @@ COScopeCtrl::~COScopeCtrl() BOOL COScopeCtrl::Create(DWORD dwStyle, const CRect &rect, CWnd *pParentWnd, UINT nID) { - static const CString &className = AfxRegisterWndClass(CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, AfxGetApp()->LoadStandardCursor(IDC_ARROW)); + static const CString &className(AfxRegisterWndClass(CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, AfxGetApp()->LoadStandardCursor(IDC_ARROW))); BOOL result = CWnd::CreateEx(/*WS_EX_CLIENTEDGE*/ // strong (default) border WS_EX_STATICEDGE // lightweight border @@ -213,15 +211,16 @@ void COScopeCtrl::SetTrendRatio(int iTrend, unsigned iRatio) { ASSERT(iTrend < m_NTrends && iRatio > 0); // iTrend must be a valid trend in this plot. - if (iRatio != (unsigned)m_PlotData[iTrend].iTrendRatio) { - double dTrendModifier = m_PlotData[iTrend].iTrendRatio / (double)iRatio; - m_PlotData[iTrend].iTrendRatio = iRatio; + PlotData_t &plot = m_PlotData[iTrend]; + if (iRatio != (unsigned)plot.iTrendRatio) { + double dTrendModifier = plot.iTrendRatio / (double)iRatio; + plot.iTrendRatio = iRatio; - INT_PTR iCnt = m_PlotData[iTrend].lstPoints.GetCount(); + INT_PTR iCnt = plot.lstPoints.GetCount(); for (int i = 0; i < iCnt; ++i) { - POSITION pos = m_PlotData[iTrend].lstPoints.FindIndex(i); + POSITION pos = plot.lstPoints.FindIndex(i); if (pos) - m_PlotData[iTrend].lstPoints.SetAt(pos, m_PlotData[iTrend].lstPoints.GetAt(pos) * dTrendModifier); + plot.lstPoints.SetAt(pos, plot.lstPoints.GetAt(pos) * dTrendModifier); } InvalidateCtrl(); } @@ -243,10 +242,11 @@ void COScopeCtrl::SetRange(double dLower, double dUpper, int iTrend) { ASSERT(dUpper > dLower); - m_PlotData[iTrend].dLowerLimit = dLower; - m_PlotData[iTrend].dUpperLimit = dUpper; - m_PlotData[iTrend].dRange = m_PlotData[iTrend].dUpperLimit - m_PlotData[iTrend].dLowerLimit; - m_PlotData[iTrend].dVerticalFactor = m_nPlotHeight / m_PlotData[iTrend].dRange; + PlotData_t &plot = m_PlotData[iTrend]; + plot.dLowerLimit = dLower; + plot.dUpperLimit = dUpper; + plot.dRange = plot.dUpperLimit - plot.dLowerLimit; + plot.dVerticalFactor = m_nPlotHeight / plot.dRange; InvalidateCtrl(); } @@ -255,10 +255,11 @@ void COScopeCtrl::SetRanges(double dLower, double dUpper) ASSERT(dUpper > dLower); for (int iTrend = 0; iTrend < m_NTrends; ++iTrend) { - m_PlotData[iTrend].dLowerLimit = dLower; - m_PlotData[iTrend].dUpperLimit = dUpper; - m_PlotData[iTrend].dRange = m_PlotData[iTrend].dUpperLimit - m_PlotData[iTrend].dLowerLimit; - m_PlotData[iTrend].dVerticalFactor = m_nPlotHeight / m_PlotData[iTrend].dRange; + PlotData_t &plot = m_PlotData[iTrend]; + plot.dLowerLimit = dLower; + plot.dUpperLimit = dUpper; + plot.dRange = plot.dUpperLimit - plot.dLowerLimit; + plot.dVerticalFactor = m_nPlotHeight / plot.dRange; } InvalidateCtrl(); } @@ -287,9 +288,10 @@ void COScopeCtrl::SetGridColor(COLORREF color) void COScopeCtrl::SetPlotColor(COLORREF color, int iTrend) { - m_PlotData[iTrend].crPlotColor = color; - m_PlotData[iTrend].penPlot.DeleteObject(); - m_PlotData[iTrend].penPlot.CreatePen(PS_SOLID, 0, m_PlotData[iTrend].crPlotColor); + PlotData_t &plot = m_PlotData[iTrend]; + plot.crPlotColor = color; + plot.penPlot.DeleteObject(); + plot.penPlot.CreatePen(PS_SOLID, 0, plot.crPlotColor); //InvalidateCtrl(); } @@ -372,7 +374,7 @@ void COScopeCtrl::InvalidateCtrl(bool deleteGraph) int partialSize = m_rectPlot.Width() - hourSize * m_nXGrids; int surplus = 0; if (partialSize >= hourSize) { - partialSize = (hourSize*m_nXPartial) / HR2S(1); // real partial size + partialSize = (hourSize * m_nXPartial) / HR2S(1); // real partial size surplus = m_rectPlot.Width() - hourSize * m_nXGrids - partialSize; // Pixel surplus } @@ -449,7 +451,8 @@ void COScopeCtrl::InvalidateCtrl(bool deleteGraph) int xpos = m_rectPlot.left + 2; int ypos = m_rectPlot.bottom + 3; for (int iTrend = 0; iTrend < m_NTrends; ++iTrend) { - CSize sizeLabel = m_dcGrid.GetTextExtent(m_PlotData[iTrend].LegendLabel); + PlotData_t &plot = m_PlotData[iTrend]; + CSize sizeLabel = m_dcGrid.GetTextExtent(plot.LegendLabel); if (xpos + 12 + sizeLabel.cx + 12 > m_rectPlot.right) { xpos = m_rectPlot.left + 2; ypos = m_rectPlot.bottom + sizeLabel.cy + 2; @@ -472,17 +475,17 @@ void COScopeCtrl::InvalidateCtrl(bool deleteGraph) m_dcGrid.LineTo(rcLegendFrame.left, rcLegendFrame.bottom); m_dcGrid.LineTo(rcLegendFrame.left, rcLegendFrame.top); m_dcGrid.SelectObject(oldPen); - m_dcGrid.FillSolidRect(xpos, ypos + 2, iLegBoxW, iLegBoxH, m_PlotData[iTrend].crPlotColor); + m_dcGrid.FillSolidRect(xpos, ypos + 2, iLegBoxW, iLegBoxH, plot.crPlotColor); m_dcGrid.SetBkColor(crLabelBk); } else { - CPen LegendPen(PS_SOLID, 3, m_PlotData[iTrend].crPlotColor); + CPen LegendPen(PS_SOLID, 3, plot.crPlotColor); CPen *oldPen = m_dcGrid.SelectObject(&LegendPen); m_dcGrid.MoveTo(xpos, ypos + 8); m_dcGrid.LineTo(xpos + 8, ypos + 4); m_dcGrid.SelectObject(oldPen); } - m_dcGrid.TextOut(xpos + 12, ypos, m_PlotData[iTrend].LegendLabel); + m_dcGrid.TextOut(xpos + 12, ypos, plot.LegendLabel); xpos += 12 + sizeLabel.cx + 12; } @@ -504,7 +507,7 @@ void COScopeCtrl::InvalidateCtrl(bool deleteGraph) if (m_nMaxPointCnt < iNewSize) m_nMaxPointCnt = iNewSize; - if (!theApp.IsClosing() && !thePrefs.IsGraphRecreateDisabled()) { + if (!thePrefs.IsGraphRecreateDisabled() && !theApp.IsClosing()) { // The timer will redraw the previous points in 200ms m_bDoUpdate = false; if (m_nRedrawTimer) @@ -519,19 +522,18 @@ void COScopeCtrl::AppendPoints(double dNewPoint[], bool bInvalidate, bool bAdd2L { // append a data point to the plot for (int iTrend = 0; iTrend < m_NTrends; ++iTrend) { + PlotData_t &plot = m_PlotData[iTrend]; // Changed this to support the new TrendRatio var - if (bUseTrendRatio) - m_PlotData[iTrend].dCurrentPosition = (double)dNewPoint[iTrend] / m_PlotData[iTrend].iTrendRatio; - else - m_PlotData[iTrend].dCurrentPosition = dNewPoint[iTrend]; + double dPoint = bUseTrendRatio ? dNewPoint[iTrend] / plot.iTrendRatio : dNewPoint[iTrend]; + plot.dCurrentPosition = dPoint; if (bAdd2List) { - m_PlotData[iTrend].lstPoints.AddTail(m_PlotData[iTrend].dCurrentPosition); - while (m_PlotData[iTrend].lstPoints.GetCount() > m_nMaxPointCnt) - m_PlotData[iTrend].lstPoints.RemoveHead(); + plot.lstPoints.AddTail(dPoint); + while (plot.lstPoints.GetCount() > m_nMaxPointCnt) + plot.lstPoints.RemoveHead(); } } - // Sometime responsible for 'ghost' point on the left after a resize + // Sometimes responsible for 'ghost' point on the left after a resize if (!m_bDoUpdate) return; @@ -548,7 +550,7 @@ void COScopeCtrl::AppendPoints(double dNewPoint[], bool bInvalidate, bool bAdd2L if (CustShift.m_nPointsToDo == 1) m_nShiftPixels = CustShift.m_nWidthToDo; CustShift.m_nWidthToDo -= m_nShiftPixels; - CustShift.m_nPointsToDo--; + --CustShift.m_nPointsToDo; } DrawPoint(); @@ -571,12 +573,11 @@ void COScopeCtrl::AppendEmptyPoints(double dNewPoint[], bool bInvalidate, bool b // append a data point to the plot // return the previous point for (int iTrend = 0; iTrend < m_NTrends; ++iTrend) { - double dPoint = dNewPoint[iTrend]; - if (bUseTrendRatio) - dPoint /= m_PlotData[iTrend].iTrendRatio; - m_PlotData[iTrend].dCurrentPosition = dPoint; + PlotData_t &plot = m_PlotData[iTrend]; + double dPoint = bUseTrendRatio ? dNewPoint[iTrend] / plot.iTrendRatio : dNewPoint[iTrend]; + plot.dCurrentPosition = dPoint; if (bAdd2List) - m_PlotData[iTrend].lstPoints.AddTail(dPoint); + plot.lstPoints.AddTail(dPoint); } if (m_nTrendPoints > 0) { if (CustShift.m_nPointsToDo == 0) { @@ -589,7 +590,7 @@ void COScopeCtrl::AppendEmptyPoints(double dNewPoint[], bool bInvalidate, bool b if (CustShift.m_nPointsToDo == 1) m_nShiftPixels = CustShift.m_nWidthToDo; CustShift.m_nWidthToDo -= m_nShiftPixels; - CustShift.m_nPointsToDo--; + --CustShift.m_nPointsToDo; } // DrawPoint's shift process @@ -610,12 +611,13 @@ void COScopeCtrl::AppendEmptyPoints(double dNewPoint[], bool bInvalidate, bool b // draw the next line segment for (int iTrend = 0; iTrend < m_NTrends; ++iTrend) { - m_PlotData[iTrend].nPrevY = (long)(m_rectPlot.bottom - - m_PlotData[iTrend].dVerticalFactor * - (m_PlotData[iTrend].dCurrentPosition - m_PlotData[iTrend].dLowerLimit)); + PlotData_t &plot = m_PlotData[iTrend]; + plot.nPrevY = (long)(m_rectPlot.bottom + - plot.dVerticalFactor * + (plot.dCurrentPosition - plot.dLowerLimit)); // store the current point for connection to the next point - m_PlotData[iTrend].dPreviousPosition = m_PlotData[iTrend].dCurrentPosition; + plot.dPreviousPosition = plot.dCurrentPosition; } } @@ -673,29 +675,30 @@ void COScopeCtrl::DrawPoint() // draw the next line segment for (int iTrend = 0; iTrend < m_NTrends; ++iTrend) { + PlotData_t &plot = m_PlotData[iTrend]; // grab the plotting pen - CPen *oldPen = m_dcPlot.SelectObject(&m_PlotData[iTrend].penPlot); + CPen *oldPen = m_dcPlot.SelectObject(&plot.penPlot); // move to the previous point int prevX = m_rectPlot.right - m_nShiftPixels; int prevY; - if (m_PlotData[iTrend].nPrevY > 0) - prevY = m_PlotData[iTrend].nPrevY; + if (plot.nPrevY > 0) + prevY = plot.nPrevY; else { prevY = m_rectPlot.bottom - - (long)((m_PlotData[iTrend].dPreviousPosition - m_PlotData[iTrend].dLowerLimit) - * m_PlotData[iTrend].dVerticalFactor); + - (long)((plot.dPreviousPosition - plot.dLowerLimit) + * plot.dVerticalFactor); } - if (!m_PlotData[iTrend].BarsPlot) + if (!plot.BarsPlot) m_dcPlot.MoveTo(prevX, prevY); // draw to the current point int currX = m_rectPlot.right; int currY = m_rectPlot.bottom - - (long)((m_PlotData[iTrend].dCurrentPosition - m_PlotData[iTrend].dLowerLimit) - * m_PlotData[iTrend].dVerticalFactor); - m_PlotData[iTrend].nPrevY = currY; - if (m_PlotData[iTrend].BarsPlot) + - (long)((plot.dCurrentPosition - plot.dLowerLimit) + * plot.dVerticalFactor); + plot.nPrevY = currY; + if (plot.BarsPlot) m_dcPlot.MoveTo(currX, m_rectPlot.bottom); else { if (abs(prevX - currX) > abs(prevY - currY)) @@ -715,7 +718,7 @@ void COScopeCtrl::DrawPoint() m_dcPlot.FillSolidRect(CRect(prevX - 1, m_rectPlot.bottom + 1, currX + 5, m_rectClient.bottom + 1), m_crBackColor); // store the current point for connection to the next point - m_PlotData[iTrend].dPreviousPosition = m_PlotData[iTrend].dCurrentPosition; + plot.dPreviousPosition = plot.dCurrentPosition; } } } @@ -771,37 +774,37 @@ void COScopeCtrl::Reset() { // Clear all points for (int iTrend = 0; iTrend < m_NTrends; ++iTrend) { - m_PlotData[iTrend].dPreviousPosition = 0.0; - m_PlotData[iTrend].nPrevY = -1; - m_PlotData[iTrend].lstPoints.RemoveAll(); + PlotData_t &plot = m_PlotData[iTrend]; + plot.dPreviousPosition = 0.0; + plot.nPrevY = -1; + plot.lstPoints.RemoveAll(); } InvalidateCtrl(); } -int COScopeCtrl::ReCreateGraph() +void COScopeCtrl::ReCreateGraph() { for (int iTrend = 0; iTrend < m_NTrends; ++iTrend) { - m_PlotData[iTrend].dPreviousPosition = 0.0; - m_PlotData[iTrend].nPrevY = -1; + PlotData_t &plot = m_PlotData[iTrend]; + plot.dPreviousPosition = 0.0; + plot.nPrevY = -1; } - double *pAddPoints = new double[m_NTrends]; - POSITION *pPosArray = new POSITION[m_NTrends]; - // Try to avoid to call the method AppendPoints() more than necessary // Remark: the default size of the list is 1024 - INT_PTR pointToDraw = m_PlotData[0].lstPoints.GetCount(); - if (pointToDraw > m_nPlotWidth / m_nShiftPixels + 1) - pointToDraw = m_nPlotWidth / m_nShiftPixels + 1; - INT_PTR startIndex = m_PlotData[0].lstPoints.GetCount() - pointToDraw; + // The number of points to draw is: m_nPlotWidth / m_nShiftPixels + 1 + INT_PTR startIndex = m_PlotData[0].lstPoints.GetCount(); + startIndex -= min(startIndex, m_nPlotWidth / m_nShiftPixels + 1); // Prepare to go through the elements on n lists in parallel + POSITION *pPosArray = new POSITION[m_NTrends]; for (int iTrend = 0; iTrend < m_NTrends; ++iTrend) pPosArray[iTrend] = m_PlotData[iTrend].lstPoints.FindIndex(startIndex); - // We will assume that each trends have the same among of points, so we test only the first iterator - while (pPosArray[0] != 0) { + // We will assume that all trends have the same number of points, so we test only the first iterator + double *pAddPoints = new double[m_NTrends]; + while (pPosArray[0] != NULL) { for (int iTrend = 0; iTrend < m_NTrends; ++iTrend) pAddPoints[iTrend] = m_PlotData[iTrend].lstPoints.GetNext(pPosArray[iTrend]); @@ -813,7 +816,6 @@ int COScopeCtrl::ReCreateGraph() delete[] pPosArray; Invalidate(); - return 0; } void COScopeCtrl::OnTimer(UINT_PTR nIDEvent) @@ -882,8 +884,8 @@ void COScopeCtrl::OnMouseMove(UINT nFlags, CPoint point) time_t tNow = time(NULL) - dwTime; TCHAR szDate[128]; _tcsftime(szDate, _countof(szDate), thePrefs.GetDateTimeFormat4Log(), localtime(&tNow)); - CString strInfo; - strInfo.Format(_T("%s: %u @ %s ") + GetResString(IDS_TIMEBEFORE), (LPCTSTR)m_str.YUnits, yValue, szDate, (LPCTSTR)CastSecondsToLngHM(dwTime)); + CString strInfo(m_str.YUnits); + strInfo.AppendFormat(_T(": %u @ %s ") + GetResString(IDS_TIMEBEFORE), yValue, szDate, (LPCTSTR)CastSecondsToLngHM(dwTime)); pwndParent->SendMessage(UM_OSCOPEPOSITION, 0, (LPARAM)(LPCTSTR)strInfo); } diff --git a/srchybrid/OScopeCtrl.h b/srchybrid/OScopeCtrl.h index c5bed4cc..d8c5b6bb 100644 --- a/srchybrid/OScopeCtrl.h +++ b/srchybrid/OScopeCtrl.h @@ -29,7 +29,7 @@ class COScopeCtrl : public CWnd void InvalidateCtrl(bool deleteGraph = true); void DrawPoint(); void Reset(); - int ReCreateGraph(); + void ReCreateGraph(); bool ready; bool drawBars; diff --git a/srchybrid/Opcodes.h b/srchybrid/Opcodes.h index dc8fd65b..7061a766 100644 --- a/srchybrid/Opcodes.h +++ b/srchybrid/Opcodes.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -62,7 +62,7 @@ #define MAX_CLIENTCONNECTIONTRY 2 #define CONNECTION_TIMEOUT SEC2MS(40) //40 secs - set his lower if you want less connections at once, set it higher if you have enough sockets (edonkey has its own timeout too, so a very high value won't effect this) #define FILEREASKTIME MIN2MS(29) //29 mins -#define SERVERREASKTIME MIN2MS(15) //15 mins - don't set this too low, it wont speed up anything, but it could kill emule or your internet connection +#define SERVERREASKTIME MIN2MS(15) //15 mins - don't set this too low, it won't speed up anything, but it could kill emule or your internet connection #define UDPSERVERREASKTIME MIN2MS(30) //30 mins #define MAX_SERVERFAILCOUNT 10 #define SOURCECLIENTREASKS MIN2MS(40) //40 mins @@ -127,10 +127,10 @@ #define CLIENTLIST_CLEANUP_TIME MIN2MS(34) // 34 min #define MAXPRIORITYCOLL_SIZE (50*1024) // max file size for collection file which are allowed to bypass the queue #define SEARCH_SPAM_THRESHOLD 60 -#define OLDFILES_PARTIALLYPURGE DAY2S(31) // time after which some data about a know file in the known.met and known2.met is deleted +#define OLDFILES_PARTIALLYPURGE DAY2S(31) // time after which some data about a known file in the known.met and known2.met is deleted // you shouldn't change anything here if you are not really sure, or probably emule will not work -#define UDP_KAD_MAXFRAGMENT 1420 // based on a 1500 ethernet MTU, use a conservative value to leave enough room for IP/UDP headers, tunnel headers, Kad headers(16) and misconfigs +#define UDP_KAD_MAXFRAGMENT 1420 // based on a 1500 Ethernet MTU, use a conservative value to leave enough room for IP/UDP headers, tunnel headers, Kad headers(16) and misconfigs #define EMBLOCKSIZE 184320u #define OP_EDONKEYHEADER 0xE3 #define OP_KADEMLIAHEADER 0xE4 @@ -146,7 +146,7 @@ #define UNLIMITED _UI32_MAX -//Proxytypes deadlake +//Proxy types deadlake #define PROXYTYPE_NOPROXY 0 #define PROXYTYPE_SOCKS4 1 #define PROXYTYPE_SOCKS4A 2 @@ -532,7 +532,7 @@ // values for CT_SERVER_UDPSEARCH_FLAGS #define SRVCAP_UDP_NEWTAGS_LARGEFILES 0x01 -// emule tagnames +// eMule tag names #define ET_COMPRESSION 0x20 #define ET_UDPPORT 0x21 #define ET_UDPVER 0x22 diff --git a/srchybrid/OtherFunctions.cpp b/srchybrid/OtherFunctions.cpp index 4a94575a..4f6e71ef 100644 --- a/srchybrid/OtherFunctions.cpp +++ b/srchybrid/OtherFunctions.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -21,13 +21,12 @@ #include #include #include "emule.h" -#include "OtherFunctions.h" +#include "UpDownClient.h" #include "DownloadQueue.h" #include "Preferences.h" #include "PartFile.h" #include "SharedFileList.h" #include "KnownFileList.h" -#include "UpDownClient.h" #include "Opcodes.h" #include "WebServices.h" #include @@ -87,6 +86,18 @@ static const byte base16Lookup[BASE16_LOOKUP_MAX][2] = { }; LPCTSTR const sBadFileNameChar(_T("\"*<>?|\\/:")); // lots of invalid chars for filenames in Windows :=) LPCTSTR const sHiddenPassword = _T("\012\010\011\015\033"); //tough to enter from the keyboard +const struct LinkScheme s_apszSchemes[] = +{ + { _T("ed2k://"), 7 }, + { _T("http://"), 7 }, + { _T("https://"), 8 }, + { _T("ftp://"), 6 }, + { _T("www."), 4 }, + { _T("ftp."), 4 }, + { _T("mailto:"), 7 }, + { _T("magnet:?"), 8 }, + { NULL, 0 } +}; CString CastItoXBytes(uint16 count, bool isK, bool isPerSec, uint32 decimal) { @@ -295,7 +306,7 @@ void ShellDefaultVerb(LPCTSTR lpName) bool ShellDeleteFile(LPCTSTR pszFilePath) { - if (!PathFileExists(pszFilePath)) + if (!::PathFileExists(pszFilePath)) return true; if (thePrefs.GetRemoveToBin()) { TCHAR todel[MAX_PATH + 1] = {}; @@ -356,39 +367,6 @@ CString ShellGetFolderPath(int iCSIDL) return strFolderPath; } -namespace -{ - bool IsHexDigit(int c) - { - switch (c) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - return true; - } - return false; - } -} - // Print the hash in a format which is similar to CertMgr's. CString GetCertHash(const unsigned char *pucHash, int iBytes) { @@ -418,7 +396,7 @@ CString URLDecode(const CString &inStr, bool bKeepNewLine) // decode escape sequences CString res; for (int x = 0; x < inStr.GetLength(); ++x) { - if (inStr[x] == _T('%') && x + 2 < inStr.GetLength() && IsHexDigit(inStr[x + 1]) && IsHexDigit(inStr[x + 2])) { + if (inStr[x] == _T('%') && x + 2 < inStr.GetLength() && _istxdigit(inStr[x + 1]) && _istxdigit(inStr[x + 2])) { TCHAR hexstr[3]; _tcsncpy(hexstr, inStr.Mid(x + 1, 2), 2); hexstr[2] = _T('\0'); @@ -468,7 +446,7 @@ CString EncodeURLQueryParam(const CString &sInT) // unreserved = alphanum | mark // mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" // - // See also: http://www.w3.org/MarkUp/html-spec/html-spec_8.html + // See also: https://www.w3.org/MarkUp/html-spec/html-spec_8.html CString sOut; LPTSTR pOutBuf = sOut.GetBuffer(sIn.GetLength() * 3); @@ -490,12 +468,11 @@ CString EncodeURLQueryParam(const CString &sInT) return sOut; } -/*CString MakeStringEscaped(CString in) +void DupAmpersand(CString &rstr) { - in.Replace(_T("&"), _T("&&")); - return in; + rstr.Replace(_T("&"), _T("&&")); } - +/* CString RemoveAmpersand(const CString &rstr) { CString str(rstr); @@ -563,11 +540,12 @@ bool Ask4RegFix(bool checkOnly, bool dontAsk, bool bAutoTakeCollections) regkey.Close(); } else ASSERT(0); - } else if (checkOnly) - return bAutoTakeCollections && DoCollectionRegFix(true); - else if (bAutoTakeCollections) - DoCollectionRegFix(false); - + } else { + if (checkOnly) + return bAutoTakeCollections && DoCollectionRegFix(true); + if (bAutoTakeCollections) + DoCollectionRegFix(false); + } return false; } @@ -629,9 +607,9 @@ void RevertReg() ASSERT(0); } -int GetMaxWindowsTCPConnections() +UINT GetMaxWindowsTCPConnections() { - return -1; + return UNLIMITED; /* OSVERSIONINFOEX osvi; osvi.dwOSVersionInfoSize = (DWORD)sizeof(OSVERSIONINFOEX); @@ -639,11 +617,11 @@ int GetMaxWindowsTCPConnections() //if OSVERSIONINFOEX doesn't work, try OSVERSIONINFO osvi.dwOSVersionInfoSize = (DWORD)sizeof(OSVERSIONINFO); if (!GetVersionEx((OSVERSIONINFO*)&osvi)) - return -1; //shouldn't ever happen + return UNLIMITED; //shouldn't ever happen } if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) // Windows NT product family - return -1; //no limits + return UNLIMITED; //no limits if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { // Windows 95 product family @@ -654,7 +632,7 @@ int GetMaxWindowsTCPConnections() RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("System\\CurrentControlSet\\Services\\VxD\\MSTCP") , 0, KEY_QUERY_VALUE, &hKey); - LONG lResult = RegQueryValueEx(hKey, TEXT("MaxConnections"), NULL, NULL + LONG lResult = RegQueryValueEx(hKey, _T("MaxConnections"), NULL, NULL , (LPBYTE)&dwValue, &dwLength); RegCloseKey(hKey); @@ -681,7 +659,7 @@ int GetMaxWindowsTCPConnections() return lMaxConnections; } - return -1; //give the user the benefit of the doubt, most use NT+ anyway + return UNLIMITED; //give the user the benefit of the doubt, most use NT+ anyway */ } @@ -766,39 +744,8 @@ bool IsRunningXPSP2OrHigher() uint64 GetFreeDiskSpaceX(LPCTSTR pDirectory) { - static BOOL _bInitialized = FALSE; - static BOOL(WINAPI *_pfnGetDiskFreeSpaceEx)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) = NULL; - - if (!_bInitialized) { - _bInitialized = TRUE; - (FARPROC&)_pfnGetDiskFreeSpaceEx = GetProcAddress(GetModuleHandle(_T("kernel32")), _TWINAPI("GetDiskFreeSpaceEx")); - } - - if (_pfnGetDiskFreeSpaceEx) { - ULARGE_INTEGER nFreeDiskSpace; - ULARGE_INTEGER dummy; - if ((*_pfnGetDiskFreeSpaceEx)(pDirectory, &nFreeDiskSpace, &dummy, &dummy)) - return nFreeDiskSpace.QuadPart; - return 0; - } - - TCHAR cDrive[MAX_PATH]; - const TCHAR *p = _tcschr(pDirectory, _T('\\')); - if (p) { - size_t uChars = p - pDirectory; - if (uChars >= _countof(cDrive)) - return 0; - memcpy(cDrive, pDirectory, uChars * sizeof(TCHAR)); - cDrive[uChars] = _T('\0'); - } else { - if (_tcslen(pDirectory) >= _countof(cDrive)) - return 0; - _tcscpy(cDrive, pDirectory); - } - DWORD dwSectPerClust, dwBytesPerSect, dwFreeClusters, dwDummy; - if (GetDiskFreeSpace(cDrive, &dwSectPerClust, &dwBytesPerSect, &dwFreeClusters, &dwDummy)) - return dwFreeClusters * (uint64)dwSectPerClust * (uint64)dwBytesPerSect; - return 0; + ULARGE_INTEGER nFreeDiskSpace; + return ::GetDiskFreeSpaceEx(pDirectory, &nFreeDiskSpace, NULL, NULL) ? nFreeDiskSpace.QuadPart : 0; } CString GetRateString(UINT rate) @@ -825,10 +772,9 @@ CString EncodeBase32(const unsigned char *buffer, unsigned int bufLen) CString Base32Buff; unsigned index = 0; - unsigned char word; for (unsigned i = 0; i < bufLen;) { - + unsigned char word; // Is the current word going to span a byte boundary? if (index > 3) { word = (unsigned char)(buffer[i] & (0xFF >> index)); @@ -910,7 +856,7 @@ bool DecodeBase16(const TCHAR *base16Buffer, unsigned int base16BufLen, byte *bu // New length of byte array decoded unsigned DecodeLengthBase16(unsigned base16Length) { - return base16Length / 2U; + return base16Length / 2; } uint32 DecodeBase32(LPCTSTR pszInput, uchar *paucOutput, uint32 nBufferLen) @@ -976,7 +922,7 @@ INT_PTR CWebServices::ReadAllServices() { RemoveAllServices(); - const CString &strFilePath = GetDefaultServicesFile(); + const CString &strFilePath(GetDefaultServicesFile()); FILE *readFile = _tfsopen(strFilePath, _T("r"), _SH_DENYWR); if (readFile != NULL) { CString sbuffer; @@ -992,7 +938,7 @@ INT_PTR CWebServices::ReadAllServices() int iPos = sbuffer.Find(_T(',')); if (iPos > 0) { - CString strUrlTemplate = sbuffer.Right(sbuffer.GetLength() - iPos - 1).Trim(); + const CString strUrlTemplate(sbuffer.Right(sbuffer.GetLength() - iPos - 1).Trim()); if (!strUrlTemplate.IsEmpty()) { static LPCTSTR const _apszMacros[] = { _T("#hashid"), @@ -1018,11 +964,11 @@ INT_PTR CWebServices::ReadAllServices() } } } - fclose(readFile); - struct _stat64 st; - if (statUTC(strFilePath, st) == 0) + if (statUTC((HANDLE)_get_osfhandle(_fileno(readFile)), st) == 0) m_tDefServicesFileLastModified = (time_t)st.st_mtime; + + fclose(readFile); } return m_aServices.GetCount(); @@ -1052,7 +998,7 @@ bool CWebServices::RunURL(const CAbstractFile *file, UINT uMenuID) for (int i = 0; i < m_aServices.GetCount(); ++i) { const SEd2kLinkService &rSvc(m_aServices[i]); if (rSvc.uMenuID == uMenuID) { - CString strUrlTemplate = rSvc.strUrl; + CString strUrlTemplate(rSvc.strUrl); if (file != NULL) { // Convert hash to hexadecimal text and add it to the URL strUrlTemplate.Replace(_T("#hashid"), md4str(file->GetFileHash())); @@ -1066,8 +1012,8 @@ bool CWebServices::RunURL(const CAbstractFile *file, UINT uMenuID) strUrlTemplate.Replace(_T("#filename"), EncodeURLQueryParam(file->GetFileName())); // add basename to the url - CString strBaseName = file->GetFileName(); - PathRemoveExtension(strBaseName.GetBuffer(strBaseName.GetLength())); + CString strBaseName(file->GetFileName()); + ::PathRemoveExtension(strBaseName.GetBuffer(strBaseName.GetLength())); strBaseName.ReleaseBuffer(); strUrlTemplate.Replace(_T("#name"), EncodeURLQueryParam(strBaseName)); @@ -1116,6 +1062,7 @@ extern "C" int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM, LPARAM bool SelectDir(HWND hWnd, LPTSTR pszPath, LPCTSTR pszTitle, LPCTSTR pszDlgTitle) { + ASSERT(pszPath != NULL); bool bResult = false; (void)CoInitialize(NULL); LPMALLOC pShlMalloc; @@ -1126,7 +1073,7 @@ bool SelectDir(HWND hWnd, LPTSTR pszPath, LPCTSTR pszTitle, LPCTSTR pszDlgTitle) BrsInfo.ulFlags = BIF_VALIDATE | BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS | BIF_SHAREABLE | BIF_DONTGOBELOWDOMAIN; BROWSEINIT BrsInit = {}; - if (pszPath != NULL || pszTitle != NULL || pszDlgTitle != NULL) { + if (pszTitle != NULL || pszDlgTitle != NULL) { // Need the 'BrowseCallbackProc' to set those strings BrsInfo.lpfn = BrowseCallbackProc; BrsInfo.lParam = (LPARAM)&BrsInit; @@ -1135,12 +1082,12 @@ bool SelectDir(HWND hWnd, LPTSTR pszPath, LPCTSTR pszTitle, LPCTSTR pszDlgTitle) } LPITEMIDLIST pidlBrowse; - if ((pidlBrowse = SHBrowseForFolder(&BrsInfo)) != NULL) { - if (SHGetPathFromIDList(pidlBrowse, pszPath)) - bResult = true; + if ((pidlBrowse = ::SHBrowseForFolder(&BrsInfo)) != NULL) { + bResult = ::SHGetPathFromIDList(pidlBrowse, pszPath); pShlMalloc->Free(pidlBrowse); } pShlMalloc->Release(); + ::PathAddBackslash(pszPath); } CoUninitialize(); return bResult; @@ -1148,20 +1095,22 @@ bool SelectDir(HWND hWnd, LPTSTR pszPath, LPCTSTR pszTitle, LPCTSTR pszDlgTitle) void slosh(CString &path) { - if (path.Right(1) != _T("\\")) + int i = path.GetLength() - 1; + if (i >= 0 && path[i] != _T('\\')) path += _T('\\'); } void unslosh(CString &path) { - if (path.Right(1) == _T("\\")) - path.Truncate(path.GetLength() - 1); + int i = path.GetLength() - 1; + if (i >= 0 && path[i] == _T('\\')) + path.Truncate(i); } void canonical(CString &path) { TCHAR szPath[MAX_PATH]; - if (PathCanonicalize(szPath, path)) + if (::PathCanonicalize(szPath, path)) path = szPath; } @@ -1169,7 +1118,7 @@ void MakeFoldername(CString &rstrPath) { if (!rstrPath.IsEmpty()) { // don't canonicalize an empty path, we would get a "\" canonical(rstrPath); - unslosh(rstrPath); + slosh(rstrPath); } } @@ -1255,11 +1204,11 @@ void StripTrailingColon(CString &rstr) CString ValidFilename(const CString &filename) { - CString fname = URLDecode(filename); + CString fname(URLDecode(filename)); if (fname.GetLength() > 100) fname.Truncate(100); // remove invalid characters - for (LPCTSTR p = sBadFileNameChar; *p; ) + for (LPCTSTR p = sBadFileNameChar; *p;) fname.Remove(*p++); return fname.Trim(); } @@ -1317,7 +1266,7 @@ CString CleanupFilename(const CString &filename, bool bExtension) --pos1; } - // Make leading Caps + // Making title case if (sClean.GetLength() > 1) { sClean.SetAt(0, _totupper(sClean[0])); @@ -1569,9 +1518,7 @@ EED2KFileType GetED2KFileTypeID(LPCTSTR pszFileName) ft.pszExt = strExt.MakeLower(); ft.iFileType = ED2KFT_ANY; const SED2KFileType *pFound = (SED2KFileType*)bsearch(&ft, g_aED2KFileTypes, _countof(g_aED2KFileTypes), sizeof g_aED2KFileTypes[0], CompareE2DKFileType); - if (pFound != NULL) - return pFound->iFileType; - return ED2KFT_ANY; + return pFound ? pFound->iFileType : ED2KFT_ANY; } // Returns the ed2k file type string ID which is to be used for publishing+searching @@ -1798,31 +1745,24 @@ int GetSystemErrorString(DWORD dwError, CString &rstrError) // 3) User default LANGID, based on the user's default locale value // 4) System default LANGID, based on the system default locale value // 5) US English - LPTSTR pszSysMsg = NULL; - DWORD dwLength = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT), - (LPTSTR)&pszSysMsg, 0, NULL); - if (dwLength != 0 && pszSysMsg != NULL) { - if (dwLength >= 2 && pszSysMsg[dwLength - 2] == _T('\r')) - pszSysMsg[dwLength - 2] = _T('\0'); - rstrError = pszSysMsg; - rstrError.Replace(_T("\r\n"), _T(" ")); // some messages contain CRLF within the message!? - } else - rstrError.Empty(); - - if (pszSysMsg) - LocalFree(pszSysMsg); - - return rstrError.GetLength(); + return GetModuleErrorString(dwError, rstrError, NULL); } int GetModuleErrorString(DWORD dwError, CString &rstrError, LPCTSTR pszModule) { LPTSTR pszSysMsg = NULL; - DWORD dwLength = FormatMessage(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, - GetModuleHandle(pszModule), dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT), - (LPTSTR)&pszSysMsg, 0, NULL); - if (dwLength != 0 && pszSysMsg != NULL) { + DWORD dwFlags; + LPCVOID lpSource; + if (pszModule) { + dwFlags = FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS; + lpSource = GetModuleHandle(pszModule); + } else { + dwFlags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS; + lpSource = NULL; + } + DWORD dwLength = FormatMessage(dwFlags, lpSource, dwError + , MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT), (LPTSTR)&pszSysMsg, 0, NULL); + if (dwLength > 0 && pszSysMsg != NULL) { if (dwLength >= 2 && pszSysMsg[dwLength - 2] == _T('\r')) pszSysMsg[dwLength - 2] = _T('\0'); rstrError = pszSysMsg; @@ -1838,13 +1778,11 @@ int GetModuleErrorString(DWORD dwError, CString &rstrError, LPCTSTR pszModule) int GetErrorMessage(DWORD dwError, CString &rstrErrorMsg, DWORD dwFlags) { - int iMsgLen = GetSystemErrorString(dwError, rstrErrorMsg); - if (iMsgLen == 0) + if (GetSystemErrorString(dwError, rstrErrorMsg) == 0) //0 if no error string rstrErrorMsg.Format(((long)dwError >= 0) ? _T("Error %u") : _T("Error 0x%08x"), dwError); - else if (dwFlags & 1) { - CString sMsg; - sMsg.Format(((long)dwError >= 0) ? _T("Error %u: ") : _T("Error 0x%08x: "), dwError); - rstrErrorMsg.Insert(0, sMsg); + else if (dwFlags & 1) { //show numeric error code + const CString sMsg(rstrErrorMsg); + rstrErrorMsg.Format(((long)dwError >= 0 ? _T("Error %u: %s") : _T("Error 0x%08x: %s")), dwError, (LPCTSTR)sMsg); } return rstrErrorMsg.GetLength(); } @@ -1982,20 +1920,17 @@ int GetDesktopColorDepth() int GetAppImageListColorFlag() { int iColorBits = GetDesktopColorDepth(); - int iIlcFlag; if (iColorBits >= 32) - iIlcFlag = ILC_COLOR32; - else if (iColorBits >= 24) - iIlcFlag = ILC_COLOR24; - else if (iColorBits >= 16) - iIlcFlag = ILC_COLOR16; - else if (iColorBits >= 8) - iIlcFlag = ILC_COLOR8; - else if (iColorBits >= 4) - iIlcFlag = ILC_COLOR4; - else - iIlcFlag = ILC_COLOR; - return iIlcFlag; + return ILC_COLOR32; + if (iColorBits >= 24) + return ILC_COLOR24; + if (iColorBits >= 16) + return ILC_COLOR16; + if (iColorBits >= 8) + return ILC_COLOR8; + if (iColorBits >= 4) + return ILC_COLOR4; + return ILC_COLOR; } CString DbgGetHexDump(const uint8 *data, UINT size) @@ -2004,7 +1939,7 @@ CString DbgGetHexDump(const uint8 *data, UINT size) buffer.Format(_T("Size=%u, Data=["), size); UINT i; for (i = 0; i < size && i < 50; ++i) - buffer.AppendFormat(i ? _T(" %02x") : _T("%02x"), data[i]); + buffer.AppendFormat(&(_T(" %02x")[static_cast(!i)]), data[i]); buffer += (i < size) ? _T("]") : _T("..]"); return buffer; @@ -2067,22 +2002,19 @@ CString RemoveFileExtension(const CString &rstrFilePath) return (iDot < 0) ? rstrFilePath : rstrFilePath.Left(iDot); } -int CompareDirectory(const CString &rstrDir1, const CString &rstrDir2) +bool EqualPaths(const CString &rstrDir1, const CString &rstrDir2) { - // use case insensitive compare as a starter - if (rstrDir1.CompareNoCase(rstrDir2) == 0) - return 0; - // if one of the paths ends with a '\' the paths may still be equal from the file system's POV - CString strDir1(rstrDir1); - CString strDir2(rstrDir2); - unslosh(strDir1); - unslosh(strDir2); - return strDir1.CompareNoCase(strDir2); // compare again + int i1 = rstrDir1.GetLength(); + i1 -= static_cast(i1 && rstrDir1[i1 - 1] == _T('\\')); + int i2 = rstrDir2.GetLength(); + i2 -= static_cast(i2 && rstrDir2[i2 - 1] == _T('\\')); + bool bRet = (i1 == i2); + return bRet ? _tcsnicmp(rstrDir1, rstrDir2, i1) == 0 : bRet; } bool IsGoodIP(uint32 nIP, bool forceCheck) { - // always filter following IP's + // always filter the following IPs // ------------------------------------------- // 0.0.0.0 invalid // 127.0.0.0 - 127.255.255.255 Loopback @@ -2097,7 +2029,6 @@ bool IsGoodIP(uint32 nIP, bool forceCheck) return false; #endif } - return (!thePrefs.FilterLANIPs() && !forceCheck) || !IsLANIP(nIP); } @@ -2171,6 +2102,25 @@ CString GetFormatedUInt64(ULONGLONG ullVal) return iResult ? strVal : CString(szVal); } +// this function creates the content for the "length" ed2k meta tag which was introduced by eDonkeyHybrid +// with the data type 'string' :/ to save some bytes, omit leading zeros +// Though it got handy to display media properties +CString SecToTimeLength(UINT uiSec) +{ + CString sTimeLength; + if (uiSec >= HR2S(1)) { + UINT uHours = uiSec / HR2S(1); + UINT uMin = (uiSec - HR2S(uHours)) / MIN2S(1); + UINT uSec = uiSec - HR2S(uHours) - MIN2S(uMin); + sTimeLength.Format(_T("%u:%02u:%02u"), uHours, uMin, uSec); + } else { + UINT uMin = uiSec / MIN2S(1); + UINT uSec = uiSec - MIN2S(uMin); + sTimeLength.Format(_T("%u:%02u"), uMin, uSec); + } + return sTimeLength; +} + void Debug(LPCTSTR pszFmtMsg, ...) { va_list pArgs; @@ -2190,7 +2140,7 @@ void Debug(LPCTSTR pszFmtMsg, ...) va_end(pArgs); } -void DebugHexDump(const uint8 *data, UINT lenData) +void DebugHexDump(const void *data, UINT lenData) { int lenLine = 16; CStringA line, single; @@ -2198,14 +2148,14 @@ void DebugHexDump(const uint8 *data, UINT lenData) line.Format("%08X ", pos); lenLine = (int)min((lenData - pos), 16u); for (int i = 0; i < lenLine; ++i) { - single.Format(" %02X", data[pos + i]); + single.Format(" %02X", ((const byte*)data)[pos + i]); line += single; if (i == 7) line += ' '; } line += CStringA(' ', 60 - line.GetLength()); for (int i = 0; i < lenLine; ++i) { - char c = (char)data[pos + i]; + char c = ((const char*)data)[pos + i]; line += (c > 31 && c < 127) ? c : '.'; } Debug(_T("%hs\n"), (LPCSTR)line); @@ -2416,17 +2366,16 @@ CString DbgGetMuleClientTCPOpcode(UINT opcode) _STRVAL(OP_PEERCACHE_QUERY), _STRVAL(OP_PEERCACHE_ANSWER), _STRVAL(OP_PEERCACHE_ACK), - _STRVAL(OP_PUBLICIP_ANSWER), _STRVAL(OP_PUBLICIP_REQ), - _STRVAL(OP_PORTTEST), + _STRVAL(OP_PUBLICIP_ANSWER), _STRVAL(OP_CALLBACK), - _STRVAL(OP_BUDDYPING), - _STRVAL(OP_BUDDYPONG), _STRVAL(OP_REASKCALLBACKTCP), - _STRVAL(OP_AICHANSWER), _STRVAL(OP_AICHREQUEST), + _STRVAL(OP_AICHANSWER), _STRVAL(OP_AICHFILEHASHANS), _STRVAL(OP_AICHFILEHASHREQ), + _STRVAL(OP_BUDDYPING), + _STRVAL(OP_BUDDYPONG), _STRVAL(OP_COMPRESSEDPART_I64), _STRVAL(OP_SENDINGPART_I64), _STRVAL(OP_REQUESTPARTS_I64), @@ -2434,7 +2383,12 @@ CString DbgGetMuleClientTCPOpcode(UINT opcode) _STRVAL(OP_CHATCAPTCHAREQ), _STRVAL(OP_CHATCAPTCHARES), _STRVAL(OP_FWCHECKUDPREQ), - _STRVAL(OP_KAD_FWTCPCHECK_ACK) + _STRVAL(OP_KAD_FWTCPCHECK_ACK), + _STRVAL(OP_MULTIPACKET_EXT2), + _STRVAL(OP_MULTIPACKETANSWER_EXT2), + _STRVAL(OP_HASHSETREQUEST2), + _STRVAL(OP_HASHSETANSWER2), + _STRVAL(OP_PORTTEST) }; for (unsigned i = 0; i < _countof(_aOpcodes); ++i) @@ -2452,13 +2406,14 @@ CString DbgGetClientTCPPacket(UINT protocol, UINT opcode, UINT size) { CString str; if (protocol == OP_EDONKEYPROT) - str.Format(_T("protocol=eDonkey opcode=%s size=%u"), (LPCTSTR)DbgGetDonkeyClientTCPOpcode(opcode), size); + str.Format(_T("protocol=eDonkey opcode=%s"), (LPCTSTR)DbgGetDonkeyClientTCPOpcode(opcode)); else if (protocol == OP_PACKEDPROT) - str.Format(_T("protocol=Packed opcode=%s size=%u"), (LPCTSTR)DbgGetMuleClientTCPOpcode(opcode), size); + str.Format(_T("protocol=Packed opcode=%s"), (LPCTSTR)DbgGetMuleClientTCPOpcode(opcode)); else if (protocol == OP_EMULEPROT) - str.Format(_T("protocol=eMule opcode=%s size=%u"), (LPCTSTR)DbgGetMuleClientTCPOpcode(opcode), size); + str.Format(_T("protocol=eMule opcode=%s"), (LPCTSTR)DbgGetMuleClientTCPOpcode(opcode)); else - str.Format(_T("protocol=0x%02x opcode=0x%02x size=%u"), protocol, opcode, size); + str.Format(_T("protocol=0x%02x opcode=0x%02x"), protocol, opcode); + str.AppendFormat(_T(" size=%u"), size); return str; } @@ -2500,14 +2455,17 @@ void DebugRecv(LPCSTR pszMsg, const CUpDownClient *client, const uchar *packet, void DebugSend(LPCSTR pszMsg, const CUpDownClient *client, const uchar *packet) { - if (client != NULL && packet != NULL) - Debug(_T(">>> %-20hs to %s; %s\n"), pszMsg, (LPCTSTR)client->DbgGetClientInfo(true), (LPCTSTR)DbgGetFileInfo(packet)); - else if (client != NULL && packet == NULL) - Debug(_T(">>> %-20hs to %s\n"), pszMsg, (LPCTSTR)client->DbgGetClientInfo(true)); - else if (client == NULL && packet != NULL) - Debug(_T(">>> %-20hs; %s\n"), pszMsg, (LPCTSTR)DbgGetFileInfo(packet)); - else - Debug(_T(">>> %-20hs\n"), pszMsg); + if (client) { + if (packet != NULL) + Debug(_T(">>> %-20hs to %s; %s\n"), pszMsg, (LPCTSTR)client->DbgGetClientInfo(true), (LPCTSTR)DbgGetFileInfo(packet)); + else + Debug(_T(">>> %-20hs to %s\n"), pszMsg, (LPCTSTR)client->DbgGetClientInfo(true)); + } else { + if (packet != NULL) + Debug(_T(">>> %-20hs; %s\n"), pszMsg, (LPCTSTR)DbgGetFileInfo(packet)); + else + Debug(_T(">>> %-20hs\n"), pszMsg); + } } void DebugSend(LPCSTR pszOpcode, uint32 ip, uint16 port) @@ -2539,38 +2497,31 @@ void DebugRecv(LPCSTR pszOpcode, uint32 ip, uint16 port) void DebugHttpHeaders(const CStringAArray &astrHeaders) { - for (int i = 0; i < astrHeaders.GetCount(); ++i) { - const CStringA &rstrHdr = astrHeaders[i]; - Debug(_T("<%hs\n"), (LPCSTR)rstrHdr); - } + for (int i = 0; i < astrHeaders.GetCount(); ++i) + Debug(_T("<%hs\n"), (LPCSTR)astrHeaders[i]); } -ULONGLONG GetDiskFileSize(LPCTSTR pszFilePath) +void throwCStr(LPCTSTR pStr) { - static BOOL _bInitialized = FALSE; - static DWORD(WINAPI *_pfnGetCompressedFileSize)(LPCTSTR, LPDWORD) = NULL; - - if (!_bInitialized) { - _bInitialized = TRUE; - (FARPROC&)_pfnGetCompressedFileSize = GetProcAddress(GetModuleHandle(_T("kernel32")), _TWINAPI("GetCompressedFileSize")); - } + throw CString(pStr); +} +ULONGLONG GetDiskFileSize(LPCTSTR pszFilePath) +{ // If the file is not compressed nor sparse, 'GetCompressedFileSize' returns the 'normal' file size. - if (_pfnGetCompressedFileSize) { - ULONGLONG ullCompFileSize; - ((LPDWORD)&ullCompFileSize)[0] = (*_pfnGetCompressedFileSize)(pszFilePath, &((LPDWORD)&ullCompFileSize)[1]); - if (((LPDWORD)&ullCompFileSize)[0] != INVALID_FILE_SIZE || ::GetLastError() == NO_ERROR) - return ullCompFileSize; - } + ULONGLONG ullCompFileSize; + ((LPDWORD)&ullCompFileSize)[0] = ::GetCompressedFileSize(pszFilePath, &((LPDWORD)&ullCompFileSize)[1]); + if (((LPDWORD)&ullCompFileSize)[0] != INVALID_FILE_SIZE || ::GetLastError() == NO_ERROR) + return ullCompFileSize; // If 'GetCompressedFileSize' failed or is not available, use the default function WIN32_FIND_DATA fd; - HANDLE hFind = FindFirstFile(pszFilePath, &fd); + HANDLE hFind = ::FindFirstFile(pszFilePath, &fd); if (hFind == INVALID_HANDLE_VALUE) return 0; - FindClose(hFind); + ::FindClose(hFind); - return (ULONGLONG)fd.nFileSizeHigh << 32 | (ULONGLONG)fd.nFileSizeLow; + return ((ULONGLONG)fd.nFileSizeHigh << 32) | fd.nFileSizeLow; } // Listview helper function @@ -2717,7 +2668,7 @@ class CVolumeInfo ASSERT(strVolumeId.Right(1) == _T("\\")); strVolumeId.MakeLower(); CMapStringToString::CPair *pPair = m_mapVolumeInfo.PLookup(strVolumeId); - if (pPair != NULL) + if (pPair) return pPair->value; // 'GetVolumeInformation' may cause a noticeable delay - depending on the type of volume @@ -2777,33 +2728,50 @@ void ClearVolumeInfoCache(int iDrive) bool IsFileOnNTFSVolume(LPCTSTR pszFilePath) { CString strRootPath(pszFilePath); - BOOL bResult = PathStripToRoot(strRootPath.GetBuffer()); + BOOL bResult = ::PathStripToRoot(strRootPath.GetBuffer()); strRootPath.ReleaseBuffer(); if (!bResult) return false; // Need to add a trailing backslash in case of a network share - if (!strRootPath.IsEmpty() && strRootPath[strRootPath.GetLength() - 1] != _T('\\')) { - PathAddBackslash(strRootPath.GetBuffer(strRootPath.GetLength() + 1)); - strRootPath.ReleaseBuffer(); - } + if (!strRootPath.IsEmpty()) + slosh(strRootPath); return IsNTFSVolume(strRootPath); } bool IsFileOnFATVolume(LPCTSTR pszFilePath) { CString strRootPath(pszFilePath); - BOOL bResult = PathStripToRoot(strRootPath.GetBuffer()); + BOOL bResult = ::PathStripToRoot(strRootPath.GetBuffer()); strRootPath.ReleaseBuffer(); if (!bResult) return false; // Need to add a trailing backslash in case of a network share - if (!strRootPath.IsEmpty() && strRootPath[strRootPath.GetLength() - 1] != _T('\\')) { - PathAddBackslash(strRootPath.GetBuffer(strRootPath.GetLength() + 1)); - strRootPath.ReleaseBuffer(); - } + if (!strRootPath.IsEmpty()) + slosh(strRootPath); return IsFATVolume(strRootPath); } +// ignore real(!) thumbs.db files -- seems that lot of ppl have 'thumbs.db' files without the 'System' file attribute +bool IsThumbsDb(const CString &sFilePath, const CString &sFileName) +{ + if (sFileName.CompareNoCase(_T("thumbs.db")) == 0) { + // if that's a valid 'Storage' file, we declare it as a "thumbs.db" file. + CComPtr pStorage; + if (StgOpenStorage(sFilePath, NULL, STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &pStorage) == S_OK) { + CComPtr pEnumSTATSTG; + if (SUCCEEDED(pStorage->EnumElements(0, NULL, 0, &pEnumSTATSTG))) { + STATSTG statstg; + if (pEnumSTATSTG->Next(1, &statstg, 0) == S_OK) { + ::CoTaskMemFree(statstg.pwcsName); + statstg.pwcsName = NULL; + return true; + } + } + } + } + return false; +} + bool IsAutoDaylightTimeSetActive() { CRegKey key; @@ -2845,7 +2813,7 @@ bool AdjustNTFSDaylightFileTime(time_t &ruFileDate, LPCTSTR pszFilePath) /*struct tm *ptm = localtime((time_t*)&ruFileDate); bool bFileDateInDST = (ptm && ptm->tm_isdst == 1); if (bFileDateInDST) { - ruFileDate += lDaylightBias*60; + ruFileDate += MIN2S(lDaylightBias); return true; }*/ } @@ -2856,14 +2824,14 @@ bool AdjustNTFSDaylightFileTime(time_t &ruFileDate, LPCTSTR pszFilePath) __time64_t FileTimeToUnixTime(const FILETIME &ft) { - const ULONGLONG t = *(UNALIGNED64 ULONGLONG*)&ft; + const ULONGLONG t = *(__unaligned ULONGLONG*)&ft; return t ? t / 10000000ull - 11644473600ull : 0; } -int statUTC(LPCTSTR pname, struct _stat64 &ft) +int statUTC(LPCTSTR pName, struct _stat64 &ft) { WIN32_FILE_ATTRIBUTE_DATA fa; - if (GetFileAttributesEx(pname, GetFileExInfoStandard, &fa)) { + if (GetFileAttributesEx(pName, GetFileExInfoStandard, &fa)) { memset(&ft, 0, sizeof ft); ft.st_atime = FileTimeToUnixTime(fa.ftLastAccessTime); ft.st_ctime = FileTimeToUnixTime(fa.ftCreationTime); @@ -2874,10 +2842,10 @@ int statUTC(LPCTSTR pname, struct _stat64 &ft) return -1; } -int statUTC(int ifile, struct _stat64 &ft) +int statUTC(HANDLE hFile, struct _stat64 &ft) { BY_HANDLE_FILE_INFORMATION fi; - if (GetFileInformationByHandle((HANDLE)_get_osfhandle(ifile), &fi)) { + if (GetFileInformationByHandle(hFile, &fi)) { memset(&ft, 0, sizeof ft); ft.st_atime = FileTimeToUnixTime(fi.ftLastAccessTime); ft.st_ctime = FileTimeToUnixTime(fi.ftCreationTime); @@ -2908,15 +2876,15 @@ bool ExpandEnvironmentStrings(CString &rstrStrings) uint16 GetRandomUInt16() { #if RAND_MAX == 0x7fff - // get 2 random numbers - UINT uRand0 = rand(); - UINT uRand1 = rand(); - - // NOTE: if that assert fires, you have most likely called that function *without* calling 'srand' first. + uint32 uRand0 = rand(); + uint32 uRand1 = rand(); + ASSERT(uRand0 != 41 || uRand1 != 18467); + // NOTE: if this assert fires, most likely this function was called *without* calling 'srand' first. // NOTE: each spawned thread HAS to call 'srand' for itself to get real random numbers. - ASSERT(!(uRand0 == 41 && uRand1 == 18467)); - return (uint16)(uRand0 | ((uRand1 >= RAND_MAX / 2) ? 0x8000 : 0x0000)); + uRand0 |= (uRand1 & 0x4000) << 1; + srand(::GetTickCount() ^ (uRand0 << 16)); + return (uint16)uRand0; #else #error "Implement it!" #endif @@ -2925,17 +2893,16 @@ uint16 GetRandomUInt16() uint32 GetRandomUInt32() { #if RAND_MAX == 0x7fff - //return ((uint32)GetRandomUInt16() << 16) | (uint32)GetRandomUInt16(); - // this would give the receiver the following information: - // random number N - // random number N+1 is below or greater/equal than 0x8000 - // random number N+2 - // random number N+3 is below or greater/equal than 0x8000 - - uint32 uRand0 = GetRandomUInt16(); - srand(::GetTickCount() | uRand0); - uint32 uRand1 = GetRandomUInt16(); - return (uRand0 << 16) | uRand1; + uint32 uRand0 = rand(); + uint32 uRand1 = rand(); + ASSERT(uRand0 != 41 || uRand1 != 18467); + // NOTE: if this assert fires, most likely this function was called *without* calling 'srand' first. + // NOTE: each spawned thread HAS to call 'srand' for itself to get real random numbers. + + uRand0 = (uRand0 << 15) | (uRand1 & 0x6000); + uRand0 = (uRand0 << 2) | rand(); + srand(::GetTickCount() ^ uRand0); + return uRand0; #else #error "Implement it!" #endif @@ -2973,6 +2940,13 @@ HWND ReplaceRichEditCtrl(CWnd *pwndRE, CWnd *pwndParent, CFont *pFont) return hwndNewRE; } +void DisableAutoSelect(CRichEditCtrl &re) +{ + re.SetSel(0, 0); + re.HideSelection(TRUE, FALSE); + re.SetOptions(ECOOP_OR, ECO_SAVESEL); +} + void InstallSkin(LPCTSTR pszSkinPackage) { if (thePrefs.GetMuleDirectory(EMULE_SKINDIR).IsEmpty() || _taccess(thePrefs.GetMuleDirectory(EMULE_SKINDIR), 0) != 0) { @@ -2982,7 +2956,7 @@ void InstallSkin(LPCTSTR pszSkinPackage) static TCHAR const _szSkinSuffix[] = _T(".") EMULSKIN_BASEEXT _T(".ini"); UINT uid = 0; - CString szExt(PathFindExtension(pszSkinPackage)); + CString szExt(::PathFindExtension(pszSkinPackage)); szExt.MakeLower(); if (szExt == _T(".zip")) { @@ -3013,8 +2987,8 @@ void InstallSkin(LPCTSTR pszSkinPackage) } if (zf->m_sName[zf->m_sName.GetLength() - 1] == _T('/')) { - CString strDstDirPath; - strDstDirPath.Format(_T("%s\\%s"), (LPCTSTR)thePrefs.GetMuleDirectory(EMULE_SKINDIR), (LPCTSTR)zf->m_sName.Left(zf->m_sName.GetLength() - 1)); + CString strDstDirPath(thePrefs.GetMuleDirectory(EMULE_SKINDIR)); + strDstDirPath += zf->m_sName.Left(zf->m_sName.GetLength() - 1); canonical(strDstDirPath); if (!::CreateDirectory(strDstDirPath, NULL)) { DWORD dwError = ::GetLastError(); @@ -3024,8 +2998,8 @@ void InstallSkin(LPCTSTR pszSkinPackage) break; } } else { - CString strDstFilePath; - strDstFilePath.Format(_T("%s\\%s"), (LPCTSTR)thePrefs.GetMuleDirectory(EMULE_SKINDIR), (LPCTSTR)zf->m_sName); + CString strDstFilePath(thePrefs.GetMuleDirectory(EMULE_SKINDIR)); + strDstFilePath += zf->m_sName; canonical(strDstFilePath); ::SetLastError(0); if (!zf->Extract(strDstFilePath)) { @@ -3064,8 +3038,8 @@ void InstallSkin(LPCTSTR pszSkinPackage) bFoundSkinINIFile = true; // No need to care about possible available sub-directories. UnRAR.DLL cares about that automatically. - CString strDstFilePath; - strDstFilePath.Format(_T("%s\\%s"), (LPCTSTR)thePrefs.GetMuleDirectory(EMULE_SKINDIR), (LPCTSTR)strFileName); + CString strDstFilePath(thePrefs.GetMuleDirectory(EMULE_SKINDIR)); + strDstFilePath += strFileName; canonical(strDstFilePath); ::SetLastError(0); if (!rar.Extract(strDstFilePath)) { @@ -3083,8 +3057,8 @@ void InstallSkin(LPCTSTR pszSkinPackage) rar.Close(); } else { - CString strError; - strError.Format(_T("%s\r\n\r\nDownload latest version of UNRAR.DLL from http://www.rarlab.com and copy UNRAR.DLL into eMule installation folder."), (LPCTSTR)GetResString(IDS_INSTALL_SKIN_PKG_ERROR)); + CString strError(GetResString(IDS_INSTALL_SKIN_PKG_ERROR)); + strError += _T("\r\n\r\nDownload latest version of UNRAR.DLL from https://www.rarlab.com and copy UNRAR.DLL into eMule installation folder."); AfxMessageBox(strError, MB_ICONERROR); } } @@ -3167,10 +3141,10 @@ void Sort(CSimpleArray &apstr, int(__cdecl *pfnCompare)(const vo // SLUGFILLER: heapsortCompletesrc void HeapSort(CArray &count, UINT first, UINT last) { - for (UINT r = first; !(r & (UINT)INT_MIN) && (r << 1) < last; ) { + for (UINT r = first; !(r & (UINT)INT_MIN) && (r << 1) < last;) { UINT r2 = (r << 1) + 1; if (r2 != last) - r2 += static_cast(count[r2] < count[r2 + 1]); + r2 += static_cast(count[r2] < count[r2 + 1]); if (count[r] >= count[r2]) break; uint16 t = count[r2]; @@ -3314,7 +3288,7 @@ bool IsUnicodeFile(LPCTSTR pszFilePath) { WORD wBOM; FILE *fp = _tfsopen(pszFilePath, _T("rb"), _SH_DENYWR); - bool bResult = (fp != NULL) && fread(&wBOM, sizeof wBOM, 1, fp) == 1 && wBOM == 0xFEFFui16; + bool bResult = (fp != NULL) && fread(&wBOM, sizeof wBOM, 1, fp) == 1 && wBOM == u'\xFEFF'; if (fp != NULL) fclose(fp); return bResult; @@ -3381,7 +3355,22 @@ int GetPathDriveNumber(const CString &path) if (path.GetLength() < 3 || path[1] != _T(':') || path[2] != _T('\\')) return -1; - return tolower(path[0]) - 'a'; //97, lower case 'a' + return tolower(path[0]) - 'a'; //lower case 'a' ASCII 97(0x61) +} + +CString GetShareName(const CString &path) +{ + //Should be a drive '\\?\volume\' or '\\.\volume\', or a UNC share '\\server\name\' + if (path.GetLength() >= 5 && path[0] == _T('\\') || path[1] == _T('\\')) { + int i = path.Find(_T('\\'), 3); + if (i > 0) { + i = path.Find(_T('\\'), i + 1); + if (i > 0) + return path.Left(i + 1); + } + } + ASSERT(0); + return CString(); } uint64 GetFreeTempSpace(INT_PTR tempdirindex) @@ -3394,7 +3383,7 @@ uint64 GetFreeTempSpace(INT_PTR tempdirindex) if (tempdirindex >= 0) return GetFreeDiskSpaceX(thePrefs.GetTempDir(tempdirindex)); - CArray hist; + CArray hist; uint64 sum = 0; for (INT_PTR i = 0; i < thePrefs.GetTempDirCount(); ++i) { int pdn = GetPathDriveNumber(thePrefs.GetTempDir(i)); @@ -3621,13 +3610,14 @@ EFileType GetFileTypeEx(CShareableFile *kfile, bool checkextention, bool checkfi CPartFile *pfile = static_cast(kfile); bool test4iso = (!kfile->IsPartFile() - || ((uint64)pfile->GetFileSize() > 0x8000 + HEADERCHECKSIZE && pfile->IsComplete(0x8000, 0x8000 + HEADERCHECKSIZE, true))); - if (checkfileheader && (!kfile->IsPartFile() || pfile->IsComplete(0, HEADERCHECKSIZE, true) || test4iso)) { + || ((uint64)pfile->GetCompletedSize() > 0x8000 + HEADERCHECKSIZE + && pfile->IsCompleteBD(0x8000, 0x8000 + HEADERCHECKSIZE))); + if (checkfileheader && (!kfile->IsPartFile() || pfile->IsCompleteBDSafe(0, HEADERCHECKSIZE) || test4iso)) { try { CFile inFile; if (inFile.Open(kfile->GetFilePath(), CFile::modeRead | CFile::shareDenyNone)) { unsigned char headerbuf[HEADERCHECKSIZE]; - if (!kfile->IsPartFile() || pfile->IsComplete(0, HEADERCHECKSIZE, true)) { + if (!kfile->IsPartFile() || pfile->IsCompleteBDSafe(0, HEADERCHECKSIZE)) { int read = inFile.Read(headerbuf, HEADERCHECKSIZE); if (read == HEADERCHECKSIZE) { if (memcmp(headerbuf, FILEHEADER_ZIP_ID, sizeof FILEHEADER_ZIP_ID) == 0) @@ -3666,11 +3656,8 @@ EFileType GetFileTypeEx(CShareableFile *kfile, bool checkextention, bool checkfi res = PIC_GIF; else if (memcmp(headerbuf, FILEHEADER_EXE_ID, sizeof FILEHEADER_EXE_ID) == 0) { // This could be a self extracting RAR archive. If the ED2K name of the file - // has the RAR extension we treat this 'EXE' file like an 'unverified' RAR file. - if (_tcsicmp(PathFindExtension(kfile->GetFileName()), _T(".rar")) == 0) - res = FILETYPE_UNKNOWN; - else - res = FILETYPE_EXECUTABLE; + // has the RAR extension we treat this 'EXE' file as an 'unverified' RAR file. + res = ExtensionIs(kfile->GetFileName(), _T(".rar")) ? FILETYPE_UNKNOWN : FILETYPE_EXECUTABLE; } else if ((headerbuf[0] & 0xFF) == 0xFF && (headerbuf[1] & 0xE0) == 0xE0) res = AUDIO_MPEG; } @@ -3699,10 +3686,9 @@ EFileType GetFileTypeEx(CShareableFile *kfile, bool checkextention, bool checkfi if (!checkextention) return res; - CString extLC; - int posD = kfile->GetFileName().ReverseFind(_T('.')); - if (posD >= 0) - extLC = kfile->GetFileName().Mid(posD + 1).MakeUpper(); + LPCTSTR pDot = ::PathFindExtension(kfile->GetFileName()); + CString extLC(pDot + static_cast(*pDot != _T('\0'))); //skip the dot + extLC.MakeLower(); for (const SFileExts *ext = s_fileexts; ext->ftype != FILETYPE_UNKNOWN; ++ext) { const CString &testext(ext->extlist); @@ -3710,7 +3696,7 @@ EFileType GetFileTypeEx(CShareableFile *kfile, bool checkextention, bool checkfi return ext->ftype; } - // rar multivolume old naming + // rar multi-volume old naming if (extLC.GetLength() == 3 && extLC[0] == _T('R') && _istdigit(extLC[1]) && _istdigit(extLC[2])) return ARCHIVE_RAR; return FILETYPE_UNKNOWN; @@ -3727,7 +3713,7 @@ CString GetFileTypeName(EFileType ftype) bool ExtensionIs(LPCTSTR pszFilePath, LPCTSTR pszExt) { - return _tcsicmp(PathFindExtension(pszFilePath), pszExt) == 0; + return _tcsicmp(::PathFindExtension(pszFilePath), pszExt) == 0; } // 1 - type matches acceptable extension @@ -3771,8 +3757,7 @@ uint32 LevenshteinDistance(const CString &str1, const CString &str2) return d_del; } - -// Wrapper for _tmakepath which ensures that the outputbuffer does not exceed MAX_PATH +// Wrapper for _tmakepath which ensures that the output buffer does not exceed MAX_PATH // using a smaller buffer without checking the sizes prior calling this function is not safe // If the resulting path would be bigger than MAX_PATH-1, it will be empty and return false (similar to PathCombine) bool _tmakepathlimit(LPTSTR path, LPCTSTR drive, LPCTSTR dir, LPCTSTR fname, LPCTSTR ext) @@ -3795,6 +3780,42 @@ bool _tmakepathlimit(LPTSTR path, LPCTSTR drive, LPCTSTR dir, LPCTSTR fname, LPC return true; } +bool HasSubdirectories(const CString &strDir) +{ + // Never try to enumerate the files of a drive and thus physically access the drive, just + // for the information whether the drive has subdirectories in the root folder. Depending + // on the physical drive type (floppy disk, CD-ROM drive, etc.) this creates an annoying + // physical access to that drive - which is to be avoided in each case. Even Windows + // Explorer shows all drives by default with a '+' sign (which means that the user has + // to explicitly open the drive to really get the content) - and that approach will be fine + // for eMule as well. + // Since the restriction for drives 'A:' and 'B:' was removed, this gets more important now. + CString sDir(strDir); + slosh(sDir); //required for PathIsRoot + if (::PathIsRoot(sDir)) + return true; + CFileFind finder; + for (BOOL bFound = finder.FindFile(sDir + _T('*')); bFound;) { + bFound = finder.FindNextFile(); + if (finder.IsDirectory() && !finder.IsDots() && !finder.IsSystem()) + return true; + } + return false; +} + +bool DirAccsess(const CString &strDir) +{ + // Check directory existence only for fixed disks + int iDrive = ::PathGetDriveNumber(strDir); + if (iDrive >= 0 && iDrive <= 25) { + TCHAR szRootPath[4] = _T("@:\\"); + *szRootPath = (TCHAR)(_T('A') + iDrive); + if (::GetDriveType(szRootPath) == DRIVE_FIXED && _taccess(strDir, 0) != 0) + return false; + } + return true; +} + uint8 GetMyConnectOptions(bool bEncryption, bool bCallback) { // Connect options Tag diff --git a/srchybrid/OtherFunctions.h b/srchybrid/OtherFunctions.h index 16b369dc..d22a6fb0 100644 --- a/srchybrid/OtherFunctions.h +++ b/srchybrid/OtherFunctions.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -50,21 +50,12 @@ enum EFileType : uint8 extern LPCTSTR const sBadFileNameChar; extern LPCTSTR const sHiddenPassword; -static const struct +struct LinkScheme { LPCTSTR pszScheme; int iLen; -} s_apszSchemes[] = -{ - { _T("ed2k://"), 7 }, - { _T("http://"), 7 }, - { _T("https://"), 8 }, - { _T("ftp://"), 6 }, - { _T("www."), 4 }, - { _T("ftp."), 4 }, - { _T("mailto:"), 7 }, - { _T("magnet:?"), 8 } }; +extern const struct LinkScheme s_apszSchemes[]; struct SUnresolvedHostname { @@ -79,17 +70,17 @@ struct SUnresolvedHostname #define ROUND(x) (floor((float)(x)+0.5f)) -template inline static const T maxi(const T &v0, const T &v1) +template inline static T maxi(const T &v0, const T &v1) { return v0 >= v1 ? v0 : v1; } -template inline static const T mini(const T &v0, const T &v1) +template inline static T mini(const T &v0, const T &v1) { return v0 <= v1 ? v0 : v1; } -template inline static const int sgn(const T &val) +template inline static int sgn(const T &val) //for signed types only! { return (T(0) < val) - (val < T(0)); } @@ -130,8 +121,7 @@ CString CastSecondsToHM(time_t seconds); CString CastSecondsToLngHM(time_t seconds); CString GetFormatedUInt(ULONG ulVal); CString GetFormatedUInt64(ULONGLONG ullVal); -void SecToTimeLength(unsigned long ulSec, CStringA &rstrTimeLength); -void SecToTimeLength(unsigned long ulSec, CStringW &rstrTimeLength); +CString SecToTimeLength(UINT uiSec); bool IsRegExpValid(const CString ®expr); bool RegularExpressionMatch(const CString ®expr, const CString &teststring); @@ -146,7 +136,7 @@ CString GetCertInteger(const unsigned char *pucBlob, int cbBlob); CString URLDecode(const CString &sIn, bool bKeepNewLine = false); CString URLEncode(const CString &sIn); CString EncodeURLQueryParam(const CString &rstrQuery); -//CString MakeStringEscaped(CString in); +void DupAmpersand(CString &rstr); //CString RemoveAmpersand(const CString &rstr); CString StripInvalidFilenameChars(const CString &strText); @@ -169,7 +159,7 @@ void unslosh(CString &path); //remove trailing backslash from the path void canonical(CString &path); //applies PathCanonicalize void MakeFoldername(CString &path); //removes trailing backslash CString RemoveFileExtension(const CString &rstrFilePath); -int CompareDirectory(const CString &rstrDir1, const CString &rstrDir2); +bool EqualPaths(const CString &rstrDir1, const CString &rstrDir2); CString StringLimit(const CString &in, UINT length); CString CleanupFilename(const CString &filename, bool bExtension = true); CString ValidFilename(const CString &filename); @@ -188,17 +178,21 @@ void StripTrailingColon(CString &rstr); bool IsUnicodeFile(LPCTSTR pszFilePath); uint64 GetFreeTempSpace(INT_PTR tempdirindex); int GetPathDriveNumber(const CString &path); +CString GetShareName(const CString &path); EFileType GetFileTypeEx(CShareableFile *kfile, bool checkextention = true, bool checkfileheader = true, bool nocached = false); CString GetFileTypeName(EFileType ftype); bool ExtensionIs(LPCTSTR pszFilePath, LPCTSTR pszExt); int IsExtensionTypeOf(EFileType type, const CString &ext); uint32 LevenshteinDistance(const CString &str1, const CString &str2); bool _tmakepathlimit(LPTSTR path, LPCTSTR drive, LPCTSTR dir, LPCTSTR fname, LPCTSTR ext); +bool HasSubdirectories(const CString &strDir); +bool DirAccsess(const CString &strDir); #ifdef UNICODE #define CompareLocaleStringNoCase CompareLocaleStringNoCaseW #else #define CompareLocaleStringNoCase CompareLocaleStringNoCaseA #endif // !UNICODE +bool IsThumbsDb(const CString &sFilePath, const CString &sFileName); /////////////////////////////////////////////////////////////////////////////// // GUI helpers @@ -220,6 +214,7 @@ void GetPopupMenuPos(const CTreeCtrl &tv, CPoint &point); void InitWindowStyles(CWnd *pWnd); CString GetRateString(UINT rate); HWND ReplaceRichEditCtrl(CWnd *pwndRE, CWnd *pwndParent, CFont *pFont); +void DisableAutoSelect(CRichEditCtrl &re); int FontPointSizeToLogUnits(int nPointSize); bool CreatePointFont(CFont &rFont, int nPointSize, LPCTSTR lpszFaceName); bool CreatePointFontIndirect(CFont &rFont, const LOGFONT *lpLogFont); @@ -256,7 +251,7 @@ LPCTSTR GetShellExecuteErrMsg(DWORD dwShellExecError); CString DbgGetHexDump(const uint8 *data, UINT size); //limited to the first 50 bytes void DbgSetThreadName(LPCSTR szThreadName, ...); void Debug(LPCTSTR pszFmtMsg, ...); -void DebugHexDump(const uint8 *data, UINT lenData); +void DebugHexDump(const void *data, UINT lenData); void DebugHexDump(CFile &file); CString DbgGetFileInfo(const uchar *hash); CString DbgGetFileStatus(UINT nPartCount, CSafeMemFile *data); @@ -278,7 +273,7 @@ void DebugSend(LPCSTR pszMsg, const CUpDownClient *client, const uchar *packet = void DebugSend(LPCSTR pszOpcode, uint32 ip, uint16 port); void DebugSendF(LPCSTR pszOpcode, uint32 ip, uint16 port, LPCTSTR pszMsg, ...); void DebugHttpHeaders(const CStringAArray &astrHeaders); - +void throwCStr(LPCTSTR pStr); /////////////////////////////////////////////////////////////////////////////// @@ -294,7 +289,7 @@ void SetAutoStart(bool bOn); ULONGLONG GetModuleVersion(LPCTSTR pszFilePath); ULONGLONG GetModuleVersion(HMODULE hModule); -int GetMaxWindowsTCPConnections(); +UINT GetMaxWindowsTCPConnections(); #define _WINVER_95_ 0x0400 // 4.0 #define _WINVER_NT4_ 0x0401 // 4.1 (baked version) @@ -328,7 +323,7 @@ bool AddIconGrayscaledToImageList(CImageList &rList, HICON hIcon); #define MDX_BLOCK_SIZE 64 //both MD4 and MD5 #define MDX_DIGEST_SIZE 16 -inline BYTE toHex(const BYTE &x) +inline BYTE toHex(const BYTE x) { return x + (x > 9 ? 'A' - 10 : '0'); } @@ -369,11 +364,17 @@ bool strmd4(const CString &rstr, byte *hash); /////////////////////////////////////////////////////////////////////////////// -// Compare helpers (spaceship operator would have been handy here) +// Compare helpers (three-way) // -inline int CompareUnsigned(uint32 uSize1, uint32 uSize2) + +//Designed for unsigned integral types because sgn(v0-v1) would fail. +template inline static int CompareUnsigned(const T v0, const T v1) { - return (uSize1 < uSize2) ? -1 : static_cast(uSize1 > uSize2); +#if _MSVC_LANG == 202002L + return v0 <=> v1; +#else + return (v0 < v1) ? -1 : static_cast(v0 > v1); +#endif } inline int CompareUnsignedUndefinedAtBottom(uint32 uSize1, uint32 uSize2, bool bSortAscending) @@ -388,16 +389,6 @@ inline int CompareUnsignedUndefinedAtBottom(uint32 uSize1, uint32 uSize2, bool b return CompareUnsigned(uSize1, uSize2); } -inline int CompareUnsigned64(uint64 uSize1, uint64 uSize2) -{ - return (uSize1 < uSize2) ? -1 : static_cast(uSize1 > uSize2); -} - -/*inline int CompareFloat(float uSize1, float uSize2) -{ - return (uSize1 < uSize2) ? -1 : static_cast(uSize1 > uSize2); -} -*/ inline int CompareOptLocaleStringNoCase(LPCTSTR psz1, LPCTSTR psz2) { if (psz1 && psz2) @@ -452,7 +443,7 @@ uint8 GetMyConnectOptions(bool bEncryption = true, bool bCallback = true); //No longer need separate lowID checks as we now know the servers just give *.*.*.0 users a lowID inline bool IsLowID(uint32 id) { - return (id < 16777216u); //0x01000000u + return (id < 16777216u); //0x01000000u or 2^25 } CString ipstr(uint32 nIP); CString ipstr(uint32 nIP, uint16 nPort); @@ -477,8 +468,8 @@ bool AdjustNTFSDaylightFileTime(time_t &ruFileDate, LPCTSTR pszFilePath); //MS have broken stat functions in XP builds of VS 2015+, and refused to fix it properly. //Return UTC time and file size in _stat64 structure; all time fields are in UTC. __time64_t FileTimeToUnixTime(const FILETIME &ft); -int statUTC(LPCTSTR pname, struct _stat64 &ft); -int statUTC(int ifile, struct _stat64 &ft); +int statUTC(LPCTSTR pName, struct _stat64 &ft); +int statUTC(HANDLE hFile, struct _stat64 &ft); /////////////////////////////////////////////////////////////////////////////// // Random Numbers diff --git a/srchybrid/PPgConnection.cpp b/srchybrid/PPgConnection.cpp index 0b168130..d3e82791 100644 --- a/srchybrid/PPgConnection.cpp +++ b/srchybrid/PPgConnection.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -20,7 +20,6 @@ #include "PPgConnection.h" #include "wizard.h" #include "Scheduler.h" -#include "OtherFunctions.h" #include "emuledlg.h" #include "Preferences.h" #include "Opcodes.h" @@ -223,8 +222,8 @@ BOOL CPPgConnection::OnApply() return FALSE; } - int lastmaxgu = thePrefs.maxGraphUploadRate; //save the values - int lastmaxgd = thePrefs.maxGraphDownloadRate; + uint32 lastmaxgu = thePrefs.maxGraphUploadRate; //save the values + uint32 lastmaxgd = thePrefs.maxGraphDownloadRate; thePrefs.SetMaxGraphDownloadRate(v); m_ctlMaxDown.SetRange(1, thePrefs.GetMaxGraphDownloadRate(), TRUE); @@ -313,7 +312,7 @@ BOOL CPPgConnection::OnApply() else tempcon = (u >= INT_MAX ? CPreferences::GetRecommendedMaxConnections() : u); - if (tempcon > (UINT)GetMaxWindowsTCPConnections()) { + if (tempcon > GetMaxWindowsTCPConnections()) { CString strMessage; strMessage.Format(GetResString(IDS_PW_WARNING), (LPCTSTR)GetResString(IDS_PW_MAXC), GetMaxWindowsTCPConnections()); int iResult = AfxMessageBox(strMessage, MB_ICONWARNING | MB_YESNO); @@ -386,7 +385,7 @@ void CPPgConnection::OnBnClickedWizard() bool CPPgConnection::CheckUp(uint32 mUp, uint32 &mDown) { - if (thePrefs.maxGraphDownloadRate <= 0) + if (thePrefs.maxGraphDownloadRate == 0) return false; uint32 uDown = mDown; if (mUp < 4 && mDown > mUp * 3) @@ -395,7 +394,7 @@ bool CPPgConnection::CheckUp(uint32 mUp, uint32 &mDown) mDown = mUp * 4; else if (mUp < 20 && mDown > mUp * 5) mDown = mUp * 5; - if (mDown > (uint32)thePrefs.maxGraphDownloadRate) { + if (mDown > thePrefs.maxGraphDownloadRate) { mDown = thePrefs.maxGraphDownloadRate; return true; } @@ -404,7 +403,7 @@ bool CPPgConnection::CheckUp(uint32 mUp, uint32 &mDown) bool CPPgConnection::CheckDown(uint32 &mUp, uint32 mDown) { - if (thePrefs.maxGraphUploadRate <= 0) + if (thePrefs.maxGraphUploadRate == 0) return false; uint32 uUp = mUp; if (mDown < 13 && mUp * 3 < mDown) @@ -413,7 +412,7 @@ bool CPPgConnection::CheckDown(uint32 &mUp, uint32 mDown) mUp = (mDown + 3) / 4; else if (mUp < 20 && mUp * 5 < mDown) mUp = (mDown + 4) / 5; - if (mUp > (uint32)thePrefs.maxGraphUploadRate) { + if (mUp > thePrefs.maxGraphUploadRate) { mUp = thePrefs.maxGraphUploadRate; return true; } diff --git a/srchybrid/PPgConnection.h b/srchybrid/PPgConnection.h index aed158bd..0b642259 100644 --- a/srchybrid/PPgConnection.h +++ b/srchybrid/PPgConnection.h @@ -14,7 +14,6 @@ class CPPgConnection : public CPropertyPage public: CPPgConnection(); - virtual ~CPPgConnection() = default; void Localize(); void LoadSettings(); diff --git a/srchybrid/PPgDebug.cpp b/srchybrid/PPgDebug.cpp index f2f93a4e..ae1ae0e8 100644 --- a/srchybrid/PPgDebug.cpp +++ b/srchybrid/PPgDebug.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/PPgDebug.h b/srchybrid/PPgDebug.h index 29f152c4..38748bb2 100644 --- a/srchybrid/PPgDebug.h +++ b/srchybrid/PPgDebug.h @@ -17,7 +17,6 @@ class CPPgDebug : public CPropertyPage public: CPPgDebug(); - virtual ~CPPgDebug() = default; protected: HTREEITEM m_htiServer; diff --git a/srchybrid/PPgDirectories.cpp b/srchybrid/PPgDirectories.cpp index 7fb91ecc..033a4693 100644 --- a/srchybrid/PPgDirectories.cpp +++ b/srchybrid/PPgDirectories.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -100,7 +100,7 @@ void CPPgDirectories::LoadSettings() SetDlgItemText(IDC_TEMPFILES, tempfolders); m_ShareSelector.SetSharedDirectories(thePrefs.shareddir_list); - FillUncList(); + FillUNClist(); } void CPPgDirectories::OnBnClickedSelincdir() @@ -121,44 +121,38 @@ void CPPgDirectories::OnBnClickedSeltempdir() BOOL CPPgDirectories::OnApply() { - bool testtempdirchanged = false; - const CString &testincdirchanged = thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR); - CString strIncomingDir; GetDlgItemText(IDC_INCFILES, strIncomingDir); MakeFoldername(strIncomingDir); if (strIncomingDir.IsEmpty()) { - strIncomingDir = thePrefs.GetDefaultDirectory(EMULE_INCOMINGDIR, true); // will create the directory here if it doesn't exists + strIncomingDir = thePrefs.GetDefaultDirectory(EMULE_INCOMINGDIR, true); // will create the directory here if it doesn't exist SetDlgItemText(IDC_INCFILES, strIncomingDir); } else if (thePrefs.IsInstallationDirectory(strIncomingDir)) { - LocMessageBox(IDS_WRN_INCFILE_RESERVED, MB_OK, 0); + ErrorBalloon(IDC_INCFILES, IDS_WRN_INCFILE_RESERVED); return FALSE; - } else if (strIncomingDir.CompareNoCase(testincdirchanged) != 0 && strIncomingDir.CompareNoCase(thePrefs.GetDefaultDirectory(EMULE_INCOMINGDIR, false)) != 0) { + } + + const CString &sOldIncoming(thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR)); + if (strIncomingDir.CompareNoCase(sOldIncoming) != 0 && strIncomingDir.CompareNoCase(thePrefs.GetDefaultDirectory(EMULE_INCOMINGDIR, false)) != 0) { // if the user chooses a non-default directory which already contains files, // inform him that all those files will be shared - CFileFind ff; - CString strSearchPath(strIncomingDir + _T("\\*")); - bool bEnd = !ff.FindFile(strSearchPath, 0); bool bExistingFile = false; - while (!bEnd) { - bEnd = !ff.FindNextFile(); - if (ff.IsDirectory() || ff.IsDots() || ff.IsSystem() || ff.IsTemporary() || ff.GetLength() == 0 || ff.GetLength() > MAX_EMULE_FILE_SIZE) + CFileFind ff; + for (BOOL bFound = ff.FindFile(strIncomingDir + _T('*')); bFound && !bExistingFile;) { + bFound = ff.FindNextFile(); + if (ff.IsDirectory() || ff.IsSystem() || ff.IsTemporary() || ff.GetLength() == 0 || ff.GetLength() > MAX_EMULE_FILE_SIZE) continue; // ignore real LNK files if (ExtensionIs(ff.GetFileName(), _T(".lnk"))) { SHFILEINFO info; - if (SHGetFileInfo(ff.GetFilePath(), 0, &info, sizeof(info), SHGFI_ATTRIBUTES) && (info.dwAttributes & SFGAO_LINK)) + if (::SHGetFileInfo(ff.GetFilePath(), 0, &info, sizeof info, SHGFI_ATTRIBUTES) && (info.dwAttributes & SFGAO_LINK)) if (!thePrefs.GetResolveSharedShellLinks()) continue; } // ignore real THUMBS.DB files -- seems that lot of ppl have 'thumbs.db' files without the 'System' file attribute - if (ff.GetFileName().CompareNoCase(_T("thumbs.db")) == 0) - continue; - - bExistingFile = true; - break; + bExistingFile = (ff.GetFileName().CompareNoCase(_T("thumbs.db")) != 0); } if (bExistingFile && LocMessageBox(IDS_WRN_INCFILE_EXISTS, MB_OKCANCEL | MB_ICONINFORMATION, 0) == IDCANCEL) return FALSE; @@ -168,27 +162,31 @@ BOOL CPPgDirectories::OnApply() CString strTempDir; GetDlgItemText(IDC_TEMPFILES, strTempDir); if (strTempDir.IsEmpty()) { - strTempDir = thePrefs.GetDefaultDirectory(EMULE_TEMPDIR, true); // will create the directory here if it doesn't exists + strTempDir = thePrefs.GetDefaultDirectory(EMULE_TEMPDIR, true); // will create the directory if it doesn't exist SetDlgItemText(IDC_TEMPFILES, strTempDir); } + bool testtempdirchanged = false; CStringArray temptempfolders; for (int iPos = 0; iPos >= 0;) { CString atmp(strTempDir.Tokenize(_T("|"), iPos)); if (atmp.Trim().IsEmpty()) continue; - if (CompareDirectory(strIncomingDir, atmp) == 0) { - LocMessageBox(IDS_WRN_INCTEMP_SAME, MB_OK, 0); - return FALSE; - } - if (thePrefs.IsInstallationDirectory(atmp)) { - LocMessageBox(IDS_WRN_TEMPFILES_RESERVED, MB_OK, 0); + UINT uid; + if (EqualPaths(strIncomingDir, atmp)) + uid = IDS_WRN_INCTEMP_SAME; + else if (thePrefs.IsInstallationDirectory(atmp)) + uid = IDS_WRN_TEMPFILES_RESERVED; + else + uid = 0; + if (uid) { + ErrorBalloon(IDC_TEMPFILES, uid); return FALSE; } bool bDup = false; for (INT_PTR i = temptempfolders.GetCount(); --i >= 0;) // avoid duplicate tempdirs - if (temptempfolders[i].CompareNoCase(atmp) == 0) { + if (atmp.CompareNoCase(temptempfolders[i]) == 0) { bDup = true; break; } @@ -215,9 +213,9 @@ BOOL CPPgDirectories::OnApply() for (INT_PTR i = 0; i < temptempfolders.GetCount(); ++i) { CString toadd(temptempfolders[i]); MakeFoldername(toadd); - if (!PathFileExists(toadd)) + if (!::PathFileExists(toadd)) ::CreateDirectory(toadd, NULL); - if (PathFileExists(toadd)) + if (::PathFileExists(toadd)) thePrefs.tempdir.Add(toadd); } } @@ -229,8 +227,7 @@ BOOL CPPgDirectories::OnApply() thePrefs.shareddir_list.RemoveAll(); m_ShareSelector.GetSharedDirectories(thePrefs.shareddir_list); - for (int i = 0; i < m_ctlUncPaths.GetItemCount(); ++i) - thePrefs.shareddir_list.AddTail(m_ctlUncPaths.GetItemText(i, 0)); + FillUNClist(); // check shared directories for reserved folder names for (POSITION pos = thePrefs.shareddir_list.GetHeadPosition(); pos != NULL;) { @@ -239,20 +236,19 @@ BOOL CPPgDirectories::OnApply() thePrefs.shareddir_list.RemoveAt(posLast); } - // on changing incoming dir, update incoming dirs of category of the same path - if (testincdirchanged.CompareNoCase(thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR)) != 0) { + // on changing incoming dir, update directories for categories with the same path + if (sOldIncoming.CompareNoCase(thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR)) != 0) { thePrefs.GetCategory(0)->strIncomingPath = thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR); - bool dontaskagain = false; - for (int cat = 1; cat <= thePrefs.GetCatCount() - 1; ++cat) { - const CString &oldpath = thePrefs.GetCatPath(cat); - if (oldpath.Left(testincdirchanged.GetLength()).CompareNoCase(testincdirchanged) == 0) { - - if (!dontaskagain) { - dontaskagain = true; + bool bAskedOnce = false; + for (INT_PTR cat = thePrefs.GetCatCount(); --cat > 0;) { //skip 0 + const CString &oldpath(thePrefs.GetCatPath(cat)); + if (oldpath.Left(sOldIncoming.GetLength()).CompareNoCase(sOldIncoming) == 0) { + if (!bAskedOnce) { + bAskedOnce = true; if (LocMessageBox(IDS_UPDATECATINCOMINGDIRS, MB_YESNO, 0) == IDNO) break; } - thePrefs.GetCategory(cat)->strIncomingPath = thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR) + oldpath.Mid(testincdirchanged.GetLength()); + thePrefs.GetCategory(cat)->strIncomingPath = thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR) + oldpath.Mid(sOldIncoming.GetLength()); } } thePrefs.SaveCats(); @@ -290,14 +286,14 @@ void CPPgDirectories::Localize() } } -void CPPgDirectories::FillUncList() +void CPPgDirectories::FillUNClist() { m_ctlUncPaths.DeleteAllItems(); for (POSITION pos = thePrefs.shareddir_list.GetHeadPosition(); pos != NULL;) { - const CString &folder = thePrefs.shareddir_list.GetNext(pos); - if (PathIsUNC(folder)) - m_ctlUncPaths.InsertItem(0, folder); + const CString &sDir(thePrefs.shareddir_list.GetNext(pos)); + if (::PathIsUNC(sDir)) + m_ctlUncPaths.InsertItem(INT_MAX, sDir); } } @@ -307,26 +303,24 @@ void CPPgDirectories::OnBnClickedAddUNC() inputbox.SetLabels(GetResString(IDS_UNCFOLDERS), GetResString(IDS_UNCFOLDERS), _T("\\\\Server\\Share")); if (inputbox.DoModal() != IDOK) return; - CString unc = inputbox.GetInput(); + CString unc(inputbox.GetInput()); // basic UNC check - if (!PathIsUNC(unc)) { + if (!::PathIsUNC(unc)) { LocMessageBox(IDS_ERR_BADUNC, MB_ICONERROR, 0); return; } - - if (unc.Right(1) == _T("\\")) - unc.Truncate(unc.GetLength() - 1); + slosh(unc); for (POSITION pos = thePrefs.shareddir_list.GetHeadPosition(); pos != NULL;) - if (unc.CompareNoCase(thePrefs.shareddir_list.GetNext(pos)) == 0) + if (EqualPaths(thePrefs.shareddir_list.GetNext(pos), unc)) return; for (int i = m_ctlUncPaths.GetItemCount(); --i >= 0;) - if (unc.CompareNoCase(m_ctlUncPaths.GetItemText(i, 0)) == 0) + if (EqualPaths(m_ctlUncPaths.GetItemText(i, 0), unc)) return; - m_ctlUncPaths.InsertItem(m_ctlUncPaths.GetItemCount(), unc); + m_ctlUncPaths.InsertItem(INT_MAX, unc); SetModified(); } @@ -371,4 +365,9 @@ void CPPgDirectories::OnDestroy() VERIFY(::DestroyIcon(m_icoBrowse)); m_icoBrowse = NULL; } +} + +void CPPgDirectories::ErrorBalloon(int iEdit, UINT uid) +{ + static_cast(GetDlgItem(iEdit))->ShowBalloonTip(GetResString(IDS_ERROR), GetResString(uid), TTI_ERROR); } \ No newline at end of file diff --git a/srchybrid/PPgDirectories.h b/srchybrid/PPgDirectories.h index 41ea8caa..096146d6 100644 --- a/srchybrid/PPgDirectories.h +++ b/srchybrid/PPgDirectories.h @@ -9,10 +9,9 @@ class CPPgDirectories : public CPropertyPage { IDD = IDD_PPG_DIRECTORIES }; - + void ErrorBalloon(int iEdit, UINT uid); public: CPPgDirectories(); // standard constructor - virtual ~CPPgDirectories() = default; void Localize(); @@ -22,7 +21,7 @@ class CPPgDirectories : public CPropertyPage HICON m_icoBrowse; void LoadSettings(); - void FillUncList(); + void FillUNClist(); virtual void DoDataExchange(CDataExchange *pDX); // DDX/DDV support virtual BOOL OnInitDialog(); diff --git a/srchybrid/PPgDisplay.cpp b/srchybrid/PPgDisplay.cpp index 12fbd383..e91cd252 100644 --- a/srchybrid/PPgDisplay.cpp +++ b/srchybrid/PPgDisplay.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/PPgDisplay.h b/srchybrid/PPgDisplay.h index f5824b0e..cdaa2fe9 100644 --- a/srchybrid/PPgDisplay.h +++ b/srchybrid/PPgDisplay.h @@ -13,7 +13,6 @@ class CPPgDisplay : public CPropertyPage public: CPPgDisplay(); - virtual ~CPPgDisplay() = default; void Localize(); diff --git a/srchybrid/PPgFiles.cpp b/srchybrid/PPgFiles.cpp index 5b1e15cc..74525ce4 100644 --- a/srchybrid/PPgFiles.cpp +++ b/srchybrid/PPgFiles.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -106,7 +106,7 @@ void CPPgFiles::LoadSettings() SetDlgItemText(IDC_VIDEOPLAYER, thePrefs.m_strVideoPlayer); SetDlgItemText(IDC_VIDEOPLAYER_ARGS, thePrefs.m_strVideoPlayerArgs); - CheckDlgButton(IDC_VIDEOBACKUP, static_cast(thePrefs.moviePreviewBackup)); + CheckDlgButton(IDC_VIDEOBACKUP, static_cast(thePrefs.m_bMoviePreviewBackup)); CheckDlgButton(IDC_FNCLEANUP, static_cast(thePrefs.AutoFilenameCleanup())); CheckDlgButton(IDC_WATCHCB, static_cast(thePrefs.watchclipboard)); CheckDlgButton(IDC_REMEMBERDOWNLOADED, static_cast(thePrefs.IsRememberingDownloadedFiles())); @@ -151,7 +151,7 @@ BOOL CPPgFiles::OnApply() thePrefs.m_strVideoPlayer.Trim(); GetDlgItemText(IDC_VIDEOPLAYER_ARGS, thePrefs.m_strVideoPlayerArgs); thePrefs.m_strVideoPlayerArgs.Trim(); - thePrefs.moviePreviewBackup = IsDlgButtonChecked(IDC_VIDEOBACKUP) != 0; + thePrefs.m_bMoviePreviewBackup = IsDlgButtonChecked(IDC_VIDEOBACKUP) != 0; LoadSettings(); SetModified(FALSE); diff --git a/srchybrid/PPgFiles.h b/srchybrid/PPgFiles.h index 9df019a4..79dec99a 100644 --- a/srchybrid/PPgFiles.h +++ b/srchybrid/PPgFiles.h @@ -11,7 +11,6 @@ class CPPgFiles : public CPropertyPage public: CPPgFiles(); - virtual ~CPPgFiles() = default; void Localize(); diff --git a/srchybrid/PPgGeneral.cpp b/srchybrid/PPgGeneral.cpp index fdc95659..b9569737 100644 --- a/srchybrid/PPgGeneral.cpp +++ b/srchybrid/PPgGeneral.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -86,14 +86,14 @@ void CPPgGeneral::LoadSettings() { SetLangSel(); SetDlgItemText(IDC_NICK, thePrefs.GetUserNick()); - CheckDlgButton(IDC_STARTWIN, static_cast(thePrefs.m_bAutoStart)); - CheckDlgButton(IDC_STARTMIN, static_cast(thePrefs.startMinimized)); - CheckDlgButton(IDC_ONLINESIG, static_cast(thePrefs.onlineSig)); - CheckDlgButton(IDC_EXIT, static_cast(thePrefs.confirmExit)); - CheckDlgButton(IDC_SPLASHON, static_cast(thePrefs.splashscreen)); CheckDlgButton(IDC_BRINGTOFOREGROUND, static_cast(thePrefs.bringtoforeground)); - CheckDlgButton(IDC_CHECK4UPDATE, static_cast(thePrefs.updatenotify)); + CheckDlgButton(IDC_EXIT, static_cast(thePrefs.confirmExit)); + CheckDlgButton(IDC_ONLINESIG, static_cast(thePrefs.onlineSig)); CheckDlgButton(IDC_MINIMULE, static_cast(thePrefs.m_bEnableMiniMule)); + CheckDlgButton(IDC_CHECK4UPDATE, static_cast(thePrefs.updatenotify)); + CheckDlgButton(IDC_SPLASHON, static_cast(thePrefs.splashscreen)); + CheckDlgButton(IDC_STARTMIN, static_cast(thePrefs.startMinimized)); + CheckDlgButton(IDC_STARTWIN, static_cast(thePrefs.m_bAutoStart)); if (thePrefs.GetWindowsVersion() != _WINVER_95_) CheckDlgButton(IDC_PREVENTSTANDBY, static_cast(thePrefs.GetPreventStandby())); @@ -222,16 +222,17 @@ BOOL CPPgGeneral::OnApply() } } - SetAutoStart(thePrefs.m_bAutoStart); - thePrefs.startMinimized = thePrefs.m_bAutoStart = (IsDlgButtonChecked(IDC_STARTWIN) != 0); - thePrefs.confirmExit = IsDlgButtonChecked(IDC_EXIT) != 0; - thePrefs.splashscreen = IsDlgButtonChecked(IDC_SPLASHON) != 0; thePrefs.bringtoforeground = IsDlgButtonChecked(IDC_BRINGTOFOREGROUND) != 0; - thePrefs.updatenotify = IsDlgButtonChecked(IDC_CHECK4UPDATE) != 0; + thePrefs.confirmExit = IsDlgButtonChecked(IDC_EXIT) != 0; thePrefs.onlineSig = IsDlgButtonChecked(IDC_ONLINESIG) != 0; - thePrefs.versioncheckdays = static_cast(GetDlgItem(IDC_CHECKDAYS))->GetPos(); thePrefs.m_bEnableMiniMule = IsDlgButtonChecked(IDC_MINIMULE) != 0; thePrefs.m_bPreventStandby = IsDlgButtonChecked(IDC_PREVENTSTANDBY) != 0; + thePrefs.updatenotify = IsDlgButtonChecked(IDC_CHECK4UPDATE) != 0; + thePrefs.versioncheckdays = static_cast(GetDlgItem(IDC_CHECKDAYS))->GetPos(); + thePrefs.splashscreen = IsDlgButtonChecked(IDC_SPLASHON) != 0; + thePrefs.startMinimized = IsDlgButtonChecked(IDC_STARTMIN) != 0; + thePrefs.m_bAutoStart = IsDlgButtonChecked(IDC_STARTWIN) != 0; + SetAutoStart(thePrefs.m_bAutoStart); LoadSettings(); @@ -263,18 +264,18 @@ void CPPgGeneral::Localize() SetDlgItemText(IDC_NICK_FRM, GetResString(IDS_QL_USERNAME)); SetDlgItemText(IDC_LANG_FRM, GetResString(IDS_PW_LANG)); SetDlgItemText(IDC_MISC_FRM, GetResString(IDS_PW_MISC)); - SetDlgItemText(IDC_EXIT, GetResString(IDS_PW_PROMPT)); - SetDlgItemText(IDC_SPLASHON, GetResString(IDS_PW_SPLASH)); SetDlgItemText(IDC_BRINGTOFOREGROUND, GetResString(IDS_PW_FRONT)); + SetDlgItemText(IDC_EXIT, GetResString(IDS_PW_PROMPT)); SetDlgItemText(IDC_ONLINESIG, GetResString(IDS_PREF_ONLINESIG)); - SetDlgItemText(IDC_STARTMIN, GetResString(IDS_PREF_STARTMIN)); + SetDlgItemText(IDC_MINIMULE, GetResString(IDS_ENABLEMINIMULE)); + SetDlgItemText(IDC_PREVENTSTANDBY, GetResString(IDS_PREVENTSTANDBY)); SetDlgItemText(IDC_WEBSVEDIT, GetResString(IDS_WEBSVEDIT)); SetDlgItemText(IDC_ED2KFIX, GetResString(IDS_ED2KLINKFIX)); - SetDlgItemText(IDC_CHECK4UPDATE, GetResString(IDS_CHECK4UPDATE)); SetDlgItemText(IDC_STARTUP, GetResString(IDS_STARTUP)); + SetDlgItemText(IDC_CHECK4UPDATE, GetResString(IDS_CHECK4UPDATE)); + SetDlgItemText(IDC_SPLASHON, GetResString(IDS_PW_SPLASH)); + SetDlgItemText(IDC_STARTMIN, GetResString(IDS_PREF_STARTMIN)); SetDlgItemText(IDC_STARTWIN, GetResString(IDS_STARTWITHWINDOWS)); - SetDlgItemText(IDC_MINIMULE, GetResString(IDS_ENABLEMINIMULE)); - SetDlgItemText(IDC_PREVENTSTANDBY, GetResString(IDS_PREVENTSTANDBY)); } } @@ -315,13 +316,13 @@ void CPPgGeneral::OnLangChange() LANGID newLangId = (LANGID)m_language.GetItemData(m_language.GetCurSel()); if (thePrefs.GetLanguageID() != newLangId) { if (!thePrefs.IsLanguageSupported(newLangId)) { - CString sAsk; - sAsk.Format(_T("%s\r\n\r\n%s"), (LPCTSTR)GetResString(IDS_ASKDOWNLOADLANGCAP), (LPCTSTR)GetResString(IDS_ASKDOWNLOADLANG)); + CString sAsk(GetResString(IDS_ASKDOWNLOADLANGCAP)); + sAsk.AppendFormat(_T("\r\n\r\n%s"), (LPCTSTR)GetResString(IDS_ASKDOWNLOADLANG)); if (AfxMessageBox(sAsk, MB_ICONQUESTION | MB_YESNO) == IDYES) { // download file - const CString &strFilename = thePrefs.GetLangDLLNameByID(newLangId); + const CString &strFilename(thePrefs.GetLangDLLNameByID(newLangId)); // create url, use random mirror for load balancing - UINT nRand = (rand() / (RAND_MAX / 3)) + 1; + UINT nRand = rand() % 3 + 1; CString strUrl; strUrl.Format(MIRRORS_URL _T("%s") , nRand diff --git a/srchybrid/PPgGeneral.h b/srchybrid/PPgGeneral.h index 4884545e..447af54e 100644 --- a/srchybrid/PPgGeneral.h +++ b/srchybrid/PPgGeneral.h @@ -11,7 +11,6 @@ class CPPgGeneral : public CPropertyPage void SetLangSel(); public: CPPgGeneral(); - virtual ~CPPgGeneral() = default; void Localize(); diff --git a/srchybrid/PPgIRC.cpp b/srchybrid/PPgIRC.cpp index b5bafcd2..5d3d029c 100644 --- a/srchybrid/PPgIRC.cpp +++ b/srchybrid/PPgIRC.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/PPgIRC.h b/srchybrid/PPgIRC.h index ad835e2a..40e665ea 100644 --- a/srchybrid/PPgIRC.h +++ b/srchybrid/PPgIRC.h @@ -13,7 +13,6 @@ class CPPgIRC : public CPropertyPage public: CPPgIRC(); - virtual ~CPPgIRC() = default; void Localize(); diff --git a/srchybrid/PPgMessages.cpp b/srchybrid/PPgMessages.cpp index e987f544..72a28de3 100644 --- a/srchybrid/PPgMessages.cpp +++ b/srchybrid/PPgMessages.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/PPgMessages.h b/srchybrid/PPgMessages.h index 00a264d9..08fb5588 100644 --- a/srchybrid/PPgMessages.h +++ b/srchybrid/PPgMessages.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -28,7 +28,6 @@ class CPPgMessages : public CPropertyPage public: CPPgMessages(); - virtual ~CPPgMessages() = default; void Localize(); diff --git a/srchybrid/PPgNotify.cpp b/srchybrid/PPgNotify.cpp index 12dc6a99..5553e2de 100644 --- a/srchybrid/PPgNotify.cpp +++ b/srchybrid/PPgNotify.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -106,6 +106,8 @@ BOOL CPPgNotify::OnInitDialog() bool b = IsRunningXPSP2OrHigher(); m_mail.bSendMail &= b; CheckDlgButton(IDC_CB_ENABLENOTIFICATIONS, m_mail.bSendMail ? BST_CHECKED : BST_UNCHECKED); + SetDlgItemText(IDC_EDIT_RECEIVER, m_mail.sTo); + SetDlgItemText(IDC_EDIT_SENDER, m_mail.sFrom); UpdateControls(); Localize(); @@ -239,7 +241,7 @@ void CPPgNotify::OnBnClickedTestNotification() // save current pref settings bool bCurNotifyOnImportantError = thePrefs.notifierOnImportantError; ENotifierSoundType iCurSoundType = thePrefs.notifierSoundType; - CString strSoundFile = thePrefs.notifierSoundFile; + CString strSoundFile(thePrefs.notifierSoundFile); // temporary apply current settings from dialog thePrefs.notifierOnImportantError = true; diff --git a/srchybrid/PPgNotify.h b/srchybrid/PPgNotify.h index cd126f08..831dabb9 100644 --- a/srchybrid/PPgNotify.h +++ b/srchybrid/PPgNotify.h @@ -25,7 +25,6 @@ class CPPgNotify : public CPropertyPage public: CPPgNotify(); - virtual ~CPPgNotify() = default; void Localize(); diff --git a/srchybrid/PPgProxy.cpp b/srchybrid/PPgProxy.cpp index 7c230c33..199b9d5a 100644 --- a/srchybrid/PPgProxy.cpp +++ b/srchybrid/PPgProxy.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -75,7 +75,7 @@ BOOL CPPgProxy::OnApply() proxy.bUseProxy = IsDlgButtonChecked(IDC_ENABLEPROXY) != 0; int iColon = str.Find(':'); if (iColon >= 0) { - SetDlgItemText(IDC_PROXYPORT, str.Mid(iColon + 1)); + SetDlgItemText(IDC_PROXYPORT, CPTR(str, iColon + 1)); str.Truncate(iColon); } } else diff --git a/srchybrid/PPgProxy.h b/srchybrid/PPgProxy.h index 35f7fa1f..019ec0ec 100644 --- a/srchybrid/PPgProxy.h +++ b/srchybrid/PPgProxy.h @@ -12,7 +12,6 @@ class CPPgProxy : public CPropertyPage public: CPPgProxy(); - virtual ~CPPgProxy() = default; void Localize(); diff --git a/srchybrid/PPgScheduler.cpp b/srchybrid/PPgScheduler.cpp index 9553c951..aec35c07 100644 --- a/srchybrid/PPgScheduler.cpp +++ b/srchybrid/PPgScheduler.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -279,8 +279,8 @@ CString CPPgScheduler::GetDayLabel(int index) { UINT uid; switch (index) { - case DAY_DAYLY: - uid = IDS_DAYLY; + case DAY_DAILY: + uid = IDS_DAILY; break; case DAY_MO: uid = IDS_MO; @@ -366,7 +366,7 @@ void CPPgScheduler::OnNmRClickActionlist(LPNMHDR, LRESULT *pResult) if (thePrefs.GetCatCount() > 1) m_CatActionSel.AppendMenu(MF_STRING, MP_SCHACTIONS + 20, GetResString(IDS_ALLUNASSIGNED)); m_CatActionSel.AppendMenu(MF_STRING, MP_SCHACTIONS + 21, GetResString(IDS_ALL)); - for (int i = 1; i < thePrefs.GetCatCount(); ++i) + for (INT_PTR i = 1; i < thePrefs.GetCatCount(); ++i) m_CatActionSel.AppendMenu(MF_STRING, MP_SCHACTIONS + 22 + i, thePrefs.GetCategory(i)->strTitle); m_ActionMenu.AppendMenu(MF_POPUP, (UINT_PTR)m_CatActionSel.m_hMenu, GetResString(IDS_SELECTCAT)); } else diff --git a/srchybrid/PPgScheduler.h b/srchybrid/PPgScheduler.h index 8a8471e7..7179ca68 100644 --- a/srchybrid/PPgScheduler.h +++ b/srchybrid/PPgScheduler.h @@ -11,7 +11,6 @@ class CPPgScheduler : public CPropertyPage public: CPPgScheduler(); - virtual ~CPPgScheduler() = default; void Localize(); diff --git a/srchybrid/PPgSecurity.cpp b/srchybrid/PPgSecurity.cpp index 51a3d628..056de2a5 100644 --- a/srchybrid/PPgSecurity.cpp +++ b/srchybrid/PPgSecurity.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -212,7 +212,7 @@ void CPPgSecurity::OnReloadIPFilter() void CPPgSecurity::OnEditIPFilter() { - ShellOpen(thePrefs.GetTxtEditor(), _T('\"') + thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + DFLT_IPFILTER_FILENAME + _T('\"')); + ShellOpen(thePrefs.GetTxtEditor(), _T('"') + CIPFilter::GetDefaultFilePath() + _T('"')); } void CPPgSecurity::OnLoadIPFFromURL() @@ -225,8 +225,9 @@ void CPPgSecurity::OnLoadIPFFromURL() if (m_pacIPFilterURL && m_pacIPFilterURL->IsBound()) m_pacIPFilterURL->AddItem(url, 0); + const CString &sConfDir(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); CString strTempFilePath; - _tmakepathlimit(strTempFilePath.GetBuffer(MAX_PATH), NULL, thePrefs.GetMuleDirectory(EMULE_CONFIGDIR), DFLT_IPFILTER_FILENAME, _T("tmp")); + _tmakepathlimit(strTempFilePath.GetBuffer(MAX_PATH), NULL, sConfDir, DFLT_IPFILTER_FILENAME, _T("tmp")); strTempFilePath.ReleaseBuffer(); CHttpDownloadDlg dlgDownload; @@ -259,7 +260,7 @@ void CPPgSecurity::OnLoadIPFFromURL() } if (zfile) { CString strTempUnzipFilePath; - _tmakepathlimit(strTempUnzipFilePath.GetBuffer(_MAX_PATH), NULL, thePrefs.GetMuleDirectory(EMULE_CONFIGDIR), DFLT_IPFILTER_FILENAME, _T(".unzip.tmp")); + _tmakepathlimit(strTempUnzipFilePath.GetBuffer(MAX_PATH), NULL, sConfDir, DFLT_IPFILTER_FILENAME, _T(".unzip.tmp")); strTempUnzipFilePath.ReleaseBuffer(); if (zfile->Extract(strTempUnzipFilePath)) { @@ -297,7 +298,7 @@ void CPPgSecurity::OnLoadIPFFromURL() || strFile.CompareNoCase(_T("guardian.p2p")) == 0)) { CString strTempUnzipFilePath; - _tmakepathlimit(strTempUnzipFilePath.GetBuffer(MAX_PATH), NULL, thePrefs.GetMuleDirectory(EMULE_CONFIGDIR), DFLT_IPFILTER_FILENAME, _T(".unzip.tmp")); + _tmakepathlimit(strTempUnzipFilePath.GetBuffer(MAX_PATH), NULL, sConfDir, DFLT_IPFILTER_FILENAME, _T(".unzip.tmp")); strTempUnzipFilePath.ReleaseBuffer(); if (rar.Extract(strTempUnzipFilePath)) { rar.Close(); @@ -332,11 +333,11 @@ void CPPgSecurity::OnLoadIPFFromURL() bIsArchiveFile = true; CString strTempUnzipFilePath; - _tmakepathlimit(strTempUnzipFilePath.GetBuffer(_MAX_PATH), NULL, thePrefs.GetMuleDirectory(EMULE_CONFIGDIR), DFLT_IPFILTER_FILENAME, _T(".unzip.tmp")); + _tmakepathlimit(strTempUnzipFilePath.GetBuffer(MAX_PATH), NULL, sConfDir, DFLT_IPFILTER_FILENAME, _T(".unzip.tmp")); strTempUnzipFilePath.ReleaseBuffer(); // add filename and extension of uncompressed file to temporary file - const CString &strUncompressedFileName = gz.GetUncompressedFileName(); + const CString &strUncompressedFileName(gz.GetUncompressedFileName()); if (!strUncompressedFileName.IsEmpty()) strTempUnzipFilePath.AppendFormat(_T(".%s"), (LPCTSTR)strUncompressedFileName); @@ -366,23 +367,19 @@ void CPPgSecurity::OnLoadIPFFromURL() FILE *fp = _tfsopen(strTempFilePath, _T("rb"), _SH_DENYWR); if (fp) { char szBuff[16384]; - size_t iRead = fread(szBuff, 1, _countof(szBuff) - 1, fp); + size_t iRead = fread(szBuff, 1, sizeof szBuff - 1, fp); + fclose(fp); if (iRead <= 0) bValidIPFilterFile = false; else { szBuff[iRead - 1] = '\0'; const char *pc = szBuff; - while (*pc == ' ' || *pc == '\t' || *pc == '\r' || *pc == '\n') + while (*pc && *pc <= ' ') ++pc; - if (_strnicmp(pc, "GetIPFilter().IsEmpty()) { CString strLoaded; strLoaded.Format(GetResString(IDS_IPFILTERLOADED), theApp.ipfilter->GetIPFilter().GetCount()); - CString strError; - strError.Format(_T("%s\r\n\r\n%s"), (LPCTSTR)GetResString(IDS_DWLIPFILTERFAILED), (LPCTSTR)strLoaded); + CString strError(GetResString(IDS_DWLIPFILTERFAILED)); + strError.AppendFormat(_T("\r\n\r\n%s"), (LPCTSTR)strLoaded); AfxMessageBox(strError, MB_ICONERROR); } } diff --git a/srchybrid/PPgSecurity.h b/srchybrid/PPgSecurity.h index 06b44fc6..372c1e21 100644 --- a/srchybrid/PPgSecurity.h +++ b/srchybrid/PPgSecurity.h @@ -13,7 +13,6 @@ class CPPgSecurity : public CPropertyPage public: CPPgSecurity(); - virtual ~CPPgSecurity() = default; void Localize(); void DeleteDDB(); diff --git a/srchybrid/PPgServer.cpp b/srchybrid/PPgServer.cpp index 1b7d2ecb..b02ee578 100644 --- a/srchybrid/PPgServer.cpp +++ b/srchybrid/PPgServer.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/PPgServer.h b/srchybrid/PPgServer.h index 2743efb3..bef0d6fc 100644 --- a/srchybrid/PPgServer.h +++ b/srchybrid/PPgServer.h @@ -11,7 +11,6 @@ class CPPgServer : public CPropertyPage public: CPPgServer(); - virtual ~CPPgServer() = default; void Localize(); diff --git a/srchybrid/PPgStats.cpp b/srchybrid/PPgStats.cpp index fa3c894b..ef9c12f9 100644 --- a/srchybrid/PPgStats.cpp +++ b/srchybrid/PPgStats.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -281,13 +281,13 @@ void CPPgStats::ShowInterval() CString strLabel; if (m_iGraphsUpdate == 0) - strLabel.Format(GetResString(IDS_DISABLED)); + strLabel = GetResString(IDS_DISABLED); else strLabel.Format(GetResString(IDS_STATS_UPDATELABEL), m_iGraphsUpdate); SetDlgItemText(IDC_SLIDERINFO, strLabel); if (m_iGraphsAvgTime == 0) - strLabel.Format(GetResString(IDS_DISABLED)); + strLabel = GetResString(IDS_DISABLED); else strLabel.Format(GetResString(IDS_STATS_UPDATELABEL), m_iGraphsAvgTime); SetDlgItemText(IDC_SLIDERINFO2, strLabel); diff --git a/srchybrid/PPgStats.h b/srchybrid/PPgStats.h index a815ecfd..23f4271f 100644 --- a/srchybrid/PPgStats.h +++ b/srchybrid/PPgStats.h @@ -12,7 +12,6 @@ class CPPgStats : public CPropertyPage public: CPPgStats(); - virtual ~CPPgStats() = default; void Localize(); diff --git a/srchybrid/PPgTweaks.cpp b/srchybrid/PPgTweaks.cpp index 707fdf3d..863db425 100644 --- a/srchybrid/PPgTweaks.cpp +++ b/srchybrid/PPgTweaks.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -16,12 +16,13 @@ //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "stdafx.h" #include "emule.h" +#include "opcodes.h" +#include "OtherFunctions.h" #include "SearchDlg.h" #include "PPgTweaks.h" #include "Scheduler.h" #include "DownloadQueue.h" #include "Preferences.h" -#include "OtherFunctions.h" #include "TransferDlg.h" #include "emuledlg.h" #include "SharedFilesWnd.h" @@ -29,7 +30,6 @@ #include "HelpIDs.h" #include "Log.h" #include "UserMsgs.h" -#include "opcodes.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -299,7 +299,7 @@ void CPPgTweaks::DoDataExchange(CDataExchange *pDX) m_ctrlTreeOptions.Expand(m_htiVerboseGroup, TVE_EXPAND); m_ctrlTreeOptions.Expand(m_htiCommit, TVE_EXPAND); m_ctrlTreeOptions.Expand(m_htiCheckDiskspace, TVE_EXPAND); - m_ctrlTreeOptions.Expand(m_htiDynUp, TVE_EXPAND); + m_ctrlTreeOptions.Expand(m_htiDynUp, m_bDynUpEnabled ? TVE_EXPAND : TVE_COLLAPSE); m_ctrlTreeOptions.Expand(m_htiDynUpPingToleranceGroup, TVE_EXPAND); m_ctrlTreeOptions.Expand(m_htiExtractMetaData, TVE_EXPAND); m_ctrlTreeOptions.Expand(m_htiUPnP, TVE_EXPAND); @@ -622,14 +622,14 @@ void CPPgTweaks::OnHScroll(UINT /*nSBCode*/, UINT /*nPos*/, CScrollBar *pScrollB { if (pScrollBar->GetSafeHwnd() == m_ctlFileBuffSize.m_hWnd) { m_uFileBufferSize = m_ctlFileBuffSize.GetPos() * 1024; - CString temp; - temp.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_FILEBUFFERSIZE), (LPCTSTR)CastItoXBytes(m_uFileBufferSize)); + CString temp(GetResString(IDS_FILEBUFFERSIZE)); + temp.AppendFormat(_T(": %s"), (LPCTSTR)CastItoXBytes(m_uFileBufferSize)); SetDlgItemText(IDC_FILEBUFFERSIZE_STATIC, temp); SetModified(TRUE); } else if (pScrollBar->GetSafeHwnd() == m_ctlQueueSize.m_hWnd) { m_iQueueSize = reinterpret_cast(pScrollBar)->GetPos() * 100; - CString temp; - temp.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_QUEUESIZE), (LPCTSTR)GetFormatedUInt((ULONG)m_iQueueSize)); + CString temp(GetResString(IDS_QUEUESIZE)); + temp.AppendFormat(_T(": %s"), (LPCTSTR)GetFormatedUInt((ULONG)m_iQueueSize)); SetDlgItemText(IDC_QUEUESIZE_STATIC, temp); SetModified(TRUE); } diff --git a/srchybrid/PPgTweaks.h b/srchybrid/PPgTweaks.h index 46e12c25..0e405c47 100644 --- a/srchybrid/PPgTweaks.h +++ b/srchybrid/PPgTweaks.h @@ -14,7 +14,6 @@ class CPPgTweaks : public CPropertyPage public: CPPgTweaks(); - virtual ~CPPgTweaks() = default; void Localize(); diff --git a/srchybrid/PPgWebServer.cpp b/srchybrid/PPgWebServer.cpp index 0672ec6f..6acbf7dc 100644 --- a/srchybrid/PPgWebServer.cpp +++ b/srchybrid/PPgWebServer.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -337,12 +337,12 @@ void CPPgWebServer::OnDataChange() BOOL CPPgWebServer::OnApply() { if (m_bModified) { - CString sBuf; bool bUPnP = thePrefs.GetWSUseUPnP(); bool bWSIsEnabled = IsDlgButtonChecked(IDC_WSENABLED) != 0; // get and check template file existence... + CString sBuf; GetDlgItemText(IDC_TMPLPATH, sBuf); - if (bWSIsEnabled && !PathFileExists(sBuf)) { + if (bWSIsEnabled && !::PathFileExists(sBuf)) { CString buffer; buffer.Format(GetResString(IDS_WEB_ERR_CANTLOAD), (LPCTSTR)sBuf); AfxMessageBox(buffer, MB_OK); @@ -357,7 +357,7 @@ BOOL CPPgWebServer::OnApply() bool bHTTPS = IsDlgButtonChecked(IDC_WEB_HTTPS) != 0; GetDlgItemText(IDC_CERTPATH, sBuf); if (bWSIsEnabled && bHTTPS) { - if (!PathFileExists(sBuf)) { + if (!::PathFileExists(sBuf)) { AfxMessageBox(GetResString(IDS_CERT_NOT_FOUND), MB_OK); return FALSE; } @@ -368,7 +368,7 @@ BOOL CPPgWebServer::OnApply() GetDlgItemText(IDC_KEYPATH, sBuf); if (bWSIsEnabled && bHTTPS) { - if (!PathFileExists(sBuf)) { + if (!::PathFileExists(sBuf)) { AfxMessageBox(GetResString(IDS_KEY_NOT_FOUND), MB_OK); return FALSE; } @@ -510,7 +510,7 @@ void CPPgWebServer::OnBnClickedTmplbrowse() //create cert.key and cert.crt in config directory void CPPgWebServer::OnGenerateCertificate() { - if (InterlockedExchange(&m_generating, 1)) + if (::InterlockedExchange(&m_generating, 1)) return; CWaitCursor curWaiting; @@ -543,7 +543,7 @@ void CPPgWebServer::OnGenerateCertificate() } else { LogError(_T("Certificate creation failed")); AfxMessageBox(GetResString(IDS_CERT_ERR_CREATE)); - InterlockedExchange(&m_generating, 0); //re-enable only if failed + ::InterlockedExchange(&m_generating, 0); //re-enable only if failed } } @@ -551,7 +551,8 @@ void CPPgWebServer::OnBnClickedCertbrowse() { CString strCert; GetDlgItemText(IDC_CERTPATH, strCert); - CString buffer(GetResString(IDS_CERTIFICATE) + _T(" (*.crt)|*.crt|All Files (*.*)|*.*||")); + CString buffer(GetResString(IDS_CERTIFICATE)); + buffer += _T(" (*.crt)|*.crt|All Files (*.*)|*.*||"); if (DialogBrowseFile(buffer, buffer, strCert)) SetDlgItemText(IDC_CERTPATH, buffer); if (buffer.CompareNoCase(strCert) != 0) @@ -562,7 +563,8 @@ void CPPgWebServer::OnBnClickedKeybrowse() { CString strKey; GetDlgItemText(IDC_KEYPATH, strKey); - CString buffer(GetResString(IDS_KEY) + _T(" (*.key)|*.key|All Files (*.*)|*.*||")); + CString buffer(GetResString(IDS_KEY)); + buffer += _T(" (*.key)|*.key|All Files (*.*)|*.*||"); if (DialogBrowseFile(buffer, buffer, strKey)) SetDlgItemText(IDC_KEYPATH, buffer); if (buffer.CompareNoCase(strKey) != 0) diff --git a/srchybrid/PPgWebServer.h b/srchybrid/PPgWebServer.h index 341a67c7..db4ad134 100644 --- a/srchybrid/PPgWebServer.h +++ b/srchybrid/PPgWebServer.h @@ -13,7 +13,6 @@ class CPPgWebServer : public CPropertyPage public: CPPgWebServer(); - virtual ~CPPgWebServer() = default; void Localize(); void SetUPnPState(); diff --git a/srchybrid/PShtWiz1.cpp b/srchybrid/PShtWiz1.cpp index 2d755f7d..6942b55c 100644 --- a/srchybrid/PShtWiz1.cpp +++ b/srchybrid/PShtWiz1.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -127,7 +127,6 @@ class CPPgWiz1Welcome : public CDlgPageWizard : CDlgPageWizard(nIDTemplate, pszCaption, pszHeaderTitle, pszHeaderSubTitle) { } - virtual ~CPPgWiz1Welcome() = default; virtual BOOL OnInitDialog(); protected: @@ -190,7 +189,6 @@ class CPPgWiz1General : public CDlgPageWizard : CDlgPageWizard(nIDTemplate, pszCaption, pszHeaderTitle, pszHeaderSubTitle), m_iAutoConnectAtStart(), m_iAutoStart() { } - virtual ~CPPgWiz1General() = default; virtual BOOL OnInitDialog(); CString m_strNick; @@ -251,6 +249,9 @@ class CPPgWiz1Ports : public CDlgPageWizard CPPgWiz1Ports(); explicit CPPgWiz1Ports(UINT nIDTemplate, LPCTSTR pszCaption = NULL, LPCTSTR pszHeaderTitle = NULL, LPCTSTR pszHeaderSubTitle = NULL) : CDlgPageWizard(nIDTemplate, pszCaption, pszHeaderTitle, pszHeaderSubTitle) + , m_lastudp() + , m_uTCP() + , m_uUDP() , m_pbUDPDisabled() , m_nUPnPTicks() { @@ -258,7 +259,6 @@ class CPPgWiz1Ports : public CDlgPageWizard // void ValidateShownPorts(); - virtual ~CPPgWiz1Ports() = default; virtual BOOL OnInitDialog(); afx_msg void OnStartConTest(); afx_msg void OnStartUPnP(); @@ -303,6 +303,8 @@ END_MESSAGE_MAP() CPPgWiz1Ports::CPPgWiz1Ports() : CDlgPageWizard(CPPgWiz1Ports::IDD) , m_lastudp() + , m_uTCP() + , m_uUDP() , m_pbUDPDisabled() , m_nUPnPTicks() { @@ -496,7 +498,6 @@ class CPPgWiz1UlPrio : public CDlgPageWizard : CDlgPageWizard(nIDTemplate, pszCaption, pszHeaderTitle, pszHeaderSubTitle), m_iUAP(1), m_iDAP(1) { } - virtual ~CPPgWiz1UlPrio() = default; virtual BOOL OnInitDialog(); int m_iUAP; @@ -556,7 +557,6 @@ class CPPgWiz1Upload : public CDlgPageWizard : CDlgPageWizard(nIDTemplate, pszCaption, pszHeaderTitle, pszHeaderSubTitle), m_iObfuscation() { } - virtual ~CPPgWiz1Upload() = default; virtual BOOL OnInitDialog(); int m_iObfuscation; @@ -612,7 +612,6 @@ class CPPgWiz1Server : public CDlgPageWizard , m_iSafeServerConnect(), m_iKademlia(1), m_iED2K(1), m_pbUDPDisabled() { } - virtual ~CPPgWiz1Server() = default; virtual BOOL OnInitDialog(); int m_iSafeServerConnect; @@ -689,7 +688,6 @@ class CPPgWiz1End : public CDlgPageWizard : CDlgPageWizard(nIDTemplate, pszCaption, pszHeaderTitle, pszHeaderSubTitle) { } - virtual ~CPPgWiz1End() = default; virtual BOOL OnInitDialog(); protected: @@ -745,7 +743,6 @@ class CPShtWiz1 : public CPropertySheetEx public: explicit CPShtWiz1(UINT nIDCaption, CWnd *pParentWnd = NULL, UINT iSelectPage = 0); - virtual ~CPShtWiz1() = default; protected: DECLARE_MESSAGE_MAP() diff --git a/srchybrid/Packets.cpp b/srchybrid/Packets.cpp index 5f378fb9..43d91de1 100644 --- a/srchybrid/Packets.cpp +++ b/srchybrid/Packets.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -85,7 +85,7 @@ Packet::Packet(uint8 in_opcode, uint32 in_size, uint8 protocol, bool bFromPartFi { init(); if (in_size) { - completebuffer = new char[in_size + 10](); + completebuffer = new char[in_size + 10]{}; pBuffer = completebuffer + PACKET_HEADER_SIZE; } else { completebuffer = NULL; @@ -93,8 +93,8 @@ Packet::Packet(uint8 in_opcode, uint32 in_size, uint8 protocol, bool bFromPartFi } } -Packet::Packet(CMemFile *datafile, uint8 protocol, uint8 ucOpcode) - : size(static_cast(datafile->GetLength())) +Packet::Packet(CSafeMemFile &datafile, uint8 protocol, uint8 ucOpcode) + : size(static_cast(datafile.GetLength())) , opcode(ucOpcode) , prot(protocol) , m_bSplitted() @@ -104,7 +104,7 @@ Packet::Packet(CMemFile *datafile, uint8 protocol, uint8 ucOpcode) init(); completebuffer = new char[size + 10]; pBuffer = completebuffer + PACKET_HEADER_SIZE; - BYTE *tmp = datafile->Detach(); + BYTE *tmp = datafile.Detach(); memcpy(pBuffer, tmp, size); free(tmp); } @@ -186,14 +186,14 @@ char* Packet::DetachPacket() char* Packet::GetHeader() { ASSERT(!m_bSplitted); - *reinterpret_cast(head) = Header_Struct{prot, size + 1, opcode}; + *reinterpret_cast(head) = Header_Struct{ prot, size + 1, opcode }; return head; } char* Packet::GetUDPHeader() { ASSERT(!m_bSplitted); - *reinterpret_cast(head) = UDP_Header_Struct{prot, opcode}; + *reinterpret_cast(head) = UDP_Header_Struct{ prot, opcode }; return head; } @@ -318,7 +318,7 @@ char* CRawPacket::DetachPacket() // CTag CTag::CTag(LPCSTR pszName, uint64 uVal, bool bInt64) - : m_szName(pszName) + : m_sName(pszName) , m_nBlobSize() , m_uType(bInt64 ? TAGTYPE_UINT64 : TAGTYPE_UINT32) , m_uName() @@ -339,7 +339,7 @@ CTag::CTag(uint8 uName, uint64 uVal, bool bInt64) } CTag::CTag(LPCSTR pszName, LPCTSTR pszVal) - : m_szName(pszName) + : m_sName(pszName) , m_nBlobSize() , m_uType(TAGTYPE_STRING) , m_uName() @@ -358,7 +358,7 @@ CTag::CTag(uint8 uName, LPCTSTR pszVal) } CTag::CTag(LPCSTR pszName, const CString &rstrVal) - : m_szName(pszName) + : m_sName(pszName) , m_nBlobSize() , m_uType(TAGTYPE_STRING) , m_uName() @@ -406,7 +406,7 @@ CTag::CTag(uint8 uName, BYTE *pucAttachData, uint32 nSize) } CTag::CTag(const CTag &rTag) - : m_szName(rTag.m_szName) + : m_sName(rTag.m_sName) , m_nBlobSize() , m_uType(rTag.m_uType) , m_uName(rTag.m_uName) @@ -431,25 +431,25 @@ CTag::CTag(const CTag &rTag) ASSERT_VALID(this); } -CTag::CTag(CFileDataIO *data, bool bOptUTF8) +CTag::CTag(CFileDataIO &data, bool bOptUTF8) { - m_uType = data->ReadUInt8(); + m_uType = data.ReadUInt8(); if (m_uType & 0x80) { m_uType &= 0x7F; - m_uName = data->ReadUInt8(); + m_uName = data.ReadUInt8(); } else { - UINT length = data->ReadUInt16(); + UINT length = data.ReadUInt16(); if (length == 1) - m_uName = data->ReadUInt8(); + m_uName = data.ReadUInt8(); else { m_uName = 0; - LPSTR p = m_szName.GetBuffer(length); + LPSTR p = m_sName.GetBuffer(length); try { - data->Read(p, length); + data.Read(p, length); } catch (...) { throw; } - m_szName.ReleaseBuffer(length); + m_sName.ReleaseBuffer(length); } } @@ -459,43 +459,43 @@ CTag::CTag(CFileDataIO *data, bool bOptUTF8) // not use each tag. Otherwise we will get troubles when the packets are returned in // a list - like the search results from a server. if (m_uType == TAGTYPE_STRING) - m_pstrVal = new CString(data->ReadString(bOptUTF8)); + m_pstrVal = new CString(data.ReadString(bOptUTF8)); else if (m_uType == TAGTYPE_UINT32) - m_uVal = data->ReadUInt32(); + m_uVal = data.ReadUInt32(); else if (m_uType == TAGTYPE_UINT64) - m_uVal = data->ReadUInt64(); + m_uVal = data.ReadUInt64(); else if (m_uType == TAGTYPE_UINT16) { - m_uVal = data->ReadUInt16(); + m_uVal = data.ReadUInt16(); m_uType = TAGTYPE_UINT32; } else if (m_uType == TAGTYPE_UINT8) { - m_uVal = data->ReadUInt8(); + m_uVal = data.ReadUInt8(); m_uType = TAGTYPE_UINT32; } else if (m_uType == TAGTYPE_FLOAT32) - data->Read(&m_fVal, 4); + data.Read(&m_fVal, 4); else if (m_uType >= TAGTYPE_STR1 && m_uType <= TAGTYPE_STR16) { UINT length = m_uType - TAGTYPE_STR1 + 1; - m_pstrVal = new CString(data->ReadString(bOptUTF8, length)); + m_pstrVal = new CString(data.ReadString(bOptUTF8, length)); m_uType = TAGTYPE_STRING; } else if (m_uType == TAGTYPE_HASH) { BYTE bHash[MDX_DIGEST_SIZE]; - data->Read(bHash, MDX_DIGEST_SIZE); + data.Read(bHash, MDX_DIGEST_SIZE); m_pData = new BYTE[MDX_DIGEST_SIZE]; md4cpy(m_pData, bHash); } else if (m_uType == TAGTYPE_BOOL) { TRACE("***NOTE: %s; Reading BOOL tag\n", __FUNCTION__); - data->Seek(1, CFile::current); + data.Seek(1, CFile::current); } else if (m_uType == TAGTYPE_BOOLARRAY) { TRACE("***NOTE: %s; Reading BOOL Array tag\n", __FUNCTION__); uint16 len; - data->Read(&len, 2); + data.Read(&len, 2); // 07-Apr-2004: eMule versions prior to 0.42e.29 used the formula "(len+7)/8"! - data->Seek((len / 8) + 1ll, CFile::current); + data.Seek((len / 8) + 1ll, CFile::current); } else if (m_uType == TAGTYPE_BLOB) { // 07-Apr-2004: eMule versions prior to 0.42e.29 handled the "len" as int16! - m_nBlobSize = data->ReadUInt32(); - if (m_nBlobSize <= data->GetLength() - data->GetPosition()) { + m_nBlobSize = data.ReadUInt32(); + if (m_nBlobSize <= data.GetLength() - data.GetPosition()) { m_pData = new BYTE[m_nBlobSize]; - data->Read(m_pData, m_nBlobSize); + data.Read(m_pData, m_nBlobSize); } else { ASSERT(0); m_nBlobSize = 0; @@ -505,7 +505,7 @@ CTag::CTag(CFileDataIO *data, bool bOptUTF8) if (m_uName != 0) TRACE("%s; Unknown tag: type=0x%02X specialtag=%u\n", __FUNCTION__, m_uType, m_uName); else - TRACE("%s; Unknown tag: type=0x%02X name=\"%s\"\n", __FUNCTION__, m_uType, (LPCSTR)m_szName); + TRACE("%s; Unknown tag: type=0x%02X name=\"%s\"\n", __FUNCTION__, m_uType, (LPCSTR)m_sName); m_uVal = 0; } ASSERT_VALID(this); @@ -523,7 +523,7 @@ CTag& CTag::operator=(const CTag &rTag) m_nBlobSize = 0; m_uType = rTag.m_uType; m_uName = rTag.m_uName; - m_szName = rTag.m_szName; + m_sName = rTag.m_sName; if (rTag.IsStr()) m_pstrVal = new CString(rTag.GetStr()); else if (rTag.IsInt()) @@ -547,7 +547,7 @@ CTag& CTag::operator=(const CTag &rTag) return *this; } -bool CTag::WriteNewEd2kTag(CFileDataIO *data, EUTF8str eStrEncode) const +bool CTag::WriteNewEd2kTag(CFileDataIO &data, EUTF8str eStrEncode) const { ASSERT_VALID(this); @@ -589,44 +589,44 @@ bool CTag::WriteNewEd2kTag(CFileDataIO *data, EUTF8str eStrEncode) const uType = m_uType; // Write tag name - if (m_szName.IsEmpty()) { - ASSERT(m_uName != 0); - data->WriteUInt8(uType | 0x80); - data->WriteUInt8(m_uName); + if (m_sName.IsEmpty()) { + ASSERT(m_uName); + data.WriteUInt8(uType | 0x80); + data.WriteUInt8(m_uName); } else { - data->WriteUInt8(uType); - UINT uTagNameLen = (UINT)m_szName.GetLength(); - data->WriteUInt16((uint16)uTagNameLen); - data->Write(m_szName, uTagNameLen); + data.WriteUInt8(uType); + UINT uTagNameLen = (UINT)m_sName.GetLength(); + data.WriteUInt16((uint16)uTagNameLen); + data.Write(m_sName, uTagNameLen); } // Write tag data switch (uType) { case TAGTYPE_STRING: - data->WriteUInt16((uint16)uStrValLen); - data->Write((void*)(LPCSTR)strValA, uStrValLen); + data.WriteUInt16((uint16)uStrValLen); + data.Write((void*)(LPCSTR)strValA, uStrValLen); break; case TAGTYPE_UINT64: - data->WriteUInt64(m_uVal); + data.WriteUInt64(m_uVal); break; case TAGTYPE_UINT32: - data->WriteUInt32((uint32)m_uVal); + data.WriteUInt32((uint32)m_uVal); break; case TAGTYPE_UINT16: - data->WriteUInt16((uint16)m_uVal); + data.WriteUInt16((uint16)m_uVal); break; case TAGTYPE_UINT8: - data->WriteUInt8((uint8)m_uVal); + data.WriteUInt8((uint8)m_uVal); break; case TAGTYPE_FLOAT32: - data->Write(&m_fVal, 4); + data.Write(&m_fVal, 4); break; case TAGTYPE_HASH: - data->WriteHash16(m_pData); + data.WriteHash16(m_pData); break; case TAGTYPE_BLOB: - data->WriteUInt32(m_nBlobSize); - data->Write(m_pData, m_nBlobSize); + data.WriteUInt32(m_nBlobSize); + data.Write(m_pData, m_nBlobSize); break; default: if (uType < TAGTYPE_STR1 || uType > TAGTYPE_STR16) { @@ -634,42 +634,42 @@ bool CTag::WriteNewEd2kTag(CFileDataIO *data, EUTF8str eStrEncode) const ASSERT(0); return false; } - data->Write((void*)(LPCSTR)strValA, uStrValLen); + data.Write((void*)(LPCSTR)strValA, uStrValLen); } return true; } -bool CTag::WriteTagToFile(CFileDataIO *file, EUTF8str eStrEncode) const +bool CTag::WriteTagToFile(CFileDataIO &file, EUTF8str eStrEncode) const { ASSERT_VALID(this); // don't write tags of unknown types, we wouldn't be able to read in them, // and the met file would be corrupted if (IsStr() || IsInt64() || IsFloat() || IsBlob()) { - file->WriteUInt8(m_uType); + file.WriteUInt8(m_uType); - if (m_szName.IsEmpty()) { - file->WriteUInt16(1); - file->WriteUInt8(m_uName); + if (m_sName.IsEmpty()) { + file.WriteUInt16(1); + file.WriteUInt8(m_uName); } else { - UINT taglen = (UINT)m_szName.GetLength(); - file->WriteUInt16((uint16)taglen); - file->Write(m_szName, taglen); + UINT taglen = (UINT)m_sName.GetLength(); + file.WriteUInt16((uint16)taglen); + file.Write(m_sName, taglen); } if (IsStr()) - file->WriteString(GetStr(), eStrEncode); + file.WriteString(GetStr(), eStrEncode); else if (IsInt()) - file->WriteUInt32((uint32)m_uVal); + file.WriteUInt32((uint32)m_uVal); else if (IsInt64(false)) - file->WriteUInt64(m_uVal); + file.WriteUInt64(m_uVal); else if (IsFloat()) - file->Write(&m_fVal, 4); + file.Write(&m_fVal, 4); else if (IsBlob()) { // NOTE: This will break backward compatibility with met files for eMule versions prior to 0.44a - file->WriteUInt32(m_nBlobSize); - file->Write(m_pData, m_nBlobSize); + file.WriteUInt32(m_nBlobSize); + file.Write(m_pData, m_nBlobSize); } else { //TODO: Support more tag types TRACE("%s; Unknown tag: type=0x%02X\n", __FUNCTION__, m_uType); @@ -711,8 +711,8 @@ void CTag::SetStr(LPCTSTR pszVal) CString CTag::GetFullInfo(CString(*pfnDbgGetFileMetaTagName)(UINT uMetaTagID)) const { CString strTag; - if (!m_szName.IsEmpty()) - strTag.Format(_T("\"%hs\"="), (LPCSTR)m_szName); + if (!m_sName.IsEmpty()) + strTag.Format(_T("\"%hs\"="), (LPCSTR)m_sName); else if (pfnDbgGetFileMetaTagName) strTag.Format(_T("\"%s\"="), (LPCTSTR)(*pfnDbgGetFileMetaTagName)(m_uName)); else @@ -755,14 +755,12 @@ void CTag::AssertValid() const CObject::AssertValid(); ASSERT((m_uType & ~0x80) != 0); - ASSERT(m_uName != 0 && m_szName.IsEmpty() || m_uName == 0 && !m_szName.IsEmpty()); - ASSERT(m_szName.IsEmpty() || AfxIsValidString(m_szName)); + ASSERT(m_uName != 0 && m_sName.IsEmpty() || m_uName == 0 && !m_sName.IsEmpty()); + ASSERT(m_sName.IsEmpty() || AfxIsValidString(m_sName)); if (IsStr()) - ASSERT(m_pstrVal != NULL && AfxIsValidString(*m_pstrVal)); - else if (IsHash()) - ASSERT(m_pData != NULL && AfxIsValidAddress(m_pData, 16)); - else if (IsBlob()) - ASSERT(m_pData != NULL && AfxIsValidAddress(m_pData, m_nBlobSize)); + ASSERT(m_pstrVal != NULL); + else if (IsHash() || IsBlob()) + ASSERT(m_pData != NULL); } void CTag::Dump(CDumpContext &dc) const diff --git a/srchybrid/Packets.h b/srchybrid/Packets.h index 0a124b3b..37ee6f9e 100644 --- a/srchybrid/Packets.h +++ b/srchybrid/Packets.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -44,7 +44,7 @@ class Packet public: explicit Packet(uint8 protocol = OP_EDONKEYPROT); explicit Packet(char *header); // only used for receiving packets - explicit Packet(CMemFile *datafile, uint8 protocol = OP_EDONKEYPROT, uint8 ucOpcode = 0x00); + explicit Packet(CSafeMemFile &datafile, uint8 protocol = OP_EDONKEYPROT, uint8 ucOpcode = 0x00); Packet(const CStringA &str, uint8 protocol, uint8 ucOpcode); Packet(uint8 in_opcode, uint32 in_size, uint8 protocol = OP_EDONKEYPROT, bool bFromPartFile = true); Packet(char *pPacketPart, uint32 nSize, bool bLast, bool bFromPartFile = true); // only used for split packets! @@ -56,7 +56,7 @@ class Packet virtual char* GetUDPHeader(); virtual char* GetPacket(); virtual char* DetachPacket(); - virtual uint32 GetRealPacketSize() const { return size + PACKET_HEADER_SIZE; } + virtual uint32 GetRealPacketSize() const { return (uint32)(size + PACKET_HEADER_SIZE); } //bool IsSplitted() const { return m_bSplitted; } //bool IsLastSplitted() const { return m_bLastSplitted; } bool IsFromPF() const { return m_bFromPF; } @@ -118,14 +118,15 @@ class CTag CTag(uint8 uName, size_t nSize, const BYTE *pucData); // data gets copied CTag(uint8 uName, BYTE *pucAttachData, uint32 nSize); // data gets attached (and deleted later on) CTag(const CTag &rTag); - CTag(CFileDataIO *data, bool bOptUTF8); + CTag(CFileDataIO &data, bool bOptUTF8); ~CTag(); CTag &operator=(const CTag &rTag); UINT GetType() const { return m_uType; } UINT GetNameID() const { return m_uName; } - LPCSTR GetName() const { return (LPCSTR)m_szName; } + LPCSTR GetName() const { return (LPCSTR)m_sName; } + bool HasName() const { return m_sName[0] != '\0'; } bool IsStr() const { return m_uType == TAGTYPE_STRING; } bool IsInt() const { return m_uType == TAGTYPE_UINT32; } bool IsFloat() const { return m_uType == TAGTYPE_FLOAT32; } @@ -147,8 +148,8 @@ class CTag //CTag *CloneTag() { return new CTag(*this); } - bool WriteTagToFile(CFileDataIO *file, EUTF8str eStrEncode = UTF8strNone) const; // old eD2K tags - bool WriteNewEd2kTag(CFileDataIO *data, EUTF8str eStrEncode = UTF8strNone) const; // new eD2K tags + bool WriteTagToFile(CFileDataIO &file, EUTF8str eStrEncode = UTF8strNone) const; // old eD2K tags + bool WriteNewEd2kTag(CFileDataIO &data, EUTF8str eStrEncode = UTF8strNone) const; // new eD2K tags CString GetFullInfo(CString(*pfnDbgGetFileMetaTagName)(UINT uMetaTagID) = NULL) const; @@ -166,7 +167,7 @@ class CTag float m_fVal; BYTE *m_pData; }; - CStringA m_szName; + CStringA m_sName; uint32 m_nBlobSize; uint8 m_uType; uint8 m_uName; diff --git a/srchybrid/Parser.cpp b/srchybrid/Parser.cpp index 697b9396..c0e1f45a 100644 --- a/srchybrid/Parser.cpp +++ b/srchybrid/Parser.cpp @@ -145,7 +145,7 @@ static char THIS_FILE[] = __FILE__; extern CStringArray g_astrParserErrors; -void ParsedSearchExpression(const CSearchExpr *pexpr); +void ParsedSearchExpression(const CSearchExpr &expr); int yyerror(LPCTSTR errstr); int yyerrorf(LPCTSTR errstr, ...); @@ -1491,7 +1491,7 @@ yyparse() case 2: { - ParsedSearchExpression((yyvsp[(1) - (2)].pexpr)); + ParsedSearchExpression(*(yyvsp[(1) - (2)].pexpr)); delete (yyvsp[(1) - (2)].pexpr); return 0; ; @@ -1501,8 +1501,8 @@ yyparse() case 3: { - CSearchExpr *pexpr = new CSearchExpr(&CSearchAttr((yyvsp[(1) - (2)].pstr))); - ParsedSearchExpression(pexpr); + CSearchExpr *pexpr = new CSearchExpr(CSearchAttr((yyvsp[(1) - (2)].pstr))); + ParsedSearchExpression(*pexpr); delete pexpr; delete (yyvsp[(1) - (2)].pstr); return 0; @@ -1545,7 +1545,7 @@ yyparse() case 7: { - (yyval.pexpr) = new CSearchExpr((yyvsp[(1) - (1)].pattr)); + (yyval.pexpr) = new CSearchExpr(*(yyvsp[(1) - (1)].pattr)); delete (yyvsp[(1) - (1)].pattr); ; } diff --git a/srchybrid/Parser.y b/srchybrid/Parser.y index 258dd8ec..4aa60044 100644 --- a/srchybrid/Parser.y +++ b/srchybrid/Parser.y @@ -15,7 +15,7 @@ static char THIS_FILE[] = __FILE__; extern CStringArray g_astrParserErrors; -void ParsedSearchExpression(const CSearchExpr *pexpr); +void ParsedSearchExpression(const CSearchExpr &expr); int yyerror(LPCTSTR errstr); int yyerrorf(LPCTSTR errstr, ...); @@ -74,14 +74,14 @@ action : and_searchexpr TOK_EOF * would be done and if we just 'return 0'. */ { - ParsedSearchExpression($1); + ParsedSearchExpression(*$1); delete $1; return 0; } | TOK_ED2K_LINK TOK_EOF { - CSearchExpr *pexpr = new CSearchExpr(&CSearchAttr($1)); - ParsedSearchExpression(pexpr); + CSearchExpr *pexpr = new CSearchExpr(CSearchAttr(*$1)); + ParsedSearchExpression(*pexpr); delete pexpr; delete $1; return 0; diff --git a/srchybrid/PartFile.cpp b/srchybrid/PartFile.cpp index 63f82b82..b8b2d159 100644 --- a/srchybrid/PartFile.cpp +++ b/srchybrid/PartFile.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -18,9 +18,6 @@ #include #include #include -#ifndef FSCTL_SET_SPARSE -#define FSCTL_SET_SPARSE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 49, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) -#endif #ifdef _DEBUG #include "DebugHelpers.h" #endif @@ -56,8 +53,10 @@ #include "shahashset.h" #include "PeerCacheSocket.h" #include "Log.h" -#include "CollectionViewDialog.h" #include "Collection.h" +#include "CollectionViewDialog.h" +#include "uploaddiskiothread.h" +#include "PartFileWriteThread.h" #ifndef XP_BUILD #include #endif @@ -115,21 +114,21 @@ CPartFile::CPartFile(CSearchFile *searchresult, UINT cat) default: { bool bTagAdded = false; - if (pTag->GetNameID() != 0 && !pTag->GetName()[0] && (pTag->IsStr() || pTag->IsInt())) { + if (pTag->GetNameID() != 0 && !pTag->HasName() && (pTag->IsStr() || pTag->IsInt())) { static const struct { uint8 nName; uint8 nType; } _aMetaTags[] = { - { FT_MEDIA_ARTIST, 2 }, - { FT_MEDIA_ALBUM, 2 }, - { FT_MEDIA_TITLE, 2 }, - { FT_MEDIA_LENGTH, 3 }, - { FT_MEDIA_BITRATE, 3 }, - { FT_MEDIA_CODEC, 2 }, - { FT_FILETYPE, 2 }, - { FT_FILEFORMAT, 2 } + { FT_MEDIA_ARTIST, TAGTYPE_STRING }, + { FT_MEDIA_ALBUM, TAGTYPE_STRING }, + { FT_MEDIA_TITLE, TAGTYPE_STRING }, + { FT_MEDIA_LENGTH, TAGTYPE_UINT32 }, + { FT_MEDIA_BITRATE, TAGTYPE_UINT32 }, + { FT_MEDIA_CODEC, TAGTYPE_STRING }, + { FT_FILETYPE, TAGTYPE_STRING }, + { FT_FILEFORMAT, TAGTYPE_STRING } }; for (unsigned t = 0; t < _countof(_aMetaTags); ++t) { if (pTag->GetType() == _aMetaTags[t].nType && pTag->GetNameID() == _aMetaTags[t].nName) { @@ -137,7 +136,7 @@ CPartFile::CPartFile(CSearchFile *searchresult, UINT cat) if (pTag->IsStr() && pTag->GetStr().IsEmpty()) break; - // skip integer tags with '0' values + // skip integer tags with zero values if (pTag->IsInt() && pTag->GetInt() == 0) break; @@ -164,11 +163,11 @@ CPartFile::CPartFile(const CString &edonkeylink, UINT cat) CED2KLink *pLink = NULL; try { pLink = CED2KLink::CreateLinkFromUrl(edonkeylink); - _ASSERT(pLink != 0); + ASSERT(pLink); CED2KFileLink *pFileLink = pLink->GetFileLink(); - if (pFileLink == 0) + if (!pFileLink) throw GetResString(IDS_ERR_NOTAFILELINK); - InitializeFromLink(pFileLink, cat); + InitializeFromLink(*pFileLink, cat); } catch (const CString &error) { CString strMsg; strMsg.Format(GetResString(IDS_ERR_INVALIDLINK), (LPCTSTR)error); @@ -178,36 +177,42 @@ CPartFile::CPartFile(const CString &edonkeylink, UINT cat) delete pLink; } -void CPartFile::InitializeFromLink(CED2KFileLink *fileLink, UINT cat) +void CPartFile::InitializeFromLink(const CED2KFileLink &fileLink, UINT cat) { Init(); - try { - CPartFile::SetFileName(fileLink->GetName(), true, true); - CPartFile::SetFileSize(fileLink->GetSize()); - m_FileIdentifier.SetMD4Hash(fileLink->GetHashKey()); - if (fileLink->HasValidAICHHash()) { - m_FileIdentifier.SetAICHHash(fileLink->GetAICHHash()); - m_pAICHRecoveryHashSet->SetMasterHash(fileLink->GetAICHHash(), AICH_VERIFIED); - } - if (!theApp.downloadqueue->IsFileExisting(m_FileIdentifier.GetMD4Hash())) { - if (fileLink->m_hashset && fileLink->m_hashset->GetLength() > 0) { - try { - if (!m_FileIdentifier.LoadMD4HashsetFromFile(fileLink->m_hashset, true)) { - ASSERT(m_FileIdentifier.GetRawMD4HashSet().IsEmpty()); - AddDebugLogLine(false, _T("eD2K link \"%s\" specified with invalid hashset"), fileLink->GetName()); - } else - m_bMD4HashsetNeeded = false; - } catch (CFileException *e) { - TCHAR szError[MAX_CFEXP_ERRORMSG]; - GetExceptionMessage(*e, szError, _countof(szError)); - AddDebugLogLine(false, _T("Error: Failed to process hashset for eD2K link \"%s\" - %s"), fileLink->GetName(), szError); - e->Delete(); - } + + CPartFile::SetFileName(fileLink.GetName(), true, true); + CPartFile::SetFileSize(fileLink.GetSize()); + m_FileIdentifier.SetMD4Hash(fileLink.GetHashKey()); + if (fileLink.HasValidAICHHash()) { + m_FileIdentifier.SetAICHHash(fileLink.GetAICHHash()); + m_pAICHRecoveryHashSet->SetMasterHash(fileLink.GetAICHHash(), AICH_VERIFIED); + } + if (!theApp.downloadqueue->IsFileExisting(m_FileIdentifier.GetMD4Hash())) { + if (fileLink.m_hashset && fileLink.m_hashset->GetLength() > 0) { + try { + if (!m_FileIdentifier.LoadMD4HashsetFromFile(*fileLink.m_hashset, true)) { + ASSERT(m_FileIdentifier.GetRawMD4HashSet().IsEmpty()); + AddDebugLogLine(false, _T("eD2K link \"%s\" specified with invalid hashset"), fileLink.GetName()); + } else + m_bMD4HashsetNeeded = false; + } catch (CFileException *e) { + TCHAR szError[MAX_CFEXP_ERRORMSG]; + GetExceptionMessage(*e, szError, _countof(szError)); + AddDebugLogLine(false, _T("Error: Failed to process hashset for eD2K link \"%s\" - %s"), fileLink.GetName(), szError); + e->Delete(); } - CreatePartFile(cat); - m_category = cat; - } else - SetStatus(PS_ERROR); + } + CreatePartFile(cat); + m_category = cat; + } else + SetStatus(PS_ERROR); +} + +CPartFile::CPartFile(const CED2KFileLink &fileLink, UINT cat) +{ + try { + InitializeFromLink(fileLink, cat); } catch (const CString &error) { CString strMsg; strMsg.Format(GetResString(IDS_ERR_INVALIDLINK), (LPCTSTR)error); @@ -216,11 +221,6 @@ void CPartFile::InitializeFromLink(CED2KFileLink *fileLink, UINT cat) } } -CPartFile::CPartFile(CED2KFileLink *fileLink, UINT cat) -{ - InitializeFromLink(fileLink, cat); -} - void CPartFile::Init() { m_uRating = 0; @@ -233,7 +233,8 @@ void CPartFile::Init() m_DeadSourceList.Init(false); lastseencomplete = 0; - m_iAllocinfo = 0; + m_hWrite = INVALID_HANDLE_VALUE; + m_iWrites = 0; m_LastSearchTime = 0; m_LastSearchTimeKad = 0; memset(src_stats, 0, sizeof src_stats); @@ -245,7 +246,6 @@ void CPartFile::Init() srcarevisible = false; m_bMD4HashsetNeeded = true; - m_AllocateThread = NULL; m_pAICHRecoveryHashSet = new CAICHRecoveryHashSet(this); m_percentcompleted = 0; m_completedsize = 0ull; @@ -259,12 +259,12 @@ void CPartFile::Init() m_tLastModified = (time_t)-1; m_tCreated = 0; m_uFileOpProgress = 0; - lastSwapForSourceExchangeTick = lastpurgetime = ::GetTickCount(); + lastSwapForSourceExchangeTick = m_lastpurgetime = ::GetTickCount(); m_lastRefreshedDLDisplay = 0; m_nLastBufferFlushTime = 0; - m_nFlushLimitMs = thePrefs.GetFileBufferTimeLimit() + (DWORD)(rand() / (RAND_MAX / SEC2MS(2))); + m_nFileFlushTime = 0; //nothing to flush m_dwFileAttributes = 0; - m_random_update_wait = (DWORD)(rand() / (RAND_MAX / SEC2MS(1))); + m_random_update_wait = (DWORD)(rand() % SEC2MS(1)); memset(m_anStates, 0, sizeof m_anStates); m_category = 0; m_uMaxSources = 0; @@ -278,8 +278,8 @@ void CPartFile::Init() m_refresh = 0; m_iDownPriority = m_iDownPriority ? PR_HIGH : PR_NORMAL; m_paused = false; - m_bPauseOnPreview = false; m_stopped = false; + m_bPauseOnPreview = false; m_insufficient = false; m_bCompletionError = false; m_bAICHPartHashsetNeeded = true; @@ -291,33 +291,20 @@ void CPartFile::Init() CPartFile::~CPartFile() { // Barry - Ensure all buffered data is written - try { - if (IsAllocating()) { - HANDLE hThread = m_AllocateThread->m_hThread; - // 2 minutes to let the thread finish - if (::WaitForSingleObject(hThread, MIN2MS(2)) == WAIT_TIMEOUT) - ::TerminateThread(hThread, 100); - } - if (m_hpartfile.m_hFile != INVALID_HANDLE_VALUE) - FlushBuffer(true, false, true); - } catch (CFileException *e) { - e->Delete(); - } - - if (m_hpartfile.m_hFile != INVALID_HANDLE_VALUE) { + if ((HANDLE)m_hpartfile != INVALID_HANDLE_VALUE) { // commit file and directory entry + FlushBuffer(false, true); + CPartFileWriteThread::RemFile(this); m_hpartfile.Close(); // Update met file (with the current directory entry) SavePartFile(); - } - - while (!m_gaplist.IsEmpty()) - delete m_gaplist.RemoveHead(); + } else + CPartFileWriteThread::RemFile(this); while (!m_BufferedData_list.IsEmpty()) { - const PartFileBufferedData *cur_block = m_BufferedData_list.RemoveHead(); - delete[] cur_block->data; - delete cur_block; + const PartFileBufferedData *item = m_BufferedData_list.RemoveHead(); + delete[] item->data; + delete item; } delete m_pAICHRecoveryHashSet; } @@ -327,58 +314,59 @@ void CPartFile::AssertValid() const { CKnownFile::AssertValid(); - (void)m_LastSearchTime; - (void)m_LastSearchTimeKad; - (void)m_TotalSearchesKad; srclist.AssertValid(); A4AFsrclist.AssertValid(); (void)lastseencomplete; m_hpartfile.AssertValid(); m_FileCompleteMutex.AssertValid(); + (void)m_LastSearchTime; + (void)m_LastSearchTimeKad; (void)src_stats; (void)net_stats; + (void)m_TotalSearchesKad; CHECK_BOOL(m_bPreviewing); CHECK_BOOL(m_bRecoveringArchive); CHECK_BOOL(m_bLocalSrcReqQueued); CHECK_BOOL(srcarevisible); CHECK_BOOL(m_bMD4HashsetNeeded); - CHECK_BOOL(m_bAICHPartHashsetNeeded); - (void)m_iLastPausePurge; - (void)m_refresh; - (void)m_anStates; + (void)s_LoadBar; + (void)s_ChunkBar; + m_gaplist.AssertValid(); + requestedblocks_list.AssertValid(); + m_BufferedData_list.AssertValid(); + m_SrcPartFrequency.AssertValid(); + corrupted_list.AssertValid(); + m_aChangedPart.AssertValid(); + m_downloadingSourceList.AssertValid(); + (void)m_fullname; + (void)m_partmetfilename; + ASSERT(m_percentcompleted >= 0.0F && m_percentcompleted <= 100.0F); ASSERT(m_completedsize <= (uint64)m_nFileSize); + (void)m_uTransferred; (void)m_uCorruptionLoss; (void)m_uCompressionGain; + (void)m_nTotalBufferData; + (void)m_iLastPausePurge; + (void)m_lastRefreshedDLDisplay; + (void)m_nLastBufferFlushTime; + (void)m_dwFileAttributes; + (void)m_anStates; + (void)m_category; + (void)availablePartsCount; + (void)m_ClientSrcAnswered; + (void)m_lastpurgetime; + (void)m_LastNoNeededCheck; (void)m_uPartsSavedDueICH; (void)m_datarate; - (void)m_fullname; - (void)m_partmetfilename; - (void)m_uTransferred; + ASSERT(status == PS_READY || status == PS_EMPTY || status == PS_WAITINGFORHASH || status == PS_ERROR || status == PS_COMPLETING || status == PS_COMPLETE); + (void)m_refresh; + ASSERT(m_iDownPriority == PR_LOW || m_iDownPriority == PR_NORMAL || m_iDownPriority == PR_HIGH); CHECK_BOOL(m_paused); CHECK_BOOL(m_stopped); CHECK_BOOL(m_insufficient); CHECK_BOOL(m_bCompletionError); - ASSERT(m_iDownPriority == PR_LOW || m_iDownPriority == PR_NORMAL || m_iDownPriority == PR_HIGH); + CHECK_BOOL(m_bAICHPartHashsetNeeded); CHECK_BOOL(m_bAutoDownPriority); - ASSERT(status == PS_READY || status == PS_EMPTY || status == PS_WAITINGFORHASH || status == PS_ERROR || status == PS_COMPLETING || status == PS_COMPLETE); - (void)lastpurgetime; - (void)m_LastNoNeededCheck; - m_gaplist.AssertValid(); - requestedblocks_list.AssertValid(); - m_SrcPartFrequency.AssertValid(); - ASSERT(m_percentcompleted >= 0.0F && m_percentcompleted <= 100.0F); - corrupted_list.AssertValid(); - (void)availablePartsCount; - (void)m_ClientSrcAnswered; - (void)s_LoadBar; - (void)s_ChunkBar; - (void)m_lastRefreshedDLDisplay; - m_downloadingSourceList.AssertValid(); - m_BufferedData_list.AssertValid(); - (void)m_nTotalBufferData; - (void)m_nLastBufferFlushTime; - (void)m_category; - (void)m_dwFileAttributes; } void CPartFile::Dump(CDumpContext &dc) const @@ -387,7 +375,6 @@ void CPartFile::Dump(CDumpContext &dc) const } #endif - void CPartFile::CreatePartFile(UINT cat) { if ((uint64)m_nFileSize > MAX_EMULE_FILE_SIZE) { @@ -397,48 +384,57 @@ void CPartFile::CreatePartFile(UINT cat) } // decide which temp folder to use - const CString &tempdirtouse = theApp.downloadqueue->GetOptimalTempDir(cat, GetFileSize()); + const CString &tempdirtouse(theApp.downloadqueue->GetOptimalTempDir(cat, m_nFileSize)); - // use lowest free part file number for a file name (InterCeptor) + // use the lowest free part file number for a file name (InterCeptor) CString filename; int i = 0; do - filename.Format(_T("%s\\%03i.part"), (LPCTSTR)tempdirtouse, ++i); - while (PathFileExists(filename)); - m_partmetfilename.Format(_T("%03i.part.met"), i); + filename.Format(_T("%s%03i.part"), (LPCTSTR)tempdirtouse, ++i); + while (::PathFileExists(filename)); SetPath(tempdirtouse); - m_fullname.Format(_T("%s\\%s"), (LPCTSTR)tempdirtouse, (LPCTSTR)m_partmetfilename); + m_partmetfilename.Format(_T("%03i.part.met"), i); + m_fullname.Format(_T("%s%s"), (LPCTSTR)tempdirtouse, (LPCTSTR)m_partmetfilename); + const CString &partfull(RemoveFileExtension(m_fullname)); + SetFilePath(partfull); + + if (!m_hpartfile.Open(partfull, CFile::modeCreate | CFile::modeReadWrite | CFile::shareDenyNone | CFile::osSequentialScan)) { + LogError(LOG_STATUSBAR, GetResString(IDS_ERR_CREATEPARTFILE)); + SetStatus(PS_ERROR); + return; + } - CTag *partnametag = new CTag(FT_PARTFILENAME, RemoveFileExtension(m_partmetfilename)); + CTag* partnametag = new CTag(FT_PARTFILENAME, RemoveFileExtension(m_partmetfilename)); m_taglist.Add(partnametag); AddGap(0, (uint64)m_nFileSize - 1); - const CString &partfull(RemoveFileExtension(m_fullname)); - SetFilePath(partfull); - if (!m_hpartfile.Open(partfull, CFile::modeCreate | CFile::modeReadWrite | CFile::shareDenyWrite | CFile::osSequentialScan)) { - LogError(LOG_STATUSBAR, GetResString(IDS_ERR_CREATEPARTFILE)); - SetStatus(PS_ERROR); - } else { - if (thePrefs.GetSparsePartFiles()) { - DWORD dwReturnedBytes = 0; - if (!DeviceIoControl(m_hpartfile.m_hFile, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dwReturnedBytes, NULL)) { - // Errors: - // ERROR_INVALID_FUNCTION returned by WinXP when attempting to create a sparse file on a FAT32 partition - DWORD dwError = ::GetLastError(); - if (dwError != ERROR_INVALID_FUNCTION && thePrefs.GetVerboseLogPriority() <= DLP_VERYLOW) - DebugLogError(_T("Failed to apply NTFS sparse file attribute to file \"%s\" - %s"), (LPCTSTR)partfull, (LPCTSTR)GetErrorMessage(dwError, 1)); - } + if (thePrefs.GetSparsePartFiles()) { + DWORD dwReturnedBytes; + if (!DeviceIoControl((HANDLE)m_hpartfile, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dwReturnedBytes, NULL)) { + // Errors: + // ERROR_INVALID_FUNCTION returned by WinXP when attempting to create a sparse file on a FAT32 partition + DWORD dwError = ::GetLastError(); + if (dwError != ERROR_INVALID_FUNCTION && thePrefs.GetVerboseLogPriority() <= DLP_VERYLOW) + DebugLogError(_T("Failed to apply NTFS sparse file attribute to file \"%s\" - %s"), (LPCTSTR)partfull, (LPCTSTR)GetErrorMessage(dwError, 1)); } + } - struct _stat64 fileinfo; - if (statUTC(partfull, fileinfo) == 0) { - m_tLastModified = (time_t)fileinfo.st_mtime; - m_tCreated = (time_t)fileinfo.st_ctime; - } else - AddDebugLogLine(false, _T("Failed to get file date for \"%s\" - %s"), (LPCTSTR)partfull, _tcserror(errno)); + FILETIME ft_ctime, ft_mtime; + if (GetFileTime((HANDLE)m_hpartfile, &ft_ctime, (LPFILETIME)NULL, &ft_mtime)) { + m_tCreated = (time_t)FileTimeToUnixTime(ft_ctime); + m_tLastModified = (time_t)FileTimeToUnixTime(ft_mtime); + if (m_tLastModified - m_tCreated > 1) { //tunnelling! + m_tCreated = m_tLastModified; + //fix creation time + VERIFY(SetFileTime((HANDLE)m_hpartfile, &ft_mtime, (LPFILETIME)NULL, (LPFILETIME)NULL)); + } + } else { + m_tCreated = m_tLastModified = time(NULL); + AddDebugLogLine(false, _T("Failed to get file date for \"%s\" - %s"), (LPCTSTR)partfull, _tcserror(errno)); } - m_dwFileAttributes = GetFileAttributes(partfull); + + m_dwFileAttributes = ::GetFileAttributes(partfull); if (m_dwFileAttributes == INVALID_FILE_ATTRIBUTES) m_dwFileAttributes = 0; @@ -456,6 +452,7 @@ void CPartFile::CreatePartFile(UINT cat) SetFileName(CleanupFilename(GetFileName())); SavePartFile(); + m_CorruptionBlackBox.Init(m_nFileSize); SetActive(theApp.IsConnected()); } @@ -492,7 +489,7 @@ void CPartFile::CreatePartFile(UINT cat) EPartFileLoadResult CPartFile::ImportShareazaTempfile(LPCTSTR in_directory, LPCTSTR in_filename, EPartFileFormat *pOutCheckFileFormat) { CString fullname; - fullname.Format(_T("%s\\%s"), in_directory, in_filename); + fullname.Format(_T("%s%s"), in_directory, in_filename); // open the file CFile sdFile; @@ -506,7 +503,7 @@ EPartFileLoadResult CPartFile::ImportShareazaTempfile(LPCTSTR in_directory, LPCT LogError(LOG_STATUSBAR, _T("%s"), (LPCTSTR)strError); return PLR_FAILED_METFILE_NOACCESS; } - // setvbuf(sdFile.m_pStream, NULL, _IOFBF, 16384); + //::setvbuf(sdFile.m_pStream, NULL, _IOFBF, 16384); try { CArchive ar(&sdFile, CArchive::load); @@ -514,7 +511,7 @@ EPartFileLoadResult CPartFile::ImportShareazaTempfile(LPCTSTR in_directory, LPCT // Is it a valid Shareaza temp file? CHAR szID[3]; ar.Read(szID, 3); - if (strncmp(szID, "SDL", 3) != 0) { + if (memcmp(szID, "SDL", 3) != 0) { ar.Close(); if (pOutCheckFileFormat != NULL) *pOutCheckFileFormat = PMT_UNKNOWN; @@ -538,7 +535,7 @@ EPartFileLoadResult CPartFile::ImportShareazaTempfile(LPCTSTR in_directory, LPCT // Get the ed2k hash BOOL bSHA1, bTiger, Trusted, bED2K = false; - BYTE pED2K[16]; + BYTE pED2K[MDX_DIGEST_SIZE]; ar >> bSHA1; if (bSHA1) { @@ -560,7 +557,7 @@ EPartFileLoadResult CPartFile::ImportShareazaTempfile(LPCTSTR in_directory, LPCT BOOL bMD5; ar >> bMD5; if (bMD5) { - BYTE pMD5[16]; + BYTE pMD5[MDX_DIGEST_SIZE]; ar.Read(pMD5, sizeof pMD5); } } @@ -611,7 +608,7 @@ EPartFileLoadResult CPartFile::ImportShareazaTempfile(LPCTSTR in_directory, LPCT badGapList = true; break; } - AddGap(begin, begin + length - 1); + AddGap(begin, min(begin + length - 1, lSize - 1)); } } else badGapList = true; @@ -628,15 +625,14 @@ EPartFileLoadResult CPartFile::ImportShareazaTempfile(LPCTSTR in_directory, LPCT badGapList = true; break; } - AddGap(begin, begin + (length - 1ull)); + AddGap(begin, min(begin + (length - 1ull), lSize - 1)); } } else badGapList = true; } if (badGapList) { - while (!m_gaplist.IsEmpty()) - delete m_gaplist.RemoveHead(); + m_gaplist.RemoveAll(); Log(LOG_WARNING, GetResString(IDS_X_SHAREAZA_IMPORT_GAP_LIST_CORRUPT), in_filename); } @@ -711,8 +707,7 @@ EPartFileLoadResult CPartFile::ImportShareazaTempfile(LPCTSTR in_directory, LPCT return PLR_FAILED_OTHER; m_FileIdentifier.DeleteMD4Hashset(); - while (!m_gaplist.IsEmpty()) - delete m_gaplist.RemoveHead(); + m_gaplist.RemoveAll(); return LoadPartFile(in_directory, in_filename); } @@ -722,11 +717,13 @@ EPartFileLoadResult CPartFile::LoadPartFile(LPCTSTR in_directory, LPCTSTR in_fil bool isnewstyle; EPartFileFormat partmettype = PMT_UNKNOWN; - CMap gap_map; // Slugfiller + typedef CMap CGapMap; + CGapMap gap_map; // Slugfiller m_uTransferred = 0; m_partmetfilename = in_filename; SetPath(in_directory); - m_fullname.Format(_T("%s\\%s"), (LPCTSTR)GetPath(), (LPCTSTR)m_partmetfilename); + ASSERT(GetPath().Right(1) == _T("\\")); + m_fullname.Format(_T("%s%s"), (LPCTSTR)GetPath(), (LPCTSTR)m_partmetfilename); // read file data form part.met file CSafeBufferedFile metFile; @@ -740,7 +737,7 @@ EPartFileLoadResult CPartFile::LoadPartFile(LPCTSTR in_directory, LPCTSTR in_fil LogError(LOG_STATUSBAR, _T("%s"), (LPCTSTR)strError); return PLR_FAILED_METFILE_NOACCESS; } - setvbuf(metFile.m_pStream, NULL, _IOFBF, 16384); + ::setvbuf(metFile.m_pStream, NULL, _IOFBF, 16384); try { uint8 version = metFile.ReadUInt8(); @@ -773,23 +770,23 @@ EPartFileLoadResult CPartFile::LoadPartFile(LPCTSTR in_directory, LPCTSTR in_fil uint32 temp; metFile.Read(&temp, sizeof temp); - if (temp == 0) { // 0.48 partmets - different again - m_FileIdentifier.LoadMD4HashsetFromFile(&metFile, false); - } else { + if (temp == 0) // 0.48 partmets - different again + m_FileIdentifier.LoadMD4HashsetFromFile(metFile, false); + else { uchar gethash[MDX_DIGEST_SIZE]; metFile.Seek(2, CFile::begin); - LoadDateFromFile(&metFile); + LoadDateFromFile(metFile); metFile.Read(gethash, sizeof gethash); m_FileIdentifier.SetMD4Hash(gethash); } } else { - LoadDateFromFile(&metFile); - m_FileIdentifier.LoadMD4HashsetFromFile(&metFile, false); + LoadDateFromFile(metFile); + m_FileIdentifier.LoadMD4HashsetFromFile(metFile, false); } bool bHadAICHHashSetTag = false; for (uint32 tagcount = metFile.ReadUInt32(); tagcount > 0; --tagcount) { - CTag *newtag = new CTag(&metFile, false); + CTag *newtag = new CTag(metFile, false); if (pOutCheckFileFormat == NULL || newtag->GetNameID() == FT_FILESIZE || newtag->GetNameID() == FT_FILENAME) { switch (newtag->GetNameID()) { case FT_FILENAME: @@ -859,10 +856,9 @@ EPartFileLoadResult CPartFile::LoadPartFile(LPCTSTR in_directory, LPCTSTR in_fil break; case FT_STATUS: ASSERT(newtag->IsInt()); - if (newtag->IsInt()) { - m_paused = newtag->GetInt() != 0; - m_stopped = m_paused; - } + if (newtag->IsInt()) + m_paused = m_stopped = (newtag->GetInt() != 0); + break; case FT_ULPRIORITY: ASSERT(newtag->IsInt()); @@ -969,7 +965,7 @@ EPartFileLoadResult CPartFile::LoadPartFile(LPCTSTR in_directory, LPCTSTR in_fil case FT_AICHHASHSET: if (newtag->IsBlob()) { CSafeMemFile aichHashSetFile(newtag->GetBlob(), newtag->GetBlobSize()); - m_FileIdentifier.LoadAICHHashsetFromFile(&aichHashSetFile, false); + m_FileIdentifier.LoadAICHHashsetFromFile(aichHashSetFile, false); aichHashSetFile.Detach(); bHadAICHHashSetTag = true; } else @@ -979,16 +975,17 @@ EPartFileLoadResult CPartFile::LoadPartFile(LPCTSTR in_directory, LPCTSTR in_fil if (newtag->GetNameID() == 0 && (newtag->GetName()[0] == FT_GAPSTART || newtag->GetName()[0] == FT_GAPEND)) { ASSERT(newtag->IsInt64(true)); if (newtag->IsInt64(true)) { - Gap_Struct *gap; UINT gapkey = atoi(&newtag->GetName()[1]); - if (!gap_map.Lookup(gapkey, gap)) { - gap = new Gap_Struct{ _UI64_MAX, _UI64_MAX }; - gap_map.SetAt(gapkey, gap); + CGapMap::CPair *pair = gap_map.PLookup(gapkey); + if (!pair) { + gap_map[gapkey] = Gap_Struct{ _UI64_MAX, _UI64_MAX }; + pair = gap_map.PLookup(gapkey); + ASSERT(pair); } if (newtag->GetName()[0] == FT_GAPSTART) - gap->start = newtag->GetInt64(); - if (newtag->GetName()[0] == FT_GAPEND) - gap->end = newtag->GetInt64() - 1; + pair->value.start = newtag->GetInt64(); + else if (newtag->GetName()[0] == FT_GAPEND) + pair->value.end = newtag->GetInt64() - 1; } } else { m_taglist.Add(newtag); @@ -1054,24 +1051,18 @@ EPartFileLoadResult CPartFile::LoadPartFile(LPCTSTR in_directory, LPCTSTR in_fil } // Now flush the map into the list (Slugfiller) - for (POSITION pos = gap_map.GetStartPosition(); pos != NULL;) { - Gap_Struct *gap; - UINT gapkey; - gap_map.GetNextAssoc(pos, gapkey, gap); + for (const CGapMap::CPair *pair = gap_map.PGetFirstAssoc(); pair != NULL; pair = gap_map.PGetNextAssoc(pair)) { + const Gap_Struct &gap = pair->value; // SLUGFILLER: SafeHash - revised code, and extra safety - if (gap->start != _UI64_MAX && gap->end != _UI64_MAX && gap->start <= gap->end && gap->start < (uint64)m_nFileSize) { - if (gap->end >= (uint64)m_nFileSize) - gap->end = (uint64)m_nFileSize - 1; // Clipping - AddGap(gap->start, gap->end); // All tags accounted for, use safe adding - } - delete gap; + if (gap.start != _UI64_MAX && gap.end != _UI64_MAX && gap.start <= gap.end && gap.start < (uint64)m_nFileSize) + AddGap(gap.start, min(gap.end, (uint64)m_nFileSize - 1)); // use safe adding // SLUGFILLER: SafeHash } // verify corrupted parts list for (POSITION posCorruptedPart = corrupted_list.GetHeadPosition(); posCorruptedPart != NULL;) { POSITION posLast = posCorruptedPart; - if (IsComplete(corrupted_list.GetNext(posCorruptedPart), true)) + if (IsCompleteBD(corrupted_list.GetNext(posCorruptedPart))) corrupted_list.RemoveAt(posLast); } @@ -1083,7 +1074,7 @@ EPartFileLoadResult CPartFile::LoadPartFile(LPCTSTR in_directory, LPCTSTR in_fil const CString &searchpath(RemoveFileExtension(m_fullname)); ASSERT(searchpath.Right(5) == _T(".part")); CFileException fexpPart; - if (!m_hpartfile.Open(searchpath, CFile::modeReadWrite | CFile::shareDenyWrite | CFile::osSequentialScan, &fexpPart)) { + if (!m_hpartfile.Open(searchpath, CFile::modeReadWrite | CFile::shareDenyNone | CFile::osSequentialScan, &fexpPart)) { CString strError; strError.Format(GetResString(IDS_ERR_FILEOPEN), (LPCTSTR)searchpath, (LPCTSTR)GetFileName()); TCHAR szError[MAX_CFEXP_ERRORMSG]; @@ -1093,25 +1084,25 @@ EPartFileLoadResult CPartFile::LoadPartFile(LPCTSTR in_directory, LPCTSTR in_fil return PLR_FAILED_OTHER; } - // read part file creation time - struct _stat64 fileinfo; - if (statUTC(searchpath, fileinfo) == 0) { - m_tLastModified = (time_t)fileinfo.st_mtime; - m_tCreated = (time_t)fileinfo.st_ctime; + // get part file's time + struct _stat64 st; + if (statUTC((HANDLE)m_hpartfile, st) == 0) { + m_tCreated = (time_t)st.st_ctime; + m_tLastModified = (time_t)st.st_mtime; } else AddDebugLogLine(false, _T("Failed to get file date for \"%s\" - %s"), (LPCTSTR)searchpath, _tcserror(errno)); try { SetFilePath(searchpath); - m_dwFileAttributes = GetFileAttributes(GetFilePath()); + m_dwFileAttributes = ::GetFileAttributes(GetFilePath()); if (m_dwFileAttributes == INVALID_FILE_ATTRIBUTES) m_dwFileAttributes = 0; - // SLUGFILLER: SafeHash - final safety, make sure any missing part of the file is gap + // SLUGFILLER: SafeHash - final safety, make sure any missing part of the file is a gap if (m_hpartfile.GetLength() < (uint64)m_nFileSize) AddGap(m_hpartfile.GetLength(), (uint64)m_nFileSize - 1); - // Goes both ways - Partfile should never be too large - if (m_hpartfile.GetLength() > (uint64)m_nFileSize) { + else if (m_hpartfile.GetLength() > (uint64)m_nFileSize) { + // Goes both ways - Partfile should never be too large TRACE(_T("Partfile \"%s\" is too large! Truncating %I64u bytes.\n"), (LPCTSTR)GetFileName(), m_hpartfile.GetLength() - (uint64)m_nFileSize); m_hpartfile.SetLength((uint64)m_nFileSize); } @@ -1121,6 +1112,7 @@ EPartFileLoadResult CPartFile::LoadPartFile(LPCTSTR in_directory, LPCTSTR in_fil if (GetPartCount()) memset(&m_SrcPartFrequency[0], 0, GetPartCount() * sizeof m_SrcPartFrequency[0]); SetStatus(PS_EMPTY); + m_CorruptionBlackBox.Init(m_nFileSize); // check hash count, file status etc m_bMD4HashsetNeeded = !m_FileIdentifier.HasExpectedMD4HashCount(); if (m_bMD4HashsetNeeded) { @@ -1128,8 +1120,8 @@ EPartFileLoadResult CPartFile::LoadPartFile(LPCTSTR in_directory, LPCTSTR in_fil return PLR_LOADSUCCESS; } - for (uint16 i = min(m_FileIdentifier.GetAvailableMD4PartHashCount(), GetPartCount()); i-- > 0;) - if (IsComplete(i, true)) { + for (UINT i = min(m_FileIdentifier.GetAvailableMD4PartHashCount(), GetPartCount()); i-- > 0;) + if (IsCompleteBD(i)) { SetStatus(PS_READY); break; } @@ -1157,16 +1149,17 @@ EPartFileLoadResult CPartFile::LoadPartFile(LPCTSTR in_directory, LPCTSTR in_fil AdjustNTFSDaylightFileTime(fdate, filestatus.m_szFullName); if (m_tUtcLastModified != fdate) { - CString strFileInfo; - strFileInfo.Format(_T("%s (%s)"), (LPCTSTR)GetFilePath(), (LPCTSTR)GetFileName()); + CString strFileInfo(GetFilePath()); + strFileInfo.AppendFormat(_T(" (%s)"), (LPCTSTR)GetFileName()); LogError(LOG_STATUSBAR, GetResString(IDS_ERR_REHASH), (LPCTSTR)strFileInfo); // rehash SetStatus(PS_WAITINGFORHASH); - CAddFileThread *addfilethread = static_cast(AfxBeginThread(RUNTIME_CLASS(CAddFileThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED)); + CAddFileThread *addfilethread = static_cast(AfxBeginThread(RUNTIME_CLASS(CAddFileThread), THREAD_PRIORITY_BELOW_NORMAL, 0, CREATE_SUSPENDED)); if (addfilethread) { SetFileOp(PFOP_HASHING); - SetFileOpProgress(0); addfilethread->SetValues(0, GetPath(), m_hpartfile.GetFileName(), _T(""), this); + SetFileOpProgress(0); + SetStatus(PS_HASHING); addfilethread->ResumeThread(); } else SetStatus(PS_ERROR); @@ -1192,12 +1185,12 @@ bool CPartFile::SavePartFile(bool bDontOverrideBak) if (status == PS_WAITINGFORHASH || status == PS_HASHING) return false; // search part file - CFileFind ff; const CString &searchpath(RemoveFileExtension(m_fullname)); - bool end = !ff.FindFile(searchpath, 0); - if (!end) + CFileFind ff; + BOOL bFound = ff.FindFile(searchpath); + if (bFound) ff.FindNextFile(); - if (end || ff.IsDirectory()) { + if (!bFound || ff.IsDirectory()) { LogError(GetResString(IDS_ERR_SAVEMET) + _T(" - %s"), (LPCTSTR)m_partmetfilename, (LPCTSTR)GetFileName(), (LPCTSTR)GetResString(IDS_ERR_PART_FNF)); return false; } @@ -1205,7 +1198,7 @@ bool CPartFile::SavePartFile(bool bDontOverrideBak) FILETIME lwtime; ff.GetLastWriteTime(&lwtime); m_tLastModified = (time_t)FileTimeToUnixTime(lwtime); - if (m_tLastModified == 0) + if (m_tLastModified <= 0) m_tLastModified = (time_t)-1; m_tUtcLastModified = m_tLastModified; if (m_tUtcLastModified == (time_t)-1) { @@ -1215,7 +1208,7 @@ bool CPartFile::SavePartFile(bool bDontOverrideBak) AdjustNTFSDaylightFileTime(m_tUtcLastModified, ff.GetFilePath()); ff.Close(); - CString strTmpFile(m_fullname + PARTMET_TMP_EXT); + const CString &strTmpFile(m_fullname + PARTMET_TMP_EXT); // save file data to part.met file CSafeBufferedFile file; @@ -1229,7 +1222,7 @@ bool CPartFile::SavePartFile(bool bDontOverrideBak) LogError(_T("%s"), (LPCTSTR)strError); return false; } - setvbuf(file.m_pStream, NULL, _IOFBF, 16384); + ::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); try { //version @@ -1240,113 +1233,113 @@ bool CPartFile::SavePartFile(bool bDontOverrideBak) file.WriteUInt32((uint32)m_tUtcLastModified); //hash - m_FileIdentifier.WriteMD4HashsetToFile(&file); + m_FileIdentifier.WriteMD4HashsetToFile(file); UINT uTagCount = 0; ULONG uTagCountFilePos = (ULONG)file.GetPosition(); file.WriteUInt32(uTagCount); CTag nametag(FT_FILENAME, GetFileName()); - nametag.WriteTagToFile(&file, UTF8strOptBOM); + nametag.WriteTagToFile(file, UTF8strOptBOM); ++uTagCount; CTag sizetag(FT_FILESIZE, (uint64)m_nFileSize, IsLargeFile()); - sizetag.WriteTagToFile(&file); + sizetag.WriteTagToFile(file); ++uTagCount; if (m_uTransferred) { CTag transtag(FT_TRANSFERRED, m_uTransferred, IsLargeFile()); - transtag.WriteTagToFile(&file); + transtag.WriteTagToFile(file); ++uTagCount; } if (m_uCompressionGain) { CTag transtag(FT_COMPRESSION, m_uCompressionGain, IsLargeFile()); - transtag.WriteTagToFile(&file); + transtag.WriteTagToFile(file); ++uTagCount; } if (m_uCorruptionLoss) { CTag transtag(FT_CORRUPTED, m_uCorruptionLoss, IsLargeFile()); - transtag.WriteTagToFile(&file); + transtag.WriteTagToFile(file); ++uTagCount; } if (m_paused) { CTag statustag(FT_STATUS, 1); - statustag.WriteTagToFile(&file); + statustag.WriteTagToFile(file); ++uTagCount; } CTag prioritytag(FT_DLPRIORITY, IsAutoDownPriority() ? PR_AUTO : m_iDownPriority); - prioritytag.WriteTagToFile(&file); + prioritytag.WriteTagToFile(file); ++uTagCount; CTag ulprioritytag(FT_ULPRIORITY, IsAutoUpPriority() ? PR_AUTO : GetUpPriority()); - ulprioritytag.WriteTagToFile(&file); + ulprioritytag.WriteTagToFile(file); ++uTagCount; if (lastseencomplete.GetTime()) { CTag lsctag(FT_LASTSEENCOMPLETE, (UINT)lastseencomplete.GetTime()); - lsctag.WriteTagToFile(&file); + lsctag.WriteTagToFile(file); ++uTagCount; } if (m_category) { CTag categorytag(FT_CATEGORY, m_category); - categorytag.WriteTagToFile(&file); + categorytag.WriteTagToFile(file); ++uTagCount; } if (GetLastPublishTimeKadSrc()) { CTag kadLastPubSrc(FT_KADLASTPUBLISHSRC, (uint32)GetLastPublishTimeKadSrc()); - kadLastPubSrc.WriteTagToFile(&file); + kadLastPubSrc.WriteTagToFile(file); ++uTagCount; } if (GetLastPublishTimeKadNotes()) { CTag kadLastPubNotes(FT_KADLASTPUBLISHNOTES, (uint32)GetLastPublishTimeKadNotes()); - kadLastPubNotes.WriteTagToFile(&file); + kadLastPubNotes.WriteTagToFile(file); ++uTagCount; } if (GetDlActiveTime()) { CTag tagDlActiveTime(FT_DL_ACTIVE_TIME, GetDlActiveTime()); - tagDlActiveTime.WriteTagToFile(&file); + tagDlActiveTime.WriteTagToFile(file); ++uTagCount; } if (GetPreviewPrio() || IsPausingOnPreview()) { UINT uTagValue = (static_cast(IsPausingOnPreview()) << 1) | (static_cast(GetPreviewPrio()) << 0); CTag tagDlPreview(FT_DL_PREVIEW, uTagValue); - tagDlPreview.WriteTagToFile(&file); + tagDlPreview.WriteTagToFile(file); ++uTagCount; } // statistics if (statistic.GetAllTimeTransferred()) { CTag attag1(FT_ATTRANSFERRED, (uint32)statistic.GetAllTimeTransferred()); - attag1.WriteTagToFile(&file); + attag1.WriteTagToFile(file); ++uTagCount; CTag attag4(FT_ATTRANSFERREDHI, (uint32)(statistic.GetAllTimeTransferred() >> 32)); - attag4.WriteTagToFile(&file); + attag4.WriteTagToFile(file); ++uTagCount; } if (statistic.GetAllTimeRequests()) { CTag attag2(FT_ATREQUESTED, statistic.GetAllTimeRequests()); - attag2.WriteTagToFile(&file); + attag2.WriteTagToFile(file); ++uTagCount; } if (statistic.GetAllTimeAccepts()) { CTag attag3(FT_ATACCEPTED, statistic.GetAllTimeAccepts()); - attag3.WriteTagToFile(&file); + attag3.WriteTagToFile(file); ++uTagCount; } if (m_uMaxSources) { CTag attag3(FT_MAXSOURCES, m_uMaxSources); - attag3.WriteTagToFile(&file); + attag3.WriteTagToFile(file); ++uTagCount; } @@ -1360,14 +1353,14 @@ bool CPartFile::SavePartFile(bool bDontOverrideBak) } ASSERT(!strCorruptedParts.IsEmpty()); CTag tagCorruptedParts(FT_CORRUPTEDPARTS, strCorruptedParts); - tagCorruptedParts.WriteTagToFile(&file); + tagCorruptedParts.WriteTagToFile(file); ++uTagCount; } //AICH File hash if (m_FileIdentifier.HasAICHHash()) { CTag aichtag(FT_AICH_HASH, m_FileIdentifier.GetAICHHash().GetString()); - aichtag.WriteTagToFile(&file); + aichtag.WriteTagToFile(file); ++uTagCount; // AICH Part HashSet @@ -1379,7 +1372,7 @@ bool CPartFile::SavePartFile(bool bDontOverrideBak) CSafeMemFile hashSetFile(pHashBuffer, nAICHHashSetSize); bool bWriteHashSet = true; try { - m_FileIdentifier.WriteAICHHashsetToFile(&hashSetFile); + m_FileIdentifier.WriteAICHHashsetToFile(hashSetFile); } catch (CFileException *pError) { ASSERT(0); DebugLogError(_T("Memfile Error while storing AICH Part HashSet")); @@ -1389,69 +1382,78 @@ bool CPartFile::SavePartFile(bool bDontOverrideBak) } if (bWriteHashSet) { CTag tagAICHHashSet(FT_AICHHASHSET, hashSetFile.Detach(), nAICHHashSetSize); - tagAICHHashSet.WriteTagToFile(&file); + tagAICHHashSet.WriteTagToFile(file); ++uTagCount; } } } - for (INT_PTR j = 0; j < m_taglist.GetCount(); ++j) { + for (INT_PTR j = 0; j < m_taglist.GetCount(); ++j) if (m_taglist[j]->IsStr() || m_taglist[j]->IsInt()) { - m_taglist[j]->WriteTagToFile(&file, UTF8strOptBOM); + m_taglist[j]->WriteTagToFile(file, UTF8strOptBOM); ++uTagCount; } - } //gaps char namebuffer[10]; char *number = &namebuffer[1]; UINT i_pos = 0; for (POSITION pos = m_gaplist.GetHeadPosition(); pos != NULL;) { - const Gap_Struct *gap = m_gaplist.GetNext(pos); + const Gap_Struct &gap = m_gaplist.GetNext(pos); _itoa(i_pos, number, 10); namebuffer[0] = FT_GAPSTART; - CTag gapstarttag(namebuffer, gap->start, IsLargeFile()); - gapstarttag.WriteTagToFile(&file); + CTag gapstarttag(namebuffer, gap.start, IsLargeFile()); + gapstarttag.WriteTagToFile(file); ++uTagCount; // gap start = first missing byte but gap ends = first non-missing byte in edonkey // but I think its easier to use the real limits namebuffer[0] = FT_GAPEND; - CTag gapendtag(namebuffer, gap->end + 1, IsLargeFile()); - gapendtag.WriteTagToFile(&file); + CTag gapendtag(namebuffer, gap.end + 1, IsLargeFile()); + gapendtag.WriteTagToFile(file); ++uTagCount; ++i_pos; } // Add buffered data as gap too - at the time of writing the file, this data - // does not exists on the disk, so not adding it as gaps leads to inconsistencies + // does not exist on the disk, so not adding it as gaps leads to inconsistencies // which cause problems in case of failing to write the buffered data // (for example, on disk full errors) // don't bother to merge everything, we do this on the next loading // uint32 dbgMerged = 0; for (POSITION pos = m_BufferedData_list.GetHeadPosition(); pos != NULL;) { - const PartFileBufferedData *cur_block = m_BufferedData_list.GetNext(pos); - const uint64 nStart = cur_block->start; - uint64 nEnd = cur_block->end; - for (; pos != NULL; m_BufferedData_list.GetNext(pos)) { // merge if obvious - cur_block = m_BufferedData_list.GetAt(pos); - if (cur_block->start != nEnd + 1) + POSITION pos2 = pos; + const PartFileBufferedData *item = m_BufferedData_list.GetNext(pos); + if (item->flushed == PB_WRITTEN) { + DeleteWrittenItem(pos2); + continue; + } + const uint64 nStart = item->start; + uint64 nEnd = item->end; + while (pos != NULL) { // merge if obvious + pos2 = pos; + item = m_BufferedData_list.GetNext(pos); + if (item->flushed == PB_WRITTEN) { + pos = pos2; //step back; the outer loop will delete this item + break; + } + if (item->start != nEnd + 1) break; // ++dbgMerged; - nEnd = cur_block->end; + nEnd = item->end; } _itoa(i_pos, number, 10); namebuffer[0] = FT_GAPSTART; CTag gapstarttag(namebuffer, nStart, IsLargeFile()); - gapstarttag.WriteTagToFile(&file); + gapstarttag.WriteTagToFile(file); ++uTagCount; - // gap start = first missing byte but gap ends = first non-missing byte in edonkey + // gap start = first missing byte; but gap ends = first non-missing byte in edonkey // but I think its easier to user the real limits namebuffer[0] = FT_GAPEND; CTag gapendtag(namebuffer, nEnd + 1, IsLargeFile()); - gapendtag.WriteTagToFile(&file); + gapendtag.WriteTagToFile(file); ++uTagCount; ++i_pos; } @@ -1461,7 +1463,7 @@ bool CPartFile::SavePartFile(bool bDontOverrideBak) file.WriteUInt32(uTagCount); file.SeekToEnd(); - if ((theApp.IsClosing() && thePrefs.GetCommitFiles() >= 1) || thePrefs.GetCommitFiles() >= 2) { + if (thePrefs.GetCommitFiles() >= 2 || (thePrefs.GetCommitFiles() >= 1 && theApp.IsClosing())) { file.Flush(); // flush file stream buffers to disk buffers if (_commit(_fileno(file.m_pStream)) != 0) // commit disk buffers to disk AfxThrowFileException(CFileException::hardIO, ::GetLastError(), file.GetFileName()); @@ -1514,17 +1516,15 @@ void CPartFile::PartFileHashFinished(CKnownFile *result) ASSERT(result->GetFileIdentifier().GetTheoreticalMD4PartHashCount() == m_FileIdentifier.GetTheoreticalMD4PartHashCount()); ASSERT(result->GetFileIdentifier().GetTheoreticalAICHPartHashCount() == m_FileIdentifier.GetTheoreticalAICHPartHashCount()); bool errorfound = false; + bool bToShare = false; // add to the shared files list if a complete part was found // check each part - for (uint16 nPart = 0; nPart < GetPartCount(); ++nPart) { - const uint64 nPartStartPos = nPart * PARTSIZE; - const uint64 nPartEndPos = min((nPartStartPos + PARTSIZE), (uint64)GetFileSize()) - 1; - ASSERT(IsComplete(nPartStartPos, nPartEndPos, true) == IsComplete(nPartStartPos, nPartEndPos, false)); - if (IsComplete(nPartStartPos, nPartEndPos, false)) { + for (UINT nPart = 0; nPart < GetPartCount(); ++nPart) { + ASSERT(IsCompleteBD(nPart) == IsComplete(nPart)); + if (IsComplete(nPart)) { bool bMD4Error = false; - bool bMD4Checked = false; bool bAICHError = false; - bool bAICHChecked = false; // MD4 + bool bMD4Checked; if (nPart == 0 && m_FileIdentifier.GetTheoreticalMD4PartHashCount() == 0) { bMD4Checked = true; bMD4Error = !md4equ(result->GetFileIdentifier().GetMD4Hash(), GetFileIdentifier().GetMD4Hash()); @@ -1534,8 +1534,10 @@ void CPartFile::PartFileHashFinished(CKnownFile *result) bMD4Error = !md4equ(result->GetFileIdentifier().GetMD4PartHash(nPart), m_FileIdentifier.GetMD4PartHash(nPart)); else ASSERT(0); - } + } else + bMD4Checked = false; // AICH + bool bAICHChecked = false; if (GetFileIdentifier().HasAICHHash()) { if (nPart == 0 && m_FileIdentifier.GetTheoreticalAICHPartHashCount() == 0) { bAICHChecked = true; @@ -1551,20 +1553,24 @@ void CPartFile::PartFileHashFinished(CKnownFile *result) if (bMD4Error || bAICHError) { errorfound = true; LogWarning(GetResString(IDS_ERR_FOUNDCORRUPTION), nPart, (LPCTSTR)GetFileName()); - AddGap(nPartStartPos, nPartEndPos); + const uint64 nPartStart = nPart * PARTSIZE; + AddGap(nPartStart, min(nPartStart + PARTSIZE - 1, (uint64)m_nFileSize - 1)); if (bMD4Checked && bAICHChecked && bMD4Error != bAICHError) DebugLogError(_T("AICH and MD4 HashSet disagree on verifying part %u for file %s. MD4: %s - AICH: %s"), nPart , (LPCTSTR)GetFileName(), bMD4Error ? _T("Corrupt") : _T("OK"), bAICHError ? _T("Corrupt") : _T("OK")); - } + } else + bToShare = true; } } // missing md4 hashset? if (!m_FileIdentifier.HasExpectedMD4HashCount()) { DebugLogError(_T("Final hashing/rehashing without valid MD4 HashSet for file %s"), (LPCTSTR)GetFileName()); // if finished we can copy over the hashset from our hash result - if (IsComplete(0, (uint64)m_nFileSize - 1, false) && md4equ(result->GetFileIdentifier().GetMD4Hash(), GetFileIdentifier().GetMD4Hash())) { - if (m_FileIdentifier.SetMD4HashSet(result->GetFileIdentifier().GetRawMD4HashSet())) - m_bMD4HashsetNeeded = false; + if (m_gaplist.IsEmpty() + && md4equ(result->GetFileIdentifier().GetMD4Hash(), GetFileIdentifier().GetMD4Hash()) + && m_FileIdentifier.SetMD4HashSet(result->GetFileIdentifier().GetRawMD4HashSet())) + { + m_bMD4HashsetNeeded = false; } } @@ -1597,84 +1603,104 @@ void CPartFile::PartFileHashFinished(CKnownFile *result) AddLogLine(false, GetResString(IDS_HASHINGDONE), (LPCTSTR)GetFileName()); SetStatus(PS_READY); SavePartFile(); - theApp.sharedfiles->SafeAddKFile(this); + if (bToShare) + theApp.sharedfiles->SafeAddKFile(this); } } void CPartFile::AddGap(uint64 start, uint64 end) //keep the list ordered! { - ASSERT(start <= end); + ASSERT(end < (uint64)m_nFileSize && start <= end); POSITION before = NULL; for (POSITION pos = m_gaplist.GetHeadPosition(); pos != NULL;) { POSITION pos2 = pos; - const Gap_Struct *gap = m_gaplist.GetNext(pos); - if (gap->start > end) { + const Gap_Struct &gap = m_gaplist.GetNext(pos); + if (gap.start > end) { before = pos2; //no intersections, insert the new gap break; } - if (gap->end >= start) { - if (gap->start <= start && gap->end >= end) + if (gap.end >= start) { + if (gap.start <= start && gap.end >= end) return; //this gap contains the whole new gap //either start or end of this gap may be outside of the new gap, but not both - if (gap->end > end) - end = gap->end; //extend tail - else if (gap->start < start) - start = gap->start; //extend head + if (gap.end > end) + end = gap.end; //extend the tail + else if (gap.start < start) + start = gap.start; //extend the head //this gap is fully contained in the new gap m_gaplist.RemoveAt(pos2); - delete gap; } } - Gap_Struct *gap = new Gap_Struct{ start, end }; if (before) - m_gaplist.InsertBefore(before, gap); + m_gaplist.InsertBefore(before, Gap_Struct{ start, end }); else - m_gaplist.AddTail(gap); + m_gaplist.AddTail(Gap_Struct{ start, end }); UpdateDisplayedInfo(); } -bool CPartFile::IsComplete(uint64 start, uint64 end, bool bIgnoreBufferedData) const +bool CPartFile::IsComplete(uint64 start, uint64 end) const { - ASSERT(start <= end); + ASSERT(end < (uint64)m_nFileSize && start <= end); - if (end >= (uint64)m_nFileSize) - end = (uint64)m_nFileSize - 1; for (POSITION pos = m_gaplist.GetHeadPosition(); pos != NULL;) { - const Gap_Struct *gap = m_gaplist.GetNext(pos); - if (gap->start > end) + const Gap_Struct &gap = m_gaplist.GetNext(pos); + if (gap.start > end) break; //no intersections - if (gap->end >= start) + if (gap.end >= start) return false; } + return true; +} - if (bIgnoreBufferedData) - for (POSITION pos = m_BufferedData_list.GetHeadPosition(); pos != NULL;) { - const PartFileBufferedData *cur_block = m_BufferedData_list.GetNext(pos); - if (cur_block->start > end) - break; //no intersections - if (cur_block->end >= start) - return false; - } +bool CPartFile::IsCompleteSafe(uint64 start, uint64 end) const +{ + return IsComplete(start, min(end, (uint64)m_nFileSize - 1)); +} + +bool CPartFile::IsComplete(UINT uPart) const +{ + return IsCompleteSafe(uPart * PARTSIZE, uPart * PARTSIZE + PARTSIZE - 1); +} +//take into account unwritten buffered data +bool CPartFile::IsCompleteBD(uint64 start, uint64 end) const +{ + ASSERT(end < (uint64)m_nFileSize && start <= end); + + if (!IsComplete(start, end)) + return false; + + for (POSITION pos = m_BufferedData_list.GetHeadPosition(); pos != NULL;) { + const PartFileBufferedData *cur_block = m_BufferedData_list.GetNext(pos); + if (cur_block->start > end) + break; //no intersections + if (cur_block->end >= start) + return false; + } return true; } -bool CPartFile::IsComplete(uint16 uPart, bool bIgnoreBufferedData) const +bool CPartFile::IsCompleteBDSafe(uint64 start, uint64 end) const { - return IsComplete(uPart * PARTSIZE, uPart * PARTSIZE + PARTSIZE - 1, bIgnoreBufferedData); + return IsCompleteBD(start, min(end, (uint64)m_nFileSize - 1)); } -bool CPartFile::IsPureGap(uint64 start, uint64 end) const +bool CPartFile::IsCompleteBD(UINT uPart) const { - ASSERT(start <= end); + return IsCompleteBDSafe(uPart * PARTSIZE, uPart * PARTSIZE + PARTSIZE - 1); +} +bool CPartFile::IsPureGap(uint64 start, uint64 end) const +{ if (end >= (uint64)m_nFileSize) end = (uint64)m_nFileSize - 1; + ASSERT(start <= end); + for (POSITION pos = m_gaplist.GetHeadPosition(); pos != NULL;) { - const Gap_Struct *gap = m_gaplist.GetNext(pos); - if (gap->start > end) + const Gap_Struct &gap = m_gaplist.GetNext(pos); + if (gap.start > end) break; - if (gap->start <= start && gap->end >= end) //fully inside this gap + if (gap.start <= start && gap.end >= end) //fully inside this gap return true; } return false; @@ -1692,10 +1718,10 @@ bool CPartFile::IsAlreadyRequested(uint64 start, uint64 end, bool bCheckBuffers) // check our buffers if (bCheckBuffers) for (POSITION pos = m_BufferedData_list.GetHeadPosition(); pos != NULL;) { - const PartFileBufferedData *cur_block = m_BufferedData_list.GetNext(pos); - if (cur_block->start > end) + const PartFileBufferedData *item = m_BufferedData_list.GetNext(pos); + if (item->start > end) break; //no intersections - if (cur_block->end >= start) { + if (item->end >= start) { DebugLogWarning(_T("CPartFile::IsAlreadyRequested, collision with buffered data found")); return true; } @@ -1720,24 +1746,26 @@ bool CPartFile::ShrinkToAvoidAlreadyRequested(uint64 &start, uint64 &end) const start = cur_block->EndOffset + 1; else return false; + if (start > end) return false; } } - // has been shrunk to fit requested, if needed shrink it further to not collide with buffered data + // has been shrunk to fit requested, might need more shrinking to not collide with buffered data // check our buffers for (POSITION pos = m_BufferedData_list.GetHeadPosition(); pos != NULL;) { - const PartFileBufferedData *cur_block = m_BufferedData_list.GetNext(pos); - if (cur_block->start > end) + const PartFileBufferedData *item = m_BufferedData_list.GetNext(pos); + if (item->start > end) break; - if (cur_block->end >= start) { - if (cur_block->start > start) - end = cur_block->start - 1; - else if (cur_block->end < end) - start = cur_block->end + 1; + if (item->end >= start) { + if (item->start > start) + end = item->start - 1; + else if (item->end < end) + start = item->end + 1; else return false; + if (start > end) return false; } @@ -1757,19 +1785,19 @@ uint64 CPartFile::GetTotalGapSizeInRange(uint64 uRangeStart, uint64 uRangeEnd) c uRangeEnd = (uint64)m_nFileSize - 1; for (POSITION pos = m_gaplist.GetHeadPosition(); pos != NULL;) { - const Gap_Struct *gap = m_gaplist.GetNext(pos); - if (gap->start > uRangeEnd) + const Gap_Struct &gap = m_gaplist.GetNext(pos); + if (gap.start > uRangeEnd) break; - //here gap->start <= uRangeEnd - if (gap->start <= uRangeStart && gap->end >= uRangeEnd) { + //here gap.start <= uRangeEnd + if (gap.start <= uRangeStart && gap.end >= uRangeEnd) { uTotalGapSize = uRangeEnd - uRangeStart + 1; break; } - if (gap->start >= uRangeStart) { - uint64 uEnd = (gap->end > uRangeEnd) ? uRangeEnd : gap->end; - uTotalGapSize += uEnd - gap->start + 1; - } else if (gap->end >= uRangeStart && gap->end <= uRangeEnd) - uTotalGapSize += gap->end - uRangeStart + 1; + if (gap.start >= uRangeStart) { + uint64 uEnd = (gap.end > uRangeEnd) ? uRangeEnd : gap.end; + uTotalGapSize += uEnd - gap.start + 1; + } else if (gap.end >= uRangeStart && gap.end <= uRangeEnd) + uTotalGapSize += gap.end - uRangeStart + 1; } ASSERT(uTotalGapSize <= uRangeEnd - uRangeStart + 1); return uTotalGapSize; @@ -1777,11 +1805,8 @@ uint64 CPartFile::GetTotalGapSizeInRange(uint64 uRangeStart, uint64 uRangeEnd) c uint64 CPartFile::GetTotalGapSizeInPart(UINT uPart) const { - uint64 uRangeStart = uPart * PARTSIZE; - uint64 uRangeEnd = uRangeStart + PARTSIZE - 1; - if (uRangeEnd >= (uint64)m_nFileSize) - uRangeEnd = (uint64)m_nFileSize - 1; - return GetTotalGapSizeInRange(uRangeStart, uRangeEnd); + //the called method will adjust the range end + return GetTotalGapSizeInRange(uPart * PARTSIZE, uPart * PARTSIZE + PARTSIZE - 1); } bool CPartFile::GetNextEmptyBlockInPart(UINT partNumber, Requested_Block_Struct *result) const @@ -1791,22 +1816,20 @@ bool CPartFile::GetNextEmptyBlockInPart(UINT partNumber, Requested_Block_Struct uint64 start = partStart; // The end of the part must be within file size - uint64 partEnd = partStart + PARTSIZE - 1; - if (partEnd >= (uint64)GetFileSize()) - partEnd = (uint64)GetFileSize() - 1; + uint64 partEnd = min(partStart + PARTSIZE - 1, (uint64)m_nFileSize - 1); ASSERT(partStart <= partEnd); // Loop until a suitable gap is found and return true, or no more gaps and return false for (;;) { - Gap_Struct *firstGap = NULL; + const Gap_Struct *firstGap = NULL; // Find the first gap from the start position for (POSITION pos = m_gaplist.GetHeadPosition(); pos != NULL;) { - Gap_Struct *gap = m_gaplist.GetNext(pos); + const Gap_Struct &gap = m_gaplist.GetNext(pos); // Want gaps that overlap start<->partEnd - if (gap->start > partEnd) + if (gap.start > partEnd) break; - if (gap->end >= start) { - firstGap = gap; + if (gap.end >= start) { + firstGap = ⪆ //here gap.start <= partEnd break; } } @@ -1818,17 +1841,11 @@ bool CPartFile::GetNextEmptyBlockInPart(UINT partNumber, Requested_Block_Struct if (start < firstGap->start) start = firstGap->start; - // If this is not within part, exit - if (start > partEnd) - return false; - // Find end, keeping within the max block size and the part limit - uint64 end = firstGap->end; + uint64 end = min(firstGap->end, partEnd); uint64 blockLimit = partStart + ((start - partStart) / EMBLOCKSIZE + 1) * EMBLOCKSIZE - 1; if (end > blockLimit) end = blockLimit; - if (end > partEnd) - end = partEnd; // If this gap has not already been requested, we have found a valid entry if (!IsAlreadyRequested(start, end, true)) { @@ -1841,6 +1858,7 @@ bool CPartFile::GetNextEmptyBlockInPart(UINT partNumber, Requested_Block_Struct } return true; } + uint64 tempStart = start; uint64 tempEnd = end; if (ShrinkToAvoidAlreadyRequested(tempStart, tempEnd)) { @@ -1869,25 +1887,24 @@ bool CPartFile::GetNextEmptyBlockInPart(UINT partNumber, Requested_Block_Struct void CPartFile::FillGap(uint64 start, uint64 end) { - ASSERT(start <= end); + ASSERT(end < (uint64)m_nFileSize && start <= end); for (POSITION pos = m_gaplist.GetHeadPosition(); pos != NULL;) { POSITION pos2 = pos; - Gap_Struct *gap = m_gaplist.GetNext(pos); - if (gap->start > end) + Gap_Struct &gap = m_gaplist.GetNext(pos); + if (gap.start > end) break; - if (gap->end >= start) { - if (gap->start >= start && gap->end <= end) { + if (gap.end >= start) { + if (gap.start >= start && gap.end <= end) { m_gaplist.RemoveAt(pos2); //this gap is fully filled - delete gap; - } else if (gap->start >= start) - gap->start = end + 1; //cut heads of this gap - else if (gap->end <= end) - gap->end = start - 1; //cut tails of this gap + } else if (gap.start >= start) + gap.start = end + 1; //cut the head of this gap + else if (gap.end <= end) + gap.end = start - 1; //cut the tail of this gap else { - uint64 prev = gap->end; //this gap fully includes the filler - gap->end = start - 1; //cut tails, then add the remainder - m_gaplist.InsertAfter(pos2, new Gap_Struct{ end + 1, prev }); + uint64 prev = gap.end; //this gap fully includes the filler + gap.end = start - 1; //cut the tail, then add the rest + m_gaplist.InsertAfter(pos2, Gap_Struct{ end + 1, prev }); break; // [Lord KiRon] } } @@ -1901,8 +1918,8 @@ void CPartFile::UpdateCompletedInfos() { uint64 allgaps = 0; for (POSITION pos = m_gaplist.GetHeadPosition(); pos != NULL;) { - const Gap_Struct *gap = m_gaplist.GetNext(pos); - allgaps += gap->end - gap->start + 1; + const Gap_Struct &gap = m_gaplist.GetNext(pos); + allgaps += gap.end - gap.start + 1; } UpdateCompletedInfos(allgaps); @@ -1934,9 +1951,8 @@ void CPartFile::DrawShareStatusBar(CDC *dc, LPCRECT rect, bool onlygreyrect, boo } static const COLORREF crNotShared = RGB(224, 224, 224); - s_ChunkBar.SetFileSize(GetFileSize()); - s_ChunkBar.SetHeight(rect->bottom - rect->top); - s_ChunkBar.SetWidth(rect->right - rect->left); + s_ChunkBar.SetFileSize(m_nFileSize); + s_ChunkBar.SetRect(rect); s_ChunkBar.Fill(crNotShared); if (!onlygreyrect) { @@ -1944,12 +1960,11 @@ void CPartFile::DrawShareStatusBar(CDC *dc, LPCRECT rect, bool onlygreyrect, boo const COLORREF crNooneAsked(bFlat ? RGB(0, 0, 0) : RGB(104, 104, 104)); for (UINT i = GetPartCount(); i-- > 0;) { uint64 uBegin = PARTSIZE * i; - uint64 uEnd = uBegin + PARTSIZE; - if (IsComplete(uBegin, uEnd - 1, true)) { + if (IsCompleteBD(uBegin, uBegin + PARTSIZE - 1)) { COLORREF colour; if (GetStatus() != PS_PAUSED || !m_ClientUploadList.IsEmpty() || m_nCompleteSourcesCountHi > 0) { uint16 frequency; - if (GetStatus() != PS_PAUSED && !m_SrcPartFrequency.IsEmpty()) + if (GetStatus() != PS_PAUSED && i < (UINT)m_SrcPartFrequency.GetSize()) frequency = m_SrcPartFrequency[i]; else if (m_AvailPartFrequency.IsEmpty()) frequency = m_nCompleteSourcesCountLo; @@ -1962,7 +1977,7 @@ void CPartFile::DrawShareStatusBar(CDC *dc, LPCRECT rect, bool onlygreyrect, boo colour = crMissing; } else colour = crNooneAsked; - s_ChunkBar.FillRange(uBegin, uEnd, colour); + s_ChunkBar.FillRange(uBegin, uBegin + PARTSIZE, colour); } } } @@ -1971,11 +1986,8 @@ void CPartFile::DrawShareStatusBar(CDC *dc, LPCRECT rect, bool onlygreyrect, boo void CPartFile::DrawStatusBar(CDC *dc, const CRect &rect, bool bFlat) /*const*/ { - COLORREF crProgress; - COLORREF crProgressBk; - COLORREF crHave; - COLORREF crPending; - COLORREF crMissing; + COLORREF crProgress, crProgressBk, crHave, crPending, crMissing; + EPartFileStatus eVirtualState = GetStatus(); bool notgray = eVirtualState == PS_EMPTY || eVirtualState == PS_COMPLETE || eVirtualState == PS_READY; @@ -2007,8 +2019,7 @@ void CPartFile::DrawStatusBar(CDC *dc, const CRect &rect, bool bFlat) /*const*/ } } - s_ChunkBar.SetHeight(rect.Height()); - s_ChunkBar.SetWidth(rect.Width()); + s_ChunkBar.SetRect(rect); s_ChunkBar.SetFileSize((uint64)m_nFileSize); s_ChunkBar.Fill(crHave); @@ -2029,12 +2040,13 @@ void CPartFile::DrawStatusBar(CDC *dc, const CRect &rect, bool bFlat) /*const*/ } else { // red gaps uint64 allgaps = 0; + UINT i = 0; for (POSITION pos = m_gaplist.GetHeadPosition(); pos != NULL;) { - const Gap_Struct *gap = m_gaplist.GetNext(pos); - allgaps += gap->end - gap->start + 1; - uint64 start = gap->start; - uint64 end = gap->end; - for (uint16 i = 0; i < GetPartCount(); ++i) { + const Gap_Struct &gap = m_gaplist.GetNext(pos); + allgaps += gap.end - gap.start + 1; + uint64 start = gap.start; + uint64 end = gap.end; + for (; i < GetPartCount(); ++i) { const uint64 uEnd = i * PARTSIZE + PARTSIZE - 1; if (start >= PARTSIZE * i && start <= uEnd) { // is in this part? bool gapdone = (end <= uEnd); @@ -2043,7 +2055,7 @@ void CPartFile::DrawStatusBar(CDC *dc, const CRect &rect, bool bFlat) /*const*/ // paint COLORREF color; - if ((uint16)m_SrcPartFrequency.GetCount() >= i && m_SrcPartFrequency[i]) { + if (i < (UINT)m_SrcPartFrequency.GetCount() && m_SrcPartFrequency[i]) { uint16 freq = m_SrcPartFrequency[i] - 1; if (g_bLowColorDesktop) { if (notgray) @@ -2064,7 +2076,7 @@ void CPartFile::DrawStatusBar(CDC *dc, const CRect &rect, bool bFlat) /*const*/ break; start = end + 1; - end = gap->end; + end = gap.end; } } } @@ -2115,24 +2127,25 @@ void CPartFile::DrawStatusBar(CDC *dc, const CRect &rect, bool bFlat) /*const*/ } } -void CPartFile::WritePartStatus(CSafeMemFile *file) const +void CPartFile::WritePartStatus(CSafeMemFile &file) const { uint16 uED2KPartCount = GetED2KPartCount(); - file->WriteUInt16(uED2KPartCount); + file.WriteUInt16(uED2KPartCount); - for (uint16 uPart = 0; uPart < uED2KPartCount;) { + for (UINT uPart = 0; uPart < uED2KPartCount;) { uint8 towrite = 0; - for (uint16 i = 0; i < 8 && uPart < uED2KPartCount; ++i) { - towrite |= static_cast(IsComplete(uPart, true)) << i; + for (UINT i = 0; i < 8 && uPart < uED2KPartCount; ++i) { + if (IsCompleteBD(uPart)) + towrite |= 1 << i; ++uPart; } - file->WriteUInt8(towrite); + file.WriteUInt8(towrite); } } -void CPartFile::WriteCompleteSourcesCount(CSafeMemFile *file) const +void CPartFile::WriteCompleteSourcesCount(CSafeMemFile &file) const { - file->WriteUInt16(m_nCompleteSourcesCount); + file.WriteUInt16(m_nCompleteSourcesCount); } int CPartFile::GetValidSourcesCount() const @@ -2167,9 +2180,8 @@ UINT CPartFile::GetNotCurrentSourcesCount() const uint64 CPartFile::GetNeededSpace() const { - if (m_hpartfile.GetLength() > (uint64)GetFileSize()) - return 0; // Shouldn't happen, but just in case - return (uint64)GetFileSize() - m_hpartfile.GetLength(); + // Do a safety check, though it should never happen + return ((uint64)m_nFileSize > m_hpartfile.GetLength()) ? (uint64)m_nFileSize - m_hpartfile.GetLength() : 0; } EPartFileStatus CPartFile::GetStatus(bool ignorepause) const @@ -2203,17 +2215,20 @@ uint32 CPartFile::Process(uint32 reducedownload, UINT icounter/*in percent*/) ASSERT_VALID(this); UINT nOldTransSourceCount = GetSrcStatisticsValue(DS_DOWNLOADING); - DWORD dwCurTick = ::GetTickCount(); - if (dwCurTick < m_nLastBufferFlushTime) { + const DWORD curTick = ::GetTickCount(); + if (curTick < m_nLastBufferFlushTime) { ASSERT(0); - m_nLastBufferFlushTime = dwCurTick; + m_nLastBufferFlushTime = curTick; } // If buffer size exceeds limit, or if not written within time limit, flush data - if (m_nTotalBufferData > thePrefs.GetFileBufferSize() || dwCurTick >= m_nLastBufferFlushTime + m_nFlushLimitMs) - // Avoid flushing while copying preview file - if (!m_bPreviewing) - FlushBuffer(); + if (m_nTotalBufferData > thePrefs.GetFileBufferSize() || curTick >= m_nLastBufferFlushTime + thePrefs.GetFileBufferTimeLimit()) + FlushBuffer(); + //If data keeps arriving, flush to disk sometimes for extra safety + if (m_nFileFlushTime && curTick >= m_nFileFlushTime + SEC2MS(31) && m_hWrite != INVALID_HANDLE_VALUE) { + ::FlushFileBuffers(m_hWrite); + m_nFileFlushTime = 0; + } m_datarate = 0; @@ -2274,18 +2289,18 @@ uint32 CPartFile::Process(uint32 reducedownload, UINT icounter/*in percent*/) nCountForState = DS_BANNED; if (cur_src->GetSourceFrom() >= SF_SERVER && cur_src->GetSourceFrom() <= SF_PASSIVE) - src_stats[cur_src->GetSourceFrom()]++; + ++src_stats[cur_src->GetSourceFrom()]; if (cur_src->GetServerIP() && cur_src->GetServerPort()) { - net_stats[0]++; + ++net_stats[0]; if (cur_src->GetKadPort()) - net_stats[2]++; + ++net_stats[2]; } if (cur_src->GetKadPort()) - net_stats[1]++; + ++net_stats[1]; ASSERT(nCountForState < _countof(m_anStates)); - m_anStates[nCountForState]++; + ++m_anStates[nCountForState]; switch (cur_src->GetDownloadState()) { case DS_DOWNLOADING: @@ -2325,9 +2340,9 @@ uint32 CPartFile::Process(uint32 reducedownload, UINT icounter/*in percent*/) //Make sure this source is still a LowID Client, and we still cannot callback to this Client. if (cur_src->HasLowID() && !theApp.CanDoCallback(cur_src)) { //If we are almost maxed on sources, slowly remove these client to see if we can find a better source. - if ((dwCurTick >= lastpurgetime + SEC2MS(30)) && (GetSourceCount() >= GetMaxSources() * 4 / 5)) { + if ((curTick >= m_lastpurgetime + SEC2MS(30)) && (GetSourceCount() >= GetMaxSources() * 4 / 5)) { theApp.downloadqueue->RemoveSource(cur_src); - lastpurgetime = dwCurTick; + m_lastpurgetime = curTick; } break; } @@ -2337,8 +2352,8 @@ uint32 CPartFile::Process(uint32 reducedownload, UINT icounter/*in percent*/) case DS_NONEEDEDPARTS: // To Mods, please stop instantly removing these sources. // This causes sources to pop in and out creating extra overhead! - if (dwCurTick >= lastpurgetime + SEC2MS(40)) { - lastpurgetime = dwCurTick; + if (curTick >= m_lastpurgetime + SEC2MS(40)) { + m_lastpurgetime = curTick; // we only delete them if reaching the limit if (GetSourceCount() >= (GetMaxSources() * 4 / 5)) { theApp.downloadqueue->RemoveSource(cur_src); @@ -2346,25 +2361,24 @@ uint32 CPartFile::Process(uint32 reducedownload, UINT icounter/*in percent*/) } } // doubled re-ask time for no needed parts - save connections and traffic - if (cur_src->GetTimeUntilReask() > 0) - break; - - cur_src->SwapToAnotherFile(_T("A4AF for NNP file. CPartFile::Process()"), true, false, false, NULL, true, true); // ZZ:DownloadManager - // Recheck this client to see if still NNP. Set to DS_NONE so that we force a TCP re-ask next time. - cur_src->SetDownloadState(DS_ONQUEUE); //DS_NONE could be deleted in CleanUpClientList + if (cur_src->GetTimeUntilReask() == 0) { + cur_src->SwapToAnotherFile(_T("A4AF for NNP file. CPartFile::Process()"), true, false, false, NULL, true, true); // ZZ:DownloadManager + // Recheck this client to see if still NNP. Set to DS_NONE so that we force a TCP re-ask next time. + cur_src->SetDownloadState(DS_ONQUEUE); //DS_NONE could be deleted in CleanUpClientList + } break; case DS_ONQUEUE: // To Mods, please stop instantly removing these sources. // This causes sources to pop in and out creating extra overhead! if (cur_src->IsRemoteQueueFull()) { - if ((dwCurTick >= lastpurgetime + MIN2MS(1)) && (GetSourceCount() >= (GetMaxSources() * 4 / 5))) { + if ((curTick >= m_lastpurgetime + MIN2MS(1)) && (GetSourceCount() >= (GetMaxSources() * 4 / 5))) { theApp.downloadqueue->RemoveSource(cur_src); - lastpurgetime = dwCurTick; + m_lastpurgetime = curTick; break; } } - //Give up to 1 min for UDP to respond. If we are within one min of TCP re-ask, do not try. - if (theApp.IsConnected() && cur_src->GetTimeUntilReask() < MIN2MS(2) && cur_src->GetTimeUntilReask() > SEC2MS(1) && ::GetTickCount() >= cur_src->getLastTriedToConnectTime() + MIN2MS(20)) // ZZ:DownloadManager (one re-ask timestamp for each file) + //Allow up to 1 min for UDP to respond. If we are within one min of TCP re-ask, do not try. + if (theApp.IsConnected() && cur_src->GetTimeUntilReask() < MIN2MS(2) && cur_src->GetTimeUntilReask() > SEC2MS(1) && curTick >= cur_src->GetLastTriedToConnectTime() + MIN2MS(20)) // ZZ:DownloadManager (one re-ask timestamp for each file) cur_src->UDPReaskForDownload(); case DS_CONNECTING: @@ -2374,11 +2388,12 @@ uint32 CPartFile::Process(uint32 reducedownload, UINT icounter/*in percent*/) case DS_WAITCALLBACK: case DS_WAITCALLBACKKAD: if (theApp.IsConnected() && cur_src->GetTimeUntilReask() == 0) { // ZZ:DownloadManager (one re-ask timestamp for each file) - if (cur_src->socket && cur_src->socket->IsConnected() && cur_src->CheckHandshakeFinished() && cur_src->GetUploadState() != US_BANNED) { // netfinity: Ask immediately if already connected and if allowed, or we could lose the source + if (cur_src->socket && cur_src->socket->IsConnected() && cur_src->CheckHandshakeFinished() && cur_src->GetUploadState() != US_BANNED) { + // netfinity: Ask immediately if already connected and if allowed, or we may lose the source cur_src->SetDownloadState(DS_CONNECTED); - cur_src->setLastTriedToConnectTime(); + cur_src->SetLastTriedToConnectTime(); cur_src->SendFileRequest(); - } else if (::GetTickCount() >= cur_src->getLastTriedToConnectTime() + MIN2MS(20)) { + } else if (curTick >= cur_src->GetLastTriedToConnectTime() + MIN2MS(20)) { if (!cur_src->AskForDownload()) // NOTE: This may *delete* the client!! break; //I left this break here as a reminder in case of re-arranging things. } @@ -2389,7 +2404,7 @@ uint32 CPartFile::Process(uint32 reducedownload, UINT icounter/*in percent*/) NotifyStatusChange(); if (GetMaxSourcePerFileUDP() > GetSourceCount()) { - if (theApp.downloadqueue->DoKademliaFileRequest() && (Kademlia::CKademlia::GetTotalFile() < KADEMLIATOTALFILE) && (dwCurTick >= m_LastSearchTimeKad) && Kademlia::CKademlia::IsConnected() && theApp.IsConnected() && !m_stopped) { //Once we can handle lowID users in Kad, we remove the second IsConnected + if (theApp.downloadqueue->DoKademliaFileRequest() && (Kademlia::CKademlia::GetTotalFile() < KADEMLIATOTALFILE) && (curTick >= m_LastSearchTimeKad) && Kademlia::CKademlia::IsConnected() && theApp.IsConnected() && !m_stopped) { //Once we can handle lowID users in Kad, we remove the second IsConnected //Kademlia theApp.downloadqueue->SetLastKademliaFileRequest(); if (!GetKadFileSearchID()) { @@ -2397,7 +2412,7 @@ uint32 CPartFile::Process(uint32 reducedownload, UINT icounter/*in percent*/) if (pSearch) { if (m_TotalSearchesKad < 7) ++m_TotalSearchesKad; - m_LastSearchTimeKad = dwCurTick + (KADEMLIAREASKTIME*m_TotalSearchesKad); + m_LastSearchTimeKad = curTick + (KADEMLIAREASKTIME * m_TotalSearchesKad); pSearch->SetGUIName((CStringW)GetFileName()); SetKadFileSearchID(pSearch->GetSearchID()); } else @@ -2408,7 +2423,7 @@ uint32 CPartFile::Process(uint32 reducedownload, UINT icounter/*in percent*/) Kademlia::CSearchManager::StopSearch(GetKadFileSearchID(), true); // check if we want new sources from server - if (!m_bLocalSrcReqQueued && ((!m_LastSearchTime) || dwCurTick >= m_LastSearchTime + SERVERREASKTIME) && theApp.serverconnect->IsConnected() + if (!m_bLocalSrcReqQueued && (!m_LastSearchTime || curTick >= m_LastSearchTime + SERVERREASKTIME) && theApp.serverconnect->IsConnected() && GetMaxSourcePerFileSoft() > GetSourceCount() && !m_stopped && (!IsLargeFile() || (theApp.serverconnect->GetCurrentServer() != NULL && theApp.serverconnect->GetCurrentServer()->SupportsLargeFilesTCP()))) { @@ -2479,7 +2494,7 @@ void CPartFile::AddSources(CSafeMemFile *sources, uint32 serverip, uint16 server UINT debug_lowiddropped = 0; UINT debug_possiblesources = 0; - uchar achUserHash[16]; + uchar achUserHash[MDX_DIGEST_SIZE]; bool bSkip = false; for (UINT i = 0; i < ucount; ++i) { uint32 userid = sources->ReadUInt32(); @@ -2593,8 +2608,7 @@ void CPartFile::UpdatePartsInfo() bool bRefresh = (tNow - m_nCompleteSourcesTime > 0); // Reset part counters - if (m_SrcPartFrequency.GetCount() < GetPartCount()) - m_SrcPartFrequency.SetSize(GetPartCount()); + m_SrcPartFrequency.SetSize(GetPartCount()); memset(&m_SrcPartFrequency[0], 0, GetPartCount() * sizeof m_SrcPartFrequency[0]); CArray acount; @@ -2603,8 +2617,8 @@ void CPartFile::UpdatePartsInfo() for (POSITION pos = srclist.GetHeadPosition(); pos != NULL;) { const CUpDownClient *cur_src = srclist.GetNext(pos); if (cur_src->GetPartStatus()) { - for (uint16 i = GetPartCount(); i-- > 0;) - m_SrcPartFrequency[i] += static_cast(cur_src->IsPartAvailable(i)); + for (INT_PTR i = GetPartCount(); --i >= 0;) + m_SrcPartFrequency[i] += static_cast(cur_src->IsPartAvailable((UINT)i)); if (bRefresh) acount.Add(cur_src->GetUpCompleteSourcesCount()); @@ -2617,7 +2631,7 @@ void CPartFile::UpdatePartsInfo() m_nCompleteSourcesCount = 0; else { m_nCompleteSourcesCount = _UI16_MAX; - for (UINT i = GetPartCount(); i-- > 0;) + for (INT_PTR i = GetPartCount(); --i >= 0;) if (m_nCompleteSourcesCount > m_SrcPartFrequency[i]) m_nCompleteSourcesCount = m_SrcPartFrequency[i]; } @@ -2626,9 +2640,9 @@ void CPartFile::UpdatePartsInfo() int n = (int)acount.GetCount(); if (n > 0) { // SLUGFILLER: heapsortCompletesrc - for (int r = n / 2; --r >= 0; ) + for (int r = n / 2; --r >= 0;) HeapSort(acount, r, n - 1); - for (int r = n; --r; ) { + for (int r = n; --r;) { uint16 t = acount[r]; acount[r] = acount[0]; acount[0] = t; @@ -2687,7 +2701,7 @@ bool CPartFile::RemoveBlockFromList(uint64 start, uint64 end) { ASSERT(start <= end); - for (POSITION pos = requestedblocks_list.GetHeadPosition(); pos != NULL; ) { + for (POSITION pos = requestedblocks_list.GetHeadPosition(); pos != NULL;) { POSITION posLast = pos; const Requested_Block_Struct *block = requestedblocks_list.GetNext(pos); if (block->StartOffset <= start && block->EndOffset >= end) { @@ -2698,11 +2712,6 @@ bool CPartFile::RemoveBlockFromList(uint64 start, uint64 end) return false; } -bool CPartFile::IsInRequestedBlockList(const Requested_Block_Struct *block) const -{ - return requestedblocks_list.Find(const_cast(block)) != NULL; -} - void CPartFile::RemoveAllRequestedBlocks() { requestedblocks_list.RemoveAll(); @@ -2710,6 +2719,10 @@ void CPartFile::RemoveAllRequestedBlocks() void CPartFile::CompleteFile(bool bIsHashingDone) { + ASSERT(m_iWrites <= 0 && m_gaplist.IsEmpty() && m_BufferedData_list.IsEmpty()); + CPartFileWriteThread::RemFile(this); + m_nFileFlushTime = 0; + theApp.downloadqueue->RemoveLocalServerRequest(this); if (GetKadFileSearchID()) Kademlia::CSearchManager::StopSearch(GetKadFileSearchID(), false); @@ -2767,16 +2780,16 @@ UINT CPartFile::CompleteThreadProc(LPVOID pvParams) void UncompressFile(LPCTSTR pszFilePath, CPartFile *pPartFile) { // check, if it's a compressed file - DWORD dwAttr = GetFileAttributes(pszFilePath); + DWORD dwAttr = ::GetFileAttributes(pszFilePath); if (dwAttr == INVALID_FILE_ATTRIBUTES || (dwAttr & FILE_ATTRIBUTE_COMPRESSED) == 0) return; - CString strDir = pszFilePath; - PathRemoveFileSpec(strDir.GetBuffer()); + CString strDir(pszFilePath); + ::PathRemoveFileSpec(strDir.GetBuffer()); strDir.ReleaseBuffer(); // If the directory of the file has the 'Compress' attribute, do not uncompress the file - dwAttr = GetFileAttributes(strDir); + dwAttr = ::GetFileAttributes(strDir); if (dwAttr == INVALID_FILE_ATTRIBUTES || (dwAttr & FILE_ATTRIBUTE_COMPRESSED) != 0) return; @@ -2855,25 +2868,9 @@ DWORD CALLBACK CopyProgressRoutine(LARGE_INTEGER TotalFileSize, LARGE_INTEGER To return PROGRESS_CONTINUE; } -DWORD MoveCompletedPartFile(LPCTSTR pszPartFilePath, LPCTSTR pszNewPartFilePath, CPartFile *pPartFile) -{ - HMODULE hLib = GetModuleHandle(_T("kernel32")); - if (hLib) { - BOOL(WINAPI *pfnMoveFileWithProgress)(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, LPPROGRESS_ROUTINE lpProgressRoutine, LPVOID lpData, DWORD dwFlags); - (FARPROC&)pfnMoveFileWithProgress = GetProcAddress(hLib, _TWINAPI("MoveFileWithProgress")); - if (pfnMoveFileWithProgress) { - if ((*pfnMoveFileWithProgress)(pszPartFilePath, pszNewPartFilePath, CopyProgressRoutine, pPartFile, MOVEFILE_COPY_ALLOWED)) - return ERROR_SUCCESS; - return ::GetLastError(); - } - } - //use default move routine - return ::MoveFile(pszPartFilePath, pszNewPartFilePath) ? ERROR_SUCCESS : ::GetLastError(); -} - // Lord KiRon - using threads for file completion // NOTE: This function is executed within a separate thread, do *NOT* use any lists/queues -// of the main thread without synchronization. Even the access to couple of members of the CPartFile +// of the main thread without synchronization. Even access to members of the CPartFile // (e.g. filename) would need proper synchronization to achieve full multi-threading compliance. BOOL CPartFile::PerformFileComplete() { @@ -2888,14 +2885,14 @@ BOOL CPartFile::PerformFileComplete() _tcscpy(newfilename, (LPCTSTR)StripInvalidFilenameChars(newfilename)); CString indir; - if (PathFileExists(thePrefs.GetCategory(GetCategory())->strIncomingPath)) + if (::PathFileExists(thePrefs.GetCategory(GetCategory())->strIncomingPath)) indir = thePrefs.GetCategory(GetCategory())->strIncomingPath; else indir = thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR); - + ASSERT(indir.Right(1) == _T("\\")); // close permanent handle try { - if (m_hpartfile.m_hFile != INVALID_HANDLE_VALUE) + if ((HANDLE)m_hpartfile != INVALID_HANDLE_VALUE) m_hpartfile.Close(); } catch (CFileException *error) { TCHAR buffer[MAX_CFEXP_ERRORMSG]; @@ -2904,20 +2901,20 @@ BOOL CPartFile::PerformFileComplete() error->Delete(); } - CString strNewname; - strNewname.Format(_T("%s\\%s"), (LPCTSTR)indir, newfilename); - bool renamed = PathFileExists(strNewname); + CString strNewname(indir); + strNewname += newfilename; + bool renamed = ::PathFileExists(strNewname); if (renamed) { size_t length = _tcslen(newfilename); - ASSERT(length != 0); //name should never be 0 + ASSERT(length); //name should never be empty //the file extension TCHAR *ext = _tcsrchr(newfilename, _T('.')); if (ext == NULL) - ext = newfilename + length; + ext = &newfilename[length]; TCHAR *last = ext; //new end is the file name before extension - last[0] = _T('\0'); //truncate file name + *last = _T('\0'); //truncate file name int namecount = 0; //search for matching ()s and check if it contains a number @@ -2941,36 +2938,37 @@ BOOL CPartFile::PerformFileComplete() ext = min(ext + 1, newfilename + length); CString strTestName; do - strTestName.Format(_T("%s\\%s(%d).%s"), (LPCTSTR)indir, newfilename, ++namecount, ext); - while (PathFileExists(strTestName)); + strTestName.Format(_T("%s%s(%d).%s"), (LPCTSTR)indir, newfilename, ++namecount, ext); + while (::PathFileExists(strTestName)); strNewname = strTestName; } free(newfilename); + bNoNewReads = true; //this file is on the move and cannot be read for (bool bFirstTry = true; ;) { - DWORD dwMoveResult = MoveCompletedPartFile(strPartfilename, strNewname, this); - if (dwMoveResult == ERROR_SUCCESS) + if (::MoveFileWithProgress(strPartfilename, strNewname, CopyProgressRoutine, this, MOVEFILE_COPY_ALLOWED)) break; - if (dwMoveResult != ERROR_SHARING_VIOLATION || thePrefs.GetWindowsVersion() >= _WINVER_2K_ || !bFirstTry) { + DWORD dwMoveResult = ::GetLastError(); + if (dwMoveResult != ERROR_SHARING_VIOLATION || !bFirstTry) { theApp.QueueLogLine(true, GetResString(IDS_ERR_COMPLETIONFAILED) + _T(" - \"%s\": %s") , (LPCTSTR)GetFileName(), (LPCTSTR)strNewname, (LPCTSTR)GetErrorMessage(dwMoveResult)); - // If the destination file path is too long, the default system error message may not be helpful for user to know what failed. + // If the destination file path is too long, the default system error message may be unhelpful for user to know what failed. if (strNewname.GetLength() >= MAX_PATH) theApp.QueueLogLine(true, GetResString(IDS_ERR_COMPLETIONFAILED) + _T(" - \"%s\": Path too long") , (LPCTSTR)GetFileName(), (LPCTSTR)strNewname); - m_paused = true; - m_stopped = true; + m_paused = m_stopped = true; SetStatus(PS_ERROR); m_bCompletionError = true; SetFileOp(PFOP_NONE); if (!theApp.IsClosing()) VERIFY(theApp.emuledlg->PostMessage(TM_FILECOMPLETED, FILE_COMPLETION_THREAD_FAILED, (LPARAM)this)); + bNoNewReads = false; //re-enable reading till next completion attempt return FALSE; } // The UploadDiskIOThread might have an open handle to this file due to ongoing uploads // On old Windows versions this might result in a sharing violation (for new version we have FILE_SHARE_DELETE) - // So wait a few seconds and try again. Due to the lock we set, the UploadThread will close the file ASAP + // So wait a few seconds and try again. Due to the lock we set, the UploadDiskIOThread will close the file ASAP bFirstTry = false; theApp.QueueDebugLogLine(false, _T("Sharing violation while finishing partfile, might be due to ongoing upload. Locked and trying again soon. File %s") , (LPCTSTR)GetFileName()); @@ -2983,34 +2981,34 @@ BOOL CPartFile::PerformFileComplete() // to have the accurate date stored in known.met we have to update the 'date' of a just completed file. // if we don't update the file date here (after committing the file and before adding the record to known.met), // that file will be rehashed at next startup and there would also be a duplicate entry (hash+size) - // in known.met because of different file date! - ASSERT(m_hpartfile.m_hFile == INVALID_HANDLE_VALUE); // the file must be closed/committed! + // in known.met because of a different file date! + ASSERT((HANDLE)m_hpartfile == INVALID_HANDLE_VALUE); // the file must be closed/committed! struct _stat64 st; if (statUTC(strNewname, st) == 0) { m_tUtcLastModified = m_tLastModified = (time_t)st.st_mtime; AdjustNTFSDaylightFileTime(m_tUtcLastModified, strNewname); } - static LPCTSTR const pszErrfmt = _T("%s - %s"); + static LPCTSTR const pszErrfmt = _T(" - %s"); // remove part.met file - if (_tremove(m_fullname)) { - CString sFmt; - sFmt.Format(pszErrfmt, (LPCTSTR)GetResString(IDS_ERR_DELETEFAILED), _tcserror(errno)); + if (!::DeleteFile(m_fullname)) { + CString sFmt(GetResString(IDS_ERR_DELETEFAILED)); + sFmt.AppendFormat(pszErrfmt, (LPCTSTR)GetErrorMessage(::GetLastError())); theApp.QueueLogLine(true, sFmt, (LPCTSTR)m_fullname); } // remove backup files const CString &BAKName(m_fullname + PARTMET_BAK_EXT); if (!_taccess(BAKName, 0) && !::DeleteFile(BAKName)) { - CString sFmt; - sFmt.Format(pszErrfmt, (LPCTSTR)GetResString(IDS_ERR_DELETE), (LPCTSTR)GetErrorMessage(::GetLastError())); + CString sFmt(GetResString(IDS_ERR_DELETE)); + sFmt.AppendFormat(pszErrfmt, (LPCTSTR)GetErrorMessage(::GetLastError())); theApp.QueueLogLine(true, sFmt, (LPCTSTR)BAKName); } const CString &TMPName(m_fullname + PARTMET_TMP_EXT); if (!_taccess(TMPName, 0) && !::DeleteFile(TMPName)) { - CString sFmt; - sFmt.Format(pszErrfmt, (LPCTSTR)GetResString(IDS_ERR_DELETE), (LPCTSTR)GetErrorMessage(::GetLastError())); + CString sFmt(GetResString(IDS_ERR_DELETE)); + sFmt.AppendFormat(pszErrfmt, (LPCTSTR)GetErrorMessage(::GetLastError())); theApp.QueueLogLine(true, sFmt, (LPCTSTR)TMPName); } @@ -3024,6 +3022,7 @@ BOOL CPartFile::PerformFileComplete() // clear the blackbox to free up memory m_CorruptionBlackBox.Free(); + m_aChangedPart.SetSize(0); // explicitly unlock the file before posting something to the main thread. sLock.Unlock(); @@ -3044,7 +3043,10 @@ void CPartFile::PerformFileCompleteEnd(DWORD dwResult) SetStatus(PS_COMPLETE); // (set status and) update status-related modification of GUI elements theApp.knownfiles->SafeAddKFile(this); + ASSERT(!nInUse); theApp.downloadqueue->RemoveFile(this); + CUploadDiskIOThread::DissociateFile(this); //file has moved, a new handle would be required + bNoNewReads = false; //ready for uploading - enable reading if (thePrefs.GetRemoveFinishedDownloads()) theApp.emuledlg->transferwnd->GetDownloadList()->RemoveFile(this); else @@ -3120,12 +3122,6 @@ void CPartFile::DeletePartFile() // Barry - Need to tell any connected clients to stop sending the file StopFile(true); - // feel free to implement a runtime handling mechanism! - if (IsAllocating()) { - LogWarning(LOG_STATUSBAR, GetResString(IDS_DELETEAFTERALLOC), (LPCTSTR)GetFileName()); - m_bDelayDelete = true; - return; - } if (GetFileOp() != PFOP_NONE) { //hashing, copying, uncompressing if (!m_bDelayDelete) { LogWarning(LOG_STATUSBAR, GetResString(IDS_DELETEAFTERFILEOP), (LPCTSTR)GetFileName()); @@ -3139,34 +3135,34 @@ void CPartFile::DeletePartFile() theApp.emuledlg->transferwnd->GetDownloadList()->RemoveFile(this); theApp.knownfiles->AddCancelledFileID(GetFileHash()); - if (m_hpartfile.m_hFile != INVALID_HANDLE_VALUE) + if ((HANDLE)m_hpartfile != INVALID_HANDLE_VALUE) m_hpartfile.Close(); - static LPCTSTR const pszErrfmt = _T("%s - %s"); + static LPCTSTR const pszErrfmt = _T(" - %s"); if (_tremove(m_fullname)) { - CString sFmt; - sFmt.Format(pszErrfmt, (LPCTSTR)GetResString(IDS_ERR_DELETE), _tcserror(errno)); + CString sFmt(GetResString(IDS_ERR_DELETE)); + sFmt.AppendFormat(pszErrfmt, _tcserror(errno)); LogError(LOG_STATUSBAR, sFmt, (LPCTSTR)m_fullname); } const CString &partfilename(RemoveFileExtension(m_fullname)); if (_tremove(partfilename)) { - CString sFmt; - sFmt.Format(pszErrfmt, (LPCTSTR)GetResString(IDS_ERR_DELETE), _tcserror(errno)); + CString sFmt(GetResString(IDS_ERR_DELETE)); + sFmt.AppendFormat(pszErrfmt, _tcserror(errno)); LogError(LOG_STATUSBAR, sFmt, (LPCTSTR)partfilename); } const CString &BAKName(m_fullname + PARTMET_BAK_EXT); if (!_taccess(BAKName, 0) && !::DeleteFile(BAKName)) { - CString sFmt; - sFmt.Format(pszErrfmt, (LPCTSTR)GetResString(IDS_ERR_DELETE), (LPCTSTR)GetErrorMessage(::GetLastError())); + CString sFmt(GetResString(IDS_ERR_DELETE)); + sFmt.AppendFormat(pszErrfmt, (LPCTSTR)GetErrorMessage(::GetLastError())); LogError(LOG_STATUSBAR, sFmt, (LPCTSTR)BAKName); } const CString &TMPName(m_fullname + PARTMET_TMP_EXT); if (!_taccess(TMPName, 0) && !::DeleteFile(TMPName)) { - CString sFmt; - sFmt.Format(pszErrfmt, (LPCTSTR)GetResString(IDS_ERR_DELETE), (LPCTSTR)GetErrorMessage(::GetLastError())); + CString sFmt(GetResString(IDS_ERR_DELETE)); + sFmt.AppendFormat(pszErrfmt, (LPCTSTR)GetErrorMessage(::GetLastError())); LogError(LOG_STATUSBAR, sFmt, (LPCTSTR)TMPName); } @@ -3178,7 +3174,7 @@ bool CPartFile::HashSinglePart(UINT partnumber, bool *pbAICHReportedOK) // Right now we demand that AICH (if we have one) and MD4 agree on a parthash, no matter what // This is the most secure way in order to make sure eMule will never deliver a corrupt file, // even if one or both of the hash algorithms were broken - // This however doesn't means that eMule is guaranteed to be able to finish a file in case one + // This however doesn't mean that eMule is guaranteed to be able to finish a file in case one // of the algorithms is completely broken, but we will bother about that if it becomes an issue. // At least with the current implementation nothing can go horribly wrong (from the security PoV) if (pbAICHReportedOK != NULL) @@ -3190,14 +3186,6 @@ bool CPartFile::HashSinglePart(UINT partnumber, bool *pbAICHReportedOK) return true; } - const ULONGLONG uOff = PARTSIZE * partnumber; - m_hpartfile.Seek((LONGLONG)uOff, 0); - uint32 length; - if (uOff + PARTSIZE > m_hpartfile.GetLength()) { - length = (UINT)(m_hpartfile.GetLength() - uOff); - ASSERT(length <= PARTSIZE); - } else - length = PARTSIZE; CAICHHashTree *phtAICHPartHash = NULL; if (m_FileIdentifier.HasAICHHash() && m_FileIdentifier.HasExpectedAICHHashCount()) { const CAICHHashTree *pPartTree = m_pAICHRecoveryHashSet->FindPartHash((uint16)partnumber); @@ -3208,13 +3196,16 @@ bool CPartFile::HashSinglePart(UINT partnumber, bool *pbAICHReportedOK) ASSERT(0); } - uchar hashresult[16]; + const ULONGLONG uOff = PARTSIZE * partnumber; + const uint64 length = mini(m_hpartfile.GetLength() - uOff, PARTSIZE); + uchar hashresult[MDX_DIGEST_SIZE]; + m_hpartfile.Seek((LONGLONG)uOff, CFile::begin); CreateHash(&m_hpartfile, length, hashresult, phtAICHPartHash); bool bMD4Error = false; bool bMD4Checked = m_FileIdentifier.HasExpectedMD4HashCount(); if (bMD4Checked) { - if (GetPartCount() > 1 || GetFileSize() == PARTSIZE) { + if (GetPartCount() > 1 || m_nFileSize == PARTSIZE) { if (m_FileIdentifier.GetAvailableMD4PartHashCount() > partnumber) bMD4Error = !md4equ(hashresult, m_FileIdentifier.GetMD4PartHash(partnumber)); else { @@ -3285,7 +3276,7 @@ bool CPartFile::IsPreviewableFileType() const void CPartFile::SetDownPriority(uint8 NewPriority, bool resort) { - //Changed the default resort to true. As it is was, we almost never sorted the download list when a priority changed. + //Changed the default re-sort to true. As it was, we almost never sorted the download list when a priority changed. //If we don't keep the download list sorted, priority means nothing in downloadqueue.cpp->process(). //Also, if we call this method with the same priority, don't do anything to help use less CPU cycles. if (m_iDownPriority != NewPriority) { @@ -3344,8 +3335,7 @@ void CPartFile::StopFile(bool bCancel, bool resort) m_LastSearchTimeKad = 0; m_TotalSearchesKad = 0; RemoveAllSources(true); - m_paused = true; - m_stopped = true; + m_paused = m_stopped = true; m_insufficient = false; m_datarate = 0; memset(m_anStates, 0, sizeof m_anStates); @@ -3353,7 +3343,7 @@ void CPartFile::StopFile(bool bCancel, bool resort) memset(net_stats, 0, sizeof net_stats); //Xman Bugfix if (!bCancel) - FlushBuffer(true); + FlushBuffer(); if (resort) { theApp.downloadqueue->SortByPriority(); theApp.downloadqueue->CheckDiskspace(); @@ -3367,7 +3357,7 @@ void CPartFile::StopPausedFile() EPartFileStatus uState = GetStatus(); if ((uState == PS_PAUSED || uState == PS_INSUFFICIENT || uState == PS_ERROR) && !m_stopped && time(NULL) >= m_iLastPausePurge + HR2S(1)) StopFile(); - else if (m_bDelayDelete && !IsAllocating()) + else if (m_bDelayDelete) DeletePartFile(); } @@ -3405,7 +3395,7 @@ void CPartFile::PauseFile(bool bInsufficient, bool resort) if (status == PS_COMPLETE || status == PS_COMPLETING) return; - for (POSITION pos = srclist.GetHeadPosition(); pos != NULL; ) { + for (POSITION pos = srclist.GetHeadPosition(); pos != NULL;) { CUpDownClient *cur_src = srclist.GetNext(pos); if (cur_src->GetDownloadState() == DS_DOWNLOADING) { cur_src->SendCancelTransfer(); @@ -3442,15 +3432,14 @@ void CPartFile::ResumeFile(bool resort) if (status == PS_COMPLETE || status == PS_COMPLETING) return; if (status == PS_ERROR && m_bCompletionError) { - ASSERT(m_gaplist.IsEmpty()); - if (m_gaplist.IsEmpty()) { + if (m_gaplist.IsEmpty() && m_BufferedData_list.IsEmpty()) { // file rehashing could probably be avoided, but better be on the safe side. m_bCompletionError = false; CompleteFile(false); - } + } else + ASSERT(0); } else { - m_paused = false; - m_stopped = false; + m_paused = m_stopped = false; SetActive(theApp.IsConnected()); m_LastSearchTime = 0; if (resort) { @@ -3488,7 +3477,7 @@ CString CPartFile::getPartfileStatus() const break; case PS_COMPLETING: { - CString strState = GetResString(IDS_COMPLETING); + CString strState(GetResString(IDS_COMPLETING)); switch (GetFileOp()) { case PFOP_HASHING: strState.AppendFormat(_T(" (%s)"), (LPCTSTR)GetResString(IDS_HASHING)); @@ -3544,12 +3533,12 @@ int CPartFile::getPartfileStatusRank() const time_t CPartFile::getTimeRemaining() const { uint64 completesize = (uint64)GetCompletedSize(); - time_t simple = (time_t)(GetDatarate() ? ((uint64)GetFileSize() - completesize) / GetDatarate() : -1); + time_t simple = (time_t)(GetDatarate() ? ((uint64)m_nFileSize - completesize) / GetDatarate() : -1); if (thePrefs.UseSimpleTimeRemainingComputation()) return simple; time_t tActive = GetDlActiveTime(); - time_t estimate = (time_t)((tActive && completesize >= 512000u) - ? ((uint64)GetFileSize() - completesize) / ((double)completesize / tActive) : -1); + time_t estimate = (time_t)((tActive && completesize >= 512000) + ? ((uint64)m_nFileSize - completesize) / ((double)completesize / tActive) : -1); if (estimate == (time_t)-1 || (simple > 0 && simple < estimate)) return simple; //not enough data to guess; no matter if we are transferring or not @@ -3590,15 +3579,11 @@ bool CPartFile::IsReadyForPreview() const if (ePreviewAppsRes != CPreviewApps::NotHandled) return (ePreviewAppsRes == CPreviewApps::Yes); - // Barry - Allow preview of archives if length > 1k + // Barry - Allow preview of archives only if length > 1k if (IsArchive(true)) { - //if (GetStatus() != PS_COMPLETE - // && GetStatus() != PS_COMPLETING - // && (uint64)GetFileSize() > 1024 - // && (uint64)GetCompletedSize() > 1024 - // && !m_bRecoveringArchive - // && GetFreeDiskSpaceX(thePrefs.GetTempDir()) + 100000000 > 2 * GetFileSize()) - // return true; + // check if we are already trying archive recovery on this part file + if (m_bRecoveringArchive) + return false; // check part file state switch (GetStatus()) { @@ -3607,12 +3592,8 @@ bool CPartFile::IsReadyForPreview() const return false; } - // check part file size(s) - if ((uint64)GetFileSize() < 1024ull || (uint64)GetCompletedSize() < 1024ull) - return false; - - // check if we already trying to recover an archive file from this part file - if (m_bRecoveringArchive) + // check available data size + if ((uint64)GetCompletedSize() < 1024) return false; // check free disk space @@ -3620,36 +3601,36 @@ bool CPartFile::IsReadyForPreview() const ? thePrefs.GetMinFreeDiskSpace() : 20 * 1024 * 1024; if (thePrefs.GetPreviewCopiedArchives()) - uMinFreeDiskSpace += (uint64)GetFileSize() * 2; + uMinFreeDiskSpace += (uint64)m_nFileSize * 2; else uMinFreeDiskSpace += (uint64)GetCompletedSize() + 16 * 1024; - return GetFreeDiskSpaceX(GetTempPath()) >= uMinFreeDiskSpace; + return GetFreeDiskSpaceX(GetTmpPath()) >= uMinFreeDiskSpace; } + if (m_bPreviewing) + return false; + if (thePrefs.IsMoviePreviewBackup()) - return !((GetStatus() != PS_READY && GetStatus() != PS_PAUSED) - || m_bPreviewing - || GetPartCount() < 5 - || !IsMovie() - || GetFreeDiskSpaceX(GetTempPath()) + 100000000 < (uint64)GetFileSize() - || !IsComplete(0, false) - || !IsComplete(PARTSIZE * (GetPartCount() - 1), (uint64)GetFileSize() - 1, false)); + return (GetStatus() == PS_READY || GetStatus() == PS_PAUSED) + && GetPartCount() >= 5 + && IsMovie() + && (uint64)m_nFileSize < GetFreeDiskSpaceX(GetTmpPath()) + 100000000 + && IsComplete(0) + && IsComplete(GetPartCount() - 1); TCHAR szVideoPlayerFileName[_MAX_FNAME]; _tsplitpath(thePrefs.GetVideoPlayer(), NULL, NULL, szVideoPlayerFileName, NULL); - // enable the preview command if the according option is specified 'PreviewSmallBlocks' + // enable the preview command if 'PreviewSmallBlocks' option is enabled // or if VideoLAN client is specified - if (thePrefs.GetPreviewSmallBlocks() || !_tcsicmp(szVideoPlayerFileName, _T("vlc"))) { - if (m_bPreviewing) - return false; - + if (thePrefs.GetPreviewSmallBlocks() || _tcsicmp(szVideoPlayerFileName, _T("vlc")) == 0) { switch (GetStatus()) { case PS_READY: case PS_EMPTY: case PS_PAUSED: case PS_INSUFFICIENT: - break; + if ((uint64)GetCompletedSize() >= 16 * 1024) //minimum data size check + break; default: return false; } @@ -3668,41 +3649,40 @@ bool CPartFile::IsReadyForPreview() const } } - // If it's an MPEG file, VLC is even capable of showing parts of the file if the beginning of the file is missing! - bool bMPEG = false; + // If it's an MPEG file, VLC is even capable to show parts of the file with an empty beginning! + bool bMPEG; LPCTSTR pszExt = _tcsrchr(GetFileName(), _T('.')); if (pszExt != NULL) { - CString strExt(pszExt); + CString strExt(pszExt + 1); strExt.MakeLower(); - bMPEG = (strExt == _T(".mpg") || strExt == _T(".mpeg") || strExt == _T(".mpe") || strExt == _T(".mp3") || strExt == _T(".mp2") || strExt == _T(".mpa")); - } + bMPEG = (strExt == _T("mpg") || strExt == _T("mpeg") || strExt == _T("mpe") || strExt == _T("mp3") || strExt == _T("mp2") || strExt == _T("mpa")); + } else + bMPEG = false; - if (bMPEG) { - // TODO: search a block which is at least 16K (Audio) or 256K (Video) - if ((uint64)GetCompletedSize() < 16 * 1024u) + // TODO: for MPEG to search a block which is at least 16K (Audio) or 256K (Video) + if (!bMPEG) { + // For AVI files it depends on the used codec + if ((uint64)GetCompletedSize() < 256 * 1024) //minimum data size return false; - } else { - // For AVI files it depends on the used codec. - if (thePrefs.GetPreviewSmallBlocks() >= 2) { - if ((uint64)GetCompletedSize() < 256 * 1024u) - return false; - } else if (!IsComplete(0, 256 * 1024, false)) + if (thePrefs.GetPreviewSmallBlocks() < 2 && !IsComplete(0, 256 * 1024)) return false; } return true; } - return !((GetStatus() != PS_READY && GetStatus() != PS_PAUSED) - || m_bPreviewing || GetPartCount() < 2 || !IsMovie() || !IsComplete(0, false)); + return (GetStatus() == PS_READY || GetStatus() == PS_PAUSED) + && GetPartCount() >= 2 + && IsMovie() + && IsComplete(0); } void CPartFile::UpdateAvailablePartsCount() { UINT availablecounter = 0; - for (UINT ixPart = GetPartCount(); ixPart-- > 0;) - for (POSITION pos = srclist.GetHeadPosition(); pos != NULL; ) - if (srclist.GetNext(pos)->IsPartAvailable(ixPart)) { + for (UINT nPart = GetPartCount(); nPart-- > 0;) + for (POSITION pos = srclist.GetHeadPosition(); pos != NULL;) + if (srclist.GetNext(pos)->IsPartAvailable(nPart)) { ++availablecounter; break; } @@ -3769,25 +3749,16 @@ Packet* CPartFile::CreateSrcInfoPacket(const CUpDownClient *forClient, uint8 byR continue; const uint8 *srcstatus = cur_src->GetPartStatus(); if (srcstatus && cur_src->GetPartCount() == GetPartCount()) { - bool bNeeded = false; - if (reqstatus) { - ASSERT(forClient->GetUpPartCount() == GetPartCount()); - // only send sources which have needed parts for this client - for (UINT x = GetPartCount(); x-- > 0;) - if (srcstatus[x] && !reqstatus[x]) { - bNeeded = true; - break; - } - } else { - // We know this client is valid. But don't know the part count status. So, currently we just send them. - for (UINT x = GetPartCount(); x-- > 0;) - if (srcstatus[x]) { - bNeeded = true; - break; - } - } + ASSERT(!reqstatus || forClient->GetUpPartCount() == GetPartCount()); + //If reqstatus is known, only send sources which have needed parts for this client + //Otherwise, we know this client is valid, but don't know the part count status, + //and currently we just send them all. + int i = GetPartCount(); + while (--i >= 0) + if (srcstatus[i] && (!reqstatus || !reqstatus[i])) + break; - if (bNeeded) { + if (i >= 0) { //found a needed part ++nCount; uint32 dwID = cur_src->GetUserIDHybrid(); if (byUsedVersion < 3) @@ -3820,10 +3791,10 @@ Packet* CPartFile::CreateSrcInfoPacket(const CUpDownClient *forClient, uint8 byR } if (!nCount) return 0; - data.Seek(bIsSX2Packet ? 17 : 16, SEEK_SET); + data.Seek(bIsSX2Packet ? 17 : 16, CFile::begin); data.WriteUInt16((uint16)nCount); - Packet *result = new Packet(&data, OP_EMULEPROT); + Packet *result = new Packet(data, OP_EMULEPROT); result->opcode = bIsSX2Packet ? OP_ANSWERSOURCES2 : OP_ANSWERSOURCES; // (1+)16+2+501*(4+2+4+2+16+1) = 14547 (14548) bytes max. if (result->size > 354) @@ -3912,7 +3883,6 @@ void CPartFile::AddClientSources(CSafeMemFile *sources, uint8 uClientSXVersion, CString strDbgClientInfo; if (pClient) strDbgClientInfo.Format(_T("%s, "), (LPCTSTR)pClient->DbgGetClientInfo()); - DebugLogWarning(_T("Received invalid SX2 packet - Version unknown (v%u), %sFile=\"%s\""), uClientSXVersion, (LPCTSTR)strDbgClientInfo, (LPCTSTR)GetFileName()); } return; @@ -3956,7 +3926,7 @@ void CPartFile::AddClientSources(CSafeMemFile *sources, uint8 uClientSXVersion, uint32 dwServerIP = sources->ReadUInt32(); uint16 nServerPort = sources->ReadUInt16(); - uchar achUserHash[16]; + uchar achUserHash[MDX_DIGEST_SIZE]; if (uPacketSXVersion >= 2) sources->ReadHash16(achUserHash); @@ -4039,17 +4009,15 @@ void CPartFile::AddClientSources(CSafeMemFile *sources, uint8 uClientSXVersion, smaller to fill a gap. */ uint32 CPartFile::WriteToBuffer(uint64 transize, const BYTE *data, uint64 start, uint64 end - , Requested_Block_Struct *block, const CUpDownClient *client) + , Requested_Block_Struct *block, const CUpDownClient *client, bool bCopyData) { - ASSERT((sint64)transize > 0); - ASSERT(start <= end); - + ASSERT((sint64)transize > 0 && end < (uint64)m_nFileSize && start <= end); // Increment transferred bytes counter for this file if (client) //Imported Parts are not counted as transferred m_uTransferred += transize; // This is needed a few times - const uint32 lenData = static_cast(end - start + 1); + const size_t lenData = static_cast(end - start + 1); ASSERT(end - start + 1 <= INT32_MAX); if (lenData > transize) { @@ -4058,21 +4026,21 @@ uint32 CPartFile::WriteToBuffer(uint64 transize, const BYTE *data, uint64 start, } static LPCTSTR const sImport = _T("(import)"); - // Occasionally packets are duplicated, no point writing it twice - if (IsComplete(start, end, false)) { + // Occasionally packets are duplicated, no point to write it twice + if (IsComplete(start, end)) { if (thePrefs.GetVerbose()) AddDebugLogLine(false, _T("PrcBlkPkt: Already written block %s; File=%s; %s"), (LPCTSTR)DbgGetBlockInfo(start, end), (LPCTSTR)GetFileName(), client ? (LPCTSTR)client->DbgGetClientInfo() : sImport); return 0; } // security sanitize check to make sure we do not write anything into already hashed complete chunks - const uint16 nStartChunk = (uint16)(start / PARTSIZE); - if (IsComplete(nStartChunk, false)) { + const UINT nStartPart = (unsigned)(start / PARTSIZE); + if (IsComplete(nStartPart)) { DebugLogError(_T("PrcBlkPkt: Received data touches already hashed chunk - ignored (start) %s; File=%s; %s"), (LPCTSTR)DbgGetBlockInfo(start, end), (LPCTSTR)GetFileName(), client ? (LPCTSTR)client->DbgGetClientInfo() : sImport); return 0; } - const uint16 nEndChunk = (uint16)(end / PARTSIZE); - if (nStartChunk != nEndChunk) { - if (IsComplete(nEndChunk, false)) { + const UINT nEndPart = (unsigned)(end / PARTSIZE); + if (nStartPart != nEndPart) { + if (IsComplete(nEndPart)) { DebugLogError(_T("PrcBlkPkt: Received data touches already hashed chunk - ignored (end) %s; File=%s; %s"), (LPCTSTR)DbgGetBlockInfo(start, end), (LPCTSTR)GetFileName(), client ? (LPCTSTR)client->DbgGetClientInfo() : sImport); return 0; } @@ -4082,170 +4050,180 @@ uint32 CPartFile::WriteToBuffer(uint64 transize, const BYTE *data, uint64 start, // log transfer information in our "blackbox" m_CorruptionBlackBox.TransferredData(start, end, client); - // Copy data to a new buffer - BYTE *buffer = new BYTE[lenData]; - memcpy(buffer, data, lenData); + // Copy data to a new buffer if necessary + BYTE *buffer; + if (bCopyData) { + buffer = new BYTE[lenData]; + memcpy(buffer, data, lenData); + } else + buffer = const_cast(data); // Create a new buffered queue entry - PartFileBufferedData *item = new PartFileBufferedData{start, end, buffer, block}; + PartFileBufferedData *newitem = new PartFileBufferedData{ start, end, buffer, block }; // Add to the queue at the correct position (most likely the end) POSITION after = NULL; for (POSITION pos = m_BufferedData_list.GetTailPosition(); pos != NULL;) { POSITION posLast = pos; - const PartFileBufferedData *cur_block = m_BufferedData_list.GetPrev(pos); - if (cur_block->end < item->end) { - ASSERT(cur_block->end < item->start); //the list is ordered, no overlaps - //if (cur_block->end >= item->start) - // DebugLogError(_T("WriteToBuffer: (%I64u >= %I64u)"), cur_block->end, item->start); + const PartFileBufferedData *item = m_BufferedData_list.GetPrev(pos); + if (item->end < newitem->end) { + ASSERT(item->end < newitem->start); //the list is ordered, no overlaps + //if (item->end >= newitem->start) + // DebugLogError(_T("WriteToBuffer: (%I64u >= %I64u)"), item->end, newitem->start); after = posLast; break; } } if (after) - m_BufferedData_list.InsertAfter(after, item); + m_BufferedData_list.InsertAfter(after, newitem); else - m_BufferedData_list.AddHead(item); + m_BufferedData_list.AddHead(newitem); // Increment buffer size marker m_nTotalBufferData += lenData; // Mark this small section of the file as filled - FillGap(item->start, item->end); + FillGap(newitem->start, newitem->end); - // Update the flushed mark on the requested block - if (IsInRequestedBlockList(block)) + // If client is known, the caller updates the flush mark on the requested block + // Otherwise, update here (for imported parts) + if (!client && requestedblocks_list.Find(block) != NULL) block->transferred += lenData; - if (m_gaplist.IsEmpty()) - FlushBuffer(true); - else if (GetStatus() != PS_READY && GetStatus() != PS_EMPTY) //import parts - FlushBuffer(); - else if (m_nTotalBufferData > thePrefs.GetFileBufferSize() * 2ull) - // We prefer to flush the buffer on our timer, but if we get over our limit too far + // We prefer to flush the buffer on timer, but if we get over our limit too far // (high speed upload), flush here to save memory and time on the buffer list + if (m_gaplist.IsEmpty() + || (GetStatus() != PS_READY && GetStatus() != PS_EMPTY) //import parts + || (m_nTotalBufferData > thePrefs.GetFileBufferSize() * 2ull)) + { FlushBuffer(); + } // Return the length of data written to the buffer - return lenData; + return static_cast(lenData); } -void CPartFile::FlushBuffer(bool forcewait, bool bForceICH, bool bNoAICH) +void CPartFile::FlushBuffer(bool bForceICH, bool bNoAICH) { m_nLastBufferFlushTime = ::GetTickCount(); - if (m_BufferedData_list.IsEmpty()) - return; - - if (IsAllocating()) - // disk space is being allocated right now. - // so don't write and keep the data in the buffer for later. + if (GetPartCount() <= 0) //&& m_BufferedData_list.IsEmpty()) return; - bool bIncreasedFile = (m_iAllocinfo > 0); - if (bIncreasedFile) - m_iAllocinfo = 0; - //if (thePrefs.GetVerbose()) // AddDebugLogLine(false, _T("Flushing file %s - buffer size = %ld bytes (%ld queued items) transferred = %ld [time = %ld]"), (LPCTSTR)GetFileName(), m_nTotalBufferData, m_BufferedData_list.GetCount(), m_uTransferred, m_nLastBufferFlushTime); - // Remember which parts need to be checked at the end of the flush - bool *changedPart = new bool[GetPartCount()](); //set array elements to false try { + ULONGLONG cursize = m_hpartfile.GetLength(); bool bCheckDiskspace = thePrefs.IsCheckDiskspaceEnabled() && thePrefs.GetMinFreeDiskSpace() > 0; - ULONGLONG uFreeDiskSpace = bCheckDiskspace ? GetFreeDiskSpaceX(GetTempPath()) : 0; - - // Check free disk space for compressed/sparse files before possibly increasing the file size - if (bCheckDiskspace && !IsNormalFile()) { - // Compressed/sparse files; regardless whether the file is increased in size, - // check the amount of data which will be written - // would need to use disk cluster sizes for more accuracy - if (m_nTotalBufferData + thePrefs.GetMinFreeDiskSpace() >= uFreeDiskSpace) - AfxThrowFileException(CFileException::diskFull, 0, m_hpartfile.GetFileName()); - } - - // Ensure file is big enough to write data to (the last item will be the furthest from the start) - PartFileBufferedData *item = m_BufferedData_list.GetTail(); - if (m_hpartfile.GetLength() <= item->end) { - uint64 newsize = thePrefs.GetAllocCompleteMode() ? (uint64)GetFileSize() : (item->end + 1); - ULONGLONG uIncrease = newsize - m_hpartfile.GetLength(); - - // Check free disk space for normal files before increasing the file size - if (bCheckDiskspace && IsNormalFile()) { - // Normal files; check if increasing the file would reduce - // the amount of min. free space below the limit. + //Previously full file allocation was performed in a special thread. That thread was writing + // 1 byte at the end of file. Overlapped I/O is already in a separate thread, and synchronising + // 3 threads could be fun. This fun may be avoided by using overlapped I/O for allocation too, + // but the catch is that writing at the end of file may damage already written valid data due to + // unpredictable order of overlapped operations. + // The solution would be this: + // If the very last byte of the file is buffered, use that buffer for allocation. + // Otherwise, write 1 byte after the real end of file and truncate after the write. + + //Full file allocation flag: 0 - none; 1 - write an extra byte; 2 - use buffered data + byte uAllocate = static_cast(cursize <= 0 && m_nTotalBufferData > 0 && IsNormalFile() && thePrefs.GetAllocCompleteMode()); + + ULONGLONG newsize; + if (IsNormalFile() && !m_BufferedData_list.IsEmpty()) { + // Get an offset closest to the end + newsize = m_BufferedData_list.GetTail()->end + 1; + if (uAllocate) { + if (newsize == (uint64)m_nFileSize) + uAllocate = 2; //using buffered data for allocation + else + newsize = (uint64)m_nFileSize; //write an extra byte + } else if (newsize < cursize) + newsize = 0; + } else + newsize = 0; // not calling SetLength + + // Check free disk space if required + if (bCheckDiskspace) { + ULONGLONG uFreeDiskSpace = GetFreeDiskSpaceX(GetTmpPath()); + ULONGLONG uIncrease = thePrefs.GetMinFreeDiskSpace(); + if (IsNormalFile()) { + if (newsize > cursize) + uIncrease += newsize - cursize; + } else { + // Check free disk space for compressed/sparse files before possibly increasing the file size + // regardless whether the file is increased in size, use the amount of data which will be written // Would need to use disk cluster sizes for more accuracy - if (uIncrease + thePrefs.GetMinFreeDiskSpace() >= uFreeDiskSpace) - AfxThrowFileException(CFileException::diskFull, 0, m_hpartfile.GetFileName()); + uIncrease += m_nTotalBufferData; } - - // Allocate file size - if (!forcewait && IsNormalFile() && uIncrease >= 2097152) { // <2MB -> alloc it at once - m_AllocateThread = AfxBeginThread(AllocateSpaceThread, this, THREAD_PRIORITY_LOWEST, 0, CREATE_SUSPENDED); - if (IsAllocating()) { - m_iAllocinfo = newsize; - m_AllocateThread->ResumeThread(); - delete[] changedPart; - return; + // See if increasing the file would reduce the amount of min. free space below the limit. + // Would need to use disk cluster sizes for more accuracy + if (uIncrease >= uFreeDiskSpace) + AfxThrowFileException(CFileException::diskFull, 0, m_hpartfile.GetFileName()); + } + // Ensure file is big enough for asynchronous writes + if (newsize) + m_hpartfile.SetLength(newsize); // may throw 'diskFull' + + //pass data to the writing thread + CPartFileWriteThread *pThread = theApp.m_pPartFileWriteThread; + if (pThread && pThread->IsRunning()) { + bool bLocked = false; + for (POSITION pos = m_BufferedData_list.GetHeadPosition(); pos != NULL;) { + PartFileBufferedData *item = m_BufferedData_list.GetNext(pos); + if (item->flushed == PB_READY) { + if (!bLocked) { + bLocked = true; + pThread->m_lockFlushList.Lock(); + if (uAllocate == 1) //an extra byte to allocate + pThread->m_FlushList.AddHead(ToWrite{ this, new PartFileBufferedData{ (uint64)m_nFileSize, (uint64)m_nFileSize } }); + } + if (uAllocate == 2 && pos == NULL) //using the last item for allocation + pThread->m_FlushList.AddHead(ToWrite{ this, item }); + else + pThread->m_FlushList.AddTail(ToWrite{ this, item }); + item->dwError = 0; //reset error (this could be a retry) + item->flushed = PB_PENDING; } - TRACE(_T("Failed to create alloc thread! -> allocate blocking\n")); } - - bIncreasedFile = true; - // If this is an NTFS compressed file and the current block is the 1st one to be written - // and there is not enough free disk space to hold the entire *uncompressed* file, - // windows throws 'diskFull'!? - if (IsNormalFile()) - m_hpartfile.SetLength(newsize); // allocate disk space (may throw 'diskFull') + if (bLocked) + pThread->m_lockFlushList.Unlock(); + if (!pThread->m_FlushList.IsEmpty()) //let it sleep if nothing to do + pThread->WakeUpCall(); } - // Loop through the queue - while (!m_BufferedData_list.IsEmpty()) { - // Get the top item - item = m_BufferedData_list.GetHead(); - - // SLUGFILLER: SafeHash - could be more than one part - for (uint32 curpart = (uint32)(item->start / PARTSIZE); curpart <= item->end / PARTSIZE; ++curpart) - changedPart[curpart] = true; - // SLUGFILLER: SafeHash - - // Go to the proper file position, and write block of data - m_hpartfile.Seek(item->start, CFile::begin); - - const uint32 lenData = (uint32)(item->end - item->start + 1); - m_hpartfile.Write(item->data, lenData); - - // Remove item from queue - m_BufferedData_list.RemoveHead(); - - // Decrease buffer size - m_nTotalBufferData -= lenData; - - // Release memory used by this item - delete[] item->data; - delete item; + //process data from the writing thread + for (POSITION pos = m_BufferedData_list.GetHeadPosition(); pos != NULL;) { + POSITION pos2 = pos; + PartFileBufferedData *item = m_BufferedData_list.GetNext(pos); + switch (item->flushed) { + case PB_READY: + ASSERT(!pThread || !pThread->IsRunning()); + case PB_PENDING: + continue; + case PB_ERROR: + item->flushed = PB_READY; //prepare for resend + CFileException::ThrowOsError((LONG)item->dwError, m_hpartfile.GetFileName()); + //default: + case PB_WRITTEN: //success + DeleteWrittenItem(pos2); + } } // Partfile should never be too large if (m_hpartfile.GetLength() > (uint64)m_nFileSize) { - // "last chance" correction. the real bugfix had to be applied 'somewhere' else - TRACE(_T("Partfile \"%s\" is too large! Truncating %I64u bytes.\n"), (LPCTSTR)GetFileName(), m_hpartfile.GetLength() - (uint64)m_nFileSize); + // "last chance" correction. the real bugfix had to be applied elsewhere + TRACE(_T("Partfile \"%s\" is too large! Truncating %I64u byte(s).\n"), (LPCTSTR)GetFileName(), m_hpartfile.GetLength() - (uint64)m_nFileSize); m_hpartfile.SetLength((uint64)m_nFileSize); } - // Flush to disk - m_hpartfile.Flush(); - - // Check each part of the file, starting from the last - uint64 partRange = (m_hpartfile.GetLength() % PARTSIZE > 0) ? m_hpartfile.GetLength() % PARTSIZE - 1 : PARTSIZE - 1; - for (UINT uPartNumber = GetPartCount(); uPartNumber-- > 0;) { - if (!changedPart[uPartNumber]) { - // Any part other than the last must be fully sized - partRange = PARTSIZE - 1; + // Check every changed part of the file + for (UINT uPartNumber = 0; uPartNumber < GetPartCount(); ++uPartNumber) { + if (!m_aChangedPart[uPartNumber]) continue; - } + m_aChangedPart[uPartNumber] = false; + const uint64 uStart = PARTSIZE * uPartNumber; - const uint64 uEnd = uStart + partRange; + const uint64 uEnd = min(uStart + PARTSIZE - 1, (uint64)m_nFileSize - 1); // Is this 9MB part complete - if (IsComplete(uStart, uStart + PARTSIZE - 1, false)) { + if (IsCompleteBD(uStart, uEnd)) { // Is part corrupt bool bAICHAgreed; if (!HashSinglePart(uPartNumber, &bAICHAgreed)) { @@ -4256,13 +4234,14 @@ void CPartFile::FlushBuffer(bool forcewait, bool bForceICH, bool bNoAICH) if (!IsCorruptedPart(uPartNumber)) corrupted_list.AddTail((uint16)uPartNumber); - // request AICH recovery data, except if AICH already agreed anyway or we explicit don't want to + // request AICH recovery data, except if AICH already agreed anyway or we explicitly don't want to if (!bNoAICH && !bAICHAgreed) RequestAICHRecovery(uPartNumber); // update stats - m_uCorruptionLoss += partRange + 1; - thePrefs.Add2LostFromCorruption(partRange + 1); + uint64 lost = uEnd - uStart + 1; + m_uCorruptionLoss += lost; + thePrefs.Add2LostFromCorruption(lost); } else { if (!m_bMD4HashsetNeeded && thePrefs.GetVerbose()) AddDebugLogLine(DLP_VERYLOW, false, _T("Finished part %u of \"%s\""), uPartNumber, (LPCTSTR)GetFileName()); @@ -4311,33 +4290,33 @@ void CPartFile::FlushBuffer(bool forcewait, bool bForceICH, bool bNoAICH) AddToSharedFiles(); // Successfully recovered part, make it available for sharing } } - - // Any parts other than last must be full size - partRange = PARTSIZE - 1; } - // Update met file - SavePartFile(); + SavePartFile(); // Update met file if (!theApp.IsClosing()) { // may be called during shutdown! // Is this file finished? - if (m_gaplist.IsEmpty()) - CompleteFile(false); - else if (m_bPauseOnPreview && IsReadyForPreview()) { + if (m_gaplist.IsEmpty()) { + if (m_iWrites <= 0 && m_BufferedData_list.IsEmpty() && GetStatus() != PS_COMPLETING) + CompleteFile(false); + else + m_nLastBufferFlushTime -= thePrefs.GetFileBufferTimeLimit() - 211; //try again shortly + } else if (m_bPauseOnPreview && IsReadyForPreview()) { m_bPauseOnPreview = false; PauseFile(); } // Check free disk space // - // Checking the free disk space again after the file was written could most likely be avoided, but because - // we do not use real physical disk allocation units for the free disk computations, it should be more safe - // and accurate to check the free disk space again, after file was written and buffers were flushed to disk. + // Checking the free disk space again after the file was written could most likely be avoided, + // but because we do not use real physical disk allocation units for the free disk computations, + // it should be more safe and accurate to check the free disk space again, after file was written + // and buffers were flushed to disk. // - // If using a normal file, we could avoid the check disk space if the file was not increased. + // If using a normal file, we could avoid disk space check if the file was not increased. // If using a compressed or sparse file, we always have to check the space // regardless whether the file was increased in size or not. - if (bCheckDiskspace && (!IsNormalFile() || bIncreasedFile)) { + if (bCheckDiskspace && !IsNormalFile()) { switch (GetStatus()) { case PS_PAUSED: case PS_ERROR: @@ -4345,10 +4324,10 @@ void CPartFile::FlushBuffer(bool forcewait, bool bForceICH, bool bNoAICH) case PS_COMPLETE: break; default: - if (GetFreeDiskSpaceX(GetTempPath()) < thePrefs.GetMinFreeDiskSpace()) { + if (GetFreeDiskSpaceX(GetTmpPath()) < thePrefs.GetMinFreeDiskSpace()) { // Compressed/sparse files: always pause the file // Normal files: pause the file only if it would still grow - if (!IsNormalFile() || GetNeededSpace() > 0) + //if (!IsNormalFile() || GetNeededSpace() > 0) PauseFile(true); } } @@ -4362,7 +4341,6 @@ void CPartFile::FlushBuffer(bool forcewait, bool bForceICH, bool bNoAICH) FlushBuffersExceptionHandler(); } #endif - delete[] changedPart; } void CPartFile::FlushBuffersExceptionHandler(CFileException *error) @@ -4389,7 +4367,7 @@ void CPartFile::FlushBuffersExceptionHandler(CFileException *error) msg.Format(GetResString(IDS_ERR_OUTOFSPACE), (LPCTSTR)GetFileName()); LogError(LOG_STATUSBAR, msg); // may be called during shutdown! - if (!theApp.IsClosing() && thePrefs.GetNotifierOnImportantError()) + if (thePrefs.GetNotifierOnImportantError() && !theApp.IsClosing()) theApp.emuledlg->ShowNotifier(msg, TBN_IMPORTANTEVENT); } else { TCHAR buffer[MAX_CFEXP_ERRORMSG]; @@ -4404,8 +4382,11 @@ void CPartFile::FlushBuffersExceptionHandler(CFileException *error) m_anStates[DS_DOWNLOADING] = 0; } - if (!theApp.IsClosing()) // may be called during shutdown! + if (!theApp.IsClosing()) { // may be called during shutdown! + if (GetStatus() == PS_ERROR && srcarevisible) + theApp.emuledlg->transferwnd->GetDownloadList()->HideSources(this); UpdateDisplayedInfo(); + } error->Delete(); } @@ -4424,64 +4405,29 @@ void CPartFile::FlushBuffersExceptionHandler() UpdateDisplayedInfo(); } -UINT AFX_CDECL CPartFile::AllocateSpaceThread(LPVOID lpParam) -{ - DbgSetThreadName("Partfile-Allocate Space"); - InitThreadLocale(); - - CPartFile *myfile = reinterpret_cast(lpParam); - theApp.QueueDebugLogLine(false, _T("ALLOC:Start (%s) (%s)"), (LPCTSTR)myfile->GetFileName(), (LPCTSTR)CastItoXBytes(myfile->m_iAllocinfo)); - - try { - // If this is an NTFS compressed file and the current block is the 1st one to be written and there is not - // enough free disk space to hold the entire *uncompressed* file, windows throws a 'diskFull'!? - myfile->m_hpartfile.SetLength(myfile->m_iAllocinfo); // allocate disk space (may throw 'diskFull') - - // force the alloc, by temporary writing a non-zero to the file end - static const byte x00 = 0, xFF = 255; - myfile->m_hpartfile.Seek(-1, CFile::end); - myfile->m_hpartfile.Write(&xFF, 1); - myfile->m_hpartfile.Flush(); - myfile->m_hpartfile.Seek(-1, CFile::end); - myfile->m_hpartfile.Write(&x00, 1); - myfile->m_hpartfile.Flush(); - } catch (CFileException *error) { - VERIFY(theApp.emuledlg->PostMessage(TM_FILEALLOCEXC, (WPARAM)myfile, (LPARAM)error)); - myfile->m_AllocateThread = NULL; - - return 1; - } -#ifndef _DEBUG - catch (...) { - VERIFY(theApp.emuledlg->PostMessage(TM_FILEALLOCEXC, (WPARAM)myfile, 0)); - myfile->m_AllocateThread = NULL; - return 2; - } -#endif - - myfile->m_AllocateThread = NULL; - theApp.QueueDebugLogLine(false, _T("ALLOC:End (%s)"), (LPCTSTR)myfile->GetFileName()); - return 0; -} - -// Barry - This will invert the gap list, it is up to the caller to delete gaps when done -// 'Gaps' returned is an ordered list of the filled areas (for archive recovery). +// Barry - This will invert the gap list, the caller have to delete gaps when done +// 'Gaps' returned is an ordered array of the filled areas (for archive recovery and backup copies). // Note, that end values are not decremented by 1 as it was for ordinary gaps. -void CPartFile::GetFilledList(CTypedPtrList *filled) const +// +//Different usage of 'end' for 'fills' and 'gaps' is annoying and might get fixed later +void CPartFile::GetFilledArray(CArray &filled) const { + filled.RemoveAll(); if (m_gaplist.IsEmpty()) return; + uint64 uEnd = (uint64)m_nFileSize; + INT_PTR iCnt = m_gaplist.GetCount() + static_cast(m_gaplist.GetTail().end < uEnd); + filled.SetSize(iCnt); uint64 start = 0; + INT_PTR i = 0; for (POSITION pos = m_gaplist.GetHeadPosition(); pos != NULL;) { - Gap_Struct *gap = m_gaplist.GetNext(pos); - if (gap->start > start) - filled->AddTail(new Gap_Struct{ start, gap->start }); - start = gap->end + 1; + const Gap_Struct &gap = m_gaplist.GetNext(pos); + if (gap.start > start) + filled[i++] = Gap_Struct{ start, gap.start }; + start = gap.end + 1; } - - uint64 uEnd = (uint64)m_nFileSize; if (start < uEnd) - filled->AddTail(new Gap_Struct{ start, uEnd });; + filled[i] = Gap_Struct{ start, uEnd }; } void CPartFile::UpdateFileRatingCommentAvail(bool bForceUpdate) @@ -4502,7 +4448,7 @@ void CPartFile::UpdateFileRatingCommentAvail(bool bForceUpdate) uUserRatings += cur_src->GetFileRating(); } } - for (POSITION pos = m_kadNotes.GetHeadPosition(); pos != NULL; ) { + for (POSITION pos = m_kadNotes.GetHeadPosition(); pos != NULL;) { const Kademlia::CEntry *entry = m_kadNotes.GetNext(pos); if (!m_bHasComment && !entry->GetStrTagValue(Kademlia::CKadTagNameString(TAG_DESCRIPTION)).IsEmpty()) m_bHasComment = true; @@ -4522,7 +4468,7 @@ void CPartFile::UpdateFileRatingCommentAvail(bool bForceUpdate) void CPartFile::UpdateDisplayedInfo(bool force) { if (!theApp.IsClosing()) { - DWORD curTick = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); if (force || curTick >= m_lastRefreshedDLDisplay + MINWAIT_BEFORE_DLDISPLAY_WINDOWUPDATE + m_random_update_wait) { theApp.emuledlg->transferwnd->GetDownloadList()->UpdateItem(this); @@ -4564,8 +4510,10 @@ const CStringA CPartFile::GetProgressString(uint16 size) const static const char crProgress = '0'; //green static const char crHave = '1'; //black static const char crPending = '2'; //yellow - static const char crMissing = '3'; //red - static const char crWaiting[7] = "456789"; //blue '4' - few sources, '9' - full sources + //static const char crMissing = '3'; //red + //static const char crWaiting[7] = "456789"; //blue '4' - few sources, '9' - full sources + //red '3' - missing (no sources), blue: '4' - few sources, '9' - many sources + static const char crSources[8] = "3456789"; CStringA my_ChunkBar(crHave, size + 2); // two more for safety @@ -4573,14 +4521,15 @@ const CStringA CPartFile::GetProgressString(uint16 size) const if (GetStatus() == PS_COMPLETE || GetStatus() == PS_COMPLETING) CharFillRange(my_ChunkBar, 0, (uint32)((uint64)m_nFileSize * unit), crProgress); - else + else { // red gaps + UINT i = 0; for (POSITION pos = m_gaplist.GetHeadPosition(); pos != NULL;) { - Gap_Struct *gap = m_gaplist.GetNext(pos); + const Gap_Struct &gap = m_gaplist.GetNext(pos); bool gapdone = false; - uint64 start = gap->start; - uint64 end = gap->end; - for (INT_PTR i = 0; i < GetPartCount(); ++i) { + uint64 start = gap.start; + uint64 end = gap.end; + for (; i < GetPartCount(); ++i) { if (start >= i * PARTSIZE && start <= (i + 1) * PARTSIZE) { // is in this part? if (end <= (i + 1) * PARTSIZE) gapdone = true; @@ -4588,27 +4537,25 @@ const CStringA CPartFile::GetProgressString(uint16 size) const end = (i + 1) * PARTSIZE; // and next part // paint uint8 color; - if (m_SrcPartFrequency.GetCount() >= i && m_SrcPartFrequency[i]) // frequency? - //color = crWaiting; - color = m_SrcPartFrequency[i] < 10 ? crWaiting[m_SrcPartFrequency[i] / 2] : crWaiting[5]; + if (i < (UINT)m_SrcPartFrequency.GetCount()) + color = crSources[min((m_SrcPartFrequency[i] + 1) / 2, sizeof crSources - 1)]; else - color = crMissing; - + color = crSources[0]; //crMissing CharFillRange(my_ChunkBar, (uint32)(start * unit), (uint32)(end * unit + 1), color); if (gapdone) // finished? break; start = end; - end = gap->end; + end = gap.end; } } } - + } // yellow pending parts for (POSITION pos = requestedblocks_list.GetHeadPosition(); pos != NULL;) { const Requested_Block_Struct *block = requestedblocks_list.GetNext(pos); - CharFillRange(my_ChunkBar, (uint32)((block->StartOffset + block->transferred) * unit), (uint32)(block->EndOffset*unit), crPending); + CharFillRange(my_ChunkBar, (uint32)((block->StartOffset + block->transferred) * unit), (uint32)(block->EndOffset * unit), crPending); } return my_ChunkBar; @@ -4622,16 +4569,34 @@ void CPartFile::CharFillRange(CStringA &buffer, uint32 start, uint32 end, char c void CPartFile::AddToSharedFiles() { - if (!theApp.IsClosing() // may be called during shutdown! - && status == PS_EMPTY + if (status == PS_EMPTY + && !m_bMD4HashsetNeeded && m_FileIdentifier.HasExpectedMD4HashCount() - && !m_bMD4HashsetNeeded) + && !theApp.IsClosing()) // may be called during shutdown! { SetStatus(PS_READY); //available for sharing theApp.sharedfiles->SafeAddKFile(this); } } +void CPartFile::DeleteWrittenItem(const POSITION pos) +{ + const PartFileBufferedData *item = m_BufferedData_list.GetAt(pos); + ASSERT(!item->dwError); + m_nTotalBufferData -= item->end - item->start + 1; + // SLUGFILLER: SafeHash - could be more than one part + for (INT_PTR i = (INT_PTR)(item->start / PARTSIZE); i <= (INT_PTR)(item->end / PARTSIZE); ++i) + m_aChangedPart[i] = true; + // SLUGFILLER: SafeHash + + m_BufferedData_list.RemoveAt(pos); + delete[] item->data; + delete item; + + if (!m_nFileFlushTime) + m_nFileFlushTime = ::GetTickCount(); +} + void CPartFile::SetCategory(UINT cat) { m_category = cat; @@ -4685,7 +4650,6 @@ UINT CPartFile::GetTransferringSrcCount() const } // [Maella -Enhanced Chunk Selection- (based on jicxicmic)] - #pragma pack(push, 1) struct Chunk { @@ -4693,13 +4657,13 @@ struct Chunk union { uint16 frequency; // Availability of the chunk - uint16 rank; // Download priority factor (highest = 0, lowest = 0xffff) + uint16 rank; // Download priority factor (highest = 0, lowest = _UI16_MAX) }; }; #pragma pack(pop) bool CPartFile::GetNextRequestedBlock(CUpDownClient *sender, Requested_Block_Struct **newblocks - , uint16 *pcount) /*const*/ + , int &iCount) /*const*/ { // The purpose of this function is to return a list of blocks (~180KB) to // download. To avoid a premature stop of the downloading, all blocks that @@ -4713,49 +4677,49 @@ bool CPartFile::GetNextRequestedBlock(CUpDownClient *sender, Requested_Block_Str // The selection is based on several criteria: // - Frequency of the chunk (availability), very rare chunks must be downloaded // as quickly as possible to become a new available source. - // - Parts used for preview (first + last chunk), preview or check a + // - Parts used for preview (first + last chunk); to preview or check a // file (e.g. movie, mp3) - // - Completion (shortest-to-complete), partially retrieved chunks should be - // completed before starting to download other one. + // - Completion (nearest-to-complete), partially retrieved chunks should be + // completed before starting to download an other one. // - // The frequency criterion defines several zones: very rare, rare, almost rare, - // and common. Inside each zone, the criteria have a specific weight, used + // The frequency criterion defines 4 grades of availability: very rare, rare, almost rare, + // and common. Inside each grade, the criteria have a specific weight, used // to calculate the priority of chunks. The chunk(s) with the highest // priority (highest=0, lowest=0xffff) is/are selected first. // - // This algorithm usually selects the rarest chunk(s) first. However, partially - // complete chunk(s) that is/are close to completion may overtake the priority - // (priority inversion). For common chunks, it also tries to put the transferring - // clients on the same chunk, to complete it sooner. + // This algorithm usually selects the rarest chunk(s). However, chunk(s) that is/are + // close to completion may still get a higher priority (priority inversion). + // For common chunks to complete faster, it also tries to put the transferring clients + // onto the same chunk. // // Check input parameters - if (pcount == NULL || sender->GetPartStatus() == NULL) + if (iCount <= 0 || sender->GetPartStatus() == NULL) return false; //AddDebugLogLine(DLP_VERYLOW, false, _T("Evaluating chunks for file: \"%s\" Client: %s"), (LPCTSTR)GetFileName(), (LPCTSTR)sender->DbgGetClientInfo()); // Define and create the list of the chunks to download - const uint16 partCount = GetPartCount(); + const UINT partCount = GetPartCount(); CList chunksList(partCount); - uint16 tempLastPartAsked = _UI16_MAX; - if (sender->m_lastPartAsked != _UI16_MAX && sender->GetClientSoft() == SO_EMULE && sender->GetVersion() < MAKE_CLIENT_VERSION(0, 43, 1)) - tempLastPartAsked = sender->m_lastPartAsked; + uint16 tempLastPartAsked = sender->m_lastPartAsked; + if (tempLastPartAsked != _UI16_MAX && (sender->GetClientSoft() != SO_EMULE || sender->GetVersion() < MAKE_CLIENT_VERSION(0, 43, 1))) + tempLastPartAsked = _UI16_MAX; // Main loop - uint16 newBlockCount = 0; - while (newBlockCount != *pcount) { + int newBlockCount = 0; + while (newBlockCount < iCount) { // Create a request block structure if a chunk has been previously selected if (tempLastPartAsked != _UI16_MAX) { Requested_Block_Struct *pBlock = new Requested_Block_Struct; if (GetNextEmptyBlockInPart(tempLastPartAsked, pBlock)) { //AddDebugLogLine(false, _T("Got request block. Interval %i-%i. File %s. Client: %s"), pBlock->StartOffset, pBlock->EndOffset, (LPCTSTR)GetFileName(), (LPCTSTR)sender->DbgGetClientInfo()); - // Keep a track of all pending requested blocks + // Keep track of all pending requested blocks requestedblocks_list.AddTail(pBlock); // Update list of blocks to return newblocks[newBlockCount++] = pBlock; - // Skip end of loop (=> CPU load) + // Skip the rest of the main loop (=> CPU load) continue; } // All blocks for this chunk have been already requested @@ -4763,27 +4727,20 @@ bool CPartFile::GetNextRequestedBlock(CUpDownClient *sender, Requested_Block_Str // => Try to select another chunk sender->m_lastPartAsked = tempLastPartAsked = _UI16_MAX; } - - // Check if a new chunk must be selected (e.g. download starting, previous chunk complete) -// if(tempLastPartAsked == _UI16_MAX) { - always true here + // A new chunk must be selected (e.g. download starting, previous chunk complete) // Quantify all chunks (create list of chunks to download) // This is done only one time and only if it is necessary (=> CPU load) if (chunksList.IsEmpty()) { // Identify the locally missing part(s) that this source has - for (uint16 i = 0; i < partCount; ++i) { - if (sender->IsPartAvailable(i) && GetNextEmptyBlockInPart(i, NULL)) { - // Create a new entry for this chunk and add it to the list - Chunk newEntry; - newEntry.part = i; - newEntry.frequency = m_SrcPartFrequency[i]; - chunksList.AddTail(newEntry); - } - } + for (UINT i = 0; i < partCount; ++i) + if (sender->IsPartAvailable(i) && GetNextEmptyBlockInPart(i, NULL)) + // Add to the list a new entry for this chunk + chunksList.AddTail(Chunk{ (uint16)i, { m_SrcPartFrequency[i]} }); // Check if any block(s) could be downloaded if (chunksList.IsEmpty()) - break; // Exit main loop while() + break; // Exit the main loop // Define the bounds of the zones (very rare, rare etc) // more depending on available sources @@ -4794,7 +4751,9 @@ bool CPartFile::GetNextRequestedBlock(CUpDownClient *sender, Requested_Block_Str const uint16 almostRareBound = 4 * limit; // Cache Preview state (Criterion 2) - const bool isPreviewEnable = (thePrefs.GetPreviewPrio() || (thePrefs.IsExtControlsEnabled() && GetPreviewPrio())) && IsPreviewableFileType(); + const bool isPreviewEnable = (thePrefs.GetPreviewPrio() || (GetPreviewPrio() && thePrefs.IsExtControlsEnabled())) + && (uint64)m_nFileSize > 2 * PARTSIZE + && IsPreviewableFileType(); // Collect and calculate criteria for all chunks for (POSITION pos = chunksList.GetHeadPosition(); pos != NULL;) { @@ -4803,53 +4762,44 @@ bool CPartFile::GetNextRequestedBlock(CUpDownClient *sender, Requested_Block_Str // Offsets of chunk UINT uCurChunkPart = cur_chunk.part; // help VC71... const uint64 uStart = uCurChunkPart * PARTSIZE; - const uint64 uEnd = min(uStart + PARTSIZE, (uint64)GetFileSize()) - 1; + const uint64 uEnd = min(uStart + PARTSIZE - 1, (uint64)m_nFileSize - 1); ASSERT(uStart <= uEnd); // Criterion 2. Parts used for preview // Remark: - We need to download the first part and the last part(s). - // - When the last part is very small, it's necessary to - // download the two last parts. - bool critPreview = false; - if (isPreviewEnable) { - if (cur_chunk.part == 0) - critPreview = true; // First chunk - else if (cur_chunk.part == partCount - 1) - critPreview = true; // Last chunk - else if (cur_chunk.part == partCount - 2) { - // Last chunk - 1 (only if last chunk is too small) - if (GetFileSize() - uEnd < PARTSIZE / 3) - critPreview = true; // Last chunk - 1 - } - } + // - When the last part is very small, it's necessary to + // download the two last parts. + bool critPreview = isPreviewEnable + && (cur_chunk.part == 0 // First chunk + || cur_chunk.part == partCount - 1 // Last chunk + || (cur_chunk.part == partCount - 2 && m_nFileSize - uEnd < PARTSIZE / 3)); // Criterion 3. Request state (downloading in process from other source(s)) - //const bool critRequested = IsAlreadyRequested(uStart, uEnd); bool critRequested = false; // <--- This is set as a part of the second critCompletion loop below // Criterion 4. Completion uint64 partSize = uEnd - uStart + 1; //If all is covered by gaps, we have downloaded PARTSIZE, or possibly less for the last chunk ASSERT(partSize <= PARTSIZE); for (POSITION pos1 = m_gaplist.GetHeadPosition(); pos1 != NULL;) { - const Gap_Struct *gap = m_gaplist.GetNext(pos1); - if (gap->start > uEnd) + const Gap_Struct &gap = m_gaplist.GetNext(pos1); + if (gap.start > uEnd) break; // Check if Gap is within the bounds - if (gap->start < uStart) { - if (gap->end > uStart && gap->end < uEnd) { - ASSERT(partSize >= (gap->end - uStart + 1)); - partSize -= gap->end - uStart + 1; - } else if (gap->end >= uEnd) { + if (gap.start < uStart) { + if (gap.end > uStart && gap.end < uEnd) { + ASSERT(partSize >= (gap.end - uStart + 1)); + partSize -= gap.end - uStart + 1; + } else if (gap.end >= uEnd) { partSize = 0; - break; // exit loop for() + break; // exit Criterion 4 loop } - } else { //if (gap->start <= uEnd) { - if (gap->end < uEnd) { - ASSERT(partSize >= (gap->end - gap->start + 1)); - partSize -= gap->end - gap->start + 1; + } else { //if (gap.start <= uEnd) { + if (gap.end < uEnd) { + ASSERT(partSize >= (gap.end - gap.start + 1)); + partSize -= gap.end - gap.start + 1; } else { - ASSERT(partSize >= (uEnd - gap->start + 1)); - partSize -= uEnd - gap->start + 1; + ASSERT(partSize >= (uEnd - gap.start + 1)); + partSize -= uEnd - gap.start + 1; } } } @@ -4858,7 +4808,7 @@ bool CPartFile::GetNextRequestedBlock(CUpDownClient *sender, Requested_Block_Str // requested blocks from sources we are currently downloading from are counted as if already downloaded // This code will cause bytes that has been requested AND transferred to be counted twice, so we can end // up with a completion number > PARTSIZE. That's OK, since it's just a relative number to compare chunks. - for (POSITION reqPos = requestedblocks_list.GetHeadPosition(); reqPos != NULL; ) { + for (POSITION reqPos = requestedblocks_list.GetHeadPosition(); reqPos != NULL;) { const Requested_Block_Struct *reqBlock = requestedblocks_list.GetNext(reqPos); if (reqBlock->StartOffset < uStart) { if (reqBlock->EndOffset > uStart) { @@ -4903,7 +4853,7 @@ bool CPartFile::GetNextRequestedBlock(CUpDownClient *sender, Requested_Block_Str // Calculate criterion 6 and 7 if (transferringClientsScore > 1) { UINT totalDownloadDatarateForThisPart = 1; - for (POSITION downloadingClientPos = m_downloadingSourceList.GetHeadPosition(); downloadingClientPos != NULL; ) { + for (POSITION downloadingClientPos = m_downloadingSourceList.GetHeadPosition(); downloadingClientPos != NULL;) { const CUpDownClient *downloadingClient = m_downloadingSourceList.GetNext(downloadingClientPos); if (downloadingClient->IsPartAvailable(cur_chunk.part)) { --transferringClientsScore; @@ -4913,7 +4863,7 @@ bool CPartFile::GetNextRequestedBlock(CUpDownClient *sender, Requested_Block_Str bandwidthScore = (uint16)min((UINT)((PARTSIZE - partSize) / (totalDownloadDatarateForThisPart * 5ull)), 2000u); //AddDebugLogLine(DLP_VERYLOW, false - // , _T("BandwidthScore for chunk %i: bandwidthScore = %u = min((PARTSIZE-partSize)/(totalDownloadDatarateForThisChunk*5), 2000u) = min((PARTSIZE-%I64u)/(%u*5), 2000)") + // , _T("BandwidthScore for chunk %i: bandwidthScore = %u = min((PARTSIZE-partSize)/(totalDownloadDatarateForThisChunk * 5), 2000u) = min((PARTSIZE-%I64u)/(%u*5), 2000u)") // , cur_chunk.part, bandwidthScore, partSize, totalDownloadDatarateForThisChunk); } @@ -4923,8 +4873,8 @@ bool CPartFile::GetNextRequestedBlock(CUpDownClient *sender, Requested_Block_Str if (partSize > 0 && GetSourceCount() <= GetSrcA4AFCount()) { // If there are too many a4af sources, the completion of blocks have very high prio cur_chunk.rank = (cur_chunk.frequency) // Criterion 1 - + static_cast(!critRequested) // Criterion 3 + (critPreview ? 0 : 200) // Criterion 2 + + static_cast(!critRequested) // Criterion 3 + (100 - critCompletion) // Criterion 4 + static_cast(!sameChunk) // Criterion 5 + bandwidthScore; // Criterion 7 @@ -4956,7 +4906,7 @@ bool CPartFile::GetNextRequestedBlock(CUpDownClient *sender, Requested_Block_Str //ASSERT(cur_chunk.frequency >= rareBound); // used to slightly lessen the importance of frequency - uint16 randomAdd = 1 + (uint16)((((uint32)rand() * (almostRareBound - rareBound)) + (RAND_MAX / 2)) / RAND_MAX); + uint16 randomAdd = (uint16)((3 * RAND_MAX / 2 + (uint32)rand() *(almostRareBound - rareBound)) / RAND_MAX); //AddDebugLogLine(DLP_VERYLOW, false, _T("RandomAdd: %i, (%i-%i=%i)"), randomAdd, rareBound, almostRareBound, almostRareBound-rareBound); cur_chunk.rank = (cur_chunk.frequency) // Criterion 1 @@ -4973,84 +4923,72 @@ bool CPartFile::GetNextRequestedBlock(CUpDownClient *sender, Requested_Block_Str + static_cast(!sameChunk) // Criterion 5 + bandwidthScore; // Criterion 7 } - //AddDebugLogLine(DLP_VERYLOW, false, _T("Rank: %u"), cur_chunk.rank); } } - if (chunksList.IsEmpty()) - // There is no remaining chunk to download - break; // Exit the main while() loop + if (chunksList.IsEmpty()) // No chunks remained to download + break; // Exit the main loop // Select the next chunk to download // Find and count the chunk(s) with the highest priority - uint16 cnt = 0; // Number of found chunks with same priority + int cnt = 0; // Number of found chunks with the same priority uint16 rank = _UI16_MAX; // Highest priority found + CArray aBest; + aBest.SetSize(partCount); for (POSITION pos = chunksList.GetHeadPosition(); pos != NULL;) { + POSITION pos2 = pos; const Chunk &cur_chunk = chunksList.GetNext(pos); if (cur_chunk.rank < rank) { - cnt = 1; + cnt = 0; rank = cur_chunk.rank; - } else - cnt += static_cast(cur_chunk.rank == rank); + } + if (cur_chunk.rank == rank) + aBest[cnt++] = pos2; } - // Use a random access to avoid that everybody tries to download the + // Pick a random chunk to avoid that everybody tries to download the // same chunks at the same time (=> spread the selected chunk among clients) - uint16 randomness = 1 + (uint16)((((uint32)rand() * (cnt - 1)) + (RAND_MAX / 2)) / RAND_MAX); - for (POSITION pos = chunksList.GetHeadPosition(); pos != NULL;) { - POSITION cur_pos = pos; - const Chunk &cur_chunk = chunksList.GetNext(pos); - if (cur_chunk.rank == rank) { - if (--randomness == 0) { - // Selection process is over - sender->m_lastPartAsked = tempLastPartAsked = cur_chunk.part; - //AddDebugLogLine(DLP_VERYLOW, false, _T("Chunk number %i selected. Rank: %u"), cur_chunk.part, cur_chunk.rank); - - // Remark: this list might be reused up to *count times - chunksList.RemoveAt(cur_pos); - break; // exit loop for() - } - } - } -// } + POSITION pos = aBest[cnt > 1 ? rand() % cnt : 0]; + sender->m_lastPartAsked = tempLastPartAsked = chunksList.GetAt(pos).part; + chunksList.RemoveAt(pos); } // Return the number of the blocks - *pcount = newBlockCount; + iCount = newBlockCount; // Return return (newBlockCount > 0); } // Maella end - CString CPartFile::GetInfoSummary(bool bNoFormatCommands) const { if (!IsPartFile()) return CKnownFile::GetInfoSummary(); - CString compl; - compl.Format(_T("%s: %s/%s (%.1f%%)") - , (LPCTSTR)GetResString(IDS_DL_TRANSFCOMPL) + CString compl(GetResString(IDS_DL_TRANSFCOMPL)); + compl.AppendFormat(_T(": %s/%s (%.1f%%)") , (LPCTSTR)CastItoXBytes((uint64)GetCompletedSize()) - , (LPCTSTR)CastItoXBytes((uint64)GetFileSize()) + , (LPCTSTR)CastItoXBytes((uint64)m_nFileSize) , GetPercentCompleted()); - const CString &lsc = (lastseencomplete != 0) ? lastseencomplete.Format(thePrefs.GetDateTimeFormat()) : GetResString(IDS_NEVER); + const CString &lsc((lastseencomplete > 0) ? lastseencomplete.Format(thePrefs.GetDateTimeFormat()) : GetResString(IDS_NEVER)); float availability = (GetPartCount() > 0) ? GetAvailablePartCount() * 100.0f / GetPartCount() : 0.0f; CString avail; avail.Format(GetResString(IDS_AVAIL), GetPartCount(), GetAvailablePartCount(), availability); - const CString &lastdwl = (GetFileDate() != 0) ? GetCFileDate().Format(thePrefs.GetDateTimeFormat()) : GetResString(IDS_NEVER); + const CString &lastdwl(GetFileDate() ? GetCFileDate().Format(thePrefs.GetDateTimeFormat()) : GetResString(IDS_NEVER)); - CString sourcesinfo; - sourcesinfo.Format(GetResString(IDS_DL_SOURCES) + _T(": ") + GetResString(IDS_SOURCESINFO) + _T('\n'), GetSourceCount(), GetValidSourcesCount(), GetSrcStatisticsValue(DS_NONEEDEDPARTS), GetSrcA4AFCount()); + CString sourcesinfo(GetResString(IDS_DL_SOURCES)); + sourcesinfo += _T(": "); + sourcesinfo.AppendFormat(GetResString(IDS_SOURCESINFO), GetSourceCount(), GetValidSourcesCount(), GetSrcStatisticsValue(DS_NONEEDEDPARTS), GetSrcA4AFCount()); + sourcesinfo += _T('\n'); // always show space on disk - CString sod; - sod.Format(_T(" (%s%s)"), (LPCTSTR)GetResString(IDS_ONDISK), (LPCTSTR)CastItoXBytes(GetRealFileSize())); + CString sOnDisk; + sOnDisk.Format(_T(" (%s%s)"), (LPCTSTR)GetResString(IDS_ONDISK), (LPCTSTR)CastItoXBytes(GetRealFileSize())); CString sStatus; if (GetTransferringSrcCount() > 0) @@ -5058,8 +4996,8 @@ CString CPartFile::GetInfoSummary(bool bNoFormatCommands) const else sStatus = getPartfileStatus(); - CString info; - info.Format(_T("%s\n") + CString info(GetFileName()); + info.AppendFormat(_T("\n") _T("%s %s\n") _T("%s %s %s\n") _T("%s\n") @@ -5069,9 +5007,8 @@ CString CPartFile::GetInfoSummary(bool bNoFormatCommands) const _T("%s%s") _T("%s %s\n") _T("%s %s") - , (LPCTSTR)GetFileName() , (LPCTSTR)GetResString(IDS_FD_HASH), (LPCTSTR)md4str(GetFileHash()) - , (LPCTSTR)GetResString(IDS_FD_SIZE), (LPCTSTR)CastItoXBytes(GetFileSize()), (LPCTSTR)sod + , (LPCTSTR)GetResString(IDS_FD_SIZE), (LPCTSTR)CastItoXBytes((uint64)m_nFileSize), (LPCTSTR)sOnDisk , bNoFormatCommands ? _T("") : _T("") , (LPCTSTR)GetResString(IDS_FD_MET), (LPCTSTR)GetPartMetFileName() , (LPCTSTR)GetResString(IDS_STATUS), (LPCTSTR)sStatus @@ -5083,43 +5020,66 @@ CString CPartFile::GetInfoSummary(bool bNoFormatCommands) const return info; } -bool CPartFile::GrabImage(uint8 nFramesToGrab, double dStartTime, bool bReduceColor, uint16 nMaxWidth, void *pSender) +//This method is supposed to be called from other threads. +//To prevent the part file from vanishing while copying, a lock on m_FileCompleteMutex +//might be better than currently used m_bPreviewing flag +bool CPartFile::CopyPartFile(CArray &raFilled, const CString & tempFileName) { - if (!IsPartFile()) - return CKnownFile::GrabImage(GetPath() + _T('\\') + GetFileName(), nFramesToGrab, dStartTime, bReduceColor, nMaxWidth, pSender); - - if (((GetStatus() != PS_READY && GetStatus() != PS_PAUSED) || m_bPreviewing || GetPartCount() < 2 || !IsComplete(0, true))) - return false; - if (!m_FileCompleteMutex.Lock(100)) - return false; - m_bPreviewing = true; + const INT_PTR iLast = raFilled.GetCount() - 1; + ASSERT(iLast >= 0); try { - if (m_hpartfile.m_hFile != INVALID_HANDLE_VALUE) - m_hpartfile.Close(); - } catch (CFileException *exception) { - exception->Delete(); - m_FileCompleteMutex.Unlock(); + // Create destination file and set length to the last filled end position + CFile destFile; + destFile.Open(tempFileName, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite | CFile::osSequentialScan); + destFile.SetLength(raFilled[iLast].end); + + // Loop through the filled areas and copy data + m_bPreviewing = true; + for (INT_PTR i = 0; i <= iLast; ++i) { + const Gap_Struct &fill = raFilled[i]; + for (uint64 uStart = fill.start; uStart < fill.end;) { //last valid byte was at fill.end-1 + BYTE buffer[16384]; + OVERLAPPED ovr = { 0, 0, {{ LODWORD(uStart), HIDWORD(uStart)}} }; + OVERLAPPED ovw = ovr; + DWORD lenData = (DWORD)min(uStart - fill.end, sizeof buffer); + DWORD dwRead; + if (!::ReadFile((HANDLE)m_hpartfile, buffer, lenData, &dwRead, &ovr)) + CFileException::ThrowOsError((LONG)::GetLastError(), GetFileName()); + if (!::WriteFile((HANDLE)destFile, buffer, dwRead, NULL, &ovw)) + CFileException::ThrowOsError((LONG)::GetLastError(), tempFileName); + ASSERT(dwRead && dwRead < fill.end); + uStart += dwRead; + } + } m_bPreviewing = false; - return false; + return true; + } catch (CFileException *error) { + error->Delete(); + } catch (...) { + ASSERT(0); } + m_bPreviewing = false; + return false; +} - return CKnownFile::GrabImage(RemoveFileExtension(GetFullName()), nFramesToGrab, dStartTime, bReduceColor, nMaxWidth, pSender); +bool CPartFile::GrabImage(uint8 nFramesToGrab, double dStartTime, bool bReduceColor, uint16 nMaxWidth, void *pSender) +{ + if (IsPartFile()) { + if (((GetStatus() != PS_READY && GetStatus() != PS_PAUSED) || m_bPreviewing || GetPartCount() < 2 || !IsCompleteBD(0))) + return false; + m_bPreviewing = m_FileCompleteMutex.Lock(100); + if (!m_bPreviewing) + return false; + } + const CString &sFile(IsPartFile() ? RemoveFileExtension(m_fullname) : GetFilePath()); + return CKnownFile::GrabImage(sFile, nFramesToGrab, dStartTime, bReduceColor, nMaxWidth, pSender); } void CPartFile::GrabbingFinished(CxImage **imgResults, uint8 nFramesGrabbed, void *pSender) { - // unlock and reopen the file if (IsPartFile()) { - const CString &strFileName = RemoveFileExtension(GetFullName()); - if (!m_hpartfile.Open(strFileName, CFile::modeReadWrite | CFile::shareDenyWrite | CFile::osSequentialScan)) { - // uh-uh, that's really bad - LogError(LOG_STATUSBAR, GetResString(IDS_FAILEDREOPEN), (LPCTSTR)RemoveFileExtension(GetPartMetFileName()), (LPCTSTR)GetFileName()); - SetStatus(PS_ERROR); - StopFile(); - } m_bPreviewing = false; - m_FileCompleteMutex.Unlock(); - // continue processing + m_FileCompleteMutex.Unlock(); // unlock the file and continue processing } CKnownFile::GrabbingFinished(imgResults, nFramesGrabbed, pSender); } @@ -5129,16 +5089,16 @@ void CPartFile::GetLeftToTransferAndAdditionalNeededSpace(uint64 &rui64LeftToTra { uint64 uSizeLastGap = 0; for (POSITION pos = m_gaplist.GetHeadPosition(); pos != NULL;) { - const Gap_Struct *gap = m_gaplist.GetNext(pos); - uint64 uGapSize = gap->end - gap->start + 1; + const Gap_Struct &gap = m_gaplist.GetNext(pos); + uint64 uGapSize = gap.end - gap.start + 1; rui64LeftToTransfer += uGapSize; - if (gap->end == (uint64)GetFileSize() - 1) + if (gap.end == (uint64)m_nFileSize - 1) uSizeLastGap = uGapSize; } if (IsNormalFile()) { // File is not NTFS-Compressed nor NTFS-Sparse - if (GetFileSize() == GetRealFileSize()) // already fully allocated? + if (m_nFileSize == GetRealFileSize()) // already fully allocated? rui64AdditionalNeededSpace = 0; else rui64AdditionalNeededSpace = uSizeLastGap; @@ -5171,7 +5131,7 @@ void CPartFile::SetLastAnsweredTimeTimeout() 15 Pic 16 Program */ -bool CPartFile::CheckShowItemInGivenCat(int inCategory) /*const*/ +bool CPartFile::CheckShowItemInGivenCat(INT_PTR inCategory) /*const*/ { // common cases if (inCategory >= thePrefs.GetCatCount()) @@ -5288,15 +5248,19 @@ bool CPartFile::RightFileHasHigherPrio(CPartFile *left, CPartFile *right) { if (!right) return false; + if (!left) + return true; + const UINT lCat = left->GetCategory(); + const UINT rCat = right->GetCategory(); + const Category_Struct *lCatStruct = thePrefs.GetCategory(lCat); + const Category_Struct *rCatStruct = thePrefs.GetCategory(rCat); - return !left - || thePrefs.GetCategory(right->GetCategory())->prio > thePrefs.GetCategory(left->GetCategory())->prio - || (thePrefs.GetCategory(right->GetCategory())->prio == thePrefs.GetCategory(left->GetCategory())->prio + return rCatStruct->prio > lCatStruct->prio + || (rCatStruct->prio == lCatStruct->prio && (right->GetDownPriority() > left->GetDownPriority() || (right->GetDownPriority() == left->GetDownPriority() - && right->GetCategory() == left->GetCategory() - && right->GetCategory() != 0 - && thePrefs.GetCategory(right->GetCategory())->downloadInAlphabeticalOrder + && rCat != 0 && rCat == lCat + && rCatStruct->downloadInAlphabeticalOrder && thePrefs.IsExtControlsEnabled() && !right->GetFileName().IsEmpty() && !left->GetFileName().IsEmpty() && right->GetFileName().CompareNoCase(left->GetFileName()) < 0 @@ -5311,7 +5275,7 @@ void CPartFile::RequestAICHRecovery(UINT nPart) AddDebugLogLine(DLP_DEFAULT, false, _T("Unable to request AICH recovery data because we have no trusted Masterhash")); return; } - if ((uint64)GetFileSize() <= PARTSIZE * nPart + EMBLOCKSIZE) + if ((uint64)m_nFileSize <= PARTSIZE * nPart + EMBLOCKSIZE) return; if (CAICHRecoveryHashSet::IsClientRequestPending(this, (uint16)nPart)) { AddDebugLogLine(DLP_DEFAULT, false, _T("RequestAICHRecovery: Already a request for this part pending")); @@ -5379,16 +5343,11 @@ void CPartFile::AICHRecoveryDataAvailable(UINT nPart) ASSERT(0); return; } - FlushBuffer(true, true, true); + FlushBuffer(true, true); const uint64 uStart = PARTSIZE * nPart; - const uint64 uEnd = uStart + PARTSIZE; - uint32 length = PARTSIZE; - if (uEnd > m_hpartfile.GetLength()) { - length = (uint32)(m_hpartfile.GetLength() - uStart); - ASSERT(length <= PARTSIZE); - } + const uint64 length = mini(m_hpartfile.GetLength() - uStart, PARTSIZE); // if the part was already OK, it would now be complete - if (IsComplete(uStart, uStart + length - 1, true)) { + if (IsCompleteBD(uStart, uStart + length - 1)) { AddDebugLogLine(DLP_DEFAULT, false, _T("Processing AICH recovery data: The part (%u) is already complete, canceling")); return; } @@ -5401,7 +5360,7 @@ void CPartFile::AICHRecoveryDataAvailable(UINT nPart) } CAICHHashTree htOurHash(pVerifiedHash->m_nDataSize, pVerifiedHash->m_bIsLeftBranch, pVerifiedHash->GetBaseSize()); try { - m_hpartfile.Seek((LONGLONG)uStart, 0); + m_hpartfile.Seek((LONGLONG)uStart, CFile::begin); CreateHash(&m_hpartfile, length, NULL, &htOurHash); } catch (...) { ASSERT(0); @@ -5414,10 +5373,10 @@ void CPartFile::AICHRecoveryDataAvailable(UINT nPart) return; } - // now compare the hash we just did, to the verified hash and re-add all blocks which are OK - uint32 nRecovered = 0; - for (uint32 pos = 0; pos < length; pos += EMBLOCKSIZE) { - const uint32 nBlockSize = min(EMBLOCKSIZE, length - pos); + // now compare the hash we just made, to the verified hash and re-add all blocks which are OK + uint64 nRecovered = 0; + for (uint64 pos = 0; pos < length; pos += EMBLOCKSIZE) { + const uint64 nBlockSize = min(EMBLOCKSIZE, length - pos); const CAICHHashTree *pVerifiedBlock = pVerifiedHash->FindExistingHash(pos, nBlockSize); CAICHHashTree *pOurBlock = htOurHash.FindHash(pos, nBlockSize); if (pVerifiedBlock == NULL || pOurBlock == NULL || !pVerifiedBlock->m_bHashValid || !pOurBlock->m_bHashValid) { @@ -5443,7 +5402,7 @@ void CPartFile::AICHRecoveryDataAvailable(UINT nPart) thePrefs.sesLostFromCorruption -= nRecovered; // OK now some sanity checks - if (IsComplete(uStart, uStart + length - 1, true)) { + if (IsCompleteBD(uStart, uStart + length - 1)) { // this is bad, but it could probably happen under some rare circumstances // make sure that HashSinglePart() (MD4 and possibly AICH again) agrees to this fact too, for Verified Hashes problems are handled within that functions, otherwise: if (!HashSinglePart(nPart)) { @@ -5463,13 +5422,13 @@ void CPartFile::AICHRecoveryDataAvailable(UINT nPart) AddToSharedFiles(); // Successfully recovered part, make it available for sharing - if (!theApp.IsClosing() && m_gaplist.IsEmpty()) // Is this file finished? + if (m_gaplist.IsEmpty() && m_BufferedData_list.IsEmpty() && !theApp.IsClosing()) // Is this file finished? CompleteFile(false); } // end sanity check // Update met file SavePartFile(); - // make sure the user appreciates our great recovering work :P + // make sure the user appreciates our great recovery work :P AddLogLine(true, GetResString(IDS_AICH_WORKED), (LPCTSTR)CastItoXBytes(nRecovered), (LPCTSTR)CastItoXBytes(length), nPart, (LPCTSTR)GetFileName()); //AICH successfully recovered %s of %s from part %u for %s } @@ -5493,14 +5452,14 @@ UINT CPartFile::GetMaxSourcePerFileUDP() const return (temp > MAX_SOURCES_FILE_UDP) ? MAX_SOURCES_FILE_UDP : temp; } -CString CPartFile::GetTempPath() const +CString CPartFile::GetTmpPath() const { return m_fullname.Left(m_fullname.ReverseFind(_T('\\')) + 1); } void CPartFile::RefilterFileComments() { - const CString &cfilter = thePrefs.GetCommentFilter(); + const CString &cfilter(thePrefs.GetCommentFilter()); // check all available comments against our filter again if (cfilter.IsEmpty()) return; @@ -5529,4 +5488,5 @@ void CPartFile::SetFileSize(EMFileSize nFileSize) ASSERT(m_pAICHRecoveryHashSet != NULL); m_pAICHRecoveryHashSet->SetFileSize(nFileSize); CKnownFile::SetFileSize(nFileSize); + m_aChangedPart.SetSize((INT_PTR)(((uint64)nFileSize + PARTSIZE - 1) / PARTSIZE)); } \ No newline at end of file diff --git a/srchybrid/PartFile.h b/srchybrid/PartFile.h index aee4d34d..685ca600 100644 --- a/srchybrid/PartFile.h +++ b/srchybrid/PartFile.h @@ -1,4 +1,4 @@ -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -46,7 +46,7 @@ enum EPartFileStatus #define STATES_COUNT 17 -enum EPartFileFormat +enum EPartFileFormat : uint8 { PMT_UNKNOWN = 0, PMT_DEFAULTOLD, @@ -83,14 +83,15 @@ class CUpDownClient; enum EDownloadState : uint8; class CxImage; class CSafeMemFile; +class CED2KFileLink; #pragma pack(push, 1) struct Requested_Block_Struct { uint64 StartOffset; uint64 EndOffset; - uchar FileID[16]; - uint64 transferred; // Barry - This counts bytes completed + uchar FileID[MDX_DIGEST_SIZE]; + uint64 transferred; // Barry - this counts completed bytes for partfile 'progress' display }; #pragma pack(pop) @@ -100,12 +101,20 @@ struct Gap_Struct uint64 end; }; +//part file buffer write status (in PartFileBufferedData.flushed) +#define PB_READY 0 +#define PB_PENDING 1 +#define PB_ERROR 2 +#define PB_WRITTEN 3 + struct PartFileBufferedData { uint64 start; // Barry - This is the start offset of the data uint64 end; // Barry - This is the end offset of the data BYTE *data; // Barry - This is the data to be written Requested_Block_Struct *block; // Barry - This is the requested block that this data relates to + DWORD dwError; // returned from the writing thread + byte flushed; // 0 - ready 1 - sent to writing thread 2 - error 3 - written }; typedef CTypedPtrList CUpDownClientPtrList; @@ -119,7 +128,7 @@ class CPartFile : public CKnownFile explicit CPartFile(UINT cat = 0); explicit CPartFile(CSearchFile *searchresult, UINT cat = 0); explicit CPartFile(const CString &edonkeylink, UINT cat = 0); - explicit CPartFile(class CED2KFileLink *fileLink, UINT cat = 0); + explicit CPartFile(const CED2KFileLink &fileLink, UINT cat = 0); virtual ~CPartFile(); bool IsPartFile() const { return (status != PS_COMPLETE); } @@ -133,11 +142,10 @@ class CPartFile : public CKnownFile // full path to part.met file or completed file const CString& GetFullName() const { return m_fullname; } void SetFullName(const CString &name) { m_fullname = name; } - CString GetTempPath() const; + CString GetTmpPath() const; // local file system related properties bool IsNormalFile() const { return (m_dwFileAttributes & (FILE_ATTRIBUTE_COMPRESSED | FILE_ATTRIBUTE_SPARSE_FILE)) == 0; } - const bool IsAllocating() const { return m_AllocateThread != 0; } EMFileSize GetRealFileSize() const; void GetLeftToTransferAndAdditionalNeededSpace(uint64 &rui64LeftToTransfer, uint64 &rui64AdditionalNeededSpace) const; uint64 GetNeededSpace() const; @@ -152,7 +160,7 @@ class CPartFile : public CKnownFile CTime GetCrCFileDate() const { return CTime(m_tCreated); } time_t GetCrFileDate() const { return m_tCreated; } - void InitializeFromLink(CED2KFileLink *fileLink, UINT cat = 0); + void InitializeFromLink(const CED2KFileLink &fileLink, UINT cat = 0); uint32 Process(uint32 reducedownload, UINT icounter); EPartFileLoadResult LoadPartFile(LPCTSTR in_directory, LPCTSTR in_filename, EPartFileFormat *pOutCheckFileFormat = NULL); //filename = *.part.met EPartFileLoadResult ImportShareazaTempfile(LPCTSTR in_directory, LPCTSTR in_filename, EPartFileFormat *pOutCheckFileFormat = NULL); @@ -163,10 +171,14 @@ class CPartFile : public CKnownFile void AddGap(uint64 start, uint64 end); void FillGap(uint64 start, uint64 end); - void DrawStatusBar(CDC *dc, const CRect &rect, bool bFlat) /*const*/; - virtual void DrawShareStatusBar(CDC *dc, LPCRECT rect, bool onlygreyrect, bool bFlat) const; - bool IsComplete(uint64 start, uint64 end, bool bIgnoreBufferedData) const; - bool IsComplete(uint16 uPart, bool bIgnoreBufferedData) const; + void DrawStatusBar(CDC *dc, const CRect &rect, bool bFlat); + virtual void DrawShareStatusBar(CDC *dc, LPCRECT rect, bool onlygreyrect, bool bFlat) const; + bool IsComplete(uint64 start, uint64 end) const; + bool IsCompleteSafe(uint64 start, uint64 end) const; + bool IsComplete(UINT uPart) const; + bool IsCompleteBD(uint64 start, uint64 end) const; + bool IsCompleteBDSafe(uint64 start, uint64 end) const; + bool IsCompleteBD(UINT uPart) const; bool IsPureGap(uint64 start, uint64 end) const; bool IsAlreadyRequested(uint64 start, uint64 end, bool bCheckBuffers = false) const; bool ShrinkToAvoidAlreadyRequested(uint64 &start, uint64 &end) const; @@ -177,9 +189,9 @@ class CPartFile : public CKnownFile void UpdateCompletedInfos(uint64 uTotalGaps); virtual void UpdatePartsInfo(); - bool GetNextRequestedBlock(CUpDownClient *sender, Requested_Block_Struct **newblocks, uint16 *pcount) /*const*/; - void WritePartStatus(CSafeMemFile *file) const; - void WriteCompleteSourcesCount(CSafeMemFile *file) const; + bool GetNextRequestedBlock(CUpDownClient *sender, Requested_Block_Struct **newblocks, int &iCount) /*const*/; + void WritePartStatus(CSafeMemFile &file) const; + void WriteCompleteSourcesCount(CSafeMemFile &file) const; void AddSources(CSafeMemFile *sources, uint32 serverip, uint16 serverport, bool bWithObfuscationAndHash); void AddSource(LPCTSTR pszURL, uint32 nIP); static bool CanAddSource(uint32 userid, uint16 port, uint32 serverip, uint16 serverport, UINT *pdebug_lowiddropped = NULL, bool ed2kID = true); @@ -216,16 +228,15 @@ class CPartFile : public CKnownFile time_t GetDlActiveTime() const; // Barry - Added as replacement for BlockReceived to buffer data before writing to disk - uint32 WriteToBuffer(uint64 transize, const BYTE *data, uint64 start, uint64 end, Requested_Block_Struct *block, const CUpDownClient *client); - void FlushBuffer(bool forcewait = false, bool bForceICH = false, bool bNoAICH = false); + uint32 WriteToBuffer(uint64 transize, const BYTE *data, uint64 start, uint64 end, Requested_Block_Struct *block, const CUpDownClient *client, bool bCopyData); + void FlushBuffer(bool bForceICH = false, bool bNoAICH = false); // Barry - This will invert the gap list, up to caller to delete gaps when done // 'Gaps' returned are really the filled areas, and guaranteed to be in order - void GetFilledList(CTypedPtrList *filled) const; + void GetFilledArray(CArray &filled) const; // Barry - Added to prevent list containing deleted blocks on shutdown void RemoveAllRequestedBlocks(); bool RemoveBlockFromList(uint64 start, uint64 end); - bool IsInRequestedBlockList(const Requested_Block_Struct *block) const; void RemoveAllSources(bool bTryToSwap); bool CanOpenFile() const; @@ -251,7 +262,7 @@ class CPartFile : public CKnownFile UINT GetAvailablePartCount() const { return (status == PS_COMPLETING || status == PS_COMPLETE) ? GetPartCount() : availablePartsCount; } void UpdateAvailablePartsCount(); - uint32 GetLastAnsweredTime() const { return m_ClientSrcAnswered; } + DWORD GetLastAnsweredTime() const { return m_ClientSrcAnswered; } void SetLastAnsweredTime() { m_ClientSrcAnswered = ::GetTickCount(); } void SetLastAnsweredTimeTimeout(); @@ -274,9 +285,10 @@ class CPartFile : public CKnownFile UINT GetCategory() /*const*/; void SetCategory(UINT cat); bool HasDefaultCategory() const; - bool CheckShowItemInGivenCat(int inCategory) /*const*/; + bool CheckShowItemInGivenCat(INT_PTR inCategory) /*const*/; //preview + bool CopyPartFile(CArray &raFilled, const CString &tempFileName); virtual bool GrabImage(uint8 nFramesToGrab, double dStartTime, bool bReduceColor, uint16 nMaxWidth, void *pSender); virtual void GrabbingFinished(CxImage **imgResults, uint8 nFramesGrabbed, void *pSender); @@ -306,7 +318,7 @@ class CPartFile : public CKnownFile UINT GetMaxSourcePerFileUDP() const; bool GetPreviewPrio() const { return m_bpreviewprio; } - void SetPreviewPrio(bool in) { m_bpreviewprio=in; } + void SetPreviewPrio(bool in) { m_bpreviewprio = in; } static bool RightFileHasHigherPrio(CPartFile *left, CPartFile *right); bool IsDeleting() const { return m_bDelayDelete; } @@ -322,9 +334,10 @@ class CPartFile : public CKnownFile CTime lastseencomplete; CFile m_hpartfile; // permanent opened handle to avoid write conflicts CMutex m_FileCompleteMutex; // Lord KiRon - Mutex for file completion - uint64 m_iAllocinfo; - uint32 m_LastSearchTime; - uint32 m_LastSearchTimeKad; + HANDLE m_hWrite; // asynchronous part file writing + int m_iWrites; // outstanding I/O counter - read only in the main thread + DWORD m_LastSearchTime; + DWORD m_LastSearchTimeKad; uint16 src_stats[4]; uint16 net_stats[3]; uint8 m_TotalSearchesKad; @@ -343,23 +356,23 @@ class CPartFile : public CKnownFile private: BOOL PerformFileComplete(); // Lord KiRon static UINT CompleteThreadProc(LPVOID pvParams); // Lord KiRon - Used as separate thread to complete file - static UINT AFX_CDECL AllocateSpaceThread(LPVOID lpParam); void CharFillRange(CStringA &buffer, uint32 start, uint32 end, char color) const; void AddToSharedFiles(); + void DeleteWrittenItem(const POSITION pos); static CBarShader s_LoadBar; static CBarShader s_ChunkBar; CCorruptionBlackBox m_CorruptionBlackBox; - CTypedPtrList m_gaplist; + CList m_gaplist; CTypedPtrList requestedblocks_list; // Barry - Buffered data to be written CTypedPtrList m_BufferedData_list; CArray m_SrcPartFrequency; CList corrupted_list; + CArray m_aChangedPart; CUpDownClientPtrList m_downloadingSourceList; CString m_fullname; CString m_partmetfilename; - CWinThread *m_AllocateThread; CAICHRecoveryHashSet *m_pAICHRecoveryHashSet; float m_percentcompleted; EMFileSize m_completedsize; @@ -376,15 +389,15 @@ class CPartFile : public CKnownFile DWORD lastSwapForSourceExchangeTick; // ZZ:DownloadManaager DWORD m_lastRefreshedDLDisplay; DWORD m_nLastBufferFlushTime; - DWORD m_nFlushLimitMs; //randomize to prevent simultaneous flushing for several files + DWORD m_nFileFlushTime; //if file is idle long enough, flush new data to disk DWORD m_dwFileAttributes; DWORD m_random_update_wait; UINT m_anStates[STATES_COUNT]; UINT m_category; UINT m_uMaxSources; UINT availablePartsCount; - uint32 m_ClientSrcAnswered; - uint32 lastpurgetime; + DWORD m_ClientSrcAnswered; + DWORD m_lastpurgetime; uint32 m_LastNoNeededCheck; uint32 m_uPartsSavedDueICH; uint32 m_datarate; @@ -393,8 +406,8 @@ class CPartFile : public CKnownFile byte m_refresh; //delay counter for display uint8 m_iDownPriority; bool m_paused; - bool m_bPauseOnPreview; bool m_stopped; + bool m_bPauseOnPreview; bool m_insufficient; bool m_bCompletionError; bool m_bAICHPartHashsetNeeded; diff --git a/srchybrid/PartFileConvert.cpp b/srchybrid/PartFileConvert.cpp index 5e4641c0..54469bf1 100644 --- a/srchybrid/PartFileConvert.cpp +++ b/srchybrid/PartFileConvert.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -50,14 +50,14 @@ enum convstatus struct ConvertJob { + uint64 size; + uint64 spaceneeded; CString folder; CString filename; CString filehash; - uint64 size; - uint64 spaceneeded; int format; int state; - uint8 partmettype; + EPartFileFormat partmettype; bool removeSource; ConvertJob() : size() @@ -68,32 +68,33 @@ struct ConvertJob , removeSource(true) { } - //~ConvertJob() = default; }; +static CWinThread *convertPfThread; +static CList m_jobs; +static ConvertJob *pfconverting; +static CPartFileConvertDlg *m_convertgui; int CPartFileConvert::ScanFolderToAdd(const CString &folder, bool deletesource) { - CFileFind finder; + ASSERT(folder.Right(1) != _T("\\")); int count = 0; - BOOL bWorking = finder.FindFile(folder + _T("\\*.part.met")); - while (bWorking) { - bWorking = finder.FindNextFile(); + CFileFind finder; + for (BOOL bFound = finder.FindFile(folder + _T("\\*.part.met")); bFound;) { + bFound = finder.FindNextFile(); ConvertToeMule(finder.GetFilePath(), deletesource); ++count; } // Shareaza - bWorking = finder.FindFile(folder + _T("\\*.sd")); - while (bWorking) { - bWorking = finder.FindNextFile(); + for (BOOL bFound = finder.FindFile(folder + _T("\\*.sd")); bFound;) { + bFound = finder.FindNextFile(); ConvertToeMule(finder.GetFilePath(), deletesource); ++count; } - bWorking = finder.FindFile(folder + _T("\\*.*")); - while (bWorking) { - bWorking = finder.FindNextFile(); - if (finder.IsDirectory() && finder.GetFileName().Left(1) != _T(".")) + for (BOOL bFound = finder.FindFile(folder + _T("\\*.*")); bFound;) { + bFound = finder.FindNextFile(); + if (finder.IsDirectory() && !finder.IsDots()) count += ScanFolderToAdd(finder.GetFilePath(), deletesource); } return count; @@ -101,7 +102,7 @@ int CPartFileConvert::ScanFolderToAdd(const CString &folder, bool deletesource) void CPartFileConvert::ConvertToeMule(const CString &folder, bool deletesource) { - if (!PathFileExists(folder)) + if (!::PathFileExists(folder)) return; //if (folder.Left(strlen(thePrefs.GetTempDir())).CompareNoCase(thePrefs.GetTempDir()) == 0) // return; @@ -122,7 +123,7 @@ void CPartFileConvert::ConvertToeMule(const CString &folder, bool deletesource) void CPartFileConvert::StartThread() { if (convertPfThread == NULL) - convertPfThread = AfxBeginThread(run, NULL, THREAD_PRIORITY_LOWEST); + convertPfThread = AfxBeginThread(run, NULL, THREAD_PRIORITY_IDLE); } UINT AFX_CDECL CPartFileConvert::run(LPVOID /*lpParam*/) @@ -166,70 +167,63 @@ UINT AFX_CDECL CPartFileConvert::run(LPVOID /*lpParam*/) int CPartFileConvert::performConvertToeMule(const CString &folder) { - int i = folder.ReverseFind(_T('\\')); - if (i < 0) + int i = folder.ReverseFind(_T('\\')) + 1; + if (i <= 0) return CONV_FAILED; - const CString &partfile(folder.Mid(i + 1)); - CString sDir(folder.Left(i)); //no trailing backslash + const CString &partfile(folder.Mid(i)); + CString sDir(folder, i); //keep the trailing backslash UpdateGUI(0, GetResString(IDS_IMP_STEPREADPF), true); const CString &filepartindex(partfile.Left(partfile.Find(_T('.')))); - UpdateGUI(4, GetResString(IDS_IMP_STEPBASICINF)); + UpdateGUI(4.0f, GetResString(IDS_IMP_STEPBASICINF)); CPartFile *file = new CPartFile(); - EPartFileFormat eFormat = PMT_UNKNOWN; - if (file->LoadPartFile(sDir, partfile, &eFormat) == PLR_CHECKSUCCESS) { - pfconverting->partmettype = (uint8)eFormat; - switch (pfconverting->partmettype) { - case PMT_UNKNOWN: - case PMT_BADFORMAT: - delete file; - return CONV_BADFORMAT; - } - } else { + EPartFileFormat eFormat; + if (file->LoadPartFile(sDir, partfile, &eFormat) != PLR_CHECKSUCCESS) + eFormat = PMT_UNKNOWN; + switch (eFormat) { + case PMT_UNKNOWN: + case PMT_BADFORMAT: delete file; return CONV_BADFORMAT; } + if (theApp.downloadqueue->GetFileByID(file->GetFileHash()) != NULL) { + delete file; + return CONV_ALREADYEXISTS; + } pfconverting->size = file->GetFileSize(); pfconverting->filename = file->GetFileName(); pfconverting->filehash = EncodeBase16(file->GetFileHash(), 16); + pfconverting->partmettype = eFormat; UpdateGUI(pfconverting); - if (theApp.downloadqueue->GetFileByID(file->GetFileHash()) != NULL) { - delete file; - return CONV_ALREADYEXISTS; - } - - sDir += _T('\\'); //now add trailing backslash CString newfilename; CFileFind finder; - CString buffer; if (pfconverting->partmettype == PMT_SPLITTED) { try { CByteArray ba; ba.SetSize(PARTSIZE); - // just count - UINT maxindex = 0; + // find highest part file number + int maxindex = 0; UINT partfilecount = 0; - BOOL bWorking = finder.FindFile(sDir + filepartindex + _T(".*.part")); - while (bWorking) { - bWorking = finder.FindNextFile(); + for (BOOL bFound = finder.FindFile(sDir + filepartindex + _T(".*.part")); bFound;) { + bFound = finder.FindNextFile(); ++partfilecount; - buffer = finder.GetFileName(); - int pos1 = buffer.Find('.'); - int pos2 = buffer.Find('.', pos1 + 1); - UINT fileindex = _tstoi(buffer.Mid(pos1 + 1, pos2 - pos1)); + const CString &filename(finder.GetFileName()); + int pos1 = filename.Find('.'); + int pos2 = filename.Find('.', pos1 + 1); + int fileindex = _tstoi(filename.Mid(pos1 + 1, pos2 - pos1)); if (fileindex > maxindex) maxindex = fileindex; } float stepperpart; if (partfilecount > 0) { stepperpart = (80.0f / partfilecount); - if (maxindex*PARTSIZE <= pfconverting->size) + if (maxindex * PARTSIZE <= pfconverting->size) pfconverting->spaceneeded = maxindex * PARTSIZE; else pfconverting->spaceneeded = ((pfconverting->size / PARTSIZE) * PARTSIZE) + (pfconverting->size % PARTSIZE); @@ -238,30 +232,31 @@ int CPartFileConvert::performConvertToeMule(const CString &folder) pfconverting->spaceneeded = 0; } - UpdateGUI(pfconverting); - - if (GetFreeDiskSpaceX(thePrefs.GetTempDir()) < maxindex*PARTSIZE) { + if (GetFreeDiskSpaceX(thePrefs.GetTempDir()) < maxindex * PARTSIZE) { delete file; return CONV_OUTOFDISKSPACE; } + UpdateGUI(pfconverting); + // create new partmetfile, and remember the new name file->CreatePartFile(); newfilename = file->GetFullName(); - UpdateGUI(8, GetResString(IDS_IMP_STEPCRDESTFILE)); + UpdateGUI(8.0f, GetResString(IDS_IMP_STEPCRDESTFILE)); file->m_hpartfile.SetLength(pfconverting->spaceneeded); + CString buffer; CFile inputfile; unsigned curindex = 0; - bWorking = finder.FindFile(sDir + filepartindex + _T(".*.part")); - while (bWorking) { - bWorking = finder.FindNextFile(); + for (BOOL bFound = finder.FindFile(sDir + filepartindex + _T(".*.part")); bFound;) { + bFound = finder.FindNextFile(); //stats ++curindex; + float fPercent = 10 + curindex * stepperpart; buffer.Format(GetResString(IDS_IMP_LOADDATA), curindex, partfilecount); - UpdateGUI(10 + (curindex*stepperpart), buffer); + UpdateGUI(fPercent, buffer); const CString &filename(finder.GetFileName()); int pos1 = filename.Find('.'); @@ -274,15 +269,16 @@ int CPartFileConvert::performConvertToeMule(const CString &folder) // open, read data of the part-part-file into buffer, close file inputfile.Open(finder.GetFilePath(), CFile::modeRead | CFile::shareDenyWrite); - UINT readed = inputfile.Read(ba.GetData(), (UINT)PARTSIZE); + UINT nRead = inputfile.Read(ba.GetData(), (UINT)PARTSIZE); inputfile.Close(); buffer.Format(GetResString(IDS_IMP_SAVEDATA), curindex, partfilecount); - UpdateGUI(10 + (curindex*stepperpart), buffer); + UpdateGUI(fPercent, buffer); // write the buffered data - file->m_hpartfile.Seek(chunkstart, CFile::begin); - file->m_hpartfile.Write(ba.GetData(), readed); + OVERLAPPED ov = { 0, 0, {{LODWORD(chunkstart), HIDWORD(chunkstart)}} }; + if (!::WriteFile((HANDLE)file->m_hpartfile, ba.GetData(), nRead, NULL, &ov)) + CFileException::ThrowOsError((LONG)::GetLastError(), file->m_hpartfile.GetFileName()); } } catch (CFileException *error) { CString strError(GetResString(IDS_IMP_IOERROR)); @@ -303,31 +299,31 @@ int CPartFileConvert::performConvertToeMule(const CString &folder) if (!pfconverting->removeSource) pfconverting->spaceneeded = GetDiskFileSize(oldfile); - UpdateGUI(pfconverting); - if (!pfconverting->removeSource && (GetFreeDiskSpaceX(thePrefs.GetTempDir()) < pfconverting->spaceneeded)) { delete file; return CONV_OUTOFDISKSPACE; } + UpdateGUI(pfconverting); + file->CreatePartFile(); newfilename = file->GetFullName(); file->m_hpartfile.Close(); - UpdateGUI(92, GetResString(IDS_COPY)); + UpdateGUI(92.0f, GetResString(IDS_COPY)); ::DeleteFile(newfilename.Left(newfilename.GetLength() - 4)); BOOL ret; - if (!PathFileExists(oldfile)) { + if (!::PathFileExists(oldfile)) { // data file does not exist. well, then create a 0 byte big one - HANDLE hFile = ::CreateFile(newfilename.Left(newfilename.GetLength() - 4), // file to open - GENERIC_WRITE, // open for reading - FILE_SHARE_READ, // share for reading - NULL, // default security - CREATE_NEW, // existing file only - FILE_ATTRIBUTE_NORMAL, // normal file - NULL); // no attr. template + HANDLE hFile = ::CreateFile(newfilename.Left(newfilename.GetLength() - 4) // file to open + , GENERIC_WRITE // open for reading + , FILE_SHARE_READ // share for reading + , NULL // default security + , CREATE_NEW // existing file only + , FILE_ATTRIBUTE_NORMAL // normal file + , NULL); // no attr. template ret = (hFile != INVALID_HANDLE_VALUE); @@ -343,7 +339,7 @@ int CPartFileConvert::performConvertToeMule(const CString &folder) } } - UpdateGUI(94, GetResString(IDS_IMP_GETPFINFO)); + UpdateGUI(94.0f, GetResString(IDS_IMP_GETPFINFO)); ::DeleteFile(newfilename); if (pfconverting->removeSource) @@ -353,8 +349,7 @@ int CPartFileConvert::performConvertToeMule(const CString &folder) // clean up file->GetFileIdentifier().DeleteMD4Hashset(); - while (!file->m_gaplist.IsEmpty()) - delete file->m_gaplist.RemoveHead(); + file->m_gaplist.RemoveAll(); file->ClearTags(); // reload from part.met file if (file->LoadPartFile(thePrefs.GetTempDir(), file->GetPartMetFileName()) != PLR_LOADSUCCESS) { @@ -368,7 +363,7 @@ int CPartFileConvert::performConvertToeMule(const CString &folder) file->m_uCorruptionLoss = 0; } - UpdateGUI(100, GetResString(IDS_IMP_ADDDWL)); + UpdateGUI(100.0f, GetResString(IDS_IMP_ADDDWL)); theApp.downloadqueue->AddDownload(file, thePrefs.AddNewFilesPaused()); file->SavePartFile(); @@ -376,11 +371,9 @@ int CPartFileConvert::performConvertToeMule(const CString &folder) if (file->GetStatus(true) == PS_READY) theApp.sharedfiles->SafeAddKFile(file); // part files are always shared files - if (pfconverting->removeSource) { - BOOL bWorking = finder.FindFile(sDir + filepartindex + _T(".*")); - while (bWorking) { - bWorking = finder.FindNextFile(); + for (BOOL bFound = finder.FindFile(sDir + filepartindex + _T(".*")); bFound;) { + bFound = finder.FindNextFile(); VERIFY(_tunlink(finder.GetFilePath()) == 0); } @@ -437,18 +430,18 @@ void CPartFileConvert::ShowGUI() m_convertgui->SetIcon(m_convertgui->m_icoWnd = theApp.LoadIcon(_T("Convert")), FALSE); - // init gui + // init GUI m_convertgui->pb_current.SetRange(0, 100); m_convertgui->joblist.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP); if (!pfconverting == NULL) { UpdateGUI(pfconverting); - UpdateGUI(50, GetResString(IDS_IMP_FETCHSTATUS), true); + UpdateGUI(50.0f, GetResString(IDS_IMP_FETCHSTATUS), true); } Localize(); - // fill joblist + // fill job list for (POSITION pos = m_jobs.GetHeadPosition(); pos != NULL;) { ConvertJob *job = m_jobs.GetNext(pos); m_convertgui->AddJob(job); @@ -470,7 +463,7 @@ void CPartFileConvert::Localize() m_convertgui->joblist.InsertColumn(2, GetResString(IDS_DL_SIZE), LVCFMT_LEFT, DFLT_SIZE_COL_WIDTH); m_convertgui->joblist.InsertColumn(3, GetResString(IDS_FILEHASH), LVCFMT_LEFT, DFLT_HASH_COL_WIDTH); - // set gui labels + // set GUI labels m_convertgui->SetDlgItemText(IDC_ADDITEM, GetResString(IDS_IMP_ADDBTN)); m_convertgui->SetDlgItemText(IDC_RETRY, GetResString(IDS_IMP_RETRYBTN)); m_convertgui->SetDlgItemText(IDC_CONVREMOVE, GetResString(IDS_IMP_REMOVEBTN)); diff --git a/srchybrid/PartFileConvert.h b/srchybrid/PartFileConvert.h index f6a1d00b..c24959a2 100644 --- a/srchybrid/PartFileConvert.h +++ b/srchybrid/PartFileConvert.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -42,8 +42,6 @@ class CPartFileConvert static int performConvertToeMule(const CString &folder); static UINT AFX_CDECL run(LPVOID lpParam); -// static void ReConvertNewEDPartfile(CString folder); -// static UINT PFConvertThread(LPVOID param); }; @@ -82,10 +80,4 @@ class CPartFileConvertDlg : public CResizableDialog afx_msg void OnCancel(); afx_msg void RetrySel(); afx_msg void RemoveSel(); - //afx_msg void ShowInfo(); -}; - -static CWinThread *convertPfThread; -static CList m_jobs; -static ConvertJob *pfconverting; -static CPartFileConvertDlg *m_convertgui; \ No newline at end of file +}; \ No newline at end of file diff --git a/srchybrid/PartFileWriteThread.cpp b/srchybrid/PartFileWriteThread.cpp new file mode 100644 index 00000000..5375bc74 --- /dev/null +++ b/srchybrid/PartFileWriteThread.cpp @@ -0,0 +1,231 @@ +//this file is part of eMule +//Copyright (C)2020-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) +// +//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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#include "StdAfx.h" +#include "updownclient.h" +#include "PartFileWriteThread.h" +#include "emule.h" +#include "DownloadQueue.h" +#include "partfile.h" +#include "log.h" +#include "preferences.h" +#include "Statistics.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +IMPLEMENT_DYNCREATE(CPartFileWriteThread, CWinThread) + +CPartFileWriteThread::CPartFileWriteThread() + : m_eventThreadEnded(FALSE, TRUE) + , m_hPort() + , m_bRun() +{ + AfxBeginThread(RunProc, (LPVOID)this, THREAD_PRIORITY_BELOW_NORMAL); +} + +CPartFileWriteThread::~CPartFileWriteThread() +{ + ASSERT(!m_hPort && !m_bRun); +} + +UINT AFX_CDECL CPartFileWriteThread::RunProc(LPVOID pParam) +{ + DbgSetThreadName("PartWriteThread"); + InitThreadLocale(); + return pParam ? static_cast(pParam)->RunInternal() : 1; +} + +void CPartFileWriteThread::EndThread() +{ + m_bRun = false; + PostQueuedCompletionStatus(m_hPort, 0, 0, NULL); + m_eventThreadEnded.Lock(); +} + +UINT CPartFileWriteThread::RunInternal() +{ + m_hPort = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 1); + if (!m_hPort) + return ::GetLastError(); + + DWORD dwWrite = 0; + ULONG_PTR completionKey = 0; //pointer to CPartFile? + OverlappedWrite_Struct *pCurIO = NULL; + m_bRun = true; + while (m_bRun + && ::GetQueuedCompletionStatus(m_hPort, &dwWrite, &completionKey, (LPOVERLAPPED*)&pCurIO, INFINITE) + && completionKey) + { + //move buffer lists into the local storage + if (!m_FlushList.IsEmpty()) { + m_lockFlushList.Lock(); + while (!m_FlushList.IsEmpty()) + m_listToWrite.AddTail(m_FlushList.RemoveHead()); + m_lockFlushList.Unlock(); + } + + //write new buffers + WriteBuffers(); + + //completed I/O + do { + if (!completionKey) + break; + if (completionKey != (ULONG_PTR)(~0)) //wake up call + WriteCompletionRoutine(dwWrite, pCurIO); + } while (::GetQueuedCompletionStatus(m_hPort, &dwWrite, &completionKey, (LPOVERLAPPED*)&pCurIO, 0)); + + //thread termination + if (!completionKey) // && !dwRead && !pCurIO) + break; + } + m_bRun = false; + + //Improper termination of asynchronous I/O follows... + //close file handles to release I/O completion port + while (!m_listPendingIO.IsEmpty()) + WriteCompletionRoutine(0, m_listPendingIO.RemoveHead()); + + ::CloseHandle(m_hPort); + m_hPort = 0; + + m_eventThreadEnded.SetEvent(); + return 0; +} + +void CPartFileWriteThread::WriteBuffers() +{ + //process internal list + while (!m_listToWrite.IsEmpty() && m_bRun) { + const ToWrite &item = m_listToWrite.RemoveHead(); + PartFileBufferedData *pBuffer = item.pBuffer; + ASSERT(pBuffer->end >= pBuffer->start && (pBuffer->data || pBuffer->end == pBuffer->start)); //verifies allocation requests too + + CPartFile *pFile = item.pFile; + if (AddFile(pFile)) { + //initiate write + OverlappedWrite_Struct *pOvWrite = new OverlappedWrite_Struct; + pOvWrite->oOverlap.Internal = 0; + pOvWrite->oOverlap.InternalHigh = 0; + //pOvWrite->oOverlap.Offset = LODWORD(currentblock->StartOffset); + //pOvWrite->oOverlap.OffsetHigh = HIDWORD(currentblock->StartOffset); + *(uint64*)&pOvWrite->oOverlap.Offset = pBuffer->start; + pOvWrite->oOverlap.hEvent = 0; + pOvWrite->pFile = pFile; + pOvWrite->pBuffer = pBuffer; + + static const BYTE zero = 0; + if (!::WriteFile(pFile->m_hWrite, pBuffer->data ? pBuffer->data : &zero, (DWORD)(pBuffer->end - pBuffer->start + 1), NULL, (LPOVERLAPPED)pOvWrite)) { + DWORD dwError = ::GetLastError(); + if (dwError != ERROR_IO_PENDING) { + delete pOvWrite; + if (item.pBuffer->data) { //check for an allocation request + item.pBuffer->dwError = dwError; + item.pBuffer->flushed = PB_ERROR; + theApp.QueueDebugLogLineEx(LOG_WARNING, _T("WriteBuffers error: %lu"), dwError); + } + RemFile(pFile); + return; + } + } + pOvWrite->pos = m_listPendingIO.AddTail(pOvWrite); + ++pFile->m_iWrites; + } else + theApp.QueueDebugLogLineEx(LOG_ERROR, _T("WriteBuffers error: CPartFile cannot be written")); + } +} + +void CPartFileWriteThread::WriteCompletionRoutine(DWORD dwBytesWritten, const OverlappedWrite_Struct *pOvWrite) +{ + if (pOvWrite == NULL) { + ASSERT(0); + return; + } + CPartFile *pFile = pOvWrite->pFile; + if (m_bRun) { + PartFileBufferedData *pBuffer = pOvWrite->pBuffer; + const DWORD dwWrite = (DWORD)(pBuffer->end - pBuffer->start + 1); + + ASSERT(pOvWrite->pos); + m_listPendingIO.RemoveAt(pOvWrite->pos); + if (dwBytesWritten && dwWrite == dwBytesWritten) { + if (pFile) { + --pFile->m_iWrites; + if (pBuffer->data) { //write data + ASSERT(pBuffer->flushed = PB_PENDING && pFile->m_iWrites >= 0); + pBuffer->flushed = PB_WRITTEN; + } else { //full file allocation + ASSERT(dwBytesWritten == 1); + ::FlushFileBuffers(pFile->m_hWrite); + pFile->m_hpartfile.SetLength(pBuffer->start); //truncate the extra byte + delete pBuffer; + } + } + } else { + pBuffer->flushed = PB_ERROR; //error code is unknown + Debug(_T(" Completed write size: expected %lu, written %lu\n"), dwWrite, dwBytesWritten); + } + } else if (pFile) + RemFile(pFile); + + delete pOvWrite; +} + +bool CPartFileWriteThread::AddFile(CPartFile *pFile) +{ + ASSERT(m_hPort && m_bRun); + if (pFile && pFile->m_hWrite == INVALID_HANDLE_VALUE) { + const CString sPartFile(RemoveFileExtension(pFile->GetFullName())); + pFile->m_hWrite = ::CreateFile(sPartFile, GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if (pFile->m_hWrite == INVALID_HANDLE_VALUE) { + DebugLogError(_T("Failed to open \"%s\" for overlapped write: %s"), (LPCTSTR)sPartFile, (LPCTSTR)GetErrorMessage(::GetLastError(), 1)); + pFile->SetStatus(PS_ERROR); + return false; + } + if (m_hPort != ::CreateIoCompletionPort(pFile->m_hWrite, m_hPort, (ULONG_PTR)pFile, 0)) { + DebugLogError(_T("Failed to associate \"%s\" with IOCP: %s"), (LPCTSTR)sPartFile, (LPCTSTR)GetErrorMessage(::GetLastError(), 1)); + RemFile(pFile); + pFile->SetStatus(PS_ERROR); + return false; + } + } + return true; +} + +void CPartFileWriteThread::RemFile(CPartFile *pFile) +{ + ASSERT(pFile); + if (pFile->m_hWrite != INVALID_HANDLE_VALUE) { + VERIFY(::CloseHandle(pFile->m_hWrite)); + pFile->m_hWrite = INVALID_HANDLE_VALUE; + } +} + +bool CPartFileWriteThread::IsRunning() +{ + return m_bRun; +} + +void CPartFileWriteThread::WakeUpCall() +{ + if (m_bRun) + PostQueuedCompletionStatus(m_hPort, 0, (ULONG_PTR)(~0), NULL); +} \ No newline at end of file diff --git a/srchybrid/PartFileWriteThread.h b/srchybrid/PartFileWriteThread.h new file mode 100644 index 00000000..28f27ce3 --- /dev/null +++ b/srchybrid/PartFileWriteThread.h @@ -0,0 +1,68 @@ +//this file is part of eMule +//Copyright (C)2020-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) +// +//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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#pragma once + +struct PartFileBufferedData; + +struct ToWrite +{ + CPartFile *pFile; + PartFileBufferedData *pBuffer; +}; + +struct OverlappedWrite_Struct +{ + OVERLAPPED oOverlap; // must be the first member + CPartFile *pFile; + PartFileBufferedData *pBuffer; + POSITION pos; // in m_listPendingIO +}; + +class CPartFileWriteThread : public CWinThread +{ + DECLARE_DYNCREATE(CPartFileWriteThread) +public: + CPartFileWriteThread(); + ~CPartFileWriteThread(); + CPartFileWriteThread(const CPartFileWriteThread&) = delete; + CPartFileWriteThread& operator=(const CPartFileWriteThread&) = delete; + CCriticalSection m_lockWriteList; + + void EndThread(); //completionkey == 0 + void WakeUpCall(); //completionkey == -1 + bool IsRunning(); + bool AddFile(CPartFile *pFile); + static void RemFile(CPartFile *pFile); + + CCriticalSection m_lockFlushList; + CList m_FlushList; + +private: + static UINT AFX_CDECL RunProc(LPVOID pParam); + UINT RunInternal(); + + void WriteBuffers(); + void WriteCompletionRoutine(DWORD dwBytesWritten, const OverlappedWrite_Struct *pOvWrite); + + CList m_listToWrite; + CTypedPtrList m_listPendingIO; + + CEvent m_eventThreadEnded; + HANDLE m_hPort; + volatile bool m_bRun; +}; \ No newline at end of file diff --git a/srchybrid/PeerCacheClient.cpp b/srchybrid/PeerCacheClient.cpp index 4cc26353..b750b491 100644 --- a/srchybrid/PeerCacheClient.cpp +++ b/srchybrid/PeerCacheClient.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -316,11 +316,11 @@ bool CUpDownClient::ProcessPeerCacheDownHttpResponse(const CStringAArray &astrHe ASSERT(m_ePeerCacheDownState == PCDS_WAIT_CACHE_REPLY); if (m_reqfile == NULL) - throw CString(_T("Failed to process HTTP response - No 'reqfile' attached")); + throwCStr(_T("Failed to process HTTP response - No 'reqfile' attached")); if (GetDownloadState() != DS_DOWNLOADING) - throw CString(_T("Failed to process HTTP response - Invalid client download state")); + throwCStr(_T("Failed to process HTTP response - Invalid client download state")); if (astrHeaders.IsEmpty()) - throw CString(_T("Unexpected HTTP response - No headers available")); + throwCStr(_T("Unexpected HTTP response - No headers available")); const CStringA &rstrHdr = astrHeaders[0]; UINT uHttpMajVer, uHttpMinVer, uHttpStatusCode; @@ -344,7 +344,7 @@ bool CUpDownClient::ProcessPeerCacheDownHttpResponse(const CStringAArray &astrHe bool bCacheHit = false; bool bValidContentRange = false; for (int i = 1; i < astrHeaders.GetCount(); ++i) { - const CStringA &rstrHdr1 = astrHeaders[i]; + const CStringA &rstrHdr1(astrHeaders[i]); if (_strnicmp(rstrHdr1, "Content-Length:", 15) == 0) { uContentLength = _atoi64((LPCSTR)rstrHdr1 + 15); if (uContentLength > m_uReqEnd - m_uReqStart + 1) { @@ -402,7 +402,7 @@ bool CUpDownClient::ProcessPeerCacheDownHttpResponse(const CStringAArray &astrHe Debug(_T(" %s\n"), bCacheHit ? _T("CacheHit") : _T("CacheMiss")); } - Packet *pEd2kPacket = new Packet(&dataAck, OP_EMULEPROT, OP_PEERCACHE_ACK); + Packet *pEd2kPacket = new Packet(dataAck, OP_EMULEPROT, OP_PEERCACHE_ACK); theStats.AddUpDataOverheadFileRequest(pEd2kPacket->size); socket->SendPacket(pEd2kPacket); } @@ -465,7 +465,7 @@ UINT CUpDownClient::ProcessPeerCacheUpHttpRequest(const CStringAArray &astrHeade uint64 ui64RangeEnd = 0; DWORD dwPushID = 0; for (int i = 1; i < astrHeaders.GetCount(); ++i) { - const CStringA &rstrHdr2 = astrHeaders[i]; + const CStringA &rstrHdr2(astrHeaders[i]); if (_strnicmp(rstrHdr2, "Range:", 6) == 0) { int iParams; if ((iParams = sscanf((LPCSTR)rstrHdr2 + 6, " bytes = %I64u - %I64u", &ui64RangeStart, &ui64RangeEnd)) != 2 @@ -523,9 +523,9 @@ void CUpDownClient::ProcessPeerCacheUpHttpResponse(const CStringAArray &astrHead ASSERT(m_ePeerCacheUpState == PCUS_WAIT_CACHE_REPLY); if (astrHeaders.IsEmpty()) - throw CString(_T("Unexpected HTTP response - No headers available")); + throwCStr(_T("Unexpected HTTP response - No headers available")); - const CStringA &rstrHdr = astrHeaders[0]; + const CStringA &rstrHdr(astrHeaders[0]); UINT uHttpMajVer, uHttpMinVer, uHttpStatusCode; if (sscanf(rstrHdr, "HTTP/%u.%u %u", &uHttpMajVer, &uHttpMinVer, &uHttpStatusCode) != 3) { CString strError; @@ -551,9 +551,9 @@ bool CUpDownClient::SendHttpBlockRequests() m_bPeerCacheDownHit = false; m_dwLastBlockReceived = ::GetTickCount(); if (m_reqfile == NULL) - throw CString(_T("Failed to send block requests - No 'reqfile' attached")); + throwCStr(_T("Failed to send block requests - No 'reqfile' attached")); - CreateBlockRequests(1, 1); + CreateBlockRequests(1); if (m_PendingBlocks_list.IsEmpty()) { if (m_pPCDownSocket != NULL) { m_pPCDownSocket->Safe_Delete(); @@ -645,22 +645,22 @@ bool CUpDownClient::SendPeerCacheFileRequest() data.WriteUInt8(PCOP_REQ); data.WriteUInt8(5); CTag tagCacheIP(PCTAG_CACHEIP, theApp.m_pPeerCache->GetCacheIP()); - tagCacheIP.WriteNewEd2kTag(&data); + tagCacheIP.WriteNewEd2kTag(data); CTag tagPushId(PCTAG_PUSHID, m_uPeerCacheDownloadPushId); - tagPushId.WriteNewEd2kTag(&data); + tagPushId.WriteNewEd2kTag(data); CTag tagFileId(PCTAG_FILEID, (uchar*)m_reqfile->GetFileHash()); - tagFileId.WriteNewEd2kTag(&data); + tagFileId.WriteNewEd2kTag(data); CTag tagPublicIP(PCTAG_PUBLICIP, theApp.GetPublicIP()); - tagPublicIP.WriteNewEd2kTag(&data); + tagPublicIP.WriteNewEd2kTag(data); CTag tagCachePort(PCTAG_CACHEPORT, theApp.m_pPeerCache->GetCachePort()); - tagCachePort.WriteNewEd2kTag(&data); + tagCachePort.WriteNewEd2kTag(data); if (thePrefs.GetDebugClientTCPLevel() > 0) { DebugSend("OP_PeerCacheQuery", this, m_reqfile->GetFileHash()); Debug(_T(" CacheIP=%s PushId=%u PublicIP=%s FileId=%s\n"), (LPCTSTR)ipstr(tagCacheIP.GetInt()), tagPushId.GetInt(), (LPCTSTR)ipstr(tagPublicIP.GetInt()), (LPCTSTR)md4str(tagFileId.GetHash())); } - Packet *pEd2kPacket = new Packet(&data, OP_EMULEPROT, OP_PEERCACHE_QUERY); + Packet *pEd2kPacket = new Packet(data, OP_EMULEPROT, OP_PEERCACHE_QUERY); theStats.AddUpDataOverheadFileRequest(pEd2kPacket->size); socket->SendPacket(pEd2kPacket); SetDownloadState(DS_DOWNLOADING); @@ -696,14 +696,14 @@ bool CUpDownClient::ProcessPeerCacheQuery(const uchar *packet, UINT size) return false; } - uchar aucFileHash[16] = {}; + uchar aucFileHash[MDX_DIGEST_SIZE] = {}; uint32 uPushId = 0; uint32 uCacheIP = 0; uint16 uCachePort = 0; CString strInfo; for (UINT uTags = dataRecv.ReadUInt8(); uTags > 0; --uTags) { - CTag tag(&dataRecv, GetUnicodeSupport() != UTF8strNone); + CTag tag(dataRecv, GetUnicodeSupport() != UTF8strNone); if (tag.GetNameID() == PCTAG_CACHEIP && tag.IsInt()) { uCacheIP = tag.GetInt(); if (bDebug) @@ -721,9 +721,10 @@ bool CUpDownClient::ProcessPeerCacheQuery(const uchar *packet, UINT size) if (bDebug) strInfo.AppendFormat(_T(" FileId=%s"), (LPCTSTR)md4str(aucFileHash)); } else if (tag.GetNameID() == PCTAG_PUBLICIP && tag.IsInt()) { - uint32 uPublicIP = tag.GetInt(); - if (bDebug) + if (bDebug) { + uint32 uPublicIP = tag.GetInt(); strInfo.AppendFormat(_T(" PublicIP=%s"), (LPCTSTR)ipstr(uPublicIP)); + } } else { if (bDebug) strInfo.AppendFormat(_T(" ***UnkTag: %s"), (LPCTSTR)tag.GetFullInfo()); @@ -788,18 +789,18 @@ bool CUpDownClient::ProcessPeerCacheQuery(const uchar *packet, UINT size) dataSend.WriteUInt8(PCOP_RES); dataSend.WriteUInt8(3); CTag tagPushId(PCTAG_PUSHID, uPushId); - tagPushId.WriteNewEd2kTag(&dataSend); + tagPushId.WriteNewEd2kTag(dataSend); CTag tagPublicIP(PCTAG_PUBLICIP, theApp.GetPublicIP()); - tagPublicIP.WriteNewEd2kTag(&dataSend); + tagPublicIP.WriteNewEd2kTag(dataSend); CTag tagFileId(PCTAG_FILEID, (BYTE*)aucFileHash); - tagFileId.WriteNewEd2kTag(&dataSend); + tagFileId.WriteNewEd2kTag(dataSend); if (thePrefs.GetDebugClientTCPLevel() > 0) { DebugSend("OP_PeerCacheAnswer", this, aucFileHash); Debug(_T(" PushId=%u PublicIP=%s FileId=%s\n"), tagPushId.GetInt(), (LPCTSTR)ipstr(tagPublicIP.GetInt()), (LPCTSTR)md4str(tagFileId.GetHash())); } - Packet *pEd2kPacket = new Packet(&dataSend, OP_EMULEPROT, OP_PEERCACHE_ANSWER); + Packet *pEd2kPacket = new Packet(dataSend, OP_EMULEPROT, OP_PEERCACHE_ANSWER); theStats.AddUpDataOverheadFileRequest(pEd2kPacket->size); socket->SendPacket(pEd2kPacket); return true; @@ -840,13 +841,13 @@ bool CUpDownClient::ProcessPeerCacheAnswer(const uchar *packet, UINT size) return false; } + uchar aucFileHash[MDX_DIGEST_SIZE] = {}; uint32 uPushId = 0; uint32 uRemoteIP = 0; - uchar aucFileHash[16] = {}; CString strInfo; for (UINT uTags = dataRecv.ReadUInt8(); uTags > 0; --uTags) { - CTag tag(&dataRecv, GetUnicodeSupport() != UTF8strNone); + CTag tag(dataRecv, GetUnicodeSupport() != UTF8strNone); if (tag.GetNameID() == PCTAG_PUSHID && tag.IsInt()) { uPushId = tag.GetInt(); if (bDebug) diff --git a/srchybrid/PeerCacheFinder.cpp b/srchybrid/PeerCacheFinder.cpp index 249f2721..d06ee275 100644 --- a/srchybrid/PeerCacheFinder.cpp +++ b/srchybrid/PeerCacheFinder.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -21,9 +21,9 @@ #include "Preferences.h" #include "opcodes.h" #include "md5sum.h" -#include #include "Log.h" #include "UserMsgs.h" +#include "cryptopp/rsa.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -69,7 +69,7 @@ CPeerCacheFinder::CPeerCacheFinder() , m_nFailedDownloads() , m_posCurrentLookUp() , m_nPCPort() - , m_bValdited() + , m_bValidated() , m_bNotReSearched() , m_bNotReValdited() { @@ -129,7 +129,7 @@ void CPeerCacheFinder::Init(time_t dwLastSearch, bool bLastSearchSuccess, bool b return; } // no need to revalidate the cache yet - m_bValdited = true; + m_bValidated = true; m_bNotReValdited = true; DEBUG_ONLY(theApp.QueueDebugLogLine(false, _T("PeerCache: CacheIdent still valid, not trying to revalidate this time"))); } else @@ -191,7 +191,7 @@ void CPeerCacheFinder::SearchForPC() // we have to wait until we get our IP from a reverse lookup m_PCStatus = PCS_OWNIPUNKNOWN; else { - if (!m_bValdited) { + if (!m_bValidated) { m_PCStatus = PCS_VALDATING; ValidateDescriptorFile(); } else { @@ -262,7 +262,7 @@ CString ReverseDnsLookup(DWORD dwIP) HMODULE hLib = LoadLibrary(_T("dnsapi.dll")); if (hLib) { - DNS_STATUS(WINAPI *pfnDnsQueryConfig)(DNS_CONFIG_TYPE Config, DWORD Flag, PWSTR pwsAdapterName, PVOID pReserved, PVOID pBuffer, PDWORD pBufferLength); + DNS_STATUS(WINAPI *pfnDnsQueryConfig)(DNS_CONFIG_TYPE Config, DWORD Flag, PCWSTR pwsAdapterName, PVOID pReserved, PVOID pBuffer, PDWORD pBufferLength); DNS_STATUS(WINAPI *pfnDnsQuery)(PCTSTR pszName, WORD wType, DWORD Options, PIP4_ARRAY aipServers, PDNS_RECORD *ppQueryResults, PVOID *pReserved); VOID(WINAPI *pfnDnsRecordListFree)(PDNS_RECORD pRecordList, DNS_FREE_TYPE FreeType); @@ -328,7 +328,7 @@ void CPeerCacheFinder::ValidateDescriptorFile() pValidateThread->ResumeThread(); } -void CPeerCacheFinder::AddBannedVersion(CClientVersionInfo cviVersion) +void CPeerCacheFinder::AddBannedVersion(const CClientVersionInfo &cviVersion) { // Thread safe, due to logic this is not really needed at this time // (because no one will access the list while the ValidateThread is running), @@ -337,7 +337,7 @@ void CPeerCacheFinder::AddBannedVersion(CClientVersionInfo cviVersion) liBannedVersions.Add(cviVersion); } -void CPeerCacheFinder::AddAllowedVersion(CClientVersionInfo cviVersion) +void CPeerCacheFinder::AddAllowedVersion(const CClientVersionInfo &cviVersion) { CSingleLock lock(&m_SettingsMutex, TRUE); liAllowedVersions.Add(cviVersion); @@ -395,8 +395,8 @@ BOOL CPCValidateThread::InitInstance() BOOL CPCValidateThread::Run() { if (!theApp.IsClosing()) { - if (Valdite()) { - m_pOwner->m_bValdited = true; + if (Validate()) { + m_pOwner->m_bValidated = true; m_pOwner->m_nPCPort = m_nPCPort; if (m_pOwner->m_PCStatus == PCS_VALDATING) { DEBUG_ONLY(theApp.QueueDebugLogLine(false, _T("PeerCache: Validating .p2pinfo succeeded"))); @@ -405,7 +405,7 @@ BOOL CPCValidateThread::Run() } else ASSERT(0); } else { - m_pOwner->m_bValdited = false; + m_pOwner->m_bValidated = false; m_pOwner->m_PCStatus = PCS_NOTVERIFIED; m_pOwner->m_nPCPort = 0; } @@ -420,10 +420,9 @@ void CPCValidateThread::SetValues(CPeerCacheFinder *in_pOwner, uint32 dwPCIP, ui m_pOwner = in_pOwner; } -bool CPCValidateThread::Valdite() +bool CPCValidateThread::Validate() { - ASSERT(m_dwPCIP != 0); - ASSERT(m_dwMyIP != 0); + ASSERT(m_dwPCIP && m_dwMyIP); CInternetSession session; CInternetFile *file = NULL; @@ -475,10 +474,11 @@ bool CPCValidateThread::Valdite() CStringA strLine(pszLine); int posSeparator = strLine.Find('=', 1); if (posSeparator >= 0 && strLine.GetLength() - posSeparator > 1) { - CStringA strTopic = strLine.Left(posSeparator).Trim(); - CStringA strContent = strLine.Mid(posSeparator + 1).Trim(); + CStringA strTopic(strLine, posSeparator); + strTopic.Trim(); + CStringA strContent(strLine.Mid(posSeparator + 1).Trim()); - //DEBUG_ONLY(theApp.QueueDebugLogLine(false, _T("PeerCache: Current line to be processed: %hs"),strLine); + //DEBUG_ONLY(theApp.QueueDebugLogLine(false, _T("PeerCache: Current line to be processed: %hs"), strLine); ///////***** CacheIP if (strTopic == "CacheIP") @@ -531,7 +531,7 @@ bool CPCValidateThread::Valdite() // finish the RangeChack bool bIPCheckFailed = true; for (int i = 0; i != astrIPRanges.GetCount(); ++i) { - CStringA strCurRange = astrIPRanges[i]; + const CStringA &strCurRange(astrIPRanges[i]); int posContentSeparator = strCurRange.Find('-', 7); if (!(posContentSeparator == -1 || strCurRange.GetLength() - posContentSeparator <= 7)) { uint32 dwIPRangeStart = inet_addr(strCurRange.Left(posContentSeparator).Trim()); @@ -613,7 +613,7 @@ bool CPCValidateThread::Valdite() uchar aucResult[SIGNATURELENGTH]; result.Encode(aucResult, SIGNATURELENGTH); - uchar aucHash1[16]; + uchar aucHash1[MDX_DIGEST_SIZE]; for (int i = 0; i < 16; ++i) aucHash1[i] = aucResult[(SIGNATURELENGTH - 1) - i]; bSignatureCheckResult = md4equ(MD5Sum(pachCompleteFile, nIFileSize - SIGNATURELENGTH).GetRawHash(), aucHash1); @@ -639,12 +639,11 @@ END_MESSAGE_MAP() IMPLEMENT_DYNCREATE(CPCReverseDnsThread, CWinThread) BOOL CPCReverseDnsThread::InitInstance() { - ASSERT(m_wndAsyncResult != NULL); - ASSERT(m_dwIP != 0); + ASSERT(m_wndAsyncResult && m_dwIP); InitThreadLocale(); memset(s_acDNSBuffer, 0, sizeof s_acDNSBuffer); - const CString &strHostname = ReverseDnsLookup(m_dwIP); + const CString &strHostname(ReverseDnsLookup(m_dwIP)); if (strHostname.IsEmpty()) { in_addr IPHost; // FIXME: Unable to resolve my own host - will always get the Windows Computer/Domain name. Dunno how to avoid this @@ -656,7 +655,7 @@ BOOL CPCReverseDnsThread::InitInstance() } } else { UINT uError; - CStringA strHostnameA(strHostname); + const CStringA strHostnameA(strHostname); UINT uBufLen = sizeof(HOSTENT) // 'hostent' structure + sizeof(char*) // h_aliases list + NUL entry + sizeof(DWORD) * 2 // h_addr_list + NUL entry diff --git a/srchybrid/PeerCacheFinder.h b/srchybrid/PeerCacheFinder.h index f2359a9b..c061c4cb 100644 --- a/srchybrid/PeerCacheFinder.h +++ b/srchybrid/PeerCacheFinder.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -20,12 +20,12 @@ enum EPeerCacheStatus { - // permanent failure 20..11 + // permanent failure: 20..11 PCS_NOTFOUND = 20, PCS_NOTVERIFIED = 19, PCS_DISABLED = 18, - // still trying to find & valdite 10..1 + // still trying to find & validate: 10..1 PCS_DOINGLOOKUPS = 10, PCS_VALDATING = 9, PCS_NOINIT = 8, @@ -63,8 +63,8 @@ class CPeerCacheFinder uint16 GetCachePort() const { return m_nPCPort; } void DownloadAttemptStarted() { ++m_nDownloadAttempts; } void DownloadAttemptFailed(); - void AddBannedVersion(CClientVersionInfo cviVersion); - void AddAllowedVersion(CClientVersionInfo cviVersion); + void AddBannedVersion(const CClientVersionInfo &cviVersion); + void AddAllowedVersion(const CClientVersionInfo &cviVersion); bool IsClientPCCompatible(uint32 dwTagVersionInfo, UINT nClientSoft); bool IsClientPCCompatible(const CClientVersionInfo &cviToCheck); LRESULT OnPeerCacheCheckResponse(WPARAM, LPARAM lParam); @@ -88,7 +88,7 @@ class CPeerCacheFinder uint32 m_nFailedDownloads; int m_posCurrentLookUp; uint16 m_nPCPort; - bool m_bValdited; + bool m_bValidated; bool m_bNotReSearched; bool m_bNotReValdited; @@ -103,9 +103,9 @@ class CPCValidateThread : public CWinThread protected: CPCValidateThread(); // protected constructor used by dynamic creation - virtual ~CPCValidateThread() = default; + DECLARE_MESSAGE_MAP() - bool Valdite(); + bool Validate(); public: virtual BOOL InitInstance(); diff --git a/srchybrid/PeerCacheSocket.h b/srchybrid/PeerCacheSocket.h index 76bb15bb..350ce6ee 100644 --- a/srchybrid/PeerCacheSocket.h +++ b/srchybrid/PeerCacheSocket.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/PerfLog.cpp b/srchybrid/PerfLog.cpp index b9ce392c..d7f455f0 100644 --- a/srchybrid/PerfLog.cpp +++ b/srchybrid/PerfLog.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -63,7 +63,7 @@ void CPerfLog::Startup() m_eFileFormat = (ELogFileFormat)ini.GetInt(_T("FileFormat"), CSV); // set default log file path - CString strDefFilePath = thePrefs.GetMuleDirectory(EMULE_CONFIGBASEDIR); + CString strDefFilePath(thePrefs.GetMuleDirectory(EMULE_CONFIGBASEDIR)); if (m_eFileFormat == CSV) strDefFilePath += _T("perflog.csv"); else @@ -113,7 +113,7 @@ void CPerfLog::WriteSamples(UINT nCurDn, UINT nCurUp, UINT nCurDnOH, UINT nCurUp LogError(LOG_DEFAULT, _T("Failed to open performance log file \"%s\" - %s"), (LPCTSTR)m_strFilePath, _tcserror(errno)); return; } - setvbuf(fp, NULL, _IOFBF, 16384); // ensure that all lines are written to file with one call + ::setvbuf(fp, NULL, _IOFBF, 16384); // ensure that all lines are written to file with one call if (m_eMode == OneSample || _filelength(_fileno(fp)) == 0) fprintf(fp, "\"(PDH-CSV 4.0)\",\"DatDown\",\"DatUp\",\"OvrDown\",\"OvrUp\"\n"); fprintf(fp, "\"%s\",\"%u\",\"%u\",\"%u\",\"%u\"\n", szTime, nCurDn, nCurUp, nCurDnOH, nCurUpOH); @@ -142,8 +142,8 @@ void CPerfLog::LogSamples() if (m_eMode == None) return; - DWORD dwNow = ::GetTickCount(); - if (dwNow < m_dwLastSampled + m_dwInterval) + const DWORD curTick = ::GetTickCount(); + if (curTick < m_dwLastSampled + m_dwInterval) return; // 'data counters' amount of transferred file data @@ -170,7 +170,7 @@ void CPerfLog::LogSamples() m_nLastSessionSentBytes = theStats.sessionSentBytes; m_nLastDnOH = nDnOHTotal; m_nLastUpOH = nUpOHTotal; - m_dwLastSampled = dwNow; + m_dwLastSampled = curTick; } void CPerfLog::Shutdown() diff --git a/srchybrid/Pinger.cpp b/srchybrid/Pinger.cpp index 0dc8113f..28a0e9fa 100644 --- a/srchybrid/Pinger.cpp +++ b/srchybrid/Pinger.cpp @@ -92,6 +92,7 @@ */ #include "stdafx.h" +#include #include "emule.h" #include "TimeTick.h" #include "Pinger.h" @@ -99,8 +100,6 @@ #include "OtherFunctions.h" #include "opcodes.h" -extern CString GetErrorMessage(DWORD dwError, DWORD dwFlags); - #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE @@ -108,52 +107,10 @@ static char THIS_FILE[] = __FILE__; #endif -#define BUFSIZE 8192 #define DEFAULT_LEN 0 +#define BUFSIZE 32 //should be >= DEFAULT_LEN + 8 #define TIMEOUT SEC2MS(3) -/*--------------------------------------------------------- - * IcmpSendEcho() Error Strings - * - * The values in the status word returned in the ICMP Echo - * Reply buffer after calling IcmpSendEcho() all have a - * base value of 11000 (IP_STATUS_BASE). At times, - * when IcmpSendEcho() fails outright, GetLastError() will - * subsequently return these error values also. - * - * Two Errors value defined in ms_icmp.h are missing from - * this string table (just to simplify use of the table): - * "IP_GENERAL_FAILURE (11050)" - * "IP_PENDING (11255)" - */ - //#define MAX_ICMP_ERR_STRING (IP_STATUS_BASE + 22) -- use _countof() instead -static LPCTSTR const aszSendEchoErr[] = -{ - _T("IP_STATUS_BASE (11000)"), - _T("IP_BUF_TOO_SMALL (11001)"), - _T("IP_DEST_NET_UNREACHABLE (11002)"), - _T("IP_DEST_HOST_UNREACHABLE (11003)"), - _T("IP_DEST_PROT_UNREACHABLE (11004)"), - _T("IP_DEST_PORT_UNREACHABLE (11005)"), - _T("IP_NO_RESOURCES (11006)"), - _T("IP_BAD_OPTION (11007)"), - _T("IP_HW_ERROR (11008)"), - _T("IP_PACKET_TOO_BIG (11009)"), - _T("IP_REQ_TIMED_OUT (11010)"), - _T("IP_BAD_REQ (11011)"), - _T("IP_BAD_ROUTE (11012)"), - _T("IP_TTL_EXPIRED_TRANSIT (11013)"), - _T("IP_TTL_EXPIRED_REASSEM (11014)"), - _T("IP_PARAM_PROBLEM (11015)"), - _T("IP_SOURCE_QUENCH (11016)"), - _T("IP_OPTION_TOO_BIG (11017)"), - _T("IP_BAD_DESTINATION (11018)"), - _T("IP_ADDR_DELETED (11019)"), - _T("IP_SPEC_MTU_CHANGE (11020)"), - _T("IP_MTU_CHANGE (11021)"), - _T("IP_UNLOAD (11022)") -}; - Pinger::Pinger() : us(INVALID_SOCKET) , udpStarted() @@ -166,12 +123,12 @@ Pinger::Pinger() sa.sin_addr.s_addr = INADDR_ANY; sa.sin_port = 0; - // attempt to initialize raw ICMP socket + // attempt to initialize raw ICMP socket (raw sockets require an Administrator) is = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if (is != INVALID_SOCKET) { if (bind(is, (sockaddr*)&sa, sizeof sa) == SOCKET_ERROR) { - //WSAGetLastError(); - not using this errpr code - closesocket(is); // ignore return value - error close anyway + //WSAGetLastError(); - never using the value + closesocket(is); // ignore return value - error close anyway } else { // attempt to initialize ordinary UDP socket - why should this fail??? // NB! no need to bind this at a moment - will be bound later, implicitly at sendto @@ -184,36 +141,19 @@ Pinger::Pinger() } // udp end - // Open ICMP.DLL - hICMP_DLL = LoadLibrary(_T("ICMP.DLL")); - if (hICMP_DLL == 0) { - theApp.QueueDebugLogLine(false, _T("Pinger: LoadLibrary() failed: Unable to locate ICMP.DLL!")); - return; - } - - // Get pointers to ICMP.DLL functions - lpfnIcmpCreateFile = (IcmpCreateFile*)GetProcAddress(hICMP_DLL, "IcmpCreateFile"); - lpfnIcmpCloseHandle = (IcmpCloseHandle*)GetProcAddress(hICMP_DLL, "IcmpCloseHandle"); - lpfnIcmpSendEcho = (IcmpSendEcho*)GetProcAddress(hICMP_DLL, "IcmpSendEcho"); - if (!lpfnIcmpCreateFile || !lpfnIcmpCloseHandle || !lpfnIcmpSendEcho) { - theApp.QueueDebugLogLine(false, _T("Pinger: GetProcAddr() failed for at least one function.")); - return; - } - // Open the ping service - hICMP = (HANDLE)lpfnIcmpCreateFile(); + hICMP = IcmpCreateFile(); if (hICMP == INVALID_HANDLE_VALUE) { DWORD nErr = ::GetLastError(); - theApp.QueueDebugLogLine(false, _T("Pinger: IcmpCreateFile() failed, err: %u"), nErr); - PIcmpErr(nErr); - return; + CString sErr; + sErr.Format(_T("IcmpCreateFile() failed, err: %lu "), nErr); + PIcmpErr(sErr, nErr); + } else { + stIPInfo.Tos = 0; // Init IPInfo structure + stIPInfo.Flags = 0; + stIPInfo.OptionsSize = 0; + stIPInfo.OptionsData = NULL; } - - // Init IPInfo structure - stIPInfo.Tos = 0; - stIPInfo.Flags = 0; - stIPInfo.OptionsSize = 0; - stIPInfo.OptionsData = NULL; } Pinger::~Pinger() @@ -226,14 +166,13 @@ Pinger::~Pinger() // UDPing reworked cleanup end <-- // Close the ICMP handle - if (!lpfnIcmpCloseHandle(hICMP)) { + if (!IcmpCloseHandle(hICMP)) { DWORD nErr = ::GetLastError(); - theApp.QueueDebugLogLine(false, _T("Error closing ICMP handle, err: %u"), nErr); - PIcmpErr(nErr); + CString sErr; + sErr.Format(_T("Closing ICMP handle failed, err: %lu "), nErr); + PIcmpErr(sErr, nErr); } - // Shut down... - FreeLibrary(hICMP_DLL); } PingStatus Pinger::Ping(uint32 lAddr, uint32 ttl, bool doLog, bool useUdp) @@ -241,13 +180,12 @@ PingStatus Pinger::Ping(uint32 lAddr, uint32 ttl, bool doLog, bool useUdp) return (useUdp && udpStarted) ? PingUDP(lAddr, ttl, doLog) : PingICMP(lAddr, ttl, doLog); } -PingStatus Pinger::PingUDP(uint32 lAddr, uint32 ttl, bool doLog) +PingStatus Pinger::PingUDP(uint32 lAddr, DWORD ttl, bool doLog) { // UDPing reworked ping sequence --> - int nTTL = ttl; sockaddr_in sa; int nAddrLen = sizeof(sockaddr_in); - char bufICMP[1500]; // allow full MTU + char bufICMP[1500]; // allow full MTU // clear ICMP socket before sending UDP - not best solution, but may be needed to exclude late responses etc u_long bytes2read = 0; @@ -256,29 +194,21 @@ PingStatus Pinger::PingUDP(uint32 lAddr, uint32 ttl, bool doLog) sa.sin_addr.s_addr = INADDR_ANY; sa.sin_port = 0; - recvfrom(is /* socket */ - , (LPSTR)bufICMP /* buffer */ - , 1500 /* length */ - , 0 /* flags */ - , (sockaddr*)&sa /* source */ - , &nAddrLen); /* addrlen*/ + recvfrom(is, (LPSTR)bufICMP, 1500, 0, (sockaddr*)&sa, &nAddrLen); } - // set TTL value for UDP packet - should success with winsock 2 + // set TTL value for UDP packet - should succeed with winsock 2 // NB! take care about IP_TTL value - it's redefined in Ws2tcpip.h! // TODO: solve next problem correctly: // eMule is linking sockets functions using wsock32.lib (IP_TTL=7) // to use IP_TTL define, we must enforce linker to bind this function // to ws2_32.lib (IP_TTL=4) (linker options: ignore wsock32.lib) - int nRet = setsockopt(us, IPPROTO_IP, IP_TTL, (char*)&nTTL, sizeof(int)); + int nRet = setsockopt(us, IPPROTO_IP, IP_TTL, (const char*)&ttl, sizeof ttl); if (nRet == SOCKET_ERROR) { PingStatus returnValue; - returnValue.success = false; - returnValue.delay = TIMEOUT; + returnValue.fDelay = TIMEOUT; + returnValue.bSuccess = false; returnValue.error = WSAGetLastError(); - //if (toNowTimeOut < 3) - // ++toNowTimeOut; - //lastTimeOut = 3; return returnValue; } @@ -286,17 +216,12 @@ PingStatus Pinger::PingUDP(uint32 lAddr, uint32 ttl, bool doLog) sa.sin_addr.s_addr = lAddr; sa.sin_port = htons(UDP_PORT); - // send lonely UDP packet with almost minimal content (0 bytes is allowed too, but no data will be sent then) - nRet = sendto(us, (LPSTR)&nTTL, 4, 0, (sockaddr*)&sa, sizeof sa); // send four bytes - TTL :) - CTimeTick m_time; - m_time.Tick(); + // send lone UDP packet with minimal content (0 bytes is allowed, but no data will be sent in that case) + nRet = sendto(us, (const char*)&ttl, 4, 0, (sockaddr*)&sa, sizeof sa); // send four bytes - TTL :) if (nRet == SOCKET_ERROR) { PingStatus returnValue; - returnValue.success = false; returnValue.error = WSAGetLastError(); - //if (toNowTimeOut < 3) - // ++toNowTimeOut; - //lastTimeOut = 3; + returnValue.bSuccess = false; return returnValue; } @@ -310,17 +235,16 @@ PingStatus Pinger::PingUDP(uint32 lAddr, uint32 ttl, bool doLog) noRcvTimeOut = true; float usResTime = 0.0f; - while ((usResTime += m_time.Tick()) < TIMEOUT) { + CTimeTick c_time; + c_time.Start(); + while ((usResTime += c_time.Tick()) < TIMEOUT) { if (noRcvTimeOut) { nRet = ioctlsocket(is, FIONREAD, &bytes2read); if (nRet != 0) { PingStatus returnValue; - returnValue.success = false; - returnValue.delay = TIMEOUT; + returnValue.fDelay = TIMEOUT; returnValue.error = WSAGetLastError(); - //if (toNowTimeOut < 3) - // ++toNowTimeOut; - //lastTimeOut = 3; + returnValue.bSuccess = false; return returnValue; } if (bytes2read <= 0) { @@ -332,156 +256,164 @@ PingStatus Pinger::PingUDP(uint32 lAddr, uint32 ttl, bool doLog) sa.sin_family = AF_INET; sa.sin_addr.s_addr = INADDR_ANY; sa.sin_port = 0; - nRet = recvfrom(is /* socket */ - , bufICMP /* buffer */ - , 1500 /* length */ - , 0 /* flags */ - , (sockaddr*)&sa /* source */ - , &nAddrLen); /* addrlen*/ - - usResTime += m_time.Tick(); + nRet = recvfrom(is, bufICMP, 1500, 0, (sockaddr*)&sa, &nAddrLen); + + usResTime += c_time.Tick(); if (nRet == SOCKET_ERROR) { PingStatus returnValue; - returnValue.success = false; - returnValue.delay = TIMEOUT; + returnValue.fDelay = TIMEOUT; returnValue.error = WSAGetLastError(); - //if (toNowTimeOut < 3) - // ++toNowTimeOut; - //lastTimeOut = 3; + returnValue.bSuccess = false; return returnValue; } unsigned short header_len = reply->h_len * 4; ICMPHeader *icmphdr = reinterpret_cast(bufICMP + header_len); - IN_ADDR stDestAddr; - - stDestAddr.s_addr = reply->source_ip; if ((icmphdr->type == ICMP_T_TTL_EXPIRE || icmphdr->type == ICMP_T_DEST_UNREACH) - && icmphdr->UDP.dest_port == htons(UDP_PORT) && icmphdr->hdrsent.dest_ip == lAddr) + && icmphdr->UDP.dest_port == htons(UDP_PORT) + && icmphdr->hdrsent.dest_ip == lAddr) { PingStatus returnValue; - returnValue.success = true; - returnValue.delay = usResTime; - returnValue.destinationAddress = stDestAddr.s_addr; + returnValue.fDelay = usResTime; + returnValue.destinationAddress = reply->source_ip; if (icmphdr->type == ICMP_T_TTL_EXPIRE) { returnValue.status = IP_TTL_EXPIRED_TRANSIT; - returnValue.ttl = ttl; + returnValue.ttl = (UCHAR)ttl; } else { returnValue.status = IP_DEST_HOST_UNREACHABLE; - returnValue.ttl = 64 - (reply->ttl & 63); + returnValue.ttl = 64 - (reply->ttl & 0x3f); //63 } + returnValue.error = 0; + returnValue.bSuccess = true; - if (doLog) { + if (doLog) theApp.QueueDebugLogLine(false - , _T("Reply (UDP-pinger) from %s: bytes=%d time=%3.2fms TTL=%i") - , (LPCTSTR)ipstr(stDestAddr) + , _T("Reply (UDP-pinger) from %s: bytes=%d time=%3.2fms TTL=%hhu") + , (LPCTSTR)ipstr(reply->source_ip) , nRet , usResTime , returnValue.ttl); - } + return returnValue; } // verbose log filtered packets info (not seen yet...) - //if (lastTimeOut) - // --lastTimeOut; - //if (!lastTimeOut && toNowTimeOut) { - // --toNowTimeOut; - // if (toNowTimeOut) - // lastTimeOut = 3; - //} + if (doLog) theApp.QueueDebugLogLine(false , _T("Filtered reply (UDP-pinger) from %s: bytes=%d time=%3.2fms TTL=%i type=%i") - , (LPCTSTR)ipstr(stDestAddr) + , (LPCTSTR)ipstr(reply->source_ip) , nRet , usResTime - , 64 - (reply->ttl & 63) + , 64 - (reply->ttl & 0x3f) //63 , icmphdr->type); } - //if (usResTime >= TIMEOUT) { - // if (toNowTimeOut < 3) - // ++toNowTimeOut; - // lastTimeOut = 3; - //} // UDPing reworked ping sequence end <-- PingStatus returnValue; - returnValue.success = false; - returnValue.delay = TIMEOUT; + returnValue.fDelay = TIMEOUT; returnValue.error = IP_REQ_TIMED_OUT; + returnValue.bSuccess = false; return returnValue; } -PingStatus Pinger::PingICMP(uint32 lAddr, uint32 ttl, bool doLog) +PingStatus Pinger::PingICMP(uint32 lAddr, DWORD ttl, bool doLog) { - PingStatus returnValue; - - IN_ADDR stDestAddr; - char achRepData[sizeof(icmp_echo_reply) + BUFSIZE]; + char achRepData[sizeof(ICMP_ECHO_REPLY) + BUFSIZE]; // Address is assumed to be OK + IN_ADDR stDestAddr; stDestAddr.s_addr = lAddr; stIPInfo.Ttl = (UCHAR)ttl; - CTimeTick m_time; - m_time.Tick(); + CTimeTick c_time; + c_time.Start(); // Send the ICMP Echo Request and read the Reply - DWORD dwReplyCount = lpfnIcmpSendEcho(hICMP + DWORD dwReplyCount = IcmpSendEcho(hICMP , stDestAddr.s_addr , NULL // data buffer - , 0 // DataLen, length of data buffer + , DEFAULT_LEN // DataLen, length of data buffer. Currently 0 , &stIPInfo , achRepData , sizeof achRepData , TIMEOUT); - float usResTime = m_time.Tick(); - if (dwReplyCount != 0) { - const PICMP_ECHO_REPLY preply = reinterpret_cast(achRepData); - long pingTime = preply->RoundTripTime; - - IN_ADDR stDestAddr1; - - stDestAddr1.s_addr = preply->Address; - - returnValue.success = true; - returnValue.status = preply->Status; - returnValue.delay = (m_time.isPerformanceCounter() && (pingTime <= 20 || pingTime % 10 == 0) && (pingTime + 10 > usResTime && usResTime + 10 > pingTime)) ? usResTime : pingTime; - returnValue.destinationAddress = stDestAddr1.s_addr; - returnValue.ttl = (returnValue.status != IP_SUCCESS) ? ttl : (preply->Options).Ttl; - - if (doLog) { - theApp.QueueDebugLogLine(false, _T("Reply (ICMP-pinger) from %s: bytes=%hu time=%3.2fms (%3.2fms %lums) TTL=%u") - , (LPCTSTR)ipstr(stDestAddr1) - , preply->DataSize - , returnValue.delay - , m_time.isPerformanceCounter() ? usResTime : -1.0f - , preply->RoundTripTime + float usResTime = c_time.Tick(); + + PingStatus returnValue; + if (dwReplyCount > 0) { + const ICMP_ECHO_REPLY &Reply = *reinterpret_cast(achRepData); + long pingTime = Reply.RoundTripTime; + + returnValue.fDelay = (c_time.isPerformanceCounter() && (pingTime <= 20 || pingTime % 10 == 0) && (pingTime + 10 > usResTime && usResTime + 10 > pingTime)) ? usResTime : pingTime; + returnValue.destinationAddress = Reply.Address; + returnValue.status = Reply.Status; + returnValue.error = 0; + returnValue.ttl = (Reply.Status == IP_SUCCESS) ? Reply.Options.Ttl : (UCHAR)ttl; + returnValue.bSuccess = true; + + if (doLog) + theApp.QueueDebugLogLine(false, _T("Reply (ICMP-pinger) from %s: bytes=%hu time=%3.2fms (%3.2fms %lums) TTL=%hhu") + , (LPCTSTR)ipstr(Reply.Address) + , Reply.DataSize + , returnValue.fDelay + , c_time.isPerformanceCounter() ? usResTime : -1.0f + , Reply.RoundTripTime , returnValue.ttl); - } + } else { - returnValue.success = false; returnValue.error = ::GetLastError(); + returnValue.bSuccess = false; if (doLog) - theApp.QueueDebugLogLine(false - , _T("Error from %s: Error=%u") + theApp.QueueDebugLogLine(false , _T("Error from %s: Error=%u") , (LPCTSTR)ipstr(stDestAddr) , returnValue.error); - } return returnValue; } - -void Pinger::PIcmpErr(DWORD nICMPErr) +void Pinger::PIcmpErr(LPCTSTR pszMsg, DWORD nICMPErr) { - if (nICMPErr >= IP_STATUS_BASE && nICMPErr < IP_STATUS_BASE + _countof(aszSendEchoErr)) { - // Display ICMP Error String - theApp.QueueDebugLogLine(false, _T("%s"), aszSendEchoErr[nICMPErr - IP_STATUS_BASE]); - } else { - // Error value is out of range, use system routine - theApp.QueueDebugLogLine(false, _T("Pinger: %s"), (LPCTSTR)GetErrorMessage(nICMPErr, 1)); - } +#if XP_BUILD + static LPCTSTR const aszSendEchoErr[] = + { + _T("IP_STATUS_BASE (11000)"), + _T("IP_BUF_TOO_SMALL (11001)"), + _T("IP_DEST_NET_UNREACHABLE (11002)"), + _T("IP_DEST_HOST_UNREACHABLE (11003)"), + _T("IP_DEST_PROT_UNREACHABLE (11004)"), + _T("IP_DEST_PORT_UNREACHABLE (11005)"), + _T("IP_NO_RESOURCES (11006)"), + _T("IP_BAD_OPTION (11007)"), + _T("IP_HW_ERROR (11008)"), + _T("IP_PACKET_TOO_BIG (11009)"), + _T("IP_REQ_TIMED_OUT (11010)"), + _T("IP_BAD_REQ (11011)"), + _T("IP_BAD_ROUTE (11012)"), + _T("IP_TTL_EXPIRED_TRANSIT (11013)"), + _T("IP_TTL_EXPIRED_REASSEM (11014)"), + _T("IP_PARAM_PROBLEM (11015)"), + _T("IP_SOURCE_QUENCH (11016)"), + _T("IP_OPTION_TOO_BIG (11017)"), + _T("IP_BAD_DESTINATION (11018)"), + _T("IP_ADDR_DELETED (11019)"), + _T("IP_SPEC_MTU_CHANGE (11020)"), + _T("IP_MTU_CHANGE (11021)"), + _T("IP_UNLOAD (11022)") + }; + + bool b = (nICMPErr >= IP_STATUS_BASE && nICMPErr < IP_STATUS_BASE + _countof(aszSendEchoErr)); + theApp.QueueDebugLogLine(false, _T("%sPinger: %s") + , pszMsg ? pszMsg : _T("") + , (LPCTSTR)(b ? aszSendEchoErr[nICMPErr - IP_STATUS_BASE] : GetErrorMessage(nICMPErr, 1))); +#else + DWORD dwSize = 511; + CStringW sErr; + bool b = (GetIpErrorString(nICMPErr, sErr.GetBuffer(dwSize), &dwSize) == NO_ERROR); + sErr.ReleaseBuffer(); //the string has trailing spaces! + theApp.QueueDebugLogLine(false, _T("%sPinger: %s") + , pszMsg ? pszMsg : _T("") + , (LPCTSTR)(b ? (CString)sErr.Trim() : GetErrorMessage(nICMPErr, 1))); +#endif } \ No newline at end of file diff --git a/srchybrid/Pinger.h b/srchybrid/Pinger.h index 30f93e24..69e531ab 100644 --- a/srchybrid/Pinger.h +++ b/srchybrid/Pinger.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -20,7 +20,7 @@ * Some code in this file has been copied from a ping demo that was * created by Bob Quinn, 1997 http://www.sockets.com * -* As some general documenation about how the ping is implemented, +* As some general documentation about how the ping is implemented, * here is the description Bob Quinn wrote about the ping demo. * * Description: @@ -72,82 +72,24 @@ #define DEFAULT_TTL 64 -#define IP_STATUS_BASE 11000 -#define IP_SUCCESS 0 -#define IP_BUF_TOO_SMALL (IP_STATUS_BASE + 1) -#define IP_DEST_NET_UNREACHABLE (IP_STATUS_BASE + 2) -#define IP_DEST_HOST_UNREACHABLE (IP_STATUS_BASE + 3) -#define IP_DEST_PROT_UNREACHABLE (IP_STATUS_BASE + 4) -#define IP_DEST_PORT_UNREACHABLE (IP_STATUS_BASE + 5) -#define IP_NO_RESOURCES (IP_STATUS_BASE + 6) -#define IP_BAD_OPTION (IP_STATUS_BASE + 7) -#define IP_HW_ERROR (IP_STATUS_BASE + 8) -#define IP_PACKET_TOO_BIG (IP_STATUS_BASE + 9) -#define IP_REQ_TIMED_OUT (IP_STATUS_BASE + 10) -#define IP_BAD_REQ (IP_STATUS_BASE + 11) -#define IP_BAD_ROUTE (IP_STATUS_BASE + 12) -#define IP_TTL_EXPIRED_TRANSIT (IP_STATUS_BASE + 13) -#define IP_TTL_EXPIRED_REASSEM (IP_STATUS_BASE + 14) -#define IP_PARAM_PROBLEM (IP_STATUS_BASE + 15) -#define IP_SOURCE_QUENCH (IP_STATUS_BASE + 16) -#define IP_OPTION_TOO_BIG (IP_STATUS_BASE + 17) -#define IP_BAD_DESTINATION (IP_STATUS_BASE + 18) -#define IP_ADDR_DELETED (IP_STATUS_BASE + 19) -#define IP_SPEC_MTU_CHANGE (IP_STATUS_BASE + 20) -#define IP_MTU_CHANGE (IP_STATUS_BASE + 21) -#define IP_UNLOAD (IP_STATUS_BASE + 22) -#define IP_GENERAL_FAILURE (IP_STATUS_BASE + 50) -#define MAX_IP_STATUS IP_GENERAL_FAILURE -#define IP_PENDING (IP_STATUS_BASE + 255) - -typedef HANDLE WINAPI IcmpCreateFile(); /* INVALID_HANDLE_VALUE on error */ -typedef BOOL WINAPI IcmpCloseHandle(HANDLE IcmpHandle); /* FALSE on error */ - -/* Note 2: For the most part, you can refer to RFC 791 for details -* on how to fill in values for the IP option information structure. -*/ -//typedef struct ip_option_information { -// u_char Ttl; /* Time To Live (used for traceroute) */ -// u_char Tos; /* Type Of Service (usually 0) */ -// u_char Flags; /* IP header flags (usually 0) */ -// u_char OptionsSize; /* Size of options data (usually 0, max 40) */ -// u_char FAR *OptionsData; /* Options data buffer */ -//} IPINFO, *PIPINFO, FAR *LPIPINFO; - /* Note 1: The Reply Buffer will have an array of ICMP_ECHO_REPLY * structures, followed by options and the data in ICMP echo reply * datagram received. You must have room for at least one ICMP * echo reply structure, plus 8 bytes for an ICMP header. */ -//typedef struct icmp_echo_reply { -// u_long Address; /* source address */ -// u_long Status; /* IP status value (see below) */ -// u_long RTTime; /* Round Trip Time in milliseconds */ -// u_short DataSize; /* reply data size */ -// u_short Reserved; /* */ -// void FAR *Data; /* reply data buffer */ -// struct ip_option_information Options; /* reply options */ -//} ICMPECHO, *PICMPECHO, FAR *LPICMPECHO; - -typedef DWORD WINAPI IcmpSendEcho( - HANDLE IcmpHandle, /* handle returned from IcmpCreateFile() */ - u_long DestAddress, /* destination IP address (in network order) */ - LPVOID RequestData, /* pointer to buffer to send */ - WORD RequestSize, /* length of data in buffer */ - PIP_OPTION_INFORMATION RequestOptns, /* see Note 2 */ - LPVOID ReplyBuffer, /* see Note 1 */ - DWORD ReplySize, /* length of reply (must allow at least 1 reply) */ - DWORD Timeout /* time in milliseconds to wait for reply */ -); + +/* Note 2: For the most part, you can refer to RFC 791 for details +* on how to fill in values for the IP option information structure. +*/ struct PingStatus { - bool success; - DWORD status; - float delay; + float fDelay; uint32 destinationAddress; - uint32 ttl; + DWORD status; DWORD error; + UCHAR ttl; + bool bSuccess; }; // UDPing - required constants and structures --> @@ -155,15 +97,15 @@ struct PingStatus // ICMP packet types #define ICMP_T_ECHO_REPLY 0 #define ICMP_T_DEST_UNREACH 3 -#define ICMP_T_TTL_EXPIRE 11 #define ICMP_T_ECHO_REQUEST 8 +#define ICMP_T_TTL_EXPIRE 11 // Minimum ICMP packet size, in bytes #define ICMP_MIN 8 -#ifdef _MSC_VER // The following two structures need to be packed tightly, but unlike // Borland C++, Microsoft C++ does not do this by default. +#ifdef _MSC_VER #pragma pack(push, 1) #endif @@ -183,7 +125,7 @@ struct IPHeader ULONG dest_ip; }; -// ICMP header for DEST_UNREACH and TTL_EXPIRE replys +// ICMP header for DEST_UNREACH and TTL_EXPIRE replies struct ICMPHeader { BYTE type; // ICMP packet type @@ -223,20 +165,14 @@ class Pinger PingStatus Ping(uint32 lAddr, uint32 ttl = DEFAULT_TTL, bool doLog = false, bool useUdp = false); - static void PIcmpErr(DWORD nICMPErr); + static void PIcmpErr(LPCTSTR pszMsg, DWORD nICMPErr); private: -// void DisplayErr(int nWSAErr); - - IcmpCreateFile *lpfnIcmpCreateFile; - IcmpCloseHandle *lpfnIcmpCloseHandle; - IcmpSendEcho *lpfnIcmpSendEcho; - PingStatus PingUDP(uint32 lAddr, uint32 ttl, bool doLog); - PingStatus PingICMP(uint32 lAddr, uint32 ttl, bool doLog); + PingStatus PingICMP(uint32 lAddr, DWORD ttl, bool doLog); + PingStatus PingUDP(uint32 lAddr, DWORD ttl, bool doLog); - HANDLE hICMP; - HMODULE hICMP_DLL; // PENDING: was HANDLE IP_OPTION_INFORMATION stIPInfo; + HANDLE hICMP; SOCKET us; // UDP socket to send requests SOCKET is; // raw ICMP socket to catch responses diff --git a/srchybrid/Preferences.cpp b/srchybrid/Preferences.cpp index b8c7ea7c..47bea7c9 100644 --- a/srchybrid/Preferences.cpp +++ b/srchybrid/Preferences.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -22,6 +22,7 @@ #include "emule.h" #include "Preferences.h" #include "Opcodes.h" +#include "UpDownClient.h" #include "Ini2.h" #include "DownloadQueue.h" #include "UploadQueue.h" @@ -32,14 +33,13 @@ #include "ListenSocket.h" #include "ServerList.h" #include "SharedFileList.h" -#include "UpDownClient.h" #include "SafeFile.h" #include "emuledlg.h" #include "StatisticsDlg.h" #include "Log.h" #include "MuleToolbarCtrl.h" #include "VistaDefines.h" -#include +#include "cryptopp/osrng.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -47,6 +47,9 @@ static char THIS_FILE[] = __FILE__; #endif +#define SHAREDDIRS _T("shareddir.dat") +LPCTSTR const strDefaultToolbar = _T("0099010203040506070899091011"); + CPreferences thePrefs; CString CPreferences::m_astrDefaultDirs[13]; @@ -95,14 +98,14 @@ UINT CPreferences::statsInterval; bool CPreferences::m_bFillGraphs; uchar CPreferences::userhash[MDX_DIGEST_SIZE]; WINDOWPLACEMENT CPreferences::EmuleWindowPlacement; -int CPreferences::maxGraphDownloadRate; -int CPreferences::maxGraphUploadRate; +uint32 CPreferences::maxGraphDownloadRate; +uint32 CPreferences::maxGraphUploadRate; uint32 CPreferences::maxGraphUploadRateEstimated = 0; bool CPreferences::beepOnError; bool CPreferences::m_bIconflashOnNewMessage; bool CPreferences::confirmExit; DWORD CPreferences::m_adwStatsColors[15]; -bool CPreferences::bHasCustomTaskIconColor; +bool CPreferences::m_bHasCustomTaskIconColor; bool CPreferences::splashscreen; bool CPreferences::filterLANIPs; bool CPreferences::m_bAllocLocalHostIP; @@ -330,7 +333,7 @@ bool CPreferences::showRatesInTitle; CString CPreferences::m_strTxtEditor; CString CPreferences::m_strVideoPlayer; CString CPreferences::m_strVideoPlayerArgs; -bool CPreferences::moviePreviewBackup; +bool CPreferences::m_bMoviePreviewBackup; int CPreferences::m_iPreviewSmallBlocks; bool CPreferences::m_bPreviewCopiedArchives; int CPreferences::m_iInspectAllFileTypes; @@ -439,7 +442,7 @@ CStringList CPreferences::addresses_list; CString CPreferences::m_strFileCommentsFilePath; Preferences_Ext_Struct* CPreferences::prefsExt; WORD CPreferences::m_wWinVer; -CArray CPreferences::catMap; +CArray CPreferences::catArr; UINT CPreferences::m_nWebMirrorAlertLevel; bool CPreferences::m_bRunAsUser; bool CPreferences::m_bPreferRestrictedOverUser; @@ -501,21 +504,20 @@ LPCTSTR CPreferences::GetConfigFile() void CPreferences::Init() { - srand((unsigned int)time(NULL)); // we need random numbers sometimes + //srand((unsigned)time(NULL)); // we need random numbers sometimes - prefsExt = new Preferences_Ext_Struct(); + prefsExt = new Preferences_Ext_Struct{}; - const CString &confdir(GetMuleDirectory(EMULE_CONFIGDIR)); - m_strFileCommentsFilePath.Format(_T("%sfileinfo.ini"), (LPCTSTR)confdir); + const CString &sConfDir(GetMuleDirectory(EMULE_CONFIGDIR)); + m_strFileCommentsFilePath.Format(_T("%sfileinfo.ini"), (LPCTSTR)sConfDir); /////////////////////////////////////////////////////////////////////////// // Move *.log files from application directory into 'log' directory // CFileFind ff; - BOOL bFoundFile = ff.FindFile(GetMuleDirectory(EMULE_EXECUTABLEDIR) + _T("eMule*.log"), 0); - while (bFoundFile) { - bFoundFile = ff.FindNextFile(); - if (!ff.IsDots() && !ff.IsSystem() && !ff.IsDirectory() && !ff.IsHidden()) + for (BOOL bFound = ff.FindFile(GetMuleDirectory(EMULE_EXECUTABLEDIR) + _T("eMule*.log")); bFound;) { + bFound = ff.FindNextFile(); + if (!ff.IsDirectory() && !ff.IsSystem() && !ff.IsHidden()) ::MoveFile(ff.GetFilePath(), GetMuleDirectory(EMULE_LOGDIR) + ff.GetFileName()); } ff.Close(); @@ -524,19 +526,19 @@ void CPreferences::Init() // Move 'downloads.txt/bak' files from application and/or data-base directory // into 'config' directory // - CString sdir = GetMuleDirectory(EMULE_DATABASEDIR); - if (PathFileExists(sdir + _T("downloads.txt"))) - ::MoveFile(sdir + _T("downloads.txt"), confdir + _T("downloads.txt")); - if (PathFileExists(sdir + _T("downloads.bak"))) - ::MoveFile(sdir + _T("downloads.bak"), confdir + _T("downloads.bak")); - sdir = GetMuleDirectory(EMULE_EXECUTABLEDIR); - if (PathFileExists(sdir + _T("downloads.txt"))) - ::MoveFile(sdir + _T("downloads.txt"), confdir + _T("downloads.txt")); - if (PathFileExists(sdir + _T("downloads.bak"))) - ::MoveFile(sdir + _T("downloads.bak"), confdir + _T("downloads.bak")); + const CString &sDBdir(GetMuleDirectory(EMULE_DATABASEDIR)); + if (::PathFileExists(sDBdir + _T("downloads.txt"))) + ::MoveFile(sDBdir + _T("downloads.txt"), sConfDir + _T("downloads.txt")); + if (::PathFileExists(sDBdir + _T("downloads.bak"))) + ::MoveFile(sDBdir + _T("downloads.bak"), sConfDir + _T("downloads.bak")); + const CString &sEXEdir(GetMuleDirectory(EMULE_EXECUTABLEDIR)); + if (::PathFileExists(sEXEdir + _T("downloads.txt"))) + ::MoveFile(sEXEdir + _T("downloads.txt"), sConfDir + _T("downloads.txt")); + if (::PathFileExists(sEXEdir + _T("downloads.bak"))) + ::MoveFile(sEXEdir + _T("downloads.bak"), sConfDir + _T("downloads.bak")); // load preferences.dat or set standard values - CString strFullPath = confdir + _T("preferences.dat"); + CString strFullPath(sConfDir + _T("preferences.dat")); FILE *preffile = _tfsopen(strFullPath, _T("rb"), _SH_DENYWR); LoadPreferences(); @@ -553,56 +555,44 @@ void CPreferences::Init() CreateUserHash(); // shared directories - strFullPath.Format(_T("%sshareddir.dat"), (LPCTSTR)confdir); - CStdioFile *sdirfile = new CStdioFile(); + strFullPath.Format(_T("%s") SHAREDDIRS, (LPCTSTR)sConfDir); bool bIsUnicodeFile = IsUnicodeFile(strFullPath); // check for BOM // open the text file either as ANSI (text) or Unicode (binary), // this way we can read old and new files with almost the same code. - if (sdirfile->Open(strFullPath, CFile::modeRead | CFile::shareDenyWrite | (bIsUnicodeFile ? CFile::typeBinary : 0))) { + CStdioFile sdirfile; + if (sdirfile.Open(strFullPath, CFile::modeRead | CFile::shareDenyWrite | (bIsUnicodeFile ? CFile::typeBinary : 0))) { try { if (bIsUnicodeFile) - sdirfile->Seek(sizeof(WORD), SEEK_SET); // skip BOM + sdirfile.Seek(sizeof(WORD), CFile::begin); // skip BOM CString toadd; - while (sdirfile->ReadString(toadd)) { + while (sdirfile.ReadString(toadd)) { toadd.Trim(_T(" \t\r\n")); // need to trim '\r' in binary mode - if (toadd.IsEmpty()) - continue; - canonical(toadd); - if (!IsShareableDirectory(toadd)) - continue; - - // Skip non-existing directories from fixed disks only - int iDrive = PathGetDriveNumber(toadd); - if (iDrive >= 0 && iDrive <= 25) { - TCHAR szRootPath[4] = _T("@:\\"); - *szRootPath = (TCHAR)(_T('A') + iDrive); - if (GetDriveType(szRootPath) == DRIVE_FIXED && !m_bKeepUnavailableFixedSharedDirs) - if (_taccess(toadd, 0) != 0) - continue; + if (!toadd.IsEmpty()) { + MakeFoldername(toadd); + // skip non-shareable directories + // maybe skip non-existing directories on fixed disks only + if (IsShareableDirectory(toadd) && (m_bKeepUnavailableFixedSharedDirs || DirAccsess(toadd))) + shareddir_list.AddTail(toadd); } - slosh(toadd); - shareddir_list.AddHead(toadd); } - sdirfile->Close(); } catch (CFileException *ex) { ASSERT(0); ex->Delete(); } + sdirfile.Close(); } - delete sdirfile; // server list addresses - strFullPath.Format(_T("%saddresses.dat"), (LPCTSTR)confdir); - sdirfile = new CStdioFile(); + strFullPath.Format(_T("%s") _T("addresses.dat"), (LPCTSTR)sConfDir); bIsUnicodeFile = IsUnicodeFile(strFullPath); - if (sdirfile->Open(strFullPath, CFile::modeRead | CFile::shareDenyWrite | (bIsUnicodeFile ? CFile::typeBinary : 0))) { + if (sdirfile.Open(strFullPath, CFile::modeRead | CFile::shareDenyWrite | (bIsUnicodeFile ? CFile::typeBinary : 0))) { try { if (bIsUnicodeFile) - sdirfile->Seek(sizeof(WORD), SEEK_CUR); // skip BOM + sdirfile.Seek(sizeof(WORD), CFile::current); // skip BOM CString toadd; - while (sdirfile->ReadString(toadd)) { + while (sdirfile.ReadString(toadd)) { toadd.Trim(_T(" \t\r\n")); // need to trim '\r' in binary mode if (!toadd.IsEmpty()) addresses_list.AddTail(toadd); @@ -611,49 +601,47 @@ void CPreferences::Init() ASSERT(0); ex->Delete(); } - sdirfile->Close(); + sdirfile.Close(); } - delete sdirfile; // Explicitly inform the user about errors with incoming/temp folders! - if (!PathFileExists(GetMuleDirectory(EMULE_INCOMINGDIR)) && !::CreateDirectory(GetMuleDirectory(EMULE_INCOMINGDIR), 0)) { + if (!::PathFileExists(GetMuleDirectory(EMULE_INCOMINGDIR)) && !::CreateDirectory(GetMuleDirectory(EMULE_INCOMINGDIR), 0)) { CString strError; strError.Format(GetResString(IDS_ERR_CREATE_DIR), (LPCTSTR)GetResString(IDS_PW_INCOMING), (LPCTSTR)GetMuleDirectory(EMULE_INCOMINGDIR), (LPCTSTR)GetErrorMessage(::GetLastError())); AfxMessageBox(strError, MB_ICONERROR); m_strIncomingDir = GetDefaultDirectory(EMULE_INCOMINGDIR, true); // will also try to create it if needed - if (!PathFileExists(GetMuleDirectory(EMULE_INCOMINGDIR))) { + if (!::PathFileExists(GetMuleDirectory(EMULE_INCOMINGDIR))) { strError.Format(GetResString(IDS_ERR_CREATE_DIR), (LPCTSTR)GetResString(IDS_PW_INCOMING), (LPCTSTR)GetMuleDirectory(EMULE_INCOMINGDIR), (LPCTSTR)GetErrorMessage(::GetLastError())); AfxMessageBox(strError, MB_ICONERROR); } } - if (!PathFileExists(GetTempDir()) && !::CreateDirectory(GetTempDir(), 0)) { + if (!::PathFileExists(GetTempDir()) && !::CreateDirectory(GetTempDir(), 0)) { CString strError; strError.Format(GetResString(IDS_ERR_CREATE_DIR), (LPCTSTR)GetResString(IDS_PW_TEMP), GetTempDir(), (LPCTSTR)GetErrorMessage(::GetLastError())); AfxMessageBox(strError, MB_ICONERROR); - tempdir.SetAt(0, GetDefaultDirectory(EMULE_TEMPDIR, true)); // will also try to create it if needed); - if (!PathFileExists(GetTempDir())) { + tempdir[0] = GetDefaultDirectory(EMULE_TEMPDIR, true); // will also try to create it if needed; + if (!::PathFileExists(GetTempDir())) { strError.Format(GetResString(IDS_ERR_CREATE_DIR), (LPCTSTR)GetResString(IDS_PW_TEMP), GetTempDir(), (LPCTSTR)GetErrorMessage(::GetLastError())); AfxMessageBox(strError, MB_ICONERROR); } } // Create 'skins' directory - if (!PathFileExists(GetMuleDirectory(EMULE_SKINDIR)) && !::CreateDirectory(GetMuleDirectory(EMULE_SKINDIR), 0)) + if (!::PathFileExists(GetMuleDirectory(EMULE_SKINDIR)) && !::CreateDirectory(GetMuleDirectory(EMULE_SKINDIR), 0)) m_strSkinProfileDir = GetDefaultDirectory(EMULE_SKINDIR, true); // will also try to create it if needed // Create 'toolbars' directory - if (!PathFileExists(GetMuleDirectory(EMULE_TOOLBARDIR)) && !::CreateDirectory(GetMuleDirectory(EMULE_TOOLBARDIR), 0)) + if (!::PathFileExists(GetMuleDirectory(EMULE_TOOLBARDIR)) && !::CreateDirectory(GetMuleDirectory(EMULE_TOOLBARDIR), 0)) m_sToolbarBitmapFolder = GetDefaultDirectory(EMULE_TOOLBARDIR, true); // will also try to create it if needed; } void CPreferences::Uninit() { - while (!catMap.IsEmpty()) { - const Category_Struct *delcat = catMap[0]; - catMap.RemoveAt(0); - delete delcat; + for (INT_PTR i = catArr.GetCount(); --i >= 0;) { + delete catArr[i]; + catArr.RemoveAt(i); } } @@ -674,12 +662,12 @@ bool CPreferences::IsTempFile(const CString &rstrDirectory, const CString &rstrN { bool bFound = false; for (INT_PTR i = tempdir.GetCount(); --i >= 0;) - if (CompareDirectory(rstrDirectory, GetTempDir(i)) == 0) { + if (EqualPaths(rstrDirectory, GetTempDir(i))) { bFound = true; //OK, found a directory break; } - if (!bFound) //found nowhere - not a tempfile... + if (!bFound) //not found - not a tempfile... return false; // do not share a file from the temp directory, if it matches one of the following patterns @@ -711,20 +699,20 @@ uint32 CPreferences::GetMaxDownload() uint64 CPreferences::GetMaxDownloadInBytesPerSec(bool dynamic) { //don't be a Lam3r :) - uint32 maxup; + uint64 maxup; if (dynamic && thePrefs.IsDynUpEnabled() && theApp.uploadqueue->GetWaitingUserCount() > 0 && theApp.uploadqueue->GetDatarate() > 0) maxup = theApp.uploadqueue->GetDatarate(); else - maxup = GetMaxUpload() * 1024u; + maxup = GetMaxUpload() * 1024ull; uint64 maxdown = m_maxdownload * 1024ull; - if (maxup >= 20u * 1024u) + if (maxup >= 20 * 1024) return maxdown; - uint64 coef; - if (maxup < 4u * 1024u) + uint32 coef; + if (maxup < 4 * 1024) coef = 3; - else if (maxup < 10u * 1024u) + else if (maxup < 10 * 1024) coef = 4; else coef = 5; @@ -732,7 +720,7 @@ uint64 CPreferences::GetMaxDownloadInBytesPerSec(bool dynamic) return min(coef * maxup, maxdown); } -// -khaos--+++> A whole bunch of methods! Keep going until you reach the end tag. +// -khaos--+++> A whole bunch of methods! Keep going until you reach the end tag. void CPreferences::SaveStats(int bBackUp) { // This function saves all of the new statistics in my addon. It is also used to @@ -752,14 +740,14 @@ void CPreferences::SaveStats(int bBackUp) CIni ini(strFullPath, _T("Statistics")); - // Save cumulative statistics to preferences.ini, going in order as they appear val CStatisticsDlg::ShowStatistics. + // Save cumulative statistics to statistics.ini, going in the order they appear in CStatisticsDlg::ShowStatistics. // We do NOT SET the values in prefs struct here. // Save Cum Down Data ini.WriteUInt64(_T("TotalDownloadedBytes"), theStats.sessionReceivedBytes + GetTotalDownloaded()); ini.WriteInt(_T("DownSuccessfulSessions"), cumDownSuccessfulSessions); ini.WriteInt(_T("DownFailedSessions"), cumDownFailedSessions); - ini.WriteInt(_T("DownAvgTime"), (GetDownC_AvgTime() + GetDownS_AvgTime()) / 2); + ini.WriteInt(_T("DownAvgTime"), GetDownC_AvgTime()); //never needed this ini.WriteUInt64(_T("LostFromCorruption"), cumLostFromCorruption + sesLostFromCorruption); ini.WriteUInt64(_T("SavedFromCompression"), sesSavedFromCompression + cumSavedFromCompression); ini.WriteInt(_T("PartsSavedByICH"), cumPartsSavedByICH + sesPartsSavedByICH); @@ -802,7 +790,7 @@ void CPreferences::SaveStats(int bBackUp) ini.WriteUInt64(_T("TotalUploadedBytes"), theStats.sessionSentBytes + GetTotalUploaded()); ini.WriteInt(_T("UpSuccessfulSessions"), theApp.uploadqueue->GetSuccessfullUpCount() + GetUpSuccessfulSessions()); ini.WriteInt(_T("UpFailedSessions"), theApp.uploadqueue->GetFailedUpCount() + GetUpFailedSessions()); - ini.WriteInt(_T("UpAvgTime"), (theApp.uploadqueue->GetAverageUpTime() + GetUpAvgTime()) / 2); + ini.WriteInt(_T("UpAvgTime"), GetUpAvgTime()); //never needed this ini.WriteUInt64(_T("UpData_EDONKEY"), GetCumUpData_EDONKEY()); ini.WriteUInt64(_T("UpData_EDONKEYHYBRID"), GetCumUpData_EDONKEYHYBRID()); ini.WriteUInt64(_T("UpData_EMULE"), GetCumUpData_EMULE()); @@ -1094,7 +1082,9 @@ void CPreferences::Add2SessionTransferData(UINT uClientID, UINT uClientPort, BOO case (UINT)-1: sesDownDataPort_PeerCache += bytes; break; - //case (UINT)-2: sesDownDataPort_URL+=bytes; break; + //case (UINT)-2: + // sesDownDataPort_URL += bytes; + // break; default: sesDownDataPort_OTHER += bytes; break; @@ -1210,9 +1200,10 @@ bool CPreferences::LoadStats(int loadBackUp) // loadBackUp is 0 by default // loadBackUp = 0: Load the stats normally like we used to do in LoadPreferences // loadBackUp = 1: Load the stats from statbkup.ini and create a backup of the current stats. Also, do not initialize session variables. - CString sINI(GetMuleDirectory(EMULE_CONFIGDIR)); + const CString &sConfDir(GetMuleDirectory(EMULE_CONFIGDIR)); CFileFind findBackUp; + CString sINI(sConfDir); switch (loadBackUp) { case 1: sINI += _T("statbkup.ini"); @@ -1223,13 +1214,13 @@ bool CPreferences::LoadStats(int loadBackUp) case 0: default: // for transition... - if (PathFileExists(sINI + _T("statistics.ini"))) + if (::PathFileExists(sINI + _T("statistics.ini"))) sINI += _T("statistics.ini"); else sINI += _T("preferences.ini"); } - BOOL fileex = PathFileExists(sINI); + BOOL fileex = ::PathFileExists(sINI); CIni ini(sINI, _T("Statistics")); totalDownloadedBytes = ini.GetUInt64(_T("TotalDownloadedBytes")); @@ -1286,7 +1277,7 @@ bool CPreferences::LoadStats(int loadBackUp) cumDownCompletedFiles = ini.GetInt(_T("DownCompletedFiles")); cumDownSuccessfulSessions = ini.GetInt(_T("DownSuccessfulSessions")); cumDownFailedSessions = ini.GetInt(_T("DownFailedSessions")); - cumDownAvgTime = ini.GetInt(_T("DownAvgTime")); + cumDownAvgTime = ini.GetInt(_T("DownAvgTime")); //never needed this // Cumulative statistics for saved due to compression/lost due to corruption cumLostFromCorruption = ini.GetUInt64(_T("LostFromCorruption")); @@ -1358,7 +1349,7 @@ bool CPreferences::LoadStats(int loadBackUp) // Check to make sure the backup of the values we just overwrote exists. If so, rename it to the backup file. // This allows us to undo a restore, so to speak, just in case we don't like the restored values... - CString sINIBackUp(GetMuleDirectory(EMULE_CONFIGDIR) + _T("statbkuptmp.ini")); + CString sINIBackUp(sConfDir + _T("statbkuptmp.ini")); if (findBackUp.FindFile(sINIBackUp)) { ::DeleteFile(sINI); // Remove the backup that we just restored from ::MoveFile(sINIBackUp, sINI); // Rename our temporary backup to the normal statbkup.ini filename. @@ -1424,8 +1415,7 @@ bool CPreferences::LoadStats(int loadBackUp) // If this value is 0 (Never reset), then it returns Unknown. CString CPreferences::GetStatsLastResetStr(bool formatLong) { - // formatLong dictates the format of the string returned. - // For example... + // The format of the returned string depends on formatLong. // true: DateTime format from the .ini // false: DateTime format from the .ini for the log if (GetStatsLastResetLng()) { @@ -1447,8 +1437,9 @@ CString CPreferences::GetStatsLastResetStr(bool formatLong) bool CPreferences::Save() { static LPCTSTR const stmp = _T(".tmp"); - bool error = false; - const CString &strPrefPath(GetMuleDirectory(EMULE_CONFIGDIR) + _T("preferences.dat")); + const CString &sConfDir(GetMuleDirectory(EMULE_CONFIGDIR)); + const CString &strPrefPath(sConfDir + _T("preferences.dat")); + bool error; FILE *preffile = _tfsopen(strPrefPath + stmp, _T("wb"), _SH_DENYWR); //keep contents if (preffile) { @@ -1458,31 +1449,31 @@ bool CPreferences::Save() error = (fwrite(prefsExt, sizeof(Preferences_Ext_Struct), 1, preffile) != 1); error |= (fclose(preffile) != 0); if (!error) - error = MoveFileEx(strPrefPath + stmp, strPrefPath, MOVEFILE_REPLACE_EXISTING); + error = !MoveFileEx(strPrefPath + stmp, strPrefPath, MOVEFILE_REPLACE_EXISTING); } else error = true; SavePreferences(); SaveStats(); - const CString &strSharPath(GetMuleDirectory(EMULE_CONFIGDIR) + _T("shareddir.dat")); + const CString &strSharesPath(sConfDir + SHAREDDIRS); CStdioFile sdirfile; - if (sdirfile.Open(strSharPath + stmp, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite | CFile::typeBinary)) { + if (sdirfile.Open(strSharesPath + stmp, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite | CFile::typeBinary)) { try { // write Unicode byte order mark 0xFEFF - static const WORD wBOM = 0xFEFFui16; //UTF-16LE + static const WORD wBOM = u'\xFEFF'; //UTF-16LE sdirfile.Write(&wBOM, sizeof wBOM); for (POSITION pos = shareddir_list.GetHeadPosition(); pos != NULL;) { sdirfile.WriteString(shareddir_list.GetNext(pos)); sdirfile.Write(_T("\r\n"), 2 * sizeof(TCHAR)); } sdirfile.Close(); - MoveFileEx(strSharPath + stmp, strSharPath, MOVEFILE_REPLACE_EXISTING); + error |= (MoveFileEx(strSharesPath + stmp, strSharesPath, MOVEFILE_REPLACE_EXISTING) == 0); } catch (CFileException *ferror) { TCHAR buffer[MAX_CFEXP_ERRORMSG]; GetExceptionMessage(*ferror, buffer, _countof(buffer)); if (thePrefs.GetVerbose()) - AddDebugLogLine(true, _T("Failed to save %s - %s"), (LPCTSTR)strSharPath, buffer); + AddDebugLogLine(true, _T("Failed to save %s - %s"), (LPCTSTR)strSharesPath, buffer); ferror->Delete(); } } else @@ -1499,15 +1490,15 @@ void CPreferences::CreateUserHash() CryptoPP::AutoSeededRandomPool rng; rng.GenerateBlock(userhash, sizeof userhash); } - // mark as emule client. that will be needed in later version + // mark as emule client. this will be needed in later version userhash[5] = 14; //0x0e userhash[14] = 111; //0x6f } -int CPreferences::GetRecommendedMaxConnections() +UINT CPreferences::GetRecommendedMaxConnections() { - int iRealMax = GetMaxWindowsTCPConnections(); - if (iRealMax == -1 || iRealMax > 520) + UINT iRealMax = GetMaxWindowsTCPConnections(); + if (iRealMax == UNLIMITED || iRealMax > 520) return 500; if (iRealMax < 20) @@ -1521,8 +1512,6 @@ int CPreferences::GetRecommendedMaxConnections() void CPreferences::SavePreferences() { - CString buffer; - CIni ini(GetConfigFile(), _T("eMule")); //--- ini.WriteString(_T("AppVersion"), theApp.m_strCurVersionLong); @@ -1563,8 +1552,8 @@ void CPreferences::SavePreferences() ini.WriteInt(_T("StatGraphsInterval"), trafficOMeterInterval); ini.WriteInt(_T("StatsInterval"), statsInterval); ini.WriteBool(_T("StatsFillGraphs"), m_bFillGraphs); - ini.WriteInt(_T("DownloadCapacity"), maxGraphDownloadRate); - ini.WriteInt(_T("UploadCapacityNew"), maxGraphUploadRate); + ini.WriteInt(_T("DownloadCapacity"), (int)maxGraphDownloadRate); + ini.WriteInt(_T("UploadCapacityNew"), (int)maxGraphUploadRate); ini.WriteInt(_T("DeadServerRetry"), m_uDeadServerRetries); ini.WriteInt(_T("ServerKeepAliveTimeout"), m_dwServerKeepAliveTimeout); ini.WriteInt(_T("SplitterbarPosition"), splitterbarPosition); @@ -1696,7 +1685,7 @@ void CPreferences::SavePreferences() ini.WriteBool(_T("ManualHighPrio"), m_bManualAddedServersHighPriority); ini.WriteBool(_T("FullChunkTransfers"), m_btransferfullchunks); ini.WriteBool(_T("ShowOverhead"), m_bshowoverhead); - ini.WriteBool(_T("VideoPreviewBackupped"), moviePreviewBackup); + ini.WriteBool(_T("VideoPreviewBackupped"), m_bMoviePreviewBackup); ini.WriteInt(_T("StartNextFile"), m_istartnextfile); ini.DeleteKey(_T("FileBufferSizePref")); // delete old 'file buff size' setting @@ -1811,13 +1800,13 @@ void CPreferences::SavePreferences() // ini.WriteInt(_T("statsConnectionsGraphRatio"), statsConnectionsGraphRatio, _T("Statistics")); ini.WriteString(_T("statsExpandedTreeItems"), m_strStatsExpandedTreeItems); - CString buffer2; + CString sValue, sKey; for (int i = 0; i < 15; ++i) { - buffer.Format(_T("0x%06lx"), GetStatsColor(i)); - buffer2.Format(_T("StatColor%i"), i); - ini.WriteString(buffer2, buffer, _T("Statistics")); + sValue.Format(_T("0x%06lx"), GetStatsColor(i)); + sKey.Format(_T("StatColor%i"), i); + ini.WriteString(sKey, sValue, _T("Statistics")); } - ini.WriteBool(_T("HasCustomTaskIconColor"), bHasCustomTaskIconColor, _T("Statistics")); + ini.WriteBool(_T("HasCustomTaskIconColor"), m_bHasCustomTaskIconColor, _T("Statistics")); /////////////////////////////////////////////////////////////////////////// @@ -1867,15 +1856,16 @@ void CPreferences::ResetStatsColor(int index) if (index >= 0 && index < _countof(defcol)) { m_adwStatsColors[index] = defcol[index]; if (index == 11) /**/ - bHasCustomTaskIconColor = false; + m_bHasCustomTaskIconColor = false; } } void CPreferences::GetAllStatsColors(int iCount, LPDWORD pdwColors) { const size_t cnt = iCount * sizeof(*pdwColors); - memset(pdwColors, 0, cnt); memcpy(pdwColors, m_adwStatsColors, min(sizeof m_adwStatsColors, cnt)); + if (cnt > sizeof m_adwStatsColors) + memset(&pdwColors[sizeof m_adwStatsColors], 0, cnt - sizeof m_adwStatsColors); } bool CPreferences::SetAllStatsColors(int iCount, const LPDWORD pdwColors) @@ -1887,7 +1877,7 @@ bool CPreferences::SetAllStatsColors(int iCount, const LPDWORD pdwColors) m_adwStatsColors[i] = pdwColors[i]; bModified = true; if (i == 11) - bHasCustomTaskIconColor = true; + m_bHasCustomTaskIconColor = true; } return bModified; @@ -1896,13 +1886,11 @@ bool CPreferences::SetAllStatsColors(int iCount, const LPDWORD pdwColors) void CPreferences::IniCopy(const CString &si, const CString &di) { CIni ini(GetConfigFile(), _T("eMule")); - const CString &s = ini.GetString(si); + const CString &sValue(ini.GetString(si)); // Do NOT write empty settings, this will mess up reading of default settings in case // there were no settings available at all (fresh emule install)! - if (!s.IsEmpty()) { - ini.SetSection(_T("ListControlSetup")); - ini.WriteString(di, s); - } + if (!sValue.IsEmpty()) + ini.WriteString(di, sValue, _T("ListControlSetup")); } void CPreferences::LoadPreferences() @@ -1942,48 +1930,45 @@ void CPreferences::LoadPreferences() sTempdirs.AppendFormat(_T("|%s"), (LPCTSTR)ini.GetString(_T("TempDirs"))); for (int iPos = 0; iPos >= 0;) { - CString atmp(sTempdirs.Tokenize(_T("|"), iPos)); - if (atmp.Trim().IsEmpty()) + CString sTmp(sTempdirs.Tokenize(_T("|"), iPos)); + if (sTmp.Trim().IsEmpty()) continue; - MakeFoldername(atmp); + MakeFoldername(sTmp); bool bDup = false; for (INT_PTR i = tempdir.GetCount(); --i >= 0;) // avoid duplicate tempdirs - if (atmp.CompareNoCase(GetTempDir(i)) == 0) { + if (sTmp.CompareNoCase(GetTempDir(i)) == 0) { bDup = true; break; } - if (!bDup && (PathFileExists(atmp) || ::CreateDirectory(atmp, NULL)) || tempdir.IsEmpty()) - tempdir.Add(atmp); + if (!bDup && (::PathFileExists(sTmp) || ::CreateDirectory(sTmp, NULL)) || tempdir.IsEmpty()) + tempdir.Add(sTmp); } - - maxGraphDownloadRate = ini.GetInt(_T("DownloadCapacity"), 96); - if (maxGraphDownloadRate == 0) - maxGraphDownloadRate = 96; - - maxGraphUploadRate = ini.GetInt(_T("UploadCapacityNew"), -1); - if (maxGraphUploadRate == 0) - maxGraphUploadRate = UNLIMITED; - else if (maxGraphUploadRate == -1) { + + SetMaxGraphDownloadRate((uint32)ini.GetInt(_T("DownloadCapacity"), 100)); + + SetMaxGraphUploadRate((uint32)ini.GetInt(_T("UploadCapacityNew"), 0)); + if (maxGraphUploadRate == UNLIMITED) { // converting value from prior versions - int nOldUploadCapacity = ini.GetInt(_T("UploadCapacity"), 32); + int nOldUploadCapacity = ini.GetInt(_T("UploadCapacity"), 100); if (nOldUploadCapacity == 16 && ini.GetInt(_T("MaxUpload"), 12) == 12) { // either this is a complete new install, or the prior version used the default value - // in both cases, set the new default values to unlimited - maxGraphUploadRate = UNLIMITED; - ini.WriteInt(_T("MaxUpload"), UNLIMITED, _T("eMule")); + // in both cases, set the new default values + ini.WriteInt(_T("MaxUpload"), 100, _T("eMule")); } else maxGraphUploadRate = nOldUploadCapacity; // use old custom value } m_minupload = (uint32)ini.GetInt(_T("MinUpload"), 1); - m_maxupload = (uint32)ini.GetInt(_T("MaxUpload"), UNLIMITED); - if (m_maxupload > (uint32)maxGraphUploadRate && m_maxupload != UNLIMITED) - m_maxupload = (uint32)(maxGraphUploadRate * 4 / 5); + if (m_minupload < 1) + m_minupload = 1; + m_maxupload = (uint32)ini.GetInt(_T("MaxUpload"), 80); + if (m_maxupload > maxGraphUploadRate && m_maxupload != UNLIMITED) + m_maxupload = maxGraphUploadRate * 4 / 5; - m_maxdownload = (uint32)ini.GetInt(_T("MaxDownload"), UNLIMITED); - if (m_maxdownload > (uint32)maxGraphDownloadRate && m_maxdownload != UNLIMITED) - m_maxdownload = (uint32)(maxGraphDownloadRate * 4 / 5); + m_maxdownload = (uint32)ini.GetInt(_T("MaxDownload"), 90); + if (m_maxdownload > maxGraphDownloadRate && m_maxdownload != UNLIMITED) + m_maxdownload = maxGraphDownloadRate * 9 / 10; maxconnections = ini.GetInt(_T("MaxConnections"), GetRecommendedMaxConnections()); maxhalfconnections = ini.GetInt(_T("MaxHalfConnections"), 9); m_bConditionalTCPAccept = ini.GetBool(_T("ConditionalTCPAccept"), false); @@ -2179,7 +2164,7 @@ void CPreferences::LoadPreferences() m_iDebugClientKadUDPLevel = ini.GetInt(_T("DebugClientKadUDP"), 0); m_iDebugSearchResultDetailLevel = ini.GetInt(_T("DebugSearchResultDetailLevel"), 0); #else - // for normal release builds ensure that those options are all turned off + // for normal release builds ensure that all these options are turned off m_iDebugServerTCPLevel = 0; m_iDebugServerUDPLevel = 0; m_iDebugServerSourcesLevel = 0; @@ -2196,7 +2181,7 @@ void CPreferences::LoadPreferences() m_btransferfullchunks = ini.GetBool(_T("FullChunkTransfers"), true); m_istartnextfile = ini.GetInt(_T("StartNextFile"), 0); m_bshowoverhead = ini.GetBool(_T("ShowOverhead"), false); - moviePreviewBackup = ini.GetBool(_T("VideoPreviewBackupped"), true); + m_bMoviePreviewBackup = ini.GetBool(_T("VideoPreviewBackupped"), true); m_iPreviewSmallBlocks = ini.GetInt(_T("PreviewSmallBlocks"), 0); m_bPreviewCopiedArchives = ini.GetBool(_T("PreviewCopiedArchives"), true); m_iInspectAllFileTypes = ini.GetInt(_T("InspectAllFileTypes"), 0); @@ -2222,7 +2207,7 @@ void CPreferences::LoadPreferences() m_iQueueSize = (INT_PTR)ini.GetInt(_T("QueueSizePref"), 50) * 100; // old setting m_iQueueSize = ini.GetInt(_T("QueueSize"), (int)m_iQueueSize); - m_iCommitFiles = ini.GetInt(_T("CommitFiles"), 1); // 1 = "commit" on application shut down; 2 = "commit" on each file saving + m_iCommitFiles = ini.GetInt(_T("CommitFiles"), 1); // 1 = "commit" on application shutdown; 2 = "commit" on each file saving versioncheckdays = ini.GetInt(_T("Check4NewVersionDelay"), 5); m_bDAP = ini.GetBool(_T("DAPPref"), true); m_bUAP = ini.GetBool(_T("UAPPref"), true); @@ -2267,7 +2252,7 @@ void CPreferences::LoadPreferences() // if emule is using the default, check if the file is in the config folder, as it used to be val prior version // and might be wanted by the user when switching to a personalized template if (m_strTemplateFile.Compare(GetMuleDirectory(EMULE_EXECUTABLEDIR) + _T("eMule.tmpl")) == 0) - if (PathFileExists(GetMuleDirectory(EMULE_CONFIGDIR) + _T("eMule.tmpl"))) + if (::PathFileExists(GetMuleDirectory(EMULE_CONFIGDIR) + _T("eMule.tmpl"))) m_strTemplateFile = GetMuleDirectory(EMULE_CONFIGDIR) + _T("eMule.tmpl"); messageFilter = ini.GetStringLong(_T("MessageFilter"), _T("fastest download speed|fastest eMule")); @@ -2291,6 +2276,8 @@ void CPreferences::LoadPreferences() m_sToolbarBitmapFolder = ini.GetString(_T("ToolbarBitmapFolder"), _T("")); if (m_sToolbarBitmapFolder.IsEmpty()) // We want GetDefaultDirectory to also create the folder, so we have to know if we use the default or not m_sToolbarBitmapFolder = GetDefaultDirectory(EMULE_TOOLBARDIR, true); + else + slosh(m_sToolbarBitmapFolder); m_nToolbarLabels = (EToolbarLabelType)ini.GetInt(_T("ToolbarLabels"), CMuleToolbarCtrl::GetDefaultLabelType()); m_bReBarToolbar = ini.GetBool(_T("ReBarToolbar"), 1); m_sizToolbarIconSize.cx = m_sizToolbarIconSize.cy = ini.GetInt(_T("ToolbarIconSize"), 32); @@ -2301,7 +2288,8 @@ void CPreferences::LoadPreferences() m_strSkinProfileDir = ini.GetString(_T("SkinProfileDir"), _T("")); if (m_strSkinProfileDir.IsEmpty()) // We want GetDefaultDirectory to also create the folder, so we have to know if we use the default or not m_strSkinProfileDir = GetDefaultDirectory(EMULE_SKINDIR, true); - + else + slosh(m_strSkinProfileDir); LPBYTE pData = NULL; UINT uSize = sizeof m_lfHyperText; @@ -2331,8 +2319,6 @@ void CPreferences::LoadPreferences() m_bDynUpUseMillisecondPingTolerance = ini.GetBool(_T("USSUseMillisecondPingTolerance"), false); m_iDynUpPingTolerance = ini.GetInt(_T("USSPingTolerance"), 500); m_iDynUpPingToleranceMilliseconds = ini.GetInt(_T("USSPingToleranceMilliseconds"), 200); - if (m_minupload < 1) - m_minupload = 1; m_iDynUpGoingUpDivider = ini.GetInt(_T("USSGoingUpDivider"), 1000); m_iDynUpGoingDownDivider = ini.GetInt(_T("USSGoingDownDivider"), 1000); m_iDynUpNumberOfPings = ini.GetInt(_T("USSNumberOfPings"), 1); @@ -2398,7 +2384,7 @@ void CPreferences::LoadPreferences() if (_stscanf(ini.GetString(buffer, _T("")), _T("%li"), (long*)&m_adwStatsColors[i]) != 1) ResetStatsColor(i); } - bHasCustomTaskIconColor = ini.GetBool(_T("HasCustomTaskIconColor"), false); + m_bHasCustomTaskIconColor = ini.GetBool(_T("HasCustomTaskIconColor"), false); m_bShowVerticalHourMarkers = ini.GetBool(_T("ShowVerticalHourMarkers"), true); // -khaos--+++> Load Stats @@ -2492,16 +2478,16 @@ UINT CPreferences::GetDefaultMaxConperFive() void CPreferences::SaveCats() { CString strCatIniFilePath; - strCatIniFilePath.Format(_T("%sCategory.ini"), (LPCTSTR)GetMuleDirectory(EMULE_CONFIGDIR)); + strCatIniFilePath.Format(_T("%s") _T("Category.ini"), (LPCTSTR)GetMuleDirectory(EMULE_CONFIGDIR)); (void)_tremove(strCatIniFilePath); CIni ini(strCatIniFilePath); - ini.WriteInt(_T("Count"), (int)catMap.GetCount() - 1, _T("General")); - for (INT_PTR i = 0; i < catMap.GetCount(); ++i) { + ini.WriteInt(_T("Count"), (int)catArr.GetCount() - 1, _T("General")); + for (INT_PTR i = 0; i < catArr.GetCount(); ++i) { CString strSection; strSection.Format(_T("Cat#%i"), (int)i); ini.SetSection(strSection); - const Category_Struct *cmap = catMap[i]; + const Category_Struct *cmap = catArr[i]; ini.WriteStringUTF8(_T("Title"), cmap->strTitle); ini.WriteStringUTF8(_T("Incoming"), cmap->strIncomingPath); @@ -2521,7 +2507,7 @@ void CPreferences::SaveCats() void CPreferences::LoadCats() { CString strCatIniFilePath; - strCatIniFilePath.Format(_T("%sCategory.ini"), (LPCTSTR)GetMuleDirectory(EMULE_CONFIGDIR)); + strCatIniFilePath.Format(_T("%s") _T("Category.ini"), (LPCTSTR)GetMuleDirectory(EMULE_CONFIGDIR)); CIni ini(strCatIniFilePath); int iNumCategories = ini.GetInt(_T("Count"), 0, _T("General")); for (INT_PTR i = 0; i <= iNumCategories; ++i) { @@ -2536,10 +2522,9 @@ void CPreferences::LoadCats() newcat->strIncomingPath = ini.GetStringUTF8(_T("Incoming")); MakeFoldername(newcat->strIncomingPath); if (!IsShareableDirectory(newcat->strIncomingPath) - || (!PathFileExists(newcat->strIncomingPath) && !::CreateDirectory(newcat->strIncomingPath, 0))) + || (!::PathFileExists(newcat->strIncomingPath) && !::CreateDirectory(newcat->strIncomingPath, 0))) { newcat->strIncomingPath = GetMuleDirectory(EMULE_INCOMINGDIR); - MakeFoldername(newcat->strIncomingPath); } } else newcat->strIncomingPath.Empty(); @@ -2559,17 +2544,17 @@ void CPreferences::LoadCats() void CPreferences::RemoveCat(INT_PTR index) { - if (index >= 0 && index < catMap.GetCount()) { - const Category_Struct *delcat = catMap[index]; - catMap.RemoveAt(index); + if (index >= 0 && index < catArr.GetCount()) { + const Category_Struct *delcat = catArr[index]; + catArr.RemoveAt(index); delete delcat; } } bool CPreferences::SetCatFilter(INT_PTR index, int filter) { - if (index >= 0 && index < catMap.GetCount()) { - catMap[index]->filter = filter; + if (index >= 0 && index < catArr.GetCount()) { + catArr[index]->filter = filter; return true; } return false; @@ -2577,36 +2562,36 @@ bool CPreferences::SetCatFilter(INT_PTR index, int filter) int CPreferences::GetCatFilter(INT_PTR index) { - if (index >= 0 && index < catMap.GetCount()) - return catMap[index]->filter; + if (index >= 0 && index < catArr.GetCount()) + return catArr[index]->filter; return 0; } bool CPreferences::GetCatFilterNeg(INT_PTR index) { - if (index >= 0 && index < catMap.GetCount()) - return catMap[index]->filterNeg; + if (index >= 0 && index < catArr.GetCount()) + return catArr[index]->filterNeg; return false; } void CPreferences::SetCatFilterNeg(INT_PTR index, bool val) { - if (index >= 0 && index < catMap.GetCount()) - catMap[index]->filterNeg = val; + if (index >= 0 && index < catArr.GetCount()) + catArr[index]->filterNeg = val; } bool CPreferences::MoveCat(INT_PTR from, INT_PTR to) { - if (from >= catMap.GetCount() || to >= catMap.GetCount() + 1 || from == to) + if (from >= catArr.GetCount() || to >= catArr.GetCount() + 1 || from == to) return false; - Category_Struct *tomove = catMap[from]; + Category_Struct *tomove = catArr[from]; if (from < to) { - catMap.RemoveAt(from); - catMap.InsertAt(to - 1, tomove); + catArr.RemoveAt(from); + catArr.InsertAt(to - 1, tomove); } else { - catMap.InsertAt(to, tomove); - catMap.RemoveAt(from + 1); + catArr.InsertAt(to, tomove); + catArr.RemoveAt(from + 1); } SaveCats(); return true; @@ -2614,8 +2599,8 @@ bool CPreferences::MoveCat(INT_PTR from, INT_PTR to) DWORD CPreferences::GetCatColor(INT_PTR index, int nDefault) { - if (index >= 0 && index < catMap.GetCount()) { - const COLORREF c = catMap[index]->color; + if (index >= 0 && index < catArr.GetCount()) { + const COLORREF c = catArr[index]->color; if (c != CLR_NONE) return c; } @@ -2628,26 +2613,23 @@ DWORD CPreferences::GetCatColor(INT_PTR index, int nDefault) bool CPreferences::IsInstallationDirectory(const CString &rstrDir) { - CString strFullPath(rstrDir); - canonical(strFullPath); // skip sharing of several special eMule folders - return !CompareDirectory(strFullPath, GetMuleDirectory(EMULE_EXECUTABLEDIR)) - || !CompareDirectory(strFullPath, GetMuleDirectory(EMULE_CONFIGDIR)) - || !CompareDirectory(strFullPath, GetMuleDirectory(EMULE_WEBSERVERDIR)) - || !CompareDirectory(strFullPath, GetMuleDirectory(EMULE_INSTLANGDIR)) - || !CompareDirectory(strFullPath, GetMuleDirectory(EMULE_LOGDIR)); + return EqualPaths(rstrDir, GetMuleDirectory(EMULE_EXECUTABLEDIR)) + || EqualPaths(rstrDir, GetMuleDirectory(EMULE_CONFIGDIR)) + || EqualPaths(rstrDir, GetMuleDirectory(EMULE_WEBSERVERDIR)) + || EqualPaths(rstrDir, GetMuleDirectory(EMULE_INSTLANGDIR)) + || EqualPaths(rstrDir, GetMuleDirectory(EMULE_LOGDIR)); } bool CPreferences::IsShareableDirectory(const CString &rstrDir) { + // skip sharing of several special eMule folders if (IsInstallationDirectory(rstrDir)) return false; - CString strFullPath(rstrDir); - canonical(strFullPath); - - // skip sharing of several special eMule folders + if (EqualPaths(rstrDir, GetMuleDirectory(EMULE_INCOMINGDIR))) + return false; for (INT_PTR i = GetTempDirCount(); --i >= 0;) - if (!CompareDirectory(strFullPath, GetTempDir(i))) // ".\eMule\temp" + if (EqualPaths(rstrDir, GetTempDir(i))) // ".\eMule\temp" return false; return true; @@ -2713,27 +2695,29 @@ CString CPreferences::GetHomepageBaseURLForLevel(int nLevel) CString CPreferences::GetVersionCheckBaseURL() { CString tmp; + LPCTSTR p = NULL; UINT nWebMirrorAlertLevel = GetWebMirrorAlertLevel(); if (nWebMirrorAlertLevel < 100) - tmp = _T("https://vcheck.emule-project.net"); + p = _T("https://vcheck.emule-project.net"); else if (nWebMirrorAlertLevel < 150) tmp.Format(_T("https://vcheck%u.emule-project.org"), nWebMirrorAlertLevel); else if (nWebMirrorAlertLevel < 200) tmp.Format(_T("https://vcheck%u.emule-project.com"), nWebMirrorAlertLevel); else if (nWebMirrorAlertLevel == 200) - tmp = _T("https://emule.sf.net"); + p = _T("https://emule.sf.net"); else if (nWebMirrorAlertLevel == 201) - tmp = _T("https://www.emuleproject.net"); + p = _T("https://www.emuleproject.net"); else - tmp = _T("https://vcheck.emule-project.net"); + p = _T("https://vcheck.emule-project.net"); + if (p) + tmp = p; return tmp; } CString CPreferences::GetVersionCheckURL() { - CString theUrl; - theUrl.Format(_T("%s/en/version_check.php?version=%u&language=%u") _T("&mod=1") //this suffix for community version only - , (LPCTSTR)thePrefs.GetVersionCheckBaseURL() + CString theUrl(thePrefs.GetVersionCheckBaseURL()); + theUrl.AppendFormat(_T("/en/version_check.php?version=%u&language=%u") _T("&mod=1") //this suffix for community version only , theApp.m_uCurVersionCheck , thePrefs.GetLanguageID()); return theUrl; @@ -2780,11 +2764,11 @@ bool CPreferences::GetUseReBarToolbar() return GetReBarToolbar() && theApp.m_ullComCtrlVer >= MAKEDLLVERULL(5, 8, 0, 0); } -int CPreferences::GetMaxGraphUploadRate(bool bEstimateIfUnlimited) +uint32 CPreferences::GetMaxGraphUploadRate(bool bEstimateIfUnlimited) { if (maxGraphUploadRate != UNLIMITED || !bEstimateIfUnlimited) return maxGraphUploadRate; - return (maxGraphUploadRateEstimated != 0) ? maxGraphUploadRateEstimated + 4 : 16; + return (maxGraphUploadRateEstimated != 0) ? maxGraphUploadRateEstimated + 4 : 16u; } void CPreferences::EstimateMaxUploadCap(uint32 nCurrentUpload) @@ -2796,9 +2780,9 @@ void CPreferences::EstimateMaxUploadCap(uint32 nCurrentUpload) } } -void CPreferences::SetMaxGraphUploadRate(int in) +void CPreferences::SetMaxGraphUploadRate(uint32 in) { - maxGraphUploadRate = (in) ? in : UNLIMITED; + maxGraphUploadRate = (in ? in : UNLIMITED); } bool CPreferences::IsDynUpEnabled() @@ -2819,32 +2803,16 @@ uint16 CPreferences::GetRandomTCPPort() { // Get table of currently used TCP ports. PMIB_TCPTABLE pTCPTab = NULL; - // Couple of crash dmp files are showing that we may crash somewhere in 'iphlpapi.dll' when doing the 2nd call - __try { - HMODULE hIpHlpDll = LoadLibrary(_T("iphlpapi.dll")); - if (hIpHlpDll) { - DWORD(WINAPI *pfnGetTcpTable)(PMIB_TCPTABLE, PDWORD, BOOL); - (FARPROC&)pfnGetTcpTable = GetProcAddress(hIpHlpDll, "GetTcpTable"); - if (pfnGetTcpTable) { - DWORD dwSize = 0; - if ((*pfnGetTcpTable)(NULL, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER) { - // The nr. of TCP entries could change (increase) between - // the two function calls, allocate some more memory. - dwSize += sizeof(pTCPTab->table[0]) * 50; - pTCPTab = (PMIB_TCPTABLE)malloc(dwSize); - if (pTCPTab) { - if ((*pfnGetTcpTable)(pTCPTab, &dwSize, TRUE) != ERROR_SUCCESS) { - free(pTCPTab); - pTCPTab = NULL; - } - } - } - } - FreeLibrary(hIpHlpDll); + ULONG dwSize = 0; + if (GetTcpTable(pTCPTab, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER) { + // Allocate more memory in case the number of TCP entries increased + // between the function calls. + dwSize += sizeof(MIB_TCPROW) * 50; + pTCPTab = (PMIB_TCPTABLE)malloc(dwSize); + if (pTCPTab && GetTcpTable(pTCPTab, &dwSize, TRUE) != ERROR_SUCCESS) { + free(pTCPTab); + pTCPTab = NULL; } - } __except (EXCEPTION_EXECUTE_HANDLER) { - free(pTCPTab); - pTCPTab = NULL; } static const UINT uValidPortRange = 61000; @@ -2855,14 +2823,14 @@ uint16 CPreferences::GetRandomTCPPort() // Get random port nPort = 4096 + (GetRandomUInt16() % uValidPortRange); - // The port is by default assumed to be available. If we got a table of currently - // used TCP ports, we verify that this port is currently not used in any way. + // The port is assumed to be available by default. If we got a table of currently + // used TCP ports, verify that the port is not in this table. bPortIsFree = true; if (pTCPTab) { uint16 nPortBE = htons(nPort); for (DWORD e = pTCPTab->dwNumEntries; e-- > 0;) { // If there is a TCP entry in the table (regardless of its state), the port - // is treated as not available. + // is treated as unavailable. if (pTCPTab->table[e].dwLocalPort == nPortBE) { bPortIsFree = false; break; @@ -2878,30 +2846,16 @@ uint16 CPreferences::GetRandomUDPPort() { // Get table of currently used UDP ports. PMIB_UDPTABLE pUDPTab = NULL; - // Couple of crash dmp files are showing that we may crash somewhere in 'iphlpapi.dll' when doing the 2nd call - __try { - HMODULE hIpHlpDll = LoadLibrary(_T("iphlpapi.dll")); - if (hIpHlpDll) { - DWORD(WINAPI *pfnGetUdpTable)(PMIB_UDPTABLE, PDWORD, BOOL); - (FARPROC&)pfnGetUdpTable = GetProcAddress(hIpHlpDll, "GetUdpTable"); - if (pfnGetUdpTable) { - DWORD dwSize = 0; - if ((*pfnGetUdpTable)(NULL, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER) { - // The nr. of UDP entries could change (increase) between - // the two function calls, allocate some more memory. - dwSize += sizeof(pUDPTab->table[0]) * 50; - pUDPTab = (PMIB_UDPTABLE)malloc(dwSize); - if (pUDPTab && (*pfnGetUdpTable)(pUDPTab, &dwSize, TRUE) != ERROR_SUCCESS) { - free(pUDPTab); - pUDPTab = NULL; - } - } - } - FreeLibrary(hIpHlpDll); + ULONG dwSize = 0; + if (GetUdpTable(NULL, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER) { + // Allocate more memory in case the number of UDP entries increased + // between the function calls. + dwSize += sizeof(MIB_UDPROW) * 50; + pUDPTab = (PMIB_UDPTABLE)malloc(dwSize); + if (pUDPTab && GetUdpTable(pUDPTab, &dwSize, TRUE) != ERROR_SUCCESS) { + free(pUDPTab); + pUDPTab = NULL; } - } __except (EXCEPTION_EXECUTE_HANDLER) { - free(pUDPTab); - pUDPTab = NULL; } static const UINT uValidPortRange = 61000; @@ -2912,8 +2866,8 @@ uint16 CPreferences::GetRandomUDPPort() // Get random port nPort = 4096 + (GetRandomUInt16() % uValidPortRange); - // The port is by default assumed to be available. If we got a table of currently - // used UDP ports, we verify that this port is currently not used in any way. + // The port is assumed to be available by default. If we got a table of currently + // used UDP ports, verify that the port is not in this table. bPortIsFree = true; if (pUDPTab) { uint16 nPortBE = htons(nPort); @@ -2952,19 +2906,19 @@ CString CPreferences::GetDefaultDirectory(EDefaultDirectory eDirectory, bool bCr TCHAR tchBuffer[MAX_PATH]; ::GetModuleFileName(NULL, tchBuffer, _countof(tchBuffer)); tchBuffer[_countof(tchBuffer) - 1] = _T('\0'); - LPTSTR pszFileName = _tcsrchr(tchBuffer, L'\\') + 1; - *pszFileName = L'\0'; + LPTSTR pszFileName = _tcsrchr(tchBuffer, _T('\\')) + 1; + *pszFileName = _T('\0'); m_astrDefaultDirs[EMULE_EXECUTABLEDIR] = tchBuffer; // set our results to old default / fallback values // those 3 dirs are the base for all others - CString strSelectedDataBaseDirectory = m_astrDefaultDirs[EMULE_EXECUTABLEDIR]; - CString strSelectedConfigBaseDirectory = m_astrDefaultDirs[EMULE_EXECUTABLEDIR]; - CString strSelectedExpansionBaseDirectory = m_astrDefaultDirs[EMULE_EXECUTABLEDIR]; + CString strSelectedDataBaseDirectory(m_astrDefaultDirs[EMULE_EXECUTABLEDIR]); + CString strSelectedConfigBaseDirectory(m_astrDefaultDirs[EMULE_EXECUTABLEDIR]); + CString strSelectedExpansionBaseDirectory(m_astrDefaultDirs[EMULE_EXECUTABLEDIR]); m_nCurrentUserDirMode = 2; // To let us know which "mode" we are using in case we want to switch per options // check if preferences.ini exists already in our default / fallback dir - bool bConfigAvailableExecutable = (PathFileExists(strSelectedConfigBaseDirectory + CONFIGFOLDER _T("preferences.ini")) != FALSE); + bool bConfigAvailableExecutable = (::PathFileExists(strSelectedConfigBaseDirectory + CONFIGFOLDER _T("preferences.ini")) != FALSE); // check if our registry setting is present which forces the single or multiuser directories // and lets us ignore other defaults @@ -2992,7 +2946,7 @@ CString CPreferences::GetDefaultDirectory(EDefaultDirectory eDirectory, bool bCr PWSTR pszPublicDownloads = NULL; PWSTR pszProgramData = NULL; - // function not available on < WinVista + // function not available before WinVista HRESULT(WINAPI *pfnSHGetKnownFolderPath)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR*); (FARPROC&)pfnSHGetKnownFolderPath = GetProcAddress(hShell32, "SHGetKnownFolderPath"); @@ -3002,8 +2956,10 @@ CString CPreferences::GetDefaultDirectory(EDefaultDirectory eDirectory, bool bCr && (*pfnSHGetKnownFolderPath)(FOLDERID_PublicDownloads, 0, NULL, &pszPublicDownloads) == S_OK && (*pfnSHGetKnownFolderPath)(FOLDERID_ProgramData, 0, NULL, &pszProgramData) == S_OK) { - if (_tcsclen(pszLocalAppData) < MAX_PATH - 30 && _tcsclen(pszPersonalDownloads) < MAX_PATH - 40 - && _tcsclen(pszProgramData) < MAX_PATH - 30 && _tcsclen(pszPublicDownloads) < MAX_PATH - 40) + if (_tcsclen(pszLocalAppData) < MAX_PATH - 30 + && _tcsclen(pszPersonalDownloads) < MAX_PATH - 40 + && _tcsclen(pszProgramData) < MAX_PATH - 30 + && _tcsclen(pszPublicDownloads) < MAX_PATH - 40) { CString strLocalAppData(pszLocalAppData); CString strPersonalDownloads(pszPersonalDownloads); @@ -3016,16 +2972,14 @@ CString CPreferences::GetDefaultDirectory(EDefaultDirectory eDirectory, bool bCr if (nRegistrySetting == _UI32_MAX) { // no registry default, check if we find a preferences.ini to use - if (PathFileExists(strLocalAppData + _T("eMule\\") CONFIGFOLDER _T("preferences.ini"))) + if (::PathFileExists(strLocalAppData + _T("eMule\\") CONFIGFOLDER _T("preferences.ini"))) m_nCurrentUserDirMode = 0; - else { - if (PathFileExists(strProgramData + _T("eMule\\") CONFIGFOLDER _T("preferences.ini"))) - m_nCurrentUserDirMode = 1; - else if (bConfigAvailableExecutable) - m_nCurrentUserDirMode = 2; - else - m_nCurrentUserDirMode = 0; // no preferences.ini found, use the default - } + else if (::PathFileExists(strProgramData + _T("eMule\\") CONFIGFOLDER _T("preferences.ini"))) + m_nCurrentUserDirMode = 1; + else if (bConfigAvailableExecutable) + m_nCurrentUserDirMode = 2; + else + m_nCurrentUserDirMode = 0; // no preferences.ini found, use the default } else m_nCurrentUserDirMode = nRegistrySetting; @@ -3048,14 +3002,14 @@ CString CPreferences::GetDefaultDirectory(EDefaultDirectory eDirectory, bool bCr ASSERT(0); } - CoTaskMemFree(pszLocalAppData); - CoTaskMemFree(pszPersonalDownloads); - CoTaskMemFree(pszPublicDownloads); - CoTaskMemFree(pszProgramData); + ::CoTaskMemFree(pszLocalAppData); + ::CoTaskMemFree(pszPersonalDownloads); + ::CoTaskMemFree(pszPublicDownloads); + ::CoTaskMemFree(pszProgramData); } else { // GetWindowsVersion() < _WINVER_VISTA_ - CString strAppData = ShellGetFolderPath(CSIDL_APPDATA); - CString strPersonal = ShellGetFolderPath(CSIDL_PERSONAL); + CString strAppData(ShellGetFolderPath(CSIDL_APPDATA)); + CString strPersonal(ShellGetFolderPath(CSIDL_PERSONAL)); if (!strAppData.IsEmpty() && !strPersonal.IsEmpty()) { if (strAppData.GetLength() < MAX_PATH - 30 && strPersonal.GetLength() < MAX_PATH - 40) { slosh(strPersonal); @@ -3067,7 +3021,7 @@ CString CPreferences::GetDefaultDirectory(EDefaultDirectory eDirectory, bool bCr m_nCurrentUserDirMode = 0; // strSelectedExpansionBaseDirectory stays default } else if (nRegistrySetting == _UI32_MAX && !bConfigAvailableExecutable) { - if (PathFileExists(strAppData + _T("eMule\\") CONFIGFOLDER _T("preferences.ini"))) { + if (::PathFileExists(strAppData + _T("eMule\\") CONFIGFOLDER _T("preferences.ini"))) { // preferences.ini found, so we use this as default strSelectedDataBaseDirectory = strPersonal + _T("eMule Downloads\\"); strSelectedConfigBaseDirectory = strAppData + _T("eMule\\"); @@ -3086,20 +3040,20 @@ CString CPreferences::GetDefaultDirectory(EDefaultDirectory eDirectory, bool bCr } } - // the use of ending backslashes is inconsistent, would need a rework throughout the code to fix this + // All the directories (categories also) should have a trailing backslash m_astrDefaultDirs[EMULE_CONFIGDIR] = strSelectedConfigBaseDirectory + CONFIGFOLDER; - m_astrDefaultDirs[EMULE_TEMPDIR] = strSelectedDataBaseDirectory + _T("Temp"); - m_astrDefaultDirs[EMULE_INCOMINGDIR] = strSelectedDataBaseDirectory + _T("Incoming"); + m_astrDefaultDirs[EMULE_TEMPDIR] = strSelectedDataBaseDirectory + _T("Temp\\"); + m_astrDefaultDirs[EMULE_INCOMINGDIR] = strSelectedDataBaseDirectory + _T("Incoming\\"); m_astrDefaultDirs[EMULE_LOGDIR] = strSelectedConfigBaseDirectory + _T("logs\\"); m_astrDefaultDirs[EMULE_ADDLANGDIR] = strSelectedExpansionBaseDirectory + _T("lang\\"); m_astrDefaultDirs[EMULE_INSTLANGDIR] = m_astrDefaultDirs[EMULE_EXECUTABLEDIR] + _T("lang\\"); m_astrDefaultDirs[EMULE_WEBSERVERDIR] = m_astrDefaultDirs[EMULE_EXECUTABLEDIR] + _T("webserver\\"); - m_astrDefaultDirs[EMULE_SKINDIR] = strSelectedExpansionBaseDirectory + _T("skins"); - m_astrDefaultDirs[EMULE_DATABASEDIR] = strSelectedDataBaseDirectory; // has ending backslashes - m_astrDefaultDirs[EMULE_CONFIGBASEDIR] = strSelectedConfigBaseDirectory; // has ending backslashes - // EMULE_EXECUTABLEDIR - m_astrDefaultDirs[EMULE_TOOLBARDIR] = strSelectedExpansionBaseDirectory + _T("skins"); - m_astrDefaultDirs[EMULE_EXPANSIONDIR] = strSelectedExpansionBaseDirectory; // has ending backslashes + m_astrDefaultDirs[EMULE_SKINDIR] = strSelectedExpansionBaseDirectory + _T("skins\\"); + m_astrDefaultDirs[EMULE_DATABASEDIR] = strSelectedDataBaseDirectory; + m_astrDefaultDirs[EMULE_CONFIGBASEDIR] = strSelectedConfigBaseDirectory; + // [EMULE_EXECUTABLEDIR] - has been set already + m_astrDefaultDirs[EMULE_TOOLBARDIR] = m_astrDefaultDirs[EMULE_SKINDIR]; + m_astrDefaultDirs[EMULE_EXPANSIONDIR] = strSelectedExpansionBaseDirectory; /*CString strDebug; for (int i = 0; i < 12; ++i) @@ -3133,7 +3087,7 @@ CString CPreferences::GetMuleDirectory(EDefaultDirectory eDirectory, bool bCreat case EMULE_INCOMINGDIR: return m_strIncomingDir; case EMULE_TEMPDIR: - ASSERT(0); // use GetTempDir() instead! This function can only return the first tempdirectory + ASSERT(0); // This function can return only the first temp. directory. Use GetTempDir() instead! return GetTempDir(0); case EMULE_SKINDIR: return m_strSkinProfileDir; @@ -3151,9 +3105,11 @@ void CPreferences::SetMuleDirectory(EDefaultDirectory eDirectory, const CString break; case EMULE_SKINDIR: m_strSkinProfileDir = strNewDir; + slosh(m_strSkinProfileDir); break; case EMULE_TOOLBARDIR: m_sToolbarBitmapFolder = strNewDir; + slosh(m_sToolbarBitmapFolder); break; default: ASSERT(0); @@ -3170,7 +3126,7 @@ void CPreferences::ChangeUserDirMode(int nNewMode) } // check if our registry setting is present which forces the single or multiuser directories // and lets us ignore other defaults - // 0 = Multiuser, 1 = Publicuser, 2 = ExecutableDir. + // 0 = Multiuser, 1 = Public user, 2 = ExecutableDir. CRegKey rkEMuleRegKey; if (rkEMuleRegKey.Create(HKEY_CURRENT_USER, _T("Software\\eMule")) == ERROR_SUCCESS) { if (rkEMuleRegKey.SetDWORDValue(_T("UsePublicUserDirectories"), nNewMode) != ERROR_SUCCESS) diff --git a/srchybrid/Preferences.h b/srchybrid/Preferences.h index 49f6214d..124cd08a 100644 --- a/srchybrid/Preferences.h +++ b/srchybrid/Preferences.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -16,7 +16,7 @@ //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #pragma once -static LPCTSTR const strDefaultToolbar = _T("0099010203040506070899091011"); +extern LPCTSTR const strDefaultToolbar; enum EViewSharedFilesAccess { @@ -116,10 +116,10 @@ struct Category_Struct CString strIncomingPath; CString strTitle; CString strComment; - COLORREF color; - UINT prio; CString autocat; CString regexp; + COLORREF color; + UINT prio; int filter; bool filterNeg; bool care4all; @@ -144,6 +144,8 @@ class CPreferences friend class CPPgTweaks; friend class Wizard; + static LPCSTR m_pszBindAddrA; + static LPCWSTR m_pszBindAddrW; public: static CString strNick; // ZZ:UploadSpeedSense --> @@ -151,9 +153,7 @@ class CPreferences // ZZ:UploadSpeedSense <-- static uint32 m_maxupload; static uint32 m_maxdownload; - static LPCSTR m_pszBindAddrA; static CStringA m_strBindAddrA; - static LPCWSTR m_pszBindAddrW; static CStringW m_strBindAddrW; static uint16 port; static uint16 udpport; @@ -189,15 +189,15 @@ class CPreferences static bool m_bFillGraphs; static uchar userhash[16]; static WINDOWPLACEMENT EmuleWindowPlacement; - static int maxGraphDownloadRate; - static int maxGraphUploadRate; + static uint32 maxGraphDownloadRate; + static uint32 maxGraphUploadRate; static uint32 maxGraphUploadRateEstimated; static bool beepOnError; static bool confirmExit; static DWORD m_adwStatsColors[15]; - static bool bHasCustomTaskIconColor; + static bool m_bHasCustomTaskIconColor; static bool m_bIconflashOnNewMessage; - + static bool splashscreen; static bool filterLANIPs; static bool m_bAllocLocalHostIP; @@ -473,11 +473,11 @@ class CPreferences static UINT versioncheckdays; static bool showRatesInTitle; - + static CString m_strTxtEditor; static CString m_strVideoPlayer; static CString m_strVideoPlayerArgs; - static bool moviePreviewBackup; + static bool m_bMoviePreviewBackup; static int m_iPreviewSmallBlocks; static bool m_bPreviewCopiedArchives; static int m_iInspectAllFileTypes; @@ -489,7 +489,7 @@ class CPreferences static bool m_bFirstStart; static bool m_bBetaNaggingDone; static bool m_bCreditSystem; - + static bool log2disk; static bool debug2disk; static int iMaxLogBuff; @@ -500,13 +500,13 @@ class CPreferences static bool msgonlyfriends; static bool msgsecure; static bool m_bUseChatCaptchas; - + static UINT filterlevel; static UINT m_uFileBufferSize; static INT_PTR m_iQueueSize; static int m_iCommitFiles; static DWORD m_uFileBufferTimeLimit; - + static UINT maxmsgsessions; static time_t versioncheckLastAutomatic; static CString messageFilter; @@ -561,11 +561,11 @@ class CPreferences static bool m_bRemoveFinishedDownloads; static INT_PTR m_iMaxChatHistory; static bool m_bShowActiveDownloadsBold; - + static int m_iSearchMethod; static bool m_bAdvancedSpamfilter; static bool m_bUseSecureIdent; - + static bool networkkademlia; static bool networked2k; @@ -576,7 +576,7 @@ class CPreferences static CString m_sToolbarSettings; static bool m_bReBarToolbar; static CSize m_sizToolbarIconSize; - + static bool m_bWinaTransToolbar; static bool m_bShowDownloadToolbar; @@ -607,7 +607,7 @@ class CPreferences static UINT m_nWebMirrorAlertLevel; static bool m_bRunAsUser; static bool m_bPreferRestrictedOverUser; - + static bool m_bUseOldTimeRemaining; // PeerCache @@ -788,19 +788,19 @@ class CPreferences // Saved stats for cumulative upline data static uint32 GetUpSuccessfulSessions() { return cumUpSuccessfulSessions; } static uint32 GetUpFailedSessions() { return cumUpFailedSessions; } - static uint32 GetUpAvgTime() { return cumUpAvgTime; } + static uint32 GetUpAvgTime() { return cumUpSuccessfulSessions ? cumConnUploadTime / cumUpSuccessfulSessions : 0; } // Saved stats for cumulative downline data static uint32 GetDownCompletedFiles() { return cumDownCompletedFiles; } static uint32 GetDownC_SuccessfulSessions() { return cumDownSuccessfulSessions; } static uint32 GetDownC_FailedSessions() { return cumDownFailedSessions; } - static uint32 GetDownC_AvgTime() { return cumDownAvgTime; } + static uint32 GetDownC_AvgTime() { return cumDownSuccessfulSessions ? cumConnDownloadTime / cumDownSuccessfulSessions : 0; } // Session download stats static uint32 GetDownSessionCompletedFiles() { return sesDownCompletedFiles; } static uint32 GetDownS_SuccessfulSessions() { return sesDownSuccessfulSessions; } static uint32 GetDownS_FailedSessions() { return sesDownFailedSessions; } - static uint32 GetDownS_AvgTime() { return GetDownS_SuccessfulSessions() ? sesDownAvgTime / GetDownS_SuccessfulSessions() : 0; } + static uint32 GetDownS_AvgTime() { return sesDownSuccessfulSessions ? sesDownAvgTime / sesDownSuccessfulSessions : 0; } // Saved stats for corruption/compression static uint64 GetCumLostFromCorruption() { return cumLostFromCorruption; } @@ -969,10 +969,10 @@ class CPreferences static bool FilterLANIPs() { return filterLANIPs; } static bool GetAllowLocalHostIP() { return m_bAllocLocalHostIP; } static bool IsOnlineSignatureEnabled() { return onlineSig; } - static int GetMaxGraphUploadRate(bool bEstimateIfUnlimited); - static int GetMaxGraphDownloadRate() { return maxGraphDownloadRate; } - static void SetMaxGraphUploadRate(int in); - static void SetMaxGraphDownloadRate(int in) { maxGraphDownloadRate = (in ? in : 96); } + static uint32 GetMaxGraphDownloadRate() { return maxGraphDownloadRate; } + static void SetMaxGraphDownloadRate(uint32 in) { maxGraphDownloadRate = (in ? in : 96); } + static uint32 GetMaxGraphUploadRate(bool bEstimateIfUnlimited); + static void SetMaxGraphUploadRate(uint32 in); static uint32 GetMaxDownload(); static uint64 GetMaxDownloadInBytesPerSec(bool dynamic = false); @@ -1135,7 +1135,7 @@ class CPreferences static void GetAllStatsColors(int iCount, LPDWORD pdwColors); static bool SetAllStatsColors(int iCount, const LPDWORD pdwColors); static void ResetStatsColor(int index); - static bool HasCustomTaskIconColor() { return bHasCustomTaskIconColor; } + static bool HasCustomTaskIconColor() { return m_bHasCustomTaskIconColor; } static void SetMaxConsPerFive(UINT in) { MaxConperFive = in; } static LPLOGFONT GetHyperTextLogFont() { return &m_lfHyperText; } @@ -1151,7 +1151,7 @@ class CPreferences static bool IsSafeServerConnectEnabled() { return m_bSafeServerConnect; } static void SetSafeServerConnectEnabled(bool in) { m_bSafeServerConnect = in; } - static bool IsMoviePreviewBackup() { return moviePreviewBackup; } + static bool IsMoviePreviewBackup() { return m_bMoviePreviewBackup; } static int GetPreviewSmallBlocks() { return m_iPreviewSmallBlocks; } static bool GetPreviewCopiedArchives() { return m_bPreviewCopiedArchives; } static int GetInspectAllFileTypes() { return m_iInspectAllFileTypes; } @@ -1193,16 +1193,16 @@ class CPreferences static const CString& GetDateTimeFormat4Lists() { return m_strDateTimeFormat4Lists; } // Download Categories (Ornis) - static INT_PTR AddCat(Category_Struct *cat) { catMap.Add(cat); return catMap.GetCount() - 1; } + static INT_PTR AddCat(Category_Struct *cat) { catArr.Add(cat); return catArr.GetCount() - 1; } static bool MoveCat(INT_PTR from, INT_PTR to); static void RemoveCat(INT_PTR index); - static INT_PTR GetCatCount() { return catMap.GetCount(); } + static INT_PTR GetCatCount() { return catArr.GetCount(); } static bool SetCatFilter(INT_PTR index, int filter); static int GetCatFilter(INT_PTR index); static bool GetCatFilterNeg(INT_PTR index); static void SetCatFilterNeg(INT_PTR index, bool val); - static Category_Struct* GetCategory(INT_PTR index) { return (index >= 0 && indexstrIncomingPath; } + static Category_Struct* GetCategory(INT_PTR index) { return (index >= 0 && indexstrIncomingPath; } static DWORD GetCatColor(INT_PTR index, int nDefault = COLOR_BTNTEXT); static bool GetPreviewOnIconDblClk() { return m_bPreviewOnIconDblClk; } @@ -1362,8 +1362,10 @@ class CPreferences static bool GetLogFileSaving() { return m_bVerbose && m_bLogFileSaving; } static bool GetLogA4AF() { return m_bVerbose && m_bLogA4AF; } // ZZ:DownloadManager static bool GetLogUlDlEvents() { return m_bVerbose && m_bLogUlDlEvents; } - static bool GetLogKadSecurityEvents() { return m_bVerbose && true; } + static bool GetLogKadSecurityEvents() { return m_bVerbose; } static bool GetUseDebugDevice() { return m_bUseDebugDevice; } + static int GetVerboseLogPriority() { return m_byLogLevel; } +#if defined(_DEBUG) || defined(USE_DEBUG_DEVICE) static int GetDebugServerTCPLevel() { return m_iDebugServerTCPLevel; } static int GetDebugServerUDPLevel() { return m_iDebugServerUDPLevel; } static int GetDebugServerSourcesLevel() { return m_iDebugServerSourcesLevel; } @@ -1372,7 +1374,18 @@ class CPreferences static int GetDebugClientUDPLevel() { return m_iDebugClientUDPLevel; } static int GetDebugClientKadUDPLevel() { return m_iDebugClientKadUDPLevel; } static int GetDebugSearchResultDetailLevel() { return m_iDebugSearchResultDetailLevel; } - static int GetVerboseLogPriority() { return m_byLogLevel; } +#else + // release builds optimise out the corresponding debug-only code + static int GetDebugServerTCPLevel() { return 0; } + static int GetDebugServerUDPLevel() { return 0; } + static int GetDebugServerSourcesLevel() { return 0; } + static int GetDebugServerSearchesLevel() { return 0; } + static int GetDebugClientTCPLevel() { return 0; } + static int GetDebugClientUDPLevel() { return 0; } + static int GetDebugClientKadUDPLevel() { return 0; } + static int GetDebugSearchResultDetailLevel() { return 0; } +#endif + // Firewall settings static bool IsOpenPortsOnStartupEnabled() { return m_bOpenPortsOnStartUp; } @@ -1438,14 +1451,14 @@ class CPreferences static CString m_strFileCommentsFilePath; static Preferences_Ext_Struct *prefsExt; static WORD m_wWinVer; - static CArray catMap; + static CArray catArr; static CString m_astrDefaultDirs[13]; static bool m_abDefaultDirsCreated[13]; static int m_nCurrentUserDirMode; // Only for PPgTweaks static void CreateUserHash(); static void SetStandardValues(); - static int GetRecommendedMaxConnections(); + static UINT GetRecommendedMaxConnections(); static void LoadPreferences(); static void SavePreferences(); static CString GetHomepageBaseURLForLevel(int nLevel); diff --git a/srchybrid/PreferencesDlg.cpp b/srchybrid/PreferencesDlg.cpp index 316c0f15..a750500b 100644 --- a/srchybrid/PreferencesDlg.cpp +++ b/srchybrid/PreferencesDlg.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -179,9 +179,9 @@ void CPreferencesDlg::OnHelp() HELPINFO hi = {}; hi.cbSize = (UINT)sizeof hi; hi.iContextType = HELPINFO_WINDOW; - hi.iCtrlId = 0; + //hi.iCtrlId = 0; hi.hItemHandle = pPage->m_hWnd; - hi.dwContextId = 0; + //hi.dwContextId = 0; pPage->SendMessage(WM_HELP, 0, (LPARAM)&hi); return; } diff --git a/srchybrid/PreferencesDlg.h b/srchybrid/PreferencesDlg.h index 2dd79901..97b8e0fc 100644 --- a/srchybrid/PreferencesDlg.h +++ b/srchybrid/PreferencesDlg.h @@ -27,7 +27,6 @@ class CPreferencesDlg : public CTreePropSheet void LocalizeItemText(int i, UINT strid); public: CPreferencesDlg(); - virtual ~CPreferencesDlg() = default; virtual BOOL OnInitDialog(); CPPgGeneral m_wndGeneral; diff --git a/srchybrid/Preview.cpp b/srchybrid/Preview.cpp index fcb98901..002f5412 100644 --- a/srchybrid/Preview.cpp +++ b/srchybrid/Preview.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -15,12 +15,13 @@ //along with this program; if not, write to the Free Software //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "stdafx.h" +#include #include #include #include "emule.h" -#include "Preview.h" #include "Preferences.h" #include "PartFile.h" +#include "Preview.h" #include "MenuCmds.h" #include "opcodes.h" @@ -38,11 +39,12 @@ CPreviewApps thePreviewApps; IMPLEMENT_DYNCREATE(CPreviewThread, CWinThread) -BEGIN_MESSAGE_MAP(CPreviewThread, CWinThread) -END_MESSAGE_MAP() +//BEGIN_MESSAGE_MAP(CPreviewThread, CWinThread) +//END_MESSAGE_MAP() CPreviewThread::CPreviewThread() : m_pPartfile() + , m_aFilled() { } @@ -55,61 +57,34 @@ BOOL CPreviewThread::InitInstance() BOOL CPreviewThread::Run() { - ASSERT(m_pPartfile); - CFile srcFile; - if (!srcFile.Open(m_pPartfile->GetFilePath(), CFile::modeRead | CFile::shareDenyNone)) - return FALSE; try { - uint64 nSize = m_pPartfile->GetFileSize(); - const CString strExtension(_tcsrchr(m_pPartfile->GetFileName(), _T('.'))); - CString strPreviewName; - strPreviewName.Format(_T("%s%s_preview%s"), (LPCTSTR)m_pPartfile->GetTempPath(), (LPCTSTR)m_pPartfile->GetFileName().Left(5), (LPCTSTR)strExtension); - bool bFullSized = (strExtension.CompareNoCase(_T(".mpg")) && strExtension.CompareNoCase(_T(".mpeg"))); - CFile destFile; - if (!destFile.Open(strPreviewName, CFile::modeWrite | CFile::shareDenyWrite | CFile::modeCreate)) + const CString srcName(m_pPartfile->GetFileName()); + LPCTSTR const pExt = _tcsrchr(srcName, _T('.')); + CString strPreviewName(m_pPartfile->GetTmpPath()); + strPreviewName.AppendFormat(_T("%s_preview%s"), (LPCTSTR)srcName.Left(5), (pExt ? pExt : _T(""))); + strPreviewName.Format(_T("%s%s-rec.tmp"), (LPCTSTR)m_pPartfile->GetTmpPath(), (LPCTSTR)m_pPartfile->GetFileName().Left(5)); + + bool bRet = m_pPartfile->CopyPartFile(m_aFilled, strPreviewName); + m_aFilled.RemoveAll(); + if (!bRet) return FALSE; - srcFile.SeekToBegin(); - if (bFullSized) - destFile.SetLength(nSize); - destFile.SeekToBegin(); - BYTE abyBuffer[4096]; - uint32 nRead; - while (destFile.GetPosition() + (sizeof abyBuffer) < PARTSIZE * 2) { - nRead = srcFile.Read(abyBuffer, sizeof abyBuffer); - destFile.Write(abyBuffer, nRead); - } - srcFile.Seek(-(LONGLONG)(PARTSIZE * 2), CFile::end); - uint32 nToGo = PARTSIZE * 2; - if (bFullSized) - destFile.Seek(-(LONGLONG)(PARTSIZE * 2), CFile::end); - do { - nRead = (nToGo - (sizeof abyBuffer) < 1) ? nToGo : sizeof abyBuffer; - nToGo -= nRead; - nRead = srcFile.Read(abyBuffer, sizeof abyBuffer); - destFile.Write(abyBuffer, nRead); - } while (nToGo); - destFile.Close(); - srcFile.Close(); - m_pPartfile->m_bPreviewing = false; SHELLEXECUTEINFO SE = {}; + SE.cbSize = (DWORD)sizeof SE; SE.fMask = SEE_MASK_NOCLOSEPROCESS; + SE.nShow = SW_SHOW; if (m_strCommand.IsEmpty()) { - SE.lpVerb = NULL; // use the default verb or the open verb for the document + // use the default verb for the document SE.lpFile = strPreviewName; + ShellExecuteEx(&SE); } else { SE.lpVerb = _T("open"); // "open" the specified video player // get directory of video player application - CString strCommandDir = m_strCommand; + CString strCommandDir(m_strCommand); int iPos = strCommandDir.ReverseFind(_T('\\')); - if (iPos < 0) - strCommandDir.Empty(); - else - strCommandDir.Truncate(iPos + 1); - PathRemoveBackslash(strCommandDir.GetBuffer()); - strCommandDir.ReleaseBuffer(); + strCommandDir.Truncate(iPos + 1); //may be empty CString strArgs(m_strCommandArgs); if (!strArgs.IsEmpty()) @@ -119,17 +94,15 @@ BOOL CPreviewThread::Run() else strArgs += strPreviewName; - CString strCommand = m_strCommand; + CString strCommand(m_strCommand); ExpandEnvironmentStrings(strCommand); ExpandEnvironmentStrings(strArgs); ExpandEnvironmentStrings(strCommandDir); SE.lpFile = strCommand; SE.lpParameters = strArgs; SE.lpDirectory = strCommandDir; + ShellExecuteEx(&SE); } - SE.nShow = SW_SHOW; - SE.cbSize = (DWORD)sizeof SE; - ShellExecuteEx(&SE); if (SE.hProcess) { ::WaitForSingleObject(SE.hProcess, INFINITE); ::CloseHandle(SE.hProcess); @@ -145,6 +118,7 @@ BOOL CPreviewThread::Run() void CPreviewThread::SetValues(CPartFile *pPartFile, LPCTSTR pszCommand, LPCTSTR pszCommandArgs) { m_pPartfile = pPartFile; + pPartFile->GetFilledArray(m_aFilled); m_strCommand = pszCommand; m_strCommandArgs = pszCommandArgs; } @@ -197,7 +171,7 @@ INT_PTR CPreviewApps::ReadAllApps() if (strCommand.Trim().IsEmpty()) continue; - LPCTSTR pszCommandArgs = PathGetArgs((LPCTSTR)strCommand); + LPCTSTR pszCommandArgs = ::PathGetArgs((LPCTSTR)strCommand); if (pszCommandArgs) strCommand.Truncate((int)(pszCommandArgs - (LPCTSTR)strCommand)); if (strCommand.Trim(_T(" \t\"")).IsEmpty()) @@ -236,11 +210,12 @@ INT_PTR CPreviewApps::ReadAllApps() m_aApps.Add(svc); } } - fclose(readFile); - struct _stat64 st; - if (statUTC(strFilePath, st) == 0) + if (statUTC((HANDLE)_get_osfhandle(_fileno(readFile)), st) == 0) m_tDefAppsFileLastModified = (time_t)st.st_mtime; + + fclose(readFile); + } return m_aApps.GetCount(); @@ -277,12 +252,7 @@ void ExecutePartFile(CPartFile *file, LPCTSTR pszCommand, LPCTSTR pszCommandArgs // get directory of video player application CString strCommandDir(pszCommand); int iPos = strCommandDir.ReverseFind(_T('\\')); - if (iPos < 0) - strCommandDir.Empty(); - else - strCommandDir.Truncate(iPos + 1); - PathRemoveBackslash(strCommandDir.GetBuffer()); - strCommandDir.ReleaseBuffer(); + strCommandDir.Truncate(iPos + 1); //may be empty CString strArgs(pszCommandArgs); if (!strArgs.IsEmpty()) @@ -349,7 +319,7 @@ void ExecutePartFile(CPartFile *file, LPCTSTR pszCommand, LPCTSTR pszCommandArgs int CPreviewApps::GetPreviewApp(const CPartFile *file) { - LPCTSTR pszExt = PathFindExtension(file->GetFileName()); + LPCTSTR pszExt = ::PathFindExtension(file->GetFileName()); if (*pszExt) { UpdateApps(); for (INT_PTR i = m_aApps.GetCount(); --i >= 0;) { @@ -368,15 +338,12 @@ CPreviewApps::ECanPreviewRes CPreviewApps::CanPreview(const CPartFile *file) if (iApp == -1) return NotHandled; - const SPreviewApp *pApp = &m_aApps[iApp]; - if (pApp->ullMinCompletedSize != 0) { - if (file->GetCompletedSize() < pApp->ullMinCompletedSize) - return No; - } + const SPreviewApp &rApp = m_aApps[iApp]; + if ((uint64)file->GetCompletedSize() < rApp.ullMinCompletedSize) + return No; - if (pApp->ullMinStartOfFile != 0) - if (!file->IsComplete(0, pApp->ullMinStartOfFile, false)) - return No; + if (rApp.ullMinStartOfFile &&!file->IsComplete(0, min(rApp.ullMinStartOfFile, (uint64)file->GetFileSize()) - 1)) + return No; return Yes; } @@ -384,7 +351,7 @@ CPreviewApps::ECanPreviewRes CPreviewApps::CanPreview(const CPartFile *file) bool CPreviewApps::Preview(CPartFile *file) { int iApp = GetPreviewApp(file); - if (iApp == -1) + if (iApp < 0) return false; RunApp(file, MP_PREVIEW_APP_MIN + iApp); return true; diff --git a/srchybrid/Preview.h b/srchybrid/Preview.h index 997d8e58..3e2126ea 100644 --- a/srchybrid/Preview.h +++ b/srchybrid/Preview.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -32,13 +32,13 @@ class CPreviewThread : public CWinThread protected: CPreviewThread(); // protected constructor used by dynamic creation - virtual ~CPreviewThread() = default; CPartFile *m_pPartfile; + CArray m_aFilled; CString m_strCommand; CString m_strCommandArgs; - DECLARE_MESSAGE_MAP() + //DECLARE_MESSAGE_MAP() }; diff --git a/srchybrid/PreviewDlg.cpp b/srchybrid/PreviewDlg.cpp index 33b8cf94..28705923 100644 --- a/srchybrid/PreviewDlg.cpp +++ b/srchybrid/PreviewDlg.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2003 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2003-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -46,7 +46,7 @@ PreviewDlg::PreviewDlg(CWnd *pParent /*=NULL*/) PreviewDlg::~PreviewDlg() { - for (unsigned i = 0; i < _countof(m_icons); ++i) + for (int i = _countof(m_icons); --i >= 0;) if (m_icons[i]) VERIFY(::DestroyIcon(m_icons[i])); } @@ -65,16 +65,19 @@ BOOL PreviewDlg::OnInitDialog() return FALSE; } InitWindowStyles(this); - CString title; - title.Format(_T("%s: %s"), (LPCTSTR)GetResNoAmp(IDS_DL_PREVIEW), (LPCTSTR)m_pFile->GetFileName()); + CString title(GetResNoAmp(IDS_DL_PREVIEW)); + title.AppendFormat(_T(": %s"), (LPCTSTR)m_pFile->GetFileName()); SetWindowText(title); m_nCurrentImage = 0; ShowImage(0); - static_cast(GetDlgItem(IDC_PV_EXIT))->SetIcon(m_icons[0] = theApp.LoadIcon(_T("Cancel"))); - static_cast(GetDlgItem(IDC_PV_NEXT))->SetIcon(m_icons[1] = theApp.LoadIcon(_T("Forward"))); - static_cast(GetDlgItem(IDC_PV_PRIOR))->SetIcon(m_icons[2] = theApp.LoadIcon(_T("Back"))); + m_icons[0] = theApp.LoadIcon(_T("Cancel")); + static_cast(GetDlgItem(IDC_PV_EXIT))->SetIcon(m_icons[0]); + m_icons[1] = theApp.LoadIcon(_T("Forward")); + static_cast(GetDlgItem(IDC_PV_NEXT))->SetIcon(m_icons[1]); + m_icons[2] = theApp.LoadIcon(_T("Back")); + static_cast(GetDlgItem(IDC_PV_PRIOR))->SetIcon(m_icons[2]); return TRUE; } diff --git a/srchybrid/PreviewDlg.h b/srchybrid/PreviewDlg.h index 6a2f6d48..efc54253 100644 --- a/srchybrid/PreviewDlg.h +++ b/srchybrid/PreviewDlg.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2003 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2003-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/ProgressCtrlX.cpp b/srchybrid/ProgressCtrlX.cpp index 5c0991c2..e1c400f1 100644 --- a/srchybrid/ProgressCtrlX.cpp +++ b/srchybrid/ProgressCtrlX.cpp @@ -147,7 +147,7 @@ void CProgressCtrlX::DrawMultiGradient(const CDrawInfo &info, const CRect &rcGra rcGradBand.right = rcGrad.right; if (rcGradBand.right < rcClip.left) - continue; // skip bands before theclipping rect + continue; // skip bands before the clipping rect RECT rcClipBand(rcGradBand); if (rcClipBand.left < rcClip.left) @@ -207,7 +207,8 @@ void CProgressCtrlX::DrawGradient(const CDrawInfo &info, const CRect &rcGrad, co rcFill.right = rcClip.right; COLORREF clrFill = RGB(r + (int)(i * rStep), g + (int)(i * gStep), b + (int)(i * bStep)); - info.pDC->FillSolidRect(&ConvertToReal(info, rcFill), clrFill); + const CRect rcTmp(ConvertToReal(info, rcFill)); + info.pDC->FillSolidRect(&rcTmp, clrFill); if (rcFill.right >= rcClip.right) break; // stop filling if we reach the current position } diff --git a/srchybrid/ProgressCtrlX.h b/srchybrid/ProgressCtrlX.h index 81d9dea0..514d1020 100644 --- a/srchybrid/ProgressCtrlX.h +++ b/srchybrid/ProgressCtrlX.h @@ -57,7 +57,7 @@ class /*UIBITS_API*/ CProgressCtrlX : public CProgressCtrl CProgressCtrlX(); // Attributes - void SetGradientColors(COLORREF clrStart, COLORREF clrEnd) { m_ardwGradColors.SetSize(2); m_ardwGradColors.SetAt(0, clrStart); m_ardwGradColors.SetAt(1, clrEnd); } + void SetGradientColors(COLORREF clrStart, COLORREF clrEnd) { m_ardwGradColors.SetSize(2); m_ardwGradColors[0] = clrStart; m_ardwGradColors[1] = clrEnd; } void GetGradientColors(COLORREF &clrStart, COLORREF &clrEnd) { clrStart = m_ardwGradColors[0]; clrEnd = m_ardwGradColors[1]; } void SetGradientColorsX(int nCount, COLORREF clrFirst, COLORREF clrNext, ...); @@ -103,9 +103,6 @@ class /*UIBITS_API*/ CProgressCtrlX : public CProgressCtrl //{{AFX_VIRTUAL(CProgressCtrlX) //}}AFX_VIRTUAL - // Implementation - virtual ~CProgressCtrlX() = default; - protected: struct CDrawInfo { diff --git a/srchybrid/Quantize.cpp b/srchybrid/Quantize.cpp index 99d255c4..97102019 100644 --- a/srchybrid/Quantize.cpp +++ b/srchybrid/Quantize.cpp @@ -7,14 +7,14 @@ static char THIS_FILE[] = __FILE__; #endif - ///////////////////////////////////////////////////////////////////////////// CQuantizer::CQuantizer(UINT nMaxColors, UINT nColorBits) : m_pTree() , m_pReducibleNodes() , m_nLeafCount() - , m_nMaxColors(nMaxColors) - , m_nColorBits(nColorBits < 8 ? nColorBits : 8) + , m_nMaxColors(max(nMaxColors, 16)) + , m_nOutputMaxColors(nMaxColors) + , m_nColorBits(max(nColorBits, 8)) { } ///////////////////////////////////////////////////////////////////////////// @@ -27,42 +27,39 @@ CQuantizer::~CQuantizer() BOOL CQuantizer::ProcessImage(HANDLE hImage) { BITMAPINFOHEADER ds; - memcpy(&ds, hImage, sizeof ds); - int effwdt = ((((ds.biBitCount * ds.biWidth) + 31) / 32) * 4); + memcpy(&ds, hImage, sizeof(ds)); + int effwdt = ((ds.biBitCount * ds.biWidth + 31) / 32) * 4; - int nPad = effwdt - (((ds.biWidth * ds.biBitCount) + 7) / 8); + int nPad = effwdt - (ds.biWidth * ds.biBitCount + 7) / 8; - BYTE *pbBits = (BYTE*)hImage + *(LPDWORD)hImage; + BYTE *pbBits = (BYTE*)hImage + *(DWORD*)hImage + ds.biClrUsed * sizeof(RGBQUAD); switch (ds.biBitCount) { - - case 1: // 1-bit DIB - case 4: // 4-bit DIB - case 8: // 8-bit DIB - for (int i = 0; i < ds.biHeight; ++i) { + case 1: // 1-bit DIB + case 4: // 4-bit DIB + case 8: // 8-bit DIB + for (int i = 0; i < ds.biHeight; ++i) for (int j = 0; j < ds.biWidth; ++j) { BYTE idx = GetPixelIndex(j, i, ds.biBitCount, effwdt, pbBits); - BYTE *pal = (BYTE*)(hImage)+sizeof(BITMAPINFOHEADER); - long ldx = idx * sizeof(RGBQUAD); - BYTE b = pal[ldx++]; - BYTE g = pal[ldx++]; - BYTE r = pal[ldx]; - AddColor(&m_pTree, r, g, b, m_nColorBits, 0, &m_nLeafCount, - m_pReducibleNodes); + BYTE *pal = (BYTE*)hImage + sizeof(BITMAPINFOHEADER); + size_t ldx = idx * sizeof(RGBQUAD); + BYTE b = pal[ldx]; + BYTE g = pal[++ldx]; + BYTE r = pal[++ldx]; + BYTE a = pal[++ldx]; + AddColor(&m_pTree, r, g, b, a, m_nColorBits, 0, &m_nLeafCount, m_pReducibleNodes); while (m_nLeafCount > m_nMaxColors) - ReduceTree(m_nColorBits, &m_nLeafCount, - m_pReducibleNodes); + ReduceTree(m_nColorBits, &m_nLeafCount, m_pReducibleNodes); } - } + return TRUE; - case 24: // 24-bit DIB + case 24: // 24-bit DIB for (int i = 0; i < ds.biHeight; ++i) { for (int j = 0; j < ds.biWidth; ++j) { BYTE b = *pbBits++; BYTE g = *pbBits++; BYTE r = *pbBits++; - AddColor(&m_pTree, r, g, b, m_nColorBits, 0, &m_nLeafCount, - m_pReducibleNodes); + AddColor(&m_pTree, r, g, b, 0, m_nColorBits, 0, &m_nLeafCount, m_pReducibleNodes); while (m_nLeafCount > m_nMaxColors) ReduceTree(m_nColorBits, &m_nLeafCount, m_pReducibleNodes); } @@ -70,67 +67,68 @@ BOOL CQuantizer::ProcessImage(HANDLE hImage) } return TRUE; } - - return FALSE; //Unrecognized color format + // Unrecognized color format + return FALSE; } ///////////////////////////////////////////////////////////////////////////// -void CQuantizer::AddColor(NODE **ppNode, BYTE r, BYTE g, BYTE b, +void CQuantizer::AddColor(NODE **ppNode, BYTE r, BYTE g, BYTE b, BYTE a, UINT nColorBits, UINT nLevel, UINT *pLeafCount, NODE **pReducibleNodes) { - static BYTE mask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; + static const BYTE mask[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; // If the node doesn't exist, create it. if (*ppNode == NULL) *ppNode = (NODE*)CreateNode(nLevel, nColorBits, pLeafCount, pReducibleNodes); - // Update color information if it's a leaf node. - if ((*ppNode)->bIsLeaf) { - (*ppNode)->nPixelCount++; - (*ppNode)->nRedSum += r; - (*ppNode)->nGreenSum += g; - (*ppNode)->nBlueSum += b; - } else { // Recurse a level deeper if the node is not a leaf. - int shift = 7 - nLevel; - int nIndex = (((r & mask[nLevel]) >> shift) << 2) | - (((g & mask[nLevel]) >> shift) << 1) | - ((b & mask[nLevel]) >> shift); - AddColor(&((*ppNode)->pChild[nIndex]), r, g, b, nColorBits, - nLevel + 1, pLeafCount, pReducibleNodes); - } + // Update color information if it's a leaf node. + if (*ppNode != NULL) + if ((*ppNode)->bIsLeaf) { + (*ppNode)->nPixelCount++; + (*ppNode)->nRedSum += r; + (*ppNode)->nGreenSum += g; + (*ppNode)->nBlueSum += b; + (*ppNode)->nAlphaSum += a; + } else { // Recurse a level deeper if the node is not a leaf. + int shift = 7 - nLevel; + int nIndex = (((r & mask[nLevel]) >> shift) << 2) | + (((g & mask[nLevel]) >> shift) << 1) | + ((b & mask[nLevel]) >> shift); + AddColor(&((*ppNode)->pChild[nIndex]), r, g, b, a, nColorBits + , nLevel + 1, pLeafCount, pReducibleNodes); + } } ///////////////////////////////////////////////////////////////////////////// -void* CQuantizer::CreateNode(UINT nLevel, UINT nColorBits, UINT *pLeafCount, +void* CQuantizer::CreateNode(UINT nLevel, UINT nColorBits, UINT *pLeafCount, NODE **pReducibleNodes) { NODE *pNode = (NODE*)calloc(1, sizeof(NODE)); - if (pNode == NULL) - return NULL; - - pNode->bIsLeaf = static_cast(nLevel == nColorBits); - if (pNode->bIsLeaf) - ++(*pLeafCount); - else { - pNode->pNext = pReducibleNodes[nLevel]; - pReducibleNodes[nLevel] = pNode; + if (pNode != NULL) { + pNode->bIsLeaf = (nLevel == nColorBits); + if (pNode->bIsLeaf) + ++(*pLeafCount); + else { + pNode->pNext = pReducibleNodes[nLevel]; + pReducibleNodes[nLevel] = pNode; + } } return pNode; } ///////////////////////////////////////////////////////////////////////////// -void CQuantizer::ReduceTree(UINT nColorBits, UINT *pLeafCount, - NODE **pReducibleNodes) +void CQuantizer::ReduceTree(UINT nColorBits, UINT *pLeafCount, NODE **pReducibleNodes) { - // Find the deepest level containing at least one reducible node. int i; - for (i = nColorBits - 1; (i > 0) && (pReducibleNodes[i] == NULL); i--); + // Find the deepest level containing at least one reducible node. + for (i = nColorBits; --i > 0 && pReducibleNodes[i] == NULL;); - // Reduce the node most recently added to the list at level i. + // Reduce the node most recently added to the list at level i. NODE *pNode = pReducibleNodes[i]; pReducibleNodes[i] = pNode->pNext; UINT nRedSum = 0; UINT nGreenSum = 0; UINT nBlueSum = 0; + UINT nAlphaSum = 0; UINT nChildren = 0; for (i = 0; i < 8; ++i) { @@ -138,6 +136,7 @@ void CQuantizer::ReduceTree(UINT nColorBits, UINT *pLeafCount, nRedSum += pNode->pChild[i]->nRedSum; nGreenSum += pNode->pChild[i]->nGreenSum; nBlueSum += pNode->pChild[i]->nBlueSum; + nAlphaSum += pNode->pChild[i]->nAlphaSum; pNode->nPixelCount += pNode->pChild[i]->nPixelCount; free(pNode->pChild[i]); pNode->pChild[i] = NULL; @@ -145,14 +144,15 @@ void CQuantizer::ReduceTree(UINT nColorBits, UINT *pLeafCount, } } - pNode->bIsLeaf = TRUE; + pNode->bIsLeaf = true; pNode->nRedSum = nRedSum; pNode->nGreenSum = nGreenSum; pNode->nBlueSum = nBlueSum; - *pLeafCount -= (nChildren - 1); + pNode->nAlphaSum = nAlphaSum; + *pLeafCount -= nChildren - 1; } ///////////////////////////////////////////////////////////////////////////// -void CQuantizer::DeleteTree(NODE** ppNode) +void CQuantizer::DeleteTree(NODE **ppNode) { for (int i = 0; i < 8; ++i) if ((*ppNode)->pChild[i] != NULL) @@ -162,19 +162,24 @@ void CQuantizer::DeleteTree(NODE** ppNode) *ppNode = NULL; } ///////////////////////////////////////////////////////////////////////////// -void CQuantizer::GetPaletteColors(NODE *pTree, RGBQUAD *prgb, UINT *pIndex) +void CQuantizer::GetPaletteColors(NODE *pTree, RGBQUAD *prgb, UINT *pIndex, UINT *pSum) { - if (pTree) + if (pTree) { if (pTree->bIsLeaf) { - prgb[*pIndex].rgbRed = (BYTE)((pTree->nRedSum) / (pTree->nPixelCount)); - prgb[*pIndex].rgbGreen = (BYTE)((pTree->nGreenSum) / (pTree->nPixelCount)); - prgb[*pIndex].rgbBlue = (BYTE)((pTree->nBlueSum) / (pTree->nPixelCount)); - prgb[*pIndex].rgbReserved = 0; + const UINT nPix = pTree->nPixelCount; + const UINT nHalf = pTree->nPixelCount >> 1; + prgb[*pIndex].rgbRed = (BYTE)min(255, (pTree->nRedSum + nHalf) / nPix); + prgb[*pIndex].rgbGreen = (BYTE)min(255, (pTree->nGreenSum + nHalf) / nPix); + prgb[*pIndex].rgbBlue = (BYTE)min(255, (pTree->nBlueSum + nHalf) / nPix); + prgb[*pIndex].rgbReserved = (BYTE)min(255, (pTree->nAlphaSum + nHalf) / nPix); + if (pSum) + pSum[*pIndex] = nPix; ++(*pIndex); } else for (int i = 0; i < 8; ++i) if (pTree->pChild[i] != NULL) - GetPaletteColors(pTree->pChild[i], prgb, pIndex); + GetPaletteColors(pTree->pChild[i], prgb, pIndex, pSum); + } } ///////////////////////////////////////////////////////////////////////////// UINT CQuantizer::GetColorCount() const @@ -185,24 +190,48 @@ UINT CQuantizer::GetColorCount() const void CQuantizer::SetColorTable(RGBQUAD *prgb) { UINT nIndex = 0; - GetPaletteColors(m_pTree, prgb, &nIndex); + if (m_nOutputMaxColors < 16) { + UINT nSum[16]; + RGBQUAD tmppal[16]; + GetPaletteColors(m_pTree, tmppal, &nIndex, nSum); + if (m_nLeafCount > m_nOutputMaxColors) { + for (UINT j = 0; j < m_nOutputMaxColors; ++j) { + UINT a = (j * m_nLeafCount) / m_nOutputMaxColors; + UINT b = ((j + 1) * m_nLeafCount) / m_nOutputMaxColors; + UINT nr = 0, ng = 0, nb = 0, na = 0, ns = 0; + for (UINT k = a; k < b; ++k) { + nr += tmppal[k].rgbRed * nSum[k]; + ng += tmppal[k].rgbGreen * nSum[k]; + nb += tmppal[k].rgbBlue * nSum[k]; + na += tmppal[k].rgbReserved * nSum[k]; + ns += nSum[k]; + } + UINT nh = ns >> 1; + prgb[j].rgbRed = (BYTE)min(255, (nh + nr) / ns); + prgb[j].rgbGreen = (BYTE)min(255, (nh + ng) / ns); + prgb[j].rgbBlue = (BYTE)min(255, (nh + nb) / ns); + prgb[j].rgbReserved = (BYTE)min(255, (nh + na) / ns); + } + } else + memcpy(prgb, tmppal, m_nLeafCount * sizeof(RGBQUAD)); + } else + GetPaletteColors(m_pTree, prgb, &nIndex, 0); } ///////////////////////////////////////////////////////////////////////////// BYTE CQuantizer::GetPixelIndex(long x, long y, int nbit, long effwdt, BYTE *pimage) { if (nbit == 8) - return pimage[y*effwdt + x]; + return pimage[y * effwdt + x]; - BYTE iDst = pimage[y*effwdt + (x*nbit >> 3)]; + BYTE iDst = pimage[y * effwdt + ((x * nbit) >> 3)]; if (nbit == 4) { - BYTE pos = (BYTE)(4 * (1 - x % 2)); - iDst &= (0x0F << pos); - return iDst >> pos; + BYTE pos = (BYTE)(4 * (~x & 1)); + return (iDst >> pos) & 0x0F; } if (nbit == 1) { - BYTE pos = (BYTE)(7 - x % 8); - iDst &= (0x01 << pos); - return iDst >> pos; + BYTE pos = (BYTE)(~x & 7); + return (iDst >> pos) & 0x01; } + return 0; } \ No newline at end of file diff --git a/srchybrid/Quantize.h b/srchybrid/Quantize.h index 15d71e2c..ecffb0ec 100644 --- a/srchybrid/Quantize.h +++ b/srchybrid/Quantize.h @@ -4,6 +4,10 @@ * * CQuantizer (c) 1996-1997 Jeff Prosise * + * 31/08/2003 Davide Pizzolato - www.xdp.it + * - fixed minor bug in ProcessImage when bpp<=8 + * - better color reduction to less than 16 colors + * * COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY * OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES * THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE @@ -23,36 +27,35 @@ class CQuantizer { typedef struct _NODE { - BOOL bIsLeaf; // TRUE if node has no children + struct _NODE *pChild[8]; // Pointers to child nodes + struct _NODE *pNext; // Pointer to next reducible node UINT nPixelCount; // Number of pixels represented by this leaf UINT nRedSum; // Sum of red components UINT nGreenSum; // Sum of green components UINT nBlueSum; // Sum of blue components - struct _NODE *pChild[8]; // Pointers to child nodes - struct _NODE *pNext; // Pointer to next reducible node + UINT nAlphaSum; // Sum of alpha components + bool bIsLeaf; // true if node has no children } NODE; protected: NODE *m_pTree; NODE *m_pReducibleNodes[9]; UINT m_nLeafCount; UINT m_nMaxColors; + UINT m_nOutputMaxColors; UINT m_nColorBits; public: CQuantizer(UINT nMaxColors, UINT nColorBits); - virtual ~CQuantizer(); + virtual ~CQuantizer(); BOOL ProcessImage(HANDLE hImage); UINT GetColorCount() const; - void SetColorTable(RGBQUAD *prgb); + void SetColorTable(RGBQUAD* prgb); protected: - void AddColor(NODE **ppNode, BYTE r, BYTE g, BYTE b, UINT nColorBits - , UINT nLevel, UINT *pLeafCount, NODE **pReducibleNodes); - void* CreateNode(UINT nLevel, UINT nColorBits, UINT *pLeafCount - , NODE **pReducibleNodes); - void ReduceTree(UINT nColorBits, UINT *pLeafCount - , NODE **pReducibleNodes); + void AddColor(NODE **ppNode, BYTE r, BYTE g, BYTE b, BYTE a, UINT nColorBits, UINT nLevel, UINT *pLeafCount, NODE **pReducibleNodes); + void* CreateNode(UINT nLevel, UINT nColorBits, UINT* pLeafCount, NODE **pReducibleNodes); void DeleteTree(NODE **ppNode); - static void GetPaletteColors(NODE *pTree, RGBQUAD *prgb, UINT *pIndex); + static void ReduceTree(UINT nColorBits, UINT *pLeafCount, NODE **pReducibleNodes); + static void GetPaletteColors(NODE *pTree, RGBQUAD *prgb, UINT *pIndex, UINT *pSum); static BYTE GetPixelIndex(long x, long y, int nbit, long effwdt, BYTE *pimage); }; \ No newline at end of file diff --git a/srchybrid/QueueListCtrl.cpp b/srchybrid/QueueListCtrl.cpp index 85177171..5959aa74 100644 --- a/srchybrid/QueueListCtrl.cpp +++ b/srchybrid/QueueListCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -17,7 +17,7 @@ #include "stdafx.h" #include "emule.h" #include "QueueListCtrl.h" -#include "OtherFunctions.h" +#include "UpDownClient.h" #include "MenuCmds.h" #include "ClientDetailDialog.h" #include "Exceptions.h" @@ -25,7 +25,6 @@ #include "emuledlg.h" #include "FriendList.h" #include "UploadQueue.h" -#include "UpDownClient.h" #include "TransferDlg.h" #include "MemDC.h" #include "SharedFileList.h" @@ -77,22 +76,22 @@ void CQueueListCtrl::Init() SetPrefsKey(_T("QueueListCtrl")); SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP); - InsertColumn(0, GetResString(IDS_QL_USERNAME), LVCFMT_LEFT, DFLT_CLIENTNAME_COL_WIDTH); - InsertColumn(1, GetResString(IDS_FILE), LVCFMT_LEFT, DFLT_FILENAME_COL_WIDTH); - InsertColumn(2, GetResString(IDS_FILEPRIO), LVCFMT_LEFT, DFLT_PRIORITY_COL_WIDTH); - InsertColumn(3, GetResString(IDS_QL_RATING), LVCFMT_LEFT, 60); - InsertColumn(4, GetResString(IDS_SCORE), LVCFMT_LEFT, 60); - InsertColumn(5, GetResString(IDS_ASKED), LVCFMT_LEFT, 60); - InsertColumn(6, GetResString(IDS_LASTSEEN), LVCFMT_LEFT, 110); - InsertColumn(7, GetResString(IDS_ENTERQUEUE), LVCFMT_LEFT, 110); - InsertColumn(8, GetResString(IDS_BANNED), LVCFMT_LEFT, 60); - InsertColumn(9, GetResString(IDS_UPSTATUS), LVCFMT_LEFT, DFLT_PARTSTATUS_COL_WIDTH); + InsertColumn(0, _T(""), LVCFMT_LEFT, DFLT_CLIENTNAME_COL_WIDTH); //IDS_QL_USERNAME + InsertColumn(1, _T(""), LVCFMT_LEFT, DFLT_FILENAME_COL_WIDTH); //IDS_FILE + InsertColumn(2, _T(""), LVCFMT_LEFT, DFLT_PRIORITY_COL_WIDTH); //IDS_FILEPRIO + InsertColumn(3, _T(""), LVCFMT_LEFT, 60); //IDS_QL_RATING + InsertColumn(4, _T(""), LVCFMT_LEFT, 60); //IDS_SCORE + InsertColumn(5, _T(""), LVCFMT_LEFT, 60); //IDS_ASKED + InsertColumn(6, _T(""), LVCFMT_LEFT, 110); //IDS_LASTSEEN + InsertColumn(7, _T(""), LVCFMT_LEFT, 110); //IDS_ENTERQUEUE + InsertColumn(8, _T(""), LVCFMT_LEFT, 60); //IDS_BANNED + InsertColumn(9, _T(""), LVCFMT_LEFT, DFLT_PARTSTATUS_COL_WIDTH); //IDS_UPSTATUS SetAllIcons(); Localize(); LoadSettings(); SetSortArrow(); - SortItems(SortProc, GetSortItem() + (GetSortAscending() ? 0 : 100)); + SortItems(SortProc, MAKELONG(GetSortItem(), !GetSortAscending())); } void CQueueListCtrl::Localize() @@ -103,15 +102,7 @@ void CQueueListCtrl::Localize() , IDS_ASKED, IDS_LASTSEEN, IDS_ENTERQUEUE, IDS_BANNED, IDS_UPSTATUS }; - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); - HDITEM hdi; - hdi.mask = HDI_TEXT; - - for (int i = 0; i < _countof(uids); ++i) { - CString strRes(GetResString(uids[i])); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(i, &hdi); - } + LocaliseHeaderCtrl(uids, _countof(uids)); } void CQueueListCtrl::OnSysColorChange() @@ -123,70 +114,68 @@ void CQueueListCtrl::OnSysColorChange() void CQueueListCtrl::SetAllIcons() { ApplyImageList(NULL); - m_pImageList = theApp.emuledlg->transferwnd->GetClientIconList(); // Apply the image list also to the listview control, even if we use our own 'DrawItem'. // This is needed to give the listview control a chance to initialize the row height. ASSERT((GetStyle() & LVS_SHAREIMAGELISTS) != 0); + m_pImageList = &theApp.emuledlg->GetClientIconList(); VERIFY(ApplyImageList(*m_pImageList) == NULL); } void CQueueListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { - if (theApp.IsClosing() || !lpDrawItemStruct->itemData) + if (!lpDrawItemStruct->itemData || theApp.IsClosing()) return; - CMemoryDC dc(CDC::FromHandle(lpDrawItemStruct->hDC), &lpDrawItemStruct->rcItem); + CRect rcItem(lpDrawItemStruct->rcItem); + CMemoryDC dc(CDC::FromHandle(lpDrawItemStruct->hDC), rcItem); BOOL bCtrlFocused; InitItemMemDC(dc, lpDrawItemStruct, bCtrlFocused); - CRect rcItem(lpDrawItemStruct->rcItem); - CRect rcClient; + RECT rcClient; GetClientRect(&rcClient); const CUpDownClient *client = reinterpret_cast(lpDrawItemStruct->itemData); - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); + const CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); int iCount = pHeaderCtrl->GetItemCount(); - rcItem.right = rcItem.left - sm_iLabelOffset; - rcItem.left += sm_iIconOffset; + LONG itemLeft = rcItem.left; + LONG iIconY = max((rcItem.Height() - 15) / 2, 0); for (int iCurrent = 0; iCurrent < iCount; ++iCurrent) { int iColumn = pHeaderCtrl->OrderToIndex(iCurrent); - if (!IsColumnHidden(iColumn)) { - UINT uDrawTextAlignment; - int iColumnWidth = GetColumnWidth(iColumn, uDrawTextAlignment); - rcItem.right += iColumnWidth; - if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) { - const CString &sItem(GetItemDisplayText(client, iColumn)); - switch (iColumn) { - case 0: //user name - { - int iImage; - UINT uOverlayImage; - client->GetDisplayImage(iImage, uOverlayImage); - - int iIconPosY = (rcItem.Height() > 16) ? ((rcItem.Height() - 16) / 2) : 1; - const POINT point = {rcItem.left, rcItem.top + iIconPosY}; - m_pImageList->Draw(dc, iImage, point, ILD_NORMAL | INDEXTOOVERLAYMASK(uOverlayImage)); - - rcItem.left += 16 + sm_iLabelOffset; - dc.DrawText(sItem, -1, &rcItem, MLC_DT_TEXT | uDrawTextAlignment); - rcItem.left -= 16; - rcItem.right -= sm_iSubItemInset; - } - break; - case 9: //obtained parts - if (client->GetUpPartCount()) { - ++rcItem.top; - --rcItem.bottom; - client->DrawUpStatusBar(dc, &rcItem, false, thePrefs.UseFlatBar()); - ++rcItem.bottom; - --rcItem.top; - } - break; - default: - dc.DrawText(sItem, -1, &rcItem, MLC_DT_TEXT | uDrawTextAlignment); + if (IsColumnHidden(iColumn)) + continue; + + UINT uDrawTextAlignment; + int iColumnWidth = GetColumnWidth(iColumn, uDrawTextAlignment); + rcItem.left = itemLeft; + rcItem.right = itemLeft + iColumnWidth; + if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) { + const CString &sItem(GetItemDisplayText(client, iColumn)); + switch (iColumn) { + case 0: //user name + { + int iImage; + UINT uOverlayImage; + client->GetDisplayImage(iImage, uOverlayImage); + + const POINT point = { rcItem.left, rcItem.top + iIconY }; + m_pImageList->Draw(dc, iImage, point, ILD_NORMAL | INDEXTOOVERLAYMASK(uOverlayImage)); + rcItem.left += 16 + sm_iLabelOffset - sm_iSubItemInset; + } + default: //any text column + rcItem.left += sm_iSubItemInset; + rcItem.right -= sm_iSubItemInset; + dc.DrawText(sItem, -1, &rcItem, MLC_DT_TEXT | uDrawTextAlignment); + break; + case 9: //obtained parts + if (client->GetUpPartCount()) { + ++rcItem.top; + --rcItem.bottom; + client->DrawUpStatusBar(dc, &rcItem, false, thePrefs.UseFlatBar()); + ++rcItem.bottom; + --rcItem.top; } } - rcItem.left += iColumnWidth; } + itemLeft += iColumnWidth; } DrawFocusRect(dc, &lpDrawItemStruct->rcItem, lpDrawItemStruct->itemState & ODS_FOCUS, bCtrlFocused, lpDrawItemStruct->itemState & ODS_SELECTED); @@ -274,16 +263,16 @@ CString CQueueListCtrl::GetItemDisplayText(const CUpDownClient *client, int iSub void CQueueListCtrl::OnLvnGetDispInfo(LPNMHDR pNMHDR, LRESULT *pResult) { if (!theApp.IsClosing()) { - // Although we have an owner drawn listview control we store the text for the primary item in the listview, to be - // capable of quick searching those items via the keyboard. Because our listview items may change their contents, - // we do this via a text callback function. The listview control will send us the LVN_DISPINFO notification if - // it needs to know the contents of the primary item. + // Although we have an owner drawn listview control we store the text for the primary item in the + // listview, to be capable of quick searching those items via the keyboard. Because our listview + // items may change their contents, we do this via a text callback function. The listview control + // will send us the LVN_DISPINFO notification if it needs to know the contents of the primary item. // - // But, the listview control sends this notification all the time, even if we do not search for an item. At least - // this notification is only sent for the visible items and not for all items in the list. Though, because this - // function is invoked *very* often, do *NOT* put any time consuming code in here. + // But, the listview control sends this notification all the time, even if we do not search for an item. + // At least this notification is only sent for the visible items and not for all items in the list. + // Though, because this function is invoked *very* often, do *NOT* put any time consuming code in here. // - // Vista: That callback is used to get the strings for the label tips for the sub(!) items. + // Vista: That callback is used to get the strings for the label tips for the sub(!)-items. // const LVITEMW &rItem = reinterpret_cast(pNMHDR)->item; if (rItem.mask & LVIF_TEXT) { @@ -297,12 +286,10 @@ void CQueueListCtrl::OnLvnGetDispInfo(LPNMHDR pNMHDR, LRESULT *pResult) void CQueueListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) { - NMLISTVIEW *pNMListView = reinterpret_cast(pNMHDR); + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); bool sortAscending; - if (GetSortItem() == pNMListView->iSubItem) - sortAscending = !GetSortAscending(); - else - switch (pNMListView->iSubItem) { + if (GetSortItem() != pNMLV->iSubItem) + switch (pNMLV->iSubItem) { case 2: // Up Priority case 3: // Rating case 4: // Score @@ -314,12 +301,13 @@ void CQueueListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) default: sortAscending = true; } + else + sortAscending = !GetSortAscending(); // Sort table - UpdateSortHistory(pNMListView->iSubItem + (sortAscending ? 0 : 100)); - SetSortArrow(pNMListView->iSubItem, sortAscending); - SortItems(SortProc, pNMListView->iSubItem + (sortAscending ? 0 : 100)); - + UpdateSortHistory(MAKELONG(pNMLV->iSubItem, !sortAscending)); + SetSortArrow(pNMLV->iSubItem, sortAscending); + SortItems(SortProc, MAKELONG(pNMLV->iSubItem, !sortAscending)); *pResult = 0; } @@ -327,10 +315,10 @@ int CALLBACK CQueueListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lPa { const CUpDownClient *item1 = reinterpret_cast(lParam1); const CUpDownClient *item2 = reinterpret_cast(lParam2); - LPARAM iColumn = (lParamSort >= 100) ? lParamSort - 100 : lParamSort; + int iResult = 0; - switch (iColumn) { - case 0: + switch (LOWORD(lParamSort)) { + case 0: //user name if (item1->GetUserName() && item2->GetUserName()) iResult = CompareLocaleStringNoCase(item1->GetUserName(), item2->GetUserName()); else if (item1->GetUserName() == NULL) @@ -338,7 +326,7 @@ int CALLBACK CQueueListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lPa else if (item2->GetUserName() == NULL) iResult = -1; // place clients with no user names at bottom break; - case 1: + case 1: //file name { const CKnownFile *file1 = theApp.sharedfiles->GetFileByID(item1->GetUploadFileID()); const CKnownFile *file2 = theApp.sharedfiles->GetFileByID(item2->GetUploadFileID()); @@ -381,14 +369,14 @@ int CALLBACK CQueueListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lPa iResult = CompareUnsigned(item1->GetUpPartCount(), item2->GetUpPartCount()); } - if (lParamSort >= 100) + if (HIWORD(lParamSort)) iResult = -iResult; - //call secondary sortorder, if this one results in equal + //call secondary sort order, if the first one resulted as equal if (iResult == 0) { - int dwNextSort = theApp.emuledlg->transferwnd->GetQueueList()->GetNextSortOrder((int)lParamSort); - if (dwNextSort != -1) - iResult = SortProc(lParam1, lParam2, dwNextSort); + LPARAM iNextSort = theApp.emuledlg->transferwnd->GetQueueList()->GetNextSortOrder(lParamSort); + if (iNextSort != -1) + iResult = SortProc(lParam1, lParam2, iNextSort); } return iResult; @@ -473,7 +461,7 @@ BOOL CQueueListCtrl::OnCommand(WPARAM wParam, LPARAM) Kademlia::CKademlia::Bootstrap(ntohl(client->GetIP()), client->GetKadPort()); } } - return true; + return TRUE; } void CQueueListCtrl::AddClient(CUpDownClient *client, bool resetclient) @@ -482,11 +470,11 @@ void CQueueListCtrl::AddClient(CUpDownClient *client, bool resetclient) client->SetWaitStartTime(); client->SetAskedCount(1); } - if (!theApp.IsClosing() && !thePrefs.IsQueueListDisabled()) { + if (!thePrefs.IsQueueListDisabled() && !theApp.IsClosing()) { int iItemCount = GetItemCount(); int iItem = InsertItem(LVIF_TEXT | LVIF_PARAM, iItemCount, LPSTR_TEXTCALLBACK, 0, 0, 0, (LPARAM)client); Update(iItem); - theApp.emuledlg->transferwnd->UpdateListCount(CTransferDlg::wnd2OnQueue, iItemCount + 1); + theApp.emuledlg->transferwnd->UpdateListCount(CTransferWnd::wnd2OnQueue, iItemCount + 1); } } @@ -499,15 +487,15 @@ void CQueueListCtrl::RemoveClient(const CUpDownClient *client) int iItem = FindItem(&find); if (iItem >= 0) { DeleteItem(iItem); - theApp.emuledlg->transferwnd->UpdateListCount(CTransferDlg::wnd2OnQueue); + theApp.emuledlg->transferwnd->UpdateListCount(CTransferWnd::wnd2OnQueue); } } } void CQueueListCtrl::RefreshClient(const CUpDownClient *client) { - if (!theApp.IsClosing() - && theApp.emuledlg->activewnd == theApp.emuledlg->transferwnd + if (theApp.emuledlg->activewnd == theApp.emuledlg->transferwnd + && !theApp.IsClosing() && theApp.emuledlg->transferwnd->GetQueueList()->IsWindowVisible()) { LVFINDINFO find; @@ -552,15 +540,15 @@ void CALLBACK CQueueListCtrl::QueueUpdateTimer(HWND /*hwnd*/, UINT /*uiMsg*/, UI { // NOTE: Always handle all type of MFC exceptions in TimerProcs - otherwise we'll get mem leaks try { - if (theApp.IsClosing() // Don't do anything if the app is shutting down - can cause unhandled exceptions - || !thePrefs.GetUpdateQueueList() - || theApp.emuledlg->activewnd != theApp.emuledlg->transferwnd - || !theApp.emuledlg->transferwnd->GetQueueList()->IsWindowVisible()) - return; - - const CUpDownClient *update = NULL; - while ((update = theApp.uploadqueue->GetNextClient(update)) != NULL) - theApp.emuledlg->transferwnd->GetQueueList()->RefreshClient(update); + if (thePrefs.GetUpdateQueueList() + && theApp.emuledlg->activewnd == theApp.emuledlg->transferwnd + && !theApp.IsClosing() // Don't do anything if the app is shutting down - can cause unhandled exceptions + && theApp.emuledlg->transferwnd->GetQueueList()->IsWindowVisible()) + { + const CUpDownClient *update = NULL; + while ((update = theApp.uploadqueue->GetNextClient(update)) != NULL) + theApp.emuledlg->transferwnd->GetQueueList()->RefreshClient(update); + } } CATCH_DFLT_EXCEPTIONS(_T("CQueueListCtrl::QueueUpdateTimer")) } \ No newline at end of file diff --git a/srchybrid/QueueListCtrl.h b/srchybrid/QueueListCtrl.h index 549f1161..077ef046 100644 --- a/srchybrid/QueueListCtrl.h +++ b/srchybrid/QueueListCtrl.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -24,6 +24,7 @@ class CQueueListCtrl : public CMuleListCtrl, public CListCtrlItemWalk { DECLARE_DYNAMIC(CQueueListCtrl) + CImageList *m_pImageList; public: CQueueListCtrl(); virtual ~CQueueListCtrl(); @@ -39,7 +40,6 @@ class CQueueListCtrl : public CMuleListCtrl, public CListCtrlItemWalk void ShowQueueClients(); protected: - CImageList *m_pImageList; UINT_PTR m_hTimer; void SetAllIcons(); diff --git a/srchybrid/RARFile.cpp b/srchybrid/RARFile.cpp index 8670618c..281310a7 100644 --- a/srchybrid/RARFile.cpp +++ b/srchybrid/RARFile.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/RARFile.h b/srchybrid/RARFile.h index 56b83bb2..fabbe71e 100644 --- a/srchybrid/RARFile.h +++ b/srchybrid/RARFile.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2005-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -96,13 +96,13 @@ class CRARFile bool Skip() const; protected: - HMODULE m_hLibUnRar; CString m_strArchiveFilePath; + HMODULE m_hLibUnRar; HANDLE m_hArchive; bool InitUnRarLib(); - HANDLE(WINAPI *m_pfnRAROpenArchiveEx)(struct RAROpenArchiveDataEx *ArchiveData) throw(...); - int (WINAPI *m_pfnRARCloseArchive)(HANDLE hArcData) throw(...); - int (WINAPI *m_pfnRARReadHeaderEx)(HANDLE hArcData, struct RARHeaderDataEx *HeaderData) throw(...); - int (WINAPI *m_pfnRARProcessFileW)(HANDLE hArcData, int iOperation, const WCHAR *pszDestFolder, const WCHAR *pszDestName) throw(...); + HANDLE(WINAPI *m_pfnRAROpenArchiveEx)(struct RAROpenArchiveDataEx *ArchiveData) noexcept(false); + int (WINAPI *m_pfnRARCloseArchive)(HANDLE hArcData) noexcept(false); + int (WINAPI *m_pfnRARReadHeaderEx)(HANDLE hArcData, struct RARHeaderDataEx *HeaderData) noexcept(false); + int (WINAPI *m_pfnRARProcessFileW)(HANDLE hArcData, int iOperation, const WCHAR *pszDestFolder, const WCHAR *pszDestName) noexcept(false); }; \ No newline at end of file diff --git a/srchybrid/Resource.h b/srchybrid/Resource.h index 119b2623..5fcc8e9c 100644 --- a/srchybrid/Resource.h +++ b/srchybrid/Resource.h @@ -805,7 +805,7 @@ #define IDS_GLOBALSEARCH 875 #define IDS_METHOD 876 #define IDS_UNDO 877 -#define IDS_DAYLY 878 +#define IDS_DAILY 878 #define IDS_DAY_MO_FR 879 #define IDS_DAY_SA_SO 880 #define IDS_MO 881 @@ -1009,7 +1009,7 @@ #define IDS_USS_STARTING 1065 #define IDS_A4AF 1066 #define IDS_ENABLEIMPORTPARTS 1067 -//***#define 1068 +#define IDS_ERR_REGEXP 1068 #define IDS_AUTOCAT_LABEL 1069 #define IDS_SHOWEXTSETTINGS 1070 #define IDS_TREEOPTIONS_TRUE 1071 @@ -1664,6 +1664,7 @@ #define IDC_ADDSERVER 2169 #define IDC_DOWNLOAD_CAP 2171 #define IDC_SEARCHLIST 2172 +#define IDC_KADSEARCHLIST 2173 #define IDC_UPDATESERVERMETFROMURL 2174 #define IDC_COMBO1 2175 #define IDC_AUTOSERVER 2176 @@ -2372,10 +2373,12 @@ #define IDC_SMTPUSER 3034 #define IDC_SMTPPASS_LBL 3035 #define IDC_SMTPPASS 3036 +#define IDC_SF_FICON 3037 +#define IDC_SF_FNAME 3038 #define IDA_ENTER 32771 // Next default values for new objects -// +// #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 1568 diff --git a/srchybrid/RichEditCtrlX.cpp b/srchybrid/RichEditCtrlX.cpp index da3a6a49..271ebeaa 100644 --- a/srchybrid/RichEditCtrlX.cpp +++ b/srchybrid/RichEditCtrlX.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -261,15 +261,15 @@ void CRichEditCtrlX::UpdateSyntaxColoring() LPTSTR pszStart = const_cast((LPCTSTR)strText); LPCTSTR psz = pszStart; while (*psz != _T('\0')) { - if (*psz == _T('\"')) { - LPCTSTR pszEnd = _tcschr(psz + 1, _T('\"')); + if (*psz == _T('"')) { + LPCTSTR pszEnd = _tcschr(psz + 1, _T('"')); if (!pszEnd) break; psz = pszEnd + 1; } else { bool bFoundKeyword = false; for (int k = 0; k < m_astrKeywords.GetCount(); ++k) { - const CString &rstrKeyword = m_astrKeywords[k]; + const CString &rstrKeyword(m_astrKeywords[k]); int iKwLen = rstrKeyword.GetLength(); if (_tcsncmp(psz, rstrKeyword, iKwLen) == 0 && (psz[iKwLen] == _T('\0') || _tcschr(m_strSeparators, psz[iKwLen]) != NULL)) { long iStart = (long)(psz - pszStart); diff --git a/srchybrid/RichEditCtrlX.h b/srchybrid/RichEditCtrlX.h index 36cdb749..2a5f52cd 100644 --- a/srchybrid/RichEditCtrlX.h +++ b/srchybrid/RichEditCtrlX.h @@ -7,7 +7,6 @@ class CRichEditCtrlX : public CRichEditCtrl { public: CRichEditCtrlX(); - virtual ~CRichEditCtrlX() = default; void SetDisableSelectOnFocus(bool bDisable = true); void SetSyntaxColoring(LPCTSTR *ppszKeywords = NULL, LPCTSTR pszSeparators = NULL); diff --git a/srchybrid/RichEditStream.cpp b/srchybrid/RichEditStream.cpp index bceb9b48..ede43d59 100644 --- a/srchybrid/RichEditStream.cpp +++ b/srchybrid/RichEditStream.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/RichEditStream.h b/srchybrid/RichEditStream.h index 61daf0d5..0509ed82 100644 --- a/srchybrid/RichEditStream.h +++ b/srchybrid/RichEditStream.h @@ -7,7 +7,6 @@ class CRichEditStream : public CRichEditCtrl { public: CRichEditStream(); - virtual ~CRichEditStream() = default; CRichEditStream& operator<<(LPCTSTR const psz); CRichEditStream& operator<<(const char *const psz); diff --git a/srchybrid/SHA.cpp b/srchybrid/SHA.cpp index fd24010b..07809b61 100644 --- a/srchybrid/SHA.cpp +++ b/srchybrid/SHA.cpp @@ -168,7 +168,7 @@ bool CSHA::HashFromString(LPCTSTR pszHash, SHA1 *pHashIn) DWORD nBits = 0; int nCount = 0; - for (int nChars = 32; nChars--; ++pszHash) { + for (int nChars = 32; --nChars >= 0; ++pszHash) { if (*pszHash >= 'A' && *pszHash <= 'Z') nBits |= (*pszHash - 'A'); else if (*pszHash >= 'a' && *pszHash <= 'z') diff --git a/srchybrid/SHAHashSet.cpp b/srchybrid/SHAHashSet.cpp index 6bae7268..aa5f7cca 100644 --- a/srchybrid/SHAHashSet.cpp +++ b/srchybrid/SHAHashSet.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -52,19 +52,19 @@ CString CAICHHash::GetString() const return EncodeBase32(m_abyBuffer, HASHSIZE); } -void CAICHHash::Read(CFileDataIO *file) +void CAICHHash::Read(CFileDataIO &file) { - file->Read(m_abyBuffer, HASHSIZE); + file.Read(m_abyBuffer, HASHSIZE); } -void CAICHHash::Skip(LONGLONG distance, CFileDataIO *file) +void CAICHHash::Skip(LONGLONG distance, CFileDataIO &file) { - file->Seek(distance, CFile::current); + file.Seek(distance, CFile::current); } -void CAICHHash::Write(CFileDataIO *file) const +void CAICHHash::Write(CFileDataIO &file) const { - file->Write(m_abyBuffer, HASHSIZE); + file.Write(m_abyBuffer, HASHSIZE); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -245,7 +245,7 @@ bool CAICHHashTree::VerifyHashTree(CAICHHashAlgo *hashalg, bool bDeleteBadTrees) delete m_pRightTree; m_pRightTree = NULL; } - theApp.QueueDebugLogLine(/*DLP_HIGH,*/ false, _T("VerifyHashSet failed - Hashtree incomplete")); + theApp.QueueDebugLogLine(/*DLP_HIGH,*/ false, _T("VerifyHashSet failed - Hash tree incomplete")); return false; } if ((m_pRightTree && m_pRightTree->m_bHashValid) && (m_pLeftTree && m_pLeftTree->m_bHashValid)) { @@ -267,24 +267,23 @@ bool CAICHHashTree::VerifyHashTree(CAICHHashAlgo *hashalg, bool bDeleteBadTrees) return false; } return m_pLeftTree->VerifyHashTree(hashalg, bDeleteBadTrees) && m_pRightTree->VerifyHashTree(hashalg, bDeleteBadTrees); - } else { - // last hash in branch - nothing below to verify + } - // delete empty (without a hash) branches if they exist - they may actually have hashes in leafs below but they are not part of the tree - // because of that, the tree itself can still succeed verification - if (bDeleteBadTrees) { - if (m_pLeftTree && !m_pLeftTree->m_bHashValid) { - delete m_pLeftTree; - m_pLeftTree = NULL; - } - if (m_pRightTree && !m_pRightTree->m_bHashValid) { - delete m_pRightTree; - m_pRightTree = NULL; - } + // last hash in branch - nothing below to verify + + // delete empty (without a hash) branches if they exist - they may actually have hashes in leafs below but they are not part of the tree + // because of that, the tree itself can still succeed verification + if (bDeleteBadTrees) { + if (m_pLeftTree && !m_pLeftTree->m_bHashValid) { + delete m_pLeftTree; + m_pLeftTree = NULL; + } + if (m_pRightTree && !m_pRightTree->m_bHashValid) { + delete m_pRightTree; + m_pRightTree = NULL; } - return true; } - + return true; } void CAICHHashTree::SetBlockHash(uint64 nSize, uint64 nStartPos, CAICHHashAlgo *pHashAlg) @@ -310,7 +309,7 @@ void CAICHHashTree::SetBlockHash(uint64 nSize, uint64 nStartPos, CAICHHashAlgo * } -bool CAICHHashTree::CreatePartRecoveryData(uint64 nStartPos, uint64 nSize, CFileDataIO *fileDataOut, uint32 wHashIdent, bool b32BitIdent) +bool CAICHHashTree::CreatePartRecoveryData(uint64 nStartPos, uint64 nSize, CFileDataIO &fileDataOut, uint32 wHashIdent, bool b32BitIdent) { if (nStartPos + nSize > m_nDataSize || nSize > m_nDataSize) { // sanity ASSERT(0); @@ -355,31 +354,34 @@ bool CAICHHashTree::CreatePartRecoveryData(uint64 nStartPos, uint64 nSize, CFile } -void CAICHHashTree::WriteHash(CFileDataIO *fileDataOut, uint32 wHashIdent, bool b32BitIdent) const +void CAICHHashTree::WriteHash(CFileDataIO &fileDataOut, uint32 wHashIdent, bool b32BitIdent) const { ASSERT(m_bHashValid); wHashIdent <<= 1; wHashIdent |= static_cast(m_bIsLeftBranch); - if (!b32BitIdent) { + if (b32BitIdent) + fileDataOut.WriteUInt32(wHashIdent); + else { ASSERT(wHashIdent <= _UI16_MAX); - fileDataOut->WriteUInt16((uint16)wHashIdent); - } else - fileDataOut->WriteUInt32(wHashIdent); + fileDataOut.WriteUInt16((uint16)wHashIdent); + } m_Hash.Write(fileDataOut); } // write lowest level hashes into file, ordered from left to right optional without identifier -bool CAICHHashTree::WriteLowestLevelHashes(CFileDataIO *fileDataOut, uint32 wHashIdent, bool bNoIdent, bool b32BitIdent) const +bool CAICHHashTree::WriteLowestLevelHashes(CFileDataIO &fileDataOut, uint32 wHashIdent, bool bNoIdent, bool b32BitIdent) const { wHashIdent <<= 1; wHashIdent |= static_cast(m_bIsLeftBranch); if (m_pLeftTree == NULL && m_pRightTree == NULL) { if (m_nDataSize <= GetBaseSize() && m_bHashValid) { - if (!bNoIdent && !b32BitIdent) { - ASSERT(wHashIdent <= _UI16_MAX); - fileDataOut->WriteUInt16((uint16)wHashIdent); - } else if (!bNoIdent && b32BitIdent) - fileDataOut->WriteUInt32(wHashIdent); + if (!bNoIdent) + if (b32BitIdent) + fileDataOut.WriteUInt32(wHashIdent); + else { + ASSERT(wHashIdent <= _UI16_MAX); + fileDataOut.WriteUInt16((uint16)wHashIdent); + } m_Hash.Write(fileDataOut); //theApp.AddDebugLogLine(false,_T("%s"),m_Hash.GetString(), wHashIdent, this); return true; @@ -396,7 +398,7 @@ bool CAICHHashTree::WriteLowestLevelHashes(CFileDataIO *fileDataOut, uint32 wHas } // recover all low level hashes from given data. hashes are assumed to be ordered in left to right - no identifier used -bool CAICHHashTree::LoadLowestLevelHashes(CFileDataIO *fileInput) +bool CAICHHashTree::LoadLowestLevelHashes(CFileDataIO &fileInput) { if (m_nDataSize <= GetBaseSize()) { // sanity // lowest level, read hash @@ -425,7 +427,7 @@ bool CAICHHashTree::LoadLowestLevelHashes(CFileDataIO *fileInput) // write the hash, specified by wHashIdent, with Data from fileInput. -bool CAICHHashTree::SetHash(CFileDataIO *fileInput, uint32 wHashIdent, sint8 nLevel, bool bAllowOverwrite) +bool CAICHHashTree::SetHash(CFileDataIO &fileInput, uint32 wHashIdent, sint8 nLevel, bool bAllowOverwrite) { if (nLevel == -1) { // first call, check how many level we need to go @@ -546,7 +548,7 @@ bool CAICHRecoveryHashSet::GetPartHashes(CArray &rResult) const if (uPartCount <= 1) return true; // No AICH Part hashes for (uint32 nPart = 0; nPart < uPartCount; ++nPart) { - uint64 nPartStartPos = (uint64)nPart*PARTSIZE; + uint64 nPartStartPos = nPart * PARTSIZE; uint32 nPartSize = (uint32)min(PARTSIZE, (uint64)m_pOwner->GetFileSize() - nPartStartPos); const CAICHHashTree *pPartHashTree = m_pHashTree.FindExistingHash(nPartStartPos, nPartSize); if (pPartHashTree == NULL || !pPartHashTree->m_bHashValid) { @@ -561,18 +563,17 @@ bool CAICHRecoveryHashSet::GetPartHashes(CArray &rResult) const const CAICHHashTree* CAICHRecoveryHashSet::FindPartHash(uint16 nPart) { - ASSERT(m_pOwner); - ASSERT(m_pOwner->IsPartFile()); + ASSERT(m_pOwner && m_pOwner->IsPartFile()); if (m_pOwner->GetFileSize() <= PARTSIZE) return &m_pHashTree; - uint64 nPartStartPos = (uint64)nPart*PARTSIZE; + uint64 nPartStartPos = nPart * PARTSIZE; uint32 nPartSize = (uint32)(min(PARTSIZE, (uint64)m_pOwner->GetFileSize() - nPartStartPos)); const CAICHHashTree *phtResult = m_pHashTree.FindHash(nPartStartPos, nPartSize); ASSERT(phtResult != NULL); return phtResult; } -bool CAICHRecoveryHashSet::CreatePartRecoveryData(uint64 nPartStartPos, CFileDataIO *fileDataOut, bool bDbgDontLoad) +bool CAICHRecoveryHashSet::CreatePartRecoveryData(uint64 nPartStartPos, CFileDataIO &fileDataOut, bool bDbgDontLoad) { ASSERT(m_pOwner); if (m_pOwner->IsPartFile() || m_eStatus != AICH_HASHSETCOMPLETE) { @@ -596,11 +597,11 @@ bool CAICHRecoveryHashSet::CreatePartRecoveryData(uint64 nPartStartPos, CFileDat const bool bUse32BitIdentifier = m_pOwner->IsLargeFile(); if (bUse32BitIdentifier) - fileDataOut->WriteUInt16(0); // no 16bit hashes to write - fileDataOut->WriteUInt16(nHashesToWrite); - ULONGLONG nCheckFilePos = fileDataOut->GetPosition(); + fileDataOut.WriteUInt16(0); // no 16bit hashes to write + fileDataOut.WriteUInt16(nHashesToWrite); + ULONGLONG nCheckFilePos = fileDataOut.GetPosition(); if (m_pHashTree.CreatePartRecoveryData(nPartStartPos, nPartSize, fileDataOut, 0, bUse32BitIdentifier)) { - bResult = (nHashesToWrite * (HASHSIZE + (bUse32BitIdentifier ? 4ull : 2ull)) == fileDataOut->GetPosition() - nCheckFilePos); + bResult = (nHashesToWrite * (HASHSIZE + (bUse32BitIdentifier ? 4ull : 2ull)) == fileDataOut.GetPosition() - nCheckFilePos); if (!bResult) { ASSERT(0); theApp.QueueDebugLogLine(/*DLP_VERYHIGH,*/ false, _T("Created recovery data has wrong length (file: %s)"), (LPCTSTR)m_pOwner->GetFileName()); @@ -612,7 +613,7 @@ bool CAICHRecoveryHashSet::CreatePartRecoveryData(uint64 nPartStartPos, CFileDat SetStatus(AICH_ERROR); } if (!bUse32BitIdentifier) - fileDataOut->WriteUInt16(0); // no 32bit hashes to write + fileDataOut.WriteUInt16(0); // no 32bit hashes to write if (!bDbgDontLoad) FreeHashSet(); @@ -620,7 +621,7 @@ bool CAICHRecoveryHashSet::CreatePartRecoveryData(uint64 nPartStartPos, CFileDat return bResult; } -bool CAICHRecoveryHashSet::ReadRecoveryData(uint64 nPartStartPos, CSafeMemFile *fileDataIn) +bool CAICHRecoveryHashSet::ReadRecoveryData(uint64 nPartStartPos, CSafeMemFile &fileDataIn) { if (/*TODO !m_pOwner->IsPartFile() ||*/ !(m_eStatus == AICH_VERIFIED || m_eStatus == AICH_TRUSTED)) { ASSERT(0); @@ -642,15 +643,15 @@ bool CAICHRecoveryHashSet::ReadRecoveryData(uint64 nPartStartPos, CSafeMemFile * uint16 nHashsToRead = (uint16)((nLevel - 1) + nPartSize / EMBLOCKSIZE + static_cast(nPartSize % EMBLOCKSIZE != 0)); // read hashes with 16 bit identifier - uint16 nHashesAvailable = fileDataIn->ReadUInt16(); - if (fileDataIn->GetLength() - fileDataIn->GetPosition() < (ULONGLONG)nHashsToRead * (HASHSIZE + 2) || (nHashsToRead != nHashesAvailable && nHashesAvailable != 0)) { + uint16 nHashesAvailable = fileDataIn.ReadUInt16(); + if (fileDataIn.GetLength() - fileDataIn.GetPosition() < (ULONGLONG)nHashsToRead * (HASHSIZE + 2) || (nHashsToRead != nHashesAvailable && nHashesAvailable != 0)) { // this check is redundant, CSafememfile would catch such an error too - theApp.QueueDebugLogLine(/*DLP_VERYHIGH,*/ false, _T("Failed to read recovery data for %s - Received data size/amounts of hashes was invalid (1)"), (LPCTSTR)m_pOwner->GetFileName()); + theApp.QueueDebugLogLine(/*DLP_VERYHIGH,*/ false, _T("Failed to read recovery data for %s - Received data size/count of hashes was invalid (1)"), (LPCTSTR)m_pOwner->GetFileName()); return false; } DEBUG_ONLY(theApp.QueueDebugLogLine(/*DLP_VERYHIGH,*/ false, _T("Read recovery data for %s - Received packet with %u 16bit hash identifiers)"), (LPCTSTR)m_pOwner->GetFileName(), nHashesAvailable)); for (uint32 i = 0; i < nHashesAvailable; ++i) { - uint16 wHashIdent = fileDataIn->ReadUInt16(); + uint16 wHashIdent = fileDataIn.ReadUInt16(); if (wHashIdent == 1 /*never allow masterhash to be overwritten*/ || !m_pHashTree.SetHash(fileDataIn, wHashIdent, -1, false)) { @@ -661,17 +662,17 @@ bool CAICHRecoveryHashSet::ReadRecoveryData(uint64 nPartStartPos, CSafeMemFile * } // read hashes with 32bit identifier - if (nHashesAvailable == 0 && fileDataIn->GetLength() - fileDataIn->GetPosition() >= 2) { - nHashesAvailable = fileDataIn->ReadUInt16(); - if (fileDataIn->GetLength() - fileDataIn->GetPosition() < (ULONGLONG)nHashsToRead * (HASHSIZE + 4) || (nHashsToRead != nHashesAvailable && nHashesAvailable != 0)) { + if (nHashesAvailable == 0 && fileDataIn.GetLength() - fileDataIn.GetPosition() >= 2) { + nHashesAvailable = fileDataIn.ReadUInt16(); + if (fileDataIn.GetLength() - fileDataIn.GetPosition() < (ULONGLONG)nHashsToRead * (HASHSIZE + 4) || (nHashsToRead != nHashesAvailable && nHashesAvailable != 0)) { // this check is redundant, CSafememfile would catch such an error too - theApp.QueueDebugLogLine(/*DLP_VERYHIGH,*/ false, _T("Failed to read recovery data for %s - Received datasize/amounts of hashes was invalid (2)"), (LPCTSTR)m_pOwner->GetFileName()); + theApp.QueueDebugLogLine(/*DLP_VERYHIGH,*/ false, _T("Failed to read recovery data for %s - Received data size/count of hashes was invalid (2)"), (LPCTSTR)m_pOwner->GetFileName()); return false; } DEBUG_ONLY(theApp.QueueDebugLogLine(/*DLP_VERYHIGH,*/ false, _T("Read recovery data for %s - Received packet with %u 32bit hash identifiers)"), (LPCTSTR)m_pOwner->GetFileName(), nHashesAvailable)); for (uint32 i = 0; i != nHashsToRead; ++i) { - uint32 wHashIdent = fileDataIn->ReadUInt32(); - if (wHashIdent == 1 /*never allow masterhash to be overwritten*/ + uint32 wHashIdent = fileDataIn.ReadUInt32(); + if (wHashIdent == 1 //never allow masterhash to be overwritten || wHashIdent > 0x400000 || !m_pHashTree.SetHash(fileDataIn, wHashIdent, -1, false)) { @@ -680,8 +681,8 @@ bool CAICHRecoveryHashSet::ReadRecoveryData(uint64 nPartStartPos, CSafeMemFile * return false; } } - } else if (fileDataIn->GetLength() - fileDataIn->GetPosition() >= 2) - fileDataIn->ReadUInt16(); + } else if (fileDataIn.GetLength() - fileDataIn.GetPosition() >= 2) + fileDataIn.ReadUInt16(); if (nHashesAvailable == 0) { theApp.QueueDebugLogLine(/*DLP_VERYHIGH,*/ false, _T("Failed to read recovery data for %s - Packet didn't contain any hashes"), (LPCTSTR)m_pOwner->GetFileName()); @@ -702,7 +703,7 @@ bool CAICHRecoveryHashSet::ReadRecoveryData(uint64 nPartStartPos, CSafeMemFile * return true; } - theApp.QueueDebugLogLine(/*DLP_VERYHIGH,*/ false, _T("Failed to read recovery data for %s - Verifying received hashtree failed"), (LPCTSTR)m_pOwner->GetFileName()); + theApp.QueueDebugLogLine(/*DLP_VERYHIGH,*/ false, _T("Failed to read recovery data for %s - Verifying received hash tree failed"), (LPCTSTR)m_pOwner->GetFileName()); return false; } @@ -735,15 +736,14 @@ bool CAICHRecoveryHashSet::SaveHashSet() return false; } try { - //setvbuf(file.m_pStream, NULL, _IOFBF, 16384); + //::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); if (file.GetLength() <= 0) file.WriteUInt8(KNOWN2_MET_VERSION); else if (file.ReadUInt8() != KNOWN2_MET_VERSION) AfxThrowFileException(CFileException::endOfFile, 0, file.GetFileName()); // first we check if the hashset we want to write is already stored - ULONGLONG nTmp; - if (m_mapAICHHashsStored.Lookup(m_pHashTree.m_Hash, nTmp)) { + if (m_mapAICHHashsStored.PLookup(m_pHashTree.m_Hash)) { theApp.QueueDebugLogLine(false, _T("AICH Hashset to write should be already present in known2.met - %s"), (LPCTSTR)m_pHashTree.m_Hash.GetString()); // this hashset if already available, no need to save it again return true; @@ -753,25 +753,25 @@ bool CAICHRecoveryHashSet::SaveHashSet() ULONGLONG nExistingSize = file.GetLength(); file.SeekToEnd(); ULONGLONG nHashSetWritePosition = file.GetPosition(); - m_pHashTree.m_Hash.Write(&file); + m_pHashTree.m_Hash.Write(file); uint32 nHashCount = (uint32)((PARTSIZE / EMBLOCKSIZE + static_cast(PARTSIZE % EMBLOCKSIZE != 0)) * (m_pHashTree.m_nDataSize / PARTSIZE)); if (m_pHashTree.m_nDataSize % PARTSIZE != 0) nHashCount += (uint32)((m_pHashTree.m_nDataSize % PARTSIZE) / EMBLOCKSIZE + static_cast((m_pHashTree.m_nDataSize % PARTSIZE) % EMBLOCKSIZE != 0)); file.WriteUInt32(nHashCount); - if (!m_pHashTree.WriteLowestLevelHashes(&file, 0, true, true)) { + if (!m_pHashTree.WriteLowestLevelHashes(file, 0, true, true)) { // that's bad... really file.SetLength(nExistingSize); theApp.QueueDebugLogLine(true, _T("Failed to save HashSet: WriteLowestLevelHashes() failed!")); return false; } - if (file.GetLength() != nExistingSize + (nHashCount + 1ull)*HASHSIZE + 4) { + if (file.GetLength() != nExistingSize + (nHashCount + 1ull) * HASHSIZE + 4) { // that's even worse file.SetLength(nExistingSize); theApp.QueueDebugLogLine(true, _T("Failed to save HashSet: Calculated and real size of hashset differ!")); return false; } CAICHRecoveryHashSet::AddStoredAICHHash(m_pHashTree.m_Hash, nHashSetWritePosition); - theApp.QueueDebugLogLine(false, _T("Successfully saved eMuleAC Hashset, %u Hashes + 1 Masterhash written"), nHashCount); + theApp.QueueDebugLogLine(false, _T("Successfully saved AICH Hashset, %u Hashes + 1 Masterhash written"), nHashCount); file.Flush(); file.Close(); } catch (CFileException *error) { @@ -815,7 +815,7 @@ bool CAICHRecoveryHashSet::LoadHashSet() return false; } try { - //setvbuf(file.m_pStream, NULL, _IOFBF, 16384); + //::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); uint8 header = file.ReadUInt8(); if (header != KNOWN2_MET_VERSION) AfxThrowFileException(CFileException::endOfFile, 0, file.GetFileName()); @@ -825,8 +825,9 @@ bool CAICHRecoveryHashSet::LoadHashSet() uint32 nHashCount; bool bUseExpectedPos = true; - ULONGLONG nExpectedHashSetPos = 0; + ULONGLONG nExpectedHashSetPos; if (!m_mapAICHHashsStored.Lookup(m_pHashTree.m_Hash, nExpectedHashSetPos) || nExpectedHashSetPos >= nExistingSize) { + nExpectedHashSetPos = 0; bUseExpectedPos = false; theApp.QueueDebugLogLine(false, _T("AICH Hashset to read not present in AICH hash index - %s"), (LPCTSTR)m_pHashTree.m_Hash.GetString()); } @@ -835,17 +836,17 @@ bool CAICHRecoveryHashSet::LoadHashSet() if (bUseExpectedPos) { ULONGLONG nFallbackPos = file.GetPosition(); file.Seek(nExpectedHashSetPos, CFile::begin); - CurrentHash.Read(&file); + CurrentHash.Read(file); if (m_pHashTree.m_Hash != CurrentHash) { ASSERT(0); theApp.QueueDebugLogLine(false, _T("AICH Hashset to read not present at expected position according to AICH hash index - %s"), (LPCTSTR)m_pHashTree.m_Hash.GetString()); // fallback and do a full search of the file for the hashset file.Seek(nFallbackPos, CFile::begin); - CurrentHash.Read(&file); + CurrentHash.Read(file); } bUseExpectedPos = false; } else - CurrentHash.Read(&file); + CurrentHash.Read(file); if (m_pHashTree.m_Hash == CurrentHash) { // found Hashset uint32 nExpectedCount = (uint32)((PARTSIZE / EMBLOCKSIZE + static_cast(PARTSIZE % EMBLOCKSIZE != 0)) * (m_pHashTree.m_nDataSize / PARTSIZE)); @@ -853,11 +854,11 @@ bool CAICHRecoveryHashSet::LoadHashSet() nExpectedCount += (uint32)((m_pHashTree.m_nDataSize % PARTSIZE) / EMBLOCKSIZE + static_cast((m_pHashTree.m_nDataSize % PARTSIZE) % EMBLOCKSIZE != 0)); nHashCount = file.ReadUInt32(); if (nHashCount != nExpectedCount) { - theApp.QueueDebugLogLine(true, _T("Failed to load HashSet: Available hashes and expected hashcount differ!")); + theApp.QueueDebugLogLine(true, _T("Failed to load HashSet: Available hashes and expected hash count differ!")); return false; } //uint32 dbgPos = file.GetPosition(); - if (!m_pHashTree.LoadLowestLevelHashes(&file)) { + if (!m_pHashTree.LoadLowestLevelHashes(file)) { theApp.QueueDebugLogLine(true, _T("Failed to load HashSet: LoadLowestLevelHashes failed!")); return false; } @@ -1058,17 +1059,16 @@ CAICHRequestedData CAICHRecoveryHashSet::GetAICHReqDetails(const CUpDownClient ULONGLONG CAICHRecoveryHashSet::AddStoredAICHHash(CAICHHash Hash, ULONGLONG nFilePos) { ULONGLONG foundPos; - if (!m_mapAICHHashsStored.Lookup(Hash, foundPos)) - foundPos = 0; - else { + if (m_mapAICHHashsStored.Lookup(Hash, foundPos)) { if (nFilePos <= foundPos) return 0; //this was an older hash; ignore it #ifdef _DEBUG theApp.QueueDebugLogLine(false, _T("AICH hash storing is not unique - %s"), (LPCTSTR)Hash.GetString()); ASSERT(0); #endif - } - m_mapAICHHashsStored.SetAt(Hash, nFilePos); + } else + foundPos = 0; + m_mapAICHHashsStored[Hash] = nFilePos; return foundPos; //non-zero if an old hash existed } @@ -1115,14 +1115,14 @@ void CAICHRecoveryHashSet::DbgTest() CSafeMemFile file; uint64 i; for (i = 0; i + PARTSIZE < TESTSIZE; i += PARTSIZE) { - VERIFY(CreatePartRecoveryData(i, &file)); + VERIFY(CreatePartRecoveryData(i, file)); /*uint32 nRandomCorruption = (rand() * rand()) % (file.GetLength()-4); file.Seek(nRandomCorruption, CFile::begin); file.Write(&nRandomCorruption, 4);*/ file.SeekToBegin(); - VERIFY(TestHashSet.ReadRecoveryData(i, &file)); + VERIFY(TestHashSet.ReadRecoveryData(i, file)); file.SeekToBegin(); TestHashSet.FreeHashSet(); uint32 j; @@ -1140,9 +1140,9 @@ void CAICHRecoveryHashSet::DbgTest() ++cHash; } - VERIFY(CreatePartRecoveryData(i, &file)); + VERIFY(CreatePartRecoveryData(i, file)); file.SeekToBegin(); - VERIFY(TestHashSet.ReadRecoveryData(i, &file)); + VERIFY(TestHashSet.ReadRecoveryData(i, file)); file.SeekToBegin(); TestHashSet.FreeHashSet(); uint64 j; diff --git a/srchybrid/SHAHashSet.h b/srchybrid/SHAHashSet.h index 5442f112..77aeb367 100644 --- a/srchybrid/SHAHashSet.h +++ b/srchybrid/SHAHashSet.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -96,15 +96,15 @@ class CAICHHash : m_abyBuffer() { } - explicit CAICHHash(CFileDataIO *file) { Read(file); } + explicit CAICHHash(CFileDataIO &file) { Read(file); } explicit CAICHHash(const uchar *data) { Read(data); } CAICHHash(const CAICHHash &k1) { *this = k1; } CAICHHash& operator=(const CAICHHash &k1) { memcpy(m_abyBuffer, k1.m_abyBuffer, HASHSIZE); return *this; } friend bool operator==(const CAICHHash &k1, const CAICHHash &k2) { return memcmp(k1.m_abyBuffer, k2.m_abyBuffer, HASHSIZE) == 0; } friend bool operator!=(const CAICHHash &k1, const CAICHHash &k2) { return !(k1 == k2); } - void Read(CFileDataIO *file); - static void Skip(LONGLONG distance, CFileDataIO *file); - void Write(CFileDataIO *file) const; + void Read(CFileDataIO &file); + static void Skip(LONGLONG distance, CFileDataIO &file); + void Write(CFileDataIO &file) const; void Read(const uchar *data) { memcpy(m_abyBuffer, data, HASHSIZE); } CString GetString() const; uchar* GetRawHash() { return m_abyBuffer; } @@ -127,7 +127,7 @@ template<> inline UINT AFXAPI HashKey(const CAICHHash &key) class CAICHHashAlgo { public: - virtual ~CAICHHashAlgo() = default; //just in case... + virtual ~CAICHHashAlgo() = default; virtual void Reset() = 0; virtual void Add(LPCVOID pData, DWORD nLength) = 0; virtual void Finish(CAICHHash &Hash) = 0; @@ -154,11 +154,11 @@ class CAICHHashTree protected: CAICHHashTree* FindHash(uint64 nStartPos, uint64 nSize, uint8 *nLevel); const CAICHHashTree* FindExistingHash(uint64 nStartPos, uint64 nSize, uint8 *nLevel) const; - bool CreatePartRecoveryData(uint64 nStartPos, uint64 nSize, CFileDataIO *fileDataOut, uint32 wHashIdent, bool b32BitIdent); - void WriteHash(CFileDataIO *fileDataOut, uint32 wHashIdent, bool b32BitIdent) const; - bool WriteLowestLevelHashes(CFileDataIO *fileDataOut, uint32 wHashIdent, bool bNoIdent, bool b32BitIdent) const; - bool LoadLowestLevelHashes(CFileDataIO *fileInput); - bool SetHash(CFileDataIO *fileInput, uint32 wHashIdent, sint8 nLevel = -1, bool bAllowOverwrite = true); + bool CreatePartRecoveryData(uint64 nStartPos, uint64 nSize, CFileDataIO &fileDataOut, uint32 wHashIdent, bool b32BitIdent); + void WriteHash(CFileDataIO &fileDataOut, uint32 wHashIdent, bool b32BitIdent) const; + bool WriteLowestLevelHashes(CFileDataIO &fileDataOut, uint32 wHashIdent, bool bNoIdent, bool b32BitIdent) const; + bool LoadLowestLevelHashes(CFileDataIO &fileInput); + bool SetHash(CFileDataIO &fileInput, uint32 wHashIdent, sint8 nLevel = -1, bool bAllowOverwrite = true); bool ReduceToBaseSize(uint64 nBaseSize); CAICHHashTree *m_pLeftTree; @@ -221,8 +221,8 @@ class CAICHRecoveryHashSet public: explicit CAICHRecoveryHashSet(CKnownFile *pOwner, EMFileSize nSize = 0ull); ~CAICHRecoveryHashSet(); - bool CreatePartRecoveryData(uint64 nPartStartPos, CFileDataIO *fileDataOut, bool bDbgDontLoad = false); - bool ReadRecoveryData(uint64 nPartStartPos, CSafeMemFile *fileDataIn); + bool CreatePartRecoveryData(uint64 nPartStartPos, CFileDataIO &fileDataOut, bool bDbgDontLoad = false); + bool ReadRecoveryData(uint64 nPartStartPos, CSafeMemFile &fileDataIn); bool ReCalculateHash(bool bDontReplace = false); bool VerifyHashTree(bool bDeleteBadTrees); void UntrustedHashReceived(const CAICHHash &Hash, uint32 dwFromIP); diff --git a/srchybrid/SMTPdialog.cpp b/srchybrid/SMTPdialog.cpp index 5889325c..471d9a92 100644 --- a/srchybrid/SMTPdialog.cpp +++ b/srchybrid/SMTPdialog.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -64,7 +64,7 @@ void CSMTPserverDlg::OnBnClickedOk() if (GetDlgItemText(IDC_TXT_SMTPSERVER, str)) { int iColon = str.Find(':'); if (iColon >= 0) { - SetDlgItemText(IDC_SMTPPORT, str.Mid(iColon + 1)); + SetDlgItemText(IDC_SMTPPORT, CPTR(str, iColon + 1)); str.Truncate(iColon); } } diff --git a/srchybrid/SafeFile.cpp b/srchybrid/SafeFile.cpp index a83138ed..6efcb6c3 100644 --- a/srchybrid/SafeFile.cpp +++ b/srchybrid/SafeFile.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -19,7 +19,7 @@ #include "Packets.h" #include "StringConversion.h" #include "kademlia/utils/UInt128.h" -#include +#include "OtherFunctions.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -59,9 +59,9 @@ uint64 CFileDataIO::ReadUInt64() return nVal; } -void CFileDataIO::ReadUInt128(Kademlia::CUInt128 *pVal) +void CFileDataIO::ReadUInt128(Kademlia::CUInt128 &Val) { - Read(pVal->GetDataPtr(), 16); + Read(Val.GetDataPtr(), 16); } void CFileDataIO::ReadHash16(uchar *pVal) @@ -158,9 +158,9 @@ void CFileDataIO::WriteUInt64(uint64 nVal) Write(&nVal, sizeof nVal); } -void CFileDataIO::WriteUInt128(const Kademlia::CUInt128 *pVal) +void CFileDataIO::WriteUInt128(const Kademlia::CUInt128 &Val) { - Write(pVal->GetData(), 16); + Write(Val.GetData(), 16); } void CFileDataIO::WriteHash16(const uchar *pVal) @@ -193,7 +193,7 @@ void CFileDataIO::WriteString(const CString &rstr, EUTF8str eEncode) #undef WRITE_STR_LEN } -void CFileDataIO::WriteString(LPCSTR psz) +void CFileDataIO::WriteString(LPCSTR const psz) { size_t uLen = strlen(psz); WriteUInt16((uint16)uLen); @@ -226,7 +226,7 @@ void CFileDataIO::WriteLongString(const CString &rstr, EUTF8str eEncode) #undef WRITE_STR_LEN } -void CFileDataIO::WriteLongString(LPCSTR psz) +void CFileDataIO::WriteLongString(LPCSTR const psz) { UINT uLen = (UINT)strlen(psz); WriteUInt32(uLen); @@ -318,21 +318,17 @@ uint64 CSafeMemFile::ReadUInt64() return nResult; } -void CSafeMemFile::ReadUInt128(Kademlia::CUInt128 *pVal) +void CSafeMemFile::ReadUInt128(Kademlia::CUInt128 &Val) { - ReadHash16(pVal->GetDataPtr()); + ReadHash16(Val.GetDataPtr()); } void CSafeMemFile::ReadHash16(uchar *pVal) { - if (m_nPosition + sizeof(uint32[4]) > m_nFileSize) + if (m_nPosition + MDX_DIGEST_SIZE > m_nFileSize) AfxThrowFileException(CFileException::endOfFile, 0, GetFileName()); - const uint32 *pUInt32 = (uint32*)&m_lpBuffer[m_nPosition]; - ((uint32*)pVal)[0] = pUInt32[0]; - ((uint32*)pVal)[1] = pUInt32[1]; - ((uint32*)pVal)[2] = pUInt32[2]; - ((uint32*)pVal)[3] = pUInt32[3]; - m_nPosition += sizeof(uint32[4]); + md4cpy(pVal, &m_lpBuffer[m_nPosition]); + m_nPosition += MDX_DIGEST_SIZE; } void CSafeMemFile::WriteUInt8(uint8 nVal) @@ -374,21 +370,17 @@ void CSafeMemFile::WriteUInt64(uint64 nVal) m_nFileSize = m_nPosition; } -void CSafeMemFile::WriteUInt128(const Kademlia::CUInt128 *pVal) +void CSafeMemFile::WriteUInt128(const Kademlia::CUInt128 &Val) { - WriteHash16(pVal->GetData()); + WriteHash16(Val.GetData()); } void CSafeMemFile::WriteHash16(const uchar *pVal) { - if (m_nPosition + sizeof(uint32[4]) > m_nBufferSize) - GrowFile(m_nPosition + sizeof(uint32[4])); - uint32 *pUInt32 = (uint32*)&m_lpBuffer[m_nPosition]; - pUInt32[0] = ((uint32*)pVal)[0]; - pUInt32[1] = ((uint32*)pVal)[1]; - pUInt32[2] = ((uint32*)pVal)[2]; - pUInt32[3] = ((uint32*)pVal)[3]; - m_nPosition += sizeof(uint32[4]); + if (m_nPosition + MDX_DIGEST_SIZE > m_nBufferSize) + GrowFile(m_nPosition + MDX_DIGEST_SIZE); + md4cpy(&m_lpBuffer[m_nPosition], pVal); + m_nPosition += MDX_DIGEST_SIZE; if (m_nPosition > m_nFileSize) m_nFileSize = m_nPosition; } diff --git a/srchybrid/SafeFile.h b/srchybrid/SafeFile.h index 4978f723..0ce5ceed 100644 --- a/srchybrid/SafeFile.h +++ b/srchybrid/SafeFile.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -49,7 +49,7 @@ class CFileDataIO virtual uint16 ReadUInt16(); virtual uint32 ReadUInt32(); virtual uint64 ReadUInt64(); - virtual void ReadUInt128(Kademlia::CUInt128 *pVal); + virtual void ReadUInt128(Kademlia::CUInt128 &Val); virtual void ReadHash16(uchar *pVal); virtual CString ReadString(bool bOptUTF8); virtual CString ReadString(bool bOptUTF8, UINT uRawSize); @@ -59,12 +59,14 @@ class CFileDataIO virtual void WriteUInt16(uint16 nVal); virtual void WriteUInt32(uint32 nVal); virtual void WriteUInt64(uint64 nVal); - virtual void WriteUInt128(const Kademlia::CUInt128 *pVal); + virtual void WriteUInt128(const Kademlia::CUInt128 &Val); virtual void WriteHash16(const uchar *pVal); virtual void WriteString(const CString &rstr, EUTF8str eEncode); - virtual void WriteString(LPCSTR psz); + virtual void WriteString(LPCSTR const psz); virtual void WriteLongString(const CString &rstr, EUTF8str eEncode); - virtual void WriteLongString(LPCSTR psz); + virtual void WriteLongString(LPCSTR const psz); +protected: + virtual ~CFileDataIO() = default; }; @@ -98,7 +100,7 @@ class CSafeMemFile : public CMemFile, public CFileDataIO : CMemFile(nGrowBytes) { } - //CSafeMemFile::CSafeMemFile(BYTE *lpBuffer, UINT nBufferSize, UINT nGrowBytes = 0) + //CSafeMemFile(BYTE *lpBuffer, UINT nBufferSize, UINT nGrowBytes = 0) // : CMemFile(lpBuffer, nBufferSize, nGrowBytes) {} CSafeMemFile(const BYTE *lpBuffer, UINT nBufferSize) : CMemFile(const_cast(lpBuffer), nBufferSize, 0) @@ -120,14 +122,14 @@ class CSafeMemFile : public CMemFile, public CFileDataIO virtual uint16 ReadUInt16(); virtual uint32 ReadUInt32(); virtual uint64 ReadUInt64(); - virtual void ReadUInt128(Kademlia::CUInt128 *pVal); + virtual void ReadUInt128(Kademlia::CUInt128 &Val); virtual void ReadHash16(uchar *pVal); virtual void WriteUInt8(uint8 nVal); virtual void WriteUInt16(uint16 nVal); virtual void WriteUInt32(uint32 nVal); virtual void WriteUInt64(uint64 nVal); - virtual void WriteUInt128(const Kademlia::CUInt128 *pVal); + virtual void WriteUInt128(const Kademlia::CUInt128 &Val); virtual void WriteHash16(const uchar *pVal); }; diff --git a/srchybrid/Scanner.cpp b/srchybrid/Scanner.cpp index 092b2acb..2fb96235 100644 --- a/srchybrid/Scanner.cpp +++ b/srchybrid/Scanner.cpp @@ -1177,8 +1177,9 @@ YY_RULE_SETUP BEGIN(STRING); return TOK_EXT; } - else if (opt_strnicmp(yytext+1, "availability", 3) == 0 || - opt_strnicmp(yytext+1, "sources", 3) == 0) { + else if (opt_strnicmp(yytext+1, "availability", 3) == 0 + || opt_strnicmp(yytext+1, "sources", 3) == 0) + { BEGIN(NUMBER); return TOK_SOURCES; } @@ -1530,22 +1531,20 @@ YY_RULE_SETUP } } #ifndef _UNICODE - else{ - if ((unsigned char)c >= 0x80 && IsDBCSLeadByte(yytext[0])){ - psz[i++] = (unsigned char)c; - if (i >= l){ - char *pszNew = (char*)realloc(psz, l += 128); - if (pszNew == NULL){ - free(psz); - yyerror(_T("Less memory for string")); - yyterminate(); - /*NOT REACHED*/ - break; - } - psz = pszNew; + else if ((unsigned char)c >= 0x80 && IsDBCSLeadByte(yytext[0])) { + psz[i++] = (unsigned char)c; + if (i >= l) { + char *pszNew = (char*)realloc(psz, l += 128); + if (pszNew == NULL) { + free(psz); + yyerror(_T("Less memory for string")); + yyterminate(); + /*NOT REACHED*/ + break; } - c = yyinput(); + psz = pszNew; } + c = yyinput(); } #endif @@ -1565,11 +1564,8 @@ YY_RULE_SETUP psz[i] = '\0'; if (s_bKeepQuotedStrings && YYSTATE != STRING) { - CStringA quoted; - quoted = '\"'; - quoted += psz; - quoted += '\"'; - yylval.pstr = new CStringA(quoted); + yylval.pstr = new CStringA(); + yylval.pstr->Format("\"%s\"", psz); } else yylval.pstr = new CStringA(psz); @@ -1912,8 +1908,8 @@ static int yy_get_next_buffer (void) while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); + yy_cp += dest - source; + yy_bp += dest - source; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = (int)YY_CURRENT_BUFFER_LVALUE->yy_buf_size; @@ -1952,7 +1948,7 @@ static int yy_get_next_buffer (void) else { /* need more input */ - int offset = (yy_c_buf_p) - (yytext_ptr); + int offset = (int)(yy_c_buf_p - (yytext_ptr)); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) @@ -2275,9 +2271,9 @@ YY_BUFFER_STATE yy_scan_buffer (char *base, yy_size_t size ) { YY_BUFFER_STATE b; - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) + if ( size < 2 + || base[size-2] != YY_END_OF_BUFFER_CHAR + || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; diff --git a/srchybrid/Scanner.l b/srchybrid/Scanner.l index 2712c9f2..488bea0b 100644 --- a/srchybrid/Scanner.l +++ b/srchybrid/Scanner.l @@ -105,8 +105,8 @@ number {num1}|{num2} BEGIN(STRING); return TOK_EXT; } - else if (opt_strnicmp(yytext+1, "availability", 3) == 0 || - opt_strnicmp(yytext+1, "sources", 3) == 0) { + else if (opt_strnicmp(yytext+1, "availability", 3) == 0 + || opt_strnicmp(yytext+1, "sources", 3) == 0) { BEGIN(NUMBER); return TOK_SOURCES; } @@ -419,22 +419,20 @@ number {num1}|{num2} } } #ifndef _UNICODE - else{ - if ((unsigned char)c >= 0x80 && IsDBCSLeadByte(yytext[0])){ - psz[i++] = (unsigned char)c; - if (i >= l){ - char *pszNew = (char*)realloc(psz, l += 128); - if (pszNew == NULL){ - free(psz); - yyerror(_T("Less memory for string")); - yyterminate(); - /*NOT REACHED*/ - break; - } - psz = pszNew; + else if ((unsigned char)c >= 0x80 && IsDBCSLeadByte(yytext[0])){ + psz[i++] = (unsigned char)c; + if (i >= l){ + char *pszNew = (char*)realloc(psz, l += 128); + if (pszNew == NULL){ + free(psz); + yyerror(_T("Less memory for string")); + yyterminate(); + /*NOT REACHED*/ + break; } - c = yyinput(); + psz = pszNew; } + c = yyinput(); } #endif @@ -454,11 +452,8 @@ number {num1}|{num2} psz[i] = '\0'; if (s_bKeepQuotedStrings && YYSTATE != STRING) { - CStringA quoted; - quoted = '\"'; - quoted += psz; - quoted += '\"'; - yylval.pstr = new CStringA(quoted); + yylval.pstr = new CStringA(); + yylval.pstr->Format("\"%s\"", psz); } else yylval.pstr = new CStringA(psz); diff --git a/srchybrid/Scheduler.cpp b/srchybrid/Scheduler.cpp index a7ce5b96..c3eeec82 100644 --- a/srchybrid/Scheduler.cpp +++ b/srchybrid/Scheduler.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -47,15 +47,15 @@ CScheduler::~CScheduler() int CScheduler::LoadFromFile() { - CString strName; - strName.Format(_T("%spreferences.ini"), (LPCTSTR)thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); + CString strName(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); + strName += _T("preferences.ini"); CIni ini(strName, _T("Scheduler")); UINT max = ini.GetInt(_T("Count"), 0); UINT count; for (count = 0; count < max; ++count) { strName.Format(_T("Schedule#%u"), count); - const CString &temp = ini.GetString(_T("Title"), _T(""), strName); + const CString &temp(ini.GetString(_T("Title"), _T(""), strName)); if (temp.IsEmpty()) break; Schedule_Struct *news = new Schedule_Struct(); @@ -134,7 +134,7 @@ int CScheduler::Check(bool forcecheck) continue; // check day of week - if (schedule->day != DAY_DAYLY) { + if (schedule->day != DAY_DAILY) { int dow = tNow.GetDayOfWeek(); switch (schedule->day) { case DAY_MO: diff --git a/srchybrid/Scheduler.h b/srchybrid/Scheduler.h index d367dd24..545de9db 100644 --- a/srchybrid/Scheduler.h +++ b/srchybrid/Scheduler.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -25,7 +25,7 @@ #define ACTION_CATSTOP 6 #define ACTION_CATRESUME 7 -#define DAY_DAYLY 0 +#define DAY_DAILY 0 #define DAY_MO 1 #define DAY_DI 2 #define DAY_MI 3 diff --git a/srchybrid/SearchDlg.cpp b/srchybrid/SearchDlg.cpp index eebbc412..da09b034 100644 --- a/srchybrid/SearchDlg.cpp +++ b/srchybrid/SearchDlg.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -18,7 +18,6 @@ #include "emule.h" #include "emuleDlg.h" #include "SearchDlg.h" -#include "SearchParamsWnd.h" #include "SearchResultsWnd.h" #include "OtherFunctions.h" #include "HelpIDs.h" @@ -45,14 +44,8 @@ BEGIN_MESSAGE_MAP(CSearchDlg, CFrameWnd) END_MESSAGE_MAP() CSearchDlg::CSearchDlg() + : m_pwndResults() { - m_pwndParams = new CSearchParamsWnd; - m_pwndResults = NULL; -} - -CSearchDlg::~CSearchDlg() -{ - delete m_pwndParams; } BOOL CSearchDlg::Create(CWnd *pParent) @@ -76,27 +69,27 @@ int CSearchDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) context.m_pNewViewClass = RUNTIME_CLASS(CSearchResultsWnd); context.m_pNewDocTemplate = NULL; m_pwndResults = static_cast(CreateView(&context)); - m_pwndParams->m_searchdlg = m_pwndResults; + m_wndParams.m_searchdlg = m_pwndResults; m_pwndResults->ModifyStyle(WS_BORDER, 0); m_pwndResults->ModifyStyleEx(WS_EX_CLIENTEDGE, WS_EX_STATICEDGE); - m_pwndParams->Create(this, IDD_SEARCH_PARAMS + m_wndParams.Create(this, IDD_SEARCH_PARAMS , WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_SIZE_FIXED | CBRS_SIZE_DYNAMIC | CBRS_GRIPPER , IDBAR_SEARCH_PARAMS); - ASSERT(m_pwndParams->GetStyle() & WS_CLIPSIBLINGS); - ASSERT(m_pwndParams->GetStyle() & WS_CLIPCHILDREN); - m_pwndParams->SetWindowText(GetResString(IDS_SEARCHPARAMS)); - m_pwndParams->EnableDocking(CBRS_ALIGN_ANY); + ASSERT(m_wndParams.GetStyle() & WS_CLIPSIBLINGS); + ASSERT(m_wndParams.GetStyle() & WS_CLIPCHILDREN); + m_wndParams.SetWindowText(GetResString(IDS_SEARCHPARAMS)); + m_wndParams.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); - DockControlBar(m_pwndParams, AFX_IDW_DOCKBAR_TOP, (LPRECT)NULL); + DockControlBar(&m_wndParams, AFX_IDW_DOCKBAR_TOP, (LPRECT)NULL); - m_pwndResults->m_pwndParams = m_pwndParams; + m_pwndResults->m_pwndParams = &m_wndParams; m_pwndResults->SendMessage(WM_INITIALUPDATE); LoadBarState(SEARCH_PARAMS_PROFILE); - DockParametersWnd(); // Too much bug reports about vanished search parameters window. Force to dock. - ShowControlBar(m_pwndParams, TRUE, TRUE); + DockParametersWnd(); // Too many bug reports about vanished search parameters window. Force to dock. + OpenParametersWnd(); Localize(); return 0; @@ -116,7 +109,7 @@ void CSearchDlg::DeleteAllSearchListCtrlItems() void CSearchDlg::OnShowWindow(BOOL bShow, UINT nStatus) { CFrameWnd::OnShowWindow(bShow, nStatus); - if (m_pwndParams->IsFloating()) { + if (m_wndParams.IsFloating()) { //ShowControlBar(m_pwndParams, bShow, TRUE); DockParametersWnd(); // Too much bug reports about vanished search parameters window. Force to dock. } @@ -125,37 +118,37 @@ void CSearchDlg::OnShowWindow(BOOL bShow, UINT nStatus) void CSearchDlg::OnSetFocus(CWnd *pOldWnd) { CFrameWnd::OnSetFocus(pOldWnd); - if (m_pwndParams->m_hWnd) - m_pwndParams->SetFocus(); + if (m_wndParams.m_hWnd) + m_wndParams.SetFocus(); } void CSearchDlg::SaveAllSettings() { - m_pwndParams->SaveSettings(); + m_wndParams.SaveSettings(); } void CSearchDlg::ResetHistory() { - m_pwndParams->ResetHistory(); + m_wndParams.ResetHistory(); } BOOL CSearchDlg::IsSearchParamsWndVisible() const { - return m_pwndParams->IsWindowVisible(); + return m_wndParams.IsWindowVisible(); } void CSearchDlg::OpenParametersWnd() { - ShowControlBar(m_pwndParams, TRUE, TRUE); + ShowControlBar(&m_wndParams, TRUE, TRUE); } void CSearchDlg::DockParametersWnd() { - if (m_pwndParams->IsFloating()) { + if (m_wndParams.IsFloating()) { UINT uMRUDockID = AFX_IDW_DOCKBAR_TOP; - if (m_pwndParams->m_pDockContext) - uMRUDockID = m_pwndParams->m_pDockContext->m_uMRUDockID; - DockControlBar(m_pwndParams, uMRUDockID); + if (m_wndParams.m_pDockContext) + uMRUDockID = m_wndParams.m_pDockContext->m_uMRUDockID; + DockControlBar(&m_wndParams, uMRUDockID); } } @@ -219,7 +212,7 @@ void CSearchDlg::AddEd2kSearchResults(UINT nCount) void CSearchDlg::Localize() { m_pwndResults->Localize(); - m_pwndParams->Localize(); + m_wndParams.Localize(); } void CSearchDlg::CreateMenus() @@ -239,7 +232,7 @@ bool CSearchDlg::DoNewEd2kSearch(SSearchParams *pParams) void CSearchDlg::ProcessEd2kSearchLinkRequest(const CString &strSearchTerm) { - m_pwndParams->ProcessEd2kSearchLinkRequest(strSearchTerm); + m_wndParams.ProcessEd2kSearchLinkRequest(strSearchTerm); } void CSearchDlg::DeleteAllSearches() diff --git a/srchybrid/SearchDlg.h b/srchybrid/SearchDlg.h index 35702335..c9b6a910 100644 --- a/srchybrid/SearchDlg.h +++ b/srchybrid/SearchDlg.h @@ -1,8 +1,6 @@ #pragma once -struct SSearchParams; -class CSearchResultsWnd; -class CSearchParamsWnd; +#include "SearchParamsWnd.h" class CSearchFile; class CClosableTabCtrl; @@ -16,7 +14,6 @@ class CSearchDlg : public CFrameWnd public: CSearchDlg(); // protected constructor used by dynamic creation - virtual ~CSearchDlg(); CSearchResultsWnd *m_pwndResults; BOOL Create(CWnd *pParent); @@ -49,13 +46,11 @@ class CSearchDlg : public CFrameWnd bool CreateNewTab(SSearchParams *pParams, bool bActiveIcon = true); SSearchParams* GetSearchParamsBySearchID(uint32 nSearchID); -// void ShowSearchSelector(bool visible); CClosableTabCtrl& GetSearchSelector(); int GetSelectedCat(); void UpdateCatTabs(); void SaveAllSettings(); -// BOOL SaveSearchStrings(); void ResetHistory(); void SetToolTipsDelay(UINT uDelay); @@ -68,7 +63,7 @@ class CSearchDlg : public CFrameWnd void UpdateSearch(CSearchFile *pSearchFile); protected: - CSearchParamsWnd *m_pwndParams; + CSearchParamsWnd m_wndParams; virtual BOOL PreTranslateMessage(MSG *pMsg); diff --git a/srchybrid/SearchExpr.h b/srchybrid/SearchExpr.h index c2193203..50358b6d 100644 --- a/srchybrid/SearchExpr.h +++ b/srchybrid/SearchExpr.h @@ -83,11 +83,11 @@ class CSearchAttr case FT_MEDIA_TITLE: case FT_MEDIA_ALBUM: case FT_MEDIA_ARTIST: - ASSERT( m_uIntegerOperator == ED2K_SEARCH_OP_EQUAL ); + ASSERT(m_uIntegerOperator == ED2K_SEARCH_OP_EQUAL); strDbg.Format(_T("%s=%s"), (LPCTSTR)DbgGetFileMetaTagName(m_iTag), (LPCTSTR)OptUtf8ToStr(m_str)); break; default: - ASSERT( m_iTag == FT_FILENAME ); + ASSERT(m_iTag == FT_FILENAME); strDbg.Format(_T("\"%s\""), (LPCTSTR)OptUtf8ToStr(m_str)); } return strDbg; @@ -108,21 +108,26 @@ class CSearchExpr { } - explicit CSearchExpr(const CSearchAttr *pAttr) + explicit CSearchExpr(const CSearchAttr &Attr) { - m_aExpr.Add(*pAttr); + m_aExpr.Add(Attr); } void Add(ESearchOperators eOperator) { - if (eOperator == SEARCHOP_OR) - m_aExpr.Add(CSearchAttr(SEARCHOPTOK_OR)); - else if (eOperator == SEARCHOP_NOT) - m_aExpr.Add(CSearchAttr(SEARCHOPTOK_NOT)); - else { - ASSERT( eOperator == SEARCHOP_AND ); - m_aExpr.Add(CSearchAttr(SEARCHOPTOK_AND)); + LPCSTR pszOp; + switch (eOperator) { + case SEARCHOP_OR: + pszOp = SEARCHOPTOK_OR; + break; + case SEARCHOP_NOT: + pszOp = SEARCHOPTOK_NOT; + break; + default: + ASSERT(eOperator == SEARCHOP_AND); + pszOp = SEARCHOPTOK_AND; } + m_aExpr.Add(CSearchAttr(pszOp)); } void Add(const CSearchAttr *pAttr) diff --git a/srchybrid/SearchFile.cpp b/srchybrid/SearchFile.cpp index f99ff173..72c49b69 100644 --- a/srchybrid/SearchFile.cpp +++ b/srchybrid/SearchFile.cpp @@ -1,6 +1,6 @@ // parts of this file are based on work from pan One (http://home-3.tiscali.nl/~meost/pms/) //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -51,7 +51,7 @@ bool IsValidSearchResultClientIPPort(uint32 nIP, uint16 nPort) void ConvertED2KTag(CTag *&pTag) { - if (pTag->GetNameID() == 0 && pTag->GetName()[0]) { + if (pTag->GetNameID() == 0 && pTag->HasName()) { static const struct { uint8 nID; @@ -147,7 +147,7 @@ CSearchFile::CSearchFile(const CSearchFile *copyfrom) m_nCompleteSources = copyfrom->m_nCompleteSources; } -CSearchFile::CSearchFile(CFileDataIO *in_data, bool bOptUTF8, uint32 nSearchID, uint32 nServerIP, +CSearchFile::CSearchFile(CFileDataIO &in_data, bool bOptUTF8, uint32 nSearchID, uint32 nServerIP, uint16 nServerPort, LPCTSTR pszDirectory, bool bKademlia, bool bServerUDPAnswer) : m_bMultipleAICHFound() , m_bKademlia(bKademlia) @@ -165,15 +165,15 @@ CSearchFile::CSearchFile(CFileDataIO *in_data, bool bOptUTF8, uint32 nSearchID, , m_eKnown(NotDetermined) { m_FileIdentifier.SetMD4Hash(in_data); - m_nClientID = in_data->ReadUInt32(); - m_nClientPort = in_data->ReadUInt16(); + m_nClientID = in_data.ReadUInt32(); + m_nClientPort = in_data.ReadUInt16(); if (!IsValidSearchResultClientIPPort(m_nClientID, m_nClientPort)) { if (thePrefs.GetDebugServerSearchesLevel() > 1) Debug(_T("Filtered source from search result %s:%u\n"), (LPCTSTR)DbgGetClientID(m_nClientID), m_nClientPort); m_nClientID = 0; m_nClientPort = 0; } - uint32 tagcount = in_data->ReadUInt32(); + uint32 tagcount = in_data.ReadUInt32(); // NSERVER2.EXE (lugdunum v16.38 patched for Win32) returns the ClientIP+Port of the client which offered that // file, even if that client has not filled the according fields in the OP_OFFERFILES packet with its IP+Port. // @@ -248,7 +248,7 @@ CSearchFile::CSearchFile(CFileDataIO *in_data, bool bOptUTF8, uint32 nSearchID, // // but, in no case, we will use the received file type when adding this search result to the download queue, to avoid // that we are using 'wrong' file types in part files. (this has to be handled when creating the part files) - const CString &rstrFileType = GetStrTagValue(FT_FILETYPE); + const CString &rstrFileType(GetStrTagValue(FT_FILETYPE)); CSearchFile::SetFileName(GetStrTagValue(FT_FILENAME), false, rstrFileType.IsEmpty(), true); uint64 ui64FileSize = 0; @@ -272,7 +272,7 @@ CSearchFile::CSearchFile(CFileDataIO *in_data, bool bOptUTF8, uint32 nSearchID, if (!rstrFileType.IsEmpty()) if (rstrFileType == _T(ED2KFTSTR_PROGRAM)) { - const CString &strDetailFileType = GetFileTypeByName(GetFileName()); + const CString &strDetailFileType(GetFileTypeByName(GetFileName())); CSearchFile::SetFileType(strDetailFileType.IsEmpty() ? rstrFileType : strDetailFileType); } else CSearchFile::SetFileType(rstrFileType); @@ -306,13 +306,13 @@ void CSearchFile::StoreToFile(CFileDataIO &rFile) const for (INT_PTR pos = 0; pos < m_taglist.GetCount(); ++pos) { const CTag *tag = m_taglist[pos]; if (tag->GetNameID() == FT_FILERATING && tag->IsInt()) - CTag(FT_FILERATING, (tag->GetInt() * (255 / 5)) & 0xFF).WriteNewEd2kTag(&rFile); + CTag(FT_FILERATING, (tag->GetInt() * (255 / 5)) & 0xFF).WriteNewEd2kTag(rFile); else - tag->WriteNewEd2kTag(&rFile, UTF8strRaw); + tag->WriteNewEd2kTag(rFile, UTF8strRaw); } if (m_FileIdentifier.HasAICHHash()) { CTag aichtag(FT_AICH_HASH, m_FileIdentifier.GetAICHHash().GetString()); - aichtag.WriteNewEd2kTag(&rFile); + aichtag.WriteNewEd2kTag(rFile); } } diff --git a/srchybrid/SearchFile.h b/srchybrid/SearchFile.h index 67a0607c..1907ba8b 100644 --- a/srchybrid/SearchFile.h +++ b/srchybrid/SearchFile.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -28,7 +28,7 @@ class CSearchFile : public CAbstractFile friend class CSearchListCtrl; public: - CSearchFile(CFileDataIO *in_data, bool bOptUTF8, uint32 nSearchID + CSearchFile(CFileDataIO &in_data, bool bOptUTF8, uint32 nSearchID , uint32 nServerIP = 0, uint16 nServerPort = 0 , LPCTSTR pszDirectory = NULL , bool bKademlia = false @@ -61,7 +61,7 @@ class CSearchFile : public CAbstractFile int GetClientsCount() const { return m_aClients.GetSize() + static_cast(GetClientID() && GetClientPort()); } uint32 GetKadPublishInfo() const { return m_nKadPublishInfo; } // == TAG_PUBLISHINFO void SetKadPublishInfo(uint32 dwVal) { m_nKadPublishInfo = dwVal; } - bool DidFoundMultipleAICH() const { return m_bMultipleAICHFound; } + bool HasFoundMultipleAICH() const { return m_bMultipleAICHFound; } void SetFoundMultipleAICH() { m_bMultipleAICHFound = true; } // Spam filter @@ -93,6 +93,7 @@ class CSearchFile : public CAbstractFile , m_nServerPort() { } + SClient(uint32 nIP, uint16 nPort, uint32 nServerIP, uint16 nServerPort) : m_nIP(nIP) , m_nServerIP(nServerIP) @@ -100,11 +101,13 @@ class CSearchFile : public CAbstractFile , m_nServerPort(nServerPort) { } + friend inline bool __stdcall operator==(const CSearchFile::SClient &c1, const CSearchFile::SClient &c2) { return c1.m_nIP == c2.m_nIP && c1.m_nServerIP == c2.m_nServerIP && c1.m_nPort == c2.m_nPort && c1.m_nServerPort == c2.m_nServerPort; } + uint32 m_nIP; uint32 m_nServerIP; uint16 m_nPort; @@ -135,6 +138,7 @@ class CSearchFile : public CAbstractFile { return s1.m_nIP == s2.m_nIP && s1.m_nPort == s2.m_nPort; } + UINT m_uAvail; uint32 m_nIP; uint16 m_nPort; @@ -168,7 +172,7 @@ class CSearchFile : public CAbstractFile bool m_bServerUDPAnswer; struct { - byte noshow : 1; //bit #0 - do not display in lists + byte noshow : 1; //bit #0 - do not display in GUI lists byte nowrite : 1; //bit #1 - do not save this entry } m_flags; uint32 m_nSources; diff --git a/srchybrid/SearchList.cpp b/srchybrid/SearchList.cpp index 59e21015..69ebe4a4 100644 --- a/srchybrid/SearchList.cpp +++ b/srchybrid/SearchList.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -60,13 +60,12 @@ CSearchList::CSearchList() CSearchList::~CSearchList() { Clear(); - for (POSITION pos = m_aUDPServerRecords.GetStartPosition(); pos != NULL;) { + for (POSITION pos = m_mUDPServerRecords.GetStartPosition(); pos != NULL;) { uint32 dwIP; UDPServerRecord *pRecord; - m_aUDPServerRecords.GetNextAssoc(pos, dwIP, pRecord); + m_mUDPServerRecords.GetNextAssoc(pos, dwIP, pRecord); delete pRecord; } - //m_aUDPServerRecords.RemoveAll(); will be called in the next destructor } void CSearchList::Clear() @@ -100,10 +99,10 @@ void CSearchList::RemoveResults(uint32 nSearchID) void CSearchList::ShowResults(uint32 nSearchID) { ASSERT(outputwnd); - outputwnd->SetRedraw(FALSE); + outputwnd->SetRedraw(false); CMuleListCtrl::EUpdateMode bCurUpdateMode = outputwnd->SetUpdateMode(CMuleListCtrl::none/*direct*/); - SearchList *list = GetSearchListForID(nSearchID); + const SearchList *list = GetSearchListForID(nSearchID); for (POSITION pos = list->GetHeadPosition(); pos != NULL;) { const CSearchFile *cur_file = list->GetNext(pos); ASSERT(cur_file->GetSearchID() == nSearchID); @@ -115,7 +114,7 @@ void CSearchList::ShowResults(uint32 nSearchID) } outputwnd->SetUpdateMode(bCurUpdateMode); - outputwnd->SetRedraw(TRUE); + outputwnd->SetRedraw(true); } void CSearchList::RemoveResult(CSearchFile *todel) @@ -141,25 +140,25 @@ void CSearchList::NewSearch(CSearchListCtrl *pWnd, const CString &strResultFileT m_aCurED2KSentRequestsIPs.RemoveAll(); m_aCurED2KSentReceivedIPs.RemoveAll(); } - m_foundFilesCount.SetAt(pParams->dwSearchID, 0); - m_foundSourcesCount.SetAt(pParams->dwSearchID, 0); - m_ReceivedUDPAnswersCount.SetAt(pParams->dwSearchID, 0); - m_RequestedUDPAnswersCount.SetAt(pParams->dwSearchID, 0); + m_foundFilesCount[pParams->dwSearchID] = 0; + m_foundSourcesCount[pParams->dwSearchID] = 0; + m_ReceivedUDPAnswersCount[pParams->dwSearchID] = 0; + m_RequestedUDPAnswersCount[pParams->dwSearchID] = 0; // convert the expression into an array of search keywords which the user has typed in // this is used for the spam filter later and not at all semantically equal to // the actual search expression any more m_astrSpamCheckCurSearchExp.RemoveAll(); - pParams->strExpression.MakeLower(); - if (pParams->strExpression.Find(_T("related:"), 0) != 0) { // ignore special searches + CString sExpr(pParams->strExpression); + if (_tcsncmp(sExpr.MakeLower(), _T("related:"), 8) != 0) { // ignore special searches int nPos, nPos2; - while ((nPos = pParams->strExpression.Find(_T('"'))) >= 0 && (nPos2 = pParams->strExpression.Find(_T('"'), nPos + 1)) >= 0) { - const CString &strQuoted(pParams->strExpression.Mid(nPos + 1, (nPos2 - nPos) - 1)); + while ((nPos = sExpr.Find(_T('"'))) >= 0 && (nPos2 = sExpr.Find(_T('"'), nPos + 1)) >= 0) { + const CString &strQuoted(sExpr.Mid(nPos + 1, (nPos2 - nPos) - 1)); m_astrSpamCheckCurSearchExp.Add(strQuoted); - pParams->strExpression.Delete(nPos, (nPos2 - nPos) + 1); + sExpr.Delete(nPos, (nPos2 - nPos) + 1); } for (int iPos = 0; iPos >= 0;) { - const CString &sToken(pParams->strExpression.Tokenize(_T(".[]()!-'_ "), iPos)); + const CString &sToken(sExpr.Tokenize(_T(".[]()!-'_ "), iPos)); if (!sToken.IsEmpty() && sToken != "and" && sToken != "or" && sToken != "not") m_astrSpamCheckCurSearchExp.Add(sToken); } @@ -180,14 +179,14 @@ UINT CSearchList::ProcessSearchAnswer(const uchar *in_packet, uint32 size pParams->dwSearchID = uSearchID; pParams->bClientSharedFiles = true; if (theApp.emuledlg->searchwnd->CreateNewTab(pParams)) { - m_foundFilesCount.SetAt(uSearchID, 0); - m_foundSourcesCount.SetAt(uSearchID, 0); + m_foundFilesCount[uSearchID] = 0; + m_foundSourcesCount[uSearchID] = 0; } else delete pParams; CSafeMemFile packet(in_packet, size); for (uint32 results = packet.ReadUInt32(); results > 0; --results) { - CSearchFile *toadd = new CSearchFile(&packet, sender.GetUnicodeSupport() != UTF8strNone, uSearchID, 0, 0, pszDirectory); + CSearchFile *toadd = new CSearchFile(packet, sender.GetUnicodeSupport() != UTF8strNone, uSearchID, 0, 0, pszDirectory); if (toadd->IsLargeFile() && !sender.SupportsLargeFiles()) { DebugLogWarning(_T("Client offers large file (%s) but did not announce support for it - ignoring file"), (LPCTSTR)toadd->GetFileName()); delete toadd; @@ -213,7 +212,7 @@ UINT CSearchList::ProcessSearchAnswer(const uchar *in_packet, uint32 size uint8 ucMore = packet.ReadUInt8(); if (ucMore <= 0x01) { if (pbMoreResultsAvailable) - *pbMoreResultsAvailable = ucMore != 0; + *pbMoreResultsAvailable = (ucMore != 0); if (thePrefs.GetDebugClientTCPLevel() > 0) Debug(_T(" Client search answer(%s): More=%u\n"), sender.GetUserName(), ucMore); } else if (thePrefs.GetDebugClientTCPLevel() > 0) @@ -235,7 +234,7 @@ UINT CSearchList::ProcessSearchAnswer(const uchar *in_packet, uint32 size, bool { CSafeMemFile packet(in_packet, size); for (uint32 i = packet.ReadUInt32(); i > 0; --i) { - CSearchFile *toadd = new CSearchFile(&packet, bOptUTF8, m_nCurED2KSearchID); + CSearchFile *toadd = new CSearchFile(packet, bOptUTF8, m_nCurED2KSearchID); toadd->SetClientServerIP(nServerIP); toadd->SetClientServerPort(nServerPort); if (nServerIP && nServerPort) { @@ -271,7 +270,7 @@ UINT CSearchList::ProcessSearchAnswer(const uchar *in_packet, uint32 size, bool UINT CSearchList::ProcessUDPSearchAnswer(CFileDataIO &packet, bool bOptUTF8, uint32 nServerIP, uint16 nServerPort) { - CSearchFile *toadd = new CSearchFile(&packet, bOptUTF8, m_nCurED2KSearchID, nServerIP, nServerPort, NULL, false, true); + CSearchFile *toadd = new CSearchFile(packet, bOptUTF8, m_nCurED2KSearchID, nServerIP, nServerPort, NULL, false, true); bool bFound = false; for (INT_PTR i = m_aCurED2KSentRequestsIPs.GetCount(); --i >= 0;) @@ -297,18 +296,18 @@ UINT CSearchList::ProcessUDPSearchAnswer(CFileDataIO &packet, bool bOptUTF8, uin uint32 nResponses; if (!m_ReceivedUDPAnswersCount.Lookup(m_nCurED2KSearchID, nResponses)) nResponses = 0; - m_ReceivedUDPAnswersCount.SetAt(m_nCurED2KSearchID, nResponses + 1); + m_ReceivedUDPAnswersCount[m_nCurED2KSearchID] = nResponses + 1; m_aCurED2KSentReceivedIPs.Add(nServerIP); } - UDPServerRecord *pRecord; - if (m_aUDPServerRecords.Lookup(nServerIP, pRecord)) - pRecord->m_nResults++; + const CUDPServerRecordMap::CPair *pair = m_mUDPServerRecords.PLookup(nServerIP); + if (pair) + ++pair->value->m_nResults; else { - pRecord = new UDPServerRecord; + UDPServerRecord *pRecord = new UDPServerRecord; pRecord->m_nResults = 1; pRecord->m_nSpamResults = 0; - m_aUDPServerRecords.SetAt(nServerIP, pRecord); + m_mUDPServerRecords[nServerIP] = pRecord; } AddToList(toadd, false, nServerIP); @@ -418,10 +417,8 @@ bool CSearchList::AddToList(CSearchFile *toadd, bool bClientResponse, uint32 dwF // search for a 'parent' with same file hash and search-id as the new search result entry for (POSITION pos = list->GetHeadPosition(); pos != NULL;) { CSearchFile *parent = list->GetNext(pos); - if (parent->GetListParent() == NULL - && md4equ(parent->GetFileHash(), toadd->GetFileHash())) - { - // if this parent does not yet have any child entries, create one child entry + if (parent->GetListParent() == NULL && md4equ(parent->GetFileHash(), toadd->GetFileHash())) { + // if this parent does not have any child entries yet, create one child entry // which is equal to the current parent entry (needed for GUI when expanding the child list). if (!parent->GetListChildCount()) { CSearchFile *child = new CSearchFile(parent); @@ -449,7 +446,7 @@ bool CSearchList::AddToList(CSearchFile *toadd, bool bClientResponse, uint32 dwF ; // for debugging: do not merge search results else { // check if that parent already has a child with same filename as the new search result entry - for (POSITION pos2 = list->GetHeadPosition(); pos2 != NULL && !bFound; ) { + for (POSITION pos2 = list->GetHeadPosition(); pos2 != NULL && !bFound;) { CSearchFile *child = list->GetNext(pos2); if (child != toadd // not the same object && child->GetListParent() == parent // is a child of our result (one file hash) @@ -469,7 +466,7 @@ bool CSearchList::AddToList(CSearchFile *toadd, bool bClientResponse, uint32 dwF child->AddCompleteSources(uCompleteSources); // Check AICH Hash - if they differ, clear it (see KademliaSearchKeyword) - // if we didn't have a hash yet, take it over + // if we don't have a hash yet, take it over if (toadd->GetFileIdentifier().HasAICHHash()) { if (child->GetFileIdentifier().HasAICHHash()) { if (parent->GetFileIdentifier().GetAICHHash() != toadd->GetFileIdentifier().GetAICHHash()) { @@ -477,7 +474,7 @@ bool CSearchList::AddToList(CSearchFile *toadd, bool bClientResponse, uint32 dwF child->SetFoundMultipleAICH(); child->GetFileIdentifier().ClearAICHHash(); } - } else if (!child->DidFoundMultipleAICH()) { + } else if (!child->HasFoundMultipleAICH()) { DEBUG_ONLY(DebugLog(_T("Kad: SearchList: AddToList: Received searchresult with new AICH hash %s, taking over to existing result. Entry: %s"), (LPCTSTR)toadd->GetFileIdentifier().GetAICHHash().GetString(), (LPCTSTR)child->GetFileName())); child->GetFileIdentifier().SetAICHHash(toadd->GetFileIdentifier().GetAICHHash()); } @@ -505,10 +502,8 @@ bool CSearchList::AddToList(CSearchFile *toadd, bool bClientResponse, uint32 dwF if (parent->GetClients().Find(client) < 0) parent->AddClient(client); } - } else { - if (thePrefs.GetDebugServerSearchesLevel() > 1) - Debug(_T("Filtered source from search result %s:%u\n"), (LPCTSTR)DbgGetClientID(toadd->GetClientID()), toadd->GetClientPort()); - } + } else if (thePrefs.GetDebugServerSearchesLevel() > 1) + Debug(_T("Filtered source from search result %s:%u\n"), (LPCTSTR)DbgGetClientID(toadd->GetClientID()), toadd->GetClientPort()); // copy possible available servers from new search result entry to parent // will be used in future @@ -544,7 +539,7 @@ bool CSearchList::AddToList(CSearchFile *toadd, bool bClientResponse, uint32 dwF aichHash = fileid.GetAICHHash(); bAICHHashValid = true; } - } else if (child->DidFoundMultipleAICH()) + } else if (child->HasFoundMultipleAICH()) bHasMultipleAICHHashes = true; if (parent->IsKademlia()) { @@ -608,7 +603,7 @@ bool CSearchList::AddToList(CSearchFile *toadd, bool bClientResponse, uint32 dwF UINT tempValue; if (!m_foundFilesCount.Lookup(toadd->GetSearchID(), tempValue)) tempValue = 0; - m_foundFilesCount.SetAt(toadd->GetSearchID(), tempValue + 1); + m_foundFilesCount[toadd->GetSearchID()] = tempValue + 1; // get the 'Availability' of this new search result entry @@ -646,20 +641,15 @@ CSearchFile* CSearchList::GetSearchFileByHash(const uchar *hash) const return NULL; } -bool CSearchList::AddNotes(Kademlia::CEntry *entry, const uchar *hash) +bool CSearchList::AddNotes(const Kademlia::CEntry &cEntry, const uchar *hash) { bool flag = false; for (POSITION pos = m_listFileLists.GetHeadPosition(); pos != NULL;) { const SearchListsStruct *listCur = m_listFileLists.GetNext(pos); for (POSITION pos2 = listCur->m_listSearchFiles.GetHeadPosition(); pos2 != NULL;) { CSearchFile *sf = listCur->m_listSearchFiles.GetNext(pos2); - if (md4equ(hash, sf->GetFileHash())) { - Kademlia::CEntry *entryClone = entry->Copy(); - if (sf->AddNote(entryClone)) - flag = true; - else - delete entryClone; - } + if (md4equ(hash, sf->GetFileHash()) && sf->AddNote(cEntry)) + flag = true; } } return flag; @@ -688,14 +678,13 @@ void CSearchList::AddResultCount(uint32 nSearchID, const uchar *hash, UINT nCoun tempValue = 0; // spam files count as max 5 availability - m_foundSourcesCount.SetAt(nSearchID, tempValue - + ((bSpam && thePrefs.IsSearchSpamFilterEnabled()) ? min(nCount, 5) : nCount)); + m_foundSourcesCount[nSearchID] = tempValue + ((bSpam && thePrefs.IsSearchSpamFilterEnabled()) ? min(nCount, 5) : nCount); } // FIXME LARGE FILES -void CSearchList::KademliaSearchKeyword(uint32 searchID, const Kademlia::CUInt128 *pFileID, LPCTSTR name +void CSearchList::KademliaSearchKeyword(uint32 nSearchID, const Kademlia::CUInt128 *pFileID, LPCTSTR name , uint64 size, LPCTSTR type, UINT uKadPublishInfo - , CArray &raAICHHashes, CArray &raAICHHashPopularity + , CArray &raAICHHashes, CArray &raAICHHashPopularity , SSearchTerm *pQueriedSearchTerm, UINT numProperties, ...) { va_list args; @@ -720,18 +709,18 @@ void CSearchList::KademliaSearchKeyword(uint32 searchID, const Kademlia::CUInt12 uint32 tagcount = 0; // standard tags CTag tagName(FT_FILENAME, name); - tagName.WriteTagToFile(&temp, eStrEncode); + tagName.WriteTagToFile(temp, eStrEncode); ++tagcount; verifierEntry.SetFileName(Kademlia::CKadTagValueString(name)); CTag tagSize(FT_FILESIZE, size, true); - tagSize.WriteTagToFile(&temp, eStrEncode); + tagSize.WriteTagToFile(temp, eStrEncode); ++tagcount; verifierEntry.m_uSize = size; if (type != NULL && type[0] != _T('\0')) { CTag tagType(FT_FILETYPE, type); - tagType.WriteTagToFile(&temp, eStrEncode); + tagType.WriteTagToFile(temp, eStrEncode); ++tagcount; verifierEntry.AddTag(new Kademlia::CKadTagStr(TAG_FILETYPE, type)); } @@ -745,10 +734,10 @@ void CSearchList::KademliaSearchKeyword(uint32 searchID, const Kademlia::CUInt12 if ((LPCTSTR)pvPropValue != NULL && ((LPCTSTR)pvPropValue)[0] != _T('\0')) { if (strlen(pszPropName) == 1) { CTag tagProp((uint8)*pszPropName, (LPCTSTR)pvPropValue); - tagProp.WriteTagToFile(&temp, eStrEncode); + tagProp.WriteTagToFile(temp, eStrEncode); } else { CTag tagProp(pszPropName, (LPCTSTR)pvPropValue); - tagProp.WriteTagToFile(&temp, eStrEncode); + tagProp.WriteTagToFile(temp, eStrEncode); } verifierEntry.AddTag(new Kademlia::CKadTagStr(pszPropName, (LPCTSTR)pvPropValue)); ++tagcount; @@ -756,7 +745,7 @@ void CSearchList::KademliaSearchKeyword(uint32 searchID, const Kademlia::CUInt12 } else if (uPropType == TAGTYPE_UINT32) { if ((uint32)pvPropValue != 0) { CTag tagProp(pszPropName, (uint32)pvPropValue); - tagProp.WriteTagToFile(&temp, eStrEncode); + tagProp.WriteTagToFile(temp, eStrEncode); ++tagcount; verifierEntry.AddTag(new Kademlia::CKadTagUInt(pszPropName, (uint32)pvPropValue)); } @@ -764,12 +753,12 @@ void CSearchList::KademliaSearchKeyword(uint32 searchID, const Kademlia::CUInt12 ASSERT(0); } va_end(args); - temp.Seek(uFilePosTagCount, SEEK_SET); + temp.Seek(uFilePosTagCount, CFile::begin); temp.WriteUInt32(tagcount); if (pQueriedSearchTerm == NULL || verifierEntry.StartSearchTermsMatch(*pQueriedSearchTerm)) { temp.SeekToBegin(); - CSearchFile *tempFile = new CSearchFile(&temp, eStrEncode == UTF8strRaw, searchID, 0, 0, NULL, true); + CSearchFile *tempFile = new CSearchFile(temp, eStrEncode == UTF8strRaw, nSearchID, 0, 0, NULL, true); tempFile->SetKadPublishInfo(uKadPublishInfo); // About the AICH hash: We received a list of possible AICH hashes for this file and now have to decide what to do // If it wasn't for backwards compatibility, the choice would be easy: Each different md4+aich+size is its own result, @@ -867,7 +856,7 @@ void CSearchList::DoSpamRating(CSearchFile *pSearchFile, bool bIsClientFile, boo nDbgFileHash = nDbgStrings = nDbgSize = nDbgServer = nDbgSources = nDbgHeuristic = nDbgOnlySpamServer = 0; // 1- file hash - bool bSpam = false; + bool bSpam; if (m_mapKnownSpamHashes.Lookup(CSKey(pSearchFile->GetFileHash()), bSpam)) { if (!bMarkAsNoSpam && bSpam) { nSpamScore += SPAM_FILEHASH_HIT; @@ -877,15 +866,16 @@ void CSearchList::DoSpamRating(CSearchFile *pSearchFile, bool bIsClientFile, boo else bSureNegative = true; } - CSearchFile *pParent = NULL; + CSearchFile *pParent; if (pSearchFile->GetListParent() != NULL) pParent = pSearchFile->GetListParent(); - else if (pSearchFile->GetListChildCount() > 0) - pParent = pSearchFile; + else + pParent = pSearchFile->GetListChildCount() ? pSearchFile : NULL; + CSearchFile *pTempFile = (pSearchFile->GetListParent() != NULL) ? pSearchFile->GetListParent() : pSearchFile; if (!bSureNegative && bMarkAsNoSpam) - m_mapKnownSpamHashes.SetAt(CSKey(pSearchFile->GetFileHash()), false); + m_mapKnownSpamHashes[CSKey(pSearchFile->GetFileHash())] = false; #ifndef _DEBUG else if (bSureNegative && !bMarkAsNoSpam) { #endif @@ -895,7 +885,7 @@ void CSearchList::DoSpamRating(CSearchFile *pSearchFile, bool bIsClientFile, boo uint32 nHighestRating; if (pParent != NULL) { nHighestRating = GetSpamFilenameRatings(pParent, bMarkAsNoSpam); - SearchList *list = GetSearchListForID(pParent->GetSearchID()); + const SearchList *list = GetSearchListForID(pParent->GetSearchID()); for (POSITION pos = list->GetHeadPosition(); pos != NULL;) { const CSearchFile *pCurFile = list->GetNext(pos); if (pCurFile->GetListParent() == pParent) { @@ -957,17 +947,15 @@ void CSearchList::DoSpamRating(CSearchFile *pSearchFile, bool bIsClientFile, boo bool bNormalServerPresent = bNormalServerWithoutCurrentPresent; for (int i = 0; i < aservers.GetSize(); ++i) { UDPServerRecord *pRecord = NULL; - if (!bMarkAsNoSpam && aservers[i].m_bUDPAnswer && m_aUDPServerRecords.Lookup(aservers[i].m_nIP, pRecord) && pRecord != NULL) { + if (!bMarkAsNoSpam && aservers[i].m_bUDPAnswer && m_mUDPServerRecords.Lookup(aservers[i].m_nIP, pRecord) && pRecord != NULL) { ASSERT(pRecord->m_nResults >= pRecord->m_nSpamResults); - int nRatio; - if (pRecord->m_nResults >= pRecord->m_nSpamResults && pRecord->m_nResults != 0) { - nRatio = (pRecord->m_nSpamResults * 100) / pRecord->m_nResults; + if (pRecord->m_nResults >= pRecord->m_nSpamResults && pRecord->m_nResults > 0) { + int nRatio = (pRecord->m_nSpamResults * 100) / pRecord->m_nResults; if (nRatio < 50) { bNormalServerWithoutCurrentPresent |= (dwFromUDPServerIP != aservers[i].m_nIP); bNormalServerPresent = true; } - } else - nRatio = 100; + } } else if (!aservers[i].m_bUDPAnswer) { bNormalServerWithoutCurrentPresent = true; bNormalServerPresent = true; @@ -1075,7 +1063,7 @@ void CSearchList::DoSpamRating(CSearchFile *pSearchFile, bool bIsClientFile, boo if (pParent != NULL) { pParent->SetSpamRating(bMarkAsNoSpam ? 0 : nSpamScore); - SearchList *list = GetSearchListForID(pParent->GetSearchID()); + const SearchList *list = GetSearchListForID(pParent->GetSearchID()); for (POSITION pos = list->GetHeadPosition(); pos != NULL;) { CSearchFile *pCurFile = list->GetNext(pos); if (pCurFile->GetListParent() == pParent) @@ -1089,20 +1077,20 @@ void CSearchList::DoSpamRating(CSearchFile *pSearchFile, bool bIsClientFile, boo const CSimpleArray &aservers = pTempFile->GetServers(); for (int i = 0; i < aservers.GetSize(); ++i) { UDPServerRecord *pRecord; - if (aservers[i].m_bUDPAnswer && m_aUDPServerRecords.Lookup(aservers[i].m_nIP, pRecord) && pRecord != NULL) { + if (aservers[i].m_bUDPAnswer && m_mUDPServerRecords.Lookup(aservers[i].m_nIP, pRecord) && pRecord != NULL) { if (pSearchFile->IsConsideredSpam()) - pRecord->m_nSpamResults++; + ++pRecord->m_nSpamResults; else { ASSERT(pRecord->m_nSpamResults > 0); - pRecord->m_nSpamResults--; + --pRecord->m_nSpamResults; } } } } else if (dwFromUDPServerIP != 0 && pSearchFile->IsConsideredSpam()) { - // files was already spam, but a new server also gave it as result, add it to his spam stats - UDPServerRecord *pRecord = NULL; - if (m_aUDPServerRecords.Lookup(dwFromUDPServerIP, pRecord) && pRecord != NULL) - pRecord->m_nSpamResults++; + // files were a spam already, but server returned it in results - add it to server's spam stats + const CUDPServerRecordMap::CPair *pair = m_mUDPServerRecords.PLookup(dwFromUDPServerIP); + if (pair) + ++pair->value->m_nSpamResults; } if (bUpdate && outputwnd != NULL) @@ -1113,19 +1101,19 @@ void CSearchList::DoSpamRating(CSearchFile *pSearchFile, bool bIsClientFile, boo uint32 CSearchList::GetSpamFilenameRatings(const CSearchFile *pSearchFile, bool bMarkAsNoSpam) { - for (int i = 0; i < m_astrKnownSpamNames.GetCount(); ++i) { + for (INT_PTR i = m_astrKnownSpamNames.GetCount(); --i >= 0;) { if (pSearchFile->GetFileName().CompareNoCase(m_astrKnownSpamNames[i]) == 0) { if (!bMarkAsNoSpam) return (pSearchFile->GetFileName().GetLength() <= 10) ? SPAM_SMALLFULLNAME_HIT : SPAM_FULLNAME_HIT; m_astrKnownSpamNames.RemoveAt(i); - --i; } } + uint32 nResult = 0; if (!m_astrKnownSimilarSpamNames.IsEmpty() && !pSearchFile->GetNameWithoutKeyword().IsEmpty()) { - const CString &cname = pSearchFile->GetNameWithoutKeyword(); - for (int i = 0; i < m_astrKnownSimilarSpamNames.GetCount(); ++i) { + const CString &cname(pSearchFile->GetNameWithoutKeyword()); + for (INT_PTR i = m_astrKnownSimilarSpamNames.GetCount(); --i >= 0;) { bool bRemove = false; if (cname == m_astrKnownSimilarSpamNames[i]) { if (!bMarkAsNoSpam) @@ -1137,22 +1125,19 @@ uint32 CSearchList::GetSpamFilenameRatings(const CSearchFile *pSearchFile, bool || cname.GetLength() / abs(cname.GetLength() - m_astrKnownSimilarSpamNames[i].GetLength()) >= 3)) { uint32 nStringComp = LevenshteinDistance(cname, m_astrKnownSimilarSpamNames[i]); - if (nStringComp != 0) + if (nStringComp != 0) { nStringComp = cname.GetLength() / nStringComp; - if (nStringComp >= 3) { - if (!bMarkAsNoSpam) { - if (nStringComp >= 6) + if (nStringComp >= 3) + if (bMarkAsNoSpam) + bRemove = true; + else if (nStringComp >= 6) nResult = SPAM_SIMILARNAME_NEARHIT; else nResult = max(nResult, SPAM_SIMILARNAME_FARHIT); - } else - bRemove = true; } } - if (bRemove) { + if (bRemove) m_astrKnownSimilarSpamNames.RemoveAt(i); - --i; - } } } return nResult; @@ -1175,7 +1160,7 @@ SearchList* CSearchList::GetSearchListForID(uint32 nSearchID) void CSearchList::SentUDPRequestNotification(uint32 nSearchID, uint32 dwServerIP) { if (nSearchID == m_nCurED2KSearchID) - m_RequestedUDPAnswersCount.SetAt(nSearchID, (uint32)m_aCurED2KSentRequestsIPs.Add(dwServerIP) + 1); + m_RequestedUDPAnswersCount[nSearchID] = (uint32)m_aCurED2KSentRequestsIPs.Add(dwServerIP) + 1; else ASSERT(0); @@ -1188,21 +1173,21 @@ void CSearchList::MarkFileAsSpam(CSearchFile *pSpamFile, bool bRecalculateAll, b m_astrKnownSpamNames.Add(pSpamFile->GetFileName()); m_astrKnownSimilarSpamNames.Add(pSpamFile->GetNameWithoutKeyword()); - m_mapKnownSpamHashes.SetAt(CSKey(pSpamFile->GetFileHash()), true); + m_mapKnownSpamHashes[CSKey(pSpamFile->GetFileHash())] = true; m_aui64KnownSpamSizes.Add((uint64)pSpamFile->GetFileSize()); if (IsValidSearchResultClientIPPort(pSpamFile->GetClientID(), pSpamFile->GetClientPort()) && !::IsLowID(pSpamFile->GetClientID())) { - m_mapKnownSpamSourcesIPs.SetAt(pSpamFile->GetClientID(), true); + m_mapKnownSpamSourcesIPs[pSpamFile->GetClientID()] = true; } - for (int i = 0; i < pSpamFile->GetClients().GetSize(); ++i) + for (int i = pSpamFile->GetClients().GetSize(); --i >= 0;) if (pSpamFile->GetClients()[i].m_nIP != 0) - m_mapKnownSpamSourcesIPs.SetAt(pSpamFile->GetClients()[i].m_nIP, true); + m_mapKnownSpamSourcesIPs[pSpamFile->GetClients()[i].m_nIP] = true; - for (int i = 0; i < pSpamFile->GetServers().GetSize(); ++i) + for (int i = pSpamFile->GetServers().GetSize(); --i >= 0;) if (pSpamFile->GetServers()[i].m_nIP != 0 && pSpamFile->GetServers()[i].m_bUDPAnswer) - m_mapKnownSpamServerIPs.SetAt(pSpamFile->GetServers()[i].m_nIP, true); + m_mapKnownSpamServerIPs[pSpamFile->GetServers()[i].m_nIP] = true; if (bRecalculateAll) @@ -1219,7 +1204,7 @@ void CSearchList::RecalculateSpamRatings(uint32 nSearchID, bool bExpectHigher, b ASSERT(!(bExpectHigher && bExpectLower)); ASSERT(m_bSpamFilterLoaded); - SearchList *list = GetSearchListForID(nSearchID); + const SearchList *list = GetSearchListForID(nSearchID); for (POSITION pos = list->GetHeadPosition(); pos != NULL;) { CSearchFile *pCurFile = list->GetNext(pos); // check only parents and only if we expect a status change @@ -1241,7 +1226,6 @@ void CSearchList::LoadSpamFilter() m_mapKnownSpamSourcesIPs.RemoveAll(); m_mapKnownSpamHashes.RemoveAll(); m_aui64KnownSpamSizes.RemoveAll(); - unsigned nDbgFileHashPos = 0; m_bSpamFilterLoaded = true; @@ -1258,7 +1242,7 @@ void CSearchList::LoadSpamFilter() } return; } - setvbuf(file.m_pStream, NULL, _IOFBF, 16384); + ::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); try { uint8 header = file.ReadUInt8(); @@ -1267,19 +1251,20 @@ void CSearchList::LoadSpamFilter() DebugLogError(_T("Failed to load searchspam.met, invalid first byte")); return; } + unsigned nDbgFileHashPos = 0; for (uint32 i = file.ReadUInt32(); i > 0; --i) { //number of records - CTag tag(&file, false); + CTag tag(file, false); switch (tag.GetNameID()) { case SP_FILEHASHSPAM: ASSERT(tag.IsHash()); if (tag.IsHash()) - m_mapKnownSpamHashes.SetAt(CSKey(tag.GetHash()), true); + m_mapKnownSpamHashes[CSKey(tag.GetHash())] = true; break; case SP_FILEHASHNOSPAM: ASSERT(tag.IsHash()); if (tag.IsHash()) { - m_mapKnownSpamHashes.SetAt(CSKey(tag.GetHash()), false); + m_mapKnownSpamHashes[CSKey(tag.GetHash())] = false; ++nDbgFileHashPos; } break; @@ -1296,12 +1281,12 @@ void CSearchList::LoadSpamFilter() case SP_FILESOURCEIP: ASSERT(tag.IsInt()); if (tag.IsInt()) - m_mapKnownSpamSourcesIPs.SetAt(tag.GetInt(), true); + m_mapKnownSpamSourcesIPs[tag.GetInt()] = true; break; case SP_FILESERVERIP: ASSERT(tag.IsInt()); if (tag.IsInt()) - m_mapKnownSpamServerIPs.SetAt(tag.GetInt(), true); + m_mapKnownSpamServerIPs[tag.GetInt()] = true; break; case SP_FILESIZE: ASSERT(tag.IsInt64()); @@ -1315,9 +1300,9 @@ void CSearchList::LoadSpamFilter() UDPServerRecord *pRecord = new UDPServerRecord; pRecord->m_nResults = PeekUInt32(&pBuffer[4]); pRecord->m_nSpamResults = PeekUInt32(&pBuffer[8]); - m_aUDPServerRecords.SetAt(PeekUInt32(&pBuffer[0]), pRecord); + m_mUDPServerRecords[PeekUInt32(&pBuffer[0])] = pRecord; int nRatio; - if (pRecord->m_nResults >= pRecord->m_nSpamResults && pRecord->m_nResults != 0) + if (pRecord->m_nResults >= pRecord->m_nSpamResults && pRecord->m_nResults > 0) nRatio = (pRecord->m_nSpamResults * 100) / pRecord->m_nResults; else nRatio = 100; @@ -1330,6 +1315,15 @@ void CSearchList::LoadSpamFilter() } } file.Close(); + + DebugLog(_T("Loaded search Spam Filter. Entries - ServerIPs: %u, SourceIPs, %u, hashes: %u, PositiveHashes: %i, FileSizes: %u, FullNames: %u, SimilarNames: %u") + , (unsigned)m_mapKnownSpamSourcesIPs.GetCount() + , (unsigned)m_mapKnownSpamServerIPs.GetCount() + , (unsigned)m_mapKnownSpamHashes.GetCount() - nDbgFileHashPos + , nDbgFileHashPos + , (unsigned)m_aui64KnownSpamSizes.GetCount() + , (unsigned)m_astrKnownSpamNames.GetCount() + , (unsigned)m_astrKnownSimilarSpamNames.GetCount()); } catch (CFileException *error) { if (error->m_cause == CFileException::endOfFile) DebugLogError(_T("Failed to load searchspam.met, corrupt")); @@ -1339,17 +1333,7 @@ void CSearchList::LoadSpamFilter() DebugLogError(_T("Failed to load searchspam.met, %s"), buffer); } error->Delete(); - return; } - - DebugLog(_T("Loaded search Spam Filter. Entries - ServerIPs: %u, SourceIPs, %u, hashes: %u, PositiveHashes: %i, FileSizes: %u, FullNames: %u, SimilarNames: %u") - , (unsigned)m_mapKnownSpamSourcesIPs.GetCount() - , (unsigned)m_mapKnownSpamServerIPs.GetCount() - , (unsigned)m_mapKnownSpamHashes.GetCount() - nDbgFileHashPos - , nDbgFileHashPos - , (unsigned)m_aui64KnownSpamSizes.GetCount() - , (unsigned)m_astrKnownSpamNames.GetCount() - , (unsigned)m_astrKnownSimilarSpamNames.GetCount()); } void CSearchList::SaveSpamFilter() @@ -1370,86 +1354,65 @@ void CSearchList::SaveSpamFilter() } return; } - setvbuf(file.m_pStream, NULL, _IOFBF, 16384); - uint32 nCount = 0; + ::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); try { + uint32 nCount = 0; file.WriteUInt8(MET_HEADER_I64TAGS); file.WriteUInt32(nCount); for (int i = 0; i < m_astrKnownSpamNames.GetCount(); ++i) { CTag tag(SP_FILEFULLNAME, m_astrKnownSpamNames[i]); - tag.WriteNewEd2kTag(&file, UTF8strOptBOM); + tag.WriteNewEd2kTag(file, UTF8strOptBOM); ++nCount; } for (int i = 0; i < m_astrKnownSimilarSpamNames.GetCount(); ++i) { CTag tag(SP_FILESIMILARNAME, m_astrKnownSimilarSpamNames[i]); - tag.WriteNewEd2kTag(&file, UTF8strOptBOM); + tag.WriteNewEd2kTag(file, UTF8strOptBOM); ++nCount; } for (int i = 0; i < m_aui64KnownSpamSizes.GetCount(); ++i) { CTag tag(SP_FILESIZE, m_aui64KnownSpamSizes[i], true); - tag.WriteNewEd2kTag(&file); + tag.WriteNewEd2kTag(file); ++nCount; } - CSKey key; - for (POSITION pos = m_mapKnownSpamHashes.GetStartPosition(); pos != NULL;) { - bool bSpam; - m_mapKnownSpamHashes.GetNextAssoc(pos, key, bSpam); - if (bSpam) { - CTag tag(SP_FILEHASHSPAM, (BYTE*)key.m_key); - tag.WriteNewEd2kTag(&file); - } else { - CTag tag(SP_FILEHASHNOSPAM, (BYTE*)key.m_key); - tag.WriteNewEd2kTag(&file); - } + for (const CMap::CPair *pair = m_mapKnownSpamHashes.PGetFirstAssoc(); pair != NULL; pair = m_mapKnownSpamHashes.PGetNextAssoc(pair)) { + CTag tag((pair->value ? SP_FILEHASHSPAM : SP_FILEHASHNOSPAM), (BYTE*)pair->key.m_key); + tag.WriteNewEd2kTag(file); ++nCount; } - for (POSITION pos = m_mapKnownSpamServerIPs.GetStartPosition(); pos != NULL;) { - uint32 dwIP; - bool bTmp; - m_mapKnownSpamServerIPs.GetNextAssoc(pos, dwIP, bTmp); - CTag tag(SP_FILESERVERIP, dwIP); - tag.WriteNewEd2kTag(&file); + for (const CSpammerIPMap::CPair *pair = m_mapKnownSpamServerIPs.PGetFirstAssoc(); pair != NULL; pair = m_mapKnownSpamServerIPs.PGetNextAssoc(pair)) { + CTag tag(SP_FILESERVERIP, pair->key); //IP + tag.WriteNewEd2kTag(file); ++nCount; } - for (POSITION pos = m_mapKnownSpamSourcesIPs.GetStartPosition(); pos != NULL;) { - uint32 dwIP; - bool bTmp; - m_mapKnownSpamSourcesIPs.GetNextAssoc(pos, dwIP, bTmp); - CTag tag(SP_FILESOURCEIP, dwIP); - tag.WriteNewEd2kTag(&file); + for (const CSpammerIPMap::CPair *pair = m_mapKnownSpamSourcesIPs.PGetFirstAssoc(); pair != NULL; pair = m_mapKnownSpamSourcesIPs.PGetNextAssoc(pair)) { + CTag tag(SP_FILESOURCEIP, pair->key); //IP + tag.WriteNewEd2kTag(file); ++nCount; } - for (POSITION pos = m_aUDPServerRecords.GetStartPosition(); pos != NULL;) { - uint32 dwIP; - UDPServerRecord *pRecord; - m_aUDPServerRecords.GetNextAssoc(pos, dwIP, pRecord); - BYTE abyBuffer[12]; - PokeUInt32(&abyBuffer[0], dwIP); - PokeUInt32(&abyBuffer[4], pRecord->m_nResults); - PokeUInt32(&abyBuffer[8], pRecord->m_nSpamResults); - CTag tag(SP_UDPSERVERSPAMRATIO, sizeof(abyBuffer), abyBuffer); - tag.WriteNewEd2kTag(&file); + for (const CUDPServerRecordMap::CPair *pair = m_mUDPServerRecords.PGetFirstAssoc(); pair != NULL; pair = m_mUDPServerRecords.PGetNextAssoc(pair)) { + const uint32 buf[3] = { pair->key, pair->value->m_nResults, pair->value->m_nSpamResults }; + CTag tag(SP_UDPSERVERSPAMRATIO, sizeof(buf), (const BYTE*)buf); + tag.WriteNewEd2kTag(file); ++nCount; } file.Seek(1ull, CFile::begin); file.WriteUInt32(nCount); file.Close(); + DebugLog(_T("Stored searchspam.met, wrote %u records"), nCount); } catch (CFileException *error) { TCHAR buffer[MAX_CFEXP_ERRORMSG]; GetExceptionMessage(*error, buffer, _countof(buffer)); DebugLogError(_T("Failed to save searchspam.met, %s"), buffer); error->Delete(); - return; } - DebugLog(_T("Stored searchspam.met, wrote %u records"), nCount); } void CSearchList::StoreSearches() @@ -1469,21 +1432,21 @@ void CSearchList::StoreSearches() } return; } - setvbuf(file.m_pStream, NULL, _IOFBF, 16384); - uint16 nCount = 0; + ::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); try { file.WriteUInt8(MET_HEADER_I64TAGS); file.WriteUInt8(STOREDSEARCHES_VERSION); // count how many (if any) open searches we have which are GUI related + uint16 nCount = 0; for (POSITION pos = m_listFileLists.GetHeadPosition(); pos != NULL;) { - SearchListsStruct *pSl = m_listFileLists.GetNext(pos); + const SearchListsStruct *pSl = m_listFileLists.GetNext(pos); nCount += static_cast(theApp.emuledlg->searchwnd->GetSearchParamsBySearchID(pSl->m_nSearchID) != NULL); } file.WriteUInt16(nCount); if (nCount > 0) for (POSITION pos = m_listFileLists.GetHeadPosition(); pos != NULL;) { - SearchListsStruct *pSl = m_listFileLists.GetNext(pos); - SSearchParams *pParams = theApp.emuledlg->searchwnd->GetSearchParamsBySearchID(pSl->m_nSearchID); + const SearchListsStruct *pSl = m_listFileLists.GetNext(pos); + const SSearchParams *pParams = theApp.emuledlg->searchwnd->GetSearchParamsBySearchID(pSl->m_nSearchID); if (pParams != NULL) { pParams->StorePartially(file); uint32 uCount = 0; @@ -1492,22 +1455,21 @@ void CSearchList::StoreSearches() file.WriteUInt32(uCount); for (POSITION pos2 = pSl->m_listSearchFiles.GetHeadPosition(); pos2 != NULL;) { - CSearchFile *f = pSl->m_listSearchFiles.GetNext(pos2); - if (!f->m_flags.nowrite) - f->StoreToFile(file); + CSearchFile *sf = pSl->m_listSearchFiles.GetNext(pos2); + if (!sf->m_flags.nowrite) + sf->StoreToFile(file); } } } file.Close(); + DebugLog(_T("Stored %u open search(es) for restoring on next start"), nCount); } catch (CFileException *error) { TCHAR buffer[MAX_CFEXP_ERRORMSG]; GetExceptionMessage(*error, buffer, _countof(buffer)); DebugLogError(_T("Failed to save %s, %s"), STOREDSEARCHES_FILENAME, buffer); error->Delete(); - return; } - DebugLog(_T("Stored %u open searches for restoring on next start"), nCount); } void CSearchList::LoadSearches() @@ -1526,7 +1488,7 @@ void CSearchList::LoadSearches() } return; } - setvbuf(file.m_pStream, NULL, _IOFBF, 16384); + ::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); try { uint8 header = file.ReadUInt8(); @@ -1547,19 +1509,19 @@ void CSearchList::LoadSearches() pParams->dwSearchID = ++nID; //renumber // create a new tab - const CString &strResultType = pParams->strFileType; + const CString &strResultType(pParams->strFileType); NewSearch(NULL, (strResultType == _T(ED2KFTSTR_PROGRAM) ? CString() : strResultType), pParams); bool bDeleteParams = !theApp.emuledlg->searchwnd->CreateNewTab(pParams, false); if (!bDeleteParams) { - m_foundFilesCount.SetAt(pParams->dwSearchID, 0); - m_foundSourcesCount.SetAt(pParams->dwSearchID, 0); + m_foundFilesCount[pParams->dwSearchID] = 0; + m_foundSourcesCount[pParams->dwSearchID] = 0; } else ASSERT(0); //failed to create tab // fill the list with stored results for (uint32 nFileCount = file.ReadUInt32(); nFileCount-- > 0;) { - CSearchFile *toadd = new CSearchFile(&file, true, pParams->dwSearchID, 0, 0, NULL, pParams->eType == SearchTypeKademlia); + CSearchFile *toadd = new CSearchFile(file, true, pParams->dwSearchID, 0, 0, NULL, pParams->eType == SearchTypeKademlia); AddToList(toadd, pParams->bClientSharedFiles); } if (bDeleteParams) @@ -1570,13 +1532,15 @@ void CSearchList::LoadSearches() Kademlia::CSearchManager::SetNextSearchID(++nID); theApp.emuledlg->searchwnd->SetNextSearchID(0x80000000u + nID); } catch (CFileException *error) { + LPCTSTR sErr; + TCHAR buffer[MAX_CFEXP_ERRORMSG]; if (error->m_cause == CFileException::endOfFile) - DebugLogError(_T("Failed to load %s, corrupt"), STOREDSEARCHES_FILENAME); + sErr = _T("corrupt"); else { - TCHAR buffer[MAX_CFEXP_ERRORMSG]; + sErr = buffer; GetExceptionMessage(*error, buffer, _countof(buffer)); - DebugLogError(_T("Failed to load %s, %s"), STOREDSEARCHES_FILENAME, buffer); } + DebugLogError(_T("Failed to load %s, %s"), STOREDSEARCHES_FILENAME, sErr); error->Delete(); } } \ No newline at end of file diff --git a/srchybrid/SearchList.h b/srchybrid/SearchList.h index 1ec90020..15e926bc 100644 --- a/srchybrid/SearchList.h +++ b/srchybrid/SearchList.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -70,23 +70,19 @@ class CSearchList UINT GetED2KResultCount() const; UINT GetResultCount(uint32 nSearchID) const; void AddResultCount(uint32 nSearchID, const uchar *hash, UINT nCount, bool bSpam); - void SetOutputWnd(CSearchListCtrl *in_wnd) - { - outputwnd = in_wnd; - } + + void SetOutputWnd(CSearchListCtrl *in_wnd) { outputwnd = in_wnd; } void RemoveResults(uint32 nSearchID); void RemoveResult(CSearchFile *todel); void ShowResults(uint32 nSearchID); void GetWebList(CQArray *SearchFileArray, int iSortBy) const; - void AddFileToDownloadByHash(const uchar *hash) - { - AddFileToDownloadByHash(hash, 0); - } + + void AddFileToDownloadByHash(const uchar *hash) { AddFileToDownloadByHash(hash, 0); } void AddFileToDownloadByHash(const uchar *hash, int cat); bool AddToList(CSearchFile *toadd, bool bClientResponse = false, uint32 dwFromUDPServerIP = 0); CSearchFile* GetSearchFileByHash(const uchar *hash) const; - void KademliaSearchKeyword(uint32 searchID, const Kademlia::CUInt128 *pFileID, LPCTSTR name, uint64 size, LPCTSTR type, UINT uKadPublishInfo, CArray &raAICHHashes, CArray &raAICHHashPopularity, SSearchTerm *pQueriedSearchTerm, UINT numProperties, ...); - bool AddNotes(Kademlia::CEntry *entry, const uchar *hash); + void KademliaSearchKeyword(uint32 nSearchID, const Kademlia::CUInt128 *pFileID, LPCTSTR name, uint64 size, LPCTSTR type, UINT uKadPublishInfo, CArray &raAICHHashes, CArray &raAICHHashPopularity, SSearchTerm *pQueriedSearchTerm, UINT numProperties, ...); + bool AddNotes(const Kademlia::CEntry &cEntry, const uchar *hash); void SetNotesSearchStatus(const uchar *pFileHash, bool bSearchRunning); void SentUDPRequestNotification(uint32 nSearchID, uint32 dwServerIP); @@ -102,17 +98,16 @@ class CSearchList void RecalculateSpamRatings(uint32 nSearchID, bool bExpectHigher, bool bExpectLower, bool bUpdate); void SaveSpamFilter(); - UINT GetFoundFiles(uint32 searchID) const + UINT GetFoundFiles(uint32 nSearchID) const { UINT returnVal; - return m_foundFilesCount.Lookup(searchID, returnVal) ? returnVal : 0; + return m_foundFilesCount.Lookup(nSearchID, returnVal) ? returnVal : 0; } -protected: - SearchList* GetSearchListForID(uint32 nSearchID); - uint32 GetSpamFilenameRatings(const CSearchFile *pSearchFile, bool bMarkAsNoSpam); - void LoadSpamFilter(); - +protected: + SearchList* GetSearchListForID(uint32 nSearchID); + uint32 GetSpamFilenameRatings(const CSearchFile *pSearchFile, bool bMarkAsNoSpam); + void LoadSpamFilter(); private: CTypedPtrList m_listFileLists; @@ -121,20 +116,22 @@ class CSearchList CMap m_ReceivedUDPAnswersCount; CMap m_RequestedUDPAnswersCount; CSearchListCtrl *outputwnd; - CString m_strResultFileType; + CString m_strResultFileType; - uint32 m_nCurED2KSearchID; + uint32 m_nCurED2KSearchID; // spam filter + typedef CMap CSpammerIPMap; + typedef CMap CUDPServerRecordMap; CStringArray m_astrSpamCheckCurSearchExp; CStringArray m_astrKnownSpamNames; CStringArray m_astrKnownSimilarSpamNames; - CMap m_mapKnownSpamServerIPs; - CMap m_mapKnownSpamSourcesIPs; + CSpammerIPMap m_mapKnownSpamServerIPs; + CSpammerIPMap m_mapKnownSpamSourcesIPs; CMap m_mapKnownSpamHashes; CArray m_aui64KnownSpamSizes; CArray m_aCurED2KSentRequestsIPs; CArray m_aCurED2KSentReceivedIPs; - CMap m_aUDPServerRecords; + CUDPServerRecordMap m_mUDPServerRecords; bool m_bSpamFilterLoaded; }; \ No newline at end of file diff --git a/srchybrid/SearchListCtrl.cpp b/srchybrid/SearchListCtrl.cpp index 2b77e9fd..01dfea04 100644 --- a/srchybrid/SearchListCtrl.cpp +++ b/srchybrid/SearchListCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -35,7 +35,6 @@ #include "PartFile.h" #include "KnownFileList.h" #include "MenuCmds.h" -#include "OtherFunctions.h" #include "Opcodes.h" #include "Packets.h" #include "WebServices.h" @@ -43,7 +42,6 @@ #include "HighColorTab.hpp" #include "ListViewWalkerPropertySheet.h" #include "UserMsgs.h" -#include "ToolTipCtrlX.h" #include "SearchDlg.h" #include "SearchResultsWnd.h" #include "ServerConnect.h" @@ -74,7 +72,6 @@ class CSearchResultFileDetailSheet : public CListViewWalkerPropertySheet void Localize(); public: CSearchResultFileDetailSheet(CTypedPtrList &paFiles, UINT uInvokePage = 0, CListCtrlItemWalk *pListCtrl = NULL); - virtual ~CSearchResultFileDetailSheet() = default; protected: CMetaDataDlg m_wndMetaData; @@ -207,7 +204,6 @@ CSearchListCtrl::CSearchListCtrl() , m_nResultsID() { SetGeneralPurposeFind(true); - m_tooltip = new CToolTipCtrlX; m_eFileSizeFormat = (EFileSizeFormat)theApp.GetProfileInt(_T("eMule"), _T("SearchResultsFileSizeFormat"), fsizeDefault); SetSkinKey(_T("SearchResultsLv")); } @@ -228,15 +224,15 @@ void CSearchListCtrl::SetAllIcons() ApplyImageList(NULL); m_ImageList.DeleteImageList(); m_ImageList.Create(16, 16, theApp.m_iDfltImageListColorFlags | ILC_MASK, 0, 1); - m_ImageList.Add(CTempIconLoader(_T("EMPTY"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_NotRated"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_Fake"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_Poor"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_Fair"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_Good"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_Excellent"))); - m_ImageList.Add(CTempIconLoader(_T("Collection_Search"))); // rating for comments are searched on kad - m_ImageList.Add(CTempIconLoader(_T("Spam"))); // spam indicator + m_ImageList.Add(CTempIconLoader(_T("EMPTY"))); //0 + m_ImageList.Add(CTempIconLoader(_T("Rating_NotRated"))); //1 + m_ImageList.Add(CTempIconLoader(_T("Rating_Fake"))); //2 + m_ImageList.Add(CTempIconLoader(_T("Rating_Poor"))); //3 + m_ImageList.Add(CTempIconLoader(_T("Rating_Fair"))); //4 + m_ImageList.Add(CTempIconLoader(_T("Rating_Good"))); //5 + m_ImageList.Add(CTempIconLoader(_T("Rating_Excellent"))); //6 + m_ImageList.Add(CTempIconLoader(_T("Collection_Search"))); //7 rating for comments are searched on kad + m_ImageList.Add(CTempIconLoader(_T("Spam"))); //8 spam indicator m_ImageList.SetOverlayImage(m_ImageList.Add(CTempIconLoader(_T("FileCommentsOvl"))), 1); // Apply the image list also to the listview control, even if we use our own 'DrawItem'. // This is needed to give the listview control a chance to initialize the row height. @@ -255,29 +251,29 @@ void CSearchListCtrl::Init(CSearchList *in_searchlist) CToolTipCtrl *tooltip = GetToolTips(); if (tooltip) { - m_tooltip->SetFileIconToolTip(true); - m_tooltip->SubclassWindow(*tooltip); + m_tooltip.SetFileIconToolTip(true); + m_tooltip.SubclassWindow(*tooltip); tooltip->ModifyStyle(0, TTS_NOPREFIX); tooltip->SetDelayTime(TTDT_AUTOPOP, SEC2MS(20)); //tooltip->SetDelayTime(TTDT_INITIAL, SEC2MS(thePrefs.GetToolTipDelay())); } searchlist = in_searchlist; - InsertColumn(0, GetResString(IDS_DL_FILENAME), LVCFMT_LEFT, DFLT_FILENAME_COL_WIDTH); - InsertColumn(1, GetResString(IDS_DL_SIZE), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH); - InsertColumn(2, GetResString(IDS_SEARCHAVAIL) + (thePrefs.IsExtControlsEnabled() ? _T(" (") + GetResString(IDS_DL_SOURCES) + _T(')') : CString()), LVCFMT_RIGHT, 60); - InsertColumn(3, GetResString(IDS_COMPLSOURCES), LVCFMT_RIGHT, 70); - InsertColumn(4, GetResString(IDS_TYPE), LVCFMT_LEFT, DFLT_FILETYPE_COL_WIDTH); - InsertColumn(5, GetResString(IDS_FILEID), LVCFMT_LEFT, DFLT_HASH_COL_WIDTH, -1, true); - InsertColumn(6, GetResString(IDS_ARTIST), LVCFMT_LEFT, DFLT_ARTIST_COL_WIDTH); - InsertColumn(7, GetResString(IDS_ALBUM), LVCFMT_LEFT, DFLT_ALBUM_COL_WIDTH); - InsertColumn(8, GetResString(IDS_TITLE), LVCFMT_LEFT, DFLT_TITLE_COL_WIDTH); - InsertColumn(9, GetResString(IDS_LENGTH), LVCFMT_RIGHT, DFLT_LENGTH_COL_WIDTH); - InsertColumn(10, GetResString(IDS_BITRATE), LVCFMT_RIGHT, DFLT_BITRATE_COL_WIDTH); - InsertColumn(11, GetResString(IDS_CODEC), LVCFMT_LEFT, DFLT_CODEC_COL_WIDTH); - InsertColumn(12, GetResString(IDS_FOLDER), LVCFMT_LEFT, DFLT_FOLDER_COL_WIDTH, -1, true); - InsertColumn(13, GetResString(IDS_KNOWN), LVCFMT_LEFT, 50); - InsertColumn(14, GetResString(IDS_AICHHASH), LVCFMT_LEFT, DFLT_HASH_COL_WIDTH, -1, true); + InsertColumn(0, _T(""), LVCFMT_LEFT, DFLT_FILENAME_COL_WIDTH); //IDS_DL_FILENAME + InsertColumn(1, _T(""), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH); //IDS_DL_SIZE + InsertColumn(2, _T(""), LVCFMT_RIGHT, 60); //IDS_SEARCHAVAIL + InsertColumn(3, _T(""), LVCFMT_RIGHT, 70); //IDS_COMPLSOURCES + InsertColumn(4, _T(""), LVCFMT_LEFT, DFLT_FILETYPE_COL_WIDTH); //IDS_TYPE + InsertColumn(5, _T(""), LVCFMT_LEFT, DFLT_HASH_COL_WIDTH, -1, true); //IDS_FILEID + InsertColumn(6, _T(""), LVCFMT_LEFT, DFLT_ARTIST_COL_WIDTH); //IDS_ARTIST + InsertColumn(7, _T(""), LVCFMT_LEFT, DFLT_ALBUM_COL_WIDTH); //IDS_ALBUM + InsertColumn(8, _T(""), LVCFMT_LEFT, DFLT_TITLE_COL_WIDTH); //IDS_TITLE + InsertColumn(9, _T(""), LVCFMT_RIGHT, DFLT_LENGTH_COL_WIDTH); //IDS_LENGTH + InsertColumn(10, _T(""), LVCFMT_RIGHT, DFLT_BITRATE_COL_WIDTH); //IDS_BITRATE + InsertColumn(11, _T(""), LVCFMT_LEFT, DFLT_CODEC_COL_WIDTH); //IDS_CODEC + InsertColumn(12, _T(""), LVCFMT_LEFT, DFLT_FOLDER_COL_WIDTH, -1, true); //IDS_FOLDER + InsertColumn(13, _T(""), LVCFMT_LEFT, 50); //IDS_KNOWN + InsertColumn(14, _T(""), LVCFMT_LEFT, DFLT_HASH_COL_WIDTH, -1, true); //IDS_AICHHASH SetAllIcons(); @@ -302,9 +298,9 @@ void CSearchListCtrl::Init(CSearchList *in_searchlist) SetHighlightColors(); // Barry - Use preferred sort order from preferences - if (GetSortItem() != -1) {// don't force a sorting if '-1' is specified, so we can better see how the search results are arriving + if (GetSortItem() != -1) {// don't force sorting if '-1' is specified; we can see better how the search results are arriving SetSortArrow(); - SortItems(SortProc, GetSortItem() + (GetSortAscending() ? 0 : 100)); + SortItems(SortProc, MAKELONG(GetSortItem(), !GetSortAscending())); } } @@ -316,32 +312,26 @@ CSearchListCtrl::~CSearchListCtrl() m_mapSortSelectionStates.GetNextAssoc(pos, nKey, pValue); delete pValue; } - // m_mapSortSelectionStates.RemoveAll(); -- will be called in destructor - delete m_tooltip; } void CSearchListCtrl::Localize() { - static const UINT ids[15] = + static const UINT uids[15] = { - IDS_DL_FILENAME, IDS_DL_SIZE, IDS_SEARCHAVAIL, IDS_COMPLSOURCES, IDS_TYPE + IDS_DL_FILENAME, IDS_DL_SIZE, 0/*IDS_SEARCHAVAIL*/, IDS_COMPLSOURCES, IDS_TYPE , IDS_FILEID, IDS_ARTIST, IDS_ALBUM, IDS_TITLE, IDS_LENGTH , IDS_BITRATE, IDS_CODEC, IDS_FOLDER, IDS_KNOWN, IDS_AICHHASH }; - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); + LocaliseHeaderCtrl(uids, _countof(uids)); + HDITEM hdi; hdi.mask = HDI_TEXT; - CString strRes; - - for (int icol = pHeaderCtrl->GetItemCount(); --icol >= 0;) { - strRes = GetResString(ids[icol]); - if (thePrefs.IsExtControlsEnabled() && icol == 2) - strRes.AppendFormat(_T(" (%s)"), (LPCTSTR)GetResString(IDS_DL_SOURCES)); - - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(icol, &hdi); - } + CString strRes(GetResString(IDS_SEARCHAVAIL)); + if (thePrefs.IsExtControlsEnabled()) + strRes.AppendFormat(_T(" (%s)"), (LPCTSTR)GetResString(IDS_DL_SOURCES)); //modify "availability" header + hdi.pszText = const_cast((LPCTSTR)strRes); + GetHeaderCtrl()->SetItem(2, &hdi); CreateMenus(); } @@ -349,36 +339,32 @@ void CSearchListCtrl::Localize() void CSearchListCtrl::AddResult(const CSearchFile *toshow) { bool bFilterActive = !theApp.emuledlg->searchwnd->m_pwndResults->m_astrFilter.IsEmpty(); - bool bItemFiltered = bFilterActive ? IsFilteredItem(toshow) : false; + bool bItemFiltered = bFilterActive && IsFilteredOut(toshow); // update tab-counter for the given searchfile CClosableTabCtrl &searchselect = theApp.emuledlg->searchwnd->GetSearchSelector(); - int iTabItems = searchselect.GetItemCount(); - if (iTabItems > 0) { - TCITEM ti; - ti.mask = TCIF_PARAM; - for (int iItem = 0; iItem < iTabItems; ++iItem) { - if (searchselect.GetItem(iItem, &ti) && ti.lParam != NULL) { - const SSearchParams *pSearchParams = reinterpret_cast(ti.lParam); - if (pSearchParams->dwSearchID == toshow->GetSearchID()) { - UINT iAvailResults = searchlist->GetFoundFiles(toshow->GetSearchID()); - CString strTabLabel; - if (bFilterActive) { - int iFilteredResult = GetItemCount() + static_cast(!bItemFiltered); - strTabLabel.Format(_T("%s (%i/%u)"), (LPCTSTR)pSearchParams->strSearchTitle, iFilteredResult, iAvailResults); - } else - strTabLabel.Format(_T("%s (%u)"), (LPCTSTR)pSearchParams->strSearchTitle, iAvailResults); - strTabLabel.Replace(_T("&"), _T("&&")); - ti.pszText = const_cast((LPCTSTR)strTabLabel); - ti.mask = TCIF_TEXT; - searchselect.SetItem(iItem, &ti); - if (searchselect.GetCurSel() != iItem) - searchselect.HighlightItem(iItem); - break; - } + TCITEM ti; + ti.mask = TCIF_PARAM; + for (int iItem = searchselect.GetItemCount(); --iItem >= 0;) + if (searchselect.GetItem(iItem, &ti) && ti.lParam != NULL) { + const SSearchParams* pSearchParams = reinterpret_cast(ti.lParam); + if (pSearchParams->dwSearchID == toshow->GetSearchID()) { + UINT iAvailResults = searchlist->GetFoundFiles(toshow->GetSearchID()); + CString strTabLabel(pSearchParams->strSearchTitle); + if (bFilterActive) { + int iFilteredResult = GetItemCount() + static_cast(!bItemFiltered); + strTabLabel.AppendFormat(_T(" (%i/%u)"), iFilteredResult, iAvailResults); + } else + strTabLabel.AppendFormat(_T(" (%u)"), iAvailResults); + DupAmpersand(strTabLabel); + ti.pszText = const_cast((LPCTSTR)strTabLabel); + ti.mask = TCIF_TEXT; + searchselect.SetItem(iItem, &ti); + if (searchselect.GetCurSel() != iItem) + searchselect.HighlightItem(iItem); + break; } } - } if (bItemFiltered || toshow->GetSearchID() != m_nResultsID) return; @@ -404,9 +390,9 @@ void CSearchListCtrl::UpdateSources(const CSearchFile *toupdate) find.lParam = (LPARAM)toupdate; int iItem = FindItem(&find); if (iItem >= 0) { - CString strBuffer; uint32 nSources = toupdate->GetSourceCount(); int iClients = toupdate->GetClientsCount(); + CString strBuffer; if (thePrefs.IsExtControlsEnabled() && iClients > 0) strBuffer.Format(_T("%u (%i)"), nSources, iClients); else @@ -416,7 +402,7 @@ void CSearchListCtrl::UpdateSources(const CSearchFile *toupdate) if (toupdate->IsListExpanded()) { const SearchList *list = theApp.searchlist->GetSearchListForID(toupdate->GetSearchID()); - for (POSITION pos = list->GetHeadPosition(); pos != NULL; ) { + for (POSITION pos = list->GetHeadPosition(); pos != NULL;) { const CSearchFile *cur_file = list->GetNext(pos); if (cur_file->GetListParent() == toupdate) { LVFINDINFO find1; @@ -436,7 +422,7 @@ void CSearchListCtrl::UpdateSources(const CSearchFile *toupdate) void CSearchListCtrl::UpdateSearch(CSearchFile *toupdate) { - if (!theApp.IsClosing() && toupdate) { + if (toupdate && !theApp.IsClosing()) { LVFINDINFO find; find.flags = LVFI_PARAM; find.lParam = (LPARAM)toupdate; @@ -520,19 +506,19 @@ void CSearchListCtrl::ShowResults(uint32 nResultsID) pCurState->m_nSortItem = GetSortItem(); pCurState->m_bSortAscending = GetSortAscending(); pCurState->m_nScrollPosition = GetTopIndex(); - m_mapSortSelectionStates.SetAt(m_nResultsID, pCurState); + m_mapSortSelectionStates[m_nResultsID] = pCurState; } DeleteAllItems(); // recover stored state - CSortSelectionState *pNewState = NULL; + CSortSelectionState *pNewState; if (nResultsID != 0 && nResultsID != m_nResultsID && m_mapSortSelectionStates.Lookup(nResultsID, pNewState)) { m_mapSortSelectionStates.RemoveKey(nResultsID); // sort order SetSortArrow(pNewState->m_nSortItem, pNewState->m_bSortAscending); - SortItems(SortProc, pNewState->m_nSortItem + (pNewState->m_bSortAscending ? 0 : 100)); + SortItems(SortProc, MAKELONG(pNewState->m_nSortItem, !pNewState->m_bSortAscending)); // fill in the items m_nResultsID = nResultsID; searchlist->ShowResults(m_nResultsID); @@ -540,11 +526,11 @@ void CSearchListCtrl::ShowResults(uint32 nResultsID) for (int i = (int)pNewState->m_aSelectedItems.GetCount(); --i >= 0;) SetItemState(pNewState->m_aSelectedItems[i], LVIS_SELECTED, LVIS_SELECTED); - POINT Point; if (pNewState->m_nScrollPosition > 0) { + POINT Point; GetItemPosition(pNewState->m_nScrollPosition - 1, &Point); Point.x = 0; - Scroll(CSize(Point)); + Scroll((CSize)Point); } delete pNewState; } else { @@ -555,12 +541,10 @@ void CSearchListCtrl::ShowResults(uint32 nResultsID) void CSearchListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) { - NMLISTVIEW *pNMListView = reinterpret_cast(pNMHDR); + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); bool sortAscending; - if (GetSortItem() == pNMListView->iSubItem) - sortAscending = !GetSortAscending(); - else - switch (pNMListView->iSubItem) { + if (GetSortItem() != pNMLV->iSubItem) + switch (pNMLV->iSubItem) { case 2: // Availability case 3: // Complete Sources sortAscending = false; @@ -568,12 +552,13 @@ void CSearchListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) default: sortAscending = true; } + else + sortAscending = !GetSortAscending(); // Sort table - UpdateSortHistory(pNMListView->iSubItem + (sortAscending ? 0 : 100)); - SetSortArrow(pNMListView->iSubItem, sortAscending); - SortItems(SortProc, pNMListView->iSubItem + (sortAscending ? 0 : 100)); - + UpdateSortHistory(MAKELONG(pNMLV->iSubItem, !sortAscending)); + SetSortArrow(pNMLV->iSubItem, sortAscending); + SortItems(SortProc, MAKELONG(pNMLV->iSubItem, !sortAscending)); *pResult = 0; } @@ -581,65 +566,59 @@ int CALLBACK CSearchListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lP { const CSearchFile *item1 = reinterpret_cast(lParam1); const CSearchFile *item2 = reinterpret_cast(lParam2); - int orgSort = (int)lParamSort; - int sortMod = 1; - if (lParamSort >= 100) { - sortMod = -1; - lParamSort -= 100; - } + bool bDirect = !HIWORD(lParamSort); - int comp; + int iResult; if (item1->GetListParent() == NULL && item2->GetListParent() != NULL) { if (item1 == item2->GetListParent()) return -1; - comp = Compare(item1, item2->m_list_parent, lParamSort, sortMod == 1) * sortMod; + iResult = Compare(item1, item2->m_list_parent, lParamSort, bDirect); + if (!bDirect) + iResult = -iResult; } else if (item2->GetListParent() == NULL && item1->GetListParent() != NULL) { if (item1->m_list_parent == item2) return 1; - comp = Compare(item1->GetListParent(), item2, lParamSort, sortMod == 1) * sortMod; - } else if (item1->GetListParent() == NULL) - comp = Compare(item1, item2, lParamSort, sortMod == 1) * sortMod; - else { - comp = Compare(item1->GetListParent(), item2->GetListParent(), lParamSort, sortMod == 1); - if (comp != 0) - return sortMod * comp; - - if ((item1->GetListParent() == NULL && item2->GetListParent() != NULL) || (item2->GetListParent() == NULL && item1->GetListParent() != NULL)) { - if (item1->GetListParent() == NULL) - return -1; - return 1; - } - comp = CompareChild(item1, item2, lParamSort); + iResult = Compare(item1->GetListParent(), item2, lParamSort, bDirect); + if (!bDirect) + iResult = -iResult; + } else if (item1->GetListParent() == NULL) { + iResult = Compare(item1, item2, lParamSort, bDirect); + if (!bDirect) + iResult = -iResult; + } else { + iResult = Compare(item1->GetListParent(), item2->GetListParent(), lParamSort, bDirect); + if (iResult != 0) + return bDirect ? iResult : -iResult; + + if ((item1->GetListParent() == NULL && item2->GetListParent() != NULL) || (item2->GetListParent() == NULL && item1->GetListParent() != NULL)) + return item1->GetListParent() ? 1 : -1; + iResult = CompareChild(item1, item2, lParamSort); } - //call secondary sort order, if this one results in equal - if (comp == 0) { - int dwNextSort = theApp.emuledlg->searchwnd->m_pwndResults->searchlistctrl.GetNextSortOrder(orgSort); - if (dwNextSort != -1) - comp = SortProc(lParam1, lParam2, dwNextSort); + //call secondary sort order, if the first one resulted as equal + if (iResult == 0) { + LPARAM iNextSort = theApp.emuledlg->searchwnd->m_pwndResults->searchlistctrl.GetNextSortOrder(lParamSort); + if (iNextSort != -1) + iResult = SortProc(lParam1, lParam2, iNextSort); } - return comp; + return iResult; } int CSearchListCtrl::CompareChild(const CSearchFile *item1, const CSearchFile *item2, LPARAM lParamSort) { - LPARAM iColumn = lParamSort >= 100 ? lParamSort - 100 : lParamSort; - int iResult = 0; - switch (iColumn) { - case 0: //filename + int iResult; + switch (LOWORD(lParamSort)) { + case 0: //filename iResult = CompareLocaleStringNoCase(item1->GetFileName(), item2->GetFileName()); break; case 14: // AICH Hash iResult = CompareAICHHash(item1->GetFileIdentifierC(), item2->GetFileIdentifierC(), true); break; - default: - // always sort by descending availability + default: // always sort by descending availability iResult = -CompareUnsigned(item1->GetSourceCount(), item2->GetSourceCount()); } - if (lParamSort >= 100) - return -iResult; - return iResult; + return HIWORD(lParamSort) ? -iResult : iResult; } int CSearchListCtrl::Compare(const CSearchFile *item1, const CSearchFile *item2, LPARAM lParamSort, bool bSortAscending) @@ -653,11 +632,11 @@ int CSearchListCtrl::Compare(const CSearchFile *item1, const CSearchFile *item2, } } - switch (lParamSort) { + switch (LOWORD(lParamSort)) { case 0: //filename asc return CompareLocaleStringNoCase(item1->GetFileName(), item2->GetFileName()); case 1: //size asc - return CompareUnsigned64(item1->GetFileSize(), item2->GetFileSize()); + return CompareUnsigned(item1->GetFileSize(), item2->GetFileSize()); case 2: //sources asc return CompareUnsigned(item1->GetSourceCount(), item2->GetSourceCount()); case 3: // complete sources asc @@ -670,8 +649,8 @@ int CSearchListCtrl::Compare(const CSearchFile *item1, const CSearchFile *item2, if (iResult) return iResult; // the types are equal, sub-sort by extension - LPCTSTR pszExt1 = PathFindExtension(item1->GetFileName()); - LPCTSTR pszExt2 = PathFindExtension(item2->GetFileName()); + LPCTSTR pszExt1 = ::PathFindExtension(item1->GetFileName()); + LPCTSTR pszExt2 = ::PathFindExtension(item2->GetFileName()); if (!*pszExt1 ^ !*pszExt2) return *pszExt1 ? -1 : 1; return *pszExt1 ? _tcsicmp(pszExt1, pszExt2) : 0; @@ -710,20 +689,18 @@ void CSearchListCtrl::OnContextMenu(CWnd*, CPoint point) const CSearchFile *pFile = reinterpret_cast(GetItemData(GetNextSelectedItem(pos))); if (pFile) { ++iSelected; - if (pFile->IsPreviewPossible()) - ++iToPreview; - if (!theApp.downloadqueue->IsFileExisting(pFile->GetFileHash(), false)) - ++iToDownload; + iToPreview += static_cast(pFile->IsPreviewPossible()); + iToDownload += static_cast(!theApp.downloadqueue->IsFileExisting(pFile->GetFileHash(), false)); if (!pFile->IsConsideredSpam()) bContainsNotSpamFile = true; } } m_SearchFileMenu.EnableMenuItem(MP_RESUME, iToDownload > 0 ? MF_ENABLED : MF_GRAYED); - if (thePrefs.IsExtControlsEnabled()) + if (thePrefs.IsExtControlsEnabled()) { m_SearchFileMenu.EnableMenuItem(MP_RESUMEPAUSED, iToDownload > 0 ? MF_ENABLED : MF_GRAYED); - if (thePrefs.IsExtControlsEnabled()) m_SearchFileMenu.EnableMenuItem(MP_DETAIL, iSelected == 1 ? MF_ENABLED : MF_GRAYED); + } m_SearchFileMenu.EnableMenuItem(MP_CMT, iSelected > 0 ? MF_ENABLED : MF_GRAYED); m_SearchFileMenu.EnableMenuItem(MP_GETED2KLINK, iSelected > 0 ? MF_ENABLED : MF_GRAYED); m_SearchFileMenu.EnableMenuItem(MP_GETHTMLED2KLINK, iSelected > 0 ? MF_ENABLED : MF_GRAYED); @@ -831,14 +808,14 @@ BOOL CSearchListCtrl::OnCommand(WPARAM wParam, LPARAM) case MPG_DELETE: { CWaitCursor curWait; - SetRedraw(FALSE); + SetRedraw(false); for (POSITION pos = selectedList.GetHeadPosition(); pos != NULL;) { file = selectedList.GetNext(pos); HideSources(file); theApp.searchlist->RemoveResult(file); } AutoSelectItem(); - SetRedraw(TRUE); + SetRedraw(true); } return TRUE; case MP_DETAIL: @@ -859,7 +836,7 @@ BOOL CSearchListCtrl::OnCommand(WPARAM wParam, LPARAM) if (!theApp.clientlist->AttachToAlreadyKnown(&newclient, NULL)) theApp.clientlist->AddClient(newclient); - newclient->SendPreviewRequest(file); + newclient->SendPreviewRequest(*file); // add to res - later AddLogLine(true, _T("Preview Requested - Please wait")); } @@ -872,7 +849,7 @@ BOOL CSearchListCtrl::OnCommand(WPARAM wParam, LPARAM) case MP_MARKASSPAM: { CWaitCursor curWait; - SetRedraw(FALSE); + SetRedraw(false); bool bContainsNotSpamFile = false; for (POSITION pos = selectedList.GetHeadPosition(); pos != NULL;) { file = selectedList.GetNext(pos); @@ -890,7 +867,7 @@ BOOL CSearchListCtrl::OnCommand(WPARAM wParam, LPARAM) theApp.searchlist->MarkFileAsSpam(file, false, true); } theApp.searchlist->RecalculateSpamRatings(file->GetSearchID(), bContainsNotSpamFile, !bContainsNotSpamFile, true); - SetRedraw(TRUE); + SetRedraw(true); } return TRUE; default: @@ -988,9 +965,9 @@ void CSearchListCtrl::OnLvnGetInfoTip(LPNMHDR pNMHDR, LRESULT *pResult) if (GetSelectedCount() <= 1) { const CSearchFile *file = (CSearchFile*)GetItemData(pGetInfoTip->iItem); if (file && pGetInfoTip->pszText && pGetInfoTip->cchTextMax > 0) { - CString strInfo, strHead; - strHead.Format(_T("%s\n") _T("%s %s\n") _T("%s %s\n\n") - , (LPCTSTR)file->GetFileName() + CString strInfo; + CString strHead(file->GetFileName()); + strHead.AppendFormat(_T("\n") _T("%s %s\n") _T("%s %s\n\n") , (LPCTSTR)GetResString(IDS_FD_HASH), (LPCTSTR)md4str(file->GetFileHash()) , (LPCTSTR)GetResString(IDS_FD_SIZE), (LPCTSTR)CastItoXBytes((uint64)file->GetFileSize())); @@ -1000,12 +977,12 @@ void CSearchListCtrl::OnLvnGetInfoTip(LPNMHDR pNMHDR, LRESULT *pResult) if (tag) { CString strTag; switch (tag->GetNameID()) { - /*case FT_FILENAME: - strTag.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_SW_NAME), (LPCTSTR)tag->GetStr()); - break; - case FT_FILESIZE: - strTag.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_DL_SIZE), FormatFileSize(tag->GetInt64())); - break;*/ + /*case FT_FILENAME: + strTag.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_SW_NAME), (LPCTSTR)tag->GetStr()); + break; + case FT_FILESIZE: + strTag.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_DL_SIZE), FormatFileSize(tag->GetInt64())); + break;*/ case FT_FILETYPE: strTag.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_TYPE), (LPCTSTR)tag->GetStr()); break; @@ -1016,23 +993,34 @@ void CSearchListCtrl::OnLvnGetInfoTip(LPNMHDR pNMHDR, LRESULT *pResult) strTag.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_SEARCHAVAIL), file->GetSourceCount()); break; case 0x13: // remote client's upload file priority (tested with Hybrid 0.47) - if (tag->GetInt() == 0) - strTag.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_PRIORITY), (LPCTSTR)GetResString(IDS_PRIONORMAL)); - else if (tag->GetInt() == 2) - strTag.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_PRIORITY), (LPCTSTR)GetResString(IDS_PRIOHIGH)); - else if (tag->GetInt() == (UINT)-2) - strTag.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_PRIORITY), (LPCTSTR)GetResString(IDS_PRIOLOW)); + { + strTag.Format(_T("%s: "), (LPCTSTR)GetResString(IDS_PRIORITY)); + UINT uid = 0; + switch ((int)tag->GetInt()) { + case 0: + uid = IDS_PRIONORMAL; + break; + case 2: + uid = IDS_PRIOHIGH; + break; + case -2: + uid = IDS_PRIOLOW; + break; #ifdef _DEBUG - else - strTag.Format(_T("%s: %u (***Unknown***)"), (LPCTSTR)GetResString(IDS_PRIORITY), tag->GetInt()); + default: + strTag.AppendFormat(_T("%u (***Unknown***)"), tag->GetInt()); #endif + } + if (uid) + strTag += GetResString(IDS_PRIORITY); + } break; default: { bool bSkipTag = false; if (tag->GetNameID() == FT_FILENAME || tag->GetNameID() == FT_FILESIZE) bSkipTag = true; - else if (tag->GetName()[0]) { + else if (tag->HasName()) { strTag.Format(_T("%hs: "), tag->GetName()); strTag.SetAt(0, _totupper(strTag[0])); } else { @@ -1043,18 +1031,16 @@ void CSearchListCtrl::OnLvnGetInfoTip(LPNMHDR pNMHDR, LRESULT *pResult) strTag.Format(_T("Unknown tag #%02X: "), tag->GetNameID()); #endif break; - } else - strTag = strTagName + _T(": "); + } + strTag.Format(_T("%s: "), (LPCTSTR)strTagName); } if (!bSkipTag) { if (tag->IsStr()) strTag += tag->GetStr(); else if (tag->IsInt()) { - if (tag->GetNameID() == FT_MEDIA_LENGTH) { - CString strTemp; - SecToTimeLength(tag->GetInt(), strTemp); - strTag += strTemp; - } else + if (tag->GetNameID() == FT_MEDIA_LENGTH) + strTag += SecToTimeLength(tag->GetInt()); + else strTag.AppendFormat(_T("%u"), tag->GetInt()); } else if (tag->IsFloat()) strTag.AppendFormat(_T("%f"), tag->GetFloat()); @@ -1122,7 +1108,7 @@ void CSearchListCtrl::OnLvnGetInfoTip(LPNMHDR pNMHDR, LRESULT *pResult) uint32 uServerIP = aServers[i].m_nIP; CString strServer; if (i == 0) - strServer.Format(_T("Servers")); + strServer = _T("Servers"); strServer.AppendFormat(_T(": %u.%u.%u.%u:%u Avail: %u"), (uint8)uServerIP, (uint8)(uServerIP >> 8), (uint8)(uServerIP >> 16), (uint8)(uServerIP >> 24), aServers[i].m_nPort, aServers[i].m_uAvail); if (!strInfo.IsEmpty()) @@ -1133,7 +1119,7 @@ void CSearchListCtrl::OnLvnGetInfoTip(LPNMHDR pNMHDR, LRESULT *pResult) } } #endif - strInfo = strHead + strInfo; + strInfo.Insert(0, strHead); strInfo += TOOLTIP_AUTOFORMAT_SUFFIX_CH; _tcsncpy(pGetInfoTip->pszText, strInfo, pGetInfoTip->cchTextMax); pGetInfoTip->pszText[pGetInfoTip->cchTextMax - 1] = _T('\0'); @@ -1150,9 +1136,9 @@ void CSearchListCtrl::OnLvnGetInfoTip(LPNMHDR pNMHDR, LRESULT *pResult) } if (iSelected > 0) { - CString strInfo; - strInfo.Format(_T("%s: %i\r\n%s: %s%c") - , (LPCTSTR)GetResString(IDS_FILES), iSelected + CString strInfo(GetResString(IDS_FILES)); + strInfo.AppendFormat(_T(": %i\r\n%s: %s%c") + , iSelected , (LPCTSTR)GetResString(IDS_DL_SIZE) , (LPCTSTR)FormatFileSize(ulTotalSize) , TOOLTIP_AUTOFORMAT_SUFFIX_CH @@ -1192,16 +1178,16 @@ void CSearchListCtrl::ExpandCollapseItem(int iItem, int iAction) return; // Go through the whole list to find out the sources for this file - SetRedraw(FALSE); + SetRedraw(false); const SearchList *list = theApp.searchlist->GetSearchListForID(searchfile->GetSearchID()); - for (POSITION pos = list->GetHeadPosition(); pos != NULL; ) { + for (POSITION pos = list->GetHeadPosition(); pos != NULL;) { const CSearchFile *cur_file = list->GetNext(pos); if (cur_file->GetListParent() == searchfile) { searchfile->SetListExpanded(true); InsertItem(LVIF_PARAM | LVIF_TEXT, iItem + 1, cur_file->GetFileName(), 0, 0, 0, (LPARAM)cur_file); } } - SetRedraw(TRUE); + SetRedraw(true); } } else { if (iAction == EXPAND_COLLAPSE || iAction == COLLAPSE_ONLY) { @@ -1218,12 +1204,12 @@ void CSearchListCtrl::ExpandCollapseItem(int iItem, int iAction) void CSearchListCtrl::HideSources(CSearchFile *toCollapse) { - SetRedraw(FALSE); + SetRedraw(false); for (int i = GetItemCount(); --i >= 0;) if (reinterpret_cast(GetItemData(i))->GetListParent() == toCollapse) DeleteItem(i); toCollapse->SetListExpanded(false); - SetRedraw(TRUE); + SetRedraw(true); } void CSearchListCtrl::OnNmClick(LPNMHDR pNMHDR, LRESULT*) @@ -1261,123 +1247,86 @@ void CSearchListCtrl::OnNmDblClk(LPNMHDR, LRESULT*) void CSearchListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { - if (theApp.IsClosing()) - return; - if (!lpDrawItemStruct->itemData) + if (!lpDrawItemStruct->itemData || theApp.IsClosing()) return; - CMemoryDC dc(CDC::FromHandle(lpDrawItemStruct->hDC), &lpDrawItemStruct->rcItem); + CRect rcItem(lpDrawItemStruct->rcItem); + CMemoryDC dc(CDC::FromHandle(lpDrawItemStruct->hDC), rcItem); BOOL bCtrlFocused; InitItemMemDC(dc, lpDrawItemStruct, bCtrlFocused); - CRect rcItem(lpDrawItemStruct->rcItem); - CRect rcClient; + RECT rcClient; GetClientRect(&rcClient); CSearchFile *content = reinterpret_cast(lpDrawItemStruct->itemData); if (!g_bLowColorDesktop || (lpDrawItemStruct->itemState & ODS_SELECTED) == 0) dc.SetTextColor(GetSearchItemColor(content)); - BOOL notLast = lpDrawItemStruct->itemID + 1 != (UINT)GetItemCount(); - BOOL notFirst = lpDrawItemStruct->itemID != 0; + bool isChild = (content->GetListParent() != NULL); + bool notLast = (lpDrawItemStruct->itemID + 1 != (UINT)GetItemCount()); + bool notFirst = (lpDrawItemStruct->itemID != 0); int tree_start = 0; int tree_end = 0; - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); + const CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); int iCount = pHeaderCtrl->GetItemCount(); + LONG itemLeft = rcItem.left; rcItem.right = rcItem.left - sm_iLabelOffset; rcItem.left += sm_iIconOffset; // icon - int iIndent = (content->GetListParent() != NULL) ? 8 : 0; // indent child items - int iIconPosY = (rcItem.Height() > theApp.GetSmallSytemIconSize().cy) ? ((rcItem.Height() - theApp.GetSmallSytemIconSize().cy) / 2) : 0; - - // spam indicator takes the place of commentsrating icon + LONG iIndent = isChild ? 8 : 0; // indent child items + LONG iIconY = max((rcItem.Height() - theApp.GetSmallSytemIconSize().cy - 1) / 2, 0); + const POINT point = { itemLeft + iIndent + TREE_WIDTH + 18, rcItem.top + iIconY }; + // spam indicator takes the place of comments & rating icon + int iImage; if (thePrefs.IsSearchSpamFilterEnabled() && content->IsConsideredSpam()) - m_ImageList.Draw(dc, 8, CPoint(rcItem.left + iIndent + TREE_WIDTH + 18, rcItem.top + iIconPosY), ILD_NORMAL); + iImage = 8; else if (thePrefs.ShowRatingIndicator() && (content->HasComment() || content->HasRating() || content->IsKadCommentSearchRunning())) - m_ImageList.Draw(dc, content->UserRating(true) + 1, CPoint(rcItem.left + iIndent + TREE_WIDTH + 18, rcItem.top + iIconPosY), ILD_NORMAL); - - int iImage = theApp.GetFileTypeSystemImageIdx(content->GetFileName()); - ::ImageList_Draw(theApp.GetSystemImageList(), iImage, dc, rcItem.left + iIndent + TREE_WIDTH, rcItem.top + iIconPosY, ILD_TRANSPARENT); - - // Parent entries - if (content->GetListParent() == NULL) { - for (int iCurrent = 0; iCurrent < iCount; ++iCurrent) { - int iColumn = pHeaderCtrl->OrderToIndex(iCurrent); - if (!IsColumnHidden(iColumn)) { - UINT uDrawTextAlignment; - int iColumnWidth = GetColumnWidth(iColumn, uDrawTextAlignment); - if (iColumn == 0) { - int iNextLeft = rcItem.left + iColumnWidth; - int iNextRight = rcItem.right + iColumnWidth; - - //set up tree vars - rcItem.left = rcItem.right + sm_iLabelOffset; - rcItem.right = rcItem.left + min(8, iColumnWidth); - tree_start = rcItem.left + 1; - tree_end = rcItem.right; - - //normal column stuff - rcItem.left = rcItem.right + 1; - rcItem.right = tree_start + iColumnWidth - sm_iLabelOffset; - if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) - DrawSourceParent(dc, 0, &rcItem, uDrawTextAlignment, content); - rcItem.left = iNextLeft + sm_iLabelOffset; - rcItem.right = iNextRight - sm_iSubItemInset; - } else { - rcItem.right += iColumnWidth; - if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) - DrawSourceParent(dc, iColumn, &rcItem, uDrawTextAlignment, content); - rcItem.left += iColumnWidth; - } - } - } - } else { - for (int iCurrent = 0; iCurrent < iCount; ++iCurrent) { - int iColumn = pHeaderCtrl->OrderToIndex(iCurrent); - if (!IsColumnHidden(iColumn)) { - UINT uDrawTextAlignment; - int iColumnWidth = GetColumnWidth(iColumn, uDrawTextAlignment); - if (iColumn == 0) { - int iNextLeft = rcItem.left + iColumnWidth; - int iNextRight = rcItem.right + iColumnWidth; - - //set up tree vars - rcItem.left = rcItem.right + sm_iLabelOffset; - rcItem.right = rcItem.left + min(8, iColumnWidth); - tree_start = rcItem.left + 1; - tree_end = rcItem.right; - - //normal column stuff - rcItem.left = rcItem.right + 1; - rcItem.right = tree_start + iColumnWidth - sm_iLabelOffset; - if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) - DrawSourceChild(dc, 0, &rcItem, uDrawTextAlignment, content); - rcItem.left = iNextLeft; - rcItem.right = iNextRight; - rcItem.left += sm_iLabelOffset; - rcItem.right -= sm_iSubItemInset; - } else { - rcItem.right += iColumnWidth; - if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) - DrawSourceChild(dc, iColumn, &rcItem, uDrawTextAlignment, content); - rcItem.left += iColumnWidth; - } - } + iImage = content->UserRating(true) + 1; + else + iImage = 0; + if (iImage) + m_ImageList.Draw(dc, iImage, point, ILD_NORMAL); + + iImage = theApp.GetFileTypeSystemImageIdx(content->GetFileName()); + ::ImageList_Draw(theApp.GetSystemImageList(), iImage, dc, point.x - 18, point.y, ILD_TRANSPARENT); + + for (int iCurrent = 0; iCurrent < iCount; ++iCurrent) { + int iColumn = pHeaderCtrl->OrderToIndex(iCurrent); + if (IsColumnHidden(iColumn)) + continue; + + UINT uDrawTextAlignment; + int iColumnWidth = GetColumnWidth(iColumn, uDrawTextAlignment); + rcItem.left = itemLeft; + rcItem.right = itemLeft + iColumnWidth - sm_iLabelOffset; + switch (iColumn) { + case 0: //file name & tree + //set up tree vars + tree_start = rcItem.left + 1; + rcItem.left += min(8, iColumnWidth); + tree_end = rcItem.left; + default: + rcItem.left += sm_iLabelOffset; + if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) + if (isChild) + DrawSourceChild(dc, iColumn, &rcItem, uDrawTextAlignment, content); + else + DrawSourceParent(dc, iColumn, &rcItem, uDrawTextAlignment, content); } + itemLeft += iColumnWidth; } DrawFocusRect(dc, &lpDrawItemStruct->rcItem, lpDrawItemStruct->itemState & ODS_FOCUS, bCtrlFocused, lpDrawItemStruct->itemState & ODS_SELECTED); - //draw tree last so it draws over selected and focus (looks better) + //draw the tree last, over selected and focus (looks better) if (tree_start < tree_end) { //set new bounds RECT tree_rect = { tree_start, lpDrawItemStruct->rcItem.top, tree_end, lpDrawItemStruct->rcItem.bottom }; dc.SetBoundsRect(&tree_rect, DCB_DISABLE); //gather some information - BOOL hasNext = notLast && reinterpret_cast(GetItemData(lpDrawItemStruct->itemID + 1))->GetListParent() != NULL; - BOOL isOpenRoot = hasNext && content->GetListParent() == NULL; - BOOL isChild = content->GetListParent() != NULL; + bool hasNext = notLast && reinterpret_cast(GetItemData(lpDrawItemStruct->itemID + 1))->GetListParent() != NULL; + bool isOpenRoot = hasNext && !isChild; //might as well calculate these now int treeCenter = tree_start + 4; @@ -1399,10 +1348,11 @@ void CSearchListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) dc.MoveTo(treeCenter, middle); dc.LineTo(treeCenter, rcItem.bottom + 1); } - } else if (isOpenRoot || (content->GetListParent() == NULL && content->GetListChildCount() > 1)) { + } else if (isOpenRoot || content->GetListChildCount() > 1) { //draw box const RECT circle_rec = { treeCenter - 4, middle - 5, treeCenter + 5, middle + 4 }; - dc.FrameRect(&circle_rec, &CBrush(crLine)); + CBrush brush(crLine); + dc.FrameRect(&circle_rec, &brush); CPen penBlack; penBlack.CreatePen(PS_SOLID, 1, (!g_bLowColorDesktop || (lpDrawItemStruct->itemState & ODS_SELECTED) == 0) ? m_crWindowText : m_crHighlightText); CPen *pOldPen2 = dc.SelectObject(&penBlack); @@ -1443,17 +1393,19 @@ COLORREF CSearchListCtrl::GetSearchItemColor(/*const*/ CSearchFile *src) if (static_cast(pFile)->GetStatus() == PS_PAUSED) return m_crSearchResultDownloadStopped; return m_crSearchResultDownloading; - } else { - src->SetKnownType(CSearchFile::Shared); - return m_crSearchResultShareing; } - } else if (theApp.sharedfiles->GetFileByID(src->GetFileHash())) { src->SetKnownType(CSearchFile::Shared); return m_crSearchResultShareing; - } else if (theApp.knownfiles->FindKnownFileByID(src->GetFileHash())) { + } + if (theApp.sharedfiles->GetFileByID(src->GetFileHash())) { + src->SetKnownType(CSearchFile::Shared); + return m_crSearchResultShareing; + } + if (theApp.knownfiles->FindKnownFileByID(src->GetFileHash())) { src->SetKnownType(CSearchFile::Downloaded); return m_crSearchResultKnown; - } else if (theApp.knownfiles->IsCancelledFileByID(src->GetFileHash())) { + } + if (theApp.knownfiles->IsCancelledFileByID(src->GetFileHash())) { src->SetKnownType(CSearchFile::Cancelled); return m_crSearchResultCancelled; } @@ -1464,9 +1416,8 @@ COLORREF CSearchListCtrl::GetSearchItemColor(/*const*/ CSearchFile *src) // unknown file -> show shades of a color uint32 srccnt = src->GetSourceCount(); - if (srccnt > 0) - --srccnt; - return m_crShades[(srccnt >= AVBLYSHADECOUNT) ? AVBLYSHADECOUNT - 1 : srccnt]; + srccnt -= static_cast(srccnt > 0); + return m_crShades[min(srccnt, AVBLYSHADECOUNT - 1)]; } void CSearchListCtrl::DrawSourceChild(CDC *dc, int nColumn, LPRECT lpRect, UINT uDrawTextAlignment, const CSearchFile *src) @@ -1474,22 +1425,17 @@ void CSearchListCtrl::DrawSourceChild(CDC *dc, int nColumn, LPRECT lpRect, UINT const CString &sItem(GetItemDisplayText(src, nColumn)); switch (nColumn) { case 0: // file name + lpRect->left += 8 + 8 + theApp.GetSmallSytemIconSize().cy;// +sm_iLabelOffset; + if ((thePrefs.ShowRatingIndicator() && (src->HasComment() || src->HasRating() || src->IsKadCommentSearchRunning())) + || (thePrefs.IsSearchSpamFilterEnabled() && src->IsConsideredSpam())) { - UINT uOffset = 8 + 8 + theApp.GetSmallSytemIconSize().cy + sm_iLabelOffset; - if ((thePrefs.ShowRatingIndicator() && (src->HasComment() || src->HasRating() || src->IsKadCommentSearchRunning())) - || (thePrefs.IsSearchSpamFilterEnabled() && src->IsConsideredSpam())) - { - uOffset += 16; - } - lpRect->left += uOffset; - dc->DrawText(sItem, -1, lpRect, MLC_DT_TEXT | uDrawTextAlignment); - lpRect->left -= uOffset; + lpRect->left += 16; } + default: + dc->DrawText(sItem, -1, lpRect, MLC_DT_TEXT | uDrawTextAlignment); case 4: // file type case 5: // file hash break; - default: - dc->DrawText(sItem, -1, lpRect, MLC_DT_TEXT | uDrawTextAlignment); } } @@ -1498,31 +1444,23 @@ void CSearchListCtrl::DrawSourceParent(CDC *dc, int nColumn, LPRECT lpRect, UINT const CString &sItem(GetItemDisplayText(src, nColumn)); switch (nColumn) { case 0: // file name + lpRect->left += 8 + theApp.GetSmallSytemIconSize().cx; + if ((thePrefs.ShowRatingIndicator() && (src->HasComment() || src->HasRating() || src->IsKadCommentSearchRunning())) + || (thePrefs.IsSearchSpamFilterEnabled() && src->IsConsideredSpam())) { - UINT uOffset = 8 + theApp.GetSmallSytemIconSize().cx + sm_iLabelOffset; - if ((thePrefs.ShowRatingIndicator() && (src->HasComment() || src->HasRating() || src->IsKadCommentSearchRunning())) - || (thePrefs.IsSearchSpamFilterEnabled() && src->IsConsideredSpam())) - { - uOffset += 16; - } - lpRect->left += uOffset; - dc->DrawText(sItem, -1, lpRect, MLC_DT_TEXT | uDrawTextAlignment); - lpRect->left -= uOffset; + lpRect->left += 16; } + default: + dc->DrawText(sItem, -1, lpRect, MLC_DT_TEXT | uDrawTextAlignment); break; case 3: // complete sources { bool bComplete = IsComplete(src, src->GetSourceCount()); - COLORREF crOldTextColor = 0; - if (!bComplete) - crOldTextColor = dc->SetTextColor(RGB(255, 0, 0)); + COLORREF crOldTextColor = (bComplete ? 0 : dc->SetTextColor(RGB(255, 0, 0))); dc->DrawText(sItem, -1, lpRect, MLC_DT_TEXT | uDrawTextAlignment); if (!bComplete) dc->SetTextColor(crOldTextColor); } - break; - default: - dc->DrawText(sItem, -1, lpRect, MLC_DT_TEXT | uDrawTextAlignment); } } @@ -1596,7 +1534,7 @@ void CSearchListCtrl::OnLvnKeyDown(LPNMHDR pNMHDR, LRESULT *pResult) void CSearchListCtrl::ClearResultViewState(uint32 nResultsID) { // just clean up our stored states for this search - CSortSelectionState *pState = NULL; + CSortSelectionState *pState; if (m_mapSortSelectionStates.Lookup(nResultsID, pState)) { m_mapSortSelectionStates.RemoveKey(nResultsID); delete pState; @@ -1671,7 +1609,7 @@ CString CSearchListCtrl::GetItemDisplayText(const CSearchFile *src, int iSubItem { uint32 nMediaLength = src->GetIntTagValue(FT_MEDIA_LENGTH); if (nMediaLength) - SecToTimeLength(nMediaLength, sText); + sText = SecToTimeLength(nMediaLength); } break; case 10: @@ -1688,7 +1626,7 @@ CString CSearchListCtrl::GetItemDisplayText(const CSearchFile *src, int iSubItem if (src->GetDirectory()) sText = src->GetDirectory(); break; - case 13: + case 13: //known { UINT uid; switch (src->m_eKnown) { @@ -1710,9 +1648,7 @@ CString CSearchListCtrl::GetItemDisplayText(const CSearchFile *src, int iSubItem if (uid) sText = GetResString(uid); #ifdef _DEBUG - if (!sText.IsEmpty()) - sText += _T(' '); - sText.AppendFormat(_T("SR: %u%%"), src->GetSpamRating()); + sText.AppendFormat(&_T(" SR: %u%%")[static_cast(sText.IsEmpty())], src->GetSpamRating()); #endif } break; @@ -1726,16 +1662,16 @@ CString CSearchListCtrl::GetItemDisplayText(const CSearchFile *src, int iSubItem void CSearchListCtrl::OnLvnGetDispInfo(LPNMHDR pNMHDR, LRESULT *pResult) { if (!theApp.IsClosing()) { - // Although we have an owner drawn listview control we store the text for the primary item in the listview, to be - // capable of quick searching those items via the keyboard. Because our listview items may change their contents, - // we do this via a text callback function. The listview control will send us the LVN_DISPINFO notification if - // it needs to know the contents of the primary item. + // Although we have an owner drawn listview control we store the text for the primary item in the + // listview, to be capable of quick searching those items via the keyboard. Because our listview + // items may change their contents, we do this via a text callback function. The listview control + // will send us the LVN_DISPINFO notification if it needs to know the contents of the primary item. // - // But, the listview control sends this notification all the time, even if we do not search for an item. At least - // this notification is only sent for the visible items and not for all items in the list. Though, because this - // function is invoked *very* often, do *NOT* put any time consuming code in here. + // But, the listview control sends this notification all the time, even if we do not search for an item. + // At least this notification is only sent for the visible items and not for all items in the list. + // Though, because this function is invoked *very* often, do *NOT* put any time consuming code in here. // - // Vista: That callback is used to get the strings for the label tips for the sub(!) items. + // Vista: That callback is used to get the strings for the label tips for the sub(!)-items. // const LVITEMW &rItem = reinterpret_cast(pNMHDR)->item; if (rItem.mask & LVIF_TEXT) { @@ -1754,8 +1690,8 @@ CString CSearchListCtrl::FormatFileSize(ULONGLONG ullFileSize) const return GetFormatedUInt64((ullFileSize + 1024 - 1) / 1024) + _T(' ') + GetResString(IDS_KBYTES); if (m_eFileSizeFormat == fsizeMByte) { - //return GetFormatedUInt64((ullFileSize + 1024*1024 - 1) / (1024*1024)) + _T(' ') + GetResString(IDS_MBYTES); - double fFileSize = ullFileSize / (1024.0*1024.0); + //return GetFormatedUInt64((ullFileSize + 1024 * 1024 - 1) / (1024 * 1024)) + _T(' ') + GetResString(IDS_MBYTES); + double fFileSize = ullFileSize / (1024.0 * 1024.0); if (fFileSize < 0.01) fFileSize = 0.01; @@ -1786,14 +1722,14 @@ void CSearchListCtrl::SetFileSizeFormat(EFileSizeFormat eFormat) UpdateWindow(); } -bool CSearchListCtrl::IsFilteredItem(const CSearchFile *pSearchFile) const +bool CSearchListCtrl::IsFilteredOut(const CSearchFile *pSearchFile) const { if (pSearchFile->m_flags.noshow) //do not show return true; const CStringArray &rastrFilter = theApp.emuledlg->searchwnd->m_pwndResults->m_astrFilter; if (!rastrFilter.IsEmpty()) { // filtering is done by text only for all columns to keep it consistent and simple - // for the user even if that doesn't allows complex filters + // for the user even if that doesn't allow complex filters // for example for a file size range - but this could be done at server search time already const CString &szFilterTarget(GetItemDisplayText(pSearchFile, theApp.emuledlg->searchwnd->m_pwndResults->GetFilterColumn())); diff --git a/srchybrid/SearchListCtrl.h b/srchybrid/SearchListCtrl.h index 28d18723..1c983ca7 100644 --- a/srchybrid/SearchListCtrl.h +++ b/srchybrid/SearchListCtrl.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -18,12 +18,12 @@ #include "MuleListCtrl.h" #include "TitleMenu.h" #include "ListCtrlItemWalk.h" +#include "ToolTipCtrlX.h" #define AVBLYSHADECOUNT 13 class CSearchList; class CSearchFile; -class CToolTipCtrlX; enum EFileSizeFormat { @@ -71,23 +71,24 @@ class CSearchListCtrl : public CMuleListCtrl, public CListCtrlItemWalk void SetFileSizeFormat(EFileSizeFormat eFormat); protected: - CTitleMenu m_SearchFileMenu; - CSearchList *searchlist; - CToolTipCtrlX *m_tooltip; - CImageList m_ImageList; - COLORREF m_crSearchResultDownloading; - COLORREF m_crSearchResultDownloadStopped; - COLORREF m_crSearchResultKnown; - COLORREF m_crSearchResultShareing; - COLORREF m_crSearchResultCancelled; - COLORREF m_crShades[AVBLYSHADECOUNT]; - uint32 m_nResultsID; - EFileSizeFormat m_eFileSizeFormat; + CTitleMenu m_SearchFileMenu; + CSearchList *searchlist; + CToolTipCtrlX m_tooltip; + CImageList m_ImageList; + COLORREF m_crSearchResultDownloading; + COLORREF m_crSearchResultDownloadStopped; + COLORREF m_crSearchResultKnown; + COLORREF m_crSearchResultShareing; + COLORREF m_crSearchResultCancelled; + COLORREF m_crShades[AVBLYSHADECOUNT]; + uint32 m_nResultsID; + EFileSizeFormat m_eFileSizeFormat; - CMap m_mapSortSelectionStates; + typedef CMap CSortSelectionStatesMap; + CSortSelectionStatesMap m_mapSortSelectionStates; COLORREF GetSearchItemColor(/*const*/ CSearchFile *src); - bool IsComplete(const CSearchFile *pFile, UINT uSources) const; + bool IsComplete(const CSearchFile *pFile, UINT uSources) const; CString GetCompleteSourcesDisplayString(const CSearchFile *pFile, UINT uSources, bool *pbComplete = NULL) const; void ExpandCollapseItem(int iItem, int iAction); void HideSources(CSearchFile *toCollapse); @@ -96,7 +97,7 @@ class CSearchListCtrl : public CMuleListCtrl, public CListCtrlItemWalk void SetAllIcons(); CString FormatFileSize(ULONGLONG ullFileSize) const; CString GetItemDisplayText(const CSearchFile *src, int iSubItem) const; - bool IsFilteredItem(const CSearchFile *pSearchFile) const; + bool IsFilteredOut(const CSearchFile *pSearchFile) const; void DrawSourceParent(CDC *dc, int nColumn, LPRECT lpRect, UINT uDrawTextAlignment, const CSearchFile *src); void DrawSourceChild(CDC *dc, int nColumn, LPRECT lpRect, UINT uDrawTextAlignment, const CSearchFile *src); diff --git a/srchybrid/SearchParams.h b/srchybrid/SearchParams.h index 14676d4b..a5dd989f 100644 --- a/srchybrid/SearchParams.h +++ b/srchybrid/SearchParams.h @@ -24,15 +24,15 @@ enum ESearchType : uint8 struct SSearchParams { SSearchParams() - : dwSearchID(_UI32_MAX) - , bClientSharedFiles() - , eType(SearchTypeEd2kServer) - , ullMinSize() + : ullMinSize() , ullMaxSize() + , dwSearchID(_UI32_MAX) , uAvailability() , uComplete() - , ulMinBitrate() - , ulMinLength() + , uiMinBitrate() + , uiMinLength() + , eType(SearchTypeEd2kServer) + , bClientSharedFiles() , bMatchKeywords() { } @@ -42,8 +42,8 @@ struct SSearchParams , ullMaxSize() , uAvailability() , uComplete() - , ulMinBitrate() - , ulMinLength() + , uiMinBitrate() + , uiMinLength() , bMatchKeywords() { dwSearchID = rFile.ReadUInt32(); @@ -64,29 +64,29 @@ struct SSearchParams rFile.WriteString(strFileType, UTF8strRaw); } - uint32 dwSearchID; - bool bClientSharedFiles; CString strSearchTitle; CString strExpression; CStringW strKeyword; CString strBooleanExpr; - ESearchType eType; CString strFileType; CString strMinSize; - uint64 ullMinSize; CString strMaxSize; - uint64 ullMaxSize; - UINT uAvailability; CString strExtension; - UINT uComplete; CString strCodec; - ULONG ulMinBitrate; - ULONG ulMinLength; CString strTitle; CString strAlbum; CString strArtist; CString strSpecialTitle; + uint64 ullMinSize; + uint64 ullMaxSize; + uint32 dwSearchID; + UINT uAvailability; + UINT uComplete; + UINT uiMinBitrate; + UINT uiMinLength; + ESearchType eType; + bool bClientSharedFiles; bool bMatchKeywords; }; -bool GetSearchPacket(CSafeMemFile *pData, SSearchParams *pParams, bool bTargetSupports64Bit, bool *pbPacketUsing64Bit); \ No newline at end of file +bool GetSearchPacket(CSafeMemFile &data, SSearchParams *pParams, bool bTargetSupports64Bit, bool *pbPacketUsing64Bit); \ No newline at end of file diff --git a/srchybrid/SearchParamsWnd.cpp b/srchybrid/SearchParamsWnd.cpp index ff23b214..7083ab0f 100644 --- a/srchybrid/SearchParamsWnd.cpp +++ b/srchybrid/SearchParamsWnd.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -20,7 +20,6 @@ #include "SearchDlg.h" #include "SearchParamsWnd.h" #include "SearchResultsWnd.h" -#include "SearchParams.h" #include "OtherFunctions.h" #include "CustomAutoComplete.h" #include "HelpIDs.h" @@ -61,7 +60,7 @@ END_MESSAGE_MAP() CSearchParamsWnd::CSearchParamsWnd() : m_searchdlg() - , m_hcurMove(::LoadCursor(NULL, IDC_SIZEALL)) // load default windows system cursor (a shared resource) + , m_hcurMove(::LoadCursor(NULL, IDC_SIZEALL)) // load default windows system cursor (a shared resource, do not destoy) , m_pacSearchString() { } @@ -72,10 +71,6 @@ CSearchParamsWnd::~CSearchParamsWnd() m_pacSearchString->Unbind(); m_pacSearchString->Release(); } - - // 'DestroyCursor' is not to be used for a shared cursor (as returned with LoadCursor) (?!) -// if (m_hcurMove) -// VERIFY(::DestroyCursor(m_hcurMove)); } void CSearchParamsWnd::DoDataExchange(CDataExchange *pDX) @@ -265,16 +260,13 @@ CSize CSearchParamsWnd::CalcDynamicLayout(int nLength, DWORD dwMode) BOOL CSearchParamsWnd::OnSetCursor(CWnd *pWnd, UINT nHitTest, UINT message) { if (m_hcurMove && ((m_dwStyle & (CBRS_GRIPPER | CBRS_FLOATING)) == CBRS_GRIPPER) && pWnd->GetSafeHwnd() == m_hWnd) { - CPoint ptCursor; + POINT ptCursor; if (::GetCursorPos(&ptCursor)) { ScreenToClient(&ptCursor); CRect rcClient; GetClientRect(&rcClient); - bool bMouseOverGripper; - if (m_dwStyle & CBRS_ORIENT_HORZ) - bMouseOverGripper = (rcClient.PtInRect(ptCursor) && ptCursor.x <= 10); - else - bMouseOverGripper = (rcClient.PtInRect(ptCursor) && ptCursor.y <= 10); + bool bMouseOverGripper = rcClient.PtInRect(ptCursor) + && ((m_dwStyle & CBRS_ORIENT_HORZ) ? ptCursor.x : ptCursor.y) <= 10; if (bMouseOverGripper) { ::SetCursor(m_hcurMove); return TRUE; @@ -295,11 +287,11 @@ void CSearchParamsWnd::OnSize(UINT nType, int cx, int cy) GetClientRect(&rcClient); CalcInsideRect(rcClient, TRUE); - // resizing the name field instead the filter fields makes sense, because the filter input mostly stays small while a bigger - // name filed allows longer search queries without scrolling. - // however it doesn't look nice at all, because of the asymmetry which is created by not resizing the method selectors - // but resizing them wouldn't make any sense at all, so we need to find a better build up at some point, but for now - // stay with the old method which is not perfect but looks fair enough + // resizing the name field instead the filter fields makes sense, because the filter input mostly + // stays small while a bigger name filed allows longer search queries without scrolling. + // however it doesn't look nice because of the asymmetry which is created by not resizing + // the method selectors but resizing them wouldn't make any sense at all, so we need to find a better + // build up at some point. For now stay with the old method which is not perfect but looks fair enough /* HDWP hdwp = BeginDeferWindowPos(12); if (hdwp) { @@ -308,7 +300,7 @@ void CSearchParamsWnd::OnSize(UINT nType, int cx, int cy) if (iWidthOpts < m_rcOpts.Width()) iWidthOpts = m_rcOpts.Width(); int iXPosOpts = rcClient.right - iWidthOpts; - ASSERT( m_rcStart.Width() == m_rcMore.Width() && m_rcStart.Width() == m_rcCancel.Width() ); + ASSERT(m_rcStart.Width() == m_rcMore.Width() && m_rcStart.Width() == m_rcCancel.Width()); int iXPosButtons = iXPosOpts - m_rcStart.Width() - 2; int iXPosDDArrow = iXPosButtons - 2 - m_rcDropDownArrow.Width(); int iWidthName = iXPosDDArrow - (rcClient.left + m_rcName.left); @@ -335,7 +327,7 @@ void CSearchParamsWnd::OnSize(UINT nType, int cx, int cy) int iWidthOpts = rcClient.right - (rcClient.left + m_rcOpts.left); HDWP hdwp = BeginDeferWindowPos(12); if (hdwp) { - UINT uFlags = SWP_NOZORDER | SWP_NOACTIVATE; + const UINT uFlags = SWP_NOZORDER | SWP_NOACTIVATE; hdwp = DeferWindowPos(hdwp, *GetDlgItem(IDC_MSTATIC3), NULL, rcClient.left + m_rcNameLbl.left, rcClient.top + m_rcNameLbl.top, m_rcNameLbl.Width(), m_rcNameLbl.Height(), uFlags); hdwp = DeferWindowPos(hdwp, m_ctlName, NULL, rcClient.left + m_rcName.left, rcClient.top + m_rcName.top, m_rcName.Width(), m_rcName.Height(), uFlags); hdwp = DeferWindowPos(hdwp, *GetDlgItem(IDC_DD), NULL, rcClient.left + m_rcDropDownArrow.left, rcClient.top + m_rcDropDownArrow.top, m_rcDropDownArrow.Width(), m_rcDropDownArrow.Height(), uFlags); @@ -366,27 +358,30 @@ void CSearchParamsWnd::OnSize(UINT nType, int cx, int cy) int y = rcClient.top; + CWnd *item = GetDlgItem(IDC_MSTATIC3); CRect rcNameLbl; - GetDlgItem(IDC_MSTATIC3)->GetWindowRect(rcNameLbl); + item->GetWindowRect(rcNameLbl); ScreenToClient(rcNameLbl); - GetDlgItem(IDC_MSTATIC3)->MoveWindow(rcClient.left, y, rcNameLbl.Width(), rcNameLbl.Height()); + item->MoveWindow(rcClient.left, y, rcNameLbl.Width(), rcNameLbl.Height()); y += rcNameLbl.Height() + 2; CRect rcName; m_ctlName.GetWindowRect(rcName); ScreenToClient(rcName); + item = GetDlgItem(IDC_DD); CRect rcDropDownArrow; - GetDlgItem(IDC_DD)->GetWindowRect(rcDropDownArrow); + item->GetWindowRect(rcDropDownArrow); ScreenToClient(rcDropDownArrow); int iNameWidth = rcClient.Width() - 4 - rcDropDownArrow.Width(); m_ctlName.MoveWindow(rcClient.left, y, iNameWidth, rcName.Height()); - GetDlgItem(IDC_DD)->MoveWindow(rcClient.left + iNameWidth + 4, y, rcDropDownArrow.Width(), rcDropDownArrow.Height()); + item->MoveWindow(rcClient.left + iNameWidth + 4, y, rcDropDownArrow.Width(), rcDropDownArrow.Height()); y += rcName.Height() + 2; + item = GetDlgItem(IDC_MSTATIC7); CRect rcFileTypeLbl; - GetDlgItem(IDC_MSTATIC7)->GetWindowRect(rcFileTypeLbl); + item->GetWindowRect(rcFileTypeLbl); ScreenToClient(rcFileTypeLbl); - GetDlgItem(IDC_MSTATIC7)->MoveWindow(rcClient.left, y, rcFileTypeLbl.Width(), rcFileTypeLbl.Height()); + item->MoveWindow(rcClient.left, y, rcFileTypeLbl.Width(), rcFileTypeLbl.Height()); y += rcFileTypeLbl.Height() + 2; CRect rcFileType; @@ -394,17 +389,20 @@ void CSearchParamsWnd::OnSize(UINT nType, int cx, int cy) ScreenToClient(rcFileType); m_ctlFileType.MoveWindow(rcClient.left, y, rcFileType.Width(), rcFileType.Height()); + //Combo box height is 24 and button is 22, but the same on-screen height + item = GetDlgItem(IDC_SEARCH_RESET); CRect rcReset; - GetDlgItem(IDC_SEARCH_RESET)->GetWindowRect(rcReset); + item->GetWindowRect(rcReset); ScreenToClient(rcReset); - GetDlgItem(IDC_SEARCH_RESET)->MoveWindow(rcClient.left + rcFileType.Width() + 8, y, rcReset.Width(), rcReset.Height()); + item->MoveWindow(rcClient.left + rcFileType.Width() + 8, y - 1, rcReset.Width(), rcReset.Height()); y += rcFileType.Height() + 8; + item = GetDlgItem(IDC_METH); CRect rcMethodLbl; - GetDlgItem(IDC_METH)->GetWindowRect(rcMethodLbl); + item->GetWindowRect(rcMethodLbl); ScreenToClient(rcMethodLbl); - GetDlgItem(IDC_METH)->MoveWindow(rcClient.left, y, rcMethodLbl.Width(), rcMethodLbl.Height()); + item->MoveWindow(rcClient.left, y, rcMethodLbl.Width(), rcMethodLbl.Height()); y += rcMethodLbl.Height() + 2; CRect rcMethod; @@ -437,16 +435,12 @@ void CSearchParamsWnd::OnUpdateCmdUI(CFrameWnd* /*pTarget*/, BOOL /*bDisableIfNo void CSearchParamsWnd::UpdateControls() { int iMethod = m_ctlMethod.GetCurSel(); - if (iMethod != CB_ERR) { - if (iMethod != thePrefs.GetSearchMethod()) { - if (iMethod == SearchTypeKademlia) - OnEnChangeName(); - else if (iMethod == SearchTypeEd2kServer && m_searchdlg->IsLocalEd2kSearchRunning()) - m_ctlStart.EnableWindow(FALSE); - else if (iMethod == SearchTypeEd2kGlobal && m_searchdlg->IsGlobalEd2kSearchRunning()) - m_ctlStart.EnableWindow(FALSE); - thePrefs.SetSearchMethod(iMethod); - } + if (iMethod != CB_ERR && iMethod != thePrefs.GetSearchMethod()) { + if (iMethod == SearchTypeKademlia) + OnEnChangeName(); + else if (m_searchdlg->IsLocalEd2kSearchRunning() && (iMethod == SearchTypeEd2kServer || iMethod == SearchTypeEd2kGlobal)) + m_ctlStart.EnableWindow(FALSE); + thePrefs.SetSearchMethod(iMethod); } DWORD_PTR dwData = static_cast(iMethod == SearchTypeEd2kServer || iMethod == SearchTypeEd2kGlobal || iMethod == SearchTypeContentDB); @@ -619,12 +613,12 @@ void CSearchParamsWnd::Localize() HDITEM hdi; hdi.mask = HDI_TEXT; - CString sHdr(GetResString(IDS_PARAMETER)); + const CString &sHdr(GetResString(IDS_PARAMETER)); hdi.pszText = const_cast((LPCTSTR)sHdr); pHeaderCtrl->SetItem(0, &hdi); - sHdr = GetResString(IDS_VALUE); - hdi.pszText = const_cast((LPCTSTR)sHdr); + const CString &sHdr1(GetResString(IDS_VALUE)); + hdi.pszText = const_cast((LPCTSTR)sHdr1); pHeaderCtrl->SetItem(1, &hdi); } @@ -729,9 +723,7 @@ void CSearchParamsWnd::OnDDClicked() BOOL CSearchParamsWnd::SaveSearchStrings() { - if (m_pacSearchString == NULL) - return FALSE; - return m_pacSearchString->SaveList(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + SEARCH_STRINGS_PROFILE); + return m_pacSearchString && m_pacSearchString->SaveList(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + SEARCH_STRINGS_PROFILE); } void CSearchParamsWnd::SaveSettings() @@ -769,6 +761,9 @@ void CSearchParamsWnd::OnSysCommand(UINT nID, LPARAM lParam) void CSearchParamsWnd::SetParameters(const SSearchParams *pParams) { + //There was a weird report about persistent "Syntax error" with all fields + //seemingly empty. That effectively disabled any search until restart. + WipeOptionFields(); //set all to blanks if (!pParams->bClientSharedFiles) { m_ctlName.SetWindowText(pParams->strExpression); m_ctlFileType.SelectItemDataString(pParams->strFileType); @@ -777,34 +772,29 @@ void CSearchParamsWnd::SetParameters(const SSearchParams *pParams) m_ctlOpts.SetItemText(orMaxSize, 1, pParams->strMaxSize); m_ctlOpts.SetItemText(orExtension, 1, pParams->strExtension); CString strBuff; - if (pParams->uAvailability > 0) + if (pParams->uAvailability > 0) { strBuff.Format(_T("%u"), pParams->uAvailability); - m_ctlOpts.SetItemText(orAvailability, 1, strBuff); - - if (pParams->uComplete > 0) + m_ctlOpts.SetItemText(orAvailability, 1, strBuff); + } + if (pParams->uComplete > 0) { strBuff.Format(_T("%u"), pParams->uComplete); - else - strBuff.Empty(); - m_ctlOpts.SetItemText(orCompleteSources, 1, strBuff); - - m_ctlOpts.SetItemText(orCodec, 1, pParams->strCodec); - - if (pParams->ulMinBitrate > 0) - strBuff.Format(_T("%lu"), pParams->ulMinBitrate); - else - strBuff.Empty(); - m_ctlOpts.SetItemText(orBitrate, 1, strBuff); - - if (pParams->ulMinLength > 0) - SecToTimeLength(pParams->ulMinLength, strBuff); - else - strBuff.Empty(); - m_ctlOpts.SetItemText(orLength, 1, strBuff); - m_ctlOpts.SetItemText(orTitle, 1, pParams->strTitle); - m_ctlOpts.SetItemText(orAlbum, 1, pParams->strAlbum); - m_ctlOpts.SetItemText(orArtist, 1, pParams->strArtist); - } else - WipeOptionFields(); //as a precaution + m_ctlOpts.SetItemText(orCompleteSources, 1, strBuff); + } + if (!pParams->strCodec.IsEmpty()) + m_ctlOpts.SetItemText(orCodec, 1, pParams->strCodec); + if (pParams->uiMinBitrate > 0) { + strBuff.Format(_T("%u"), pParams->uiMinBitrate); + m_ctlOpts.SetItemText(orBitrate, 1, strBuff); + } + if (pParams->uiMinLength > 0) + m_ctlOpts.SetItemText(orLength, 1, SecToTimeLength(pParams->uiMinLength)); + if (!pParams->strTitle.IsEmpty()) + m_ctlOpts.SetItemText(orTitle, 1, pParams->strTitle); + if (!pParams->strAlbum.IsEmpty()) + m_ctlOpts.SetItemText(orAlbum, 1, pParams->strAlbum); + if (!pParams->strArtist.IsEmpty()) + m_ctlOpts.SetItemText(orArtist, 1, pParams->strArtist); + } } uint64 CSearchParamsWnd::GetSearchAttrSize(const CString &rstrExpr) @@ -897,6 +887,14 @@ ULONG CSearchParamsWnd::GetSearchAttrLength(const CString &rstrExpr) return (ULONG)(dbl + 0.5); //default is seconds } +void CSearchParamsWnd::ParamErrorBox(EOptsRows eRow) +{ + CString strError(GetResString(IDS_SEARCH_EXPRERROR)); + strError += _T("\n\n"); + strError.AppendFormat(GetResString(IDS_SEARCH_ATTRERR), (LPCTSTR)m_ctlOpts.GetItemText(eRow, 0)); + AfxMessageBox(strError, MB_ICONWARNING | MB_HELP, eMule_FAQ_Search - HID_BASE_PROMPT); +} + void CSearchParamsWnd::WipeOptionFields() { for (int i = m_ctlOpts.GetItemCount(); --i >= 0;) @@ -923,23 +921,17 @@ SSearchParams* CSearchParamsWnd::GetParameters() strFileType = pszED2KFileType; } - const CString &strMinSize = m_ctlOpts.GetItemText(orMinSize, 1); + const CString &strMinSize(m_ctlOpts.GetItemText(orMinSize, 1)); uint64 ullMinSize = GetSearchAttrSize(strMinSize); if (ullMinSize == _UI64_MAX) { - CString strError(GetResString(IDS_SEARCH_EXPRERROR)); - strError += _T("\n\n"); - strError.AppendFormat(GetResString(IDS_SEARCH_ATTRERR), (LPCTSTR)m_ctlOpts.GetItemText(orMinSize, 0)); - AfxMessageBox(strError, MB_ICONWARNING | MB_HELP, eMule_FAQ_Search - HID_BASE_PROMPT); + ParamErrorBox(orMinSize); return NULL; } - const CString &strMaxSize = m_ctlOpts.GetItemText(orMaxSize, 1); + const CString &strMaxSize(m_ctlOpts.GetItemText(orMaxSize, 1)); uint64 ullMaxSize = GetSearchAttrSize(strMaxSize); if (ullMaxSize == _UI64_MAX) { - CString strError(GetResString(IDS_SEARCH_EXPRERROR)); - strError += _T("\n\n"); - strError.AppendFormat(GetResString(IDS_SEARCH_ATTRERR), (LPCTSTR)m_ctlOpts.GetItemText(orMaxSize, 0)); - AfxMessageBox(strError, MB_ICONWARNING | MB_HELP, eMule_FAQ_Search - HID_BASE_PROMPT); + ParamErrorBox(orMaxSize); return NULL; } @@ -959,13 +951,10 @@ SSearchParams* CSearchParamsWnd::GetParameters() UINT uAvailability = 0; if ((m_ctlOpts.GetItemData(orAvailability) & 1) == 0) { - CString strAvailability = m_ctlOpts.GetItemText(orAvailability, 1); + CString strAvailability(m_ctlOpts.GetItemText(orAvailability, 1)); uAvailability = GetSearchAttrNumber(strAvailability); if (uAvailability == _UI32_MAX) { - CString strError(GetResString(IDS_SEARCH_EXPRERROR)); - strError += _T("\n\n"); - strError.AppendFormat(GetResString(IDS_SEARCH_ATTRERR), (LPCTSTR)m_ctlOpts.GetItemText(orAvailability, 0)); - AfxMessageBox(strError, MB_ICONWARNING | MB_HELP, eMule_FAQ_Search - HID_BASE_PROMPT); + ParamErrorBox(orAvailability); return NULL; } if (uAvailability > 1000000) { @@ -977,13 +966,10 @@ SSearchParams* CSearchParamsWnd::GetParameters() UINT uComplete = 0; if ((m_ctlOpts.GetItemData(orCompleteSources) & 1) == 0) { - CString strComplete = m_ctlOpts.GetItemText(orCompleteSources, 1); + CString strComplete(m_ctlOpts.GetItemText(orCompleteSources, 1)); uComplete = GetSearchAttrNumber(strComplete); - if (uComplete == _UI32_MAX) { - CString strError(GetResString(IDS_SEARCH_EXPRERROR)); - strError += _T("\n\n"); - strError.AppendFormat(GetResString(IDS_SEARCH_ATTRERR), (LPCTSTR)m_ctlOpts.GetItemText(orCompleteSources, 0)); - AfxMessageBox(strError, MB_ICONWARNING | MB_HELP, eMule_FAQ_Search - HID_BASE_PROMPT); + if (uComplete == UINT_MAX) { + ParamErrorBox(orCompleteSources); return NULL; } if (uComplete > 1000000) { @@ -997,40 +983,32 @@ SSearchParams* CSearchParamsWnd::GetParameters() if ((m_ctlOpts.GetItemData(orCodec) & 1) == 0) strCodec = m_ctlOpts.GetItemText(orCodec, 1).Trim(); - ULONG ulMinBitrate = 0; + UINT ulMinBitrate = 0; if ((m_ctlOpts.GetItemData(orBitrate) & 1) == 0) { - CString strMinBitrate = m_ctlOpts.GetItemText(orBitrate, 1); + CString strMinBitrate(m_ctlOpts.GetItemText(orBitrate, 1)); ulMinBitrate = GetSearchAttrNumber(strMinBitrate); - if (ulMinBitrate == ULONG_MAX) { - CString strError(GetResString(IDS_SEARCH_EXPRERROR)); - strError += _T("\n\n"); - strError.AppendFormat(GetResString(IDS_SEARCH_ATTRERR), (LPCTSTR)m_ctlOpts.GetItemText(orBitrate, 0)); - AfxMessageBox(strError, MB_ICONWARNING | MB_HELP, eMule_FAQ_Search - HID_BASE_PROMPT); + if (ulMinBitrate == UINT_MAX) { + ParamErrorBox(orBitrate); return NULL; } if (ulMinBitrate > 1000000) { ulMinBitrate = 1000000; - strMinBitrate.Format(_T("%lu"), ulMinBitrate); + strMinBitrate.Format(_T("%u"), ulMinBitrate); m_ctlOpts.SetItemText(orBitrate, 1, strMinBitrate); } } - ULONG ulMinLength = 0; + UINT ulMinLength = 0; if ((m_ctlOpts.GetItemData(orLength) & 1) == 0) { - const CString &strMinLength = m_ctlOpts.GetItemText(orLength, 1); + const CString &strMinLength(m_ctlOpts.GetItemText(orLength, 1)); ulMinLength = GetSearchAttrLength(strMinLength); - if (ulMinLength == ULONG_MAX) { - CString strError(GetResString(IDS_SEARCH_EXPRERROR)); - strError += _T("\n\n"); - strError.AppendFormat(GetResString(IDS_SEARCH_ATTRERR), (LPCTSTR)m_ctlOpts.GetItemText(orLength, 0)); - AfxMessageBox(strError, MB_ICONWARNING | MB_HELP, eMule_FAQ_Search - HID_BASE_PROMPT); + if (ulMinLength == UINT_MAX) { + ParamErrorBox(orLength); return NULL; } if (ulMinLength > DAY2S(1)) { ulMinLength = DAY2S(1); - CString strValue; - SecToTimeLength(ulMinLength, strValue); - m_ctlOpts.SetItemText(orLength, 1, strValue); + m_ctlOpts.SetItemText(orLength, 1, SecToTimeLength(ulMinLength)); } } @@ -1047,8 +1025,8 @@ SSearchParams* CSearchParamsWnd::GetParameters() //pParams->bMatchKeywords = IsDlgButtonChecked(IDC_MATCH_KEYWORDS) != 0; pParams->uComplete = uComplete; pParams->strCodec = strCodec; - pParams->ulMinBitrate = ulMinBitrate; - pParams->ulMinLength = ulMinLength; + pParams->uiMinBitrate = ulMinBitrate; + pParams->uiMinLength = ulMinLength; if ((m_ctlOpts.GetItemData(orTitle) & 1) == 0) pParams->strTitle = m_ctlOpts.GetItemText(orTitle, 1).Trim(); if ((m_ctlOpts.GetItemData(orAlbum) & 1) == 0) diff --git a/srchybrid/SearchParamsWnd.h b/srchybrid/SearchParamsWnd.h index b4b3253e..c26ec3dc 100644 --- a/srchybrid/SearchParamsWnd.h +++ b/srchybrid/SearchParamsWnd.h @@ -3,7 +3,9 @@ #include "EditX.h" #include "ComboBoxEx2.h" #include "ListCtrlEditable.h" +#include "SearchParams.h" class CCustomAutoComplete; +class CSearchResultsWnd; typedef enum { @@ -28,6 +30,7 @@ class CSearchParamsWnd : public CDialogBar { IDD = IDD_SEARCH_PARAMS }; + void ParamErrorBox(EOptsRows eRow); void WipeOptionFields(); // Construction diff --git a/srchybrid/SearchResultsWnd.cpp b/srchybrid/SearchResultsWnd.cpp index 0647986b..727b2ac0 100644 --- a/srchybrid/SearchResultsWnd.cpp +++ b/srchybrid/SearchResultsWnd.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -16,12 +16,12 @@ //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "stdafx.h" #include "emule.h" +#include "MenuCmds.h" #include "SearchDlg.h" #include "SearchResultsWnd.h" #include "SearchParamsWnd.h" #include "SearchParams.h" #include "Packets.h" -#include "OtherFunctions.h" #include "SearchFile.h" #include "SearchList.h" #include "ServerConnect.h" @@ -45,9 +45,6 @@ #include "StringConversion.h" #include "UserMsgs.h" #include "Log.h" -#include "MenuCmds.h" -#include "DropDownButton.h" -#include "ButtonsTabCtrl.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -109,26 +106,22 @@ CSearchResultsWnd::CSearchResultsWnd(CWnd* /*pParent*/) : CResizableFormView(CSearchResultsWnd::IDD) , m_pwndParams() , m_searchpacket() - , m_b64BitSearchPacket() , global_search_timer() , m_uTimerLocalServer() - , cancelled() - , servercount() - , m_globsearch() , m_nEd2kSearchID(0x80000000u) - , m_iSentMoreReq() , m_nFilterColumn() + , m_servercount() + , m_iSentMoreReq() + , m_b64BitSearchPacket() + , m_globsearch() + , m_cancelled() { searchselect.m_bClosable = true; - m_btnSearchListMenu = new CDropDownButton; - m_cattabs = new CButtonsTabCtrl; } CSearchResultsWnd::~CSearchResultsWnd() { - delete m_cattabs; m_ctlSearchListHeader.Detach(); - delete m_btnSearchListMenu; delete m_searchpacket; if (m_uTimerLocalServer) VERIFY(KillTimer(m_uTimerLocalServer)); @@ -150,13 +143,13 @@ void CSearchResultsWnd::OnInitialUpdate() , SEARCH_LIST_MENU_BUTTON_XOFF + SEARCH_LIST_MENU_BUTTON_WIDTH , SEARCH_LIST_MENU_BUTTON_YOFF + SEARCH_LIST_MENU_BUTTON_HEIGHT }; - m_btnSearchListMenu->Init(true, true); - m_btnSearchListMenu->MoveWindow(&rc); - m_btnSearchListMenu->AddBtnStyle(IDC_SEARCHLST_ICO, TBSTYLE_AUTOSIZE); + m_btnSearchListMenu.Init(true, true); + m_btnSearchListMenu.MoveWindow(&rc); + m_btnSearchListMenu.AddBtnStyle(IDC_SEARCHLST_ICO, TBSTYLE_AUTOSIZE); // Vista: Remove the TBSTYLE_TRANSPARENT to avoid flickering (can be done only after the toolbar was initially created with TBSTYLE_TRANSPARENT !?) - m_btnSearchListMenu->ModifyStyle(TBSTYLE_TOOLTIPS | ((theApp.m_ullComCtrlVer >= MAKEDLLVERULL(6, 16, 0, 0)) ? TBSTYLE_TRANSPARENT : 0), 0); - m_btnSearchListMenu->SetExtendedStyle(m_btnSearchListMenu->GetExtendedStyle() & ~TBSTYLE_EX_MIXEDBUTTONS); - m_btnSearchListMenu->RecalcLayout(true); + m_btnSearchListMenu.ModifyStyle(TBSTYLE_TOOLTIPS | ((theApp.m_ullComCtrlVer >= MAKEDLLVERULL(6, 16, 0, 0)) ? TBSTYLE_TRANSPARENT : 0), 0); + m_btnSearchListMenu.SetExtendedStyle(m_btnSearchListMenu.GetExtendedStyle() & ~TBSTYLE_EX_MIXEDBUTTONS); + m_btnSearchListMenu.RecalcLayout(true); m_ctlFilter.OnInit(&m_ctlSearchListHeader); @@ -165,17 +158,17 @@ void CSearchResultsWnd::OnInitialUpdate() searchprogress.SetStep(1); global_search_timer = 0; m_globsearch = false; - ShowSearchSelector(false); //sets anchor for IDC_SEARCHLIST + ShowSearchSelector(false); //set anchors for IDC_SEARCHLIST - AddAnchor(*m_btnSearchListMenu, TOP_LEFT); + AddAnchor(m_btnSearchListMenu, TOP_LEFT); AddAnchor(IDC_FILTER, TOP_RIGHT); AddAnchor(IDC_SDOWNLOAD, BOTTOM_LEFT); AddAnchor(IDC_PROGRESS1, BOTTOM_LEFT, BOTTOM_RIGHT); AddAnchor(IDC_CLEARALL, BOTTOM_RIGHT); AddAnchor(IDC_OPEN_PARAMS_WND, TOP_RIGHT); - AddAnchor(searchselect.m_hWnd, TOP_LEFT, TOP_RIGHT); + AddAnchor(searchselect, TOP_LEFT, TOP_RIGHT); AddAnchor(IDC_STATIC_DLTOof, BOTTOM_LEFT); - AddAnchor(*m_cattabs, BOTTOM_LEFT, BOTTOM_RIGHT); + AddAnchor(m_cattabs, BOTTOM_LEFT, BOTTOM_RIGHT); if (theApp.m_fontSymbol.m_hObject) { GetDlgItem(IDC_STATIC_DLTOof)->SetFont(&theApp.m_fontSymbol); @@ -211,10 +204,10 @@ void CSearchResultsWnd::DoDataExchange(CDataExchange *pDX) DDX_Control(pDX, IDC_SEARCHLIST, searchlistctrl); DDX_Control(pDX, IDC_PROGRESS1, searchprogress); DDX_Control(pDX, IDC_TAB1, searchselect); - DDX_Control(pDX, IDC_CATTAB2, *m_cattabs); + DDX_Control(pDX, IDC_CATTAB2, m_cattabs); DDX_Control(pDX, IDC_FILTER, m_ctlFilter); DDX_Control(pDX, IDC_OPEN_PARAMS_WND, m_ctlOpenParamsWnd); - DDX_Control(pDX, IDC_SEARCHLST_ICO, *m_btnSearchListMenu); + DDX_Control(pDX, IDC_SEARCHLST_ICO, m_btnSearchListMenu); } void CSearchResultsWnd::StartSearch(SSearchParams *pParams) @@ -260,7 +253,7 @@ void CSearchResultsWnd::OnTimer(UINT_PTR nIDEvent) pConnectedServer = theApp.serverlist->GetServerByAddress(pConnectedServer->GetAddress(), pConnectedServer->GetPort()); CServer *toask = NULL; - while (++servercount < theApp.serverlist->GetServerCount()) { + while (++m_servercount < (unsigned)theApp.serverlist->GetServerCount()) { searchprogress.StepIt(); toask = theApp.serverlist->GetNextSearchServer(); if (toask == NULL || (toask != pConnectedServer && toask->GetFailedCount() < thePrefs.GetDeadServerRetries())) @@ -275,7 +268,7 @@ void CSearchResultsWnd::OnTimer(UINT_PTR nIDEvent) uint32 nTagCount = 1; data.WriteUInt32(nTagCount); CTag tagFlags(CT_SERVER_UDPSEARCH_FLAGS, SRVCAP_UDP_NEWTAGS_LARGEFILES); - tagFlags.WriteNewEd2kTag(&data); + tagFlags.WriteNewEd2kTag(data); Packet *pExtSearchPacket = new Packet(OP_GLOBSEARCHREQ3, m_searchpacket->size + (uint32)data.GetLength()); data.SeekToBegin(); data.Read(pExtSearchPacket->pBuffer, (uint32)data.GetLength()); @@ -284,28 +277,28 @@ void CSearchResultsWnd::OnTimer(UINT_PTR nIDEvent) theApp.serverconnect->SendUDPPacket(pExtSearchPacket, toask, true); bRequestSent = true; if (thePrefs.GetDebugServerUDPLevel() > 0) - Debug(_T(">>> Sending %s to server %-21s (%3u of %3u)\n"), _T("OP_GlobSearchReq3"), (LPCTSTR)ipstr(toask->GetAddress(), toask->GetPort()), (unsigned)servercount, (unsigned)theApp.serverlist->GetServerCount()); + Debug(_T(">>> Sending %s to server %-21s (%3u of %3u)\n"), _T("OP_GlobSearchReq3"), (LPCTSTR)ipstr(toask->GetAddress(), toask->GetPort()), m_servercount, (unsigned)theApp.serverlist->GetServerCount()); } else if (toask->GetUDPFlags() & SRV_UDPFLG_EXT_GETFILES) { if (!m_b64BitSearchPacket || toask->SupportsLargeFilesUDP()) { m_searchpacket->opcode = OP_GLOBSEARCHREQ2; if (thePrefs.GetDebugServerUDPLevel() > 0) - Debug(_T(">>> Sending %s to server %-21s (%3u of %3u)\n"), _T("OP_GlobSearchReq2"), (LPCTSTR)ipstr(toask->GetAddress(), toask->GetPort()), (unsigned)servercount, (unsigned)theApp.serverlist->GetServerCount()); + Debug(_T(">>> Sending %s to server %-21s (%3u of %3u)\n"), _T("OP_GlobSearchReq2"), (LPCTSTR)ipstr(toask->GetAddress(), toask->GetPort()), m_servercount, (unsigned)theApp.serverlist->GetServerCount()); theStats.AddUpDataOverheadServer(m_searchpacket->size); theApp.serverconnect->SendUDPPacket(m_searchpacket, toask, false); bRequestSent = true; } else if (thePrefs.GetDebugServerUDPLevel() > 0) - Debug(_T(">>> Skipped UDP search on server %-21s (%3u of %3u): No large file support\n"), (LPCTSTR)ipstr(toask->GetAddress(), toask->GetPort()), (unsigned)servercount, (unsigned)theApp.serverlist->GetServerCount()); + Debug(_T(">>> Skipped UDP search on server %-21s (%3u of %3u): No large file support\n"), (LPCTSTR)ipstr(toask->GetAddress(), toask->GetPort()), m_servercount, (unsigned)theApp.serverlist->GetServerCount()); } else { if (!m_b64BitSearchPacket || toask->SupportsLargeFilesUDP()) { m_searchpacket->opcode = OP_GLOBSEARCHREQ; if (thePrefs.GetDebugServerUDPLevel() > 0) - Debug(_T(">>> Sending %s to server %-21s (%3u of %3u)\n"), _T("OP_GlobSearchReq1"), (LPCTSTR)ipstr(toask->GetAddress(), toask->GetPort()), (unsigned)servercount, (unsigned)theApp.serverlist->GetServerCount()); + Debug(_T(">>> Sending %s to server %-21s (%3u of %3u)\n"), _T("OP_GlobSearchReq1"), (LPCTSTR)ipstr(toask->GetAddress(), toask->GetPort()), m_servercount, (unsigned)theApp.serverlist->GetServerCount()); theStats.AddUpDataOverheadServer(m_searchpacket->size); theApp.serverconnect->SendUDPPacket(m_searchpacket, toask, false); bRequestSent = true; } else if (thePrefs.GetDebugServerUDPLevel() > 0) - Debug(_T(">>> Skipped UDP search on server %-21s (%3u of %3u): No large file support\n"), (LPCTSTR)ipstr(toask->GetAddress(), toask->GetPort()), (unsigned)servercount, (unsigned)theApp.serverlist->GetServerCount()); + Debug(_T(">>> Skipped UDP search on server %-21s (%3u of %3u): No large file support\n"), (LPCTSTR)ipstr(toask->GetAddress(), toask->GetPort()), m_servercount, (unsigned)theApp.serverlist->GetServerCount()); } if (bRequestSent) theApp.searchlist->SentUDPRequestNotification(m_nEd2kSearchID, toask->GetIP()); @@ -405,7 +398,7 @@ void CSearchResultsWnd::CancelEd2kSearch() { SetInactiveSearchResultsIcon(m_nEd2kSearchID); - cancelled = true; + m_cancelled = true; // delete any global search timer if (global_search_timer) { @@ -434,7 +427,7 @@ void CSearchResultsWnd::CancelKadSearch(uint32 uSearchID) void CSearchResultsWnd::SearchStarted() { - CWnd *pWndFocus = GetFocus(); + const CWnd *pWndFocus = GetFocus(); m_pwndParams->m_ctlStart.EnableWindow(FALSE); if (pWndFocus && pWndFocus->m_hWnd == m_pwndParams->m_ctlStart.m_hWnd) m_pwndParams->m_ctlName.SetFocus(); @@ -450,7 +443,7 @@ void CSearchResultsWnd::SearchCancelled(uint32 uSearchID) TCITEM item; item.mask = TCIF_PARAM; if (searchselect.GetItem(iSel, &item) && item.lParam != NULL && uSearchID == reinterpret_cast(item.lParam)->dwSearchID) { - CWnd *pWndFocus = GetFocus(); + const CWnd *pWndFocus = GetFocus(); m_pwndParams->m_ctlCancel.EnableWindow(FALSE); if (pWndFocus && pWndFocus->m_hWnd == m_pwndParams->m_ctlCancel.m_hWnd) m_pwndParams->m_ctlName.SetFocus(); @@ -468,7 +461,7 @@ void CSearchResultsWnd::LocalEd2kSearchEnd(UINT count, bool bMoreResultsAvailabl } AddEd2kSearchResults(count); - if (!cancelled) { + if (!m_cancelled) { if (!m_globsearch) SearchCancelled(m_nEd2kSearchID); else if (!global_search_timer) @@ -479,7 +472,7 @@ void CSearchResultsWnd::LocalEd2kSearchEnd(UINT count, bool bMoreResultsAvailabl void CSearchResultsWnd::AddEd2kSearchResults(UINT count) { - if (!cancelled && count > MAX_RESULTS) + if (!m_cancelled && count > MAX_RESULTS) CancelEd2kSearch(); } @@ -563,7 +556,7 @@ void CSearchResultsWnd::OnSysColorChange() void CSearchResultsWnd::SetAllIcons() { - m_btnSearchListMenu->SetIcon(_T("SearchResults")); + m_btnSearchListMenu.SetIcon(_T("SearchResults")); CImageList iml; iml.Create(16, 16, theApp.m_iDfltImageListColorFlags | ILC_MASK, 0, 1); @@ -587,7 +580,7 @@ void CSearchResultsWnd::Localize() UpdateCatTabs(); SetDlgItemText(IDC_CLEARALL, GetResString(IDS_REMOVEALLSEARCH)); - m_btnSearchListMenu->SetWindowText(GetResString(IDS_SW_RESULT)); + m_btnSearchListMenu.SetWindowText(GetResString(IDS_SW_RESULT)); SetDlgItemText(IDC_SDOWNLOAD, GetResString(IDS_SW_DOWNLOAD)); m_ctlOpenParamsWnd.SetWindowText(GetResString(IDS_SEARCHPARAMS) + _T("...")); } @@ -703,12 +696,12 @@ bool DumpSearchTree(int &iExpr, const CSearchExpr &rSearchExpr, int iLevel, bool return false; if (!bFlat) s_strSearchTree.AppendFormat(_T("\n%s"), (LPCTSTR)CString(_T(' '), iLevel)); - const CSearchAttr &rSearchAttr = rSearchExpr.m_aExpr[iExpr++]; - CStringA strTok = rSearchAttr.m_str; + const CSearchAttr &rSearchAttr(rSearchExpr.m_aExpr[iExpr++]); + CStringA strTok(rSearchAttr.m_str); if (bFlat && s_chLastChar != _T('(') && s_chLastChar != _T('\0')) s_strSearchTree += _T(' '); if (strTok == SEARCHOPTOK_AND || strTok == SEARCHOPTOK_OR || strTok == SEARCHOPTOK_NOT) { - s_strSearchTree.AppendFormat(_T("(%hs "), (LPCSTR)strTok.Mid(1)); + s_strSearchTree.AppendFormat(_T("(%hs "), CPTRA(strTok, 1)); s_chLastChar = _T('('); DumpSearchTree(iExpr, rSearchExpr, iLevel + 4, bFlat); DumpSearchTree(iExpr, rSearchExpr, iLevel + 4, bFlat); @@ -729,25 +722,25 @@ bool DumpSearchTree(const CSearchExpr &rSearchExpr, bool bFlat) return DumpSearchTree(iExpr, rSearchExpr, iLevel, bFlat); } -void ParsedSearchExpression(const CSearchExpr *pexpr) +void ParsedSearchExpression(const CSearchExpr &expr) { int iOpAnd = 0; int iOpOr = 0; int iOpNot = 0; int iNonDefTags = 0; //CStringA strDbg; - for (int i = 0; i < pexpr->m_aExpr.GetCount(); ++i) { - const CSearchAttr &rSearchAttr = pexpr->m_aExpr[i]; - const CStringA &rstr = rSearchAttr.m_str; + for (int i = 0; i < expr.m_aExpr.GetCount(); ++i) { + const CSearchAttr &rSearchAttr(expr.m_aExpr[i]); + const CStringA &rstr(rSearchAttr.m_str); if (rstr == SEARCHOPTOK_AND) { ++iOpAnd; - //strDbg.AppendFormat("%s ", rstr.Mid(1)); + //strDbg.AppendFormat("%s ", CPTR(rstr, 1)); } else if (rstr == SEARCHOPTOK_OR) { ++iOpOr; - //strDbg.AppendFormat("%s ", rstr.Mid(1)); + //strDbg.AppendFormat("%s ", CPTR(rstr, 1)); } else if (rstr == SEARCHOPTOK_NOT) { ++iOpNot; - //strDbg.AppendFormat("%s ", rstr.Mid(1)); + //strDbg.AppendFormat("%s ", CPTR(rstr, 1)); } else { if (rSearchAttr.m_iTag != FT_FILENAME) ++iNonDefTags; @@ -780,8 +773,8 @@ void ParsedSearchExpression(const CSearchExpr *pexpr) // do not try to rearrange keywords, which could make a search valid if (!s_strCurKadKeywordA.IsEmpty() && iOpOr > 0) if (iOpAnd + iOpNot > 0) { - if (pexpr->m_aExpr.GetCount() > 2) - if (pexpr->m_aExpr[0].m_str == SEARCHOPTOK_OR && pexpr->m_aExpr[1].m_str == s_strCurKadKeywordA) + if (expr.m_aExpr.GetCount() > 2) + if (expr.m_aExpr[0].m_str == SEARCHOPTOK_OR && expr.m_aExpr[1].m_str == s_strCurKadKeywordA) yyerror(GetResString(IDS_SEARCH_BADOPERATORCOMBINATION)); } else // if we habe only OR its not going to work out for sure yyerror(GetResString(IDS_SEARCH_BADOPERATORCOMBINATION)); @@ -796,12 +789,12 @@ void ParsedSearchExpression(const CSearchExpr *pexpr) // the same or even better if we ask the node which indexes the rare keyword "oxymoronaccelerator", so we try to rearrange // keywords and generally assume that the longer keywords are rarer if (thePrefs.GetRearrangeKadSearchKeywords() && !s_strCurKadKeywordA.IsEmpty()) { - for (int i = 0; i < pexpr->m_aExpr.GetCount(); ++i) { - const CStringA &cs = pexpr->m_aExpr[i].m_str; + for (int i = 0; i < expr.m_aExpr.GetCount(); ++i) { + const CStringA &cs(expr.m_aExpr[i].m_str); if ( cs != SEARCHOPTOK_AND && cs != s_strCurKadKeywordA - && cs.FindOneOf(g_aszInvKadKeywordCharsA) == -1 - && cs.Find('"') != 0 // no quoted expression as a keyword + && cs.FindOneOf(g_aszInvKadKeywordCharsA) < 0 + && cs[0] != '"' // no quoted expression as a keyword && cs.GetLength() >= 3 && s_strCurKadKeywordA.GetLength() < cs.GetLength()) { @@ -811,10 +804,10 @@ void ParsedSearchExpression(const CSearchExpr *pexpr) } CStringA strAndTerms; - for (int i = 0; i < pexpr->m_aExpr.GetCount(); ++i) { - const CStringA &cs = pexpr->m_aExpr[i].m_str; + for (int i = 0; i < expr.m_aExpr.GetCount(); ++i) { + const CStringA &cs(expr.m_aExpr[i].m_str); if (cs != SEARCHOPTOK_AND) { - ASSERT(pexpr->m_aExpr[i].m_iTag == FT_FILENAME); + ASSERT(expr.m_aExpr[i].m_iTag == FT_FILENAME); // Minor optimization: Because we added the Kad keyword to the boolean search expression, // we remove it here (and only here) again because we know that the entire search expression // does only contain (implicit) ANDed strings. @@ -827,22 +820,22 @@ void ParsedSearchExpression(const CSearchExpr *pexpr) } ASSERT(s_SearchExpr.m_aExpr.IsEmpty()); s_SearchExpr.m_aExpr.Add(CSearchAttr(strAndTerms)); - } else if (pexpr->m_aExpr.GetCount() != 1 - || !(pexpr->m_aExpr[0].m_iTag == FT_FILENAME && pexpr->m_aExpr[0].m_str == s_strCurKadKeywordA)) + } else if (expr.m_aExpr.GetCount() != 1 + || !(expr.m_aExpr[0].m_iTag == FT_FILENAME && expr.m_aExpr[0].m_str == s_strCurKadKeywordA)) { - s_SearchExpr.m_aExpr.Append(pexpr->m_aExpr); + s_SearchExpr.m_aExpr.Append(expr.m_aExpr); } } class CSearchExprTarget { public: - CSearchExprTarget(CSafeMemFile *pData, EUTF8str eStrEncode, bool bSupports64Bit, bool *pbPacketUsing64Bit) - : m_eStrEncode(eStrEncode) + CSearchExprTarget(CSafeMemFile &data, EUTF8str eStrEncode, bool bSupports64Bit, bool *pbPacketUsing64Bit) + : m_data(data) + , m_pbPacketUsing64Bit(pbPacketUsing64Bit) + , m_eStrEncode(eStrEncode) + , m_bSupports64Bit(bSupports64Bit) { - m_data = pData; - m_bSupports64Bit = bSupports64Bit; - m_pbPacketUsing64Bit = pbPacketUsing64Bit; if (m_pbPacketUsing64Bit) *m_pbPacketUsing64Bit = false; } @@ -854,55 +847,55 @@ class CSearchExprTarget void WriteBooleanAND() { - m_data->WriteUInt8(0); // boolean operator parameter type - m_data->WriteUInt8(0x00); // "AND" + m_data.WriteUInt8(0); // boolean operator parameter type + m_data.WriteUInt8(0x00); // "AND" m_strDbg.AppendFormat(_T("AND ")); } void WriteBooleanOR() { - m_data->WriteUInt8(0); // boolean operator parameter type - m_data->WriteUInt8(0x01); // "OR" + m_data.WriteUInt8(0); // boolean operator parameter type + m_data.WriteUInt8(0x01); // "OR" m_strDbg.AppendFormat(_T("OR ")); } void WriteBooleanNOT() { - m_data->WriteUInt8(0); // boolean operator parameter type - m_data->WriteUInt8(0x02); // "NOT" + m_data.WriteUInt8(0); // boolean operator parameter type + m_data.WriteUInt8(0x02); // "NOT" m_strDbg.AppendFormat(_T("NOT ")); } void WriteMetaDataSearchParam(const CString &rstrValue) { - m_data->WriteUInt8(1); // string parameter type - m_data->WriteString(rstrValue, m_eStrEncode); // string value + m_data.WriteUInt8(1); // string parameter type + m_data.WriteString(rstrValue, m_eStrEncode); // string value m_strDbg.AppendFormat(_T("\"%s\" "), (LPCTSTR)rstrValue); } void WriteMetaDataSearchParam(UINT uMetaTagID, const CString &rstrValue) { - m_data->WriteUInt8(2); // string parameter type - m_data->WriteString(rstrValue, m_eStrEncode); // string value - m_data->WriteUInt16(sizeof(uint8)); // meta tag ID length - m_data->WriteUInt8((uint8)uMetaTagID); // meta tag ID name + m_data.WriteUInt8(2); // string parameter type + m_data.WriteString(rstrValue, m_eStrEncode); // string value + m_data.WriteUInt16(sizeof(uint8)); // meta tag ID length + m_data.WriteUInt8((uint8)uMetaTagID); // meta tag ID name m_strDbg.AppendFormat(_T("%s=\"%s\" "), (LPCTSTR)DbgGetFileMetaTagName(uMetaTagID), (LPCTSTR)rstrValue); } void WriteMetaDataSearchParamA(UINT uMetaTagID, const CStringA &rstrValueA) { - m_data->WriteUInt8(2); // string parameter type - m_data->WriteString(rstrValueA); // string value - m_data->WriteUInt16(sizeof(uint8)); // meta tag ID length - m_data->WriteUInt8((uint8)uMetaTagID); // meta tag ID name + m_data.WriteUInt8(2); // string parameter type + m_data.WriteString(rstrValueA); // string value + m_data.WriteUInt16(sizeof(uint8)); // meta tag ID length + m_data.WriteUInt8((uint8)uMetaTagID); // meta tag ID name m_strDbg.AppendFormat(_T("%s=\"%hs\" "), (LPCTSTR)DbgGetFileMetaTagName(uMetaTagID), (LPCSTR)rstrValueA); } void WriteMetaDataSearchParam(LPCSTR pszMetaTagID, const CString &rstrValue) { - m_data->WriteUInt8(2); // string parameter type - m_data->WriteString(rstrValue, m_eStrEncode); // string value - m_data->WriteString(pszMetaTagID); // meta tag ID + m_data.WriteUInt8(2); // string parameter type + m_data.WriteString(rstrValue, m_eStrEncode); // string value + m_data.WriteString(pszMetaTagID); // meta tag ID m_strDbg.AppendFormat(_T("%s=\"%s\" "), (LPCTSTR)DbgGetFileMetaTagName(pszMetaTagID), (LPCTSTR)rstrValue); } @@ -912,45 +905,45 @@ class CSearchExprTarget if (b64BitValue && m_bSupports64Bit) { if (m_pbPacketUsing64Bit) *m_pbPacketUsing64Bit = true; - m_data->WriteUInt8(8); // numeric parameter type (int64) - m_data->WriteUInt64(ullValue); // numeric value + m_data.WriteUInt8(8); // numeric parameter type (int64) + m_data.WriteUInt64(ullValue); // numeric value } else { if (b64BitValue) - ullValue = 0xFFFFFFFFU; - m_data->WriteUInt8(3); // numeric parameter type (int32) - m_data->WriteUInt32((uint32)ullValue); // numeric value + ullValue = _UI32_MAX; + m_data.WriteUInt8(3); // numeric parameter type (int32) + m_data.WriteUInt32((uint32)ullValue); // numeric value } - m_data->WriteUInt8((uint8)uOperator); // comparison operator - m_data->WriteUInt16(sizeof(uint8)); // meta tag ID length - m_data->WriteUInt8((uint8)uMetaTagID); // meta tag ID name + m_data.WriteUInt8((uint8)uOperator); // comparison operator + m_data.WriteUInt16(sizeof(uint8)); // meta tag ID length + m_data.WriteUInt8((uint8)uMetaTagID); // meta tag ID name m_strDbg.AppendFormat(_T("%s%s%I64u "), (LPCTSTR)DbgGetFileMetaTagName(uMetaTagID), (LPCTSTR)DbgGetSearchOperatorName(uOperator), ullValue); } void WriteMetaDataSearchParam(LPCSTR pszMetaTagID, UINT uOperator, uint64 ullValue) { - bool b64BitValue = ullValue > 0xFFFFFFFFui64; + bool b64BitValue = ullValue > _UI32_MAX; if (b64BitValue && m_bSupports64Bit) { if (m_pbPacketUsing64Bit) *m_pbPacketUsing64Bit = true; - m_data->WriteUInt8(8); // numeric parameter type (int64) - m_data->WriteUInt64(ullValue); // numeric value + m_data.WriteUInt8(8); // numeric parameter type (int64) + m_data.WriteUInt64(ullValue); // numeric value } else { if (b64BitValue) - ullValue = 0xFFFFFFFFU; - m_data->WriteUInt8(3); // numeric parameter type (int32) - m_data->WriteUInt32((uint32)ullValue); // numeric value + ullValue = _UI32_MAX; + m_data.WriteUInt8(3); // numeric parameter type (int32) + m_data.WriteUInt32((uint32)ullValue); // numeric value } - m_data->WriteUInt8((uint8)uOperator); // comparison operator - m_data->WriteString(pszMetaTagID); // meta tag ID + m_data.WriteUInt8((uint8)uOperator); // comparison operator + m_data.WriteString(pszMetaTagID); // meta tag ID m_strDbg.AppendFormat(_T("%s%s%I64u "), (LPCTSTR)DbgGetFileMetaTagName(pszMetaTagID), (LPCTSTR)DbgGetSearchOperatorName(uOperator), ullValue); } protected: - CSafeMemFile *m_data; + CSafeMemFile &m_data; CString m_strDbg; + bool *m_pbPacketUsing64Bit; EUTF8str m_eStrEncode; bool m_bSupports64Bit; - bool *m_pbPacketUsing64Bit; }; static CSearchExpr s_SearchExpr2; @@ -969,21 +962,22 @@ static void AddAndAttr(UINT uTag, UINT uOpr, uint64 ullVal) s_SearchExpr2.m_aExpr.InsertAt(0, CSearchAttr(SEARCHOPTOK_AND)); } -bool GetSearchPacket(CSafeMemFile *pData, SSearchParams *pParams, bool bTargetSupports64Bit, bool *pbPacketUsing64Bit) +bool GetSearchPacket(CSafeMemFile &data, SSearchParams *pParams, bool bTargetSupports64Bit, bool *pbPacketUsing64Bit) { - CString strFileType; + LPCTSTR pFileType; if (pParams->strFileType == _T(ED2KFTSTR_ARCHIVE)) { // eDonkeyHybrid 0.48 uses type "Pro" for archives files // www.filedonkey.com used type "Pro" for archives files - strFileType = _T(ED2KFTSTR_PROGRAM); + pFileType = _T(ED2KFTSTR_PROGRAM); } else if (pParams->strFileType == _T(ED2KFTSTR_CDIMAGE)) { // eDonkeyHybrid 0.48 uses *no* type for iso/nrg/cue/img files // www.filedonkey.com used type "Pro" for CD-image files - strFileType = _T(ED2KFTSTR_PROGRAM); + pFileType = _T(ED2KFTSTR_PROGRAM); } else { //TODO: Support "Doc" types - strFileType = pParams->strFileType; + pFileType = pParams->strFileType; } + const CString &strFileType(pFileType); s_strCurKadKeywordA.Empty(); ASSERT(!pParams->strExpression.IsEmpty()); @@ -1030,7 +1024,7 @@ bool GetSearchPacket(CSafeMemFile *pData, SSearchParams *pParams, bool bTargetSu //} // create ed2k search expression - CSearchExprTarget target(pData, UTF8strRaw, bTargetSupports64Bit, pbPacketUsing64Bit); + CSearchExprTarget target(data, UTF8strRaw, bTargetSupports64Bit, pbPacketUsing64Bit); s_SearchExpr2.m_aExpr.RemoveAll(); @@ -1052,11 +1046,11 @@ bool GetSearchPacket(CSafeMemFile *pData, SSearchParams *pParams, bool bTargetSu if (pParams->uComplete > 0) AddAndAttr(FT_COMPLETE_SOURCES, ED2K_SEARCH_OP_GREATER_EQUAL, pParams->uComplete); - if (pParams->ulMinBitrate > 0) - AddAndAttr(FT_MEDIA_BITRATE, ED2K_SEARCH_OP_GREATER_EQUAL, pParams->ulMinBitrate); + if (pParams->uiMinBitrate > 0) + AddAndAttr(FT_MEDIA_BITRATE, ED2K_SEARCH_OP_GREATER_EQUAL, pParams->uiMinBitrate); - if (pParams->ulMinLength > 0) - AddAndAttr(FT_MEDIA_LENGTH, ED2K_SEARCH_OP_GREATER_EQUAL, pParams->ulMinLength); + if (pParams->uiMinLength > 0) + AddAndAttr(FT_MEDIA_LENGTH, ED2K_SEARCH_OP_GREATER_EQUAL, pParams->uiMinLength); if (!pParams->strCodec.IsEmpty()) AddAndAttr(FT_MEDIA_CODEC, pParams->strCodec); @@ -1083,8 +1077,8 @@ bool GetSearchPacket(CSafeMemFile *pData, SSearchParams *pParams, bool bTargetSu } for (int j = 0; j < s_SearchExpr.m_aExpr.GetCount(); ++j) { - const CSearchAttr &rSearchAttr = s_SearchExpr.m_aExpr[j]; - const CStringA &rstrA = rSearchAttr.m_str; + const CSearchAttr &rSearchAttr(s_SearchExpr.m_aExpr[j]); + const CStringA &rstrA(rSearchAttr.m_str); if (rstrA == SEARCHOPTOK_AND) target.WriteBooleanAND(); else if (rstrA == SEARCHOPTOK_OR) @@ -1100,8 +1094,8 @@ bool GetSearchPacket(CSafeMemFile *pData, SSearchParams *pParams, bool bTargetSu case FT_MEDIA_BITRATE: case FT_MEDIA_LENGTH: // 11-Sep-2005 []: Kad comparison operators where changed to match the ED2K operators. For backward - // compatibility with old Kad nodes, we map ">=val" and "<=val" to ">val-1" and "=val" and "<=val". + // compatibility with old Kad nodes, we map ">=val" and "<=val" to ">val-1" and "=val" and "<=val". // // TODO: This should be removed in couple of months! //if (rSearchAttr.m_uIntegerOperator == ED2K_SEARCH_OP_GREATER_EQUAL) @@ -1139,7 +1133,7 @@ bool CSearchResultsWnd::StartNewSearch(SSearchParams *pParams) if (pParams->eType == SearchTypeAutomatic) { // select between kad and server - // its easy if we are connected to one network only anyway + // its easy if we are connected to one network only if (!theApp.serverconnect->IsConnected() && Kademlia::CKademlia::IsRunning() && Kademlia::CKademlia::IsConnected()) pParams->eType = SearchTypeKademlia; else if (theApp.serverconnect->IsConnected() && (!Kademlia::CKademlia::IsRunning() || !Kademlia::CKademlia::IsConnected())) @@ -1153,15 +1147,17 @@ bool CSearchResultsWnd::StartNewSearch(SSearchParams *pParams) // connected to both // We choose Kad, except // - if we are connected to a static server - // - or a server with more than 40k and less than 2mio users connected, more than 5 mio files and if our serverlist contains less than - // 40 servers (otherwise we have assume that its polluted with fake server and we might just as well be connected to one) + // - or a server with more than 40k and less than 2mio users connected, + // more than 5 mio files and if our serverlist contains less than 40 servers + // (otherwise we have assume that its polluted with fake servers and we might + // just as well to be connected to one) // might be further optimized in the future const CServer *curserv = theApp.serverconnect->GetCurrentServer(); pParams->eType = ( theApp.serverconnect->IsConnected() && curserv != NULL && (curserv->IsStaticMember() || (curserv->GetUsers() > 40000 && theApp.serverlist->GetServerCount() < 40 - && curserv->GetUsers() < 2000000 + && curserv->GetUsers() < 2000000 //was 5M - copy & paste bug && curserv->GetFiles() > 5000000)) ) ? SearchTypeEd2kServer : SearchTypeKademlia; @@ -1187,7 +1183,6 @@ bool CSearchResultsWnd::StartNewSearch(SSearchParams *pParams) SearchStarted(); return true; - case SearchTypeKademlia: if (!Kademlia::CKademlia::IsRunning() || !Kademlia::CKademlia::IsConnected()) { LocMessageBox(IDS_ERR_NOTCONNECTEDKAD, MB_ICONWARNING, 0); @@ -1224,32 +1219,32 @@ bool CSearchResultsWnd::DoNewEd2kSearch(SSearchParams *pParams) && (theApp.serverconnect->GetCurrentServer()->GetTCPFlags() & SRV_TCPFLG_LARGEFILES); bool bPacketUsing64Bit = false; CSafeMemFile data(100); - if (!GetSearchPacket(&data, pParams, bServerSupports64Bit, &bPacketUsing64Bit) || data.GetLength() == 0) + if (!GetSearchPacket(data, pParams, bServerSupports64Bit, &bPacketUsing64Bit) || data.GetLength() == 0) return false; CancelEd2kSearch(); - CString strResultType = pParams->strFileType; + CString strResultType(pParams->strFileType); if (strResultType == _T(ED2KFTSTR_PROGRAM)) strResultType.Empty(); pParams->dwSearchID = GetNextSearchID(); theApp.searchlist->NewSearch(&searchlistctrl, strResultType, pParams); - cancelled = false; + m_cancelled = false; if (m_uTimerLocalServer) { VERIFY(KillTimer(m_uTimerLocalServer)); m_uTimerLocalServer = 0; } - // once we've sent a new search request, any previously received 'More' gets invalid. - CWnd *pWndFocus = GetFocus(); + // sending a new search request invalidates any previously received 'More' + const CWnd *pWndFocus = GetFocus(); m_pwndParams->m_ctlMore.EnableWindow(FALSE); if (pWndFocus && pWndFocus->m_hWnd == m_pwndParams->m_ctlMore.m_hWnd) m_pwndParams->m_ctlCancel.SetFocus(); m_iSentMoreReq = 0; - Packet *packet = new Packet(&data); + Packet *packet = new Packet(data); packet->opcode = OP_SEARCHREQUEST; if (thePrefs.GetDebugServerTCPLevel() > 0) Debug(_T(">>> Sending OP_SearchRequest\n")); @@ -1268,7 +1263,7 @@ bool CSearchResultsWnd::DoNewEd2kSearch(SSearchParams *pParams) m_searchpacket->opcode = OP_GLOBSEARCHREQ; // will be changed later when actually sending the packet!! m_b64BitSearchPacket = bPacketUsing64Bit; - servercount = 0; + m_servercount = 0; searchprogress.SetRange32(0, (int)theApp.serverlist->GetServerCount() - 1); } CreateNewTab(pParams); @@ -1281,7 +1276,7 @@ bool CSearchResultsWnd::SearchMore() return false; SetActiveSearchResultsIcon(m_nEd2kSearchID); - cancelled = false; + m_cancelled = false; Packet *packet = new Packet(); packet->opcode = OP_QUERY_MORE_RESULT; @@ -1300,19 +1295,19 @@ bool CSearchResultsWnd::DoNewKadSearch(SSearchParams *pParams) int iPos = 0; pParams->strKeyword = pParams->strExpression.Tokenize(_T(" "), iPos); - if (pParams->strKeyword[0] == _T('\"')) { + if (pParams->strKeyword[0] == _T('"')) { // remove leading and possibly trailing quotes, if they terminate properly (otherwise the keyword is later handled as invalid) // (quotes are still kept in search expr and matched against the result, so everything is fine) const int iLen = pParams->strKeyword.GetLength(); - if (iLen > 1 && pParams->strKeyword.Right(1) == _T("\"")) + if (iLen > 1 && pParams->strKeyword[iLen - 1] == _T('"')) pParams->strKeyword = pParams->strKeyword.Mid(1, iLen - 2); - else if (pParams->strExpression.Find(_T('\"'), 1) > iLen) + else if (pParams->strExpression.Find(_T('"'), 1) > iLen) pParams->strKeyword = pParams->strKeyword.Mid(1, iLen - 1); } pParams->strKeyword.Trim(); CSafeMemFile data(100); - if (!GetSearchPacket(&data, pParams, true, NULL)/* || (!pParams->strBooleanExpr.IsEmpty() && data.GetLength() == 0)*/) + if (!GetSearchPacket(data, pParams, true, NULL)/* || (!pParams->strBooleanExpr.IsEmpty() && data.GetLength() == 0)*/) return false; if (pParams->strKeyword.IsEmpty() || pParams->strKeyword.FindOneOf(g_aszInvKadKeywordChars) >= 0) { @@ -1343,7 +1338,7 @@ bool CSearchResultsWnd::DoNewKadSearch(SSearchParams *pParams) throw new CMsgBoxException(strException, MB_ICONWARNING | MB_HELP, eMule_FAQ_Search - HID_BASE_PROMPT); } pParams->dwSearchID = pSearch->GetSearchID(); - CString strResultType = pParams->strFileType; + CString strResultType(pParams->strFileType); if (strResultType == ED2KFTSTR_PROGRAM) strResultType.Empty(); theApp.searchlist->NewSearch(&searchlistctrl, strResultType, pParams); @@ -1368,7 +1363,7 @@ bool CSearchResultsWnd::CreateNewTab(SSearchParams *pParams, bool bActiveIcon) newitem.lParam = (LPARAM)pParams; pParams->strSearchTitle = (pParams->strSpecialTitle.IsEmpty() ? pParams->strExpression : pParams->strSpecialTitle); CString strTcLabel(pParams->strSearchTitle); - strTcLabel.Replace(_T("&"), _T("&&")); + DupAmpersand(strTcLabel); newitem.pszText = const_cast((LPCTSTR)strTcLabel); newitem.cchTextMax = 0; if (pParams->bClientSharedFiles) @@ -1420,7 +1415,7 @@ void CSearchResultsWnd::DeleteSearch(uint32 uSearchID) // delete search results if (uSearchID == m_nEd2kSearchID) { - if (!cancelled) + if (!m_cancelled) CancelEd2kSearch(); m_pwndParams->m_ctlMore.EnableWindow(FALSE); } @@ -1539,14 +1534,14 @@ LRESULT CSearchResultsWnd::OnCloseTab(WPARAM wParam, LPARAM) item.mask = TCIF_PARAM; if (searchselect.GetItem((int)wParam, &item) && item.lParam != NULL) { uint32 uSearchID = reinterpret_cast(item.lParam)->dwSearchID; - if (!cancelled && uSearchID == m_nEd2kSearchID) + if (!m_cancelled && uSearchID == m_nEd2kSearchID) CancelEd2kSearch(); DeleteSearch(uSearchID); } return TRUE; } -LRESULT CSearchResultsWnd::OnDblClickTab(WPARAM wParam, LPARAM /*lParam*/) +LRESULT CSearchResultsWnd::OnDblClickTab(WPARAM wParam, LPARAM) { TCITEM item; item.mask = TCIF_PARAM; @@ -1557,51 +1552,55 @@ LRESULT CSearchResultsWnd::OnDblClickTab(WPARAM wParam, LPARAM /*lParam*/) int CSearchResultsWnd::GetSelectedCat() { - return m_cattabs->GetCurSel(); + return m_cattabs.GetCurSel(); } void CSearchResultsWnd::UpdateCatTabs() { - int oldsel = m_cattabs->GetCurSel(); - m_cattabs->DeleteAllItems(); + int oldsel = m_cattabs.GetCurSel(); + m_cattabs.DeleteAllItems(); for (INT_PTR i = 0; i < thePrefs.GetCatCount(); ++i) { CString label(i ? thePrefs.GetCategory(i)->strTitle : GetResString(IDS_ALL)); - label.Replace(_T("&"), _T("&&")); - m_cattabs->InsertItem((int)i, label); + DupAmpersand(label); + m_cattabs.InsertItem((int)i, label); } - if (oldsel >= m_cattabs->GetItemCount() || oldsel < 0) + if (oldsel >= m_cattabs.GetItemCount() || oldsel < 0) oldsel = 0; - m_cattabs->SetCurSel(oldsel); - int flag = (m_cattabs->GetItemCount() > 1) ? SW_SHOW : SW_HIDE; - m_cattabs->ShowWindow(flag); + m_cattabs.SetCurSel(oldsel); + int flag = (m_cattabs.GetItemCount() > 1) ? SW_SHOW : SW_HIDE; + m_cattabs.ShowWindow(flag); GetDlgItem(IDC_STATIC_DLTOof)->ShowWindow(flag); } void CSearchResultsWnd::ShowSearchSelector(bool visible) { - WINDOWPLACEMENT wpSearchWinPos; - WINDOWPLACEMENT wpSelectWinPos; - searchselect.GetWindowPlacement(&wpSelectWinPos); - searchlistctrl.GetWindowPlacement(&wpSearchWinPos); - if (visible) - wpSearchWinPos.rcNormalPosition.top = wpSelectWinPos.rcNormalPosition.bottom; - else - wpSearchWinPos.rcNormalPosition.top = wpSelectWinPos.rcNormalPosition.top; - searchselect.ShowWindow(visible ? SW_SHOW : SW_HIDE); + WINDOWPLACEMENT wpTabSelect, wpList; + searchselect.GetWindowPlacement(&wpTabSelect); + searchlistctrl.GetWindowPlacement(&wpList); + + int nCmdShow; + if (visible) { + nCmdShow = SW_SHOW; + wpList.rcNormalPosition.top = wpTabSelect.rcNormalPosition.bottom; + } else { + nCmdShow = SW_HIDE; + wpList.rcNormalPosition.top = wpTabSelect.rcNormalPosition.top; + } + searchselect.ShowWindow(nCmdShow); RemoveAnchor(searchlistctrl); - searchlistctrl.SetWindowPlacement(&wpSearchWinPos); + searchlistctrl.SetWindowPlacement(&wpList); AddAnchor(searchlistctrl, TOP_LEFT, BOTTOM_RIGHT); - GetDlgItem(IDC_CLEARALL)->ShowWindow(visible ? SW_SHOW : SW_HIDE); - m_ctlFilter.ShowWindow(visible ? SW_SHOW : SW_HIDE); + GetDlgItem(IDC_CLEARALL)->ShowWindow(nCmdShow); + m_ctlFilter.ShowWindow(nCmdShow); } void CSearchResultsWnd::OnDestroy() { - for (int i = searchselect.GetItemCount(); --i >= 0;) { + for (INT_PTR i = searchselect.GetItemCount(); --i >= 0;) { TCITEM item; item.mask = TCIF_PARAM; - if (searchselect.GetItem(i, &item)) + if (searchselect.GetItem((int)i, &item)) delete reinterpret_cast(item.lParam); } @@ -1735,7 +1734,7 @@ LRESULT CSearchResultsWnd::OnChangeFilter(WPARAM wParam, LPARAM lParam) m_nFilterColumn = (uint32)wParam; CStringArray astrFilter; - CString strFullFilterExpr = (LPCTSTR)lParam; + const CString &strFullFilterExpr((LPCTSTR)lParam); for (int iPos = 0; iPos >= 0;) { const CString &strFilter(strFullFilterExpr.Tokenize(_T(" "), iPos)); if (!strFilter.IsEmpty() && strFilter != _T("-")) @@ -1781,7 +1780,7 @@ void CSearchResultsWnd::OnSearchListMenuBtnDropDown(LPNMHDR, LRESULT*) menu.AppendMenu(MF_POPUP, (UINT_PTR)menuFileSizeFormat.m_hMenu, GetResString(IDS_DL_SIZE)); RECT rc; - m_btnSearchListMenu->GetWindowRect(&rc); + m_btnSearchListMenu.GetWindowRect(&rc); menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, rc.left, rc.bottom, this); } diff --git a/srchybrid/SearchResultsWnd.h b/srchybrid/SearchResultsWnd.h index 50b7c42c..c22a262e 100644 --- a/srchybrid/SearchResultsWnd.h +++ b/srchybrid/SearchResultsWnd.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -17,7 +17,9 @@ #pragma once #include "ResizableLib\ResizableFormView.h" #include "SearchListCtrl.h" +#include "ButtonsTabCtrl.h" #include "ClosableTabCtrl.h" +#include "DropDownButton.h" #include "IconStatic.h" #include "EditX.h" #include "EditDelayed.h" @@ -29,8 +31,6 @@ class Packet; class CSafeMemFile; class CSearchParamsWnd; struct SSearchParams; -class CDropDownButton; -class CButtonsTabCtrl; /////////////////////////////////////////////////////////////////////////////// @@ -69,8 +69,8 @@ class CSearchResultsWnd : public CResizableFormView CSearchListCtrl searchlistctrl; CSearchResultsSelector searchselect; - CSearchParamsWnd *m_pwndParams; CStringArray m_astrFilter; + CSearchParamsWnd *m_pwndParams; void Localize(); @@ -112,23 +112,23 @@ class CSearchResultsWnd : public CResizableFormView uint32 GetFilterColumn() const { return m_nFilterColumn; } protected: - Packet *m_searchpacket; - bool m_b64BitSearchPacket; - UINT_PTR global_search_timer; - UINT_PTR m_uTimerLocalServer; CProgressCtrl searchprogress; CHeaderCtrl m_ctlSearchListHeader; CEditDelayed m_ctlFilter; CButton m_ctlOpenParamsWnd; - bool cancelled; - uint16 servercount; - bool m_globsearch; - uint32 m_nEd2kSearchID; CImageList m_imlSearchResults; - CButtonsTabCtrl *m_cattabs; - CDropDownButton *m_btnSearchListMenu; - int m_iSentMoreReq; + CButtonsTabCtrl m_cattabs; + CDropDownButton m_btnSearchListMenu; + Packet *m_searchpacket; + UINT_PTR global_search_timer; + UINT_PTR m_uTimerLocalServer; + uint32 m_nEd2kSearchID; uint32 m_nFilterColumn; + unsigned m_servercount; + int m_iSentMoreReq; + bool m_b64BitSearchPacket; + bool m_globsearch; + bool m_cancelled; bool StartNewSearch(SSearchParams *pParams); void SearchStarted(); @@ -150,7 +150,7 @@ class CSearchResultsWnd : public CResizableFormView afx_msg void OnDblClkSearchList(LPNMHDR, LRESULT *pResult); afx_msg void OnSelChangeTab(LPNMHDR, LRESULT *pResult); afx_msg LRESULT OnCloseTab(WPARAM wParam, LPARAM); - afx_msg LRESULT OnDblClickTab(WPARAM wParam, LPARAM lParam); + afx_msg LRESULT OnDblClickTab(WPARAM wParam, LPARAM); afx_msg void OnDestroy(); afx_msg void OnSysColorChange(); afx_msg void OnTimer(UINT_PTR nIDEvent); diff --git a/srchybrid/SecRunAsUser.cpp b/srchybrid/SecRunAsUser.cpp index c3905cc9..40ef7df9 100644 --- a/srchybrid/SecRunAsUser.cpp +++ b/srchybrid/SecRunAsUser.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2004-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2004-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -54,7 +54,7 @@ eResult CSecRunAsUser::PrepareUser() try { IADsWinNTSystemInfoPtr pNTsys; if (CoCreateInstance(CLSID_WinNTSystemInfo, NULL, CLSCTX_INPROC_SERVER, IID_IADsWinNTSystemInfo, (void**)&pNTsys) != S_OK) - throw CString(_T("Failed to create IADsWinNTSystemInfo")); + throwCStr(_T("Failed to create IADsWinNTSystemInfo")); // check if we are already running on our eMule Account // todo: check if the current account is an administrator @@ -64,11 +64,11 @@ eResult CSecRunAsUser::PrepareUser() if (m_strCurrentUser == EMULEACCOUNTW) { m_bRunningAsEmule = true; - throw CString(_T("Already running as eMule_Secure Account (everything is fine)")); + throwCStr(_T("Already running as eMule_Secure Account (everything is fine)")); } CComBSTR bstrCompName; pNTsys->get_ComputerName(&bstrCompName); - CStringW cscompName = bstrCompName; + const CStringW cscompName(bstrCompName); CComBSTR bstrDomainName; pNTsys->get_DomainName(&bstrDomainName); @@ -76,7 +76,7 @@ eResult CSecRunAsUser::PrepareUser() ADSPath.Format(L"WinNT://%s,computer", (LPCTSTR)cscompName); if (!SUCCEEDED(ADsGetObject(ADSPath.AllocSysString(), IID_IADsContainer, (void **)&pUsers))) - throw CString(_T("Failed ADsGetObject()")); + throwCStr(_T("Failed ADsGetObject()")); IEnumVARIANTPtr pEnum; ADsBuildEnumerator(pUsers, &pEnum); @@ -89,14 +89,14 @@ eResult CSecRunAsUser::PrepareUser() //If the object in the container is user then get properties CComBSTR bstrName; pChild->get_Name(&bstrName); - CStringW csName(bstrName); + const CStringW csName(bstrName); // find the emule user account if possible if (csName == EMULEACCOUNTW) { // account found, set new random password and save it m_strPassword = CreateRandomPW(); if (!SUCCEEDED(pChild->SetPassword(m_strPassword.AllocSysString()))) - throw CString(_T("Failed to set password")); + throwCStr(_T("Failed to set password")); bResult = true; break; @@ -138,7 +138,7 @@ bool CSecRunAsUser::CreateEmuleUser(IADsContainerPtr pUsers) pUser->put_AccountDisabled(bAccountDisabled); pUser->put_IsAccountLocked(bIsLocked); pUser->put_PasswordRequired(bPwRequired); - pUser->put_Description(CString(_T("Account used to run eMule with additional security")).AllocSysString()); + pUser->put_Description(CStringW(_T("Account used to run eMule with additional security")).AllocSysString()); pUser->SetInfo(); m_strPassword = CreateRandomPW(); return SUCCEEDED(pUser->SetPassword(m_strPassword.AllocSysString())); @@ -171,11 +171,10 @@ bool CSecRunAsUser::SetDirectoryPermissions() bool bSucceeded = SetObjectPermission(thePrefs.GetMuleDirectory(EMULE_CONFIGBASEDIR), FULLACCESS); bSucceeded = bSucceeded && SetObjectPermission(thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR), FULLACCESS); bSucceeded = bSucceeded && SetObjectPermission(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR), FULLACCESS); - for (int i = 0; i < thePrefs.GetTempDirCount(); ++i) + for (INT_PTR i = thePrefs.GetTempDirCount(); --i >= 0;) bSucceeded = bSucceeded && SetObjectPermission(thePrefs.GetTempDir(i), FULLACCESS); - INT_PTR cCats = thePrefs.GetCatCount(); - for (int i = 0; i < cCats; ++i) + for (INT_PTR i = thePrefs.GetCatCount(); --i >= 0;) if (!thePrefs.GetCatPath(i).IsEmpty()) bSucceeded = bSucceeded && SetObjectPermission(thePrefs.GetCatPath(i), FULLACCESS); @@ -207,28 +206,28 @@ bool CSecRunAsUser::SetObjectPermission(const CString &strDirFile, DWORD lGrante DWORD cbUserSID = 0; fAPISuccess = LookupAccountName(NULL, EMULEACCOUNTW, pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType); if ((!fAPISuccess) && ::GetLastError() != ERROR_INSUFFICIENT_BUFFER) - throw CString(_T("Run as unprivileged user: Error: LookupAccountName() failed,")); + throwCStr(_T("Run as unprivileged user: Error: LookupAccountName() failed,")); pUserSID = MHeapAlloc(cbUserSID); if (!pUserSID) - throw CString(_T("Run as unprivileged user: Error: Allocating memory failed,")); + throwCStr(_T("Run as unprivileged user: Error: Allocating memory failed,")); szDomain = (TCHAR*)MHeapAlloc(cbDomain * sizeof(TCHAR)); if (!szDomain) - throw CString(_T("Run as unprivileged user: Error: Allocating memory failed,")); + throwCStr(_T("Run as unprivileged user: Error: Allocating memory failed,")); fAPISuccess = LookupAccountName(NULL, EMULEACCOUNTW, pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType); if (!fAPISuccess) - throw CString(_T("Run as unprivileged user: Error: LookupAccountName()2 failed")); + throwCStr(_T("Run as unprivileged user: Error: LookupAccountName()2 failed")); if (CStringW(szDomain) != m_strDomain) - throw CString(_T("Run as unprivileged user: Logical Error: Domain name mismatch")); + throwCStr(_T("Run as unprivileged user: Logical Error: Domain name mismatch")); // get old ACL PACL pOldACL = NULL; fAPISuccess = GetNamedSecurityInfo(strDirFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldACL, NULL, &pSD); if (fAPISuccess != ERROR_SUCCESS) - throw CString(_T("Run as unprivileged user: Error: GetNamedSecurityInfo() failed")); + throwCStr(_T("Run as unprivileged user: Error: GetNamedSecurityInfo() failed")); // calculate size for new ACL ACL_SIZE_INFORMATION AclInfo; @@ -237,17 +236,17 @@ bool CSecRunAsUser::SetObjectPermission(const CString &strDirFile, DWORD lGrante AclInfo.AclBytesInUse = sizeof(ACL); if (pOldACL != NULL && !GetAclInformation(pOldACL, &AclInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation)) - throw CString(_T("Run as unprivileged user: Error: GetAclInformation() failed")); + throwCStr(_T("Run as unprivileged user: Error: GetAclInformation() failed")); // Create new ACL - DWORD cbNewACL = AclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pUserSID) - sizeof(DWORD); + DWORD cbNewACL = (DWORD)(AclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pUserSID) - sizeof(DWORD)); pNewACL = (PACL)MHeapAlloc(cbNewACL); if (!pNewACL) - throw CString(_T("Run as unprivileged user: Error: Allocating memory failed,")); + throwCStr(_T("Run as unprivileged user: Error: Allocating memory failed,")); if (!InitializeAcl(pNewACL, cbNewACL, ACL_REVISION2)) - throw CString(_T("Run as unprivileged user: Error: Allocating memory failed,")); + throwCStr(_T("Run as unprivileged user: Error: Allocating memory failed,")); // copy the entries form the old acl into the new one and enter a new ace in the right order @@ -256,7 +255,7 @@ bool CSecRunAsUser::SetObjectPermission(const CString &strDirFile, DWORD lGrante for (CurrentAceIndex = 0; CurrentAceIndex < AclInfo.AceCount; ++CurrentAceIndex) { LPVOID pTempAce; if (!GetAce(pOldACL, CurrentAceIndex, &pTempAce)) - throw CString(_T("Run as unprivileged user: Error: GetAce() failed,")); + throwCStr(_T("Run as unprivileged user: Error: GetAce() failed,")); if (((ACCESS_ALLOWED_ACE*)pTempAce)->Header.AceFlags & INHERITED_ACE) break; @@ -265,28 +264,28 @@ bool CSecRunAsUser::SetObjectPermission(const CString &strDirFile, DWORD lGrante continue; if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER)pTempAce)->AceSize)) - throw CString(_T("Run as unprivileged user: Error: AddAce()1 failed,")); + throwCStr(_T("Run as unprivileged user: Error: AddAce()1 failed,")); } } // here we add the actually entry if (!AddAccessAllowedAceEx(pNewACL, ACL_REVISION2, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, lGrantedAccess, pUserSID)) - throw CString(_T("Run as unprivileged user: Error: AddAccessAllowedAceEx() failed,")); + throwCStr(_T("Run as unprivileged user: Error: AddAccessAllowedAceEx() failed,")); // copy the rest if (AclInfo.AceCount) { for (; CurrentAceIndex < AclInfo.AceCount; ++CurrentAceIndex) { LPVOID pTempAce; if (!GetAce(pOldACL, CurrentAceIndex, &pTempAce)) - throw CString(_T("Run as unprivileged user: Error: GetAce()2 failed,")); + throwCStr(_T("Run as unprivileged user: Error: GetAce()2 failed,")); if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER)pTempAce)->AceSize)) - throw CString(_T("Run as unprivileged user: Error: AddAce()2 failed,")); + throwCStr(_T("Run as unprivileged user: Error: AddAce()2 failed,")); } } - fAPISuccess = SetNamedSecurityInfo((LPTSTR)(LPCTSTR)strDirFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewACL, NULL); + fAPISuccess = SetNamedSecurityInfo(const_cast((LPCTSTR)strDirFile), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewACL, NULL); if (fAPISuccess != ERROR_SUCCESS) - throw CString(_T("Run as unprivileged user: Error: SetNamedSecurityInfo() failed,")); + throwCStr(_T("Run as unprivileged user: Error: SetNamedSecurityInfo() failed,")); fAPISuccess = TRUE; } catch (const CString &error) { fAPISuccess = FALSE; @@ -347,7 +346,7 @@ eResult CSecRunAsUser::RestartAsUser() FreeAPI(); if (bResult) return RES_OK_NEED_RESTART; - + theApp.QueueDebugLogLine(false, _T("Run as unprivileged user: Error: Failed to restart eMule as different user! Error Code: %i"), ::GetLastError()); return RES_FAILED; } @@ -429,7 +428,7 @@ eResult CSecRunAsUser::RestartAsRestricted() try { // get our access token from the process if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_READ, &hProcessToken)) - throw(CString(_T("Failed to retrieve access token from process"))); + throwCStr(_T("Failed to retrieve access token from process")); // there is no easy way to check if we have already restricted token when not using the restricted SID list // so just check if we set the SANDBOX_INERT flag and hope no one else did @@ -437,22 +436,22 @@ eResult CSecRunAsUser::RestartAsRestricted() DWORD dwLen = 0; DWORD dwInertFlag; if (!GetTokenInformation(hProcessToken, TokenSandBoxInert, &dwInertFlag, sizeof(dwInertFlag), &dwLen)) - throw(CString(_T("Failed to Flag-Status from AccessToken"))); + throwCStr(_T("Failed to Flag-Status from AccessToken")); if (dwInertFlag != 0) { m_bRunningRestricted = true; - throw(CString(_T("Already using a restricted Token it seems (everything is fine!)"))); + throwCStr(_T("Already using a restricted Token it seems (everything is fine!)")); } // get the user account SID to disable it in our new token dwLen = 0; while (!GetTokenInformation(hProcessToken, TokenUser, pstructUserToken, dwLen, &dwLen)) { if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER || pstructUserToken != NULL) - throw(CString(_T("Failed to retrieve UserSID from AccessToken"))); + throwCStr(_T("Failed to retrieve UserSID from AccessToken")); pstructUserToken = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLen); } if (pstructUserToken == NULL) - throw(CString(_T("Failed to retrieve UserSID from AccessToken"))); + throwCStr(_T("Failed to retrieve UserSID from AccessToken")); // disabling our primary token would make sense from a Security POV, but this would cause file acces conflicts // in the default settings (since we cannot access files we created ourself if they don't have the write flag for the group "users") @@ -460,13 +459,13 @@ eResult CSecRunAsUser::RestartAsRestricted() // create the new token if (!CreateRestrictedToken(hProcessToken, DISABLE_MAX_PRIVILEGE | SANDBOX_INERT, 0 /*disabled*/, &pstructUserToken->User, 0, NULL, 0, NULL, &hRestrictedToken)) - throw(CString(_T("Failed to create Restricted Token"))); + throwCStr(_T("Failed to create Restricted Token")); // do the starting job TCHAR szAppPath[MAX_PATH + 2]; DWORD dwModPathLen = ::GetModuleFileName(NULL, &szAppPath[1], MAX_PATH); if (dwModPathLen == 0 || dwModPathLen >= MAX_PATH) - throw CString(_T("Failed to get module file path")); + throwCStr(_T("Failed to get module file path")); szAppPath[0] = _T('"'); szAppPath[++dwModPathLen] = _T('"'); szAppPath[++dwModPathLen] = _T('\0'); @@ -486,7 +485,8 @@ eResult CSecRunAsUser::RestartAsRestricted() if (!CreateProcessAsUser(hRestrictedToken, NULL, szAppPath, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &StartInf, &ProcessInfo)) { CString e; GetErrorMessage(::GetLastError(), e, 0); - throw (_T("CreateProcessAsUser failed: ") + e); + e.Insert(0, _T("CreateProcessAsUser failed: ")); + throw e; } ::CloseHandle(ProcessInfo.hProcess); ::CloseHandle(ProcessInfo.hThread); @@ -518,7 +518,7 @@ eResult CSecRunAsUser::RestartSecure() res = PrepareUser(); if (res == RES_OK) { theApp.QueueLogLine(false, GetResString(IDS_RAU_RUNNING), EMULEACCOUNTW); - return RES_OK; + return res; } if (res == RES_OK_NEED_RESTART) { res = RestartAsUser(); diff --git a/srchybrid/SecRunAsUser.h b/srchybrid/SecRunAsUser.h index 43b8fb94..63078726 100644 --- a/srchybrid/SecRunAsUser.h +++ b/srchybrid/SecRunAsUser.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2004-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2004-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -134,8 +134,8 @@ typedef DWORD(WINAPI *TGetLengthSid) typedef HRESULT(WINAPI *TADsGetObject) ( LPWSTR lpszPathName, - REFIID riid, - VOID **ppObject + REFIID iid, + LPVOID *ppObject ); typedef HRESULT(WINAPI *TADsBuildEnumerator) diff --git a/srchybrid/SendMail.cpp b/srchybrid/SendMail.cpp index 4ad2cc93..b3252145 100644 --- a/srchybrid/SendMail.cpp +++ b/srchybrid/SendMail.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -26,7 +26,7 @@ #include #include -#include "mbedtls/config.h" +#include "mbedtls/build_info.h" #include "mbedtls/platform.h" #include "mbedtls/base64.h" #include "mbedtls/error.h" @@ -34,7 +34,6 @@ #include "mbedtls/ssl.h" #include "mbedtls/entropy.h" #include "mbedtls/ctr_drbg.h" -#include "mbedtls/certs.h" #include "mbedtls/x509.h" #ifdef _DEBUG @@ -156,7 +155,8 @@ bool encoded_word(const CString &src, CStringA &dst) return false; } dst.ReleaseBuffer(iLength); - dst = "=?utf-8?b?" + dst + "?="; + dst.Insert(0, "=?utf-8?b?"); + dst += "?="; return true; } @@ -176,14 +176,12 @@ static int do_handshake(mbedtls_ssl_context *ssl) static int write_ssl(mbedtls_ssl_context *ssl, const char *buf, size_t len) { - if (len > 0) { - for (int ret; (ret = mbedtls_ssl_write(ssl, (unsigned char*)buf, len)) <= 0;) { + if (len > 0) + for (int ret; (ret = mbedtls_ssl_write(ssl, (unsigned char*)buf, len)) <= 0;) if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { DebugLog(LOG_DONTNOTIFY, _T("mbedtls_ssl_write returned %d"), ret); return -1; } - } - } for (;;) { unsigned char data[256]; @@ -241,7 +239,6 @@ class CNotifierMailThread : public CWinThread protected: CNotifierMailThread() = default; // protected constructor used by dynamic creation - virtual ~CNotifierMailThread() = default; static CCriticalSection sm_critSect; public: @@ -267,7 +264,6 @@ BOOL CNotifierMailThread::InitInstance() void CNotifierMailThread::sendmail() { static const unsigned char pers[] = "eMule_mail"; - int ret; CStringA sBodyA, sReceiverA, sSenderA, sServerA, sTmpA, sBufA; mbedtls_net_context server_fd; @@ -285,13 +281,13 @@ void CNotifierMailThread::sendmail() mbedtls_ctr_drbg_init(&ctr_drbg); mbedtls_entropy_init(&entropy); - ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, pers, sizeof pers -1); + int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, pers, sizeof pers -1); if (ret != 0) { DebugLogWarning(LOG_DONTNOTIFY, _T("Seeding the random number generator failed: %d"), ret); goto exit; } - sServerA = CStringA(m_mail.sServer); + sServerA = (CStringA)m_mail.sServer; sTmpA.Format("%d", m_mail.uPort); ret = mbedtls_net_connect(&server_fd, sServerA, sTmpA, MBEDTLS_NET_PROTO_TCP); if (ret != 0) { @@ -395,7 +391,7 @@ void CNotifierMailThread::sendmail() goto failed; } - sTmpA = CStringA(m_mail.sUser); + sTmpA = (CStringA)m_mail.sUser; ret = mbedtls_base64_encode(base, sizeof base, &n, (unsigned char*)(LPCSTR)sTmpA, sTmpA.GetLength()); if (ret != 0) { DebugLogWarning(LOG_DONTNOTIFY, _T("Login to base64 failed: %d"), ret); @@ -408,7 +404,7 @@ void CNotifierMailThread::sendmail() goto failed; } - sTmpA = CStringA(m_mail.sPass); + sTmpA = (CStringA)m_mail.sPass; ret = mbedtls_base64_encode(base, sizeof base, &n, (unsigned char*)(LPCSTR)sTmpA, sTmpA.GetLength()); if (ret != 0) { DebugLogWarning(LOG_DONTNOTIFY, _T("Password to base64 failed: %d"), ret); @@ -430,7 +426,7 @@ void CNotifierMailThread::sendmail() goto failed; } - sReceiverA = CStringA(m_mail.sTo); + sReceiverA = (CStringA)m_mail.sTo; sBufA.Format("RCPT TO:<%s>\r\n", (LPCSTR)sReceiverA); ret = write_data(&ssl, sBufA); //250 251 if (ret > 0 && ret < 200 || ret > 299) { @@ -444,11 +440,11 @@ void CNotifierMailThread::sendmail() goto failed; } - sBodyA = "Content-Type: text/plain;\r\n" + sBodyA.Format("Content-Type: text/plain;\r\n" "\tformat=flowed;\r\n" "\tcharset=\"utf-8\"\r\n" - "Content-Transfer-Encoding: 8bit\r\n\r\n" - + (NeedUTF8String(m_strBody) ? wc2utf8(m_strBody) : CStringA(m_strBody)); + "Content-Transfer-Encoding: 8bit\r\n\r\n%s" + , (LPCSTR)(NeedUTF8String(m_strBody) ? wc2utf8(m_strBody) : (CStringA)m_strBody)); bool bEncrypt = !m_mail.sEncryptCertName.IsEmpty(); if (bEncrypt) { @@ -463,13 +459,13 @@ void CNotifierMailThread::sendmail() goto failed; } sBodyA.ReleaseBuffer(iLength); - sBodyA = "Content-Type: application/x-pkcs7-mime;\r\n" + sBodyA.Insert(0, "Content-Type: application/x-pkcs7-mime;\r\n" "\tformat=flowed;\r\n" "\tsmime-type=enveloped-data;\r\n" "\tname=\"smime.p7m\"\r\n" "Content-Transfer-Encoding: base64\r\n" "Content-Disposition: attachment;\r\n" - "\tfilename=\"smime.p7m\"\r\n\r\n" + sBodyA; + "\tfilename=\"smime.p7m\"\r\n\r\n"); } if (!encoded_word(m_strSubject, sTmpA)) //subject @@ -514,7 +510,7 @@ int CNotifierMailThread::write_data(mbedtls_ssl_context *ssl, const char *buf) int CNotifierMailThread::write_data(mbedtls_ssl_context *ssl, const char *buf, size_t len) { return m_mail.uTLS == MODE_NONE - ? write_txt((mbedtls_net_context*)ssl->p_bio, buf, len) + ? write_txt((mbedtls_net_context*)ssl->MBEDTLS_PRIVATE(p_bio), buf, len) : write_ssl(ssl, buf, len); } diff --git a/srchybrid/Server.cpp b/srchybrid/Server.cpp index 2b21faa5..be3438b3 100644 --- a/srchybrid/Server.cpp +++ b/srchybrid/Server.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -66,7 +66,7 @@ CServer::CServer(const ServerMet_Struct *in_data) CServer::CServer(uint16 in_port, LPCTSTR pszAddr) : port(in_port) { - ip = inet_addr(CStringA(pszAddr)); + ip = inet_addr((CStringA)pszAddr); if (ip == INADDR_NONE && _tcscmp(pszAddr, _T("255.255.255.255")) != 0) { m_strDynIP = pszAddr; ip = 0; @@ -109,7 +109,7 @@ CServer::CServer(const CServer *pOld) m_bTriedCryptOnce = pOld->m_bTriedCryptOnce; } -bool CServer::AddTagFromFile(CFileDataIO *servermet) +bool CServer::AddTagFromFile(CFileDataIO &servermet) { CTag *tag = new CTag(servermet, false); switch (tag->GetNameID()) { diff --git a/srchybrid/Server.h b/srchybrid/Server.h index 1e9f7d59..7ca39b8c 100644 --- a/srchybrid/Server.h +++ b/srchybrid/Server.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -60,7 +60,7 @@ class CServer explicit CServer(const CServer *pOld); ~CServer() = default; - bool AddTagFromFile(CFileDataIO *servermet); + bool AddTagFromFile(CFileDataIO &servermet); const CString& GetListName() const { return m_strName; } void SetListName(LPCTSTR newname) { m_strName = newname; } @@ -172,7 +172,7 @@ class CServer CString m_strName; CString m_strDynIP; CString m_strVersion; - time_t lastpingedtime; //This is to decided when we retry the ping. + time_t lastpingedtime; //This is to decide when we retry the ping. time_t m_RealLastPingedTime; uint32 challenge; uint32 m_uDescReqChallenge; diff --git a/srchybrid/ServerConnect.cpp b/srchybrid/ServerConnect.cpp index fab6f69c..294feedf 100644 --- a/srchybrid/ServerConnect.cpp +++ b/srchybrid/ServerConnect.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -29,7 +29,6 @@ #include "SafeFile.h" #include "Packets.h" #include "SharedFileList.h" -#include "PeerCacheFinder.h" #include "emuleDlg.h" #include "SearchDlg.h" #include "ServerWnd.h" @@ -44,10 +43,10 @@ static char THIS_FILE[] = __FILE__; void CServerConnect::TryAnotherConnectionRequest() { - if (connectionattemps.GetCount() < (thePrefs.IsSafeServerConnectEnabled() ? 1 : 2)) { + if (connectionattempts.GetCount() < (thePrefs.IsSafeServerConnectEnabled() ? 1 : 2)) { CServer *next_server = theApp.serverlist->GetNextServer(m_bTryObfuscated); if (next_server == NULL) { - if (connectionattemps.IsEmpty()) { + if (connectionattempts.IsEmpty()) { if (m_bTryObfuscated && !thePrefs.IsClientCryptLayerRequired()) { // try all servers on the non-obfuscated port next m_bTryObfuscated = false; @@ -128,29 +127,27 @@ void CServerConnect::ConnectToServer(CServer *server, bool multiconnect, bool bN m_lstOpenSockets.AddTail((void*)newsocket); newsocket->Create(0, SOCK_STREAM, FD_READ | FD_WRITE | FD_CLOSE | FD_CONNECT, thePrefs.GetBindAddr()); newsocket->ConnectTo(server, bNoCrypt); - connectionattemps.SetAt(::GetTickCount(), newsocket); + connectionattempts[::GetTickCount()] = newsocket; } void CServerConnect::StopConnectionTry() { - connectionattemps.RemoveAll(); + connectionattempts.RemoveAll(); connecting = false; singleconnecting = false; - theApp.emuledlg->ShowConnectionState(); - if (m_idRetryTimer) { ::KillTimer(NULL, m_idRetryTimer); m_idRetryTimer = 0; } - // close all currently opened sockets except those that are: //- connected to our current server //- going to destroy itself later on - for (POSITION pos = m_lstOpenSockets.GetHeadPosition(); pos != NULL; ) { - CServerSocket *pSck = static_cast(m_lstOpenSockets.GetNext(pos)); - if (pSck != connectedsocket && !pSck->m_bIsDeleting) - DestroySocket(pSck); + for (POSITION pos = m_lstOpenSockets.GetHeadPosition(); pos != NULL;) { + CServerSocket *pSock = static_cast(m_lstOpenSockets.GetNext(pos)); + if (pSock != connectedsocket && !pSock->m_bIsDeleting) + DestroySocket(pSock); } + theApp.emuledlg->ShowConnectionState(); } void CServerConnect::ConnectionEstablished(CServerSocket *sender) @@ -182,10 +179,10 @@ void CServerConnect::ConnectionEstablished(CServerSocket *sender) data.WriteUInt32(tagcount); CTag tagName(CT_NAME, thePrefs.GetUserNick()); - tagName.WriteTagToFile(&data); + tagName.WriteTagToFile(data); CTag tagVersion(CT_VERSION, EDONKEYVERSION); - tagVersion.WriteTagToFile(&data); + tagVersion.WriteTagToFile(data); uint32 dwCryptFlags = 0; if (thePrefs.IsClientCryptLayerSupported()) @@ -196,7 +193,7 @@ void CServerConnect::ConnectionEstablished(CServerSocket *sender) dwCryptFlags |= SRVCAP_REQUIRECRYPT; CTag tagFlags(CT_SERVER_FLAGS, SRVCAP_ZLIB | SRVCAP_NEWTAGS | SRVCAP_LARGEFILES | SRVCAP_UNICODE | dwCryptFlags); - tagFlags.WriteTagToFile(&data); + tagFlags.WriteTagToFile(data); // eMule Version (14-Mar-2004: requested by lugdunummaster (needed for LowID clients // that have no chance to send a Hello packet to the server during the callback test)) @@ -205,16 +202,16 @@ void CServerConnect::ConnectionEstablished(CServerSocket *sender) (CemuleApp::m_nVersionMjr << 17) | (CemuleApp::m_nVersionMin << 10) | (CemuleApp::m_nVersionUpd << 7)); - tagMuleVersion.WriteTagToFile(&data); + tagMuleVersion.WriteTagToFile(data); - Packet *packet = new Packet(&data); + Packet *packet = new Packet(data); packet->opcode = OP_LOGINREQUEST; if (thePrefs.GetDebugServerTCPLevel() > 0) Debug(_T(">>> Sending OP_LoginRequest\n")); theStats.AddUpDataOverheadServer(packet->size); SendPacket(packet, sender); } else if (sender->GetConnectionState() == CS_CONNECTED) { - theStats.reconnects++; + ++theStats.reconnects; theStats.serverConnectTime = ::GetTickCount(); connected = true; const CServer *cserver = sender->cur_server; @@ -242,8 +239,14 @@ void CServerConnect::ConnectionEstablished(CServerSocket *sender) } CServer *pServer = theApp.serverlist->GetServerByAddress(cserver->GetAddress(), cserver->GetPort()); - if (pServer) + if (pServer) { + if (sender->IsObfusicating() && !pServer->SupportsObfuscationTCP()) { + pServer->SetObfuscationPortTCP(cserver->GetObfuscationPortTCP()); + if (!pServer->SupportsObfuscationUDP()) + pServer->SetObfuscationPortUDP(cserver->GetObfuscationPortUDP()); + } theApp.emuledlg->serverwnd->serverlistctrl.RefreshServer(pServer); + } } theApp.emuledlg->ShowConnectionState(); } @@ -309,7 +312,7 @@ void CServerConnect::ConnectionFailed(CServerSocket *sender) switch (sender->GetConnectionState()) { case CS_FATALERROR: { - bool autoretry = !singleconnecting; + bool autoretry = connecting && !singleconnecting; StopConnectionTry(); if (thePrefs.Reconnect() && autoretry && !m_idRetryTimer) { LogWarning(GetResString(IDS_RECONNECT), CS_RETRYCONNECTTIME); @@ -325,7 +328,7 @@ void CServerConnect::ConnectionFailed(CServerSocket *sender) // If possible, use the "next" server. int iPosInList = theApp.serverlist->GetPositionOfServer(pServer); if (iPosInList >= 0) - m_uStartAutoConnectPos = (iPosInList + 1) % theApp.serverlist->GetServerCount(); + m_uStartAutoConnectPos = (UINT)((iPosInList + 1) % theApp.serverlist->GetServerCount()); } VERIFY((m_idRetryTimer = ::SetTimer(NULL, 0, SEC2MS(CS_RETRYCONNECTTIME), RetryConnectTimer)) != 0); if (thePrefs.GetVerbose() && !m_idRetryTimer) @@ -366,12 +369,12 @@ void CServerConnect::ConnectionFailed(CServerSocket *sender) break; } - for (POSITION pos = connectionattemps.GetStartPosition(); pos != NULL;) { + for (POSITION pos = connectionattempts.GetStartPosition(); pos != NULL;) { DWORD tmpkey; CServerSocket *tmpsock; - connectionattemps.GetNextAssoc(pos, tmpkey, tmpsock); + connectionattempts.GetNextAssoc(pos, tmpkey, tmpsock); if (tmpsock == sender) { - connectionattemps.RemoveKey(tmpkey); + connectionattempts.RemoveKey(tmpkey); break; } } @@ -405,27 +408,26 @@ void CServerConnect::CheckForTimeout() if (thePrefs.GetProxySettings().bUseProxy) dwServerConnectTimeout = max(dwServerConnectTimeout, CONNECTION_TIMEOUT); - DWORD dwCurTick = ::GetTickCount(); - for (POSITION pos = connectionattemps.GetStartPosition(); pos != NULL;) { + const DWORD curTick = ::GetTickCount(); + for (POSITION pos = connectionattempts.GetStartPosition(); pos != NULL;) { DWORD tmpkey; CServerSocket *tmpsock; - connectionattemps.GetNextAssoc(pos, tmpkey, tmpsock); + connectionattempts.GetNextAssoc(pos, tmpkey, tmpsock); if (!tmpsock) { if (thePrefs.GetVerbose()) DebugLogError(_T("Error: Socket invalid at timeout check")); - connectionattemps.RemoveKey(tmpkey); + connectionattempts.RemoveKey(tmpkey); return; } - if (dwCurTick >= tmpkey + dwServerConnectTimeout) { + if (curTick >= tmpkey + dwServerConnectTimeout) { LogWarning(GetResString(IDS_ERR_CONTIMEOUT), (LPCTSTR)tmpsock->cur_server->GetListName(), tmpsock->cur_server->GetAddress(), tmpsock->cur_server->GetPort()); - connectionattemps.RemoveKey(tmpkey); + connectionattempts.RemoveKey(tmpkey); DestroySocket(tmpsock); if (singleconnecting) StopConnectionTry(); else TryAnotherConnectionRequest(); - } } } @@ -441,9 +443,9 @@ bool CServerConnect::Disconnect() theApp.SetPublicIP(0); DestroySocket(connectedsocket); connectedsocket = NULL; - theApp.emuledlg->ShowConnectionState(); theStats.serverConnectTime = 0; theStats.Add2TotalServerDuration(); + theApp.emuledlg->ShowConnectionState(); return true; } return false; @@ -452,7 +454,6 @@ bool CServerConnect::Disconnect() CServerConnect::CServerConnect() : m_clientid() , m_curuser() - , pendingConnects() , connectedsocket() , m_idRetryTimer() , m_uStartAutoConnectPos() @@ -502,20 +503,20 @@ void CServerConnect::SetClientID(uint32 newid) theApp.emuledlg->ShowConnectionState(); } -void CServerConnect::DestroySocket(CServerSocket *pSck) +void CServerConnect::DestroySocket(CServerSocket *pSock) { - if (pSck == NULL) + if (pSock == NULL) return; // remove socket from list of opened sockets - POSITION pos = m_lstOpenSockets.Find(pSck); + POSITION pos = m_lstOpenSockets.Find(pSock); if (pos != NULL) m_lstOpenSockets.RemoveAt(pos); - if (pSck->m_SocketData.hSocket != INVALID_SOCKET) { // deadlake PROXYSUPPORT - changed to AsyncSocketEx - pSck->AsyncSelect(FD_CLOSE); - pSck->ShutDown(CAsyncSocket::both); - pSck->Close(); + if (pSock->m_SocketData.hSocket != INVALID_SOCKET) { // deadlake PROXYSUPPORT - changed to AsyncSocketEx + pSock->AsyncSelect(FD_CLOSE); + pSock->ShutDown(CAsyncSocket::both); + pSock->Close(); } - delete pSck; + delete pSock; } bool CServerConnect::IsLocalServer(uint32 dwIP, uint16 nPort) const @@ -530,10 +531,10 @@ void CServerConnect::InitLocalIP() // Using 'gethostname/gethostbyname' does not solve the problem when we have more than // one IP address. Using 'gethostname/gethostbyname' even seems to return the last IP // address which we got. e.g. if we already got an IP from our ISP, - // 'gethostname/gethostbyname' will returned that (primary) IP, but if we add another + // 'gethostname/gethostbyname' will return this (primary) IP, but if we add another // IP by opening a VPN connection, 'gethostname' will still return the same hostname, // but 'gethostbyname' will return the 2nd IP. - // To weaken that problem at least for users which are binding eMule to a certain IP, + // To alleviate the problem at least for users which are binding eMule to a certain IP, // we use the explicitly specified bind address as our local IP address. if (thePrefs.GetBindAddrA() != NULL) { unsigned long ulBindAddr = inet_addr(thePrefs.GetBindAddrA()); @@ -543,21 +544,17 @@ void CServerConnect::InitLocalIP() } } - // Don't use 'gethostbyname(NULL)'. The winsock DLL may be replaced by a DLL from a third party - // which is not fully compatible to the original winsock DLL. ppl reported crash with SCORSOCK.DLL - // when using 'gethostbyname(NULL)'. - __try { - char szHost[256]; - if (gethostname(szHost, sizeof szHost) == 0) { - hostent *pHostEnt = gethostbyname(szHost); - if (pHostEnt != NULL && pHostEnt->h_length == 4 && pHostEnt->h_addr_list[0] != NULL) - m_nLocalIP = *((uint32*)pHostEnt->h_addr_list[0]); + char szHost[256]; + if (gethostname(szHost, sizeof szHost) == 0) { + addrinfo hints = {}; + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + addrinfo *res; + if (!getaddrinfo(szHost, NULL, &hints, &res) && res != NULL) { + m_nLocalIP = ((sockaddr_in*)res->ai_addr)->sin_addr.s_addr; + freeaddrinfo(res); } - } __except (EXCEPTION_EXECUTE_HANDLER) { - // at least two ppl reported crashes when using 'gethostbyname' with third party winsock DLLs - if (thePrefs.GetVerbose()) - DebugLogError(_T("Unknown exception in CServerConnect::InitLocalIP")); - ASSERT(0); } } @@ -571,7 +568,7 @@ void CServerConnect::KeepConnectionAlive() // an empty publish files packet -> recommended by lugdunummaster himself! CSafeMemFile files(4); files.WriteUInt32(0); // nr. of files - Packet *packet = new Packet(&files); + Packet *packet = new Packet(files); packet->opcode = OP_OFFERFILES; if (thePrefs.GetVerbose()) AddDebugLogLine(false, _T("Refreshing server connection")); @@ -590,15 +587,10 @@ bool CServerConnect::IsLowID() const // true if the IP is one of a server which we currently try to connect to bool CServerConnect::AwaitingTestFromIP(uint32 dwIP) const { - if (connectionattemps.IsEmpty()) - return false; - for (POSITION pos = connectionattemps.GetStartPosition(); pos != NULL;) { - DWORD tmpkey; - CServerSocket *tmpsock; - connectionattemps.GetNextAssoc(pos, tmpkey, tmpsock); - if (tmpsock != NULL && tmpsock->cur_server != NULL && tmpsock->cur_server->GetIP() == dwIP && tmpsock->GetConnectionState() == CS_WAITFORLOGIN) + for (const CServerSocketMap::CPair *pair = connectionattempts.PGetFirstAssoc(); pair != NULL; pair = connectionattempts.PGetNextAssoc(pair)) + if (pair->value && pair->value->cur_server && pair->value->cur_server->GetIP() == dwIP && pair->value->GetConnectionState() == CS_WAITFORLOGIN) return true; - } + return false; } diff --git a/srchybrid/ServerConnect.h b/srchybrid/ServerConnect.h index 82e09d33..e19abcb7 100644 --- a/srchybrid/ServerConnect.h +++ b/srchybrid/ServerConnect.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -53,7 +53,7 @@ class CServerConnect static VOID CALLBACK RetryConnectTimer(HWND hWnd, UINT nMsg, UINT_PTR nId, DWORD dwTime) noexcept; void CheckForTimeout(); - void DestroySocket(CServerSocket *pSck); // safe socket closure and destruction + void DestroySocket(CServerSocket *pSock); // safe socket closure and destruction bool SendPacket(Packet *packet, CServerSocket *to = NULL); bool IsUDPSocketAvailable() const { return udpsocket != NULL; } bool SendUDPPacket(Packet *packet, CServer *host, bool bDelPacket/* = false*/, uint16 nSpecialPort = 0, BYTE *pRawPacket = NULL, uint32 nLen = 0); @@ -77,10 +77,10 @@ class CServerConnect uint32 m_clientid; uint32 m_curuser; - uint8 pendingConnects; private: - CMap connectionattemps; + typedef CMap CServerSocketMap; + CServerSocketMap connectionattempts; CPtrList m_lstOpenSockets; // list of currently opened sockets CServerSocket *connectedsocket; CUDPSocket *udpsocket; diff --git a/srchybrid/ServerList.cpp b/srchybrid/ServerList.cpp index 485ae2b4..7fd8d1b0 100644 --- a/srchybrid/ServerList.cpp +++ b/srchybrid/ServerList.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -79,19 +79,17 @@ void CServerList::AutoUpdate() (void)_tremove(servermetdownload); (void)_trename(servermet, servermetbackup); - CString strURLToDownload; bool bDownloaded = false; for (POSITION Pos = thePrefs.addresses_list.GetHeadPosition(); Pos != NULL;) { CHttpDownloadDlg dlgDownload; dlgDownload.m_strTitle = GetResString(IDS_HTTP_CAPTION); - strURLToDownload = thePrefs.addresses_list.GetNext(Pos); - dlgDownload.m_sURLToDownload = strURLToDownload; + dlgDownload.m_sURLToDownload = thePrefs.addresses_list.GetNext(Pos); dlgDownload.m_sFileToDownloadInto = servermetdownload; if (dlgDownload.DoModal() == IDOK) { bDownloaded = true; break; } - LogError(LOG_STATUSBAR, GetResString(IDS_ERR_FAILEDDOWNLOADMET), (LPCTSTR)strURLToDownload); + LogError(LOG_STATUSBAR, GetResString(IDS_ERR_FAILEDDOWNLOADMET), (LPCTSTR)dlgDownload.m_sURLToDownload); } if (bDownloaded) @@ -107,18 +105,18 @@ bool CServerList::Init() if (thePrefs.GetAutoUpdateServerList()) AutoUpdate(); - // Load Metfile - const CString &confdir(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); + // Load Met file + const CString &sConfDir(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); - bool bRes = AddServerMetToList(confdir + SERVER_MET_FILENAME, false); + bool bRes = AddServerMetToList(sConfDir + SERVER_MET_FILENAME, false); if (thePrefs.GetAutoUpdateServerList()) { - bool bRes2 = AddServerMetToList(confdir + _T("server_met.download"), true); + bool bRes2 = AddServerMetToList(sConfDir + _T("server_met.download"), true); if (!bRes && bRes2) bRes = true; } - // insert static servers from textfile - AddServersFromTextFile(confdir + _T("staticservers.dat")); + // insert static servers from text file + AddServersFromTextFile(sConfDir + _T("staticservers.dat")); theApp.serverlist->GiveServersForTraceRoute(); @@ -144,7 +142,7 @@ bool CServerList::AddServerMetToList(const CString &strFile, bool bMerge) } return false; } - setvbuf(servermet.m_pStream, NULL, _IOFBF, 16384); + ::setvbuf(servermet.m_pStream, NULL, _IOFBF, 16384); try { version = servermet.ReadUInt8(); if (version != 0xE0 && version != MET_HEADER) { @@ -153,7 +151,7 @@ bool CServerList::AddServerMetToList(const CString &strFile, bool bMerge) return false; } theApp.emuledlg->serverwnd->serverlistctrl.Hide(); - theApp.emuledlg->serverwnd->serverlistctrl.SetRedraw(FALSE); + theApp.emuledlg->serverwnd->serverlistctrl.SetRedraw(false); uint32 fservercount = servermet.ReadUInt32(); ServerMet_Struct sbuffer; @@ -165,7 +163,7 @@ bool CServerList::AddServerMetToList(const CString &strFile, bool bMerge) // add tags for (uint32 i = 0; i < sbuffer.tagcount; ++i) - newserver->AddTagFromFile(&servermet); + newserver->AddTagFromFile(servermet); if (bMerge) { // If we are merging a (downloaded) server list into our list, ignore the priority of the @@ -205,7 +203,7 @@ bool CServerList::AddServerMetToList(const CString &strFile, bool bMerge) } error->Delete(); } - theApp.emuledlg->serverwnd->serverlistctrl.SetRedraw(TRUE); + theApp.emuledlg->serverwnd->serverlistctrl.SetRedraw(true); theApp.emuledlg->serverwnd->serverlistctrl.Visible(); return true; } @@ -279,7 +277,7 @@ void CServerList::ServerStats() theApp.emuledlg->serverwnd->serverlistctrl.RemoveServer(ping_server); return; } - srand((uint32)tNow); + //srand((unsigned)tNow); ping_server->SetRealLastPingedTime(tNow); // this is not used to calculate the next ping, but only to ensure a minimum delay for premature pings if (!ping_server->GetCryptPingReplyPending() && tNow >= ping_server->GetLastPingedTime() + UDPSERVSTATREASKTIME && theApp.GetPublicIP() && thePrefs.IsServerCryptLayerUDPEnabled()) { // we try an obfuscated ping first and wait 20 seconds for an answer @@ -601,8 +599,8 @@ bool CServerList::SaveServermetToFile() if (thePrefs.GetLogFileSaving()) AddDebugLogLine(false, _T("Saving servers list file \"%s\""), SERVER_MET_FILENAME); m_nLastSaved = ::GetTickCount(); - const CString &confdir(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); - const CString &curservermet(confdir + SERVER_MET_FILENAME); + const CString &sConfDir(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); + const CString &curservermet(sConfDir + SERVER_MET_FILENAME); const CString &newservermet(curservermet + _T(".new")); CSafeBufferedFile servermet; @@ -615,7 +613,7 @@ bool CServerList::SaveServermetToFile() LogError(LOG_STATUSBAR, _T("%s"), (LPCTSTR)strError); return false; } - setvbuf(servermet.m_pStream, NULL, _IOFBF, 16384); + ::setvbuf(servermet.m_pStream, NULL, _IOFBF, 16384); try { servermet.WriteUInt8(0xE0); @@ -636,116 +634,116 @@ bool CServerList::SaveServermetToFile() if (!nextserver->GetListName().IsEmpty()) { CTag servername(ST_SERVERNAME, nextserver->GetListName()); - servername.WriteTagToFile(&servermet, UTF8strOptBOM); + servername.WriteTagToFile(servermet, UTF8strOptBOM); ++uTagCount; } if (!nextserver->GetDynIP().IsEmpty()) { CTag serverdynip(ST_DYNIP, nextserver->GetDynIP()); - serverdynip.WriteTagToFile(&servermet, UTF8strOptBOM); + serverdynip.WriteTagToFile(servermet, UTF8strOptBOM); ++uTagCount; } if (!nextserver->GetDescription().IsEmpty()) { CTag serverdesc(ST_DESCRIPTION, nextserver->GetDescription()); - serverdesc.WriteTagToFile(&servermet, UTF8strOptBOM); + serverdesc.WriteTagToFile(servermet, UTF8strOptBOM); ++uTagCount; } if (nextserver->GetFailedCount()) { CTag serverfail(ST_FAIL, nextserver->GetFailedCount()); - serverfail.WriteTagToFile(&servermet); + serverfail.WriteTagToFile(servermet); ++uTagCount; } if (nextserver->GetPreference() != SRV_PR_NORMAL) { CTag serverpref(ST_PREFERENCE, nextserver->GetPreference()); - serverpref.WriteTagToFile(&servermet); + serverpref.WriteTagToFile(servermet); ++uTagCount; } if (nextserver->GetUsers()) { CTag serveruser("users", nextserver->GetUsers()); - serveruser.WriteTagToFile(&servermet); + serveruser.WriteTagToFile(servermet); ++uTagCount; } if (nextserver->GetFiles()) { CTag serverfiles("files", nextserver->GetFiles()); - serverfiles.WriteTagToFile(&servermet); + serverfiles.WriteTagToFile(servermet); ++uTagCount; } if (nextserver->GetPing()) { CTag serverping(ST_PING, nextserver->GetPing()); - serverping.WriteTagToFile(&servermet); + serverping.WriteTagToFile(servermet); ++uTagCount; } if (nextserver->GetLastPingedTime() > 0) { CTag serverlastp(ST_LASTPING, nextserver->GetLastPingedTime()); - serverlastp.WriteTagToFile(&servermet); + serverlastp.WriteTagToFile(servermet); ++uTagCount; } if (nextserver->GetMaxUsers()) { CTag servermaxusers(ST_MAXUSERS, nextserver->GetMaxUsers()); - servermaxusers.WriteTagToFile(&servermet); + servermaxusers.WriteTagToFile(servermet); ++uTagCount; } if (nextserver->GetSoftFiles()) { CTag softfiles(ST_SOFTFILES, nextserver->GetSoftFiles()); - softfiles.WriteTagToFile(&servermet); + softfiles.WriteTagToFile(servermet); ++uTagCount; } if (nextserver->GetHardFiles()) { CTag hardfiles(ST_HARDFILES, nextserver->GetHardFiles()); - hardfiles.WriteTagToFile(&servermet); + hardfiles.WriteTagToFile(servermet); ++uTagCount; } if (!nextserver->GetVersion().IsEmpty()) { // as long as we don't receive an integer version tag from the local server (TCP) we store it as string CTag tversion(ST_VERSION, nextserver->GetVersion()); - tversion.WriteTagToFile(&servermet, UTF8strOptBOM); + tversion.WriteTagToFile(servermet, UTF8strOptBOM); ++uTagCount; } if (nextserver->GetUDPFlags()) { CTag tagUDPFlags(ST_UDPFLAGS, nextserver->GetUDPFlags()); - tagUDPFlags.WriteTagToFile(&servermet); + tagUDPFlags.WriteTagToFile(servermet); ++uTagCount; } if (nextserver->GetLowIDUsers()) { CTag tagLowIDUsers(ST_LOWIDUSERS, nextserver->GetLowIDUsers()); - tagLowIDUsers.WriteTagToFile(&servermet); + tagLowIDUsers.WriteTagToFile(servermet); ++uTagCount; } if (nextserver->GetServerKeyUDP(true)) { CTag tagServerKeyUDP(ST_UDPKEY, nextserver->GetServerKeyUDP(true)); - tagServerKeyUDP.WriteTagToFile(&servermet); + tagServerKeyUDP.WriteTagToFile(servermet); ++uTagCount; } if (nextserver->GetServerKeyUDPIP()) { CTag tagServerKeyUDPIP(ST_UDPKEYIP, nextserver->GetServerKeyUDPIP()); - tagServerKeyUDPIP.WriteTagToFile(&servermet); + tagServerKeyUDPIP.WriteTagToFile(servermet); ++uTagCount; } if (nextserver->GetObfuscationPortTCP()) { CTag tagObfuscationPortTCP(ST_TCPPORTOBFUSCATION, nextserver->GetObfuscationPortTCP()); - tagObfuscationPortTCP.WriteTagToFile(&servermet); + tagObfuscationPortTCP.WriteTagToFile(servermet); ++uTagCount; } if (nextserver->GetObfuscationPortUDP()) { CTag tagObfuscationPortUDP(ST_UDPPORTOBFUSCATION, nextserver->GetObfuscationPortUDP()); - tagObfuscationPortUDP.WriteTagToFile(&servermet); + tagObfuscationPortUDP.WriteTagToFile(servermet); ++uTagCount; } @@ -754,14 +752,14 @@ bool CServerList::SaveServermetToFile() servermet.SeekToEnd(); } - if ((theApp.IsClosing() && thePrefs.GetCommitFiles() >= 1) || thePrefs.GetCommitFiles() >= 2) { + if (thePrefs.GetCommitFiles() >= 2 || (thePrefs.GetCommitFiles() >= 1 && theApp.IsClosing())) { servermet.Flush(); // flush file stream buffers to disk buffers if (_commit(_fileno(servermet.m_pStream)) != 0) // commit disk buffers to disk AfxThrowFileException(CFileException::hardIO, ::GetLastError(), servermet.GetFileName()); } servermet.Close(); - MoveFileEx(curservermet, confdir + _T("server_met.old"), MOVEFILE_REPLACE_EXISTING); + MoveFileEx(curservermet, sConfDir + _T("server_met.old"), MOVEFILE_REPLACE_EXISTING); MoveFileEx(newservermet, curservermet, MOVEFILE_REPLACE_EXISTING); } catch (CFileException *error) { CString strError(GetResString(IDS_ERR_SAVESERVERMET2)); @@ -863,7 +861,7 @@ bool CServerList::SaveStaticServers() bool bResult = false; // write Unicode byte order mark 0xFEFF - if (fputwc(0xFEFFui16, fpStaticServers) != _TEOF) { + if (fputwc(u'\xFEFF', fpStaticServers) != _TEOF) { bResult = true; for (POSITION pos = list.GetHeadPosition(); pos != NULL;) { const CServer *pServer = list.GetNext(pos); @@ -889,7 +887,7 @@ void CServerList::Process() int CServerList::GetPositionOfServer(const CServer *pServer) const { int iPos = -1; - for (POSITION pos = list.GetHeadPosition(); pos != NULL; ) { + for (POSITION pos = list.GetHeadPosition(); pos != NULL;) { ++iPos; if (pServer == list.GetNext(pos)) break; @@ -932,7 +930,7 @@ void CServerList::CheckForExpiredUDPKeys() uint32 cKeysExpired = 0; uint32 cPingDelayed = 0; const uint32 dwIP = theApp.GetPublicIP(); - ASSERT(dwIP != 0); + ASSERT(dwIP); const time_t tNow = time(NULL); for (POSITION pos = list.GetHeadPosition();pos != NULL;) { diff --git a/srchybrid/ServerList.h b/srchybrid/ServerList.h index de454cd1..d80131f1 100644 --- a/srchybrid/ServerList.h +++ b/srchybrid/ServerList.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/ServerListCtrl.cpp b/srchybrid/ServerListCtrl.cpp index a4a8879f..d56942ad 100644 --- a/srchybrid/ServerListCtrl.cpp +++ b/srchybrid/ServerListCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -30,8 +30,8 @@ #include "IrcWnd.h" #include "Opcodes.h" #include "Log.h" -#include "ToolTipCtrlX.h" #include "IPFilter.h" +#include "MemDC.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -45,7 +45,6 @@ IMPLEMENT_DYNAMIC(CServerListCtrl, CMuleListCtrl) BEGIN_MESSAGE_MAP(CServerListCtrl, CMuleListCtrl) ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, OnLvnColumnClick) ON_NOTIFY_REFLECT(LVN_GETINFOTIP, OnLvnGetInfoTip) - ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnNmCustomDraw) ON_NOTIFY_REFLECT(NM_DBLCLK, OnNmDblClk) ON_WM_CONTEXTMENU() ON_WM_SYSCOLORCHANGE() @@ -54,7 +53,6 @@ END_MESSAGE_MAP() CServerListCtrl::CServerListCtrl() { SetGeneralPurposeFind(true); - m_tooltip = new CToolTipCtrlX; SetSkinKey(_T("ServersLv")); } @@ -65,27 +63,27 @@ bool CServerListCtrl::Init() CToolTipCtrl *tooltip = GetToolTips(); if (tooltip) { - m_tooltip->SubclassWindow(*tooltip); + m_tooltip.SubclassWindow(*tooltip); tooltip->ModifyStyle(0, TTS_NOPREFIX); tooltip->SetDelayTime(TTDT_AUTOPOP, SEC2MS(20)); //tooltip->SetDelayTime(TTDT_INITIAL, SEC2MS(thePrefs.GetToolTipDelay())); } - InsertColumn(0, GetResString(IDS_SL_SERVERNAME), LVCFMT_LEFT, 150); - InsertColumn(1, GetResString(IDS_IP), LVCFMT_LEFT, 140); - InsertColumn(2, GetResString(IDS_DESCRIPTION), LVCFMT_LEFT, 150); - InsertColumn(3, GetResString(IDS_PING), LVCFMT_RIGHT, 50); - InsertColumn(4, GetResString(IDS_UUSERS), LVCFMT_RIGHT, 60); - InsertColumn(5, GetResString(IDS_MAXCLIENT), LVCFMT_RIGHT, 60); - InsertColumn(6, GetResString(IDS_PW_FILES), LVCFMT_RIGHT, 60); - InsertColumn(7, GetResString(IDS_PREFERENCE), LVCFMT_LEFT, 50); - InsertColumn(8, GetResString(IDS_UFAILED), LVCFMT_RIGHT, 50); - InsertColumn(9, GetResString(IDS_STATICSERVER), LVCFMT_LEFT, 50); - InsertColumn(10, GetResString(IDS_SOFTFILES), LVCFMT_RIGHT, 60); - InsertColumn(11, GetResString(IDS_HARDFILES), LVCFMT_RIGHT, 60, -1, true); - InsertColumn(12, GetResString(IDS_VERSION), LVCFMT_LEFT, 50, -1, true); - InsertColumn(13, GetResString(IDS_IDLOW), LVCFMT_RIGHT, 60); - InsertColumn(14, GetResString(IDS_OBFUSCATION), LVCFMT_RIGHT, 50); + InsertColumn(0, _T(""), LVCFMT_LEFT, 150); //IDS_SL_SERVERNAME + InsertColumn(1, _T(""), LVCFMT_LEFT, 140); //IDS_IP + InsertColumn(2, _T(""), LVCFMT_LEFT, 150); //IDS_DESCRIPTION + InsertColumn(3, _T(""), LVCFMT_RIGHT, 50); //IDS_PING + InsertColumn(4, _T(""), LVCFMT_RIGHT, 60); //IDS_UUSERS + InsertColumn(5, _T(""), LVCFMT_RIGHT, 60); //IDS_MAXCLIENT + InsertColumn(6, _T(""), LVCFMT_RIGHT, 60); //IDS_PW_FILES + InsertColumn(7, _T(""), LVCFMT_LEFT, 50); //IDS_PREFERENCE + InsertColumn(8, _T(""), LVCFMT_RIGHT, 50); //IDS_UFAILED + InsertColumn(9, _T(""), LVCFMT_LEFT, 50); //IDS_STATICSERVER + InsertColumn(10, _T(""), LVCFMT_RIGHT, 60); //IDS_SOFTFILES + InsertColumn(11, _T(""), LVCFMT_RIGHT, 60, -1, true); //IDS_HARDFILES + InsertColumn(12, _T(""), LVCFMT_LEFT, 50, -1, true); //IDS_VERSION + InsertColumn(13, _T(""), LVCFMT_RIGHT, 60); //IDS_IDLOW + InsertColumn(14, _T(""), LVCFMT_RIGHT, 50); //IDS_OBFUSCATION SetAllIcons(); Localize(); @@ -93,18 +91,13 @@ bool CServerListCtrl::Init() // Barry - Use preferred sort order from preferences SetSortArrow(); - SortItems(SortProc, MAKELONG(GetSortItem(), (GetSortAscending() ? 0 : 0x0001))); + SortItems(SortProc, MAKELONG(GetSortItem(), !GetSortAscending())); ShowServerCount(); return true; } -CServerListCtrl::~CServerListCtrl() -{ - delete m_tooltip; -} - void CServerListCtrl::OnSysColorChange() { CMuleListCtrl::OnSysColorChange(); @@ -113,20 +106,152 @@ void CServerListCtrl::OnSysColorChange() void CServerListCtrl::SetAllIcons() { - CImageList iml; - iml.Create(16, 16, theApp.m_iDfltImageListColorFlags | ILC_MASK, 0, 1); - iml.Add(CTempIconLoader(_T("Server"))); - HIMAGELIST himl = ApplyImageList(iml.Detach()); - if (himl) - ::ImageList_Destroy(himl); + ApplyImageList(NULL); + // Apply the image list also to the listview control, even if we use our own 'DrawItem'. + // This is needed to give the listview control a chance to initialize the row height. + ASSERT((GetStyle() & LVS_SHAREIMAGELISTS) != 0); + m_pImageList = &theApp.emuledlg->GetClientIconList(); + VERIFY(ApplyImageList(*m_pImageList) == NULL); } -void CServerListCtrl::Localize() +CString CServerListCtrl::GetItemDisplayText(const CServer *server, int iSubItem) const +{ + CString sText; + switch (iSubItem) { + case 0: //name + sText = server->GetListName(); + break; + case 1: //ip:port + sText.Format(_T("%s : %i"), server->GetAddress(), server->GetPort()); + break; + case 2: //description + sText = server->GetDescription(); + break; + case 3: //ping + if (server->GetPing()) + sText.Format(_T("%u"), server->GetPing()); + break; + case 4: //users + if (server->GetUsers()) + sText = CastItoIShort(server->GetUsers()); + break; + case 5: //max users + if (server->GetUsers()) + sText = CastItoIShort(server->GetMaxUsers()); + break; + case 6: //files + if (server->GetFiles()) + sText = CastItoIShort(server->GetFiles()); + break; + case 7: //priority + { + UINT uid; + switch (server->GetPreference()) { + case SRV_PR_LOW: + uid = IDS_PRIOLOW; + break; + case SRV_PR_NORMAL: + uid = IDS_PRIONORMAL; + break; + case SRV_PR_HIGH: + uid = IDS_PRIOHIGH; + break; + default: + uid = IDS_PRIONOPREF; + } + sText = GetResString(uid); + } + break; + case 8: //failed count + sText.Format(_T("%u"), server->GetFailedCount()); + break; + case 9: //static + sText = GetResString(server->IsStaticMember() ? IDS_YES : IDS_NO); + break; + case 10: //soft files + sText = CastItoIShort(server->GetSoftFiles()); + break; + case 11: //hard files + sText = CastItoIShort(server->GetHardFiles()); + break; + case 12: //version + sText = server->GetVersion(); + if (thePrefs.GetDebugServerUDPLevel() > 0 && server->GetUDPFlags() > 0) + sText.AppendFormat(&_T("; ExtUDP=%x")[sText.IsEmpty() ? 2 : 0], server->GetUDPFlags()); + if (thePrefs.GetDebugServerTCPLevel() > 0 && server->GetTCPFlags() > 0) + sText.AppendFormat(&_T("; ExtTCP=%x")[sText.IsEmpty() ? 2 : 0], server->GetTCPFlags()); + break; + case 13: //low ID users + sText = CastItoIShort(server->GetLowIDUsers()); + break; + case 14: //obfuscation + sText = GetResString(server->SupportsObfuscationTCP() ? IDS_YES : IDS_NO); + } + return sText; +} + +void CServerListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); - HDITEM hdi; - hdi.mask = HDI_TEXT; + const CServer *pServer = reinterpret_cast(lpDrawItemStruct->itemData); + if (!pServer || theApp.IsClosing()) + return; + CRect rcItem(lpDrawItemStruct->rcItem); + CMemoryDC dc(CDC::FromHandle(lpDrawItemStruct->hDC), rcItem); + BOOL bCtrlFocused; + InitItemMemDC(dc, lpDrawItemStruct, bCtrlFocused); + RECT rcServer; + GetClientRect(&rcServer); + + const CServer *pConnectedServer = theApp.serverconnect->GetCurrentServer(); + // the server which we are connected to, always has a valid numerical IP member assigned, + // therefore we do not need to call CServer::IsEqual which would be expensive + if (pConnectedServer && pConnectedServer->GetIP() == pServer->GetIP() && pConnectedServer->GetPort() == pServer->GetPort()) + dc.SetTextColor(RGB(32, 32, 255)); + else if (pServer->GetFailedCount() >= thePrefs.GetDeadServerRetries()) + dc.SetTextColor(RGB(192, 192, 192)); + else if (pServer->GetFailedCount() >= 2) + dc.SetTextColor(RGB(128, 128, 128)); + + const CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); + int iCount = pHeaderCtrl->GetItemCount(); + LONG itemLeft = rcItem.left; + LONG iIconY = max((rcItem.Height() - 15) / 2, 0); + for (int iCurrent = 0; iCurrent < iCount; ++iCurrent) { + int iColumn = pHeaderCtrl->OrderToIndex(iCurrent); + if (IsColumnHidden(iColumn)) + continue; + + UINT uDrawTextAlignment; + int iColumnWidth = GetColumnWidth(iColumn, uDrawTextAlignment); + rcItem.left = itemLeft; + rcItem.right = itemLeft + iColumnWidth - sm_iSubItemInset; + if (rcItem.left < rcItem.right && HaveIntersection(rcServer, rcItem)) { + const CString &sItem(GetItemDisplayText(pServer, iColumn)); + switch (iColumn) { + case 0: //server name + { + int iImage = 15; //server + UINT uOverlayImage = pServer->SupportsObfuscationTCP() ? 2 : 0; + + rcItem.left = itemLeft + sm_iIconOffset; + const POINT point = { rcItem.left, rcItem.top + iIconY }; + m_pImageList->Draw(dc, iImage, point, ILD_NORMAL | INDEXTOOVERLAYMASK(uOverlayImage)); + rcItem.left += 16 + sm_iLabelOffset - sm_iSubItemInset; + } + default: //any text column + rcItem.left += sm_iSubItemInset; + dc.DrawText(sItem, -1, &rcItem, MLC_DT_TEXT | uDrawTextAlignment); + } + } + itemLeft += iColumnWidth; + } + + DrawFocusRect(dc, &lpDrawItemStruct->rcItem, lpDrawItemStruct->itemState & ODS_FOCUS, bCtrlFocused, lpDrawItemStruct->itemState & ODS_SELECTED); +} + +void CServerListCtrl::Localize() +{ static const UINT uids[15] = { IDS_SL_SERVERNAME, IDS_IP, IDS_DESCRIPTION, IDS_PING, IDS_UUSERS @@ -134,22 +259,12 @@ void CServerListCtrl::Localize() , IDS_SOFTFILES, IDS_HARDFILES, IDS_VERSION, IDS_IDLOW, IDS_OBFUSCATION }; - for (int i = 0; i < _countof(uids); ++i) { - CString strRes(GetResString(uids[i])); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(i, &hdi); - } - - for (int i = GetItemCount(); --i >= 0;) - RefreshServer(reinterpret_cast(GetItemData(i))); + LocaliseHeaderCtrl(uids, _countof(uids)); } void CServerListCtrl::RemoveServer(const CServer *pServer) { - LVFINDINFO find; - find.flags = LVFI_PARAM; - find.lParam = (LPARAM)pServer; - int iItem = FindItem(&find); + int iItem = FindServer(pServer); if (iItem >= 0) { theApp.serverlist->RemoveServer(pServer); DeleteItem(iItem); @@ -173,7 +288,7 @@ void CServerListCtrl::RemoveAllFilteredServers() if (!thePrefs.GetFilterServerByIP()) return; ShowWindow(SW_HIDE); - for (POSITION pos = theApp.serverlist->list.GetHeadPosition(); pos != NULL; ) { + for (POSITION pos = theApp.serverlist->list.GetHeadPosition(); pos != NULL;) { const CServer *cur_server = theApp.serverlist->list.GetNext(pos); if (theApp.ipfilter->IsFiltered(cur_server->GetIP())) { if (thePrefs.GetLogFilteredIPs()) @@ -186,92 +301,17 @@ void CServerListCtrl::RemoveAllFilteredServers() bool CServerListCtrl::AddServer(const CServer *pServer, bool bAddToList, bool bRandom) { - bool bAddTail = !bRandom || ((GetRandomUInt16() % (1 + theApp.serverlist->GetServerCount())) != 0); + bool bAddTail = !bRandom || (rand() % (1 + theApp.serverlist->GetServerCount()) != 0); if (!theApp.serverlist->AddServer(pServer, bAddTail)) return false; if (bAddToList) { - InsertItem(LVIF_TEXT | LVIF_PARAM, bAddTail ? GetItemCount() : 0, pServer->GetListName(), 0, 0, 0, (LPARAM)pServer); - RefreshServer(pServer); + int iItem = InsertItem(LVIF_TEXT | LVIF_PARAM, bAddTail ? GetItemCount() : 0, pServer->GetListName(), 0, 0, 0, (LPARAM)pServer); + Update(iItem); } ShowServerCount(); return true; } -void CServerListCtrl::RefreshServer(const CServer *server) -{ - if (theApp.IsClosing() || !server) - return; - - LVFINDINFO find; - find.flags = LVFI_PARAM; - find.lParam = (LPARAM)server; - int itemnr = FindItem(&find); - if (itemnr == -1) - return; - - CString temp; - temp.Format(_T("%s : %i"), server->GetAddress(), server->GetPort()); - SetItemText(itemnr, 1, temp); - SetItemText(itemnr, 0, server->GetListName()); - SetItemText(itemnr, 2, server->GetDescription()); - - // Ping - if (server->GetPing()) - temp.Format(_T("%u"), server->GetPing()); - else - temp.Empty(); - SetItemText(itemnr, 3, temp); - - // Users - SetItemText(itemnr, 4, (server->GetUsers() ? (LPCTSTR)CastItoIShort(server->GetUsers()) : _T(""))); - // Max Users - SetItemText(itemnr, 5, (server->GetMaxUsers() ? (LPCTSTR)CastItoIShort(server->GetMaxUsers()) : _T(""))); - // Files - SetItemText(itemnr, 6, (server->GetFiles() ? (LPCTSTR)CastItoIShort(server->GetFiles()) : _T(""))); - - UINT uid; - switch (server->GetPreference()) { - case SRV_PR_LOW: - uid = IDS_PRIOLOW; - break; - case SRV_PR_NORMAL: - uid = IDS_PRIONORMAL; - break; - case SRV_PR_HIGH: - uid = IDS_PRIOHIGH; - break; - default: - uid = IDS_PRIONOPREF; - } - SetItemText(itemnr, 7, (LPCTSTR)GetResString(uid)); - - // Failed Count - temp.Format(_T("%u"), server->GetFailedCount()); - SetItemText(itemnr, 8, temp); - - // Static server - SetItemText(itemnr, 9, (LPCTSTR)GetResString(server->IsStaticMember() ? IDS_YES : IDS_NO)); - // Soft Files - SetItemText(itemnr, 10, (server->GetSoftFiles() ? (LPCTSTR)CastItoIShort(server->GetSoftFiles()) : _T(""))); - - // Hard Files - SetItemText(itemnr, 11, (server->GetHardFiles() ? (LPCTSTR)CastItoIShort(server->GetHardFiles()) : _T(""))); - - temp = server->GetVersion(); - if (thePrefs.GetDebugServerUDPLevel() > 0 && server->GetUDPFlags() > 0) - temp.AppendFormat(&_T("; ExtUDP=%x")[temp.IsEmpty() ? 2 : 0], server->GetUDPFlags()); - - if (thePrefs.GetDebugServerTCPLevel() > 0 && server->GetTCPFlags() > 0) - temp.AppendFormat(&_T("; ExtTCP=%x")[temp.IsEmpty() ? 2 : 0], server->GetTCPFlags()); - - SetItemText(itemnr, 12, temp); - - // LowID Users - SetItemText(itemnr, 13, (server->GetLowIDUsers() ? (LPCTSTR)CastItoIShort(server->GetLowIDUsers()) : _T(""))); - // Obfuscation - SetItemText(itemnr, 14, (LPCTSTR)GetResString(server->SupportsObfuscationTCP() ? IDS_YES : IDS_NO)); -} - void CServerListCtrl::OnContextMenu(CWnd*, CPoint point) { // get merged settings @@ -374,7 +414,7 @@ BOOL CServerListCtrl::OnCommand(WPARAM wParam, LPARAM) return TRUE; case MP_CUT: { - const CString &strURLs = CreateSelectedServersURLs(); + const CString &strURLs(CreateSelectedServersURLs()); if (!strURLs.IsEmpty()) theApp.CopyTextToClipboard(strURLs); DeleteSelectedServers(); @@ -384,7 +424,7 @@ BOOL CServerListCtrl::OnCommand(WPARAM wParam, LPARAM) case MP_GETED2KLINK: case Irc_SetSendLink: { - const CString &strURLs = CreateSelectedServersURLs(); + const CString &strURLs(CreateSelectedServersURLs()); if (!strURLs.IsEmpty()) if (wParam == Irc_SetSendLink) theApp.emuledlg->ircwnd->SetSendFileString(strURLs); @@ -449,20 +489,19 @@ BOOL CServerListCtrl::OnCommand(WPARAM wParam, LPARAM) CString CServerListCtrl::CreateSelectedServersURLs() { - CString buffer, link; + CString links; for (POSITION pos = GetFirstSelectedItemPosition(); pos != NULL;) { const CServer *pServer = reinterpret_cast(GetItemData(GetNextSelectedItem(pos))); - buffer.Format(_T("ed2k://|server|%s|%u|/"), pServer->GetAddress(), pServer->GetPort()); - if (!link.IsEmpty()) - link += _T("\r\n"); - link += buffer; + if (!links.IsEmpty()) + links += _T("\r\n"); + links.AppendFormat(_T("ed2k://|server|%s|%u|/"), pServer->GetAddress(), pServer->GetPort()); } - return link; + return links; } void CServerListCtrl::DeleteSelectedServers() { - SetRedraw(FALSE); + SetRedraw(false); POSITION pos; while ((pos = GetFirstSelectedItemPosition()) != NULL) { int iItem = GetNextSelectedItem(pos); @@ -470,7 +509,7 @@ void CServerListCtrl::DeleteSelectedServers() DeleteItem(iItem); } ShowServerCount(); - SetRedraw(TRUE); + SetRedraw(true); SetFocus(); AutoSelectItem(); } @@ -502,22 +541,29 @@ void CServerListCtrl::OnNmDblClk(LPNMHDR, LRESULT*) bool CServerListCtrl::AddServerMetToList(const CString &strFile) { - SetRedraw(FALSE); + SetRedraw(false); bool bResult = theApp.serverlist->AddServerMetToList(strFile, true); RemoveAllDeadServers(); ShowServerCount(); - SetRedraw(TRUE); + SetRedraw(true); return bResult; } +void CServerListCtrl::RefreshServer(const CServer *pServer) +{ + if (pServer && !theApp.IsClosing()) { + int iItem = FindServer(pServer); + if (iItem >= 0) + Update(iItem); + } +} + void CServerListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) { - NMLISTVIEW *pNMListView = reinterpret_cast(pNMHDR); + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); bool sortAscending; - if (GetSortItem() == pNMListView->iSubItem) - sortAscending = !GetSortAscending(); - else - switch (pNMListView->iSubItem) { + if (GetSortItem() != pNMLV->iSubItem) + switch (pNMLV->iSubItem) { case 4: // Users case 5: // Max Users case 6: // Files @@ -533,12 +579,13 @@ void CServerListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) default: sortAscending = true; } + else + sortAscending = !GetSortAscending(); // Sort table - UpdateSortHistory(MAKELONG(pNMListView->iSubItem, (sortAscending ? 0 : 0x0001))); - SetSortArrow(pNMListView->iSubItem, sortAscending); - SortItems(SortProc, MAKELONG(pNMListView->iSubItem, (sortAscending ? 0 : 0x0001))); - Invalidate(); + UpdateSortHistory(MAKELONG(pNMLV->iSubItem, !sortAscending)); + SetSortArrow(pNMLV->iSubItem, sortAscending); + SortItems(SortProc, MAKELONG(pNMLV->iSubItem, !sortAscending)); *pResult = 0; } @@ -548,8 +595,8 @@ int CALLBACK CServerListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lP return 0; const CServer *item1 = reinterpret_cast(lParam1); const CServer *item2 = reinterpret_cast(lParam2); - int iResult; + int iResult; switch (LOWORD(lParamSort)) { case 0: iResult = Undefined_at_bottom(item1->GetListName(), item2->GetListName()); @@ -623,41 +670,38 @@ int CALLBACK CServerListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lP if (iResult > 3) return iResult - 5; - //call secondary sortorder, if this one results in equal + //call secondary sort order, if the first one resulted as equal if (iResult == 0) { - int dwNextSort = theApp.emuledlg->serverwnd->serverlistctrl.GetNextSortOrder((int)lParamSort); - if (dwNextSort != -1) - iResult = SortProc(lParam1, lParam2, dwNextSort); + LPARAM iNextSort = theApp.emuledlg->serverwnd->serverlistctrl.GetNextSortOrder(lParamSort); + if (iNextSort != -1) + iResult = SortProc(lParam1, lParam2, iNextSort); } - if (HIWORD(lParamSort)) - iResult = -iResult; - return iResult; + return HIWORD(lParamSort) ? -iResult : iResult; } -bool CServerListCtrl::StaticServerFileAppend(CServer *server) +bool CServerListCtrl::StaticServerFileAppend(CServer *pServer) { - bool bResult; - AddLogLine(false, _T("'%s:%i,%s' %s"), server->GetAddress(), server->GetPort(), (LPCTSTR)server->GetListName(), (LPCTSTR)GetResString(IDS_ADDED2SSF)); - server->SetIsStaticMember(true); - bResult = theApp.serverlist->SaveStaticServers(); - RefreshServer(server); + AddLogLine(false, _T("'%s:%i,%s' %s"), pServer->GetAddress(), pServer->GetPort(), (LPCTSTR)pServer->GetListName(), (LPCTSTR)GetResString(IDS_ADDED2SSF)); + pServer->SetIsStaticMember(true); + bool bResult = theApp.serverlist->SaveStaticServers(); + RefreshServer(pServer); return bResult; } -bool CServerListCtrl::StaticServerFileRemove(CServer *server) +bool CServerListCtrl::StaticServerFileRemove(CServer *pServer) { - if (!server->IsStaticMember()) + if (!pServer->IsStaticMember()) return true; - server->SetIsStaticMember(false); + pServer->SetIsStaticMember(false); return theApp.serverlist->SaveStaticServers(); } void CServerListCtrl::ShowServerCount() { - CString counter; - counter.Format(_T(" (%i)"), GetItemCount()); - theApp.emuledlg->serverwnd->SetDlgItemText(IDC_SERVLIST_TEXT, GetResString(IDS_SV_SERVERLIST) + counter); + CString sCount(GetResString(IDS_SV_SERVERLIST)); + sCount.AppendFormat(_T(" (%i)"), GetItemCount()); + theApp.emuledlg->serverwnd->SetDlgItemText(IDC_SERVLIST_TEXT, sCount); } void CServerListCtrl::OnLvnGetInfoTip(LPNMHDR pNMHDR, LRESULT *pResult) @@ -709,9 +753,9 @@ void CServerListCtrl::OnLvnGetInfoTip(LPNMHDR pNMHDR, LRESULT *pResult) } if (iSelected > 0) { - CString strInfo; - strInfo.Format(_T("%s: %i\r\n%s: %s\r\n%s: %s\r\n%s: %s") TOOLTIP_AUTOFORMAT_SUFFIX - , (LPCTSTR)GetResString(IDS_FSTAT_SERVERS), iSelected + CString strInfo(GetResString(IDS_FSTAT_SERVERS)); + strInfo.AppendFormat(_T(": %i\r\n%s: %s\r\n%s: %s\r\n%s: %s") TOOLTIP_AUTOFORMAT_SUFFIX + , iSelected , (LPCTSTR)GetResString(IDS_UUSERS), (LPCTSTR)CastItoIShort(ulTotalUsers) , (LPCTSTR)GetResString(IDS_IDLOW), (LPCTSTR)CastItoIShort(ulTotalLowIdUsers) , (LPCTSTR)GetResString(IDS_PW_FILES), (LPCTSTR)CastItoIShort(ulTotalFiles) @@ -741,28 +785,10 @@ int CServerListCtrl::Undefined_at_bottom(const CString &s1, const CString &s2) return s2.IsEmpty() ? 4 : sgn(s1.CompareNoCase(s2)); } -void CServerListCtrl::OnNmCustomDraw(LPNMHDR pNMHDR, LRESULT *pResult) +int CServerListCtrl::FindServer(const CServer *pServer) { - LPNMLVCUSTOMDRAW pnmlvcd = (LPNMLVCUSTOMDRAW)pNMHDR; - - if (pnmlvcd->nmcd.dwDrawStage == CDDS_PREPAINT) { - *pResult = CDRF_NOTIFYITEMDRAW; - return; - } - - if (pnmlvcd->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) { - const CServer *pServer = reinterpret_cast(pnmlvcd->nmcd.lItemlParam); - const CServer *pConnectedServer = theApp.serverconnect->GetCurrentServer(); - // the server which we are connected to always has a valid numerical IP member assigned, - // therefore we do not need to call CServer::IsEqual which would be expensive - //if (pConnectedServer && pConnectedServer->IsEqual(pServer)) - if (pServer && pConnectedServer && pConnectedServer->GetIP() == pServer->GetIP() && pConnectedServer->GetPort() == pServer->GetPort()) - pnmlvcd->clrText = RGB(32, 32, 255); - else if (pServer && pServer->GetFailedCount() >= thePrefs.GetDeadServerRetries()) - pnmlvcd->clrText = RGB(192, 192, 192); - else if (pServer && pServer->GetFailedCount() >= 2) - pnmlvcd->clrText = RGB(128, 128, 128); - } - - *pResult = CDRF_DODEFAULT; -} \ No newline at end of file + LVFINDINFO find; + find.flags = LVFI_PARAM; + find.lParam = (LPARAM)pServer; + return FindItem(&find); +} diff --git a/srchybrid/ServerListCtrl.h b/srchybrid/ServerListCtrl.h index 2560bfb6..f9152eb2 100644 --- a/srchybrid/ServerListCtrl.h +++ b/srchybrid/ServerListCtrl.h @@ -1,52 +1,55 @@ #pragma once #include "MuleListCtrl.h" +#include "ToolTipCtrlX.h" class CServerList; class CServer; -class CToolTipCtrlX; class CServerListCtrl : public CMuleListCtrl { DECLARE_DYNAMIC(CServerListCtrl) + + CImageList *m_pImageList; public: CServerListCtrl(); - virtual ~CServerListCtrl(); bool Init(); bool AddServer(const CServer *pServer, bool bAddToList = true, bool bRandom = false); void RemoveServer(const CServer *pServer); bool AddServerMetToList(const CString &strFile); - void RefreshServer(const CServer *server); + void RefreshServer(const CServer *pServer); void RemoveAllDeadServers(); void RemoveAllFilteredServers(); void Hide() { ShowWindow(SW_HIDE); } void Visible() { ShowWindow(SW_SHOW); } void Localize(); void ShowServerCount(); - bool StaticServerFileAppend(CServer *server); - bool StaticServerFileRemove(CServer *server); + bool StaticServerFileAppend(CServer *pServer); + bool StaticServerFileRemove(CServer *pServer); private: static int Undefined_at_bottom(const uint32 i1, const uint32 i2); static int Undefined_at_bottom(const CString &s1, const CString &s2); + int FindServer(const CServer *pServer); protected: - CToolTipCtrlX *m_tooltip; + CToolTipCtrlX m_tooltip; CString CreateSelectedServersURLs(); void DeleteSelectedServers(); void SetSelectedServersPriority(UINT uPriority); void SetAllIcons(); + CString GetItemDisplayText(const CServer *server, int iSubItem) const; static int CALLBACK SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); virtual BOOL OnCommand(WPARAM wParam, LPARAM); + virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); DECLARE_MESSAGE_MAP() afx_msg void OnContextMenu(CWnd*, CPoint point); afx_msg void OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult); afx_msg void OnLvnGetInfoTip(LPNMHDR pNMHDR, LRESULT *pResult); - afx_msg void OnNmCustomDraw(LPNMHDR pNMHDR, LRESULT *pResult); afx_msg void OnNmDblClk(LPNMHDR, LRESULT*); afx_msg void OnSysColorChange(); }; \ No newline at end of file diff --git a/srchybrid/ServerSocket.cpp b/srchybrid/ServerSocket.cpp index 954ca2b2..58726e33 100644 --- a/srchybrid/ServerSocket.cpp +++ b/srchybrid/ServerSocket.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -24,13 +24,12 @@ #include "Server.h" #include "ServerList.h" #include "ServerConnect.h" -#include "OtherFunctions.h" +#include "UpDownClient.h" #include "Opcodes.h" #include "Preferences.h" #include "SafeFile.h" #include "PartFile.h" #include "Packets.h" -#include "UpDownClient.h" #include "emuleDlg.h" #include "ServerWnd.h" #include "SearchDlg.h" @@ -176,10 +175,9 @@ bool CServerSocket::ProcessPacket(const BYTE *packet, uint32 size, uint8 opcode) bool bOutputMessage = true; if (_tcsnicmp(message, _T("server version"), 14) == 0) { if (pServer) { - // truncate string to avoid misuse by servers in showing ads - CString strVer(message.Mid(14).Trim().Left(64)); + CString strVer(message.Mid(14)); UINT nVerMaj, nVerMin; - if (_stscanf(strVer, _T("%u.%u"), &nVerMaj, &nVerMin) == 2) + if (_stscanf(strVer.Trim(), _T("%u.%u"), &nVerMaj, &nVerMin) == 2) strVer.Format(_T("%u.%02u"), nVerMaj, nVerMin); pServer->SetVersion(strVer); theApp.emuledlg->serverwnd->serverlistctrl.RefreshServer(pServer); @@ -209,7 +207,7 @@ bool CServerSocket::ProcessPacket(const BYTE *packet, uint32 size, uint8 opcode) iDynIP += _countof(sDynIP) - 1; int iBracket = message.Find(_T(']'), iDynIP); if (iBracket > 0) { - const CString dynip(message.Mid(iDynIP, iBracket - iDynIP).Trim()); + const CString &dynip(message.Mid(iDynIP, iBracket - iDynIP).Trim()); if (!dynip.IsEmpty() && dynip.GetLength() < 51) { // Verify that we really received a DN. if (pServer && inet_addr((CStringA)dynip) == INADDR_NONE) { @@ -220,7 +218,7 @@ bool CServerSocket::ProcessPacket(const BYTE *packet, uint32 size, uint8 opcode) // If a dynIP-server changed its address, or if this is the // first time we get the dynIP-address for a server which we // already have as non-dynIP in our list, we need to remove - // an already available server with the same 'dynIP:port'. + // this server with the same 'dynIP:port'. if (strOldDynIP.CompareNoCase(pServer->GetDynIP()) != 0) theApp.serverlist->RemoveDuplicatesByAddress(pServer); if (cur_server) @@ -237,9 +235,9 @@ bool CServerSocket::ProcessPacket(const BYTE *packet, uint32 size, uint8 opcode) m_bStartNewMessageLog = false; theApp.emuledlg->AddServerMessageLine(LOG_INFO, _T("")); if (cur_server) { - CString strMsg; - strMsg.Format(_T("%s: ") + GetResString(IsObfusicating() ? IDS_CONNECTEDTOOBFUSCATED : IDS_CONNECTEDTO) + _T(" (%s:%u)") - , (LPCTSTR)CTime::GetCurrentTime().Format(thePrefs.GetDateTimeFormat4Log()) + CString strMsg(CTime::GetCurrentTime().Format(thePrefs.GetDateTimeFormat4Log())); + strMsg += _T(": "); + strMsg.AppendFormat(GetResString(IsObfusicating() ? IDS_CONNECTEDTOOBFUSCATED : IDS_CONNECTEDTO) + _T(" (%s:%u)") , (LPCTSTR)cur_server->GetListName() , cur_server->GetAddress() , IsObfusicating() ? cur_server->GetObfuscationPortTCP() : cur_server->GetPort()); @@ -435,7 +433,7 @@ bool CServerSocket::ProcessPacket(const BYTE *packet, uint32 size, uint8 opcode) CString strName; CString strDescription; for (uint32 i = 0; i < nTags; ++i) { - CTag tag(&data, pServer ? pServer->GetUnicodeSupport() : false); + CTag tag(data, pServer ? pServer->GetUnicodeSupport() : false); if (tag.GetNameID() == ST_SERVERNAME) { if (tag.IsStr()) { strName = tag.GetStr(); @@ -517,7 +515,7 @@ bool CServerSocket::ProcessPacket(const BYTE *packet, uint32 size, uint8 opcode) uint32 dwIP = PeekUInt32(packet); if (theApp.ipfilter->IsFiltered(dwIP)) { - theStats.filteredclients++; + ++theStats.filteredclients; if (thePrefs.GetLogFilteredIPs()) AddDebugLogLine(false, _T("Ignored callback request (IP=%s) - IP filter (%s)"), (LPCTSTR)ipstr(dwIP), (LPCTSTR)theApp.ipfilter->GetLastHit()); break; diff --git a/srchybrid/ServerSocket.h b/srchybrid/ServerSocket.h index e2f6219d..2f52bb78 100644 --- a/srchybrid/ServerSocket.h +++ b/srchybrid/ServerSocket.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/ServerWnd.cpp b/srchybrid/ServerWnd.cpp index efd1be15..e238935d 100644 --- a/srchybrid/ServerWnd.cpp +++ b/srchybrid/ServerWnd.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -23,7 +23,6 @@ #include "kademlia/kademlia/kademlia.h" #include "kademlia/kademlia/prefs.h" #include "kademlia/utils/MiscUtils.h" -#include "OtherFunctions.h" #include "emuledlg.h" #include "WebServer.h" #include "CustomAutoComplete.h" @@ -129,10 +128,12 @@ BOOL CServerWnd::OnInitDialog() servermsgbox->ApplySkin(); servermsgbox->SetTitle(GetResString(IDS_SV_SERVERINFO)); - servermsgbox->AppendText(_T("eMule v") + theApp.m_strCurVersionLong + _T('\n')); + servermsgbox->AppendText(_T("eMule v")); + servermsgbox->AppendText(theApp.m_strCurVersionLong); + servermsgbox->AppendText(_T("\n")); // MOD Note: Do not remove this part - Merkur m_strClickNewVersion.Format(_T("%s %s %s"), (LPCTSTR)GetResString(IDS_EMULEW), (LPCTSTR)GetResString(IDS_EMULEW3), (LPCTSTR)GetResString(IDS_EMULEW2)); - servermsgbox->AppendHyperLink(_T(""), _T(""), m_strClickNewVersion, _T("")); + servermsgbox->AppendHyperLink(NULL, NULL, m_strClickNewVersion, NULL); // MOD Note: end servermsgbox->AppendText(_T("\n\n")); } @@ -173,23 +174,22 @@ BOOL CServerWnd::OnInitDialog() SetDlgItemText(IDC_SPORT, _T("4661")); TCITEM newitem; - CString name; - name = GetResString(IDS_SV_SERVERINFO); - name.Replace(_T("&"), _T("&&")); + CString name(GetResString(IDS_SV_SERVERINFO)); + DupAmpersand(name); newitem.mask = TCIF_TEXT | TCIF_IMAGE; newitem.pszText = const_cast((LPCTSTR)name); newitem.iImage = 1; VERIFY(StatusSelector.InsertItem(StatusSelector.GetItemCount(), &newitem) == PaneServerInfo); name = GetResString(IDS_SV_LOG); - name.Replace(_T("&"), _T("&&")); + DupAmpersand(name); newitem.mask = TCIF_TEXT | TCIF_IMAGE; newitem.pszText = const_cast((LPCTSTR)name); newitem.iImage = 0; VERIFY(StatusSelector.InsertItem(StatusSelector.GetItemCount(), &newitem) == PaneLog); name = SZ_DEBUG_LOG_TITLE; - name.Replace(_T("&"), _T("&&")); + DupAmpersand(name); newitem.mask = TCIF_TEXT | TCIF_IMAGE; newitem.pszText = const_cast((LPCTSTR)name); newitem.iImage = 0; @@ -277,7 +277,7 @@ BOOL CServerWnd::OnInitDialog() InitSplitter(); GetDlgItem(IDC_ED2KCONNECT)->EnableWindow(false); - return true; + return TRUE; } void CServerWnd::DoDataExchange(CDataExchange *pDX) @@ -303,8 +303,8 @@ bool CServerWnd::UpdateServerMetFromURL(const CString &strURL) if (m_pacServerMetURL && m_pacServerMetURL->IsBound()) m_pacServerMetURL->AddItem(strURL, 0); - CString strTempFilename; - strTempFilename.Format(_T("%stemp-%u-server.met"), (LPCTSTR)thePrefs.GetMuleDirectory(EMULE_CONFIGDIR), ::GetTickCount()); + CString strTempFilename(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); + strTempFilename.AppendFormat(_T("temp-%u-server.met"), ::GetTickCount()); // try to download server.met Log(GetResString(IDS_DOWNLOADING_SERVERMET_FROM), (LPCTSTR)strURL); @@ -367,21 +367,20 @@ void CServerWnd::Localize() m_ctrlMyInfoFrm.SetWindowText(GetResString(IDS_MYINFO)); TCITEM item; - CString name; - name = GetResString(IDS_SV_SERVERINFO); - name.Replace(_T("&"), _T("&&")); + CString name(GetResString(IDS_SV_SERVERINFO)); + DupAmpersand(name); item.mask = TCIF_TEXT; item.pszText = const_cast((LPCTSTR)name); StatusSelector.SetItem(PaneServerInfo, &item); name = GetResString(IDS_SV_LOG); - name.Replace(_T("&"), _T("&&")); + DupAmpersand(name); item.mask = TCIF_TEXT; item.pszText = const_cast((LPCTSTR)name); StatusSelector.SetItem(PaneLog, &item); name = SZ_DEBUG_LOG_TITLE; - name.Replace(_T("&"), _T("&&")); + DupAmpersand(name); item.mask = TCIF_TEXT; item.pszText = const_cast((LPCTSTR)name); StatusSelector.SetItem(PaneVerboseLog, &item); @@ -425,7 +424,7 @@ void CServerWnd::OnBnClickedAddserver() return; } - BOOL bTranslated = FALSE; + BOOL bTranslated; uPort = (uint16)GetDlgItemInt(IDC_SPORT, &bTranslated, FALSE); if (!bTranslated) { LocMessageBox(IDS_SRV_PORT, MB_OK, 0); @@ -446,8 +445,8 @@ void CServerWnd::OnBnClickedAddserver() void CServerWnd::PasteServerFromClipboard() { - const CString strServer(theApp.CopyTextFromClipboard().Trim()); - if (strServer.IsEmpty()) + CString strServer(theApp.CopyTextFromClipboard()); + if (strServer.Trim().IsEmpty()) return; bool bAdd = true; @@ -588,7 +587,7 @@ void CServerWnd::ToggleDebugWindow() if (thePrefs.GetVerbose() && !debug) { TCITEM newitem; CString name(SZ_DEBUG_LOG_TITLE); - name.Replace(_T("&"), _T("&&")); + DupAmpersand(name); newitem.mask = TCIF_TEXT | TCIF_IMAGE; newitem.pszText = const_cast((LPCTSTR)name); newitem.iImage = 0; diff --git a/srchybrid/ServerWnd.h b/srchybrid/ServerWnd.h index 755d59b8..a1b4a7ff 100644 --- a/srchybrid/ServerWnd.h +++ b/srchybrid/ServerWnd.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/ShareableFile.cpp b/srchybrid/ShareableFile.cpp index 9dd500ad..da8ab35d 100644 --- a/srchybrid/ShareableFile.cpp +++ b/srchybrid/ShareableFile.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -28,21 +28,19 @@ CShareableFile::CShareableFile() CString CShareableFile::GetInfoSummary(bool bNoFormatCommands) const { - CString strFolder = GetPath(); - PathRemoveBackslash(strFolder.GetBuffer()); - strFolder.ReleaseBuffer(); + CString strFolder(GetPath()); + unslosh(strFolder); - CString strType = GetFileTypeDisplayStr(); + CString strType(GetFileTypeDisplayStr()); if (strType.IsEmpty()) strType += _T('-'); - CString info; - info.Format(_T("%s\n") + CString info(GetFileName()); + info.AppendFormat(_T("\n") _T("%s %s\n") _T("%s\n") _T("%s: %s\n") _T("%s: %s") - , (LPCTSTR)GetFileName() , (LPCTSTR)GetResString(IDS_FD_SIZE), (LPCTSTR)CastItoXBytes((uint64)GetFileSize()) , bNoFormatCommands ? _T("") : _T("") , (LPCTSTR)GetResString(IDS_TYPE), (LPCTSTR)strType diff --git a/srchybrid/ShareableFile.h b/srchybrid/ShareableFile.h index 5f49effb..3e1a37f1 100644 --- a/srchybrid/ShareableFile.h +++ b/srchybrid/ShareableFile.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -28,7 +28,6 @@ class CShareableFile : public CAbstractFile public: CShareableFile(); - virtual ~CShareableFile() = default; virtual void UpdateFileRatingCommentAvail(bool /*bForceUpdate = false*/) { ASSERT(0); } EFileType GetVerifiedFileType() const { return m_verifiedFileType; } @@ -38,7 +37,7 @@ class CShareableFile : public CAbstractFile void SetPath(LPCTSTR path) { m_strDirectory = path; } // Shared directory is equal to the path for all shared files, except those following a shell link - // in which case the directory of the shell link is return. Use GetPath to access the file + // in which case the directory of the shell link is returned. Use GetPath to access the file const CString& GetSharedDirectory() const { return m_strSharedDirectory.IsEmpty() ? m_strDirectory : m_strSharedDirectory; } void SetSharedDirectory(LPCTSTR path) { m_strSharedDirectory = path; } bool IsShellLinked() const { return !m_strSharedDirectory.IsEmpty(); } diff --git a/srchybrid/SharedDirsTreeCtrl.cpp b/srchybrid/SharedDirsTreeCtrl.cpp index 642d7ada..f857c71e 100644 --- a/srchybrid/SharedDirsTreeCtrl.cpp +++ b/srchybrid/SharedDirsTreeCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -132,6 +132,10 @@ void CSharedDirsTreeCtrl::SetAllIcons() // support an update of the control and the image list, we need to 'replace' our own // images so that we are able to keep the already stored images from the Windows System // image list. + + //Should be terminated with a backslash for a directory image + int nImage = theApp.GetFileTypeSystemImageIdx(thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR)); + CImageList *pCurImageList = GetImageList(TVSIL_NORMAL); if (pCurImageList != NULL && pCurImageList->GetImageCount() >= 7) { pCurImageList->Replace(0, CTempIconLoader(_T("AllFiles"))); // 0: All Directory @@ -139,10 +143,7 @@ void CSharedDirsTreeCtrl::SetAllIcons() pCurImageList->Replace(2, CTempIconLoader(_T("Incoming"))); // 2: Incoming Directory pCurImageList->Replace(3, CTempIconLoader(_T("Category"))); // 3: Cats pCurImageList->Replace(4, CTempIconLoader(_T("HardDisk"))); // 4: All Dirs - CString strTempDir(thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR)); - slosh(strTempDir); - int nImage = theApp.GetFileTypeSystemImageIdx(strTempDir); // 5: System Folder Icon - if (nImage > 0 && theApp.GetSystemImageList() != NULL) { + if (nImage > 0 && theApp.GetSystemImageList() != NULL) { // 5: System Folder Icon HICON hIcon = ::ImageList_GetIcon(theApp.GetSystemImageList(), nImage, 0); pCurImageList->Replace(5, hIcon); ::DestroyIcon(hIcon); @@ -159,10 +160,7 @@ void CSharedDirsTreeCtrl::SetAllIcons() iml.Add(CTempIconLoader(_T("Incoming"))); // 2: Incoming Directory iml.Add(CTempIconLoader(_T("Category"))); // 3: Cats iml.Add(CTempIconLoader(_T("HardDisk"))); // 4: All Dirs - CString strTempDir(thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR)); - slosh(strTempDir); - int nImage = theApp.GetFileTypeSystemImageIdx(strTempDir); // 5: System Folder Icon - if (nImage > 0 && theApp.GetSystemImageList() != NULL) { + if (nImage > 0 && theApp.GetSystemImageList() != NULL) { // 5: System Folder Icon HICON hIcon = ::ImageList_GetIcon(theApp.GetSystemImageList(), nImage, 0); iml.Add(hIcon); ::DestroyIcon(hIcon); @@ -240,14 +238,14 @@ bool CSharedDirsTreeCtrl::FilterTreeIsSubDirectory(const CString &strDir, const { CString sRoot(strRoot); sRoot.MakeLower(); - slosh(sRoot); + ASSERT(strRoot.IsEmpty() || strRoot.Right(1) == _T("\\")); CString sDir(strDir); sDir.MakeLower(); - slosh(sDir); + ASSERT(strDir.Right(1) == _T("\\")); for (POSITION pos = liDirs.GetHeadPosition(); pos != NULL;) { CString strCurrent(liDirs.GetNext(pos)); strCurrent.MakeLower(); - slosh(strCurrent); + ASSERT(strCurrent.Right(1) == _T("\\")); if (sRoot.Find(strCurrent, 0) != 0 && sDir.Find(strCurrent, 0) == 0 && strCurrent != sRoot && strCurrent != sDir) return true; } @@ -256,19 +254,16 @@ bool CSharedDirsTreeCtrl::FilterTreeIsSubDirectory(const CString &strDir, const CString GetFolderLabel(const CString &strFolderPath, bool bTopFolder, bool bAccessible) { - CString strFolder(strFolderPath); - PathRemoveBackslash(strFolder.GetBuffer()); - strFolder.ReleaseBuffer(); - - CString strLabel(strFolder); + CString strLabel(strFolderPath); if (strLabel.GetLength() == 2 && strLabel[1] == _T(':')) { ASSERT(bTopFolder); strLabel += _T('\\'); } else { + unslosh(strLabel); strLabel.Delete(0, strLabel.ReverseFind(_T('\\')) + 1); if (bTopFolder) { - CString strParentFolder(strFolder); - PathRemoveFileSpec(strParentFolder.GetBuffer()); + CString strParentFolder(strFolderPath); + ::PathRemoveFileSpec(strParentFolder.GetBuffer()); strParentFolder.ReleaseBuffer(); strLabel.AppendFormat(_T(" (%s)"), (LPCTSTR)strParentFolder); } @@ -279,8 +274,8 @@ CString GetFolderLabel(const CString &strFolderPath, bool bTopFolder, bool bAcce return strLabel; } -void CSharedDirsTreeCtrl::FilterTreeAddSubDirectories(CDirectoryItem *pDirectory, const CStringList &liDirs, - int nLevel, bool &rbShowWarning, bool bParentAccessible) +void CSharedDirsTreeCtrl::FilterTreeAddSubDirectories(CDirectoryItem *pDirectory, const CStringList &liDirs + , int nLevel, bool &rbShowWarning, bool bParentAccessible) { // just some sanity check against too deep shared dirs // shouldn't be needed, but never trust the file system or a recursive function ;) @@ -289,16 +284,14 @@ void CSharedDirsTreeCtrl::FilterTreeAddSubDirectories(CDirectoryItem *pDirectory return; } - CString strDirectoryPath(pDirectory->m_strFullPath); - strDirectoryPath.MakeLower(); - for (POSITION pos = liDirs.GetHeadPosition(); pos != NULL;) { - const CString &strCurrent = liDirs.GetNext(pos); - CString strCurrentLow = strCurrent; - strCurrentLow.MakeLower(); - if ((strDirectoryPath.IsEmpty() || strCurrentLow.Find(strDirectoryPath + _T('\\'), 0) == 0) && strCurrentLow != strDirectoryPath) { - if (!FilterTreeIsSubDirectory(strCurrentLow, strDirectoryPath, liDirs)) { - bool bAccessible = !bParentAccessible ? false : (_taccess(strCurrent, 0) == 0); - const CString &strName = GetFolderLabel(strCurrent, nLevel == 0, bAccessible); + const CString &strDirectoryPath(pDirectory->m_strFullPath); + int iLen = strDirectoryPath.GetLength(); + for (POSITION pos = liDirs.GetHeadPosition(); pos != NULL;) { //all paths in liDirs should have a trailing backslash + const CString &strCurrent(liDirs.GetNext(pos)); + if ((iLen <= 0 || _tcsnicmp(strCurrent, strDirectoryPath, iLen) == 0) && iLen != strCurrent.GetLength()) { + if (!FilterTreeIsSubDirectory(strCurrent, strDirectoryPath, liDirs)) { + bool bAccessible = bParentAccessible ? (_taccess(strCurrent, 0) == 0) : false; + const CString &strName(GetFolderLabel(strCurrent, nLevel == 0, bAccessible)); CDirectoryItem *pNewItem = new CDirectoryItem(strCurrent); pNewItem->m_htItem = InsertItem(TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE, strName, 5, 5, 0, 0, (LPARAM)pNewItem, pDirectory->m_htItem, TVI_SORT); if (!bAccessible) { @@ -331,24 +324,22 @@ void CSharedDirsTreeCtrl::FilterTreeReloadTree() break; case SDI_INCOMING: { - CString strMainIncDir = thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR); - unslosh(strMainIncDir); + CString strMainIncDir(thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR)); bool bShowWarning = false; if (thePrefs.GetCatCount() > 1) { m_strliCatIncomingDirs.RemoveAll(); - for (int i = 0; i < thePrefs.GetCatCount(); ++i) { + for (INT_PTR i = 0; i < thePrefs.GetCatCount(); ++i) { Category_Struct *pCatStruct = thePrefs.GetCategory(i); if (pCatStruct != NULL) { - CString strCatIncomingPath = pCatStruct->strIncomingPath; - unslosh(strCatIncomingPath); - + const CString &strCatIncomingPath(pCatStruct->strIncomingPath); + ASSERT(strCatIncomingPath.IsEmpty() || strCatIncomingPath.Right(1) == _T("\\")); if (!strCatIncomingPath.IsEmpty() && strCatIncomingPath.CompareNoCase(strMainIncDir) != 0 && m_strliCatIncomingDirs.Find(strCatIncomingPath) == NULL) { m_strliCatIncomingDirs.AddTail(strCatIncomingPath); bool bAccessible = _taccess(strCatIncomingPath, 00) == 0; - const CString &strName = GetFolderLabel(strCatIncomingPath, true, bAccessible); + const CString &strName(GetFolderLabel(strCatIncomingPath, true, bAccessible)); CDirectoryItem *pCatInc = new CDirectoryItem(strCatIncomingPath, 0, SDI_CATINCOMING); pCatInc->m_htItem = InsertItem(TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE, strName, 5, 5, 0, 0, (LPARAM)pCatInc, pCurrent->m_htItem, TVI_SORT); if (!bAccessible) { @@ -365,11 +356,11 @@ void CSharedDirsTreeCtrl::FilterTreeReloadTree() break; case SDI_TEMP: if (thePrefs.GetCatCount() > 1) { - for (int i = 0; i < thePrefs.GetCatCount(); ++i) { + for (INT_PTR i = 0; i < thePrefs.GetCatCount(); ++i) { Category_Struct *pCatStruct = thePrefs.GetCategory(i); if (pCatStruct != NULL) { //temp dir - CDirectoryItem *pCatTemp = new CDirectoryItem(CString(), 0, SDI_TEMP, i); + CDirectoryItem *pCatTemp = new CDirectoryItem(CString(), 0, SDI_TEMP, (int)i); pCatTemp->m_htItem = InsertItem(TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE, pCatStruct->strTitle, 3, 3, 0, 0, (LPARAM)pCatTemp, pCurrent->m_htItem, TVI_LAST); pCurrent->liSubDirectories.AddTail(pCatTemp); @@ -404,7 +395,8 @@ void CSharedDirsTreeCtrl::FilterTreeReloadTree() CDirectoryItem* CSharedDirsTreeCtrl::GetSelectedFilter() const { - return (GetSelectedItem() == NULL) ? NULL : reinterpret_cast(GetItemData(GetSelectedItem())); + const HTREEITEM item = GetSelectedItem(); + return item ? reinterpret_cast(GetItemData(item)) : NULL; } void CSharedDirsTreeCtrl::CreateMenus() @@ -609,7 +601,7 @@ BOOL CSharedDirsTreeCtrl::OnCommand(WPARAM wParam, LPARAM) if (IDNO == LocMessageBox(IDS_CONFIRM_FILEDELETE, MB_ICONWARNING | MB_DEFBUTTON2 | MB_YESNO, 0)) return TRUE; - m_pSharedFilesCtrl->SetRedraw(FALSE); + m_pSharedFilesCtrl->SetRedraw(false); bool bRemovedItems = false; while (!selectedList.IsEmpty()) { CShareableFile *myfile = selectedList.RemoveHead(); @@ -625,16 +617,16 @@ BOOL CSharedDirsTreeCtrl::OnCommand(WPARAM wParam, LPARAM) theApp.emuledlg->transferwnd->GetDownloadList()->ClearCompleted(static_cast(myfile)); } else { CString strError; - strError.Format(GetResString(IDS_ERR_DELFILE) + _T("\r\n\r\n%s"), (LPCTSTR)myfile->GetFilePath(), (LPCTSTR)GetErrorMessage(::GetLastError())); + strError.Format(GetResString(IDS_ERR_DELFILE), (LPCTSTR)myfile->GetFilePath()); + strError.AppendFormat(_T("\r\n\r\n%s"), (LPCTSTR)GetErrorMessage(::GetLastError())); AfxMessageBox(strError); } } - m_pSharedFilesCtrl->SetRedraw(TRUE); + m_pSharedFilesCtrl->SetRedraw(true); if (bRemovedItems) { m_pSharedFilesCtrl->AutoSelectItem(); - // Depending on this does not always cause a - // LVN_ITEMACTIVATE message sent. So, explicitly redraw - // the item. + // Depending on this does not always cause an LVN_ITEMACTIVATE + // message to be sent. So, explicitly redraw the item. theApp.emuledlg->sharedfileswnd->ShowSelectedFilesDetails(); theApp.emuledlg->sharedfileswnd->OnSingleFileShareStatusChanged(); // might have been a single shared file } @@ -656,38 +648,36 @@ BOOL CSharedDirsTreeCtrl::OnCommand(WPARAM wParam, LPARAM) case MP_PRIOHIGH: case MP_PRIOVERYHIGH: case MP_PRIOAUTO: - { - for (POSITION pos = selectedList.GetHeadPosition(); pos != NULL;) { - CKnownFile *file = static_cast(selectedList.GetNext(pos)); - if (file->IsKindOf(RUNTIME_CLASS(CKnownFile))) { - uint8 pri; - switch (wParam) { - case MP_PRIOVERYLOW: - pri = PR_VERYLOW; - break; - case MP_PRIOLOW: - pri = PR_LOW; - break; - case MP_PRIONORMAL: - pri = PR_NORMAL; - break; - case MP_PRIOHIGH: - pri = PR_HIGH; - break; - case MP_PRIOVERYHIGH: - pri = PR_VERYHIGH; - case MP_PRIOAUTO: - break; - default: - wParam = MP_PRIOAUTO; - } - file->SetAutoUpPriority(wParam == MP_PRIOAUTO); - if (wParam == MP_PRIOAUTO) - file->UpdateAutoUpPriority(); - else { - file->SetUpPriority(pri); - m_pSharedFilesCtrl->UpdateFile(file); - } + for (POSITION pos = selectedList.GetHeadPosition(); pos != NULL;) { + CKnownFile *file = static_cast(selectedList.GetNext(pos)); + if (file->IsKindOf(RUNTIME_CLASS(CKnownFile))) { + uint8 pri; + switch (wParam) { + case MP_PRIOVERYLOW: + pri = PR_VERYLOW; + break; + case MP_PRIOLOW: + pri = PR_LOW; + break; + case MP_PRIONORMAL: + pri = PR_NORMAL; + break; + case MP_PRIOHIGH: + pri = PR_HIGH; + break; + case MP_PRIOVERYHIGH: + pri = PR_VERYHIGH; + case MP_PRIOAUTO: + break; + default: + wParam = MP_PRIOAUTO; + } + file->SetAutoUpPriority(wParam == MP_PRIOAUTO); + if (wParam == MP_PRIOAUTO) + file->UpdateAutoUpPriority(); + else { + file->SetUpPriority(pri); + m_pSharedFilesCtrl->UpdateFile(file); } } } @@ -712,8 +702,8 @@ void CSharedDirsTreeCtrl::FileSystemTreeCreateTree() for (TCHAR *pos = drivebuffer; *pos != _T('\0'); pos += _tcslen(pos) + 2) { // Copy drive name - pos[2] = _T('\0'); //drop backslash, leave only drive letter and column - FileSystemTreeAddChildItem(m_pRootUnsharedDirectries, pos, true); // e.g. "C:" + pos[2] = _T('\0'); //drop backslash, leave only drive letter with column; e.g. "C:" + FileSystemTreeAddChildItem(m_pRootUnsharedDirectries, pos, true); } } } @@ -724,6 +714,7 @@ void CSharedDirsTreeCtrl::FileSystemTreeAddChildItem(CDirectoryItem *pRoot, cons if (!strPath.IsEmpty()) slosh(strPath); CString strDir(strPath + strText); + slosh(strDir); TVINSERTSTRUCT itInsert = {}; if (m_bUseIcons) { @@ -734,18 +725,12 @@ void CSharedDirsTreeCtrl::FileSystemTreeAddChildItem(CDirectoryItem *pRoot, cons itInsert.item.stateMask = TVIS_BOLD; } - if (FileSystemTreeHasSharedSubdirectory(strDir, true) || FileSystemTreeIsShared(strDir)) itInsert.item.state = TVIS_BOLD; else itInsert.item.state = 0; + itInsert.item.cChildren = FileSystemTreeHasSubdirectories(strDir) ? I_CHILDRENCALLBACK : 0; // used to display the '+' symbol next to each item - if (FileSystemTreeHasSubdirectories(strDir)) - itInsert.item.cChildren = I_CHILDRENCALLBACK; // used to display the + symbol next to each item - else - itInsert.item.cChildren = 0; - - unslosh(strDir); CDirectoryItem *pti = new CDirectoryItem(strDir, 0, SDI_UNSHAREDDIRECTORY); itInsert.item.pszText = const_cast((LPCTSTR)strText); @@ -754,33 +739,33 @@ void CSharedDirsTreeCtrl::FileSystemTreeAddChildItem(CDirectoryItem *pRoot, cons itInsert.item.mask |= TVIF_PARAM; itInsert.item.lParam = (LPARAM)pti; + CString sName; //temporary storage for display name if (m_bUseIcons) { if (FileSystemTreeIsShared(strDir)) { itInsert.item.stateMask |= TVIS_OVERLAYMASK; itInsert.item.state |= INDEXTOOVERLAYMASK(1); } - const CString strTemp(strDir + _T('\\')); - - UINT nType = GetDriveType(strTemp); + slosh(strDir); + UINT nType = ::GetDriveType(strDir); if (DRIVE_REMOVABLE <= nType && nType <= DRIVE_RAMDISK) itInsert.item.iImage = nType; SHFILEINFO shFinfo; shFinfo.szDisplayName[0] = _T('\0'); - if (SHGetFileInfo(strTemp, 0, &shFinfo, sizeof(shFinfo), SHGFI_ICON | SHGFI_SMALLICON | SHGFI_DISPLAYNAME)) { + if (::SHGetFileInfo(strDir, 0, &shFinfo, sizeof(shFinfo), SHGFI_ICON | SHGFI_SMALLICON | SHGFI_DISPLAYNAME)) { itInsert.itemex.iImage = AddSystemIcon(shFinfo.hIcon, shFinfo.iIcon); ::DestroyIcon(shFinfo.hIcon); if (bTopLevel && shFinfo.szDisplayName[0] != _T('\0')) { - strDir = shFinfo.szDisplayName; //strDir as a temporary storage here - itInsert.item.pszText = const_cast((LPCTSTR)strDir); + sName = shFinfo.szDisplayName; + itInsert.item.pszText = const_cast((LPCTSTR)sName); } } else { TRACE(_T("Error Getting SystemFileInfo!")); itInsert.itemex.iImage = 0; // :( } - if (SHGetFileInfo(strTemp, 0, &shFinfo, sizeof(shFinfo), SHGFI_ICON | SHGFI_OPENICON | SHGFI_SMALLICON)) { + if (::SHGetFileInfo(strDir, 0, &shFinfo, sizeof(shFinfo), SHGFI_ICON | SHGFI_OPENICON | SHGFI_SMALLICON)) { itInsert.itemex.iSelectedImage = AddSystemIcon(shFinfo.hIcon, shFinfo.iIcon); ::DestroyIcon(shFinfo.hIcon); } else { @@ -795,70 +780,44 @@ void CSharedDirsTreeCtrl::FileSystemTreeAddChildItem(CDirectoryItem *pRoot, cons bool CSharedDirsTreeCtrl::FileSystemTreeHasSubdirectories(const CString &strDir) { - CString sDir(strDir); - slosh(sDir); - // Never try to enumerate the files of a drive and thus physically access the drive, just - // for the information whether the drive has sub directories in the root folder. Depending - // on the physical drive type (floppy disk, CD-ROM drive, etc.) this creates an annoying - // physical access to that drive - which is to be avoided in each case. Even Windows - // Explorer shows all drives by default with a '+' sign (which means that the user has - // to explicitly open the drive to really get the content) - and that approach will be fine - // for eMule as well. - // Since the restriction for drives 'A:' and 'B:' was removed, this gets more important now. - if (PathIsRoot(sDir)) - return true; - CFileFind finder; - BOOL bWorking = finder.FindFile(sDir + _T("*.*")); - while (bWorking) { - bWorking = finder.FindNextFile(); - if (!finder.IsDots() && !finder.IsSystem() && finder.IsDirectory()) { - finder.Close(); - return true; - } - } - finder.Close(); - return false; + return ::HasSubdirectories(strDir); } bool CSharedDirsTreeCtrl::FileSystemTreeHasSharedSubdirectory(const CString &strDir, bool bOrFiles) { - CString sDir(strDir); - slosh(sDir.MakeLower()); + int iLen = strDir.GetLength(); + ASSERT(iLen > 0); + bool bSlosh = (strDir[iLen - 1] == _T('\\')); for (POSITION pos = m_strliSharedDirs.GetHeadPosition(); pos != NULL;) { - CString strCurrent(m_strliSharedDirs.GetNext(pos)); - strCurrent.MakeLower(); - if (strCurrent.Find(sDir) == 0 && sDir != strCurrent) + const CString &sCurrent(m_strliSharedDirs.GetNext(pos)); + if (_tcsnicmp(sCurrent, strDir, iLen) == 0 && iLen < sCurrent.GetLength() && (bSlosh || sCurrent[iLen] == _T('\\'))) return true; } - return bOrFiles && theApp.sharedfiles->ContainsSingleSharedFiles(sDir); + return bOrFiles && theApp.sharedfiles->ContainsSingleSharedFiles(strDir); } void CSharedDirsTreeCtrl::FileSystemTreeAddSubdirectories(CDirectoryItem *pRoot) { - CString strDir = pRoot->m_strFullPath; - slosh(strDir); + ASSERT(pRoot->m_strFullPath.Right(1) == _T("\\")); CFileFind finder; - BOOL bWorking = finder.FindFile(strDir + _T("*.*")); - while (bWorking) { - bWorking = finder.FindNextFile(); - if (!finder.IsDots() && !finder.IsSystem() && finder.IsDirectory()) { + for (BOOL bFound = finder.FindFile(pRoot->m_strFullPath + _T("*.*")); bFound;) { + bFound = finder.FindNextFile(); + if (finder.IsDirectory() && !finder.IsDots() && !finder.IsSystem()) { CString strFilename(finder.GetFileName()); - int i = strFilename.ReverseFind(_T('\\')); - if (i >= 0) - strFilename.Delete(0, i + 1); + strFilename.Delete(0, strFilename.ReverseFind(_T('\\')) + 1); FileSystemTreeAddChildItem(pRoot, strFilename, false); } } - finder.Close(); } int CSharedDirsTreeCtrl::AddSystemIcon(HICON hIcon, int nSystemListPos) { - int nPos = 0; + int nPos; if (!m_mapSystemIcons.Lookup(nSystemListPos, nPos)) { nPos = GetImageList(TVSIL_NORMAL)->Add(hIcon); - m_mapSystemIcons.SetAt(nSystemListPos, nPos); - } + m_mapSystemIcons[nSystemListPos] = nPos; + } else + nPos = 0; return nPos; } @@ -900,47 +859,45 @@ void CSharedDirsTreeCtrl::DeleteChildItems(CDirectoryItem *pParent) bool CSharedDirsTreeCtrl::FileSystemTreeIsShared(const CString &strDir) { for (POSITION pos = m_strliSharedDirs.GetHeadPosition(); pos != NULL;) - if (CompareDirectory(m_strliSharedDirs.GetNext(pos), strDir) == 0) + if (EqualPaths(m_strliSharedDirs.GetNext(pos), strDir)) return true; return false; } void CSharedDirsTreeCtrl::OnTvnGetdispinfo(LPNMHDR pNMHDR, LRESULT *pResult) { - LPNMTVDISPINFO pTVDispInfo = reinterpret_cast(pNMHDR); - pTVDispInfo->item.cChildren = 1; + reinterpret_cast(pNMHDR)->item.cChildren = 1; *pResult = 0; } void CSharedDirsTreeCtrl::AddSharedDirectory(const CString &strDir, bool bSubDirectories) { - if (!FileSystemTreeIsShared(strDir) && thePrefs.IsShareableDirectory(strDir)) - m_strliSharedDirs.AddTail(strDir); + CString sDir(strDir); + slosh(sDir); + if (!FileSystemTreeIsShared(sDir) && thePrefs.IsShareableDirectory(sDir)) + m_strliSharedDirs.AddTail(sDir); if (bSubDirectories) { - CString sDir(strDir); - slosh(sDir); CFileFind finder; - BOOL bWorking = finder.FindFile(sDir + _T("*.*")); - while (bWorking) { - bWorking = finder.FindNextFile(); - if (!finder.IsDots() && !finder.IsSystem() && finder.IsDirectory()) - AddSharedDirectory(sDir + finder.GetFileName(), true); + for (BOOL bFound = finder.FindFile(sDir + _T("*.*")); bFound;) { + bFound = finder.FindNextFile(); + if (finder.IsDirectory() && !finder.IsDots() && !finder.IsSystem()) + AddSharedDirectory(sDir + finder.GetFileName(), true); //no trailing backslash here } - finder.Close(); } } void CSharedDirsTreeCtrl::RemoveSharedDirectory(const CString &strDir, bool bSubDirectories) { - CString sDir(strDir); - unslosh(sDir); - sDir.MakeLower(); + int iLen = strDir.GetLength(); for (POSITION pos = m_strliSharedDirs.GetHeadPosition(); pos != NULL;) { POSITION pos2 = pos; - CString str(m_strliSharedDirs.GetNext(pos)); - if (str.MakeLower().Compare(sDir) == 0 || (bSubDirectories && str.Find(sDir) == 0)) + const CString &str(m_strliSharedDirs.GetNext(pos)); + if (_tcsnicmp(str, strDir, (bSubDirectories ? iLen : max(iLen, str.GetLength()))) == 0) { m_strliSharedDirs.RemoveAt(pos2); + if (!bSubDirectories) + break; + } } } @@ -953,7 +910,8 @@ void CSharedDirsTreeCtrl::FileSystemTreeUpdateBoldState(const CDirectoryItem *pD { if (pDir == NULL) pDir = m_pRootUnsharedDirectries; - SetItemState(pDir->m_htItem, ((FileSystemTreeHasSharedSubdirectory(pDir->m_strFullPath, true) || FileSystemTreeIsShared(pDir->m_strFullPath)) ? TVIS_BOLD : 0), TVIS_BOLD); + else + SetItemState(pDir->m_htItem, ((FileSystemTreeHasSharedSubdirectory(pDir->m_strFullPath, true) || FileSystemTreeIsShared(pDir->m_strFullPath)) ? TVIS_BOLD : 0), TVIS_BOLD); for (POSITION pos = pDir->liSubDirectories.GetHeadPosition(); pos != NULL;) FileSystemTreeUpdateBoldState(pDir->liSubDirectories.GetNext(pos)); } @@ -962,7 +920,8 @@ void CSharedDirsTreeCtrl::FileSystemTreeUpdateShareState(const CDirectoryItem *p { if (pDir == NULL) pDir = m_pRootUnsharedDirectries; - SetItemState(pDir->m_htItem, FileSystemTreeIsShared(pDir->m_strFullPath) ? INDEXTOOVERLAYMASK(1) : 0, TVIS_OVERLAYMASK); + else + SetItemState(pDir->m_htItem, FileSystemTreeIsShared(pDir->m_strFullPath) ? INDEXTOOVERLAYMASK(1) : 0, TVIS_OVERLAYMASK); for (POSITION pos = pDir->liSubDirectories.GetHeadPosition(); pos != NULL;) FileSystemTreeUpdateShareState(pDir->liSubDirectories.GetNext(pos)); } @@ -1004,11 +963,7 @@ void CSharedDirsTreeCtrl::EditSharedDirectories(const CDirectoryItem *pDir, bool // sync with the preferences list thePrefs.shareddir_list.RemoveAll(); // copy list - for (POSITION pos = m_strliSharedDirs.GetHeadPosition(); pos != NULL;) { - CString strPath = m_strliSharedDirs.GetNext(pos); - slosh(strPath); - thePrefs.shareddir_list.AddTail(strPath); - } + thePrefs.shareddir_list.AddTail(&m_strliSharedDirs); // update the shared files list theApp.emuledlg->sharedfileswnd->Reload(); @@ -1019,7 +974,6 @@ void CSharedDirsTreeCtrl::EditSharedDirectories(const CDirectoryItem *pDir, bool void CSharedDirsTreeCtrl::Reload(bool bForce) { -// bool bChanged = false; if (!bForce) { // check for changes in shared dirs bForce = (thePrefs.shareddir_list.GetCount() != m_strliSharedDirs.GetCount()); @@ -1027,11 +981,9 @@ void CSharedDirsTreeCtrl::Reload(bool bForce) POSITION pos = m_strliSharedDirs.GetHeadPosition(); POSITION pos2 = thePrefs.shareddir_list.GetHeadPosition(); while (pos != NULL && pos2 != NULL) { - CString str1 = m_strliSharedDirs.GetNext(pos); - CString str2 = thePrefs.shareddir_list.GetNext(pos2); - unslosh(str1); - unslosh(str2); - if (str1.CompareNoCase(str2) != 0) { + const CString &str(m_strliSharedDirs.GetNext(pos)); + const CString &str2(thePrefs.shareddir_list.GetNext(pos2)); + if (str.CompareNoCase(str2) != 0) { bForce = true; break; } @@ -1040,14 +992,12 @@ void CSharedDirsTreeCtrl::Reload(bool bForce) if (!bForce) { // check for changes in categories incoming dirs - CString strMainIncDir = thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR); - unslosh(strMainIncDir); + const CString &strMainIncDir(thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR)); CStringList strliFound; - for (int i = 0; i < thePrefs.GetCatCount(); ++i) { + for (INT_PTR i = 0; i < thePrefs.GetCatCount(); ++i) { const Category_Struct *pCatStruct = thePrefs.GetCategory(i); if (pCatStruct != NULL) { - CString strCatIncomingPath = pCatStruct->strIncomingPath; - unslosh(strCatIncomingPath); + CString strCatIncomingPath(pCatStruct->strIncomingPath); if (!strCatIncomingPath.IsEmpty() && strCatIncomingPath.CompareNoCase(strMainIncDir) != 0 && strliFound.Find(strCatIncomingPath) == NULL) @@ -1076,13 +1026,9 @@ void CSharedDirsTreeCtrl::Reload(bool bForce) void CSharedDirsTreeCtrl::FetchSharedDirsList() { - m_strliSharedDirs.RemoveAll(); + RemoveAllSharedDirectories(); // copy list - for (POSITION pos = thePrefs.shareddir_list.GetHeadPosition(); pos != NULL;) { - CString strPath = thePrefs.shareddir_list.GetNext(pos); - unslosh(strPath); - m_strliSharedDirs.AddTail(strPath); - } + m_strliSharedDirs.AddTail(&thePrefs.shareddir_list); } void CSharedDirsTreeCtrl::OnTvnBeginDrag(LPNMHDR pNMHDR, LRESULT *pResult) @@ -1101,19 +1047,18 @@ void CSharedDirsTreeCtrl::OnTvnBeginDrag(LPNMHDR pNMHDR, LRESULT *pResult) CImageList *piml = CreateDragImage(lpnmtv->itemNew.hItem); if (piml == NULL) return; - POINT ptOffset; - RECT rcItem; + CPoint ptOffset; + CRect rcItem; /* get the bounding rectangle of the item being dragged (rel to top-left of control) */ if (GetItemRect(lpnmtv->itemNew.hItem, &rcItem, TRUE)) { /* get offset into image that the mouse is at */ /* item rect doesn't include the image */ - const POINT ptDragBegin = lpnmtv->ptDrag; int nX, nY; ::ImageList_GetIconSize(piml->GetSafeHandle(), &nX, &nY); - ptOffset.x = (ptDragBegin.x - rcItem.left) + (nX - (rcItem.right - rcItem.left)); - ptOffset.y = (ptDragBegin.y - rcItem.top) + (nY - (rcItem.bottom - rcItem.top)); - /* convert the item rect to screen co-ords, for use later */ + ptOffset = CPoint(lpnmtv->ptDrag) - rcItem.BottomRight() + POINT{ nX, nY }; + + /* convert the item rect to screen co-ords for later use */ MapWindowPoints(NULL, &rcItem); } else { GetWindowRect(&rcItem); @@ -1147,24 +1092,22 @@ void CSharedDirsTreeCtrl::OnMouseMove(UINT nFlags, CPoint point) CImageList::DragMove(pt); CImageList::DragShowNolock(FALSE); - if (CWnd::WindowFromPoint(pt) != this) - SetCursor(AfxGetApp()->LoadStandardCursor(IDC_NO)); - else { + LPCTSTR pCursor = IDC_NO; + if (CWnd::WindowFromPoint(pt) == this) { TVHITTESTINFO tvhti; tvhti.pt = pt; ScreenToClient(&tvhti.pt); HTREEITEM hItemSel = HitTest(&tvhti); - CDirectoryItem *pDragTarget; - if (hItemSel != NULL && (pDragTarget = reinterpret_cast(GetItemData(hItemSel))) != NULL) { - //only allow dragging to shared folders - if (pDragTarget->m_eItemType == SDI_DIRECTORY || pDragTarget->m_eItemType == SDI_NO) { - SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW)); + if (hItemSel != NULL) { + CDirectoryItem *pDragTarget = reinterpret_cast(GetItemData(hItemSel)); + //allow dragging only to shared folders + if (pDragTarget != NULL && (pDragTarget->m_eItemType == SDI_DIRECTORY || pDragTarget->m_eItemType == SDI_NO)) { + pCursor = IDC_ARROW; SelectDropTarget(pDragTarget->m_htItem); - } else - SetCursor(AfxGetApp()->LoadStandardCursor(IDC_NO)); - } else - SetCursor(AfxGetApp()->LoadStandardCursor(IDC_NO)); + } + } } + SetCursor(AfxGetApp()->LoadStandardCursor(pCursor)); CImageList::DragShowNolock(TRUE); } @@ -1196,33 +1139,28 @@ void CSharedDirsTreeCtrl::OnLButtonUp(UINT nFlags, CPoint point) } } - CImageList::DragLeave(NULL); - CImageList::EndDrag(); - ReleaseCapture(); - ShowCursor(TRUE); - SelectDropTarget(NULL); - - delete m_pDraggingItem; - m_pDraggingItem = NULL; - - RedrawWindow(); + CancelMode(); } CTreeCtrl::OnLButtonUp(nFlags, point); } +void CSharedDirsTreeCtrl::CancelMode() +{ + CImageList::DragLeave(NULL); + CImageList::EndDrag(); + ::ReleaseCapture(); + ShowCursor(TRUE); + SelectDropTarget(NULL); + + delete m_pDraggingItem; + m_pDraggingItem = NULL; + RedrawWindow(); +} + void CSharedDirsTreeCtrl::OnCancelMode() { - if (m_pDraggingItem != NULL) { - CImageList::DragLeave(NULL); - CImageList::EndDrag(); - ReleaseCapture(); - ShowCursor(TRUE); - SelectDropTarget(NULL); - - delete m_pDraggingItem; - m_pDraggingItem = NULL; - RedrawWindow(); - } + if (m_pDraggingItem != NULL) + CancelMode(); CTreeCtrl::OnCancelMode(); } @@ -1234,19 +1172,20 @@ void CSharedDirsTreeCtrl::OnVolumesChanged() bool CSharedDirsTreeCtrl::ShowFileSystemDirectory(const CString &strDir) { // expand directories until we find our target directory and select it + int iLen = strDir.GetLength(); const CDirectoryItem *pCurrentItem = m_pRootUnsharedDirectries; - bool bContinue = true; - while (bContinue) { + for (bool bContinue = true; bContinue;) { bContinue = false; Expand(pCurrentItem->m_htItem, TVE_EXPAND); for (POSITION pos = pCurrentItem->liSubDirectories.GetHeadPosition(); pos != NULL;) { const CDirectoryItem *pTemp = pCurrentItem->liSubDirectories.GetNext(pos); - if (strDir.CompareNoCase(pTemp->m_strFullPath + '\\') == 0) { + if (EqualPaths(strDir, pTemp->m_strFullPath)) { Select(pTemp->m_htItem, TVGN_CARET); EnsureVisible(pTemp->m_htItem); return true; } - if (strDir.Find(pTemp->m_strFullPath + '\\') == 0) { + int jLen = pTemp->m_strFullPath.GetLength(); + if (jLen < iLen && _tcsnicmp(strDir, pTemp->m_strFullPath, jLen) == 0) { pCurrentItem = pTemp; bContinue = true; break; @@ -1271,7 +1210,7 @@ bool CSharedDirsTreeCtrl::ShowSharedDirectory(const CString &strDir) // search for the fitting sub dir for (POSITION pos2 = pTemp->liSubDirectories.GetHeadPosition(); pos2 != NULL;) { CDirectoryItem *pTemp2 = pTemp->liSubDirectories.GetNext(pos2); - if (strDir.CompareNoCase(pTemp2->m_strFullPath + _T('\\')) == 0) { + if (strDir.CompareNoCase(pTemp2->m_strFullPath) == 0) { Select(pTemp2->m_htItem, TVGN_CARET); EnsureVisible(pTemp2->m_htItem); return true; diff --git a/srchybrid/SharedDirsTreeCtrl.h b/srchybrid/SharedDirsTreeCtrl.h index f94e9e48..1826a5ac 100644 --- a/srchybrid/SharedDirsTreeCtrl.h +++ b/srchybrid/SharedDirsTreeCtrl.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -112,17 +112,18 @@ class CSharedDirsTreeCtrl : public CTreeCtrl private: void InitalizeStandardItems(); + void CancelMode(); void FileSystemTreeCreateTree(); void FileSystemTreeAddChildItem(CDirectoryItem *pRoot, const CString &strText, bool bTopLevel); - bool FileSystemTreeHasSubdirectories(const CString &strDir); + static bool FileSystemTreeHasSubdirectories(const CString &strDir); bool FileSystemTreeHasSharedSubdirectory(const CString &strDir, bool bOrFiles); void FileSystemTreeAddSubdirectories(CDirectoryItem *pRoot); bool FileSystemTreeIsShared(const CString &strDir); void FileSystemTreeUpdateShareState(const CDirectoryItem *pDir = NULL); void FileSystemTreeSetShareState(const CDirectoryItem *pDir, bool bSubDirectories); -// void FilterTreeAddSharedDirectory(CDirectoryItem *pDir, bool bRefresh); + //void FilterTreeAddSharedDirectory(CDirectoryItem *pDir, bool bRefresh); void FilterTreeAddSubDirectories(CDirectoryItem *pDirectory, const CStringList &liDirs, int nLevel, bool &rbShowWarning, bool bParentAccessible); bool FilterTreeIsSubDirectory(const CString &strDir, const CString &strRoot, const CStringList &liDirs); void FilterTreeReloadTree(); diff --git a/srchybrid/SharedFileList.cpp b/srchybrid/SharedFileList.cpp index ee1f0ed9..76653f96 100644 --- a/srchybrid/SharedFileList.cpp +++ b/srchybrid/SharedFileList.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -18,8 +18,8 @@ #include #include #include "emule.h" -#include "SharedFileList.h" #include "KnownFileList.h" +#include "SharedFileList.h" #include "Packets.h" #include "Kademlia/Kademlia/Kademlia.h" #include "kademlia/kademlia/search.h" @@ -29,12 +29,11 @@ #include "DownloadQueue.h" #include "Statistics.h" #include "Preferences.h" -#include "OtherFunctions.h" +#include "UpDownClient.h" #include "KnownFile.h" #include "ServerConnect.h" #include "SafeFile.h" #include "Server.h" -#include "UpDownClient.h" #include "PartFile.h" #include "emuledlg.h" #include "SharedFilesWnd.h" @@ -67,7 +66,7 @@ class CPublishKeyword : m_strKeyword(rstrKeyword) { // min. keyword char is allowed to be < 3 in some cases (see also 'CSearchManager::GetWords') - //ASSERT( rstrKeyword.GetLength() >= 3 ); + //ASSERT(rstrKeyword.GetLength() >= 3); ASSERT(!rstrKeyword.IsEmpty()); KadGetKeywordHash(rstrKeyword, &m_nKadID); SetNextPublishTime(0); @@ -108,15 +107,14 @@ class CPublishKeyword void RotateReferences(int iRotateSize) { - if (m_aFiles.GetSize() > iRotateSize) { + CKnownFile **ppRotated = reinterpret_cast(malloc(m_aFiles.m_nAllocSize * sizeof(*m_aFiles.GetData()))); + if (ppRotated != NULL) { int i = m_aFiles.GetSize() - iRotateSize; - CKnownFile **ppRotated = reinterpret_cast(malloc(m_aFiles.m_nAllocSize * sizeof(*m_aFiles.GetData()))); - if (ppRotated != NULL) { - memcpy(ppRotated, m_aFiles.GetData() + iRotateSize, i * sizeof(*m_aFiles.GetData())); - memcpy(ppRotated + i, m_aFiles.GetData(), iRotateSize * sizeof(*m_aFiles.GetData())); - free(m_aFiles.GetData()); - m_aFiles.m_aT = ppRotated; - } + ASSERT(i > 0); + memcpy(ppRotated, m_aFiles.GetData() + iRotateSize, i * sizeof(*m_aFiles.GetData())); + memcpy(ppRotated + i, m_aFiles.GetData(), iRotateSize * sizeof(*m_aFiles.GetData())); + free(m_aFiles.GetData()); + m_aFiles.m_aT = ppRotated; } } @@ -209,10 +207,10 @@ CPublishKeyword *CPublishKeywordList::FindKeyword(const CStringW &rstrKeyword, P void CPublishKeywordList::AddKeywords(CKnownFile *pFile) { - const Kademlia::WordList &wordlist = pFile->GetKadKeywords(); - //ASSERT( !wordlist.empty() ); + const Kademlia::WordList &wordlist(pFile->GetKadKeywords()); + //ASSERT(!wordlist.empty()); for (Kademlia::WordList::const_iterator it = wordlist.begin(); it != wordlist.end(); ++it) { - const CStringW &strKeyword = *it; + const CStringW &strKeyword(*it); CPublishKeyword *pPubKw = FindKeyword(strKeyword); if (pPubKw == NULL) { pPubKw = new CPublishKeyword(Kademlia::CKadTagValueString(strKeyword)); @@ -232,9 +230,9 @@ void CPublishKeywordList::AddKeywords(CKnownFile *pFile) void CPublishKeywordList::RemoveKeywords(CKnownFile *pFile) { const Kademlia::WordList &wordlist = pFile->GetKadKeywords(); - //ASSERT( !wordlist.empty() ); + //ASSERT(!wordlist.empty()); for (Kademlia::WordList::const_iterator it = wordlist.begin(); it != wordlist.end(); ++it) { - const CStringW &strKeyword = *it; + const CStringW &strKeyword(*it); POSITION pos; CPublishKeyword *pPubKw = FindKeyword(strKeyword, &pos); if (pPubKw != NULL && pPubKw->RemoveRef(pFile) == 0) { @@ -316,9 +314,9 @@ uint16 CAddFileThread::SetPartToImport(LPCTSTR import) m_strImport = import; - for (uint16 i = 0; i < m_partfile->GetPartCount(); ++i) - if (!m_partfile->IsComplete(i, false)) - m_PartsToImport.Add(i); + for (UINT i = 0; i < m_partfile->GetPartCount(); ++i) + if (!m_partfile->IsComplete(i)) + m_PartsToImport.Add((uint16)i); return (uint16)m_PartsToImport.GetSize(); } @@ -338,9 +336,9 @@ bool CAddFileThread::ImportParts() Log(LOG_STATUSBAR, GetResString(IDS_IMPORTPARTS_IMPORTSTART), m_PartsToImport.GetSize(), (LPCTSTR)strFilePath); uint64 fileSize = f.GetLength(); - CKnownFile *kfimport = new CKnownFile; BYTE *partData = NULL; unsigned partsuccess = 0; + CKnownFile kfimport; for (INT_PTR i = 0; i < m_PartsToImport.GetSize(); ++i) { const uint16 partnumber = m_PartsToImport[i]; const uint64 uStart = PARTSIZE * partnumber; @@ -363,7 +361,7 @@ bool CAddFileThread::ImportParts() continue; } uchar hash[MDX_DIGEST_SIZE]; - kfimport->CreateHash(partData, partSize, hash); + kfimport.CreateHash(partData, partSize, hash); ImportPart_Struct *importpart = new ImportPart_Struct; importpart->start = uStart; importpart->end = importpart->start + partSize - 1; @@ -387,7 +385,6 @@ bool CAddFileThread::ImportParts() } f.Close(); delete[] partData; - delete kfimport; try { bool importaborted = !theApp.IsRunning() || m_partfile->GetFileOp() == PFOP_NONE; @@ -412,7 +409,7 @@ BOOL CAddFileThread::InitInstance() int CAddFileThread::Run() { DbgSetThreadName(m_partfile && m_partfile->GetFileOp() == PFOP_IMPORTPARTS ? "ImportingParts %s" : "Hashing %s", (LPCTSTR)m_strFilename); - if (theApp.IsClosing() || !(m_pOwner || m_partfile) || m_strFilename.IsEmpty()) + if (!(m_pOwner || m_partfile) || m_strFilename.IsEmpty() || theApp.IsClosing()) return 0; (void)CoInitialize(NULL); @@ -427,7 +424,7 @@ int CAddFileThread::Run() // at startup when rehashing potentially corrupted downloading part files. // If all those hash threads would run concurrently, the io-system would be under // very heavy load and slowly progressing - CSingleLock sLock1(&theApp.hashing_mut, TRUE); // hash only one file at a time + CSingleLock hashingLock(&theApp.hashing_mut, TRUE); // hash only one file at a time TCHAR strFilePath[MAX_PATH]; _tmakepathlimit(strFilePath, NULL, m_strDirectory, m_strFilename, NULL); @@ -436,13 +433,13 @@ int CAddFileThread::Run() else Log(_T("%s \"%s\""), (LPCTSTR)GetResString(IDS_HASHINGFILE), strFilePath); - CKnownFile *newrecord = new CKnownFile(); - if (!theApp.IsClosing() && newrecord->CreateFromFile(m_strDirectory, m_strFilename, m_partfile)) { // SLUGFILLER: SafeHash - in case of shutdown while still hashing - newrecord->SetSharedDirectory(m_strSharedDir); + CKnownFile *newKnown = new CKnownFile(); + if (!theApp.IsClosing() && newKnown->CreateFromFile(m_strDirectory, m_strFilename, m_partfile)) { // SLUGFILLER: SafeHash - in case of shutdown while still hashing + newKnown->SetSharedDirectory(m_strSharedDir); if (m_partfile && m_partfile->GetFileOp() == PFOP_HASHING) m_partfile->SetFileOp(PFOP_NONE); - if (!theApp.emuledlg->PostMessage(TM_FINISHEDHASHING, (m_pOwner ? 0 : (WPARAM)m_partfile), (LPARAM)newrecord)) - delete newrecord; + if (!theApp.emuledlg->PostMessage(TM_FINISHEDHASHING, (m_pOwner ? 0 : (WPARAM)m_partfile), (LPARAM)newKnown)) + delete newKnown; } else { if (!theApp.IsClosing()) { if (m_partfile && m_partfile->GetFileOp() == PFOP_HASHING) @@ -458,10 +455,10 @@ int CAddFileThread::Run() } } // SLUGFILLER: SafeHash - delete newrecord; + delete newKnown; } - sLock1.Unlock(); + hashingLock.Unlock(); CoUninitialize(); return 0; } @@ -471,14 +468,13 @@ int CAddFileThread::Run() void CSharedFileList::AddDirectory(const CString &strDir, CStringList &dirlist) { - CString tmpDir(strDir); - slosh(tmpDir); - CString slDir(tmpDir); + ASSERT(strDir.Right(1) == _T("\\")); + CString slDir(strDir); slDir.MakeLower(); if (dirlist.Find(slDir) == NULL) { dirlist.AddHead(slDir); - AddFilesFromDirectory(tmpDir); + AddFilesFromDirectory(strDir); } } @@ -487,7 +483,6 @@ CSharedFileList::CSharedFileList(CServerConnect *in_server) , output() , m_currFileSrc() , m_currFileNotes() - //, m_currFileKey() , m_lastPublishKadSrc() , m_lastPublishKadNotes() , m_lastPublishED2K() @@ -496,7 +491,15 @@ CSharedFileList::CSharedFileList(CServerConnect *in_server) { m_Files_map.InitHashTable(1031); m_keywords = new CPublishKeywordList; - +#if defined(_BETA) || defined(_DEVBUILD) + // In Beta and development versions we create a test file which is published in order to make + // testing easier by allowing easily find files which are published and shared by "new" nodes + // Compose the name of the test file + m_strBetaFileName.Format(_T("eMule%u.%u%c.%u Beta Testfile "), CemuleApp::m_nVersionMjr + , CemuleApp::m_nVersionMin, _T('a') + CemuleApp::m_nVersionUpd, CemuleApp::m_nVersionBld); + const MD5Sum md5(m_strBetaFileName + CemuleApp::m_sPlatform); + m_strBetaFileName.AppendFormat(_T("%s.txt"), (LPCTSTR)md5.GetHashString().Left(6)); +#endif LoadSingleSharedFilesList(); FindSharedFiles(); } @@ -512,26 +515,17 @@ CSharedFileList::~CSharedFileList() delete m_keywords; #if defined(_BETA) || defined(_DEVBUILD) - // On Beta builds we created a testfile, delete it when closing eMule - CString tempDir = thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR); - slosh(tempDir); - CString strBetaFileName; - strBetaFileName.Format(_T("eMule%u.%u%c.%u Beta Testfile "), CemuleApp::m_nVersionMjr, - CemuleApp::m_nVersionMin, _T('a') + CemuleApp::m_nVersionUpd, CemuleApp::m_nVersionBld); - const MD5Sum md5(strBetaFileName + CemuleApp::m_sPlatform); - strBetaFileName += md5.GetHashString().Left(6) + _T(".txt"); - ::DeleteFile(tempDir + strBetaFileName); + //Delete the test file + CString sTest(thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR)); + sTest += m_strBetaFileName; + ::DeleteFile(sTest); #endif } -void CSharedFileList::CopySharedFileMap(CMap & Files_Map) +void CSharedFileList::CopySharedFileMap(CKnownFilesMap &Files_Map) { - CCKey key; - for (POSITION pos = m_Files_map.GetStartPosition(); pos != NULL;) { - CKnownFile *cur_file; - m_Files_map.GetNextAssoc(pos, key, cur_file); - Files_Map.SetAt(key, cur_file); - } + for (const CKnownFilesMap::CPair *pair = m_Files_map.PGetFirstAssoc(); pair != NULL; pair = m_Files_map.PGetNextAssoc(pair)) + Files_Map[pair->key] = pair->value; } void CSharedFileList::FindSharedFiles() @@ -548,7 +542,7 @@ void CSharedFileList::FindSharedFiles() || theApp.knownfiles->IsFilePtrInList(cur_file) || _taccess(cur_file->GetFilePath(), 0) != 0) { - m_UnsharedFiles_map.SetAt(CSKey(cur_file->GetFileHash()), true); + m_UnsharedFiles_map[CSKey(cur_file->GetFileHash())] = true; listlock.Lock(); m_Files_map.RemoveKey(key); listlock.Unlock(); @@ -559,25 +553,20 @@ void CSharedFileList::FindSharedFiles() // khaos::kmod+ Fix: Shared files loaded multiple times. CStringList l_sAdded; - CString tempDir(thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR)); - slosh(tempDir); + const CString &tempDir(thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR)); #if defined(_BETA) || defined(_DEVBUILD) - // In Beta version we create a test file which is published in order to make testing easier - // by allowing to easily find files which are published and shared by "new" nodes + //Create the test file (before adding the Incoming directory) CStdioFile f; - CString strBetaFileName; - strBetaFileName.Format(_T("eMule%u.%u%c.%u Beta Testfile "), CemuleApp::m_nVersionMjr, - CemuleApp::m_nVersionMin, _T('a') + CemuleApp::m_nVersionUpd, CemuleApp::m_nVersionBld); - const MD5Sum md5(strBetaFileName + CemuleApp::m_sPlatform); - strBetaFileName.AppendFormat(_T("%s.txt"), (LPCTSTR)md5.GetHashString().Left(6)); - if (!f.Open(tempDir + strBetaFileName, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite)) + if (!f.Open(tempDir + m_strBetaFileName, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite)) ASSERT(0); else { try { // do not translate the content! - f.WriteString(strBetaFileName + '\n'); // guarantees a different hash on different versions - f.WriteString(_T("This file is automatically created by eMule Beta versions to help the developers testing and debugging new the new features. eMule will delete this file when exiting, otherwise you can remove this file at any time.\nThanks for beta testing eMule :)")); + f.WriteString(m_strBetaFileName); // guarantees a different hash on different versions + f.WriteString(_T("\nThis file is automatically created by eMule Beta versions to help the developers testing and debugging the new features.") + _T("\neMule will delete this file when exiting, otherwise you can remove this file at any time.") + _T("\nThanks for beta testing eMule :)")); f.Close(); } catch (CFileException *ex) { ASSERT(0); @@ -585,10 +574,9 @@ void CSharedFileList::FindSharedFiles() } } #endif - AddDirectory(tempDir, l_sAdded); - for (int i = 1; i < thePrefs.GetCatCount(); ++i) + for (INT_PTR i = 1; i < thePrefs.GetCatCount(); ++i) AddDirectory(thePrefs.GetCatPath(i), l_sAdded); for (POSITION pos = thePrefs.shareddir_list.GetHeadPosition(); pos != NULL;) @@ -609,25 +597,20 @@ void CSharedFileList::FindSharedFiles() void CSharedFileList::AddFilesFromDirectory(const CString &rstrDirectory) { - CString strSearchPath(rstrDirectory); - PathAddBackslash(strSearchPath.GetBuffer(strSearchPath.GetLength() + 1)); - strSearchPath.ReleaseBuffer(); - strSearchPath += _T('*'); + ASSERT(rstrDirectory.Right(1) == _T("\\")); CFileFind ff; - bool end = !ff.FindFile(strSearchPath, 0); - if (end) { + BOOL bFound = ff.FindFile(rstrDirectory + _T('*')); + if (bFound) { + do { + bFound = ff.FindNextFile(); + CheckAndAddSingleFile(ff); + } while (bFound); + } else { DWORD dwError = ::GetLastError(); if (dwError != ERROR_FILE_NOT_FOUND) LogWarning(GetResString(IDS_ERR_SHARED_DIR), (LPCTSTR)rstrDirectory, (LPCTSTR)GetErrorMessage(dwError)); - return; } - - while (!end) { - end = !ff.FindNextFile(); - CheckAndAddSingleFile(ff); - } - ff.Close(); } bool CSharedFileList::AddSingleSharedFile(const CString &rstrFilePath, bool bNoUpdate) @@ -644,23 +627,20 @@ bool CSharedFileList::AddSingleSharedFile(const CString &rstrFilePath, bool bNoU } // check if we share this file in general - bool bShared = ShouldBeShared(rstrFilePath.Left(rstrFilePath.ReverseFind(_T('\\')) + 1), rstrFilePath, false); + bool bShared = ShouldBeShared(rstrFilePath.Left(rstrFilePath.ReverseFind(_T('\\'))), rstrFilePath, false); if (bShared && !bExclude) - // we should share this file already - return false; - if (!bShared) { - // the directory is not shared, so we need a special entry - m_liSingleSharedFiles.AddTail(rstrFilePath); - } + return false; // we should be sharing this file already + if (!bShared) + m_liSingleSharedFiles.AddTail(rstrFilePath); // the directory is not shared, so we need a new entry + return bNoUpdate || CheckAndAddSingleFile(rstrFilePath); } bool CSharedFileList::CheckAndAddSingleFile(const CString &rstrFilePath) { CFileFind ff; - bool end = !ff.FindFile(rstrFilePath, 0); - if (end) { + if (!ff.FindFile(rstrFilePath)) { DWORD dwError = ::GetLastError(); if (dwError != ERROR_FILE_NOT_FOUND) LogWarning(GetResString(IDS_ERR_SHARED_DIR), (LPCTSTR)rstrFilePath, (LPCTSTR)GetErrorMessage(dwError)); @@ -671,7 +651,7 @@ bool CSharedFileList::CheckAndAddSingleFile(const CString &rstrFilePath) ff.Close(); HashNextFile(); bHaveSingleSharedFiles = true; - // GUI updating needs to be done by caller + // GUI update to be done by the caller return true; } @@ -702,7 +682,7 @@ bool CSharedFileList::AddFile(CKnownFile *pFile) { ASSERT(pFile->GetFileIdentifier().HasExpectedMD4HashCount()); ASSERT(!pFile->IsKindOf(RUNTIME_CLASS(CPartFile)) || !static_cast(pFile)->m_bMD4HashsetNeeded); - ASSERT(!pFile->IsShellLinked() || ShouldBeShared(pFile->GetSharedDirectory(), _T(""), false)); + ASSERT(!pFile->IsShellLinked() || ShouldBeShared(pFile->GetSharedDirectory(), NULL, false)); CCKey key(pFile->GetFileHash()); CKnownFile *pFileInMap; if (m_Files_map.Lookup(key, pFileInMap)) { @@ -715,7 +695,7 @@ bool CSharedFileList::AddFile(CKnownFile *pFile) m_UnsharedFiles_map.RemoveKey(CSKey(pFile->GetFileHash())); CSingleLock listlock(&m_mutWriteList, TRUE); - m_Files_map.SetAt(key, pFile); + m_Files_map[key] = pFile; listlock.Unlock(); bool bKeywordsNeedUpdated = true; @@ -727,7 +707,7 @@ bool CSharedFileList::AddFile(CKnownFile *pFile) pFile->m_pCollection = NULL; } else if (!pFile->m_pCollection->GetCollectionAuthorKeyString().IsEmpty()) { //If the collection has a key, resetting the file name will - //cause the key to be added into the wordlist to be stored + //cause the key to be added into the word list to be stored //into Kad. pFile->SetFileName(pFile->GetFileName()); //During the initial startup, shared files are not accessible @@ -794,7 +774,7 @@ bool CSharedFileList::RemoveFile(CKnownFile *pFile, bool bDeleted) output->RemoveFile(pFile, bDeleted); m_keywords->RemoveKeywords(pFile); if (bResult) { - m_UnsharedFiles_map.SetAt(CSKey(pFile->GetFileHash()), true); + m_UnsharedFiles_map[CSKey(pFile->GetFileHash())] = true; theApp.knownfiles->m_nRequestedTotal -= pFile->statistic.GetAllTimeRequests(); theApp.knownfiles->m_nAcceptedTotal -= pFile->statistic.GetAllTimeAccepts(); theApp.knownfiles->m_nTransferredTotal -= pFile->statistic.GetAllTimeTransferred(); @@ -820,7 +800,7 @@ void CSharedFileList::SetOutputCtrl(CSharedFilesCtrl *in_ctrl) { output = in_ctrl; output->ReloadFileList(); - HashNextFile(); // SLUGFILLER: SafeHash - if hashing not yet started, start it now + HashNextFile(); // SLUGFILLER: SafeHash - if hashing not started yet, start it now } void CSharedFileList::SendListToServer() @@ -832,16 +812,14 @@ void CSharedFileList::SendListToServer() CSafeMemFile files(1024); CTypedPtrList sortedList; - CCKey bufKey; - for (POSITION pos = m_Files_map.GetStartPosition(); pos != 0;) { - CKnownFile *cur_file; - m_Files_map.GetNextAssoc(pos, bufKey, cur_file); + for (const CKnownFilesMap::CPair *pair = m_Files_map.PGetFirstAssoc(); pair != NULL; pair = m_Files_map.PGetNextAssoc(pair)) { + CKnownFile *cur_file = pair->value; //insert sorted into sortedList if (!cur_file->GetPublishedED2K() && (!cur_file->IsLargeFile() || (pCurServer != NULL && pCurServer->SupportsLargeFilesTCP()))) { bool added = false; - for (POSITION pos1 = sortedList.GetHeadPosition(); pos1 != 0 && !added;) { - POSITION pos2 = pos1; - if (GetRealPrio(sortedList.GetNext(pos1)->GetUpPriority()) <= GetRealPrio(cur_file->GetUpPriority())) { + for (POSITION pos = sortedList.GetHeadPosition(); pos != 0 && !added;) { + POSITION pos2 = pos; + if (GetRealPrio(sortedList.GetNext(pos)->GetUpPriority()) <= GetRealPrio(cur_file->GetUpPriority())) { sortedList.InsertBefore(pos2, cur_file); added = true; } @@ -851,7 +829,6 @@ void CSharedFileList::SendListToServer() } } - // add to packet uint32 limit = pCurServer ? pCurServer->GetSoftFiles() : 0; if (limit == 0 || limit > 200) @@ -868,11 +845,11 @@ void CSharedFileList::SendListToServer() uint32 count = limit; for (POSITION pos = sortedList.GetHeadPosition(); pos != 0 && count-- > 0;) { CKnownFile *file = sortedList.GetNext(pos); - CreateOfferedFilePacket(file, &files, pCurServer); + CreateOfferedFilePacket(file, files, pCurServer); file->SetPublishedED2K(true); } sortedList.RemoveAll(); - Packet *packet = new Packet(&files); + Packet *packet = new Packet(files); packet->opcode = OP_OFFERFILES; // compress packet // - this kind of data is highly compressible (N * (1 MD4 and at least 3 string meta data tags and 1 integer meta data tag)) @@ -897,31 +874,23 @@ void CSharedFileList::SendListToServer() void CSharedFileList::ClearED2KPublishInfo() { m_lastPublishED2KFlag = true; - CCKey bufKey; - for (POSITION pos = m_Files_map.GetStartPosition(); pos != NULL;) { - CKnownFile *cur_file; - m_Files_map.GetNextAssoc(pos, bufKey, cur_file); - cur_file->SetPublishedED2K(false); - } + for (const CKnownFilesMap::CPair *pair = m_Files_map.PGetFirstAssoc(); pair != NULL; pair = m_Files_map.PGetNextAssoc(pair)) + pair->value->SetPublishedED2K(false); } void CSharedFileList::ClearKadSourcePublishInfo() { - CCKey bufKey; - for (POSITION pos = m_Files_map.GetStartPosition(); pos != NULL;) { - CKnownFile *cur_file; - m_Files_map.GetNextAssoc(pos, bufKey, cur_file); - cur_file->SetLastPublishTimeKadSrc(0, 0); - } + for (const CKnownFilesMap::CPair *pair = m_Files_map.PGetFirstAssoc(); pair != NULL; pair = m_Files_map.PGetNextAssoc(pair)) + pair->value->SetLastPublishTimeKadSrc(0, 0); } -void CSharedFileList::CreateOfferedFilePacket(CKnownFile *cur_file, CSafeMemFile *files +void CSharedFileList::CreateOfferedFilePacket(CKnownFile *cur_file, CSafeMemFile &files , CServer *pServer, CUpDownClient *pClient) { UINT uEmuleVer = (pClient && pClient->IsEmuleClient()) ? pClient->GetVersion() : 0; // NOTE: This function is used for creating the offered file packet for Servers _and_ for Clients. - files->WriteHash16(cur_file->GetFileHash()); + files.WriteHash16(cur_file->GetFileHash()); // *) This function is used for offering files to the local server and for sending // shared files to some other client. In each case we send our IP+Port only, if @@ -948,39 +917,37 @@ void CSharedFileList::CreateOfferedFilePacket(CKnownFile *cur_file, CSafeMemFile nClientPort = thePrefs.GetPort(); } } - } else { - if (theApp.IsConnected() && !theApp.IsFirewalled()) { - nClientID = theApp.GetID(); - nClientPort = thePrefs.GetPort(); - } + } else if (theApp.IsConnected() && !theApp.IsFirewalled()) { + nClientID = theApp.GetID(); + nClientPort = thePrefs.GetPort(); } - files->WriteUInt32(nClientID); - files->WriteUInt16(nClientPort); + files.WriteUInt32(nClientID); + files.WriteUInt16(nClientPort); //TRACE(_T("Publishing file: Hash=%s ClientIP=%s ClientPort=%u\n"), (LPCTSTR)md4str(cur_file->GetFileHash()), (LPCTSTR)ipstr(nClientID), nClientPort); CSimpleArray tags; tags.Add(new CTag(FT_FILENAME, cur_file->GetFileName())); + const uint64 uFileSize = (uint64)cur_file->GetFileSize(); if (!cur_file->IsLargeFile()) - tags.Add(new CTag(FT_FILESIZE, (uint32)(uint64)cur_file->GetFileSize())); + tags.Add(new CTag(FT_FILESIZE, LODWORD(uFileSize))); else { - // we send 2*32 bit tags to servers, but a real 64 bit tag to other clients. + // we send two 32-bit tags to servers, but a 64-bit tag to other clients. if (pServer != NULL) { if (!pServer->SupportsLargeFilesTCP()) { ASSERT(0); tags.Add(new CTag(FT_FILESIZE, 0, false)); } else { - tags.Add(new CTag(FT_FILESIZE, (uint32)(uint64)cur_file->GetFileSize())); - tags.Add(new CTag(FT_FILESIZE_HI, (uint32)((uint64)cur_file->GetFileSize() >> 32))); + tags.Add(new CTag(FT_FILESIZE, LODWORD(uFileSize))); + tags.Add(new CTag(FT_FILESIZE_HI, HIDWORD(uFileSize))); } - } else { - if (pClient) - if (!pClient->SupportsLargeFiles()) { - ASSERT(0); - tags.Add(new CTag(FT_FILESIZE, 0, false)); - } else - tags.Add(new CTag(FT_FILESIZE, cur_file->GetFileSize(), true)); + } else if (pClient != NULL) { + if (!pClient->SupportsLargeFiles()) { + ASSERT(0); + tags.Add(new CTag(FT_FILESIZE, 0, false)); + } else + tags.Add(new CTag(FT_FILESIZE, uFileSize, true)); } } @@ -1021,14 +988,10 @@ void CSharedFileList::CreateOfferedFilePacket(CKnownFile *cur_file, CSafeMemFile // eserver 16.4+ does not need the FT_FILEFORMAT tag at all nor does any eMule client. This tag // was used for older (very old) eDonkey servers only. -> We send it only to non-eMule clients. if (pServer == NULL && uEmuleVer == 0) { - int iExt = cur_file->GetFileName().ReverseFind(_T('.')); - if (iExt >= 0) { - CString strExt = cur_file->GetFileName().Mid(iExt); - if (!strExt.IsEmpty()) { - strExt.Delete(0, 1); - if (!strExt.IsEmpty()) - tags.Add(new CTag(FT_FILEFORMAT, strExt.MakeLower())); // file extension without a "." - } + LPCTSTR pDot = ::PathFindExtension(cur_file->GetFileName()); + if (*pDot && pDot[1]) { + CString strExt(pDot + 1); //skip the dot + tags.Add(new CTag(FT_FILEFORMAT, strExt.MakeLower())); // file extension without a "." } } @@ -1085,11 +1048,8 @@ void CSharedFileList::CreateOfferedFilePacket(CKnownFile *cur_file, CSafeMemFile tags.Add(new CTag(_aMetaTags[i].nName, pTag->GetInt())); else tags.Add(new CTag(_aMetaTags[i].pszED2KName, pTag->GetInt())); - } else { - CString strValue; - SecToTimeLength(pTag->GetInt(), strValue); - tags.Add(new CTag(_aMetaTags[i].pszED2KName, strValue)); - } + } else + tags.Add(new CTag(_aMetaTags[i].pszED2KName, SecToTimeLength(pTag->GetInt()))); } else ASSERT(0); } @@ -1102,7 +1062,7 @@ void CSharedFileList::CreateOfferedFilePacket(CKnownFile *cur_file, CSafeMemFile else eStrEncode = UTF8strNone; - files->WriteUInt32(tags.GetSize()); + files.WriteUInt32(tags.GetSize()); for (int i = 0; i < tags.GetSize(); ++i) { const CTag *pTag = tags[i]; //TRACE(_T(" %s\n"), pTag->GetFullInfo(DbgGetFileMetaTagName)); @@ -1121,94 +1081,78 @@ uint64 CSharedFileList::GetDatasize(uint64 &pbytesLargest) const { pbytesLargest = 0; // <-----khaos- - uint64 fsize; - fsize = 0; + uint64 fsize = 0; - CCKey bufKey; - for (POSITION pos = m_Files_map.GetStartPosition(); pos != NULL;) { - CKnownFile *cur_file; - m_Files_map.GetNextAssoc(pos, bufKey, cur_file); - fsize += (uint64)cur_file->GetFileSize(); + for (const CKnownFilesMap::CPair *pair = m_Files_map.PGetFirstAssoc(); pair != NULL; pair = m_Files_map.PGetNextAssoc(pair)) { + uint64 cur_size = (uint64)pair->value->GetFileSize(); + fsize += cur_size; // -khaos--+++> If this file is bigger than all the others...well duh. - if (cur_file->GetFileSize() > pbytesLargest) - pbytesLargest = cur_file->GetFileSize(); + if (cur_size > pbytesLargest) + pbytesLargest = cur_size; // <-----khaos- } return fsize; } -CKnownFile *CSharedFileList::GetFileByID(const uchar *hash) const +CKnownFile* CSharedFileList::GetFileByID(const uchar *hash) const { if (hash) { - CCKey key(hash); CKnownFile *found_file; - if (m_Files_map.Lookup(key, found_file)) + if (m_Files_map.Lookup(CCKey(hash), found_file)) return found_file; } return NULL; } -CKnownFile *CSharedFileList::GetFileByIdentifier(const CFileIdentifierBase &rFileIdent, bool bStrict) const +CKnownFile* CSharedFileList::GetFileByIdentifier(const CFileIdentifierBase &rFileIdent, bool bStrict) const { CKnownFile *pResult; if (m_Files_map.Lookup(CCKey(rFileIdent.GetMD4Hash()), pResult)) - if (bStrict) - return pResult->GetFileIdentifier().CompareStrict(rFileIdent) ? pResult : NULL; - else - return pResult->GetFileIdentifier().CompareRelaxed(rFileIdent) ? pResult : NULL; - + if (bStrict) { + if (pResult->GetFileIdentifier().CompareStrict(rFileIdent)) + return pResult; + } else if (pResult->GetFileIdentifier().CompareRelaxed(rFileIdent)) + return pResult; return NULL; } -CKnownFile *CSharedFileList::GetFileByIndex(INT_PTR index) const // slow +CKnownFile* CSharedFileList::GetFileByIndex(INT_PTR index) const // slow { - INT_PTR count = 0; - CCKey bufKey; - for (POSITION pos = m_Files_map.GetStartPosition(); pos != NULL;) { - CKnownFile *cur_file; - m_Files_map.GetNextAssoc(pos, bufKey, cur_file); - if (index == count) - return cur_file; - ++count; - } + ASSERT(!index || (index > 0 && index < m_Files_map.GetCount())); + for (const CKnownFilesMap::CPair *pair = m_Files_map.PGetFirstAssoc(); pair != NULL; pair = m_Files_map.PGetNextAssoc(pair)) + if (--index < 0) + return pair->value; return NULL; } CKnownFile* CSharedFileList::GetFileNext(POSITION &pos) const { CKnownFile *cur_file = NULL; - if (m_Files_map.IsEmpty()) //XP was crashing without this check + if (m_Files_map.IsEmpty()) //XP was crashing without this pos = NULL; - if (pos != NULL) { + else if (pos != NULL) { CCKey bufKey; m_Files_map.GetNextAssoc(pos, bufKey, cur_file); } return cur_file; } -CKnownFile *CSharedFileList::GetFileByAICH(const CAICHHash &rHash) const // slow +CKnownFile* CSharedFileList::GetFileByAICH(const CAICHHash &rHash) const // slow { - CCKey bufKey; - CKnownFile *cur_file; - for (POSITION pos = m_Files_map.GetStartPosition(); pos != NULL;) { - m_Files_map.GetNextAssoc(pos, bufKey, cur_file); - if (cur_file->GetFileIdentifierC().HasAICHHash() && cur_file->GetFileIdentifierC().GetAICHHash() == rHash) - return cur_file; - } - return 0; + for (const CKnownFilesMap::CPair *pair = m_Files_map.PGetFirstAssoc(); pair != NULL; pair = m_Files_map.PGetNextAssoc(pair)) + if (pair->value->GetFileIdentifierC().HasAICHHash() && pair->value->GetFileIdentifierC().GetAICHHash() == rHash) + return pair->value; + + return NULL; } bool CSharedFileList::IsFilePtrInList(const CKnownFile *file) const { - if (file) { - CCKey key; - for (POSITION pos = m_Files_map.GetStartPosition(); pos != NULL;) { - CKnownFile *cur_file; - m_Files_map.GetNextAssoc(pos, key, cur_file); - if (file == cur_file) + if (file) + for (const CKnownFilesMap::CPair *pair = m_Files_map.PGetFirstAssoc(); pair != NULL; pair = m_Files_map.PGetNextAssoc(pair)) + if (file == pair->value) return true; - } - } + return false; } @@ -1238,12 +1182,12 @@ bool CSharedFileList::IsHashing(const CString &rstrDirectory, const CString &rst { for (POSITION pos = waitingforhash_list.GetHeadPosition(); pos != NULL;) { const UnknownFile_Struct *pFile = waitingforhash_list.GetNext(pos); - if (!pFile->strName.CompareNoCase(rstrName) && !CompareDirectory(pFile->strDirectory, rstrDirectory)) + if (pFile->strName.CompareNoCase(rstrName) == 0 && EqualPaths(pFile->strDirectory, rstrDirectory)) return true; } for (POSITION pos = currentlyhashing_list.GetHeadPosition(); pos != NULL;) { const UnknownFile_Struct *pFile = currentlyhashing_list.GetNext(pos); - if (!pFile->strName.CompareNoCase(rstrName) && !CompareDirectory(pFile->strDirectory, rstrDirectory)) + if (pFile->strName.CompareNoCase(rstrName) == 0 && EqualPaths(pFile->strDirectory, rstrDirectory)) return true; } return false; @@ -1254,10 +1198,10 @@ void CSharedFileList::RemoveFromHashing(CKnownFile *hashed) for (POSITION pos = currentlyhashing_list.GetHeadPosition(); pos != NULL;) { POSITION posLast = pos; const UnknownFile_Struct *pFile = currentlyhashing_list.GetNext(pos); - if (!pFile->strName.CompareNoCase(hashed->GetFileName()) && !CompareDirectory(pFile->strDirectory, hashed->GetPath())) { + if (pFile->strName.CompareNoCase(hashed->GetFileName()) == 0 && EqualPaths(pFile->strDirectory, hashed->GetPath())) { currentlyhashing_list.RemoveAt(posLast); delete pFile; - HashNextFile(); // start next hash if possible, but only if a previous hash finished + HashNextFile(); // start next hash if possible, but only if a previous hash finished return; } } @@ -1268,7 +1212,7 @@ void CSharedFileList::HashFailed(UnknownFile_Struct *hashed) for (POSITION pos = currentlyhashing_list.GetHeadPosition(); pos != NULL;) { POSITION posLast = pos; const UnknownFile_Struct *pFile = currentlyhashing_list.GetNext(pos); - if (!pFile->strName.CompareNoCase(hashed->strName) && !CompareDirectory(pFile->strDirectory, hashed->strDirectory)) { + if (pFile->strName.CompareNoCase(hashed->strName) == 0 && EqualPaths(pFile->strDirectory, hashed->strDirectory)) { currentlyhashing_list.RemoveAt(posLast); delete pFile; HashNextFile(); // start next hash if possible, but only if a previous hash finished @@ -1328,7 +1272,7 @@ void CSharedFileList::Publish() //pSearch was created. Which means no search was already being done with this HashID. //This also means that it was checked to see if network load wasn't a factor. - //This sets the filename into the search object so we can show it in the gui. + //This sets the filename into the search object so we can show it in the GUI. pSearch->SetGUIName(pPubKw->GetKeyword()); //Add all file IDs which relate to the current keyword to be published @@ -1337,19 +1281,19 @@ void CSharedFileList::Publish() for (int f = 0; f < aFiles.GetSize(); ++f) { //Debug check to make sure things are working well. ASSERT_VALID(aFiles[f]); - // JOHNTODO - Why is this happening. I think it may have to do with downloading a file that is already - // in the known file list. -// ASSERT( IsFilePtrInList(aFiles[f]) ); + // JOHNTODO - Why is this happening. I think it may have to do with downloading a file + // that is already in the known file list. + //ASSERT(IsFilePtrInList(aFiles[f])); //Only publish complete files as someone else should have the full file to publish these keywords. //As a side effect, this may help reduce people finding incomplete files in the network. if (!aFiles[f]->IsPartFile() && IsFilePtrInList(aFiles[f])) { - pSearch->AddFileID(Kademlia::CUInt128(aFiles[f]->GetFileHash())); - if (++count > 150) { - //We only publish up to 150 files per keyword publish then rotate the list. + //We only publish up to 150 files per keyword, then rotate the list. + if (++count >= 150) { pPubKw->RotateReferences(f); break; } + pSearch->AddFileID(Kademlia::CUInt128(aFiles[f]->GetFileHash())); } } @@ -1415,69 +1359,60 @@ void CSharedFileList::RemoveKeywords(CKnownFile *pFile) void CSharedFileList::DeletePartFileInstances() const { - // this is only allowed during shut down - ASSERT(theApp.IsClosing()); - ASSERT(theApp.knownfiles); - + // this is allowed only in shutdown + ASSERT(theApp.knownfiles && theApp.IsClosing()); CCKey key; for (POSITION pos = m_Files_map.GetStartPosition(); pos != NULL;) { CKnownFile *cur_file; m_Files_map.GetNextAssoc(pos, key, cur_file); - if (cur_file->IsKindOf(RUNTIME_CLASS(CPartFile))) - if (!theApp.downloadqueue->IsPartFile(cur_file) && !theApp.knownfiles->IsFilePtrInList(cur_file)) - delete cur_file; // this is only allowed during shut down + if (cur_file->IsKindOf(RUNTIME_CLASS(CPartFile)) + && !theApp.downloadqueue->IsPartFile(cur_file) + && !theApp.knownfiles->IsFilePtrInList(cur_file)) + { + delete cur_file; // only allowed during shut down + } } } bool CSharedFileList::IsUnsharedFile(const uchar *auFileHash) const { - if (auFileHash) { - bool bFound; - if (m_UnsharedFiles_map.Lookup(CSKey(auFileHash), bFound)) - return true; - } - return false; + return auFileHash && m_UnsharedFiles_map.PLookup(CSKey(auFileHash)); } void CSharedFileList::RebuildMetaData() { - CCKey key; - for (POSITION pos = m_Files_map.GetStartPosition(); pos != NULL;) { - CKnownFile *file; - m_Files_map.GetNextAssoc(pos, key, file); - if (!file->IsKindOf(RUNTIME_CLASS(CPartFile))) - file->UpdateMetaDataTags(); - } + for (const CKnownFilesMap::CPair *pair = m_Files_map.PGetFirstAssoc(); pair != NULL; pair = m_Files_map.PGetNextAssoc(pair)) + if (!pair->value->IsKindOf(RUNTIME_CLASS(CPartFile))) + pair->value->UpdateMetaDataTags(); } -bool CSharedFileList::ShouldBeShared(const CString &strPath, const CString &strFilePath, bool bMustBeShared) const +bool CSharedFileList::ShouldBeShared(const CString &sDirPath, LPCTSTR const pFilePath, bool bMustBeShared) const { - // determines if a file should be a shared file based on out shared directories/files preferences - - if (CompareDirectory(strPath, thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR)) == 0) + // see if a directory/file should be shared based on our preferences + if (EqualPaths(sDirPath, thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR))) return true; - for (int i = 1; i < thePrefs.GetCatCount(); ++i) - if (CompareDirectory(strPath, thePrefs.GetCatPath(i)) == 0) + for (INT_PTR i = thePrefs.GetCatCount(); --i > 0;) //down to 1 + if (EqualPaths(sDirPath, thePrefs.GetCatPath(i))) return true; - if (bMustBeShared) + if (bMustBeShared) //check only incoming & categories (cannot be unshared) return false; - // check if this file is explicitly unshared - if (!strFilePath.IsEmpty()) { + if (pFilePath) { + // check if this file is explicitly unshared for (POSITION pos = m_liSingleExcludedFiles.GetHeadPosition(); pos != NULL;) - if (strFilePath.CompareNoCase(m_liSingleExcludedFiles.GetNext(pos)) == 0) + if (m_liSingleExcludedFiles.GetNext(pos).CompareNoCase(pFilePath) == 0) return false; - // check if this file is explicitly shared + // check if this file is explicitly shared (as single file) for (POSITION pos = m_liSingleSharedFiles.GetHeadPosition(); pos != NULL;) - if (strFilePath.CompareNoCase(m_liSingleSharedFiles.GetNext(pos)) == 0) + if (m_liSingleSharedFiles.GetNext(pos).CompareNoCase(pFilePath) == 0) return true; } for (POSITION pos = thePrefs.shareddir_list.GetHeadPosition(); pos != NULL;) - if (CompareDirectory(strPath, thePrefs.shareddir_list.GetNext(pos)) == 0) + if (EqualPaths(sDirPath, thePrefs.shareddir_list.GetNext(pos))) return true; return false; @@ -1485,9 +1420,9 @@ bool CSharedFileList::ShouldBeShared(const CString &strPath, const CString &strF bool CSharedFileList::ContainsSingleSharedFiles(const CString &strDirectory) const { - ASSERT(strDirectory.Right(1) == _T("\\")); + int iLen = strDirectory.GetLength(); for (POSITION pos = m_liSingleSharedFiles.GetHeadPosition(); pos != NULL;) - if (strDirectory.CompareNoCase(m_liSingleSharedFiles.GetNext(pos).Left(strDirectory.GetLength())) == 0) + if (_tcsnicmp(strDirectory, m_liSingleSharedFiles.GetNext(pos), iLen) == 0) return true; return false; @@ -1496,7 +1431,7 @@ bool CSharedFileList::ContainsSingleSharedFiles(const CString &strDirectory) con bool CSharedFileList::ExcludeFile(const CString &strFilePath) { bool bShared = false; - // first check if we are explicitly sharing this file + // first remove from explicitly shared files for (POSITION pos = m_liSingleSharedFiles.GetHeadPosition(); pos != NULL;) { POSITION pos2 = pos; if (strFilePath.CompareNoCase(m_liSingleSharedFiles.GetNext(pos)) == 0) { @@ -1506,48 +1441,43 @@ bool CSharedFileList::ExcludeFile(const CString &strFilePath) } } - // check if we implicity share this file - bShared |= ShouldBeShared(strFilePath.Left(strFilePath.ReverseFind(_T('\\')) + 1), strFilePath, false); - - if (!bShared) { + // if this file was not shared as single file, check if we implicitly share it + if (!bShared && !ShouldBeShared(strFilePath.Left(strFilePath.ReverseFind(_T('\\'))), strFilePath, false)) { // we don't actually share this file, can't be excluded return false; } - if (ShouldBeShared(strFilePath.Left(strFilePath.ReverseFind(_T('\\')) + 1), strFilePath, true)) { + if (ShouldBeShared(strFilePath.Left(strFilePath.ReverseFind(_T('\\'))), strFilePath, true)) { // we cannot unshare this file (incoming directories) - ASSERT(0); // checks should be done earlier already + ASSERT(0); // checks should have been done earlier return false; } // add to exclude list m_liSingleExcludedFiles.AddTail(strFilePath); - // check if the file is in the shared list (doesn't has to for example if it is hashing or not loaded yet) and remove - CCKey bufKey; - for (POSITION pos = m_Files_map.GetStartPosition(); pos != NULL;) { - CKnownFile *cur_file; - m_Files_map.GetNextAssoc(pos, bufKey, cur_file); - if (strFilePath.CompareNoCase(cur_file->GetFilePath()) == 0) { - RemoveFile(cur_file); + // check if the file is in the shared list (doesn't have to; for example, if it is hashing or not loaded yet) and remove + for (const CKnownFilesMap::CPair *pair = m_Files_map.PGetFirstAssoc(); pair != NULL; pair = m_Files_map.PGetNextAssoc(pair)) + if (strFilePath.CompareNoCase(pair->value->GetFilePath()) == 0) { + RemoveFile(pair->value); break; } - } - // updating the GUI needs to be done by the caller + + // GUI update to be done by the caller return true; } void CSharedFileList::CheckAndAddSingleFile(const CFileFind &ff) { - if (ff.IsDirectory() || ff.IsDots() || ff.IsSystem() || ff.IsTemporary() || ff.GetLength() == 0 || ff.GetLength() > MAX_EMULE_FILE_SIZE) + if (ff.IsDirectory() || ff.IsSystem() || ff.IsTemporary() || ff.GetLength() == 0 || ff.GetLength() > MAX_EMULE_FILE_SIZE) return; CString strFoundFileName(ff.GetFileName()); CString strFoundFilePath(ff.GetFilePath()); - CString strFoundDirectory(strFoundFilePath.Left(ff.GetFilePath().ReverseFind(_T('\\')) + 1)); + CString strFoundDirectory(strFoundFilePath, ff.GetFilePath().ReverseFind(_T('\\')) + 1); //with backslash CString strShellLinkDir; ULONGLONG ullFoundFileSize = ff.GetLength(); - // check if this file is explicit unshared + // check if this file is explicitly unshared for (POSITION pos = m_liSingleExcludedFiles.GetHeadPosition(); pos != NULL;) if (strFoundFilePath.CompareNoCase(m_liSingleExcludedFiles.GetNext(pos)) == 0) return; @@ -1558,7 +1488,7 @@ void CSharedFileList::CheckAndAddSingleFile(const CFileFind &ff) // ignore real(!) LNK files if (ExtensionIs(strFoundFileName, _T(".lnk"))) { SHFILEINFO info; - if (SHGetFileInfo(strFoundFilePath, 0, &info, sizeof info, SHGFI_ATTRIBUTES) && (info.dwAttributes & SFGAO_LINK)) { + if (::SHGetFileInfo(strFoundFilePath, 0, &info, sizeof info, SHGFI_ATTRIBUTES) && (info.dwAttributes & SFGAO_LINK)) { if (!thePrefs.GetResolveSharedShellLinks()) { TRACE(_T("%hs: Did not share file \"%s\" - not supported file type\n"), __FUNCTION__, (LPCTSTR)strFoundFilePath); return; @@ -1567,30 +1497,28 @@ void CSharedFileList::CheckAndAddSingleFile(const CFileFind &ff) CComPtr pShellLink; if (SUCCEEDED(pShellLink.CoCreateInstance(CLSID_ShellLink))) { CComQIPtr pPersistFile(pShellLink); - if (pPersistFile) { - if (SUCCEEDED(pPersistFile->Load(strFoundFilePath, STGM_READ))) { - TCHAR szResolvedPath[MAX_PATH]; - if (pShellLink->GetPath(szResolvedPath, _countof(szResolvedPath), NULL/*DO NOT USE (read below)*/, 0) == NOERROR) { - // WIN32_FIND_DATA provided by "IShellLink::GetPath" contains the file stats which where - // taken when the shortcut was created! Thus the file stats which are returned do *not* - // reflect the current real file stats. So, do *not* use that data! - // - // Need to do an explicit 'FindFile' to get the current WIN32_FIND_DATA file stats. - // - CFileFind ffResolved; - if (!ffResolved.FindFile(szResolvedPath)) - return; - VERIFY(!ffResolved.FindNextFile()); - if (ffResolved.IsDirectory() || ffResolved.IsDots() || ffResolved.IsSystem() || ffResolved.IsTemporary() || ffResolved.GetLength() == 0 || ffResolved.GetLength() > MAX_EMULE_FILE_SIZE) - return; - strShellLinkDir = strFoundDirectory; - strFoundDirectory = ffResolved.GetRoot(); - strFoundFileName = ffResolved.GetFileName(); - strFoundFilePath = ffResolved.GetFilePath(); - ullFoundFileSize = ffResolved.GetLength(); - ffResolved.GetLastWriteTime(&tFoundFileTime); - slosh(strFoundDirectory); - } + if (pPersistFile && SUCCEEDED(pPersistFile->Load(strFoundFilePath, STGM_READ))) { + TCHAR szResolvedPath[MAX_PATH]; + if (pShellLink->GetPath(szResolvedPath, _countof(szResolvedPath), NULL/*DO NOT USE (read below)*/, 0) == NOERROR) { + // WIN32_FIND_DATA provided by "IShellLink::GetPath" contains the file stats which where + // taken when the shortcut was created! Thus the file stats which are returned do *not* + // reflect the current real file stats. So, do *not* use that data! + // + // Need to do an explicit 'FindFile' to get the current WIN32_FIND_DATA file stats. + // + CFileFind ffResolved; + if (!ffResolved.FindFile(szResolvedPath)) + return; + VERIFY(!ffResolved.FindNextFile()); + if (ffResolved.IsDirectory() || ffResolved.IsSystem() || ffResolved.IsTemporary() || ffResolved.GetLength() == 0 || ffResolved.GetLength() > MAX_EMULE_FILE_SIZE) + return; + strShellLinkDir = strFoundDirectory; + strFoundDirectory = ffResolved.GetRoot(); + strFoundFileName = ffResolved.GetFileName(); + strFoundFilePath = ffResolved.GetFilePath(); + ullFoundFileSize = ffResolved.GetLength(); + ffResolved.GetLastWriteTime(&tFoundFileTime); + slosh(strFoundDirectory); } } } @@ -1598,25 +1526,13 @@ void CSharedFileList::CheckAndAddSingleFile(const CFileFind &ff) } // ignore real(!) thumbs.db files -- seems that lot of ppl have 'thumbs.db' files without the 'System' file attribute - if (strFoundFileName.CompareNoCase(_T("thumbs.db")) == 0) { - // if that's a valid 'Storage' file, we declare it as a "thumbs.db" file. - CComPtr pStorage; - if (StgOpenStorage(strFoundFilePath, NULL, STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &pStorage) == S_OK) { - CComPtr pEnumSTATSTG; - if (SUCCEEDED(pStorage->EnumElements(0, NULL, 0, &pEnumSTATSTG))) { - STATSTG statstg = {}; - if (pEnumSTATSTG->Next(1, &statstg, 0) == S_OK) { - CoTaskMemFree(statstg.pwcsName); - statstg.pwcsName = NULL; - TRACE(_T("%hs: Did not share file \"%s\" - not supported file type\n"), __FUNCTION__, (LPCTSTR)strFoundFilePath); - return; - } - } - } + if (IsThumbsDb(strFoundFilePath, strFoundFileName)) { + TRACE(_T("%hs: Did not share file \"%s\" - not supported file type\n"), __FUNCTION__, (LPCTSTR)strFoundFilePath); + return; } time_t fdate = (time_t)FileTimeToUnixTime(tFoundFileTime); - if (fdate == 0) + if (fdate <= 0) fdate = (time_t)-1; if (fdate == (time_t)-1) { if (thePrefs.GetVerbose()) @@ -1667,7 +1583,7 @@ void CSharedFileList::Save() const if (sdirfile.Open(strFullPath, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite | CFile::typeBinary)) { try { // write Unicode byte order mark 0xFEFF - static const WORD wBOM = 0xFEFFui16; + static const WORD wBOM = u'\xFEFF'; sdirfile.Write(&wBOM, sizeof(wBOM)); for (POSITION pos = m_liSingleSharedFiles.GetHeadPosition(); pos != NULL;) { @@ -1675,10 +1591,10 @@ void CSharedFileList::Save() const sdirfile.Write(_T("\r\n"), 2 * sizeof(TCHAR)); } for (POSITION pos = m_liSingleExcludedFiles.GetHeadPosition(); pos != NULL;) { - sdirfile.WriteString(_T("-") + m_liSingleExcludedFiles.GetNext(pos)); // a '-' prefix means excluded + sdirfile.WriteString(_T('-') + m_liSingleExcludedFiles.GetNext(pos)); // a '-' prefix means excluded sdirfile.Write(_T("\r\n"), 2 * sizeof(TCHAR)); } - if ((theApp.IsClosing() && thePrefs.GetCommitFiles() >= 1) || thePrefs.GetCommitFiles() >= 2) { + if (thePrefs.GetCommitFiles() >= 2 || (thePrefs.GetCommitFiles() >= 1 && theApp.IsClosing())) { sdirfile.Flush(); // flush file stream buffers to disk buffers if (_commit(_fileno(sdirfile.m_pStream)) != 0) // commit disk buffers to disk AfxThrowFileException(CFileException::hardIO, ::GetLastError(), sdirfile.GetFileName()); @@ -1697,40 +1613,31 @@ void CSharedFileList::Save() const void CSharedFileList::LoadSingleSharedFilesList() { const CString &strFullPath(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + SHAREDFILES_FILE); - CStdioFile *sdirfile = new CStdioFile(); bool bIsUnicodeFile = IsUnicodeFile(strFullPath); // check for BOM - if (sdirfile->Open(strFullPath, CFile::modeRead | CFile::shareDenyWrite | (bIsUnicodeFile ? CFile::typeBinary : 0))) { + CStdioFile sdirfile; + if (sdirfile.Open(strFullPath, CFile::modeRead | CFile::shareDenyWrite | (bIsUnicodeFile ? CFile::typeBinary : 0))) { try { if (bIsUnicodeFile) - sdirfile->Seek(sizeof(WORD), SEEK_CUR); // skip BOM + sdirfile.Seek(sizeof(WORD), CFile::current); // skip BOM CString toadd; - while (sdirfile->ReadString(toadd)) { + while (sdirfile.ReadString(toadd)) { toadd.Trim(_T(" \t\r\n")); // need to trim '\r' in binary mode if (toadd.IsEmpty()) continue; - bool bExclude = (toadd.Left(1) == '-'); // a '-' prefix means excluded + bool bExclude = (toadd[0] == _T('-')); // a '-' prefix means excluded if (bExclude) toadd.Delete(0, 1); - // Skip non-existing directories from fixed disks only - int iDrive = PathGetDriveNumber(toadd); - if (iDrive >= 0 && iDrive <= 25) { - TCHAR szRootPath[4] = _T("@:\\"); - *szRootPath = (TCHAR)(_T('A') + iDrive); - if (GetDriveType(szRootPath) == DRIVE_FIXED) - if (_taccess(toadd, 0) != 0) //check existence - continue; - } - - if (bExclude) - ExcludeFile(toadd); - else - AddSingleSharedFile(toadd, true); - + // Skip non-existing directories on fixed disks only + if (DirAccsess(toadd)) + if (bExclude) + ExcludeFile(toadd); + else + AddSingleSharedFile(toadd, true); } - sdirfile->Close(); + sdirfile.Close(); } catch (CFileException *error) { TCHAR buffer[MAX_CFEXP_ERRORMSG]; GetExceptionMessage(*error, buffer, _countof(buffer)); @@ -1739,17 +1646,16 @@ void CSharedFileList::LoadSingleSharedFilesList() } } else DebugLogError(_T("Failed to load %s"), (LPCTSTR)strFullPath); - delete sdirfile; } bool CSharedFileList::AddSingleSharedDirectory(const CString &rstrFilePath, bool bNoUpdate) { - ASSERT(rstrFilePath.Right(1) == _T("\\")); // check if we share this dir already or are not allowed to - if (ShouldBeShared(rstrFilePath, CString(), false) || !thePrefs.IsShareableDirectory(rstrFilePath)) + if (ShouldBeShared(rstrFilePath, NULL, false) || !thePrefs.IsShareableDirectory(rstrFilePath)) return false; - thePrefs.shareddir_list.AddTail(rstrFilePath); // adds the new directory as shared, GUI updates need to be done by the caller + // add the new directory as shared, GUI update to be done by the caller + thePrefs.shareddir_list.AddTail(rstrFilePath); if (!bNoUpdate) { AddFilesFromDirectory(rstrFilePath); HashNextFile(); @@ -1759,25 +1665,27 @@ bool CSharedFileList::AddSingleSharedDirectory(const CString &rstrFilePath, bool CString CSharedFileList::GetPseudoDirName(const CString &strDirectoryName) { - // those pseudo names are sent to other clients when requesting shared files instead of the full directory names to avoid - // giving away too many information about our local file structure, which might be sensitive data in some cases, - // but we still want to use a descriptive name so the information of files sorted by directories is not lost - // So, in general we use only the name of the directory, shared subdirs keep the path up to the highest shared dir, - // this way we never reveal the name of any not directly shared directory. We then make sure its unique. - if (!ShouldBeShared(strDirectoryName, _T(""), false)) { + // Those pseudo names are sent to other clients when requesting shared files instead of + // the full directory names to avoid giving away too much information about our local + // file structure, which might be sensitive data in some cases. + // But we still want to use a descriptive name so the information of files sorted by directories is not lost + // In general we use only the name of the directory, shared subdirs keep the path up to + // the highest shared dir. This way we never reveal the name of any indirectly shared directory. + // Then we make sure it's unique. + if (!ShouldBeShared(strDirectoryName, NULL, false)) { ASSERT(0); return CString(); } - // does the name already exists? + // does the name already exist? CString strTmpPseudo, strTmpPath; for (POSITION pos = m_mapPseudoDirNames.GetStartPosition(); pos != NULL;) { m_mapPseudoDirNames.GetNextAssoc(pos, strTmpPseudo, strTmpPath); - if (CompareDirectory(strTmpPath, strDirectoryName) == 0) - return strTmpPseudo; // already done here + if (EqualPaths(strTmpPath, strDirectoryName)) + return CString(); // not sending the same directory again } // create a new Pseudoname - CString strDirectoryTmp = strDirectoryName; + CString strDirectoryTmp(strDirectoryName); unslosh(strDirectoryTmp); CString strPseudoName; @@ -1785,11 +1693,11 @@ CString CSharedFileList::GetPseudoDirName(const CString &strDirectoryName) while ((iPos = strDirectoryTmp.ReverseFind(_T('\\'))) >= 0) { strPseudoName = strDirectoryTmp.Right(strDirectoryTmp.GetLength() - iPos) + strPseudoName; strDirectoryTmp.Truncate(iPos); - if (!ShouldBeShared(strDirectoryTmp, _T(""), false)) + if (!ShouldBeShared(strDirectoryTmp, NULL, false)) break; } if (strPseudoName.IsEmpty()) { - // must be a root Existence only directory + // must be a root directory ASSERT(strDirectoryTmp.GetLength() == 2); strPseudoName = strDirectoryTmp; } else { @@ -1798,14 +1706,13 @@ CString CSharedFileList::GetPseudoDirName(const CString &strDirectoryName) strPseudoName.Delete(0, 1); } // we have the name, make sure it is unique - if (m_mapPseudoDirNames.Lookup(strPseudoName, strDirectoryTmp)) { + if (m_mapPseudoDirNames.PLookup(strPseudoName)) { CString strUnique; for (iPos = 2; ; ++iPos) { strUnique.Format(_T("%s_%i"), (LPCTSTR)strPseudoName, iPos); - if (!m_mapPseudoDirNames.Lookup(strUnique, strDirectoryTmp)) { - DebugLog(_T("Using Pseudoname %s for directory %s"), (LPCTSTR)strUnique, (LPCTSTR)strDirectoryName); - m_mapPseudoDirNames.SetAt(strUnique, strDirectoryName); - return strUnique; + if (!m_mapPseudoDirNames.PLookup(strUnique)) { + strPseudoName = strUnique; + break; } if (iPos > 200) { // wth? @@ -1813,11 +1720,11 @@ CString CSharedFileList::GetPseudoDirName(const CString &strDirectoryName) return CString(); } } - } else { - DebugLog(_T("Using Pseudoname %s for directory %s"), (LPCTSTR)strPseudoName, (LPCTSTR)strDirectoryName); - m_mapPseudoDirNames.SetAt(strPseudoName, strDirectoryName); - return strPseudoName; } + + DebugLog(_T("Using Pseudoname %s for directory %s"), (LPCTSTR)strPseudoName, (LPCTSTR)strDirectoryName); + m_mapPseudoDirNames[strPseudoName] = strDirectoryName; + return strPseudoName; } CString CSharedFileList::GetDirNameByPseudo(const CString &strPseudoName) const @@ -1835,18 +1742,18 @@ bool CSharedFileList::GetPopularityRank(const CKnownFile *pFile, uint32 &rnOutSe ASSERT(0); return false; } + UINT uAllTimeReq = pFile->statistic.GetAllTimeRequests(); + UINT uReq = pFile->statistic.GetRequests(); + // we start at rank #1, not 0 rnOutSession = 1; rnOutTotal = 1; // cycle all files, each file which has more requests than the given file lowers the rank - CCKey bufKey; - for (POSITION pos = m_Files_map.GetStartPosition(); pos != NULL;) { - CKnownFile *cur_file; - m_Files_map.GetNextAssoc(pos, bufKey, cur_file); - if (cur_file != pFile) { - rnOutTotal += static_cast(cur_file->statistic.GetAllTimeRequests() > pFile->statistic.GetAllTimeRequests()); - rnOutSession += static_cast(cur_file->statistic.GetRequests() > pFile->statistic.GetRequests()); + for (const CKnownFilesMap::CPair *pair = m_Files_map.PGetFirstAssoc(); pair != NULL; pair = m_Files_map.PGetNextAssoc(pair)) + if (pair->value != pFile) { + rnOutTotal += static_cast(pair->value->statistic.GetAllTimeRequests() > uAllTimeReq); + rnOutSession += static_cast(pair->value->statistic.GetRequests() > uReq); } - } + return true; } \ No newline at end of file diff --git a/srchybrid/SharedFileList.h b/srchybrid/SharedFileList.h index 3c54278a..99c4ec53 100644 --- a/srchybrid/SharedFileList.h +++ b/srchybrid/SharedFileList.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -26,6 +26,7 @@ class CPublishKeywordList; class CSafeMemFile; class CServer; class CCollection; +typedef CMap CKnownFilesMap; struct UnknownFile_Struct { @@ -56,7 +57,7 @@ class CSharedFileList void ClearED2KPublishInfo(); void ClearKadSourcePublishInfo(); - static void CreateOfferedFilePacket(CKnownFile *cur_file, CSafeMemFile *files, CServer *pServer, CUpDownClient *pClient = NULL); + static void CreateOfferedFilePacket(CKnownFile *cur_file, CSafeMemFile &files, CServer *pServer, CUpDownClient *pClient = NULL); bool SafeAddKFile(CKnownFile *toadd, bool bOnlyAdd = false); void RepublishFile(CKnownFile *pFile); @@ -73,7 +74,7 @@ class CSharedFileList void AddKeywords(CKnownFile *pFile); void RemoveKeywords(CKnownFile *pFile); - void CopySharedFileMap(CMap &Files_Map); + void CopySharedFileMap(CKnownFilesMap &Files_Map); CKnownFile* GetFileByID(const uchar *hash) const; CKnownFile* GetFileByIdentifier(const CFileIdentifierBase &rFileIdent, bool bStrict = false) const; @@ -83,7 +84,7 @@ class CSharedFileList bool IsFilePtrInList(const CKnownFile *file) const; // slow bool IsUnsharedFile(const uchar *auFileHash) const; - bool ShouldBeShared(const CString &strPath, const CString &strFilePath, bool bMustBeShared) const; + bool ShouldBeShared(const CString &sDirPath, LPCTSTR const pFilePath, bool bMustBeShared) const; bool ContainsSingleSharedFiles(const CString &strDirectory) const; // includes subdirs CString GetPseudoDirName(const CString &strDirectoryName); CString GetDirNameByPseudo(const CString &strPseudoName) const; @@ -116,10 +117,10 @@ class CSharedFileList bool CheckAndAddSingleFile(const CString &rstrFilePath); // add specific files without editing sharing preferences private: - void AddDirectory(const CString& strDir, CStringList& dirlist); + void AddDirectory(const CString &strDir, CStringList &dirlist); - CMap m_Files_map; - CMap m_UnsharedFiles_map; + CKnownFilesMap m_Files_map; + CMap m_UnsharedFiles_map; CMapStringToString m_mapPseudoDirNames; CPublishKeywordList *m_keywords; CTypedPtrList waitingforhash_list; @@ -128,10 +129,12 @@ class CSharedFileList CSharedFilesCtrl *output; CStringList m_liSingleSharedFiles; CStringList m_liSingleExcludedFiles; +#if defined(_BETA) || defined(_DEVBUILD) + CString m_strBetaFileName; //beta test file name +#endif INT_PTR m_currFileSrc; INT_PTR m_currFileNotes; - //INT_PTR m_currFileKey; - not used time_t m_lastPublishKadSrc; time_t m_lastPublishKadNotes; DWORD m_lastPublishED2K; @@ -148,14 +151,14 @@ class CAddFileThread : public CWinThread virtual BOOL InitInstance(); virtual int Run(); void SetValues(CSharedFileList *pOwner, LPCTSTR directory, LPCTSTR filename, LPCTSTR strSharedDir, CPartFile *partfile = NULL); - bool ImportParts(); - uint16 SetPartToImport(LPCTSTR import); + bool ImportParts(); + uint16 SetPartToImport(LPCTSTR import); private: CSharedFileList *m_pOwner; - CPartFile *m_partfile; - CString m_strDirectory; - CString m_strFilename; - CString m_strSharedDir; - CString m_strImport; + CPartFile *m_partfile; + CString m_strDirectory; + CString m_strFilename; + CString m_strSharedDir; + CString m_strImport; CArray m_PartsToImport; }; \ No newline at end of file diff --git a/srchybrid/SharedFilesCtrl.cpp b/srchybrid/SharedFilesCtrl.cpp index 67ecd2e8..84ac0c86 100644 --- a/srchybrid/SharedFilesCtrl.cpp +++ b/srchybrid/SharedFilesCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -18,7 +18,7 @@ #include "emule.h" #include "emuledlg.h" #include "SharedFilesCtrl.h" -#include "OtherFunctions.h" +#include "UpDownClient.h" #include "FileInfoDialog.h" #include "MetaDataDlg.h" #include "ED2kLinkDlg.h" @@ -41,7 +41,6 @@ #include "WebServices.h" #include "TransferDlg.h" #include "ClientList.h" -#include "UpDownClient.h" #include "Collection.h" #include "CollectionCreateDialog.h" #include "CollectionViewDialog.h" @@ -77,7 +76,6 @@ class CSharedFileDetailsSheet : public CListViewWalkerPropertySheet void Localize(); public: CSharedFileDetailsSheet(CTypedPtrList &aFiles, UINT uInvokePage = 0, CListCtrlItemWalk *pListCtrl = NULL); - virtual ~CSharedFileDetailsSheet() = default; protected: CArchivePreviewDlg m_wndArchiveInfo; @@ -263,24 +261,24 @@ void CSharedFilesCtrl::Init() SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP); ASSERT((GetStyle() & LVS_SINGLESEL) == 0); - InsertColumn(0, GetResString(IDS_DL_FILENAME), LVCFMT_LEFT, DFLT_FILENAME_COL_WIDTH); - InsertColumn(1, GetResString(IDS_DL_SIZE), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH); - InsertColumn(2, GetResString(IDS_TYPE), LVCFMT_LEFT, DFLT_FILETYPE_COL_WIDTH); - InsertColumn(3, GetResString(IDS_PRIORITY), LVCFMT_LEFT, DFLT_PRIORITY_COL_WIDTH); - InsertColumn(4, GetResString(IDS_FILEID), LVCFMT_LEFT, DFLT_HASH_COL_WIDTH, -1, true); - InsertColumn(5, GetResString(IDS_SF_REQUESTS), LVCFMT_RIGHT, 100); - InsertColumn(6, GetResString(IDS_SF_ACCEPTS), LVCFMT_RIGHT, 100, -1, true); - InsertColumn(7, GetResString(IDS_SF_TRANSFERRED), LVCFMT_RIGHT, 120); - InsertColumn(8, GetResString(IDS_SHARED_STATUS), LVCFMT_LEFT, DFLT_PARTSTATUS_COL_WIDTH); - InsertColumn(9, GetResString(IDS_FOLDER), LVCFMT_LEFT, DFLT_FOLDER_COL_WIDTH, -1, true); - InsertColumn(10, GetResString(IDS_COMPLSOURCES), LVCFMT_RIGHT, 60); - InsertColumn(11, GetResString(IDS_SHAREDTITLE), LVCFMT_LEFT, 100); - InsertColumn(12, GetResString(IDS_ARTIST), LVCFMT_LEFT, DFLT_ARTIST_COL_WIDTH, -1, true); - InsertColumn(13, GetResString(IDS_ALBUM), LVCFMT_LEFT, DFLT_ALBUM_COL_WIDTH, -1, true); - InsertColumn(14, GetResString(IDS_TITLE), LVCFMT_LEFT, DFLT_TITLE_COL_WIDTH, -1, true); - InsertColumn(15, GetResString(IDS_LENGTH), LVCFMT_RIGHT, DFLT_LENGTH_COL_WIDTH, -1, true); - InsertColumn(16, GetResString(IDS_BITRATE), LVCFMT_RIGHT, DFLT_BITRATE_COL_WIDTH, -1, true); - InsertColumn(17, GetResString(IDS_CODEC), LVCFMT_LEFT, DFLT_CODEC_COL_WIDTH, -1, true); + InsertColumn(0, _T(""), LVCFMT_LEFT, DFLT_FILENAME_COL_WIDTH); //IDS_DL_FILENAME + InsertColumn(1, _T(""), LVCFMT_RIGHT, DFLT_SIZE_COL_WIDTH); //IDS_DL_SIZE + InsertColumn(2, _T(""), LVCFMT_LEFT, DFLT_FILETYPE_COL_WIDTH); //IDS_TYPE + InsertColumn(3, _T(""), LVCFMT_LEFT, DFLT_PRIORITY_COL_WIDTH); //IDS_PRIORITY + InsertColumn(4, _T(""), LVCFMT_LEFT, DFLT_HASH_COL_WIDTH, -1, true); //IDS_FILEID + InsertColumn(5, _T(""), LVCFMT_RIGHT, 100); //IDS_SF_REQUESTS + InsertColumn(6, _T(""), LVCFMT_RIGHT, 100, -1, true); //IDS_SF_ACCEPTS + InsertColumn(7, _T(""), LVCFMT_RIGHT, 120); //IDS_SF_TRANSFERRED + InsertColumn(8, _T(""), LVCFMT_LEFT, DFLT_PARTSTATUS_COL_WIDTH); //IDS_SHARED_STATUS + InsertColumn(9, _T(""), LVCFMT_LEFT, DFLT_FOLDER_COL_WIDTH, -1, true); //IDS_FOLDER + InsertColumn(10, _T(""), LVCFMT_RIGHT, 60); //IDS_COMPLSOURCES + InsertColumn(11, _T(""), LVCFMT_LEFT, 100); //IDS_SHAREDTITLE + InsertColumn(12, _T(""), LVCFMT_LEFT, DFLT_ARTIST_COL_WIDTH, -1, true); //IDS_ARTIST + InsertColumn(13, _T(""), LVCFMT_LEFT, DFLT_ALBUM_COL_WIDTH, -1, true); //IDS_ALBUM + InsertColumn(14, _T(""), LVCFMT_LEFT, DFLT_TITLE_COL_WIDTH, -1, true); //IDS_TITLE + InsertColumn(15, _T(""), LVCFMT_RIGHT, DFLT_LENGTH_COL_WIDTH, -1, true); //IDS_LENGTH + InsertColumn(16, _T(""), LVCFMT_RIGHT, DFLT_BITRATE_COL_WIDTH, -1, true); //IDS_BITRATE + InsertColumn(17, _T(""), LVCFMT_LEFT, DFLT_CODEC_COL_WIDTH, -1, true); //IDS_CODEC SetAllIcons(); CreateMenus(); @@ -295,7 +293,7 @@ void CSharedFilesCtrl::Init() else if (GetSortItem() == 11) m_aSortBySecondValue[3] = GetSortSecondValue(); SetSortArrow(); - SortItems(SortProc, GetSortItem() + (GetSortAscending() ? 0 : 20) + (GetSortSecondValue() ? 100 : 0)); + SortItems(SortProc, MAKELONG(GetSortItem() + (GetSortSecondValue() ? 100 : 0), !GetSortAscending())); CToolTipCtrl *tooltip = GetToolTips(); if (tooltip) { @@ -322,16 +320,16 @@ void CSharedFilesCtrl::SetAllIcons() ApplyImageList(NULL); m_ImageList.DeleteImageList(); m_ImageList.Create(16, 16, theApp.m_iDfltImageListColorFlags | ILC_MASK, 0, 1); - m_ImageList.Add(CTempIconLoader(_T("EMPTY"))); - m_ImageList.Add(CTempIconLoader(_T("FileSharedServer"))); - m_ImageList.Add(CTempIconLoader(_T("FileSharedKad"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_NotRated"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_Fake"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_Poor"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_Fair"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_Good"))); - m_ImageList.Add(CTempIconLoader(_T("Rating_Excellent"))); - m_ImageList.Add(CTempIconLoader(_T("Collection_Search"))); // rating for comments are searched on kad + m_ImageList.Add(CTempIconLoader(_T("EMPTY"))); //0 + m_ImageList.Add(CTempIconLoader(_T("FileSharedServer")));//1 + m_ImageList.Add(CTempIconLoader(_T("FileSharedKad"))); //2 + m_ImageList.Add(CTempIconLoader(_T("Rating_NotRated")));//3 + m_ImageList.Add(CTempIconLoader(_T("Rating_Fake"))); //4 + m_ImageList.Add(CTempIconLoader(_T("Rating_Poor"))); //5 + m_ImageList.Add(CTempIconLoader(_T("Rating_Fair"))); //6 + m_ImageList.Add(CTempIconLoader(_T("Rating_Good"))); //7 + m_ImageList.Add(CTempIconLoader(_T("Rating_Excellent")));//8 + m_ImageList.Add(CTempIconLoader(_T("Collection_Search"))); //9 rating for comments are searched on kad m_ImageList.SetOverlayImage(m_ImageList.Add(CTempIconLoader(_T("FileCommentsOvl"))), 1); // Apply the image list also to the listview control, even if we use our own 'DrawItem'. // This is needed to give the listview control a chance to initialize the row height. @@ -343,20 +341,13 @@ void CSharedFilesCtrl::Localize() { static const UINT uids[18] = { - IDS_DL_FILENAME, IDS_DL_SIZE, IDS_TYPE, IDS_PRIORITY, IDS_FILEID, IDS_SF_REQUESTS - , IDS_SF_ACCEPTS, IDS_SF_TRANSFERRED, IDS_SHARED_STATUS, IDS_FOLDER, IDS_COMPLSOURCES - , IDS_SHAREDTITLE, IDS_ARTIST, IDS_ALBUM, IDS_TITLE, IDS_LENGTH, IDS_BITRATE, IDS_CODEC + IDS_DL_FILENAME, IDS_DL_SIZE, IDS_TYPE, IDS_PRIORITY, IDS_FILEID + , IDS_SF_REQUESTS, IDS_SF_ACCEPTS, IDS_SF_TRANSFERRED, IDS_SHARED_STATUS, IDS_FOLDER + , IDS_COMPLSOURCES, IDS_SHAREDTITLE, IDS_ARTIST, IDS_ALBUM, IDS_TITLE + , IDS_LENGTH, IDS_BITRATE, IDS_CODEC }; - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); - HDITEM hdi; - hdi.mask = HDI_TEXT; - - for (int i = 0; i < _countof(uids); ++i) { - const CString &strRes(GetResString(uids[i])); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(i, &hdi); - } + LocaliseHeaderCtrl(uids, _countof(uids)); CreateMenus(); @@ -374,45 +365,39 @@ void CSharedFilesCtrl::AddFile(const CShareableFile *file) if (m_pDirectoryFilter != NULL) { ASSERT(file->IsKindOf(RUNTIME_CLASS(CKnownFile)) || m_pDirectoryFilter->m_eItemType == SDI_UNSHAREDDIRECTORY); switch (m_pDirectoryFilter->m_eItemType) { - case SDI_ALL: - // No filter + case SDI_ALL: // No filter break; case SDI_FILESYSTEMPARENT: return; - case SDI_UNSHAREDDIRECTORY: - // Items from the whole filesystem tree + case SDI_UNSHAREDDIRECTORY: // Items from the whole file system tree if (file->IsPartFile()) return; case SDI_NO: // some shared directory - case SDI_CATINCOMING: - // Categories with special incoming dirs - if (CompareDirectory(file->GetSharedDirectory(), m_pDirectoryFilter->m_strFullPath) != 0) + case SDI_CATINCOMING: // Categories with special incoming dirs + if (!EqualPaths(file->GetSharedDirectory(), m_pDirectoryFilter->m_strFullPath)) return; break; - case SDI_TEMP: - // only temp files + case SDI_TEMP: // only temp files if (!file->IsPartFile()) return; if (m_pDirectoryFilter->m_nCatFilter != -1 && (UINT)m_pDirectoryFilter->m_nCatFilter != ((CPartFile*)file)->GetCategory()) return; break; - case SDI_DIRECTORY: - // any user selected shared dir but not incoming or temp + case SDI_DIRECTORY: // any user selected shared dir but not incoming or temp if (file->IsPartFile()) return; - if (CompareDirectory(file->GetSharedDirectory(), thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR)) == 0) + if (EqualPaths(file->GetSharedDirectory(), thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR))) return; break; - case SDI_INCOMING: - // Main incoming directory - if (CompareDirectory(file->GetSharedDirectory(), thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR)) != 0) + case SDI_INCOMING: // Main incoming directory + if (!EqualPaths(file->GetSharedDirectory(), thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR))) return; // Hmm should we show all incoming files dirs or only those from the main incoming dir here? // hard choice, will only show the main for now } } - if (IsFilteredItem(file)) + if (IsFilteredOut(file)) return; if (FindFile(file) >= 0) { // in the file system view the shared status might have changed so we need to update the item to redraw the checkbox @@ -424,7 +409,7 @@ void CSharedFilesCtrl::AddFile(const CShareableFile *file) // if we are in the file system view, this might be a CKnownFile which has to replace a CShareableFile // (in case we start sharing this file), so make sure to replace the old one instead of adding a new if (m_pDirectoryFilter != NULL && m_pDirectoryFilter->m_eItemType == SDI_UNSHAREDDIRECTORY && file->IsKindOf(RUNTIME_CLASS(CKnownFile))) - for (POSITION pos = liTempShareableFilesInDir.GetHeadPosition(); pos != NULL; ) { + for (POSITION pos = liTempShareableFilesInDir.GetHeadPosition(); pos != NULL;) { const CShareableFile *pFile = liTempShareableFilesInDir.GetNext(pos); if (pFile->GetFilePath().CompareNoCase(file->GetFilePath()) == 0) { int iOldFile = FindFile(pFile); @@ -448,7 +433,7 @@ void CSharedFilesCtrl::RemoveFile(const CShareableFile *file, bool bDeletedFromD if (iItem >= 0) { if (!bDeletedFromDisk && m_pDirectoryFilter != NULL && m_pDirectoryFilter->m_eItemType == SDI_UNSHAREDDIRECTORY) // in the file system view we usually don't need to remove a file, if it becomes unshared it will - // still be visible as its still in the file system and the knownfile object doesn't gets deleted neither + // still be visible as its still in the file system and the knownfile object doesn't get deleted neither // so to avoid having to reload the whole list we just update it instead of removing and re-finding UpdateFile(file); else @@ -459,7 +444,7 @@ void CSharedFilesCtrl::RemoveFile(const CShareableFile *file, bool bDeletedFromD void CSharedFilesCtrl::UpdateFile(const CShareableFile *file, bool bUpdateFileSummary) { - if (!theApp.IsClosing() && file) { + if (file && !theApp.IsClosing()) { int iItem = FindFile(file); if (iItem >= 0) { Update(iItem); @@ -482,16 +467,13 @@ void CSharedFilesCtrl::ReloadFileList() DeleteAllItems(); theApp.emuledlg->sharedfileswnd->ShowSelectedFilesDetails(); - CCKey bufKey; - for (POSITION pos = theApp.sharedfiles->m_Files_map.GetStartPosition(); pos != NULL;) { - CKnownFile *cur_file; - theApp.sharedfiles->m_Files_map.GetNextAssoc(pos, bufKey, cur_file); - AddFile(cur_file); - } + for (const CKnownFilesMap::CPair *pair = theApp.sharedfiles->m_Files_map.PGetFirstAssoc(); pair != NULL; pair = theApp.sharedfiles->m_Files_map.PGetNextAssoc(pair)) + AddFile(pair->value); + if (m_pDirectoryFilter != NULL && m_pDirectoryFilter->m_eItemType == SDI_UNSHAREDDIRECTORY && !m_pDirectoryFilter->m_strFullPath.IsEmpty()) AddShareableFiles(m_pDirectoryFilter->m_strFullPath); else - while (!liTempShareableFilesInDir.IsEmpty()) // cleanup temp file list + while (!liTempShareableFilesInDir.IsEmpty()) // clear temp file list delete liTempShareableFilesInDir.RemoveHead(); ShowFilesCount(); @@ -509,113 +491,111 @@ void CSharedFilesCtrl::ShowFilesCount() void CSharedFilesCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { - if (theApp.IsClosing() || !lpDrawItemStruct->itemData) + if (!lpDrawItemStruct->itemData || theApp.IsClosing()) return; - CMemoryDC dc(CDC::FromHandle(lpDrawItemStruct->hDC), &lpDrawItemStruct->rcItem); + CRect rcItem(lpDrawItemStruct->rcItem); + CMemoryDC dc(CDC::FromHandle(lpDrawItemStruct->hDC), rcItem); BOOL bCtrlFocused; InitItemMemDC(dc, lpDrawItemStruct, bCtrlFocused); - CRect rcItem(lpDrawItemStruct->rcItem); - CRect rcClient; + RECT rcClient; GetClientRect(&rcClient); CShareableFile *file = reinterpret_cast(lpDrawItemStruct->itemData); CKnownFile *pKnownFile = file->IsKindOf(RUNTIME_CLASS(CKnownFile)) ? static_cast(file) : NULL; - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); + const CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); int iCount = pHeaderCtrl->GetItemCount(); - rcItem.right = rcItem.left - sm_iLabelOffset; - rcItem.left += sm_iIconOffset; + LONG itemLeft = rcItem.left; int iIconDrawWidth = theApp.GetSmallSytemIconSize().cx; + LONG iIconY = max((rcItem.Height() - theApp.GetSmallSytemIconSize().cy - 1) / 2, 0); for (int iCurrent = 0; iCurrent < iCount; ++iCurrent) { int iColumn = pHeaderCtrl->OrderToIndex(iCurrent); - if (!IsColumnHidden(iColumn)) { - UINT uDrawTextAlignment; - int iColumnWidth = GetColumnWidth(iColumn, uDrawTextAlignment); - rcItem.right += iColumnWidth; - if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) { - const CString &sItem(GetItemDisplayText(file, iColumn)); - switch (iColumn) { - case 0: //file name - { - int iCheckboxDrawWidth = 0; - if (CheckBoxesEnabled()) { - CHECKBOXSTATES iState = (file == m_pHighlightedItem) ? CBS_UNCHECKEDHOT : CBS_UNCHECKEDNORMAL; - int iNoStyleState = (file == m_pHighlightedItem) ? DFCS_PUSHED : 0; - // no interacting with shell linked files or default shared directories - if ((file->IsShellLinked() && theApp.sharedfiles->ShouldBeShared(file->GetSharedDirectory(), file->GetFilePath(), false)) - || (theApp.sharedfiles->ShouldBeShared(file->GetSharedDirectory(), file->GetFilePath(), true))) - { - iState = CBS_CHECKEDDISABLED; - iNoStyleState = DFCS_CHECKED | DFCS_INACTIVE; - } else if (theApp.sharedfiles->ShouldBeShared(file->GetSharedDirectory(), file->GetFilePath(), false)) { - iState = (file == m_pHighlightedItem) ? CBS_CHECKEDHOT : CBS_CHECKEDNORMAL; - iNoStyleState = (file == m_pHighlightedItem) ? (DFCS_PUSHED | DFCS_CHECKED) : DFCS_CHECKED; - } else if (!thePrefs.IsShareableDirectory(file->GetPath())) { - iState = CBS_UNCHECKEDDISABLED; - iNoStyleState = DFCS_INACTIVE; - } + if (IsColumnHidden(iColumn)) + continue; - HTHEME hTheme = (g_xpStyle.IsThemeActive() && g_xpStyle.IsAppThemed()) ? g_xpStyle.OpenThemeData(NULL, L"BUTTON") : NULL; - - RECT rcCheckBox(rcItem); - rcCheckBox.left = rcItem.left; - rcCheckBox.top += max((rcItem.Height() - 16) / 2, 0); - rcCheckBox.right = rcItem.left + 16; - rcCheckBox.bottom = rcCheckBox.top + 16; - if (hTheme != NULL) - g_xpStyle.DrawThemeBackground(hTheme, dc.GetSafeHdc(), BP_CHECKBOX, iState, &rcCheckBox, NULL); - else - dc.DrawFrameControl(&rcCheckBox, DFC_BUTTON, DFCS_BUTTONCHECK | iNoStyleState | DFCS_FLAT); - rcItem.left += 2 + 16; - iCheckboxDrawWidth += 2 + 16; + UINT uDrawTextAlignment; + int iColumnWidth = GetColumnWidth(iColumn, uDrawTextAlignment); + rcItem.left = itemLeft; + rcItem.right = itemLeft + iColumnWidth; + if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) { + const CString &sItem(GetItemDisplayText(file, iColumn)); + switch (iColumn) { + case 0: //file name + { + rcItem.left += sm_iIconOffset; + LONG rcIconTop = rcItem.top + iIconY; + if (CheckBoxesEnabled()) { + CHECKBOXSTATES iState; + int iNoStyleState; + // no interaction with shell linked files or default shared directories + if ((file->IsShellLinked() && theApp.sharedfiles->ShouldBeShared(file->GetSharedDirectory(), file->GetFilePath(), false)) + || (theApp.sharedfiles->ShouldBeShared(file->GetSharedDirectory(), file->GetFilePath(), true))) + { + iState = CBS_CHECKEDDISABLED; + iNoStyleState = DFCS_CHECKED | DFCS_INACTIVE; + } else if (theApp.sharedfiles->ShouldBeShared(file->GetSharedDirectory(), file->GetFilePath(), false)) { + iState = (file == m_pHighlightedItem) ? CBS_CHECKEDHOT : CBS_CHECKEDNORMAL; + iNoStyleState = (file == m_pHighlightedItem) ? DFCS_PUSHED | DFCS_CHECKED : DFCS_CHECKED; + } else if (!thePrefs.IsShareableDirectory(file->GetPath())) { + iState = CBS_UNCHECKEDDISABLED; + iNoStyleState = DFCS_INACTIVE; + } else { + iState = (file == m_pHighlightedItem) ? CBS_UNCHECKEDHOT : CBS_UNCHECKEDNORMAL; + iNoStyleState = (file == m_pHighlightedItem) ? DFCS_PUSHED : 0; } - int iIconPosY = (rcItem.Height() > theApp.GetSmallSytemIconSize().cy) ? ((rcItem.Height() - theApp.GetSmallSytemIconSize().cy) / 2) : 0; + HTHEME hTheme = (g_xpStyle.IsThemeActive() && g_xpStyle.IsAppThemed()) ? g_xpStyle.OpenThemeData(NULL, L"BUTTON") : NULL; + RECT rcCheckBox = { rcItem.left, rcIconTop, rcItem.left + 16, rcIconTop + 16 }; + if (hTheme != NULL) + g_xpStyle.DrawThemeBackground(hTheme, dc.GetSafeHdc(), BP_CHECKBOX, iState, &rcCheckBox, NULL); + else + dc.DrawFrameControl(&rcCheckBox, DFC_BUTTON, DFCS_BUTTONCHECK | iNoStyleState | DFCS_FLAT); + rcItem.left += 16 + sm_iLabelOffset; + } + + if (theApp.GetSystemImageList() != NULL) { int iImage = theApp.GetFileTypeSystemImageIdx(file->GetFileName()); - if (theApp.GetSystemImageList() != NULL) - ::ImageList_Draw(theApp.GetSystemImageList(), iImage, dc.GetSafeHdc(), rcItem.left, rcItem.top + iIconPosY, ILD_TRANSPARENT); - if (!file->GetFileComment().IsEmpty() || file->GetFileRating()) - m_ImageList.Draw(dc, 0, POINT{ rcItem.left, rcItem.top + iIconPosY }, ILD_NORMAL | INDEXTOOVERLAYMASK(1)); - rcItem.left += iIconDrawWidth; - - if (thePrefs.ShowRatingIndicator() && (file->HasComment() || file->HasRating() || file->IsKadCommentSearchRunning())) { - m_ImageList.Draw(dc, file->UserRating(true) + 3, POINT{ rcItem.left + 2, rcItem.top + iIconPosY }, ILD_NORMAL); - rcItem.left += 2 + 16; - iIconDrawWidth += 2 + 16; - } - rcItem.left += sm_iLabelOffset; - rcItem.right -= sm_iSubItemInset; - dc.DrawText(sItem, -1, &rcItem, MLC_DT_TEXT | uDrawTextAlignment); - rcItem.left -= sm_iLabelOffset + iIconDrawWidth + iCheckboxDrawWidth; - rcItem.right += sm_iSubItemInset; + ::ImageList_Draw(theApp.GetSystemImageList(), iImage, dc.GetSafeHdc(), rcItem.left, rcIconTop, ILD_TRANSPARENT); } - break; - case 8: //shared parts bar - if (pKnownFile != NULL && pKnownFile->GetPartCount()) { - ++rcItem.top; - --rcItem.bottom; - pKnownFile->DrawShareStatusBar(dc, &rcItem, false, thePrefs.UseFlatBar()); - ++rcItem.bottom; - --rcItem.top; + + if (!file->GetFileComment().IsEmpty() || file->GetFileRating()) //not rated + m_ImageList.Draw(dc, 0, POINT{ rcItem.left, rcIconTop }, ILD_NORMAL | INDEXTOOVERLAYMASK(1)); + + rcItem.left += iIconDrawWidth + sm_iLabelOffset; + if (thePrefs.ShowRatingIndicator() && (file->HasComment() || file->HasRating() || file->IsKadCommentSearchRunning())) { + m_ImageList.Draw(dc, 3 + file->UserRating(true), POINT{ rcItem.left, rcIconTop }, ILD_NORMAL); + rcItem.left += 16 + sm_iLabelOffset; } - break; - case 11: //shared ed2k/kad - if (pKnownFile != NULL) { - if (pKnownFile->GetPublishedED2K()) - m_ImageList.Draw(dc, 1, rcItem.TopLeft(), ILD_NORMAL); - if (IsSharedInKad(pKnownFile)) { - rcItem.left += 16; - m_ImageList.Draw(dc, IsSharedInKad(pKnownFile) ? 2 : 0, rcItem.TopLeft(), ILD_NORMAL); - rcItem.left -= 16; - } + rcItem.left -= sm_iSubItemInset; + } + default: //any text column + rcItem.left += sm_iSubItemInset; + rcItem.right -= sm_iSubItemInset; + dc.DrawText(sItem, -1, &rcItem, MLC_DT_TEXT | uDrawTextAlignment); + break; + case 8: //shared parts bar + if (pKnownFile != NULL && pKnownFile->GetPartCount()) { + ++rcItem.top; + --rcItem.bottom; + pKnownFile->DrawShareStatusBar(dc, &rcItem, false, thePrefs.UseFlatBar()); + ++rcItem.bottom; + --rcItem.top; + } + break; + case 11: //shared ed2k/kad + if (pKnownFile != NULL) { + rcItem.left += sm_iIconOffset; + POINT point = { rcItem.left, rcItem.top + iIconY }; + if (pKnownFile->GetPublishedED2K()) + m_ImageList.Draw(dc, 1, point, ILD_NORMAL); + if (IsSharedInKad(pKnownFile)) { + point.x += 16 + sm_iSubItemInset; + m_ImageList.Draw(dc, IsSharedInKad(pKnownFile) ? 2 : 0, point, ILD_NORMAL); } - break; - default: //all other text columns - dc.DrawText(sItem, -1, &rcItem, MLC_DT_TEXT | uDrawTextAlignment); } } - rcItem.left += iColumnWidth; } + itemLeft += iColumnWidth; } DrawFocusRect(dc, &lpDrawItemStruct->rcItem, lpDrawItemStruct->itemState & ODS_FOCUS, bCtrlFocused, lpDrawItemStruct->itemState & ODS_SELECTED); @@ -634,7 +614,6 @@ CString CSharedFilesCtrl::GetItemDisplayText(const CShareableFile *file, int iSu case 9: sText = file->GetPath(); unslosh(sText); - //PathRemoveBackslash(sText); return sText; } @@ -683,7 +662,7 @@ CString CSharedFilesCtrl::GetItemDisplayText(const CShareableFile *file, int iSu { uint32 nMediaLength = pKnownFile->GetIntTagValue(FT_MEDIA_LENGTH); if (nMediaLength) - SecToTimeLength(nMediaLength, sText); + sText = SecToTimeLength(nMediaLength); } break; case 16: @@ -881,6 +860,14 @@ BOOL CSharedFilesCtrl::OnCommand(WPARAM wParam, LPARAM) #endif // file operations case MP_OPEN: +#if TEST_FRAMEGRABBER //see also FrameGrabThread::GrabFrames + if (file) { + CKnownFile *previewFile = theApp.sharedfiles->GetFileByID(file->GetFileHash()); + if (previewFile != NULL) + previewFile->GrabImage(4, 15, true, 450, this); + break; + } +#endif case IDA_ENTER: if (file && !file->IsPartFile()) OpenFile(file); @@ -890,8 +877,11 @@ BOOL CSharedFilesCtrl::OnCommand(WPARAM wParam, LPARAM) InstallSkin(file->GetFilePath()); break; case MP_OPENFOLDER: - if (file && !file->IsPartFile()) - ShellOpen(_T("explorer"), _T("/select,\"") + file->GetFilePath() + _T('\"')); + if (file && !file->IsPartFile()) { + CString sParam; + sParam.Format(_T("/select,\"%s\""), (LPCTSTR)file->GetFilePath()); + ShellOpen(_T("explorer"), sParam); + } break; case MP_RENAME: case MPG_F2: @@ -938,7 +928,7 @@ BOOL CSharedFilesCtrl::OnCommand(WPARAM wParam, LPARAM) if (IDNO == LocMessageBox(IDS_CONFIRM_FILEDELETE, MB_ICONWARNING | MB_DEFBUTTON2 | MB_YESNO, 0)) return TRUE; - SetRedraw(FALSE); + SetRedraw(false); bool bRemovedItems = false; while (!selectedList.IsEmpty()) { CShareableFile *myfile = selectedList.RemoveHead(); @@ -956,16 +946,16 @@ BOOL CSharedFilesCtrl::OnCommand(WPARAM wParam, LPARAM) theApp.emuledlg->transferwnd->GetDownloadList()->ClearCompleted(static_cast(myfile)); } else { CString strError; - strError.Format(GetResString(IDS_ERR_DELFILE) + _T("\r\n\r\n%s"), (LPCTSTR)myfile->GetFilePath(), (LPCTSTR)GetErrorMessage(GetLastError())); + strError.Format(GetResString(IDS_ERR_DELFILE), (LPCTSTR)myfile->GetFilePath()); + strError.AppendFormat(_T("\r\n\r\n%s"), (LPCTSTR)GetErrorMessage(GetLastError())); AfxMessageBox(strError); } } - SetRedraw(TRUE); + SetRedraw(true); if (bRemovedItems) { AutoSelectItem(); - // Depending on this does not always cause a - // LVN_ITEMACTIVATE message sent. So, explicitly redraw - // the item. + // Depending on this does not always cause an LVN_ITEMACTIVATE + // message to be sent. So, explicitly redraw the item. theApp.emuledlg->sharedfileswnd->ShowSelectedFilesDetails(); theApp.emuledlg->sharedfileswnd->OnSingleFileShareStatusChanged(); // might have been a single shared file } @@ -973,7 +963,7 @@ BOOL CSharedFilesCtrl::OnCommand(WPARAM wParam, LPARAM) break; case MP_UNSHAREFILE: { - SetRedraw(FALSE); + SetRedraw(false); bool bUnsharedItems = false; while (!selectedList.IsEmpty()) { const CShareableFile *myfile = selectedList.RemoveHead(); @@ -984,7 +974,7 @@ BOOL CSharedFilesCtrl::OnCommand(WPARAM wParam, LPARAM) ASSERT(bUnsharedItems); } } - SetRedraw(TRUE); + SetRedraw(true); if (bUnsharedItems) { theApp.emuledlg->sharedfileswnd->ShowSelectedFilesDetails(); theApp.emuledlg->sharedfileswnd->OnSingleFileShareStatusChanged(); @@ -1097,12 +1087,10 @@ BOOL CSharedFilesCtrl::OnCommand(WPARAM wParam, LPARAM) void CSharedFilesCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) { - NMLISTVIEW *pNMListView = reinterpret_cast(pNMHDR); + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); bool sortAscending; - if (GetSortItem() == pNMListView->iSubItem) - sortAscending = !GetSortAscending(); - else - switch (pNMListView->iSubItem) { + if (GetSortItem() != pNMLV->iSubItem) + switch (pNMLV->iSubItem) { case 3: // Priority case 5: // Requests case 6: // Accepted Requests @@ -1115,31 +1103,33 @@ void CSharedFilesCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) default: sortAscending = true; } + else + sortAscending = !GetSortAscending(); // Ornis 4-way-sorting int adder = 0; - if (pNMListView->iSubItem >= 5 && pNMListView->iSubItem <= 7) { // 5=IDS_SF_REQUESTS, 6=IDS_SF_ACCEPTS, 7=IDS_SF_TRANSFERRED - ASSERT(pNMListView->iSubItem - 5 < _countof(m_aSortBySecondValue)); - if (GetSortItem() == pNMListView->iSubItem && !sortAscending) // check for 'descending' because the initial sort order is also 'descending' - m_aSortBySecondValue[pNMListView->iSubItem - 5] = !m_aSortBySecondValue[pNMListView->iSubItem - 5]; - adder = m_aSortBySecondValue[pNMListView->iSubItem - 5] ? 100 : 0; - } else if (pNMListView->iSubItem == 11) { // 11=IDS_SHAREDTITLE + if (pNMLV->iSubItem >= 5 && pNMLV->iSubItem <= 7) { // 5=IDS_SF_REQUESTS, 6=IDS_SF_ACCEPTS, 7=IDS_SF_TRANSFERRED + ASSERT(pNMLV->iSubItem - 5 < _countof(m_aSortBySecondValue)); + if (GetSortItem() == pNMLV->iSubItem && !sortAscending) // check for 'descending' because the initial sort order is also 'descending' + m_aSortBySecondValue[pNMLV->iSubItem - 5] = !m_aSortBySecondValue[pNMLV->iSubItem - 5]; + if (m_aSortBySecondValue[pNMLV->iSubItem - 5]) + adder = 100; + } else if (pNMLV->iSubItem == 11) { // 11=IDS_SHAREDTITLE ASSERT(3 < _countof(m_aSortBySecondValue)); - if (GetSortItem() == pNMListView->iSubItem && !sortAscending) // check for 'descending' because the initial sort order is also 'descending' + if (GetSortItem() == pNMLV->iSubItem && !sortAscending) // check for 'descending' because the initial sort order is also 'descending' m_aSortBySecondValue[3] = !m_aSortBySecondValue[3]; - adder = m_aSortBySecondValue[3] ? 100 : 0; + if (m_aSortBySecondValue[3]) + adder = 100; } // Sort table if (adder == 0) - SetSortArrow(pNMListView->iSubItem, sortAscending); + SetSortArrow(pNMLV->iSubItem, sortAscending); else - SetSortArrow(pNMListView->iSubItem, sortAscending ? arrowDoubleUp : arrowDoubleDown); - if (!sortAscending) - adder += 20; - UpdateSortHistory(pNMListView->iSubItem + adder, 20); - SortItems(SortProc, pNMListView->iSubItem + adder); + SetSortArrow(pNMLV->iSubItem, sortAscending ? arrowDoubleUp : arrowDoubleDown); + UpdateSortHistory(MAKELONG(pNMLV->iSubItem + adder, !sortAscending)); + SortItems(SortProc, MAKELONG(pNMLV->iSubItem + adder, !sortAscending)); *pResult = 0; } @@ -1148,29 +1138,24 @@ int CALLBACK CSharedFilesCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM l const CShareableFile *item1 = reinterpret_cast(lParam1); const CShareableFile *item2 = reinterpret_cast(lParam2); - bool bSortAscending; - if (lParamSort >= 100) - bSortAscending = lParamSort < 120; - else - bSortAscending = lParamSort < 20; - LPARAM iColumn = bSortAscending ? lParamSort : lParamSort - 20; + bool bSortAscending = !HIWORD(lParamSort); int iResult = 0; bool bExtColumn = false; - switch (iColumn) { + switch (LOWORD(lParamSort)) { case 0: //file name iResult = CompareLocaleStringNoCase(item1->GetFileName(), item2->GetFileName()); break; case 1: //file size - iResult = CompareUnsigned64(item1->GetFileSize(), item2->GetFileSize()); + iResult = CompareUnsigned(item1->GetFileSize(), item2->GetFileSize()); break; case 2: //file type iResult = item1->GetFileTypeDisplayStr().Compare(item2->GetFileTypeDisplayStr()); // if the type is equal, sub-sort by extension if (iResult == 0) { - LPCTSTR pszExt1 = PathFindExtension(item1->GetFileName()); - LPCTSTR pszExt2 = PathFindExtension(item2->GetFileName()); + LPCTSTR pszExt1 = ::PathFindExtension(item1->GetFileName()); + LPCTSTR pszExt2 = ::PathFindExtension(item2->GetFileName()); if (!*pszExt1 ^ !*pszExt2) iResult = *pszExt1 ? -1 : 1; else @@ -1193,7 +1178,7 @@ int CALLBACK CSharedFilesCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM l const CKnownFile *kitem1 = static_cast(item1); const CKnownFile *kitem2 = static_cast(item2); - switch (iColumn) { + switch (LOWORD(lParamSort)) { case 3: //prio { uint8 p1 = kitem1->GetUpPriority() + 1; @@ -1211,11 +1196,11 @@ int CALLBACK CSharedFilesCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM l case 5: //requests iResult = CompareUnsigned(kitem1->statistic.GetRequests(), kitem2->statistic.GetRequests()); break; - case 6: //acc requests + case 6: //accepted requests iResult = CompareUnsigned(kitem1->statistic.GetAccepts(), kitem2->statistic.GetAccepts()); break; case 7: //all transferred - iResult = CompareUnsigned64(kitem1->statistic.GetTransferred(), kitem2->statistic.GetTransferred()); + iResult = CompareUnsigned(kitem1->statistic.GetTransferred(), kitem2->statistic.GetTransferred()); break; case 10: //complete sources iResult = CompareUnsigned(kitem1->m_nCompleteSourcesCount, kitem2->m_nCompleteSourcesCount); @@ -1249,30 +1234,26 @@ int CALLBACK CSharedFilesCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM l iResult = CompareUnsigned(kitem1->statistic.GetAllTimeAccepts(), kitem2->statistic.GetAllTimeAccepts()); break; case 107: //all transferred - iResult = CompareUnsigned64(kitem1->statistic.GetAllTimeTransferred(), kitem2->statistic.GetAllTimeTransferred()); + iResult = CompareUnsigned(kitem1->statistic.GetAllTimeTransferred(), kitem2->statistic.GetAllTimeTransferred()); break; case 111: //kad shared { time_t tNow = time(NULL); - int i2 = static_cast(tNow < kitem2->GetLastPublishTimeKadSrc()); int i1 = static_cast(tNow < kitem1->GetLastPublishTimeKadSrc()); + int i2 = static_cast(tNow < kitem2->GetLastPublishTimeKadSrc()); iResult = i1 - i2; } } } } - if (!bSortAscending) - iResult = -iResult; - - //call secondary sort order, if this one results in equal + //call secondary sort order, if the first one resulted as equal if (iResult == 0) { - int dwNextSort = theApp.emuledlg->sharedfileswnd->sharedfilesctrl.GetNextSortOrder((int)lParamSort); - if (dwNextSort != -1) - iResult = SortProc(lParam1, lParam2, dwNextSort); + LPARAM iNextSort = theApp.emuledlg->sharedfileswnd->sharedfilesctrl.GetNextSortOrder(lParamSort); + if (iNextSort != -1) + return SortProc(lParam1, lParam2, iNextSort); } - - return iResult; + return bSortAscending ? iResult : -iResult; } void CSharedFilesCtrl::OpenFile(const CShareableFile *file) @@ -1376,16 +1357,16 @@ void CSharedFilesCtrl::ShowComments(CShareableFile *file) void CSharedFilesCtrl::OnLvnGetDispInfo(LPNMHDR pNMHDR, LRESULT *pResult) { if (!theApp.IsClosing()) { - // Although we have an owner drawn listview control we store the text for the primary item in the listview, to be - // capable of quick searching those items via the keyboard. Because our listview items may change their contents, - // we do this via a text callback function. The listview control will send us the LVN_DISPINFO notification if - // it needs to know the contents of the primary item. + // Although we have an owner drawn listview control we store the text for the primary item in the + // listview, to be capable of quick searching those items via the keyboard. Because our listview + // items may change their contents, we do this via a text callback function. The listview control + // will send us the LVN_DISPINFO notification if it needs to know the contents of the primary item. // - // But, the listview control sends this notification all the time, even if we do not search for an item. At least - // this notification is only sent for the visible items and not for all items in the list. Though, because this - // function is invoked *very* often, do *NOT* put any time consuming code in here. + // But, the listview control sends this notification all the time, even if we do not search for an item. + // At least this notification is only sent for the visible items and not for all items in the list. + // Though, because this function is invoked *very* often, do *NOT* put any time consuming code in here. // - // Vista: That callback is used to get the strings for the label tips for the sub(!) items. + // Vista: That callback is used to get the strings for the label tips for the sub(!)-items. // const LVITEMW &rItem = reinterpret_cast(pNMHDR)->item; if (rItem.mask & LVIF_TEXT) { @@ -1409,7 +1390,7 @@ void CSharedFilesCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) else if (nChar == VK_SPACE && CheckBoxesEnabled()) { // Toggle Checkboxes // selection and item position might change during processing (shouldn't though, but lets make sure), so first get all pointers instead using the selection pos directly - SetRedraw(FALSE); + SetRedraw(false); CTypedPtrList selectedList; for (POSITION pos = GetFirstSelectedItemPosition(); pos != NULL;) { int index = GetNextSelectedItem(pos); @@ -1419,7 +1400,7 @@ void CSharedFilesCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) while (!selectedList.IsEmpty()) CheckBoxClicked(FindFile(selectedList.RemoveHead())); - SetRedraw(TRUE); + SetRedraw(true); } CMuleListCtrl::OnKeyDown(nChar, nRepCnt, nFlags); @@ -1457,7 +1438,7 @@ void CSharedFilesCtrl::OnLvnGetInfoTip(LPNMHDR pNMHDR, LRESULT *pResult) const CShareableFile *pFile = reinterpret_cast(GetItemData(pGetInfoTip->iItem)); if (pFile && pGetInfoTip->pszText && pGetInfoTip->cchTextMax > 0) { - CString strInfo = pFile->GetInfoSummary(); + CString strInfo(pFile->GetInfoSummary()); strInfo += TOOLTIP_AUTOFORMAT_SUFFIX_CH; _tcsncpy(pGetInfoTip->pszText, strInfo, pGetInfoTip->cchTextMax); pGetInfoTip->pszText[pGetInfoTip->cchTextMax - 1] = _T('\0'); @@ -1466,12 +1447,12 @@ void CSharedFilesCtrl::OnLvnGetInfoTip(LPNMHDR pNMHDR, LRESULT *pResult) *pResult = 0; } -bool CSharedFilesCtrl::IsFilteredItem(const CShareableFile *pFile) const +bool CSharedFilesCtrl::IsFilteredOut(const CShareableFile *pFile) const { const CStringArray &rastrFilter = theApp.emuledlg->sharedfileswnd->m_astrFilter; if (!rastrFilter.IsEmpty()) { // filtering is done by text only for all columns to keep it consistent and simple for the user - // even if that doesn't allows complex filters + // even if that doesn't allow complex filters const CString &szFilterTarget(GetItemDisplayText(pFile, theApp.emuledlg->sharedfileswnd->GetFilterColumn())); for (INT_PTR i = rastrFilter.GetCount(); --i >= 0;) { @@ -1507,25 +1488,23 @@ bool CSharedFilesCtrl::IsSharedInKad(const CKnownFile *file) const void CSharedFilesCtrl::AddShareableFiles(const CString &strFromDir) { - while (!liTempShareableFilesInDir.IsEmpty()) // cleanup old file list + while (!liTempShareableFilesInDir.IsEmpty()) // clear old file list delete liTempShareableFilesInDir.RemoveHead(); - CString strSearchPath(strFromDir); - PathAddBackslash(strSearchPath.GetBuffer(strFromDir.GetLength() + 1)); - strSearchPath.ReleaseBuffer(); + ASSERT(strFromDir.Right(1) == _T("\\")); CFileFind ff; - bool end = !ff.FindFile(strSearchPath + _T('*'), 0); - if (end) { + BOOL bFound = ff.FindFile(strFromDir + _T('*')); + if (!bFound) { DWORD dwError = ::GetLastError(); if (dwError != ERROR_FILE_NOT_FOUND) DebugLogError(_T("Failed to find files for SharedFilesListCtrl in %s, %s"), (LPCTSTR)strFromDir, (LPCTSTR)GetErrorMessage(dwError)); return; } - SetRedraw(FALSE); - while (!end) { - end = !ff.FindNextFile(); - if (ff.IsDirectory() || ff.IsDots() || ff.IsSystem() || ff.IsTemporary() || ff.GetLength() == 0 || ff.GetLength() > MAX_EMULE_FILE_SIZE) + SetRedraw(false); + do { + bFound = ff.FindNextFile(); + if (ff.IsDirectory() || ff.IsSystem() || ff.IsTemporary() || ff.GetLength() == 0 || ff.GetLength() > MAX_EMULE_FILE_SIZE) continue; const CString &strFoundFileName(ff.GetFileName()); @@ -1538,26 +1517,13 @@ void CSharedFilesCtrl::AddShareableFiles(const CString &strFromDir) // ignore real(!) LNK files if (ExtensionIs(strFoundFileName, _T(".lnk"))) { SHFILEINFO info; - if (SHGetFileInfo(strFoundFilePath, 0, &info, sizeof info, SHGFI_ATTRIBUTES) && (info.dwAttributes & SFGAO_LINK)) + if (::SHGetFileInfo(strFoundFilePath, 0, &info, sizeof info, SHGFI_ATTRIBUTES) && (info.dwAttributes & SFGAO_LINK)) continue; } // ignore real(!) thumbs.db files -- seems that lot of ppl have 'thumbs.db' files without the 'System' file attribute - if (strFoundFileName.CompareNoCase(_T("thumbs.db")) == 0) { - // if that's a valid 'Storage' file, we declare it as a "thumbs.db" file. - CComPtr pStorage; - if (StgOpenStorage(strFoundFilePath, NULL, STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &pStorage) == S_OK) { - CComPtr pEnumSTATSTG; - if (SUCCEEDED(pStorage->EnumElements(0, NULL, 0, &pEnumSTATSTG))) { - STATSTG statstg = {}; - if (pEnumSTATSTG->Next(1, &statstg, 0) == S_OK) { - CoTaskMemFree(statstg.pwcsName); - statstg.pwcsName = NULL; - continue; - } - } - } - } + if (IsThumbsDb(strFoundFilePath, strFoundFileName)) + continue; time_t fdate = (time_t)FileTimeToUnixTime(tFoundFileTime); if (fdate == 0) @@ -1580,14 +1546,13 @@ void CSharedFilesCtrl::AddShareableFiles(const CString &strFromDir) pNewTempFile->SetFileName(strFoundFileName); pNewTempFile->SetPath(strFoundDirectory); pNewTempFile->SetFileSize(ullFoundFileSize); - uchar aucMD4[16] = {}; + uchar aucMD4[MDX_DIGEST_SIZE] = {}; pNewTempFile->SetFileHash(aucMD4); liTempShareableFilesInDir.AddTail(pNewTempFile); AddFile(pNewTempFile); } - } - SetRedraw(TRUE); - ff.Close(); + } while (bFound); + SetRedraw(true); } BOOL CSharedFilesCtrl::OnNMClick(LPNMHDR pNMHDR, LRESULT *pResult) @@ -1604,7 +1569,7 @@ BOOL CSharedFilesCtrl::OnNMClick(LPNMHDR pNMHDR, LRESULT *pResult) ASSERT(rcItem.PtInRect(pointHit)); rcItem.left += sm_iIconOffset; rcItem.right = rcItem.left + 16; - rcItem.top += (rcItem.Height() > 16) ? ((rcItem.Height() - 16) / 2) : 0; + rcItem.top += (rcItem.Height() > 16) ? ((rcItem.Height() - 15) / 2) : 0; rcItem.bottom = rcItem.top + 16; if (rcItem.PtInRect(pointHit)) { // user clicked on the checkbox @@ -1627,7 +1592,7 @@ void CSharedFilesCtrl::CheckBoxClicked(int iItem) // check which state the checkbox (should) currently have const CShareableFile *pFile = reinterpret_cast(GetItemData(iItem)); if (pFile->IsShellLinked()) - return; // no interacting with shelllinked files + return; // no interacting with shell-linked files if (theApp.sharedfiles->ShouldBeShared(pFile->GetPath(), pFile->GetFilePath(), false)) { // this is currently shared so unshare it if (theApp.sharedfiles->ShouldBeShared(pFile->GetPath(), pFile->GetFilePath(), true)) @@ -1666,7 +1631,7 @@ void CSharedFilesCtrl::OnMouseMove(UINT nFlags, CPoint point) ASSERT(rcItem.PtInRect(point)); rcItem.left += sm_iIconOffset; rcItem.right = rcItem.left + 16; - rcItem.top += (rcItem.Height() > 16) ? ((rcItem.Height() - 16) / 2) : 0; + rcItem.top += (rcItem.Height() > 16) ? ((rcItem.Height() - 15) / 2) : 0; rcItem.bottom = rcItem.top + 16; if (rcItem.PtInRect(point)) { // is this checkbox already hot? @@ -1728,38 +1693,37 @@ BOOL CSharedFilesCtrl::CShareDropTarget::OnDrop(CWnd*, COleDataObject *pDataObje { HGLOBAL hGlobal = pDataObject->GetGlobalData(CF_HDROP); if (hGlobal != NULL) { - HDROP hDrop = (HDROP)GlobalLock(hGlobal); + HDROP hDrop = (HDROP)::GlobalLock(hGlobal); if (hDrop != NULL) { CString strFilePath; CFileFind ff; - CStringList liToAddFiles; // all files too add + CStringList liToAddFiles; // all files to add CStringList liToAddDirs; // all directories to add - bool bFromSingleDirectory = true; // are all files from within the same directory - CString strSingleDirectory; // which would be this one + bool bFromSingleDirectory = true; // all files are in the same directory, + CString strSingleDirectory; // which would be this one UINT nFileCount = DragQueryFile(hDrop, UINT_MAX, NULL, 0); for (UINT nFile = 0; nFile < nFileCount; ++nFile) { if (DragQueryFile(hDrop, nFile, strFilePath.GetBuffer(MAX_PATH), MAX_PATH) > 0) { strFilePath.ReleaseBuffer(); - if (ff.FindFile(strFilePath, 0)) { + if (ff.FindFile(strFilePath)) { ff.FindNextFile(); CString ffpath(ff.GetFilePath()); - // just a quick pre check, complete check is done later in the share function itself + if (ff.IsDirectory()) + slosh(ffpath); + // just a quick pre-check, complete check is done later in the share function itself if (ff.IsDots() || ff.IsSystem() || ff.IsTemporary() - || (!ff.IsDirectory() && (ff.GetLength() == 0 || ff.GetLength() > MAX_EMULE_FILE_SIZE)) - || (ff.IsDirectory() && !thePrefs.IsShareableDirectory(ffpath + _T('\\'))) - || (ff.IsDirectory() && theApp.sharedfiles->ShouldBeShared(ffpath + _T('\\'), _T(""), false)) - || (!ff.IsDirectory() && theApp.sharedfiles->ShouldBeShared(ffpath, ffpath.Left(ffpath.ReverseFind(_T('\\')) + 1), false))) + || (!ff.IsDirectory() && (ff.GetLength() == 0 || ff.GetLength() > MAX_EMULE_FILE_SIZE + || theApp.sharedfiles->ShouldBeShared(ffpath.Left(ffpath.ReverseFind(_T('\\'))), ffpath, false))) + || (ff.IsDirectory() && (!thePrefs.IsShareableDirectory(ffpath) + || theApp.sharedfiles->ShouldBeShared(ffpath, NULL, false)))) { DebugLog(_T("Drag&Drop'ed shared File ignored (%s)"), (LPCTSTR)ffpath); - ff.Close(); - continue; - } - if (ff.IsDirectory()) { - DEBUG_ONLY(DebugLog(_T("Drag'n'Drop'ed directory: %s\\"), (LPCTSTR)ffpath)); - liToAddDirs.AddTail(ffpath + _T('\\')); + } else if (ff.IsDirectory()) { + DEBUG_ONLY(DebugLog(_T("Drag&Drop'ed directory: %s"), (LPCTSTR)ffpath)); + liToAddDirs.AddTail(ffpath); } else { - DEBUG_ONLY(DebugLog(_T("Drag'n'Drop'ed file: %s"), (LPCTSTR)ffpath)); + DEBUG_ONLY(DebugLog(_T("Drag&Drop'ed file: %s"), (LPCTSTR)ffpath)); liToAddFiles.AddTail(ffpath); if (bFromSingleDirectory) { if (strSingleDirectory.IsEmpty()) @@ -1772,16 +1736,16 @@ BOOL CSharedFilesCtrl::CShareDropTarget::OnDrop(CWnd*, COleDataObject *pDataObje DebugLogError(_T("Drag&Drop'ed shared File not found (%s)"), (LPCTSTR)strFilePath); ff.Close(); - } else { ASSERT(0); strFilePath.ReleaseBuffer(); } } + if (!liToAddFiles.IsEmpty() || !liToAddDirs.IsEmpty()) { - // add the directories first as they could - // make single file adds invalid if they are contained in one of those dirs already - for (POSITION pos = liToAddDirs.GetHeadPosition(); pos != NULL; ) + // add the directories first as this would invalidate addition of + // single files, contained in one of those dirs + for (POSITION pos = liToAddDirs.GetHeadPosition(); pos != NULL;) VERIFY(theApp.sharedfiles->AddSingleSharedDirectory(liToAddDirs.GetNext(pos))); // should always succeed bool bHaveFiles = false; @@ -1801,18 +1765,16 @@ BOOL CSharedFilesCtrl::CShareDropTarget::OnDrop(CWnd*, COleDataObject *pDataObje VERIFY(theApp.emuledlg->sharedfileswnd->m_ctlSharedDirTree.ShowFileSystemDirectory(strSingleDirectory)); } else if (!liToAddDirs.IsEmpty() && !bHaveFiles) { // only directories added, if only one select the specific shared dir, otherwise the Shared Directories section - if (liToAddDirs.GetCount() == 1) - theApp.emuledlg->sharedfileswnd->m_ctlSharedDirTree.ShowSharedDirectory(liToAddDirs.GetHead()); - else - theApp.emuledlg->sharedfileswnd->m_ctlSharedDirTree.ShowSharedDirectory(_T("")); + const CString &sShow(liToAddDirs.GetCount() == 1 ? liToAddDirs.GetHead() : _T("")); + theApp.emuledlg->sharedfileswnd->m_ctlSharedDirTree.ShowSharedDirectory(sShow); } else { // otherwise select the All Shared Files category theApp.emuledlg->sharedfileswnd->m_ctlSharedDirTree.ShowAllSharedFiles(); } } - GlobalUnlock(hGlobal); + ::GlobalUnlock(hGlobal); } - GlobalFree(hGlobal); + ::GlobalFree(hGlobal); } if (m_bUseDnDHelper) { diff --git a/srchybrid/SharedFilesCtrl.h b/srchybrid/SharedFilesCtrl.h index 364ed99f..848d5e01 100644 --- a/srchybrid/SharedFilesCtrl.h +++ b/srchybrid/SharedFilesCtrl.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -85,7 +85,7 @@ class CSharedFilesCtrl : public CMuleListCtrl, public CListCtrlItemWalk void SetAllIcons(); int FindFile(const CShareableFile *pFile); CString GetItemDisplayText(const CShareableFile *file, int iSubItem) const; - bool IsFilteredItem(const CShareableFile *pKnownFile) const; + bool IsFilteredOut(const CShareableFile *pKnownFile) const; bool IsSharedInKad(const CKnownFile *file) const; void AddShareableFiles(const CString &strFromDir); void CheckBoxClicked(int iItem); diff --git a/srchybrid/SharedFilesWnd.cpp b/srchybrid/SharedFilesWnd.cpp index 7b1290b9..5c737e25 100644 --- a/srchybrid/SharedFilesWnd.cpp +++ b/srchybrid/SharedFilesWnd.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -114,7 +114,6 @@ BOOL CSharedFilesWnd::OnInitDialog() AddAnchor(m_ctlSharedDirTree, TOP_LEFT, BOTTOM_LEFT); AddAnchor(IDC_RELOADSHAREDFILES, TOP_RIGHT); - AddAllOtherAnchors(); int iPosStatInit = rcSpl.left; @@ -125,10 +124,8 @@ BOOL CSharedFilesWnd::OnInitDialog() iPosStatNew = SPLITTER_RANGE_MIN; rcSpl.left = iPosStatNew; rcSpl.right = iPosStatNew + SPLITTER_WIDTH; - if (iPosStatNew != iPosStatInit) { - m_wndSplitter.MoveWindow(&rcSpl); - DoResize(iPosStatNew - iPosStatInit); - } + m_wndSplitter.MoveWindow(&rcSpl); + DoResize(iPosStatNew - iPosStatInit); GetDlgItem(IDC_SF_HIDESHOWDETAILS)->SetFont(&theApp.m_fontSymbol); GetDlgItem(IDC_SF_HIDESHOWDETAILS)->BringWindowToTop(); @@ -157,17 +154,29 @@ void CSharedFilesWnd::DoResize(int iDelta) ScreenToClient(&rcSpl); thePrefs.SetSplitterbarPositionShared(rcSpl.left); + RemoveAnchor(m_ctlFilter); RemoveAnchor(m_wndSplitter); - AddAnchor(m_wndSplitter, TOP_LEFT); - RemoveAnchor(sharedfilesctrl); RemoveAnchor(m_ctlSharedDirTree); - RemoveAnchor(m_ctlFilter); + RemoveAnchor(sharedfilesctrl); RemoveAnchor(m_dlgDetails); + RemoveAnchor(IDC_SF_FICON); + RemoveAnchor(IDC_SF_FNAME); + + GetDlgItem(IDC_SF_FICON)->SetWindowPos(NULL, rcSpl.right + 6, rcSpl.bottom - 18, 0, 0, SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE); + CWnd *wname = GetDlgItem(IDC_SF_FNAME); + RECT rcfname; + wname->GetWindowRect(&rcfname); + ScreenToClient(&rcfname); + rcfname.left += iDelta; + wname->MoveWindow(&rcfname); - AddAnchor(sharedfilesctrl, TOP_LEFT, BOTTOM_RIGHT); - AddAnchor(m_ctlSharedDirTree, TOP_LEFT, BOTTOM_LEFT); AddAnchor(m_ctlFilter, TOP_LEFT); + AddAnchor(m_ctlSharedDirTree, TOP_LEFT, BOTTOM_LEFT); + AddAnchor(m_wndSplitter, TOP_LEFT, BOTTOM_LEFT); + AddAnchor(sharedfilesctrl, TOP_LEFT, BOTTOM_RIGHT); AddAnchor(m_dlgDetails, BOTTOM_LEFT, BOTTOM_RIGHT); + AddAnchor(IDC_SF_FICON, BOTTOM_LEFT); + AddAnchor(IDC_SF_FNAME, BOTTOM_LEFT, BOTTOM_RIGHT); RECT rcWnd; GetWindowRect(&rcWnd); @@ -178,7 +187,6 @@ void CSharedFilesWnd::DoResize(int iDelta) UpdateWindow(); } - void CSharedFilesWnd::Reload(bool bForceTreeReload) { sharedfilesctrl.SetDirectoryFilter(NULL, false); @@ -242,7 +250,7 @@ BOOL CSharedFilesWnd::PreTranslateMessage(MSG *pMsg) return FALSE; sharedfilesctrl.ScreenToClient(&point); int it = sharedfilesctrl.HitTest(point); - if (it == -1) + if (it < 0) return FALSE; sharedfilesctrl.SetItemState(-1, 0, LVIS_SELECTED); @@ -333,7 +341,7 @@ LRESULT CSharedFilesWnd::OnChangeFilter(WPARAM wParam, LPARAM lParam) m_nFilterColumn = (uint32)wParam; CStringArray astrFilter; - CString strFullFilterExpr((LPCTSTR)lParam); + const CString &strFullFilterExpr((LPCTSTR)lParam); for (int iPos = 0; iPos >= 0;) { const CString &strFilter(strFullFilterExpr.Tokenize(_T(" "), iPos)); if (!strFilter.IsEmpty() && strFilter != _T("-")) @@ -392,6 +400,19 @@ void CSharedFilesWnd::ShowSelectedFilesDetails(bool bForce) } } } + } else if (GetDlgItem(IDC_SF_FNAME)->IsWindowVisible()) { + CShareableFile *pFile = NULL; + if (sharedfilesctrl.GetSelectedCount() == 1) { + POSITION pos = sharedfilesctrl.GetFirstSelectedItemPosition(); + if (pos) { + int index = sharedfilesctrl.GetNextSelectedItem(pos); + if (index >= 0) + pFile = reinterpret_cast(sharedfilesctrl.GetItemData(index)); + } + } + static_cast(GetDlgItem(IDC_SF_FICON))->SetIcon(pFile ? icon_files : NULL); + const CString &sName(pFile ? pFile->GetFileName() : _T("")); + SetDlgItemText(IDC_SF_FNAME, sName); } if (bForce || nItems != (UINT)selectedList.GetCount()) m_dlgDetails.SetFiles(selectedList); @@ -404,36 +425,40 @@ void CSharedFilesWnd::ShowDetailsPanel(bool bShow) RemoveAnchor(sharedfilesctrl); RemoveAnchor(IDC_SF_HIDESHOWDETAILS); - RECT rcSpl; - CRect rcFiles, rcDetailDlg, rcButton; - + CRect rcFiles; sharedfilesctrl.GetWindowRect(rcFiles); ScreenToClient(rcFiles); + CRect rcDetailDlg; m_dlgDetails.GetWindowRect(rcDetailDlg); CWnd &button = *GetDlgItem(IDC_SF_HIDESHOWDETAILS); + CRect rcButton; button.GetWindowRect(rcButton); - m_ctlSharedDirTree.GetWindowRect(&rcSpl); + RECT rcSpl; + m_wndSplitter.GetWindowRect(&rcSpl); ScreenToClient(&rcSpl); - button.GetWindowRect(rcButton); if (bShow) { sharedfilesctrl.SetWindowPos(NULL, 0, 0, rcFiles.Width(), rcSpl.bottom - rcFiles.top - rcDetailDlg.Height() - 2, SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE); m_dlgDetails.ShowWindow(SW_SHOW); + GetDlgItem(IDC_SF_FICON)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_SF_FNAME)->ShowWindow(SW_HIDE); button.SetWindowPos(NULL, rcFiles.right - rcButton.Width() + 1, rcSpl.bottom - rcDetailDlg.Height() + 2, 0, 0, SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE); button.SetWindowText(_T("6")); } else { m_dlgDetails.ShowWindow(SW_HIDE); sharedfilesctrl.SetWindowPos(NULL, 0, 0, rcFiles.Width(), rcSpl.bottom - rcFiles.top - rcButton.Height() + 1, SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE); + GetDlgItem(IDC_SF_FICON)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_SF_FNAME)->ShowWindow(SW_SHOW); button.SetWindowPos(NULL, rcFiles.right - rcButton.Width() + 1, rcSpl.bottom - rcButton.Height() + 1, 0, 0, SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOACTIVATE); button.SetWindowText(_T("5")); } - sharedfilesctrl.SetFocus(); AddAnchor(sharedfilesctrl, TOP_LEFT, BOTTOM_RIGHT); AddAnchor(IDC_SF_HIDESHOWDETAILS, BOTTOM_RIGHT); + sharedfilesctrl.SetFocus(); ShowSelectedFilesDetails(); } diff --git a/srchybrid/SharedFilesWnd.h b/srchybrid/SharedFilesWnd.h index e6fa8297..87367fc8 100644 --- a/srchybrid/SharedFilesWnd.h +++ b/srchybrid/SharedFilesWnd.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -35,7 +35,6 @@ class CSharedFileDetailsModelessSheet : public CListViewPropertySheet public: CSharedFileDetailsModelessSheet(); - virtual ~CSharedFileDetailsModelessSheet() = default; CSharedFileDetailsModelessSheet(const CSharedFileDetailsModelessSheet&) = delete; CSharedFileDetailsModelessSheet& operator=(const CSharedFileDetailsModelessSheet&) = delete; diff --git a/srchybrid/SmileySelector.cpp b/srchybrid/SmileySelector.cpp index ff158a8d..e5c0142a 100644 --- a/srchybrid/SmileySelector.cpp +++ b/srchybrid/SmileySelector.cpp @@ -1,6 +1,6 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/SmileySelector.h b/srchybrid/SmileySelector.h index 6ad11c57..fa2ff00e 100644 --- a/srchybrid/SmileySelector.h +++ b/srchybrid/SmileySelector.h @@ -1,6 +1,6 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -24,7 +24,6 @@ class CSmileySelector : public CWnd public: CSmileySelector(); - virtual ~CSmileySelector() = default; BOOL Create(CWnd *pWndParent, LPCRECT pRect, CEdit *pwndEdit); diff --git a/srchybrid/SplashScreen.cpp b/srchybrid/SplashScreen.cpp index aec4ff8b..f99c2cef 100644 --- a/srchybrid/SplashScreen.cpp +++ b/srchybrid/SplashScreen.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -111,7 +111,7 @@ void CSplashScreen::OnPaint() CFont font; font.CreateFontIndirect(&lf); CFont *pOldFont = dc.SelectObject(&font); - CString strAppVersion(_T("eMule ") + theApp.m_strCurVersionLong); + const CString &strAppVersion(_T("eMule ") + theApp.m_strCurVersionLong); rc.top += dc.DrawText(strAppVersion, &rc, DT_CENTER | DT_NOPREFIX); if (pOldFont) dc.SelectObject(pOldFont); @@ -125,7 +125,7 @@ void CSplashScreen::OnPaint() _tcscpy(lf.lfFaceName, _T("Arial")); font.CreateFontIndirect(&lf); pOldFont = dc.SelectObject(&font); - dc.DrawText(_T("Copyright (C) 2002-2021 Merkur"), &rc, DT_CENTER | DT_NOPREFIX); + dc.DrawText(_T("Copyright (C) 2002-2023 Merkur"), &rc, DT_CENTER | DT_NOPREFIX); if (pOldFont) dc.SelectObject(pOldFont); font.DeleteObject(); diff --git a/srchybrid/SplitterControl.cpp b/srchybrid/SplitterControl.cpp index e6f9acab..59cfa36e 100644 --- a/srchybrid/SplitterControl.cpp +++ b/srchybrid/SplitterControl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -192,7 +192,7 @@ void CSplitterControl::OnLButtonUp(UINT nFlags, CPoint point) } CStatic::OnLButtonUp(nFlags, point); - ReleaseCapture(); + ::ReleaseCapture(); } void CSplitterControl::DrawLine(CDC *pDC, int /*x*/, int /*y*/) diff --git a/srchybrid/SplitterControl.h b/srchybrid/SplitterControl.h index 9b4cf111..c91e510a 100644 --- a/srchybrid/SplitterControl.h +++ b/srchybrid/SplitterControl.h @@ -33,7 +33,6 @@ class CSplitterControl : public CStatic { public: CSplitterControl(); - virtual ~CSplitterControl() = default; void Create(DWORD dwStyle, const CRect &rect, CWnd *pParent, UINT nID); int GetStyle(); @@ -53,7 +52,7 @@ class CSplitterControl : public CStatic int m_nType; int m_nX, m_nY; int m_nMin, m_nMax; // Min and Max range of the splitter. - int m_nSavePos; // Save point on the lbutton down message + int m_nSavePos; // Save point of the lbutton down message bool m_bDrawBorder; void MoveWindowTo(CPoint pt); diff --git a/srchybrid/StatisticFile.cpp b/srchybrid/StatisticFile.cpp index 67bdd101..7ca500b0 100644 --- a/srchybrid/StatisticFile.cpp +++ b/srchybrid/StatisticFile.cpp @@ -1,6 +1,6 @@ // parts of this file are based on work from pan One (http://home-3.tiscali.nl/~meost/pms/) //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -41,7 +41,7 @@ void CStatisticFile::AddRequest() { ++requested; ++alltimerequested; - theApp.knownfiles->requested++; + ++theApp.knownfiles->requested; theApp.sharedfiles->UpdateFile(fileParent); } @@ -49,7 +49,7 @@ void CStatisticFile::AddAccepted() { ++accepted; ++alltimeaccepted; - theApp.knownfiles->accepted++; + ++theApp.knownfiles->accepted; theApp.sharedfiles->UpdateFile(fileParent); } diff --git a/srchybrid/StatisticFile.h b/srchybrid/StatisticFile.h index ec09e8cc..836c2e80 100644 --- a/srchybrid/StatisticFile.h +++ b/srchybrid/StatisticFile.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/Statistics.cpp b/srchybrid/Statistics.cpp index 726518b5..33845763 100644 --- a/srchybrid/Statistics.cpp +++ b/srchybrid/Statistics.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -30,7 +30,7 @@ static char THIS_FILE[] = __FILE__; extern _CRT_ALLOC_HOOK g_pfnPrevCrtAllocHook; #endif -#define MAXAVERAGETIME SEC2MS(40) //millisecs +#define MAXAVERAGETIME SEC2MS(40) /////////////////////////////////////////////////////////////////////////////// // CStatistics @@ -49,19 +49,19 @@ float CStatistics::maxUp; float CStatistics::maxUpavg; float CStatistics::rateDown; float CStatistics::rateUp; -uint32 CStatistics::timeTransfers; -uint32 CStatistics::timeDownloads; -uint32 CStatistics::timeUploads; -uint32 CStatistics::start_timeTransfers; -uint32 CStatistics::start_timeDownloads; -uint32 CStatistics::start_timeUploads; -uint32 CStatistics::time_thisTransfer; -uint32 CStatistics::time_thisDownload; -uint32 CStatistics::time_thisUpload; -uint32 CStatistics::timeServerDuration; -uint32 CStatistics::time_thisServerDuration; -uint32 CStatistics::m_nDownDatarateOverhead; -uint32 CStatistics::m_nDownDataRateMSOverhead; +DWORD CStatistics::timeTransfers; +DWORD CStatistics::timeDownloads; +DWORD CStatistics::timeUploads; +DWORD CStatistics::start_timeTransfers; +DWORD CStatistics::start_timeDownloads; +DWORD CStatistics::start_timeUploads; +DWORD CStatistics::time_thisTransfer; +DWORD CStatistics::time_thisDownload; +DWORD CStatistics::time_thisUpload; +DWORD CStatistics::timeServerDuration; +DWORD CStatistics::time_thisServerDuration; +uint64 CStatistics::m_nDownDatarateOverhead; +uint64 CStatistics::m_nDownDataRateMSOverhead; uint64 CStatistics::m_nDownDataOverheadSourceExchange; uint64 CStatistics::m_nDownDataOverheadSourceExchangePackets; uint64 CStatistics::m_nDownDataOverheadFileRequest; @@ -72,8 +72,8 @@ uint64 CStatistics::m_nDownDataOverheadKad; uint64 CStatistics::m_nDownDataOverheadKadPackets; uint64 CStatistics::m_nDownDataOverheadOther; uint64 CStatistics::m_nDownDataOverheadOtherPackets; -uint32 CStatistics::m_nUpDatarateOverhead; -uint32 CStatistics::m_nUpDataRateMSOverhead; +uint64 CStatistics::m_nUpDatarateOverhead; +uint64 CStatistics::m_nUpDataRateMSOverhead; uint64 CStatistics::m_nUpDataOverheadSourceExchange; uint64 CStatistics::m_nUpDataOverheadSourceExchangePackets; uint64 CStatistics::m_nUpDataOverheadFileRequest; @@ -84,8 +84,8 @@ uint64 CStatistics::m_nUpDataOverheadKad; uint64 CStatistics::m_nUpDataOverheadKadPackets; uint64 CStatistics::m_nUpDataOverheadOther; uint64 CStatistics::m_nUpDataOverheadOtherPackets; -uint32 CStatistics::m_sumavgDDRO; -uint32 CStatistics::m_sumavgUDRO; +uint64 CStatistics::m_sumavgDDRO; +uint64 CStatistics::m_sumavgUDRO; float CStatistics::m_fGlobalDone; float CStatistics::m_fGlobalSize; @@ -214,23 +214,24 @@ void CStatistics::UpdateConnectionStats(float uploadrate, float downloadrate) // Transfer Times (Increment Session) if (uploadrate > 0 || downloadrate > 0) { - if (start_timeTransfers == 0) - start_timeTransfers = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); + if (start_timeTransfers) + time_thisTransfer = (curTick - start_timeTransfers) / SEC2MS(1); else - time_thisTransfer = (::GetTickCount() - start_timeTransfers) / SEC2MS(1); + start_timeTransfers = curTick; if (uploadrate > 0) { - if (start_timeUploads == 0) - start_timeUploads = ::GetTickCount(); + if (start_timeUploads) + time_thisUpload = (curTick - start_timeUploads) / SEC2MS(1); else - time_thisUpload = (::GetTickCount() - start_timeUploads) / SEC2MS(1); + start_timeUploads = curTick; } if (downloadrate > 0) { - if (start_timeDownloads == 0) - start_timeDownloads = ::GetTickCount(); + if (start_timeDownloads) + time_thisDownload = (curTick - start_timeDownloads) / SEC2MS(1); else - time_thisDownload = (::GetTickCount() - start_timeDownloads) / SEC2MS(1); + start_timeDownloads = curTick; } } @@ -264,17 +265,20 @@ void CStatistics::RecordRate() if (theStats.transferStarttime == 0) return; - // Accurate data rate Calculation - const DWORD tick = ::GetTickCount(); - downrateHistory.push_front(TransferredData{(uint32)theStats.sessionReceivedBytes, tick}); - uprateHistory.push_front(TransferredData{(uint32)theStats.sessionSentBytes, tick}); - - // limit to maxmins - UINT uAverageMilliseconds = MIN2MS(thePrefs.GetStatsAverageMinutes()); - while (downrateHistory.front().timestamp - downrateHistory.back().timestamp > uAverageMilliseconds) - downrateHistory.pop_back(); - while (uprateHistory.front().timestamp - uprateHistory.back().timestamp > uAverageMilliseconds) - uprateHistory.pop_back(); + // Accurate data rate calculation + DWORD curTick = ::GetTickCount(); + downrateHistory.push_front(TransferredData{ theStats.sessionReceivedBytes, curTick }); + uprateHistory.push_front(TransferredData{ theStats.sessionSentBytes, curTick }); + + DWORD avg = MIN2MS(thePrefs.GetStatsAverageMinutes()); + if (curTick > avg) { + // limit to maxmins + curTick -= avg; + while (curTick > downrateHistory.back().timestamp) + downrateHistory.pop_back(); + while (curTick > uprateHistory.back().timestamp) + uprateHistory.pop_back(); + } } // Changed these two functions (khaos)... @@ -344,41 +348,53 @@ float CStatistics::GetAvgUploadRate(int averageType) void CStatistics::CompDownDatarateOverhead() { - m_AverageDDRO_list.AddTail(TransferredData{m_nDownDataRateMSOverhead, ::GetTickCount()}); + DWORD curTick = ::GetTickCount(); + + m_AverageDDRO_list.push_back(TransferredData{ m_nDownDataRateMSOverhead, curTick }); m_sumavgDDRO += m_nDownDataRateMSOverhead; m_nDownDataRateMSOverhead = 0; - while (m_AverageDDRO_list.GetTail().timestamp - m_AverageDDRO_list.GetHead().timestamp > MAXAVERAGETIME) - m_sumavgDDRO -= m_AverageDDRO_list.RemoveHead().datalen; + while (curTick > m_AverageDDRO_list.front().timestamp + MAXAVERAGETIME) { + m_sumavgDDRO -= m_AverageDDRO_list.front().datalen; + m_AverageDDRO_list.pop_front(); + } - if (m_AverageDDRO_list.GetCount() > 10) { - DWORD dwDuration = m_AverageDDRO_list.GetTail().timestamp - m_AverageDDRO_list.GetHead().timestamp; - if (dwDuration) - m_nDownDatarateOverhead = SEC2MS(m_sumavgDDRO - m_AverageDDRO_list.GetHead().datalen) / dwDuration; - } else - m_nDownDatarateOverhead = 0; + if (m_AverageDDRO_list.size() > 10) { + const TransferredData &head = m_AverageDDRO_list.front(); + if (curTick > head.timestamp) { + m_nDownDatarateOverhead = SEC2MS(m_sumavgDDRO - head.datalen) / (curTick - head.timestamp); + return; + } + } + m_nDownDatarateOverhead = 0; } void CStatistics::CompUpDatarateOverhead() { - m_AverageUDRO_list.AddTail(TransferredData{m_nUpDataRateMSOverhead, ::GetTickCount()}); + DWORD curTick = ::GetTickCount(); + + m_AverageUDRO_list.push_back(TransferredData{ m_nUpDataRateMSOverhead, curTick }); m_sumavgUDRO += m_nUpDataRateMSOverhead; m_nUpDataRateMSOverhead = 0; - while (m_AverageUDRO_list.GetTail().timestamp - m_AverageUDRO_list.GetHead().timestamp > MAXAVERAGETIME) - m_sumavgUDRO -= m_AverageUDRO_list.RemoveHead().datalen; + while (curTick > m_AverageUDRO_list.front().timestamp + MAXAVERAGETIME) { + m_sumavgUDRO -= m_AverageUDRO_list.front().datalen; + m_AverageUDRO_list.pop_front(); + } - if (m_AverageUDRO_list.GetCount() > 10) { - DWORD dwDuration = m_AverageUDRO_list.GetTail().timestamp - m_AverageUDRO_list.GetHead().timestamp; - if (dwDuration) - m_nUpDatarateOverhead = SEC2MS(m_sumavgUDRO - m_AverageUDRO_list.GetHead().datalen) / dwDuration; - } else - m_nUpDatarateOverhead = 0; + if (m_AverageUDRO_list.size() > 10) { + const TransferredData &head = m_AverageUDRO_list.front(); + if (curTick > head.timestamp) { + m_nUpDatarateOverhead = SEC2MS(m_sumavgUDRO - head.datalen) / (curTick - head.timestamp); + return; + } + } + m_nUpDatarateOverhead = 0; } void CStatistics::ResetDownDatarateOverhead() { - m_AverageDDRO_list.RemoveAll(); + m_AverageDDRO_list.clear(); m_nDownDataRateMSOverhead = 0; m_nDownDatarateOverhead = 0; m_sumavgDDRO = 0; @@ -386,7 +402,7 @@ void CStatistics::ResetDownDatarateOverhead() void CStatistics::ResetUpDatarateOverhead() { - m_AverageUDRO_list.RemoveAll(); + m_AverageUDRO_list.clear(); m_nUpDataRateMSOverhead = 0; m_nUpDatarateOverhead = 0; m_sumavgUDRO = 0; @@ -454,7 +470,7 @@ void* my_new(size_t n) if (i >= ALLOC_SLOTS) i = ALLOC_SLOTS - 1; } - g_aAllocStats[i]++; + ++g_aAllocStats[i]; void *pResult; for (;;) { diff --git a/srchybrid/Statistics.h b/srchybrid/Statistics.h index 3d5875ae..b65e7162 100644 --- a/srchybrid/Statistics.h +++ b/srchybrid/Statistics.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -68,8 +68,8 @@ class CStatistics static void AddDownDataOverheadKad(uint32 data) { m_nDownDataRateMSOverhead += data; m_nDownDataOverheadKad += data; ++m_nDownDataOverheadKadPackets; } - static void AddDownDataOverheadCrypt(uint32 /*data*/) {} - static uint32 GetDownDatarateOverhead() { return m_nDownDatarateOverhead; } + static void AddDownDataOverheadCrypt(uint32 /*data*/) {} + static uint64 GetDownDatarateOverhead() { return m_nDownDatarateOverhead; } static uint64 GetDownDataOverheadSourceExchange() { return m_nDownDataOverheadSourceExchange; } static uint64 GetDownDataOverheadFileRequest() { return m_nDownDataOverheadFileRequest; } static uint64 GetDownDataOverheadServer() { return m_nDownDataOverheadServer; } @@ -104,7 +104,7 @@ class CStatistics ++m_nUpDataOverheadOtherPackets; } static void AddUpDataOverheadCrypt(uint32 /*data*/) {} - static uint32 GetUpDatarateOverhead() { return m_nUpDatarateOverhead; } + static uint64 GetUpDatarateOverhead() { return m_nUpDatarateOverhead; } static uint64 GetUpDataOverheadSourceExchange() { return m_nUpDataOverheadSourceExchange; } static uint64 GetUpDataOverheadFileRequest() { return m_nUpDataOverheadFileRequest; } static uint64 GetUpDataOverheadServer() { return m_nUpDataOverheadServer; } @@ -130,17 +130,17 @@ class CStatistics static float maxUpavg; static float rateDown; static float rateUp; - static uint32 timeTransfers; - static uint32 timeDownloads; - static uint32 timeUploads; - static uint32 start_timeTransfers; - static uint32 start_timeDownloads; - static uint32 start_timeUploads; - static uint32 time_thisTransfer; - static uint32 time_thisDownload; - static uint32 time_thisUpload; - static uint32 timeServerDuration; - static uint32 time_thisServerDuration; + static DWORD timeTransfers; + static DWORD timeDownloads; + static DWORD timeUploads; + static DWORD start_timeTransfers; + static DWORD start_timeDownloads; + static DWORD start_timeUploads; + static DWORD time_thisTransfer; + static DWORD time_thisDownload; + static DWORD time_thisUpload; + static DWORD timeServerDuration; + static DWORD time_thisServerDuration; static DWORD m_dwOverallStatus; static float m_fGlobalDone; static float m_fGlobalSize; @@ -156,14 +156,14 @@ class CStatistics private: typedef struct { - uint32 datalen; + uint64 datalen; DWORD timestamp; } TransferredData; std::list uprateHistory; std::list downrateHistory; - static uint32 m_nDownDatarateOverhead; - static uint32 m_nDownDataRateMSOverhead; + static uint64 m_nDownDatarateOverhead; + static uint64 m_nDownDataRateMSOverhead; static uint64 m_nDownDataOverheadSourceExchange; static uint64 m_nDownDataOverheadSourceExchangePackets; static uint64 m_nDownDataOverheadFileRequest; @@ -175,8 +175,8 @@ class CStatistics static uint64 m_nDownDataOverheadOther; static uint64 m_nDownDataOverheadOtherPackets; - static uint32 m_nUpDatarateOverhead; - static uint32 m_nUpDataRateMSOverhead; + static uint64 m_nUpDatarateOverhead; + static uint64 m_nUpDataRateMSOverhead; static uint64 m_nUpDataOverheadSourceExchange; static uint64 m_nUpDataOverheadSourceExchangePackets; static uint64 m_nUpDataOverheadFileRequest; @@ -188,10 +188,10 @@ class CStatistics static uint64 m_nUpDataOverheadOther; static uint64 m_nUpDataOverheadOtherPackets; - static uint32 m_sumavgDDRO; - static uint32 m_sumavgUDRO; - CList m_AverageDDRO_list; - CList m_AverageUDRO_list; + static uint64 m_sumavgDDRO; + static uint64 m_sumavgUDRO; + std::list m_AverageDDRO_list; + std::list m_AverageUDRO_list; }; extern CStatistics theStats; diff --git a/srchybrid/StatisticsDlg.cpp b/srchybrid/StatisticsDlg.cpp index 318c20ea..71741112 100644 --- a/srchybrid/StatisticsDlg.cpp +++ b/srchybrid/StatisticsDlg.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -20,7 +20,7 @@ #include "UploadQueue.h" #include "Statistics.h" #include "emuledlg.h" -#include "OtherFunctions.h" +#include "UpDownClient.h" #include "WebServer.h" #include "DownloadQueue.h" #include "ClientList.h" @@ -28,7 +28,6 @@ #include "ListenSocket.h" #include "ServerList.h" #include "SharedFileList.h" -#include "UpDownClient.h" #include "UserMsgs.h" #include "HelpIDs.h" #include "Kademlia/Kademlia/kademlia.h" @@ -78,7 +77,6 @@ CStatisticsDlg::CStatisticsDlg(CWnd *pParent /*=NULL*/) CStatisticsDlg::~CStatisticsDlg() { delete m_TimeToolTips; - #ifdef _DEBUG for (POSITION pos = blockFiles.GetStartPosition(); pos != NULL;) { const unsigned char *fileName; @@ -124,7 +122,7 @@ void CStatisticsDlg::SetAllIcons() iml.Add(CTempIconLoader(_T("StatsDay"))); // Time > Averages and Projections > Daily iml.Add(CTempIconLoader(_T("StatsMonth"))); // Time > Averages and Projections > Monthly iml.Add(CTempIconLoader(_T("StatsYear"))); // Time > Averages and Projections > Yearly - iml.Add(CTempIconLoader(_T("HardDisk"))); // Diskspace + iml.Add(CTempIconLoader(_T("HardDisk"))); // Disk space m_stattree.SetImageList(&iml, TVSIL_NORMAL); imagelistStatTree.DeleteImageList(); imagelistStatTree.Attach(iml.Detach()); @@ -283,16 +281,16 @@ BOOL CStatisticsDlg::OnInitDialog() m_TimeToolTips = new CToolTipCtrl(); m_TimeToolTips->Create(this); - m_TimeToolTips->AddTool(GetDlgItem(IDC_SCOPE_D), _T(""), NULL, 0); - m_TimeToolTips->AddTool(GetDlgItem(IDC_SCOPE_U), _T(""), NULL, 0); - m_TimeToolTips->AddTool(GetDlgItem(IDC_STATSSCOPE), _T(""), NULL, 0); + m_TimeToolTips->AddTool(GetDlgItem(IDC_SCOPE_D), _T("")); + m_TimeToolTips->AddTool(GetDlgItem(IDC_SCOPE_U), _T("")); + m_TimeToolTips->AddTool(GetDlgItem(IDC_STATSSCOPE), _T("")); // Any Autopop-Time which is specified higher than ~30 sec. will get reset to 5 sec. - m_TimeToolTips->SetDelayTime(TTDT_AUTOPOP, 30000); - m_TimeToolTips->SetDelayTime(TTDT_INITIAL, 30000); - m_TimeToolTips->SetDelayTime(TTDT_RESHOW, 30000); + m_TimeToolTips->SetDelayTime(TTDT_AUTOPOP, SEC2MS(30)); + m_TimeToolTips->SetDelayTime(TTDT_INITIAL, SEC2MS(30)); + m_TimeToolTips->SetDelayTime(TTDT_RESHOW, SEC2MS(30)); EnableToolTips(TRUE); - return true; + return TRUE; } void CStatisticsDlg::initCSize() @@ -521,7 +519,6 @@ LRESULT CStatisticsDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam void CStatisticsDlg::RepaintMeters() { - CString Buffer; m_DownloadOMeter.SetBackgroundColor(thePrefs.GetStatsColor(0)); // Background m_DownloadOMeter.SetGridColor(thePrefs.GetStatsColor(1)); // Grid m_DownloadOMeter.SetPlotColor(thePrefs.GetStatsColor(4), 0); // Download session @@ -548,6 +545,7 @@ void CStatisticsDlg::RepaintMeters() m_DownloadOMeter.SetYUnits(GetResString(IDS_ST_DOWNLOAD)); m_DownloadOMeter.SetLegendLabel(GetResString(IDS_ST_SESSION), 0); // Download session + CString Buffer; Buffer.Format(_T(" (%u %s)"), thePrefs.GetStatsAverageMinutes(), (LPCTSTR)GetResString(IDS_MINS)); m_DownloadOMeter.SetLegendLabel(GetResString(IDS_AVG) + Buffer, 1); // Download average m_DownloadOMeter.SetLegendLabel(GetResString(IDS_ST_CURRENT), 2); // Download current @@ -609,50 +607,49 @@ void CStatisticsDlg::SetCurrentRate(float uploadrate, float downloadrate) theApp.webserver->AddStatsLine(updown); } - +// Set Tree Values +// If a section is not expanded, don't waste CPU cycles updating it. void CStatisticsDlg::ShowStatistics(bool forceUpdate) { m_stattree.SetRedraw(false); - CString cbuffer; - // Set Tree Values + CString sText; // TRANSFER SECTION - // If a section is not expanded, don't waste CPU cycles updating it. if (forceUpdate || m_stattree.IsExpanded(h_transfer)) { - uint32 statGoodSessions = 0; - uint32 statBadSessions = 0; - double percentSessions = 0; + uint32 statGoodSessions = 0; + uint32 statBadSessions = 0; + double percentSessions = 0; // Transfer Ratios if (theStats.sessionReceivedBytes > 0 && theStats.sessionSentBytes > 0) { // Session if (theStats.sessionReceivedBytes < theStats.sessionSentBytes) - cbuffer.Format(_T("%s %.2f : 1"), (LPCTSTR)GetResString(IDS_STATS_SRATIO), (float)theStats.sessionSentBytes / theStats.sessionReceivedBytes); + sText.Format(_T("%s %.2f : 1"), (LPCTSTR)GetResString(IDS_STATS_SRATIO), (float)theStats.sessionSentBytes / theStats.sessionReceivedBytes); else - cbuffer.Format(_T("%s 1 : %.2f"), (LPCTSTR)GetResString(IDS_STATS_SRATIO), (float)theStats.sessionReceivedBytes / theStats.sessionSentBytes); + sText.Format(_T("%s 1 : %.2f"), (LPCTSTR)GetResString(IDS_STATS_SRATIO), (float)theStats.sessionReceivedBytes / theStats.sessionSentBytes); } else - cbuffer.Format(_T("%s %s"), (LPCTSTR)GetResString(IDS_STATS_SRATIO), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); // Localize - m_stattree.SetItemText(trans[0], cbuffer); + sText.Format(_T("%s %s"), (LPCTSTR)GetResString(IDS_STATS_SRATIO), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); // Localize + m_stattree.SetItemText(trans[0], sText); if (theStats.sessionReceivedBytes > 0 && theStats.sessionSentBytes > 0) { // Session if (theStats.sessionSentBytes > theStats.sessionSentBytesToFriend && theStats.sessionReceivedBytes < theStats.sessionSentBytes - theStats.sessionSentBytesToFriend) - cbuffer.Format(_T("%s %.2f : 1"), (LPCTSTR)GetResString(IDS_STATS_FRATIO), (float)(theStats.sessionSentBytes - theStats.sessionSentBytesToFriend) / theStats.sessionReceivedBytes); + sText.Format(_T("%s %.2f : 1"), (LPCTSTR)GetResString(IDS_STATS_FRATIO), (float)(theStats.sessionSentBytes - theStats.sessionSentBytesToFriend) / theStats.sessionReceivedBytes); else - cbuffer.Format(_T("%s 1 : %.2f"), (LPCTSTR)GetResString(IDS_STATS_FRATIO), (float)theStats.sessionReceivedBytes / (theStats.sessionSentBytes - theStats.sessionSentBytesToFriend)); + sText.Format(_T("%s 1 : %.2f"), (LPCTSTR)GetResString(IDS_STATS_FRATIO), (float)theStats.sessionReceivedBytes / (theStats.sessionSentBytes - theStats.sessionSentBytesToFriend)); } else - cbuffer.Format(_T("%s %s"), (LPCTSTR)GetResString(IDS_STATS_FRATIO), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); // Localize - m_stattree.SetItemText(trans[1], cbuffer); + sText.Format(_T("%s %s"), (LPCTSTR)GetResString(IDS_STATS_FRATIO), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); // Localize + m_stattree.SetItemText(trans[1], sText); if ((thePrefs.GetTotalDownloaded() > 0 && thePrefs.GetTotalUploaded() > 0) || (theStats.sessionReceivedBytes > 0 && theStats.sessionSentBytes > 0)) { // Cumulative if ((theStats.sessionReceivedBytes + thePrefs.GetTotalDownloaded()) < (theStats.sessionSentBytes + thePrefs.GetTotalUploaded())) - cbuffer.Format(_T("%s %.2f : 1"), (LPCTSTR)GetResString(IDS_STATS_CRATIO), (float)(theStats.sessionSentBytes + thePrefs.GetTotalUploaded()) / (theStats.sessionReceivedBytes + thePrefs.GetTotalDownloaded())); + sText.Format(_T("%s %.2f : 1"), (LPCTSTR)GetResString(IDS_STATS_CRATIO), (float)(theStats.sessionSentBytes + thePrefs.GetTotalUploaded()) / (theStats.sessionReceivedBytes + thePrefs.GetTotalDownloaded())); else - cbuffer.Format(_T("%s 1 : %.2f"), (LPCTSTR)GetResString(IDS_STATS_CRATIO), (float)(theStats.sessionReceivedBytes + thePrefs.GetTotalDownloaded()) / (theStats.sessionSentBytes + thePrefs.GetTotalUploaded())); + sText.Format(_T("%s 1 : %.2f"), (LPCTSTR)GetResString(IDS_STATS_CRATIO), (float)(theStats.sessionReceivedBytes + thePrefs.GetTotalDownloaded()) / (theStats.sessionSentBytes + thePrefs.GetTotalUploaded())); } else - cbuffer.Format(_T("%s %s"), (LPCTSTR)GetResString(IDS_STATS_CRATIO), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); // Localize - m_stattree.SetItemText(trans[2], cbuffer); - + sText.Format(_T("%s %s"), (LPCTSTR)GetResString(IDS_STATS_CRATIO), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); // Localize + m_stattree.SetItemText(trans[2], sText); + // TRANSFER -> DOWNLOADS SECTION if (forceUpdate || m_stattree.IsExpanded(h_download)) { uint64 DownOHTotal = 0; @@ -662,12 +659,11 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) // TRANSFER -> DOWNLOADS -> SESSION SECTION if (forceUpdate || m_stattree.IsExpanded(h_down_session)) { // Downloaded Data - cbuffer.Format(GetResString(IDS_STATS_DDATA), (LPCTSTR)CastItoXBytes(theStats.sessionReceivedBytes)); - m_stattree.SetItemText(down_S[0], cbuffer); + sText.Format(GetResString(IDS_STATS_DDATA), (LPCTSTR)CastItoXBytes(theStats.sessionReceivedBytes)); + m_stattree.SetItemText(down_S[0], sText); if (forceUpdate || m_stattree.IsExpanded(down_S[0])) { // Downloaded Data By Client if (forceUpdate || m_stattree.IsExpanded(hdown_scb)) { - int i = 0; double percentClientTransferred; uint64 DownDataTotal = thePrefs.GetDownSessionClientData(); uint64 DownDataClient = thePrefs.GetDownData_EMULE(); @@ -675,226 +671,216 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("eMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(down_scb[i], cbuffer); + int i = 0; + sText.Format(_T("eMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(down_scb[i], sText); ++i; - DownDataClient = thePrefs.GetDownData_EDONKEYHYBRID(); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("eD Hybrid: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(down_scb[i], cbuffer); + sText.Format(_T("eD Hybrid: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(down_scb[i], sText); ++i; - DownDataClient = thePrefs.GetDownData_EDONKEY(); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("eDonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(down_scb[i], cbuffer); + sText.Format(_T("eDonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(down_scb[i], sText); ++i; - DownDataClient = thePrefs.GetDownData_AMULE(); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("aMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(down_scb[i], cbuffer); + sText.Format(_T("aMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(down_scb[i], sText); ++i; - DownDataClient = thePrefs.GetDownData_MLDONKEY(); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("MLdonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(down_scb[i], cbuffer); + sText.Format(_T("MLdonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(down_scb[i], sText); ++i; - DownDataClient = thePrefs.GetDownData_SHAREAZA(); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("Shareaza: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(down_scb[i], cbuffer); + sText.Format(_T("Shareaza: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(down_scb[i], sText); ++i; - DownDataClient = thePrefs.GetDownData_EMULECOMPAT(); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("eM Compat: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(down_scb[i], cbuffer); + sText.Format(_T("eM Compat: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(down_scb[i], sText); ++i; - DownDataClient = thePrefs.GetDownData_URL(); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("URL: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(down_scb[i], cbuffer); + sText.Format(_T("URL: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(down_scb[i], sText); } // Downloaded Data By Port if (forceUpdate || m_stattree.IsExpanded(hdown_spb)) { - int i = 0; uint64 PortDataDefault = thePrefs.GetDownDataPort_4662(); uint64 PortDataOther = thePrefs.GetDownDataPort_OTHER(); uint64 PortDataPeerCache = thePrefs.GetDownDataPort_PeerCache(); uint64 PortDataTotal = thePrefs.GetDownSessionDataPort(); double percentPortTransferred; + int i = 0; if (PortDataTotal != 0 && PortDataDefault != 0) percentPortTransferred = 100.0 * PortDataDefault / PortDataTotal; else percentPortTransferred = 0; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTDEF), (LPCTSTR)CastItoXBytes(PortDataDefault), percentPortTransferred); - m_stattree.SetItemText(down_spb[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTDEF), (LPCTSTR)CastItoXBytes(PortDataDefault), percentPortTransferred); + m_stattree.SetItemText(down_spb[i], sText); ++i; - if (PortDataTotal != 0 && PortDataOther != 0) percentPortTransferred = 100.0 * PortDataOther / PortDataTotal; else percentPortTransferred = 0; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataOther), percentPortTransferred); - m_stattree.SetItemText(down_spb[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataOther), percentPortTransferred); + m_stattree.SetItemText(down_spb[i], sText); ++i; - if (PortDataTotal != 0 && PortDataPeerCache != 0) percentPortTransferred = 100.0 * PortDataPeerCache / PortDataTotal; else percentPortTransferred = 0; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), thePrefs.GetPeerCacheShow() ? _T("PeerCache") : (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataPeerCache), percentPortTransferred); - m_stattree.SetItemText(down_spb[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), thePrefs.GetPeerCacheShow() ? _T("PeerCache") : (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataPeerCache), percentPortTransferred); + m_stattree.SetItemText(down_spb[i], sText); } } // Completed Downloads - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_COMPDL), thePrefs.GetDownSessionCompletedFiles()); - m_stattree.SetItemText(down_S[1], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_COMPDL), thePrefs.GetDownSessionCompletedFiles()); + m_stattree.SetItemText(down_S[1], sText); // Active Downloads - cbuffer.Format(GetResString(IDS_STATS_ACTDL), myStats.a[1]); - m_stattree.SetItemText(down_S[2], cbuffer); + sText.Format(GetResString(IDS_STATS_ACTDL), myStats.a[1]); + m_stattree.SetItemText(down_S[2], sText); // Found Sources - cbuffer.Format(GetResString(IDS_STATS_FOUNDSRC), myStats.a[0]); - m_stattree.SetItemText(down_S[3], cbuffer); + sText.Format(GetResString(IDS_STATS_FOUNDSRC), myStats.a[0]); + m_stattree.SetItemText(down_S[3], sText); if (forceUpdate || m_stattree.IsExpanded(down_S[3])) { int i = 0; // Sources By Status - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_ONQUEUE), myStats.a[2]); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_ONQUEUE), myStats.a[2]); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_QUEUEFULL), myStats.a[3]); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_QUEUEFULL), myStats.a[3]); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_NONEEDEDPARTS), myStats.a[4]); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_NONEEDEDPARTS), myStats.a[4]); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_ASKING), myStats.a[5]); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_ASKING), myStats.a[5]); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_RECHASHSET), myStats.a[6]); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_RECHASHSET), myStats.a[6]); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_CONNECTING), myStats.a[7]); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_CONNECTING), myStats.a[7]); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_CONNVIASERVER), myStats.a[8]); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_CONNVIASERVER), myStats.a[8]); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_TOOMANYCONNS), myStats.a[9]); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_TOOMANYCONNS), myStats.a[9]); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_NOCONNECTLOW2LOW), myStats.a[10]); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_NOCONNECTLOW2LOW), myStats.a[10]); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_PROBLEMATIC), myStats.a[12]); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_PROBLEMATIC), myStats.a[12]); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_BANNED), myStats.a[13]); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_BANNED), myStats.a[13]); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_ASKED4ANOTHERFILE), myStats.a[15]); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_ASKED4ANOTHERFILE), myStats.a[15]); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_UNKNOWN), myStats.a[11]); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_UNKNOWN), myStats.a[11]); + m_stattree.SetItemText(down_sources[i], sText); ++i; // where from? (3) - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_VIAED2KSQ), myStats.a[16]); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_VIAED2KSQ), myStats.a[16]); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_VIAKAD), myStats.a[17]); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_VIAKAD), myStats.a[17]); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_VIASE), myStats.a[18]); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_VIASE), myStats.a[18]); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_VIAPASSIVE), myStats.a[14]); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_VIAPASSIVE), myStats.a[14]); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("eD2K: %u (%.1f%%)"), myStats.a[19], myStats.a[0] ? (myStats.a[19] * 100.0 / myStats.a[0]) : 0.0); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("eD2K: %u (%.1f%%)"), myStats.a[19], myStats.a[0] ? (myStats.a[19] * 100.0 / myStats.a[0]) : 0.0); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("Kad: %u (%.1f%%)"), myStats.a[20], myStats.a[0] ? (myStats.a[20] * 100.0 / myStats.a[0]) : 0.0); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("Kad: %u (%.1f%%)"), myStats.a[20], myStats.a[0] ? (myStats.a[20] * 100.0 / myStats.a[0]) : 0.0); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("eD2K/Kad: %u (%.1f%%)"), myStats.a[21], myStats.a[0] ? (myStats.a[21] * 100.0 / myStats.a[0]) : 0.0); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("eD2K/Kad: %u (%.1f%%)"), myStats.a[21], myStats.a[0] ? (myStats.a[21] * 100.0 / myStats.a[0]) : 0.0); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("%s: %s, %s: %s (%.1f%%)"), (LPCTSTR)GetResString(IDS_UDPREASKS), (LPCTSTR)CastItoIShort(theApp.downloadqueue->GetUDPFileReasks()), (LPCTSTR)GetResString(IDS_UFAILED), (LPCTSTR)CastItoIShort(theApp.downloadqueue->GetFailedUDPFileReasks()), theApp.downloadqueue->GetUDPFileReasks() ? (theApp.downloadqueue->GetFailedUDPFileReasks() * 100.0 / theApp.downloadqueue->GetUDPFileReasks()) : 0.0); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %s, %s: %s (%.1f%%)"), (LPCTSTR)GetResString(IDS_UDPREASKS), (LPCTSTR)CastItoIShort(theApp.downloadqueue->GetUDPFileReasks()), (LPCTSTR)GetResString(IDS_UFAILED), (LPCTSTR)CastItoIShort(theApp.downloadqueue->GetFailedUDPFileReasks()), theApp.downloadqueue->GetUDPFileReasks() ? (theApp.downloadqueue->GetFailedUDPFileReasks() * 100.0 / theApp.downloadqueue->GetUDPFileReasks()) : 0.0); + m_stattree.SetItemText(down_sources[i], sText); ++i; - cbuffer.Format(_T("%s: %s (%s + %s)"), (LPCTSTR)GetResString(IDS_DEADSOURCES), (LPCTSTR)CastItoIShort(static_cast(theApp.clientlist->m_globDeadSourceList.GetDeadSourcesCount() + myStats.a[22])), (LPCTSTR)CastItoIShort(static_cast(theApp.clientlist->m_globDeadSourceList.GetDeadSourcesCount())), (LPCTSTR)CastItoIShort(static_cast(myStats.a[22]))); - m_stattree.SetItemText(down_sources[i], cbuffer); + sText.Format(_T("%s: %s (%s + %s)"), (LPCTSTR)GetResString(IDS_DEADSOURCES), (LPCTSTR)CastItoIShort(static_cast(theApp.clientlist->m_globDeadSourceList.GetDeadSourcesCount() + myStats.a[22])), (LPCTSTR)CastItoIShort(static_cast(theApp.clientlist->m_globDeadSourceList.GetDeadSourcesCount())), (LPCTSTR)CastItoIShort(static_cast(myStats.a[22]))); + m_stattree.SetItemText(down_sources[i], sText); } // Set Download Sessions statGoodSessions = thePrefs.GetDownS_SuccessfulSessions() + myStats.a[1]; // Add Active Downloads statBadSessions = thePrefs.GetDownS_FailedSessions(); - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_DLSES), statGoodSessions + statBadSessions); - m_stattree.SetItemText(down_S[4], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_DLSES), statGoodSessions + statBadSessions); + m_stattree.SetItemText(down_S[4], sText); if (forceUpdate || m_stattree.IsExpanded(down_S[4])) { // Set Successful Download Sessions and Average Downloaded Per Session if (statGoodSessions > 0) { percentSessions = 100.0 * statGoodSessions / (statGoodSessions + statBadSessions); - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDATADLSES), (LPCTSTR)CastItoXBytes(theStats.sessionReceivedBytes / statGoodSessions)); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDATADLSES), (LPCTSTR)CastItoXBytes(theStats.sessionReceivedBytes / statGoodSessions)); } else { percentSessions = 0; - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDATADLSES), (LPCTSTR)CastItoXBytes((uint32)0)); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDATADLSES), (LPCTSTR)CastItoXBytes((uint32)0)); } - m_stattree.SetItemText(down_ssessions[2], cbuffer); // Set Avg DL/Session - cbuffer.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_SDLSES), statGoodSessions, percentSessions); - m_stattree.SetItemText(down_ssessions[0], cbuffer); // Set Succ Sessions - // Set Failed Download Sessions (Avoid Division) - if (percentSessions != 0 && statBadSessions > 0) - percentSessions = 100 - percentSessions; // There were some good sessions and bad ones... - else if (percentSessions == 0 && statBadSessions > 0) - percentSessions = 100; // There were bad sessions and no good ones, must be 100% + m_stattree.SetItemText(down_ssessions[2], sText); // Set Avg DL/Session + sText.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_SDLSES), statGoodSessions, percentSessions); + m_stattree.SetItemText(down_ssessions[0], sText); // Set Successful Sessions + // Set Failed Download Sessions + if (statBadSessions > 0) + percentSessions = 100 - percentSessions; // There were bad sessions else - percentSessions = 0; // No sessions at all, or no bad ones. - cbuffer.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_FDLSES), statBadSessions, percentSessions); - m_stattree.SetItemText(down_ssessions[1], cbuffer); + percentSessions = 0; // No bad sessions at all + sText.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_FDLSES), statBadSessions, percentSessions); + m_stattree.SetItemText(down_ssessions[1], sText); // Set Average Download Time - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDLTIME), (LPCTSTR)CastSecondsToLngHM(thePrefs.GetDownS_AvgTime())); - m_stattree.SetItemText(down_ssessions[3], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDLTIME), (LPCTSTR)CastSecondsToLngHM(thePrefs.GetDownS_AvgTime())); + m_stattree.SetItemText(down_ssessions[3], sText); } // Set Gain Due To Compression - cbuffer.Format(GetResString(IDS_STATS_GAINCOMP) + _T(" (%.1f%%)"), (LPCTSTR)CastItoXBytes(thePrefs.GetSesSavedFromCompression()), theStats.sessionReceivedBytes != 0 ? (thePrefs.GetSesSavedFromCompression() * 100.0 / theStats.sessionReceivedBytes) : 0.0); - m_stattree.SetItemText(down_S[5], cbuffer); + sText.Format(GetResString(IDS_STATS_GAINCOMP) + _T(" (%.1f%%)"), (LPCTSTR)CastItoXBytes(thePrefs.GetSesSavedFromCompression()), theStats.sessionReceivedBytes != 0 ? (thePrefs.GetSesSavedFromCompression() * 100.0 / theStats.sessionReceivedBytes) : 0.0); + m_stattree.SetItemText(down_S[5], sText); // Set Lost Due To Corruption - cbuffer.Format(GetResString(IDS_STATS_LOSTCORRUPT) + _T(" (%.1f%%)"), (LPCTSTR)CastItoXBytes(thePrefs.GetSesLostFromCorruption()), theStats.sessionReceivedBytes != 0 ? (thePrefs.GetSesLostFromCorruption() * 100.0 / theStats.sessionReceivedBytes) : 0.0); - m_stattree.SetItemText(down_S[6], cbuffer); + sText.Format(GetResString(IDS_STATS_LOSTCORRUPT) + _T(" (%.1f%%)"), (LPCTSTR)CastItoXBytes(thePrefs.GetSesLostFromCorruption()), theStats.sessionReceivedBytes != 0 ? (thePrefs.GetSesLostFromCorruption() * 100.0 / theStats.sessionReceivedBytes) : 0.0); + m_stattree.SetItemText(down_S[6], sText); // Set Parts Saved Due To ICH - cbuffer.Format(GetResString(IDS_STATS_ICHSAVED), thePrefs.GetSesPartsSavedByICH()); - m_stattree.SetItemText(down_S[7], cbuffer); + sText.Format(GetResString(IDS_STATS_ICHSAVED), thePrefs.GetSesPartsSavedByICH()); + m_stattree.SetItemText(down_S[7], sText); // Calculate downline OH totals DownOHTotal = theStats.GetDownDataOverheadFileRequest() @@ -909,41 +895,40 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) + theStats.GetDownDataOverheadOtherPackets(); // Downline Overhead - cbuffer.Format(GetResString(IDS_TOVERHEAD), (LPCTSTR)CastItoXBytes(DownOHTotal), (LPCTSTR)CastItoIShort(DownOHTotalPackets)); - m_stattree.SetItemText(hdown_soh, cbuffer); + sText.Format(GetResString(IDS_TOVERHEAD), (LPCTSTR)CastItoXBytes(DownOHTotal), (LPCTSTR)CastItoIShort(DownOHTotalPackets)); + m_stattree.SetItemText(hdown_soh, sText); if (forceUpdate || m_stattree.IsExpanded(hdown_soh)) { int i = 0; // Set down session file req OH - cbuffer.Format(GetResString(IDS_FROVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetDownDataOverheadFileRequest()), (LPCTSTR)CastItoIShort(theStats.GetDownDataOverheadFileRequestPackets())); - m_stattree.SetItemText(down_soh[i], cbuffer); + sText.Format(GetResString(IDS_FROVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetDownDataOverheadFileRequest()), (LPCTSTR)CastItoIShort(theStats.GetDownDataOverheadFileRequestPackets())); + m_stattree.SetItemText(down_soh[i], sText); ++i; // Set down session source exch OH - cbuffer.Format(GetResString(IDS_SSOVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetDownDataOverheadSourceExchange()), (LPCTSTR)CastItoIShort(theStats.GetDownDataOverheadSourceExchangePackets())); - m_stattree.SetItemText(down_soh[i], cbuffer); + sText.Format(GetResString(IDS_SSOVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetDownDataOverheadSourceExchange()), (LPCTSTR)CastItoIShort(theStats.GetDownDataOverheadSourceExchangePackets())); + m_stattree.SetItemText(down_soh[i], sText); ++i; // Set down session server OH - cbuffer.Format(GetResString(IDS_SOVERHEAD), + sText.Format(GetResString(IDS_SOVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetDownDataOverheadServer()), (LPCTSTR)CastItoIShort(theStats.GetDownDataOverheadServerPackets())); - m_stattree.SetItemText(down_soh[i], cbuffer); + m_stattree.SetItemText(down_soh[i], sText); ++i; // Set down session Kad OH - cbuffer.Format(GetResString(IDS_KADOVERHEAD), + sText.Format(GetResString(IDS_KADOVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetDownDataOverheadKad()), (LPCTSTR)CastItoIShort(theStats.GetDownDataOverheadKadPackets())); - m_stattree.SetItemText(down_soh[i], cbuffer); + m_stattree.SetItemText(down_soh[i], sText); } } // TRANSFER -> DOWNLOADS -> CUMULATIVE SECTION if (forceUpdate || m_stattree.IsExpanded(h_down_total)) { // Downloaded Data uint64 ullCumReceived = theStats.sessionReceivedBytes + thePrefs.GetTotalDownloaded(); - cbuffer.Format(GetResString(IDS_STATS_DDATA), (LPCTSTR)CastItoXBytes(ullCumReceived)); - m_stattree.SetItemText(down_T[0], cbuffer); + sText.Format(GetResString(IDS_STATS_DDATA), (LPCTSTR)CastItoXBytes(ullCumReceived)); + m_stattree.SetItemText(down_T[0], sText); if (forceUpdate || m_stattree.IsExpanded(down_T[0])) { // Downloaded Data By Client if (forceUpdate || m_stattree.IsExpanded(hdown_tcb)) { - int i = 0; uint64 DownDataTotal = thePrefs.GetDownTotalClientData(); uint64 DownDataClient = thePrefs.GetCumDownData_EMULE(); double percentClientTransferred; @@ -951,71 +936,65 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("eMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(down_tcb[i], cbuffer); + int i = 0; + sText.Format(_T("eMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(down_tcb[i], sText); ++i; - DownDataClient = thePrefs.GetCumDownData_EDONKEYHYBRID(); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("eD Hybrid: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(down_tcb[i], cbuffer); + sText.Format(_T("eD Hybrid: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(down_tcb[i], sText); ++i; - DownDataClient = thePrefs.GetCumDownData_EDONKEY(); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("eDonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(down_tcb[i], cbuffer); + sText.Format(_T("eDonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(down_tcb[i], sText); ++i; - DownDataClient = thePrefs.GetCumDownData_AMULE(); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("aMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(down_tcb[i], cbuffer); + sText.Format(_T("aMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(down_tcb[i], sText); ++i; - DownDataClient = thePrefs.GetCumDownData_MLDONKEY(); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("MLdonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(down_tcb[i], cbuffer); + sText.Format(_T("MLdonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(down_tcb[i], sText); ++i; - DownDataClient = thePrefs.GetCumDownData_SHAREAZA(); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("Shareaza: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(down_tcb[i], cbuffer); + sText.Format(_T("Shareaza: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(down_tcb[i], sText); ++i; - DownDataClient = thePrefs.GetCumDownData_EMULECOMPAT(); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("eM Compat: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(down_tcb[i], cbuffer); + sText.Format(_T("eM Compat: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(down_tcb[i], sText); ++i; - DownDataClient = thePrefs.GetCumDownData_URL(); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("URL: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(down_tcb[i], cbuffer); + sText.Format(_T("URL: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(down_tcb[i], sText); } // Downloaded Data By Port if (forceUpdate || m_stattree.IsExpanded(hdown_tpb)) { @@ -1030,74 +1009,67 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) percentPortTransferred = 100.0 * PortDataDefault / PortDataTotal; else percentPortTransferred = 0; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTDEF), (LPCTSTR)CastItoXBytes(PortDataDefault), percentPortTransferred); - m_stattree.SetItemText(down_tpb[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTDEF), (LPCTSTR)CastItoXBytes(PortDataDefault), percentPortTransferred); + m_stattree.SetItemText(down_tpb[i], sText); ++i; if (PortDataTotal != 0 && PortDataOther != 0) percentPortTransferred = 100.0 * PortDataOther / PortDataTotal; else percentPortTransferred = 0; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataOther), percentPortTransferred); - m_stattree.SetItemText(down_tpb[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataOther), percentPortTransferred); + m_stattree.SetItemText(down_tpb[i], sText); ++i; if (PortDataTotal != 0 && PortDataPeerCache != 0) percentPortTransferred = 100.0 * PortDataPeerCache / PortDataTotal; else percentPortTransferred = 0; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), thePrefs.GetPeerCacheShow() ? _T("PeerCache") : (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataPeerCache), percentPortTransferred); - m_stattree.SetItemText(down_tpb[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), thePrefs.GetPeerCacheShow() ? _T("PeerCache") : (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataPeerCache), percentPortTransferred); + m_stattree.SetItemText(down_tpb[i], sText); } } // Set Cum Completed Downloads - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_COMPDL), thePrefs.GetDownCompletedFiles()); - m_stattree.SetItemText(down_T[1], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_COMPDL), thePrefs.GetDownCompletedFiles()); + m_stattree.SetItemText(down_T[1], sText); // Set Cum Download Sessions statGoodSessions = thePrefs.GetDownC_SuccessfulSessions() + myStats.a[1]; // Need to reset these from the session section. Declared up there. statBadSessions = thePrefs.GetDownC_FailedSessions(); // ^^^^^^^^^^^^^^ - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_DLSES), statGoodSessions + statBadSessions); - m_stattree.SetItemText(down_T[2], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_DLSES), statGoodSessions + statBadSessions); + m_stattree.SetItemText(down_T[2], sText); if (forceUpdate || m_stattree.IsExpanded(down_T[2])) { // Set Cum Successful Download Sessions & Cum Average Download Per Sessions (Save an if-else statement) if (statGoodSessions > 0) { percentSessions = 100.0 * statGoodSessions / (statGoodSessions + statBadSessions); - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDATADLSES), (LPCTSTR)CastItoXBytes(ullCumReceived / statGoodSessions)); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDATADLSES), (LPCTSTR)CastItoXBytes(ullCumReceived / statGoodSessions)); } else { percentSessions = 0; - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDATADLSES), (LPCTSTR)CastItoXBytes((uint32)0)); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDATADLSES), (LPCTSTR)CastItoXBytes((uint32)0)); } - m_stattree.SetItemText(down_tsessions[2], cbuffer); // Set Avg DL/Session - cbuffer.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_SDLSES), statGoodSessions, percentSessions); - m_stattree.SetItemText(down_tsessions[0], cbuffer); // Set Successful Sessions + m_stattree.SetItemText(down_tsessions[2], sText); // Set Avg DL/Session + sText.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_SDLSES), statGoodSessions, percentSessions); + m_stattree.SetItemText(down_tsessions[0], sText); // Set Successful Sessions // Set Cum Failed Download Sessions - if (percentSessions != 0 && statBadSessions > 0) - percentSessions = 100 - percentSessions; // There were some good sessions and bad ones... - else if (percentSessions == 0 && statBadSessions > 0) - percentSessions = 100; // There were bad sessions and no good ones, must be 100% + if (statBadSessions > 0) + percentSessions = 100 - percentSessions; // There were bad sessions else - percentSessions = 0; // No sessions at all, or no bad ones. - cbuffer.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_FDLSES), statBadSessions, percentSessions); - m_stattree.SetItemText(down_tsessions[1], cbuffer); - // Set Cumulative Average Download Time - uint32 avgDownTime = thePrefs.GetDownS_AvgTime(); - if (thePrefs.GetDownC_AvgTime() <= 0) - thePrefs.SetDownCAvgTime(avgDownTime); - avgDownTime = (uint32)(avgDownTime + thePrefs.GetDownC_AvgTime()) / 2; - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDLTIME), (LPCTSTR)CastSecondsToLngHM(avgDownTime)); - m_stattree.SetItemText(down_tsessions[3], cbuffer); + percentSessions = 0; // No bad sessions at all + sText.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_FDLSES), statBadSessions, percentSessions); + m_stattree.SetItemText(down_tsessions[1], sText); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDLTIME), (LPCTSTR)CastSecondsToLngHM(thePrefs.GetDownC_AvgTime())); + m_stattree.SetItemText(down_tsessions[3], sText); } // Set Cumulative Gained Due To Compression uint64 ullCumCompressed = thePrefs.GetSesSavedFromCompression() + thePrefs.GetCumSavedFromCompression(); - cbuffer.Format(GetResString(IDS_STATS_GAINCOMP) + _T(" (%.1f%%)"), (LPCTSTR)CastItoXBytes(ullCumCompressed), ullCumReceived != 0 ? (ullCumCompressed * 100.0 / ullCumReceived) : 0.0); - m_stattree.SetItemText(down_T[3], cbuffer); + sText.Format(GetResString(IDS_STATS_GAINCOMP) + _T(" (%.1f%%)"), (LPCTSTR)CastItoXBytes(ullCumCompressed), ullCumReceived != 0 ? (ullCumCompressed * 100.0 / ullCumReceived) : 0.0); + m_stattree.SetItemText(down_T[3], sText); // Set Cumulative Lost Due To Corruption uint64 ullCumCorrupted = thePrefs.GetSesLostFromCorruption() + thePrefs.GetCumLostFromCorruption(); - cbuffer.Format(GetResString(IDS_STATS_LOSTCORRUPT) + _T(" (%.1f%%)"), (LPCTSTR)CastItoXBytes(ullCumCorrupted), ullCumReceived != 0 ? (ullCumCorrupted * 100.0 / ullCumReceived) : 0.0); - m_stattree.SetItemText(down_T[4], cbuffer); + sText.Format(GetResString(IDS_STATS_LOSTCORRUPT) + _T(" (%.1f%%)"), (LPCTSTR)CastItoXBytes(ullCumCorrupted), ullCumReceived != 0 ? (ullCumCorrupted * 100.0 / ullCumReceived) : 0.0); + m_stattree.SetItemText(down_T[4], sText); // Set Cumulative Saved Due To ICH - cbuffer.Format(GetResString(IDS_STATS_ICHSAVED), thePrefs.GetSesPartsSavedByICH() + thePrefs.GetCumPartsSavedByICH()); - m_stattree.SetItemText(down_T[5], cbuffer); + sText.Format(GetResString(IDS_STATS_ICHSAVED), thePrefs.GetSesPartsSavedByICH() + thePrefs.GetCumPartsSavedByICH()); + m_stattree.SetItemText(down_T[5], sText); if (DownOHTotal == 0 || DownOHTotalPackets == 0) { DownOHTotal = theStats.GetDownDataOverheadFileRequest() @@ -1112,31 +1084,31 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) + theStats.GetDownDataOverheadOtherPackets(); } // Total Overhead - cbuffer.Format(GetResString(IDS_TOVERHEAD), (LPCTSTR)CastItoXBytes(DownOHTotal + thePrefs.GetDownOverheadTotal()), (LPCTSTR)CastItoIShort(DownOHTotalPackets + thePrefs.GetDownOverheadTotalPackets())); - m_stattree.SetItemText(hdown_toh, cbuffer); + sText.Format(GetResString(IDS_TOVERHEAD), (LPCTSTR)CastItoXBytes(DownOHTotal + thePrefs.GetDownOverheadTotal()), (LPCTSTR)CastItoIShort(DownOHTotalPackets + thePrefs.GetDownOverheadTotalPackets())); + m_stattree.SetItemText(hdown_toh, sText); if (forceUpdate || m_stattree.IsExpanded(hdown_toh)) { int i = 0; // File Request Overhead - cbuffer.Format(GetResString(IDS_FROVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetDownDataOverheadFileRequest() + thePrefs.GetDownOverheadFileReq()), (LPCTSTR)CastItoIShort(theStats.GetDownDataOverheadFileRequestPackets() + thePrefs.GetDownOverheadFileReqPackets())); - m_stattree.SetItemText(down_toh[i], cbuffer); + sText.Format(GetResString(IDS_FROVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetDownDataOverheadFileRequest() + thePrefs.GetDownOverheadFileReq()), (LPCTSTR)CastItoIShort(theStats.GetDownDataOverheadFileRequestPackets() + thePrefs.GetDownOverheadFileReqPackets())); + m_stattree.SetItemText(down_toh[i], sText); ++i; // Source Exchange Overhead - cbuffer.Format(GetResString(IDS_SSOVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetDownDataOverheadSourceExchange() + thePrefs.GetDownOverheadSrcEx()), (LPCTSTR)CastItoIShort(theStats.GetDownDataOverheadSourceExchangePackets() + thePrefs.GetDownOverheadSrcExPackets())); - m_stattree.SetItemText(down_toh[i], cbuffer); + sText.Format(GetResString(IDS_SSOVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetDownDataOverheadSourceExchange() + thePrefs.GetDownOverheadSrcEx()), (LPCTSTR)CastItoIShort(theStats.GetDownDataOverheadSourceExchangePackets() + thePrefs.GetDownOverheadSrcExPackets())); + m_stattree.SetItemText(down_toh[i], sText); ++i; // Server Overhead - cbuffer.Format(GetResString(IDS_SOVERHEAD), + sText.Format(GetResString(IDS_SOVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetDownDataOverheadServer() + thePrefs.GetDownOverheadServer(), false, false), (LPCTSTR)CastItoIShort(theStats.GetDownDataOverheadServerPackets() + thePrefs.GetDownOverheadServerPackets())); - m_stattree.SetItemText(down_toh[i], cbuffer); + m_stattree.SetItemText(down_toh[i], sText); ++i; // Kad Overhead - cbuffer.Format(GetResString(IDS_KADOVERHEAD) + sText.Format(GetResString(IDS_KADOVERHEAD) , (LPCTSTR)CastItoXBytes(theStats.GetDownDataOverheadKad() + thePrefs.GetDownOverheadKad()) , (LPCTSTR)CastItoIShort(theStats.GetDownDataOverheadKadPackets() + thePrefs.GetDownOverheadKadPackets())); - m_stattree.SetItemText(down_toh[i], cbuffer); + m_stattree.SetItemText(down_toh[i], sText); } } // - End Transfer -> Downloads -> Cumulative Section } // - End Transfer -> Downloads Section @@ -1147,76 +1119,66 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) // TRANSFER -> UPLOADS -> SESSION SECTION if (forceUpdate || m_stattree.IsExpanded(h_up_session)) { // Uploaded Data - cbuffer.Format(GetResString(IDS_STATS_UDATA), (LPCTSTR)CastItoXBytes(theStats.sessionSentBytes)); - m_stattree.SetItemText(up_S[0], cbuffer); + sText.Format(GetResString(IDS_STATS_UDATA), (LPCTSTR)CastItoXBytes(theStats.sessionSentBytes)); + m_stattree.SetItemText(up_S[0], sText); if (forceUpdate || m_stattree.IsExpanded(up_S[0])) { // Uploaded Data By Client if (forceUpdate || m_stattree.IsExpanded(hup_scb)) { - int i = 0; uint64 UpDataTotal = thePrefs.GetUpSessionClientData(); - uint64 UpDataClient = thePrefs.GetUpData_EMULE(); double percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("eMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(up_scb[i], cbuffer); + int i = 0; + sText.Format(_T("eMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(up_scb[i], sText); ++i; - UpDataClient = thePrefs.GetUpData_EDONKEYHYBRID(); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("eD Hybrid: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(up_scb[i], cbuffer); + sText.Format(_T("eD Hybrid: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(up_scb[i], sText); ++i; - UpDataClient = thePrefs.GetUpData_EDONKEY(); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("eDonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(up_scb[i], cbuffer); + sText.Format(_T("eDonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(up_scb[i], sText); ++i; - UpDataClient = thePrefs.GetUpData_AMULE(); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("aMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(up_scb[i], cbuffer); + sText.Format(_T("aMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(up_scb[i], sText); ++i; - UpDataClient = thePrefs.GetUpData_MLDONKEY(); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("MLdonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(up_scb[i], cbuffer); + sText.Format(_T("MLdonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(up_scb[i], sText); ++i; - UpDataClient = thePrefs.GetUpData_SHAREAZA(); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("Shareaza: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(up_scb[i], cbuffer); + sText.Format(_T("Shareaza: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(up_scb[i], sText); ++i; - UpDataClient = thePrefs.GetUpData_EMULECOMPAT(); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("eM Compat: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(up_scb[i], cbuffer); + sText.Format(_T("eM Compat: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(up_scb[i], sText); } // Uploaded Data By Port if (forceUpdate || m_stattree.IsExpanded(hup_spb)) { - int i = 0; uint64 PortDataTotal = thePrefs.GetUpSessionPortData(); - uint64 PortDataDefault = thePrefs.GetUpDataPort_4662(); double percentPortTransferred = !PortDataTotal ? 0 : 100.0 * PortDataDefault / PortDataTotal; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTDEF), (LPCTSTR)CastItoXBytes(PortDataDefault), percentPortTransferred); - m_stattree.SetItemText(up_spb[i], cbuffer); + int i = 0; + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTDEF), (LPCTSTR)CastItoXBytes(PortDataDefault), percentPortTransferred); + m_stattree.SetItemText(up_spb[i], sText); ++i; - uint64 PortDataOther = thePrefs.GetUpDataPort_OTHER(); percentPortTransferred = !PortDataTotal ? 0 : 100.0 * PortDataOther / PortDataTotal; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataOther), percentPortTransferred); - m_stattree.SetItemText(up_spb[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataOther), percentPortTransferred); + m_stattree.SetItemText(up_spb[i], sText); ++i; - uint64 PortDataPeerCache = thePrefs.GetUpDataPort_PeerCache(); percentPortTransferred = !PortDataTotal ? 0 : 100.0 * PortDataPeerCache / PortDataTotal; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), thePrefs.GetPeerCacheShow() ? _T("PeerCache") : (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataPeerCache), percentPortTransferred); - m_stattree.SetItemText(up_spb[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), thePrefs.GetPeerCacheShow() ? _T("PeerCache") : (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataPeerCache), percentPortTransferred); + m_stattree.SetItemText(up_spb[i], sText); } // Uploaded Data By Source if (forceUpdate || m_stattree.IsExpanded(hup_ssb)) { @@ -1225,64 +1187,56 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) uint64 DataSourceFile = thePrefs.GetUpData_File(); double percentFileTransferred = !DataSourceTotal ? 0 : 100.0 * DataSourceFile / DataSourceTotal; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_DSFILE), (LPCTSTR)CastItoXBytes(DataSourceFile), percentFileTransferred); - m_stattree.SetItemText(up_ssb[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_DSFILE), (LPCTSTR)CastItoXBytes(DataSourceFile), percentFileTransferred); + m_stattree.SetItemText(up_ssb[i], sText); ++i; uint64 DataSourcePF = thePrefs.GetUpData_Partfile(); percentFileTransferred = !DataSourceTotal ? 0 : 100.0 * DataSourcePF / DataSourceTotal; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_DSPF), (LPCTSTR)CastItoXBytes(DataSourcePF), percentFileTransferred); - m_stattree.SetItemText(up_ssb[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_DSPF), (LPCTSTR)CastItoXBytes(DataSourcePF), percentFileTransferred); + m_stattree.SetItemText(up_ssb[i], sText); } } - // Amount of data uploaded to friends - cbuffer.Format(GetResString(IDS_STATS_UDATA_FRIENDS), (LPCTSTR)CastItoXBytes(theStats.sessionSentBytesToFriend)); - m_stattree.SetItemText(up_S[1], cbuffer); - + sText.Format(GetResString(IDS_STATS_UDATA_FRIENDS), (LPCTSTR)CastItoXBytes(theStats.sessionSentBytesToFriend)); + m_stattree.SetItemText(up_S[1], sText); // Set fully Active Uploads - cbuffer.Format(GetResString(IDS_STATS_ACTUL_ZZ), static_cast(theApp.uploadqueue->GetActiveUploadsCount())); //theApp.uploadqueue->GetUploadQueueLength() - m_stattree.SetItemText(up_S[2], cbuffer); - + sText.Format(GetResString(IDS_STATS_ACTUL_ZZ), static_cast(theApp.uploadqueue->GetActiveUploadsCount())); //theApp.uploadqueue->GetUploadQueueLength() + m_stattree.SetItemText(up_S[2], sText); // Set Total Uploads - cbuffer.Format(GetResString(IDS_STATS_TOTALUL), static_cast(theApp.uploadqueue->GetUploadQueueLength())); - m_stattree.SetItemText(up_S[3], cbuffer); - + sText.Format(GetResString(IDS_STATS_TOTALUL), static_cast(theApp.uploadqueue->GetUploadQueueLength())); + m_stattree.SetItemText(up_S[3], sText); // Set Queue Length - cbuffer.Format(GetResString(IDS_STATS_WAITINGUSERS), static_cast(theApp.uploadqueue->GetWaitingUserCount())); - m_stattree.SetItemText(up_S[4], cbuffer); - + sText.Format(GetResString(IDS_STATS_WAITINGUSERS), static_cast(theApp.uploadqueue->GetWaitingUserCount())); + m_stattree.SetItemText(up_S[4], sText); // Set Upload Sessions statGoodSessions = theApp.uploadqueue->GetSuccessfullUpCount() + (uint32)theApp.uploadqueue->GetUploadQueueLength(); statBadSessions = theApp.uploadqueue->GetFailedUpCount(); - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_ULSES), statGoodSessions + statBadSessions); - m_stattree.SetItemText(up_S[5], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_ULSES), statGoodSessions + statBadSessions); + m_stattree.SetItemText(up_S[5], sText); if (forceUpdate || m_stattree.IsExpanded(up_S[5])) { // Set Successful Upload Sessions & Average Uploaded Per Session - if (statGoodSessions > 0) { // Black holes are when God divided by 0 - percentSessions = 100.0*statGoodSessions / (statGoodSessions + statBadSessions); - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDATAULSES), (LPCTSTR)CastItoXBytes(theStats.sessionSentBytes / statGoodSessions)); - } else { + if (statGoodSessions > 0) // Black holes are when God divided by 0 + percentSessions = 100.0 * statGoodSessions / (statGoodSessions + statBadSessions); + else percentSessions = 0; - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDATAULSES), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); - } - m_stattree.SetItemText(up_ssessions[2], cbuffer); - cbuffer.Format(GetResString(IDS_STATS_SUCCUPCOUNT), statGoodSessions, percentSessions); - m_stattree.SetItemText(up_ssessions[0], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDATAULSES) + , (LPCTSTR)(statGoodSessions > 0 ? CastItoXBytes(theStats.sessionSentBytes / statGoodSessions) : GetResString(IDS_FSTAT_WAITING))); + m_stattree.SetItemText(up_ssessions[2], sText); + sText.Format(GetResString(IDS_STATS_SUCCUPCOUNT), statGoodSessions, percentSessions); + m_stattree.SetItemText(up_ssessions[0], sText); // Set Failed Upload Sessions - if (percentSessions != 0 && statBadSessions > 0) - percentSessions = 100 - percentSessions; // There were some good sessions and bad ones... - else if (percentSessions == 0 && statBadSessions > 0) - percentSessions = 100; // There were bad sessions and no good ones, must be 100% + if (statBadSessions > 0) + percentSessions = 100 - percentSessions; // There were bad sessions else - percentSessions = 0; // No sessions at all, or no bad ones. - cbuffer.Format(GetResString(IDS_STATS_FAILUPCOUNT), statBadSessions, percentSessions); - m_stattree.SetItemText(up_ssessions[1], cbuffer); + percentSessions = 0; // No bad sessions at all + sText.Format(GetResString(IDS_STATS_FAILUPCOUNT), statBadSessions, percentSessions); + m_stattree.SetItemText(up_ssessions[1], sText); // Set Avg Upload time - cbuffer.Format(GetResString(IDS_STATS_AVEUPTIME), (LPCTSTR)CastSecondsToLngHM(theApp.uploadqueue->GetAverageUpTime())); - m_stattree.SetItemText(up_ssessions[3], cbuffer); + sText.Format(GetResString(IDS_STATS_AVEUPTIME), (LPCTSTR)CastSecondsToLngHM(theApp.uploadqueue->GetAverageUpTime())); + m_stattree.SetItemText(up_ssessions[3], sText); } - // Calculate Upline OH Totals + // Calculate Upload OH Totals UpOHTotal = theStats.GetUpDataOverheadFileRequest() + theStats.GetUpDataOverheadSourceExchange() + theStats.GetUpDataOverheadServer() @@ -1293,37 +1247,37 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) + theStats.GetUpDataOverheadServerPackets() + theStats.GetUpDataOverheadKadPackets() + theStats.GetUpDataOverheadOtherPackets(); - // Total Upline Overhead - cbuffer.Format(GetResString(IDS_TOVERHEAD), (LPCTSTR)CastItoXBytes(UpOHTotal), (LPCTSTR)CastItoIShort(UpOHTotalPackets)); - m_stattree.SetItemText(hup_soh, cbuffer); + // Total Upload Overhead + sText.Format(GetResString(IDS_TOVERHEAD), (LPCTSTR)CastItoXBytes(UpOHTotal), (LPCTSTR)CastItoIShort(UpOHTotalPackets)); + m_stattree.SetItemText(hup_soh, sText); if (forceUpdate || m_stattree.IsExpanded(hup_soh)) { int i = 0; // File Request Overhead - cbuffer.Format(GetResString(IDS_FROVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetUpDataOverheadFileRequest()), (LPCTSTR)CastItoIShort(theStats.GetUpDataOverheadFileRequestPackets())); - m_stattree.SetItemText(up_soh[i], cbuffer); + sText.Format(GetResString(IDS_FROVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetUpDataOverheadFileRequest()), (LPCTSTR)CastItoIShort(theStats.GetUpDataOverheadFileRequestPackets())); + m_stattree.SetItemText(up_soh[i], sText); ++i; // Source Exchanged Overhead - cbuffer.Format(GetResString(IDS_SSOVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetUpDataOverheadSourceExchange()), (LPCTSTR)CastItoIShort(theStats.GetUpDataOverheadSourceExchangePackets())); - m_stattree.SetItemText(up_soh[i], cbuffer); + sText.Format(GetResString(IDS_SSOVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetUpDataOverheadSourceExchange()), (LPCTSTR)CastItoIShort(theStats.GetUpDataOverheadSourceExchangePackets())); + m_stattree.SetItemText(up_soh[i], sText); ++i; // Server Overhead - cbuffer.Format(GetResString(IDS_SOVERHEAD) + sText.Format(GetResString(IDS_SOVERHEAD) , (LPCTSTR)CastItoXBytes(theStats.GetUpDataOverheadServer()) , (LPCTSTR)CastItoIShort(theStats.GetUpDataOverheadServerPackets())); - m_stattree.SetItemText(up_soh[i], cbuffer); + m_stattree.SetItemText(up_soh[i], sText); ++i; // Kad Overhead - cbuffer.Format(GetResString(IDS_KADOVERHEAD) + sText.Format(GetResString(IDS_KADOVERHEAD) , (LPCTSTR)CastItoXBytes(theStats.GetUpDataOverheadKad()) , (LPCTSTR)CastItoIShort(theStats.GetUpDataOverheadKadPackets())); - m_stattree.SetItemText(up_soh[i], cbuffer); + m_stattree.SetItemText(up_soh[i], sText); } } // - End Transfer -> Uploads -> Session Section // TRANSFER -> UPLOADS -> CUMULATIVE SECTION if (forceUpdate || m_stattree.IsExpanded(h_up_total)) { // Uploaded Data - cbuffer.Format(GetResString(IDS_STATS_UDATA), (LPCTSTR)CastItoXBytes(theStats.sessionSentBytes + thePrefs.GetTotalUploaded())); - m_stattree.SetItemText(up_T[0], cbuffer); + sText.Format(GetResString(IDS_STATS_UDATA), (LPCTSTR)CastItoXBytes(theStats.sessionSentBytes + thePrefs.GetTotalUploaded())); + m_stattree.SetItemText(up_T[0], sText); if (forceUpdate || m_stattree.IsExpanded(up_T[0])) { // Uploaded Data By Client if (forceUpdate || m_stattree.IsExpanded(hup_tcb)) { @@ -1333,121 +1287,104 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) uint64 UpDataClient = thePrefs.GetCumUpData_EMULE(); double percentClientTransferred; percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("eMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(up_tcb[i], cbuffer); + sText.Format(_T("eMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(up_tcb[i], sText); ++i; - UpDataClient = thePrefs.GetCumUpData_EDONKEYHYBRID(); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("eD Hybrid: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(up_tcb[i], cbuffer); + sText.Format(_T("eD Hybrid: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(up_tcb[i], sText); ++i; - UpDataClient = thePrefs.GetCumUpData_EDONKEY(); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("eDonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(up_tcb[i], cbuffer); + sText.Format(_T("eDonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(up_tcb[i], sText); ++i; - UpDataClient = thePrefs.GetCumUpData_AMULE(); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("aMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(up_tcb[i], cbuffer); + sText.Format(_T("aMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(up_tcb[i], sText); ++i; - UpDataClient = thePrefs.GetCumUpData_MLDONKEY(); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("MLdonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(up_tcb[i], cbuffer); + sText.Format(_T("MLdonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(up_tcb[i], sText); ++i; - UpDataClient = thePrefs.GetCumUpData_SHAREAZA(); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("Shareaza: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(up_tcb[i], cbuffer); + sText.Format(_T("Shareaza: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(up_tcb[i], sText); ++i; - UpDataClient = thePrefs.GetCumUpData_EMULECOMPAT(); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("eM Compat: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(up_tcb[i], cbuffer); + sText.Format(_T("eM Compat: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(up_tcb[i], sText); } // Uploaded Data By Port if (forceUpdate || m_stattree.IsExpanded(hup_tpb)) { int i = 0; uint64 PortDataTotal = thePrefs.GetUpTotalPortData(); - uint64 PortDataDefault = thePrefs.GetCumUpDataPort_4662(); double percentPortTransferred = !PortDataTotal ? 0 : 100.0 * PortDataDefault / PortDataTotal; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTDEF), (LPCTSTR)CastItoXBytes(PortDataDefault), percentPortTransferred); - m_stattree.SetItemText(up_tpb[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTDEF), (LPCTSTR)CastItoXBytes(PortDataDefault), percentPortTransferred); + m_stattree.SetItemText(up_tpb[i], sText); ++i; - uint64 PortDataOther = thePrefs.GetCumUpDataPort_OTHER(); percentPortTransferred = !PortDataTotal ? 0 : 100.0 * PortDataOther / PortDataTotal; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataOther), percentPortTransferred); - m_stattree.SetItemText(up_tpb[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataOther), percentPortTransferred); + m_stattree.SetItemText(up_tpb[i], sText); ++i; - uint64 PortDataPeerCache = thePrefs.GetCumUpDataPort_PeerCache(); percentPortTransferred = !PortDataTotal ? 0 : 100.0 * PortDataPeerCache / PortDataTotal; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), thePrefs.GetPeerCacheShow() ? _T("PeerCache") : (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataPeerCache), percentPortTransferred); - m_stattree.SetItemText(up_tpb[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), thePrefs.GetPeerCacheShow() ? _T("PeerCache") : (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataPeerCache), percentPortTransferred); + m_stattree.SetItemText(up_tpb[i], sText); } // Uploaded Data By Source if (forceUpdate || m_stattree.IsExpanded(hup_tsb)) { - int i = 0; uint64 DataSourceTotal = thePrefs.GetUpTotalDataFile(); - uint64 DataSourceFile = thePrefs.GetCumUpData_File(); double percentFileTransferred = !DataSourceTotal ? 0 : 100.0 * DataSourceFile / DataSourceTotal; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_DSFILE), (LPCTSTR)CastItoXBytes(DataSourceFile), percentFileTransferred); - m_stattree.SetItemText(up_tsb[i], cbuffer); + int i = 0; + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_DSFILE), (LPCTSTR)CastItoXBytes(DataSourceFile), percentFileTransferred); + m_stattree.SetItemText(up_tsb[i], sText); ++i; - uint64 DataSourcePF = thePrefs.GetCumUpData_Partfile(); percentFileTransferred = !DataSourceTotal ? 0 : 100.0 * DataSourcePF / DataSourceTotal; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_DSPF), (LPCTSTR)CastItoXBytes(DataSourcePF), percentFileTransferred); - m_stattree.SetItemText(up_tsb[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_DSPF), (LPCTSTR)CastItoXBytes(DataSourcePF), percentFileTransferred); + m_stattree.SetItemText(up_tsb[i], sText); } } // Upload Sessions statGoodSessions = theApp.uploadqueue->GetSuccessfullUpCount() + thePrefs.GetUpSuccessfulSessions() + (uint32)theApp.uploadqueue->GetUploadQueueLength(); statBadSessions = theApp.uploadqueue->GetFailedUpCount() + thePrefs.GetUpFailedSessions(); - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_ULSES), statGoodSessions + statBadSessions); - m_stattree.SetItemText(up_T[1], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_ULSES), statGoodSessions + statBadSessions); + m_stattree.SetItemText(up_T[1], sText); if (forceUpdate || m_stattree.IsExpanded(up_T[1])) { // Set Successful Upload Sessions & Average Uploaded Per Session - if (statGoodSessions > 0) { // Black holes are when God divided by 0 - percentSessions = 100.0*statGoodSessions / (statGoodSessions + statBadSessions); - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDATAULSES), (LPCTSTR)CastItoXBytes((theStats.sessionSentBytes + thePrefs.GetTotalUploaded()) / statGoodSessions)); - } else { + if (statGoodSessions > 0) // Black holes are when God divided by 0 + percentSessions = 100.0 * statGoodSessions / (statGoodSessions + statBadSessions); + else percentSessions = 0; - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDATAULSES), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); - } - m_stattree.SetItemText(up_tsessions[2], cbuffer); - cbuffer.Format(GetResString(IDS_STATS_SUCCUPCOUNT), statGoodSessions, percentSessions); - m_stattree.SetItemText(up_tsessions[0], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_AVGDATAULSES) + , (LPCTSTR)(statGoodSessions > 0 ? CastItoXBytes((theStats.sessionSentBytes + thePrefs.GetTotalUploaded()) / statGoodSessions) : GetResString(IDS_FSTAT_WAITING))); + + m_stattree.SetItemText(up_tsessions[2], sText); + sText.Format(GetResString(IDS_STATS_SUCCUPCOUNT), statGoodSessions, percentSessions); + m_stattree.SetItemText(up_tsessions[0], sText); // Set Failed Upload Sessions - if (percentSessions != 0 && statBadSessions > 0) - percentSessions = 100 - percentSessions; // There were some good sessions and bad ones... - else if (percentSessions == 0 && statBadSessions > 0) - percentSessions = 100; // There were bad sessions and no good ones, must be 100% + if (statBadSessions > 0) + percentSessions = 100 - percentSessions; // There were bad sessions else - percentSessions = 0; // No sessions at all, or no bad ones. - cbuffer.Format(GetResString(IDS_STATS_FAILUPCOUNT), statBadSessions, percentSessions); - m_stattree.SetItemText(up_tsessions[1], cbuffer); + percentSessions = 0; // No bad sessions at all + sText.Format(GetResString(IDS_STATS_FAILUPCOUNT), statBadSessions, percentSessions); + m_stattree.SetItemText(up_tsessions[1], sText); // Set Avg Upload time - uint32 avguptime = theApp.uploadqueue->GetAverageUpTime(); - if (thePrefs.GetUpAvgTime() <= 0) - thePrefs.SetUpAvgTime(avguptime); - avguptime = (avguptime + thePrefs.GetUpAvgTime()) / 2; - cbuffer.Format(GetResString(IDS_STATS_AVEUPTIME), (LPCTSTR)CastSecondsToLngHM(avguptime)); - m_stattree.SetItemText(up_tsessions[3], cbuffer); + sText.Format(GetResString(IDS_STATS_AVEUPTIME), (LPCTSTR)CastSecondsToLngHM(thePrefs.GetUpAvgTime())); + m_stattree.SetItemText(up_tsessions[3], sText); } if (UpOHTotal == 0 || UpOHTotalPackets == 0) { - // Calculate Upline OH Totals + // Calculate Upload OH Totals UpOHTotal = theStats.GetUpDataOverheadFileRequest() + theStats.GetUpDataOverheadSourceExchange() + theStats.GetUpDataOverheadServer() @@ -1460,33 +1397,33 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) + theStats.GetUpDataOverheadOtherPackets(); } // Set Cumulative Total Overhead - cbuffer.Format(GetResString(IDS_TOVERHEAD), (LPCTSTR)CastItoXBytes(UpOHTotal + thePrefs.GetUpOverheadTotal()), (LPCTSTR)CastItoIShort(UpOHTotalPackets + thePrefs.GetUpOverheadTotalPackets())); - m_stattree.SetItemText(hup_toh, cbuffer); + sText.Format(GetResString(IDS_TOVERHEAD), (LPCTSTR)CastItoXBytes(UpOHTotal + thePrefs.GetUpOverheadTotal()), (LPCTSTR)CastItoIShort(UpOHTotalPackets + thePrefs.GetUpOverheadTotalPackets())); + m_stattree.SetItemText(hup_toh, sText); if (forceUpdate || m_stattree.IsExpanded(hup_toh)) { int i = 0; // Set up total file req OH - cbuffer.Format(GetResString(IDS_FROVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetUpDataOverheadFileRequest() + thePrefs.GetUpOverheadFileReq()), (LPCTSTR)CastItoIShort(theStats.GetUpDataOverheadFileRequestPackets() + thePrefs.GetUpOverheadFileReqPackets())); - m_stattree.SetItemText(up_toh[i], cbuffer); + sText.Format(GetResString(IDS_FROVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetUpDataOverheadFileRequest() + thePrefs.GetUpOverheadFileReq()), (LPCTSTR)CastItoIShort(theStats.GetUpDataOverheadFileRequestPackets() + thePrefs.GetUpOverheadFileReqPackets())); + m_stattree.SetItemText(up_toh[i], sText); ++i; // Set up total source exch OH - cbuffer.Format(GetResString(IDS_SSOVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetUpDataOverheadSourceExchange() + thePrefs.GetUpOverheadSrcEx()), (LPCTSTR)CastItoIShort(theStats.GetUpDataOverheadSourceExchangePackets() + thePrefs.GetUpOverheadSrcExPackets())); - m_stattree.SetItemText(up_toh[i], cbuffer); + sText.Format(GetResString(IDS_SSOVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetUpDataOverheadSourceExchange() + thePrefs.GetUpOverheadSrcEx()), (LPCTSTR)CastItoIShort(theStats.GetUpDataOverheadSourceExchangePackets() + thePrefs.GetUpOverheadSrcExPackets())); + m_stattree.SetItemText(up_toh[i], sText); ++i; // Set up total server OH - cbuffer.Format(GetResString(IDS_SOVERHEAD), + sText.Format(GetResString(IDS_SOVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetUpDataOverheadServer() + thePrefs.GetUpOverheadServer(), false, false), (LPCTSTR)CastItoIShort(theStats.GetUpDataOverheadServerPackets() + thePrefs.GetUpOverheadServerPackets())); - m_stattree.SetItemText(up_toh[i], cbuffer); + m_stattree.SetItemText(up_toh[i], sText); ++i; // Set up total Kad OH - cbuffer.Format(GetResString(IDS_KADOVERHEAD), + sText.Format(GetResString(IDS_KADOVERHEAD), (LPCTSTR)CastItoXBytes(theStats.GetUpDataOverheadKad() + thePrefs.GetUpOverheadKad(), false, false), (LPCTSTR)CastItoIShort(theStats.GetUpDataOverheadKadPackets() + thePrefs.GetUpOverheadKadPackets())); - m_stattree.SetItemText(up_toh[i], cbuffer); + m_stattree.SetItemText(up_toh[i], sText); } } // - End Transfer -> Uploads -> Cumulative Section } // - End Transfer -> Uploads Section @@ -1501,75 +1438,75 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) if (forceUpdate || m_stattree.IsExpanded(hconn_sg)) { int i = 0; // Server Reconnects - cbuffer.Format(GetResString(IDS_STATS_RECONNECTS), theStats.reconnects ? theStats.reconnects - 1 : 0); - m_stattree.SetItemText(conn_sg[i], cbuffer); + sText.Format(GetResString(IDS_STATS_RECONNECTS), theStats.reconnects ? theStats.reconnects - 1 : 0); + m_stattree.SetItemText(conn_sg[i], sText); ++i; // Active Connections - cbuffer.Format(_T("%s: %u (%s:%u | %s:%u | %s:%u)"), (LPCTSTR)GetResString(IDS_SF_ACTIVECON), theApp.listensocket->GetActiveConnections(), (LPCTSTR)GetResString(IDS_HALF), theApp.listensocket->GetTotalHalfCon(), (LPCTSTR)GetResString(IDS_CONCOMPL), theApp.listensocket->GetTotalComp(), (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), theApp.listensocket->GetActiveConnections() - theApp.listensocket->GetTotalHalfCon() - theApp.listensocket->GetTotalComp()); - m_stattree.SetItemText(conn_sg[i], cbuffer); + sText.Format(_T("%s: %u (%s:%u | %s:%u | %s:%u)"), (LPCTSTR)GetResString(IDS_SF_ACTIVECON), theApp.listensocket->GetActiveConnections(), (LPCTSTR)GetResString(IDS_HALF), theApp.listensocket->GetTotalHalfCon(), (LPCTSTR)GetResString(IDS_CONCOMPL), theApp.listensocket->GetTotalComp(), (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), theApp.listensocket->GetActiveConnections() - theApp.listensocket->GetTotalHalfCon() - theApp.listensocket->GetTotalComp()); + m_stattree.SetItemText(conn_sg[i], sText); ++i; // Average Connections - cbuffer.Format(_T("%s: %i"), (LPCTSTR)GetResString(IDS_SF_AVGCON), (int)theApp.listensocket->GetAverageConnections()); - m_stattree.SetItemText(conn_sg[i], cbuffer); + sText.Format(_T("%s: %i"), (LPCTSTR)GetResString(IDS_SF_AVGCON), (int)theApp.listensocket->GetAverageConnections()); + m_stattree.SetItemText(conn_sg[i], sText); ++i; // Peak Connections - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_SF_PEAKCON), theApp.listensocket->GetPeakConnections()); - m_stattree.SetItemText(conn_sg[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_SF_PEAKCON), theApp.listensocket->GetPeakConnections()); + m_stattree.SetItemText(conn_sg[i], sText); ++i; // Connect Limit Reached uint32 m_itemp = theApp.listensocket->GetMaxConnectionReached(); if (m_itemp != m_ilastMaxConnReached) { - cbuffer.Format(_T("%s: %u : %s"), (LPCTSTR)GetResString(IDS_SF_MAXCONLIMITREACHED), m_itemp, (LPCTSTR)CTime::GetCurrentTime().Format(_T("%c"))); - m_stattree.SetItemText(conn_sg[i], cbuffer); + sText.Format(_T("%s: %u : %s"), (LPCTSTR)GetResString(IDS_SF_MAXCONLIMITREACHED), m_itemp, (LPCTSTR)CTime::GetCurrentTime().Format(_T("%c"))); + m_stattree.SetItemText(conn_sg[i], sText); m_ilastMaxConnReached = m_itemp; } else if (m_itemp == 0) { - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_SF_MAXCONLIMITREACHED), m_itemp); - m_stattree.SetItemText(conn_sg[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_SF_MAXCONLIMITREACHED), m_itemp); + m_stattree.SetItemText(conn_sg[i], sText); } } // - End Connection -> Session -> General Section // CONNECTION -> SESSION -> UPLOADS SECTION if (forceUpdate || m_stattree.IsExpanded(hconn_su)) { int i = 0; // Upload Rate - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_ST_UPLOAD), (LPCTSTR)CastItoXBytes(theStats.rateUp, true, true)); - m_stattree.SetItemText(conn_su[i], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_ST_UPLOAD), (LPCTSTR)CastItoXBytes(theStats.rateUp, true, true)); + m_stattree.SetItemText(conn_su[i], sText); ++i; // Average Upload Rate - cbuffer.Format(GetResString(IDS_STATS_AVGUL), (LPCTSTR)CastItoXBytes(theStats.GetAvgUploadRate(AVG_SESSION), true, true)); - m_stattree.SetItemText(conn_su[i], cbuffer); + sText.Format(GetResString(IDS_STATS_AVGUL), (LPCTSTR)CastItoXBytes(theStats.GetAvgUploadRate(AVG_SESSION), true, true)); + m_stattree.SetItemText(conn_su[i], sText); ++i; // Max Upload Rate - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_MAXUL), (LPCTSTR)CastItoXBytes(theStats.maxUp, true, true)); - m_stattree.SetItemText(conn_su[i], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_MAXUL), (LPCTSTR)CastItoXBytes(theStats.maxUp, true, true)); + m_stattree.SetItemText(conn_su[i], sText); ++i; // Max Average Upload Rate float myAverageUpRate = theStats.GetAvgUploadRate(AVG_SESSION); if (myAverageUpRate > theStats.maxUpavg) theStats.maxUpavg = myAverageUpRate; - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_MAXAVGUL), (LPCTSTR)CastItoXBytes(theStats.maxUpavg, true, true)); - m_stattree.SetItemText(conn_su[i], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_MAXAVGUL), (LPCTSTR)CastItoXBytes(theStats.maxUpavg, true, true)); + m_stattree.SetItemText(conn_su[i], sText); } // - End Connection -> Session -> Uploads Section // CONNECTION -> SESSION -> DOWNLOADShead SECTION if (forceUpdate || m_stattree.IsExpanded(hconn_sd)) { int i = 0; // Download Rate - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_ST_DOWNLOAD), (LPCTSTR)CastItoXBytes(theStats.rateDown, true, true)); - m_stattree.SetItemText(conn_sd[i], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_ST_DOWNLOAD), (LPCTSTR)CastItoXBytes(theStats.rateDown, true, true)); + m_stattree.SetItemText(conn_sd[i], sText); ++i; // Average Download Rate - cbuffer.Format(GetResString(IDS_STATS_AVGDL), (LPCTSTR)CastItoXBytes(theStats.GetAvgDownloadRate(AVG_SESSION), true, true)); - m_stattree.SetItemText(conn_sd[i], cbuffer); + sText.Format(GetResString(IDS_STATS_AVGDL), (LPCTSTR)CastItoXBytes(theStats.GetAvgDownloadRate(AVG_SESSION), true, true)); + m_stattree.SetItemText(conn_sd[i], sText); ++i; // Max Download Rate - cbuffer.Format(GetResString(IDS_STATS_MAXDL), (LPCTSTR)CastItoXBytes(theStats.maxDown, true, true)); - m_stattree.SetItemText(conn_sd[i], cbuffer); + sText.Format(GetResString(IDS_STATS_MAXDL), (LPCTSTR)CastItoXBytes(theStats.maxDown, true, true)); + m_stattree.SetItemText(conn_sd[i], sText); ++i; // Max Average Download Rate float myAverageDownRate = theStats.GetAvgDownloadRate(AVG_SESSION); if (myAverageDownRate > theStats.maxDownavg) theStats.maxDownavg = myAverageDownRate; - cbuffer.Format(GetResString(IDS_STATS_MAXAVGDL), (LPCTSTR)CastItoXBytes(theStats.maxDownavg, true, true)); - m_stattree.SetItemText(conn_sd[i], cbuffer); + sText.Format(GetResString(IDS_STATS_MAXAVGDL), (LPCTSTR)CastItoXBytes(theStats.maxDownavg, true, true)); + m_stattree.SetItemText(conn_sd[i], sText); } // - End Connection -> Session -> Downloads Section } // - End Connection -> Session Section // CONNECTION -> CUMULATIVE SECTION @@ -1578,50 +1515,50 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) if (forceUpdate || m_stattree.IsExpanded(hconn_tg)) { int i = 0; // Server Reconnects - cbuffer.Format(GetResString(IDS_STATS_RECONNECTS), thePrefs.GetConnNumReconnects() + theStats.reconnects - static_cast(theStats.reconnects > 0)); - m_stattree.SetItemText(conn_tg[i], cbuffer); + sText.Format(GetResString(IDS_STATS_RECONNECTS), thePrefs.GetConnNumReconnects() + theStats.reconnects - static_cast(theStats.reconnects > 0)); + m_stattree.SetItemText(conn_tg[i], sText); ++i; // Average Connections - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_SF_AVGCON), (theApp.listensocket->GetActiveConnections() + thePrefs.GetConnAvgConnections()) / 2); - m_stattree.SetItemText(conn_tg[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_SF_AVGCON), (theApp.listensocket->GetActiveConnections() + thePrefs.GetConnAvgConnections()) / 2); + m_stattree.SetItemText(conn_tg[i], sText); ++i; // Peak Connections - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_SF_PEAKCON), thePrefs.GetConnPeakConnections()); - m_stattree.SetItemText(conn_tg[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_SF_PEAKCON), thePrefs.GetConnPeakConnections()); + m_stattree.SetItemText(conn_tg[i], sText); ++i; // Connection Limit Reached - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_SF_MAXCONLIMITREACHED), theApp.listensocket->GetMaxConnectionReached() + thePrefs.GetConnMaxConnLimitReached()); - m_stattree.SetItemText(conn_tg[i], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_SF_MAXCONLIMITREACHED), theApp.listensocket->GetMaxConnectionReached() + thePrefs.GetConnMaxConnLimitReached()); + m_stattree.SetItemText(conn_tg[i], sText); } // - End Connection -> Cumulative -> General Section // CONNECTION -> CUMULATIVE -> UPLOADS SECTION if (forceUpdate || m_stattree.IsExpanded(hconn_tu)) { int i = 0; // Average Upload Rate - cbuffer.Format(GetResString(IDS_STATS_AVGUL), (LPCTSTR)CastItoXBytes(theStats.cumUpavg, true, true)); - m_stattree.SetItemText(conn_tu[i], cbuffer); + sText.Format(GetResString(IDS_STATS_AVGUL), (LPCTSTR)CastItoXBytes(theStats.cumUpavg, true, true)); + m_stattree.SetItemText(conn_tu[i], sText); ++i; // Max Upload Rate - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_MAXUL), (LPCTSTR)CastItoXBytes(theStats.maxcumUp, true, true)); - m_stattree.SetItemText(conn_tu[i], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_MAXUL), (LPCTSTR)CastItoXBytes(theStats.maxcumUp, true, true)); + m_stattree.SetItemText(conn_tu[i], sText); ++i; // Max Average Upload Rate - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_MAXAVGUL), (LPCTSTR)CastItoXBytes(theStats.maxcumUpavg, true, true)); - m_stattree.SetItemText(conn_tu[i], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_MAXAVGUL), (LPCTSTR)CastItoXBytes(theStats.maxcumUpavg, true, true)); + m_stattree.SetItemText(conn_tu[i], sText); } // - End Connection -> Cumulative -> Uploads Section // CONNECTION -> CUMULATIVE -> DOWNLOADS SECTION if (forceUpdate || m_stattree.IsExpanded(hconn_td)) { int i = 0; // Average Download Rate - cbuffer.Format(GetResString(IDS_STATS_AVGDL), (LPCTSTR)CastItoXBytes(theStats.cumDownavg, true, true)); - m_stattree.SetItemText(conn_td[i], cbuffer); + sText.Format(GetResString(IDS_STATS_AVGDL), (LPCTSTR)CastItoXBytes(theStats.cumDownavg, true, true)); + m_stattree.SetItemText(conn_td[i], sText); ++i; // Max Download Rate - cbuffer.Format(GetResString(IDS_STATS_MAXDL), (LPCTSTR)CastItoXBytes(theStats.maxcumDown, true, true)); - m_stattree.SetItemText(conn_td[i], cbuffer); + sText.Format(GetResString(IDS_STATS_MAXDL), (LPCTSTR)CastItoXBytes(theStats.maxcumDown, true, true)); + m_stattree.SetItemText(conn_td[i], sText); ++i; // Max Average Download Rate - cbuffer.Format(GetResString(IDS_STATS_MAXAVGDL), (LPCTSTR)CastItoXBytes(theStats.maxcumDownavg, true, true)); - m_stattree.SetItemText(conn_td[i], cbuffer); + sText.Format(GetResString(IDS_STATS_MAXAVGDL), (LPCTSTR)CastItoXBytes(theStats.maxcumDownavg, true, true)); + m_stattree.SetItemText(conn_td[i], sText); } // - End Connection -> Cumulative -> Downloads Section } // - End Connection -> Cumulative Section } // - END CONNECTION SECTION @@ -1630,79 +1567,79 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) // TIME STATISTICS SECTION if (forceUpdate || m_stattree.IsExpanded(h_time)) { // Statistics Last Reset - cbuffer.Format(GetResString(IDS_STATS_LASTRESETSTATIC), (LPCTSTR)thePrefs.GetStatsLastResetStr(false)); - m_stattree.SetItemText(tvitime[0], cbuffer); + sText.Format(GetResString(IDS_STATS_LASTRESETSTATIC), (LPCTSTR)thePrefs.GetStatsLastResetStr(false)); + m_stattree.SetItemText(tvitime[0], sText); // Time Since Last Reset time_t timeDiff; if (thePrefs.GetStatsLastResetLng()) { time_t timeNow; time(&timeNow); timeDiff = timeNow - thePrefs.GetStatsLastResetLng(); // In seconds - cbuffer.Format(GetResString(IDS_STATS_TIMESINCERESET), (LPCTSTR)CastSecondsToLngHM(timeDiff)); + sText.Format(GetResString(IDS_STATS_TIMESINCERESET), (LPCTSTR)CastSecondsToLngHM(timeDiff)); } else { timeDiff = 0; - cbuffer.Format(GetResString(IDS_STATS_TIMESINCERESET), (LPCTSTR)GetResString(IDS_UNKNOWN)); + sText.Format(GetResString(IDS_STATS_TIMESINCERESET), (LPCTSTR)GetResString(IDS_UNKNOWN)); } - m_stattree.SetItemText(tvitime[1], cbuffer); + m_stattree.SetItemText(tvitime[1], sText); // TIME STATISTICS -> SESSION SECTION if (forceUpdate || m_stattree.IsExpanded(htime_s)) { int i = 0; // Run Time time_t sessionRunTime = (::GetTickCount() - theStats.starttime) / SEC2MS(1); - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_RUNTIME), (LPCTSTR)CastSecondsToLngHM(sessionRunTime)); - m_stattree.SetItemText(tvitime_s[i], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_RUNTIME), (LPCTSTR)CastSecondsToLngHM(sessionRunTime)); + m_stattree.SetItemText(tvitime_s[i], sText); ++i; if (!sessionRunTime) sessionRunTime = 1; // Transfer Time - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_TRANSTIME), (LPCTSTR)CastSecondsToLngHM(theStats.GetTransferTime()), (100.0 * theStats.GetTransferTime()) / sessionRunTime); - m_stattree.SetItemText(tvitime_s[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_TRANSTIME), (LPCTSTR)CastSecondsToLngHM(theStats.GetTransferTime()), (100.0 * theStats.GetTransferTime()) / sessionRunTime); + m_stattree.SetItemText(tvitime_s[i], sText); if (forceUpdate || m_stattree.IsExpanded(tvitime_s[i])) { int x = 0; // Upload Time - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_UPTIME), (LPCTSTR)CastSecondsToLngHM(theStats.GetUploadTime()), (100.0 * theStats.GetUploadTime()) / sessionRunTime); - m_stattree.SetItemText(tvitime_st[x], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_UPTIME), (LPCTSTR)CastSecondsToLngHM(theStats.GetUploadTime()), (100.0 * theStats.GetUploadTime()) / sessionRunTime); + m_stattree.SetItemText(tvitime_st[x], sText); ++x; // Download Time - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_DOWNTIME), (LPCTSTR)CastSecondsToLngHM(theStats.GetDownloadTime()), (100.0 * theStats.GetDownloadTime()) / sessionRunTime); - m_stattree.SetItemText(tvitime_st[x], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_DOWNTIME), (LPCTSTR)CastSecondsToLngHM(theStats.GetDownloadTime()), (100.0 * theStats.GetDownloadTime()) / sessionRunTime); + m_stattree.SetItemText(tvitime_st[x], sText); } ++i; // Current Server Duration - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_CURRSRVDUR), (LPCTSTR)CastSecondsToLngHM(theStats.time_thisServerDuration), (100.0 * theStats.time_thisServerDuration) / sessionRunTime); - m_stattree.SetItemText(tvitime_s[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_CURRSRVDUR), (LPCTSTR)CastSecondsToLngHM(theStats.time_thisServerDuration), (100.0 * theStats.time_thisServerDuration) / sessionRunTime); + m_stattree.SetItemText(tvitime_s[i], sText); ++i; // Total Server Duration - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_TOTALSRVDUR), (LPCTSTR)CastSecondsToLngHM(theStats.GetServerDuration()), (100.0 * theStats.GetServerDuration()) / sessionRunTime); - m_stattree.SetItemText(tvitime_s[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_TOTALSRVDUR), (LPCTSTR)CastSecondsToLngHM(theStats.GetServerDuration()), (100.0 * theStats.GetServerDuration()) / sessionRunTime); + m_stattree.SetItemText(tvitime_s[i], sText); } // TIME STATISTICS -> CUMULATIVE SECTION if (forceUpdate || m_stattree.IsExpanded(htime_t)) { int i = 0; // Run Time time_t totalRunTime = (::GetTickCount() - theStats.starttime) / SEC2MS(1) + thePrefs.GetConnRunTime(); - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_RUNTIME), (LPCTSTR)CastSecondsToLngHM(totalRunTime)); - m_stattree.SetItemText(tvitime_t[i], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_RUNTIME), (LPCTSTR)CastSecondsToLngHM(totalRunTime)); + m_stattree.SetItemText(tvitime_t[i], sText); ++i; if (!totalRunTime) totalRunTime = 1; // Transfer Time - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_TRANSTIME), (LPCTSTR)CastSecondsToLngHM(theStats.GetTransferTime() + thePrefs.GetConnTransferTime()), (100.0 * (theStats.GetTransferTime() + thePrefs.GetConnTransferTime())) / totalRunTime); - m_stattree.SetItemText(tvitime_t[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_TRANSTIME), (LPCTSTR)CastSecondsToLngHM(theStats.GetTransferTime() + thePrefs.GetConnTransferTime()), (100.0 * (theStats.GetTransferTime() + thePrefs.GetConnTransferTime())) / totalRunTime); + m_stattree.SetItemText(tvitime_t[i], sText); if (forceUpdate || m_stattree.IsExpanded(tvitime_t[i])) { int x = 0; // Upload Time - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_UPTIME), (LPCTSTR)CastSecondsToLngHM(theStats.GetUploadTime() + thePrefs.GetConnUploadTime()), (100.0 * (theStats.GetUploadTime() + thePrefs.GetConnUploadTime())) / totalRunTime); - m_stattree.SetItemText(tvitime_tt[x], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_UPTIME), (LPCTSTR)CastSecondsToLngHM(theStats.GetUploadTime() + thePrefs.GetConnUploadTime()), (100.0 * (theStats.GetUploadTime() + thePrefs.GetConnUploadTime())) / totalRunTime); + m_stattree.SetItemText(tvitime_tt[x], sText); ++x; // Download Time - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_DOWNTIME), (LPCTSTR)CastSecondsToLngHM(theStats.GetDownloadTime() + thePrefs.GetConnDownloadTime()), (100.0 * (theStats.GetDownloadTime() + thePrefs.GetConnDownloadTime())) / totalRunTime); - m_stattree.SetItemText(tvitime_tt[x], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_DOWNTIME), (LPCTSTR)CastSecondsToLngHM(theStats.GetDownloadTime() + thePrefs.GetConnDownloadTime()), (100.0 * (theStats.GetDownloadTime() + thePrefs.GetConnDownloadTime())) / totalRunTime); + m_stattree.SetItemText(tvitime_tt[x], sText); } ++i; // Total Server Duration - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_TOTALSRVDUR), (LPCTSTR)CastSecondsToLngHM(theStats.GetServerDuration() + thePrefs.GetConnServerDuration()), (100.0 * (theStats.GetServerDuration() + thePrefs.GetConnServerDuration())) / totalRunTime); - m_stattree.SetItemText(tvitime_t[i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_TOTALSRVDUR), (LPCTSTR)CastSecondsToLngHM(theStats.GetServerDuration() + thePrefs.GetConnServerDuration()), (100.0 * (theStats.GetServerDuration() + thePrefs.GetConnServerDuration())) / totalRunTime); + m_stattree.SetItemText(tvitime_t[i], sText); } // TIME STATISTICS -> PROJECTED AVERAGES SECTION if ((forceUpdate || m_stattree.IsExpanded(htime_aap)) && timeDiff > 0) { @@ -1718,8 +1655,8 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) // TIME STATISTICS -> PROJECTED AVERAGES -> TIME PERIOD -> UPLOADS SECTION if (forceUpdate || m_stattree.IsExpanded(time_aap_hup[mx])) { // Uploaded Data - cbuffer.Format(GetResString(IDS_STATS_UDATA), (LPCTSTR)CastItoXBytes(((double)(theStats.sessionSentBytes + thePrefs.GetTotalUploaded()))*avgModifier[mx])); - m_stattree.SetItemText(time_aap_up[mx][0], cbuffer); + sText.Format(GetResString(IDS_STATS_UDATA), (LPCTSTR)CastItoXBytes(((double)(theStats.sessionSentBytes + thePrefs.GetTotalUploaded()))*avgModifier[mx])); + m_stattree.SetItemText(time_aap_up[mx][0], sText); if (forceUpdate || m_stattree.IsExpanded(time_aap_up[mx][0])) { // Uploaded Data By Client if (forceUpdate || m_stattree.IsExpanded(time_aap_up_hd[mx][0])) { @@ -1728,44 +1665,38 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) uint64 UpDataClient = (uint64)(thePrefs.GetCumUpData_EMULE() * avgModifier[mx]); double percentClientTransferred; percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("eMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(time_aap_up_dc[mx][i], cbuffer); + sText.Format(_T("eMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(time_aap_up_dc[mx][i], sText); ++i; - UpDataClient = (uint64)(thePrefs.GetCumUpData_EDONKEYHYBRID() * avgModifier[mx]); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("eD Hybrid: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(time_aap_up_dc[mx][i], cbuffer); + sText.Format(_T("eD Hybrid: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(time_aap_up_dc[mx][i], sText); ++i; - UpDataClient = (uint64)(thePrefs.GetCumUpData_EDONKEY() * avgModifier[mx]); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("eDonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(time_aap_up_dc[mx][i], cbuffer); + sText.Format(_T("eDonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(time_aap_up_dc[mx][i], sText); ++i; - UpDataClient = (uint64)(thePrefs.GetCumUpData_AMULE() * avgModifier[mx]); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("aMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(time_aap_up_dc[mx][i], cbuffer); + sText.Format(_T("aMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(time_aap_up_dc[mx][i], sText); ++i; - UpDataClient = (uint64)(thePrefs.GetCumUpData_MLDONKEY() * avgModifier[mx]); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("MLdonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(time_aap_up_dc[mx][i], cbuffer); + sText.Format(_T("MLdonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(time_aap_up_dc[mx][i], sText); ++i; - UpDataClient = (uint64)(thePrefs.GetCumUpData_SHAREAZA() * avgModifier[mx]); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("Shareaza: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(time_aap_up_dc[mx][i], cbuffer); + sText.Format(_T("Shareaza: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(time_aap_up_dc[mx][i], sText); ++i; - UpDataClient = (uint64)(thePrefs.GetCumUpData_EMULECOMPAT() * avgModifier[mx]); percentClientTransferred = !UpDataTotal ? 0 : 100.0 * UpDataClient / UpDataTotal; - cbuffer.Format(_T("eM Compat: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); - m_stattree.SetItemText(time_aap_up_dc[mx][i], cbuffer); + sText.Format(_T("eM Compat: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(UpDataClient), percentClientTransferred); + m_stattree.SetItemText(time_aap_up_dc[mx][i], sText); } // Uploaded Data By Port if (forceUpdate || m_stattree.IsExpanded(time_aap_up_hd[mx][1])) { @@ -1778,24 +1709,22 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) if (PortDataTotal != 0 && PortDataDefault != 0) percentPortTransferred = 100.0 * PortDataDefault / PortDataTotal; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTDEF), (LPCTSTR)CastItoXBytes(PortDataDefault), percentPortTransferred); - m_stattree.SetItemText(time_aap_up_dp[mx][i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTDEF), (LPCTSTR)CastItoXBytes(PortDataDefault), percentPortTransferred); + m_stattree.SetItemText(time_aap_up_dp[mx][i], sText); ++i; - if (PortDataTotal != 0 && PortDataOther != 0) percentPortTransferred = 100.0 * PortDataOther / PortDataTotal; else percentPortTransferred = 0; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataOther), percentPortTransferred); - m_stattree.SetItemText(time_aap_up_dp[mx][i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataOther), percentPortTransferred); + m_stattree.SetItemText(time_aap_up_dp[mx][i], sText); ++i; - if (PortDataTotal != 0 && PortDataPeerCache != 0) percentPortTransferred = 100.0 * PortDataPeerCache / PortDataTotal; else percentPortTransferred = 0; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), thePrefs.GetPeerCacheShow() ? _T("PeerCache") : (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataPeerCache), percentPortTransferred); - m_stattree.SetItemText(time_aap_up_dp[mx][i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), thePrefs.GetPeerCacheShow() ? _T("PeerCache") : (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataPeerCache), percentPortTransferred); + m_stattree.SetItemText(time_aap_up_dp[mx][i], sText); } // Uploaded Data By Source if (forceUpdate || m_stattree.IsExpanded(time_aap_up_hd[mx][2])) { @@ -1804,21 +1733,20 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) uint64 DataSourceFile = (uint64)(thePrefs.GetCumUpData_File() * avgModifier[mx]); double percentFileTransferred = !DataSourceTotal ? 0 : 100.0 * DataSourceFile / DataSourceTotal; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_DSFILE), (LPCTSTR)CastItoXBytes(DataSourceFile), percentFileTransferred); - m_stattree.SetItemText(time_aap_up_ds[mx][i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_DSFILE), (LPCTSTR)CastItoXBytes(DataSourceFile), percentFileTransferred); + m_stattree.SetItemText(time_aap_up_ds[mx][i], sText); ++i; - uint64 DataSourcePF = (uint64)(thePrefs.GetCumUpData_Partfile() * avgModifier[mx]); percentFileTransferred = !DataSourceTotal ? 0 : 100.0 * DataSourcePF / DataSourceTotal; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_DSPF), (LPCTSTR)CastItoXBytes(DataSourcePF), percentFileTransferred); - m_stattree.SetItemText(time_aap_up_ds[mx][i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_DSPF), (LPCTSTR)CastItoXBytes(DataSourcePF), percentFileTransferred); + m_stattree.SetItemText(time_aap_up_ds[mx][i], sText); } } // Upload Sessions uint32 statGoodSessions = (uint32)((theApp.uploadqueue->GetSuccessfullUpCount() + thePrefs.GetUpSuccessfulSessions() + theApp.uploadqueue->GetUploadQueueLength()) * avgModifier[mx]); uint32 statBadSessions = (uint32)((theApp.uploadqueue->GetFailedUpCount() + thePrefs.GetUpFailedSessions()) * avgModifier[mx]); - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_ULSES), statGoodSessions + statBadSessions); - m_stattree.SetItemText(time_aap_up[mx][1], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_ULSES), statGoodSessions + statBadSessions); + m_stattree.SetItemText(time_aap_up[mx][1], sText); if (forceUpdate || m_stattree.IsExpanded(time_aap_up[mx][1])) { double percentSessions; // Set Successful Upload Sessions @@ -1826,20 +1754,18 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) percentSessions = (100.0 * statGoodSessions) / (statGoodSessions + statBadSessions); else percentSessions = 0; - cbuffer.Format(GetResString(IDS_STATS_SUCCUPCOUNT), statGoodSessions, percentSessions); - m_stattree.SetItemText(time_aap_up_s[mx][0], cbuffer); + sText.Format(GetResString(IDS_STATS_SUCCUPCOUNT), statGoodSessions, percentSessions); + m_stattree.SetItemText(time_aap_up_s[mx][0], sText); // Set Failed Upload Sessions - if (percentSessions != 0 && statBadSessions > 0) - percentSessions = 100 - percentSessions; // There were some good sessions and bad ones... - else if (percentSessions == 0 && statBadSessions > 0) - percentSessions = 100; // There were bad sessions and no good ones, must be 100% + if (statBadSessions > 0) + percentSessions = 100 - percentSessions; // There were bad sessions else - percentSessions = 0; // No sessions at all, or no bad ones. - cbuffer.Format(GetResString(IDS_STATS_FAILUPCOUNT), statBadSessions, percentSessions); - m_stattree.SetItemText(time_aap_up_s[mx][1], cbuffer); + percentSessions = 0; // No bad sessions at all + sText.Format(GetResString(IDS_STATS_FAILUPCOUNT), statBadSessions, percentSessions); + m_stattree.SetItemText(time_aap_up_s[mx][1], sText); } - // Calculate Upline OH Totals + // Calculate Upload OH Totals uint64 UpOHTotal = (uint64)((theStats.GetUpDataOverheadFileRequest() + theStats.GetUpDataOverheadSourceExchange() + theStats.GetUpDataOverheadServer() @@ -1854,33 +1780,33 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) ) * avgModifier[mx]); // Set Cumulative Total Overhead - cbuffer.Format(GetResString(IDS_TOVERHEAD), (LPCTSTR)CastItoXBytes(UpOHTotal + ((uint64)thePrefs.GetUpOverheadTotal() * avgModifier[mx])), (LPCTSTR)CastItoIShort((uint64)(UpOHTotalPackets + ((uint64)thePrefs.GetUpOverheadTotalPackets() * avgModifier[mx])))); - m_stattree.SetItemText(time_aap_up[mx][2], cbuffer); + sText.Format(GetResString(IDS_TOVERHEAD), (LPCTSTR)CastItoXBytes(UpOHTotal + ((uint64)thePrefs.GetUpOverheadTotal() * avgModifier[mx])), (LPCTSTR)CastItoIShort((uint64)(UpOHTotalPackets + ((uint64)thePrefs.GetUpOverheadTotalPackets() * avgModifier[mx])))); + m_stattree.SetItemText(time_aap_up[mx][2], sText); if (forceUpdate || m_stattree.IsExpanded(time_aap_up[mx][2])) { int i = 0; // Set up total file req OH - cbuffer.Format(GetResString(IDS_FROVERHEAD), (LPCTSTR)CastItoXBytes((uint64)(theStats.GetUpDataOverheadFileRequest() + thePrefs.GetUpOverheadFileReq()) * avgModifier[mx]), (LPCTSTR)CastItoIShort((uint64)(theStats.GetUpDataOverheadFileRequestPackets() + thePrefs.GetUpOverheadFileReqPackets()) * avgModifier[mx])); - m_stattree.SetItemText(time_aap_up_oh[mx][i], cbuffer); + sText.Format(GetResString(IDS_FROVERHEAD), (LPCTSTR)CastItoXBytes((uint64)(theStats.GetUpDataOverheadFileRequest() + thePrefs.GetUpOverheadFileReq()) * avgModifier[mx]), (LPCTSTR)CastItoIShort((uint64)(theStats.GetUpDataOverheadFileRequestPackets() + thePrefs.GetUpOverheadFileReqPackets()) * avgModifier[mx])); + m_stattree.SetItemText(time_aap_up_oh[mx][i], sText); ++i; // Set up total source exch OH - cbuffer.Format(GetResString(IDS_SSOVERHEAD), (LPCTSTR)CastItoXBytes((uint64)(theStats.GetUpDataOverheadSourceExchange() + thePrefs.GetUpOverheadSrcEx()) * avgModifier[mx]), (LPCTSTR)CastItoIShort((uint64)(theStats.GetUpDataOverheadSourceExchangePackets() + thePrefs.GetUpOverheadSrcExPackets()) * avgModifier[mx])); - m_stattree.SetItemText(time_aap_up_oh[mx][i], cbuffer); + sText.Format(GetResString(IDS_SSOVERHEAD), (LPCTSTR)CastItoXBytes((uint64)(theStats.GetUpDataOverheadSourceExchange() + thePrefs.GetUpOverheadSrcEx()) * avgModifier[mx]), (LPCTSTR)CastItoIShort((uint64)(theStats.GetUpDataOverheadSourceExchangePackets() + thePrefs.GetUpOverheadSrcExPackets()) * avgModifier[mx])); + m_stattree.SetItemText(time_aap_up_oh[mx][i], sText); ++i; // Set up total server OH - cbuffer.Format(GetResString(IDS_SOVERHEAD) + sText.Format(GetResString(IDS_SOVERHEAD) , (LPCTSTR)CastItoXBytes((theStats.GetUpDataOverheadServer() + thePrefs.GetUpOverheadServer()) * avgModifier[mx]) , (LPCTSTR)CastItoIShort((uint64)(theStats.GetUpDataOverheadServerPackets() + thePrefs.GetUpOverheadServerPackets()) * avgModifier[mx])); - m_stattree.SetItemText(time_aap_up_oh[mx][i], cbuffer); + m_stattree.SetItemText(time_aap_up_oh[mx][i], sText); ++i; // Set up total Kad OH - cbuffer.Format(GetResString(IDS_KADOVERHEAD) + sText.Format(GetResString(IDS_KADOVERHEAD) , (LPCTSTR)CastItoXBytes((uint64)(theStats.GetUpDataOverheadKad() + thePrefs.GetUpOverheadKad()) * avgModifier[mx]) , (LPCTSTR)CastItoIShort((uint64)(theStats.GetUpDataOverheadKadPackets() + thePrefs.GetUpOverheadKadPackets()) * avgModifier[mx])); - m_stattree.SetItemText(time_aap_up_oh[mx][i], cbuffer); + m_stattree.SetItemText(time_aap_up_oh[mx][i], sText); } } // - End Time Statistics -> Projected Averages -> Time Period -> Uploads Section // TIME STATISTICS -> PROJECTED AVERAGES -> TIME PERIOD -> DOWNLOADS SECTION @@ -1888,8 +1814,8 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) CDownloadQueue::SDownloadStats myStats; theApp.downloadqueue->GetDownloadSourcesStats(myStats); // Downloaded Data - cbuffer.Format(GetResString(IDS_STATS_DDATA), (LPCTSTR)CastItoXBytes((uint64)(theStats.sessionReceivedBytes + thePrefs.GetTotalDownloaded()) * avgModifier[mx])); - m_stattree.SetItemText(time_aap_down[mx][0], cbuffer); + sText.Format(GetResString(IDS_STATS_DDATA), (LPCTSTR)CastItoXBytes((uint64)(theStats.sessionReceivedBytes + thePrefs.GetTotalDownloaded()) * avgModifier[mx])); + m_stattree.SetItemText(time_aap_down[mx][0], sText); if (forceUpdate || m_stattree.IsExpanded(time_aap_down[mx][0])) { // Downloaded Data By Client if (forceUpdate || m_stattree.IsExpanded(time_aap_down_hd[mx][0])) { @@ -1901,71 +1827,64 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("eMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(time_aap_down_dc[mx][i], cbuffer); + sText.Format(_T("eMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(time_aap_down_dc[mx][i], sText); ++i; - DownDataClient = (uint64)(thePrefs.GetCumDownData_EDONKEYHYBRID() * avgModifier[mx]); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("eD Hybrid: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(time_aap_down_dc[mx][i], cbuffer); + sText.Format(_T("eD Hybrid: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(time_aap_down_dc[mx][i], sText); ++i; - DownDataClient = (uint64)(thePrefs.GetCumDownData_EDONKEY() * avgModifier[mx]); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("eDonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(time_aap_down_dc[mx][i], cbuffer); + sText.Format(_T("eDonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(time_aap_down_dc[mx][i], sText); ++i; - DownDataClient = (uint64)(thePrefs.GetCumDownData_AMULE() * avgModifier[mx]); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("aMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(time_aap_down_dc[mx][i], cbuffer); + sText.Format(_T("aMule: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(time_aap_down_dc[mx][i], sText); ++i; - DownDataClient = (uint64)(thePrefs.GetCumDownData_MLDONKEY() * avgModifier[mx]); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("MLdonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(time_aap_down_dc[mx][i], cbuffer); + sText.Format(_T("MLdonkey: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(time_aap_down_dc[mx][i], sText); ++i; - DownDataClient = (uint64)(thePrefs.GetCumDownData_SHAREAZA() * avgModifier[mx]); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("Shareaza: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(time_aap_down_dc[mx][i], cbuffer); + sText.Format(_T("Shareaza: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(time_aap_down_dc[mx][i], sText); ++i; - DownDataClient = (uint64)(thePrefs.GetCumDownData_EMULECOMPAT() * avgModifier[mx]); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("eM Compat: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(time_aap_down_dc[mx][i], cbuffer); + sText.Format(_T("eM Compat: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(time_aap_down_dc[mx][i], sText); ++i; - DownDataClient = (uint64)(thePrefs.GetCumDownData_URL() * avgModifier[mx]); if (DownDataTotal != 0 && DownDataClient != 0) percentClientTransferred = 100.0 * DownDataClient / DownDataTotal; else percentClientTransferred = 0; - cbuffer.Format(_T("URL: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); - m_stattree.SetItemText(time_aap_down_dc[mx][i], cbuffer); + sText.Format(_T("URL: %s (%1.1f%%)"), (LPCTSTR)CastItoXBytes(DownDataClient), percentClientTransferred); + m_stattree.SetItemText(time_aap_down_dc[mx][i], sText); } // Downloaded Data By Port if (forceUpdate || m_stattree.IsExpanded(time_aap_down_hd[mx][1])) { @@ -1980,34 +1899,34 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) percentPortTransferred = 100.0 * PortDataDefault / PortDataTotal; else percentPortTransferred = 0; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTDEF), (LPCTSTR)CastItoXBytes(PortDataDefault), percentPortTransferred); - m_stattree.SetItemText(time_aap_down_dp[mx][i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTDEF), (LPCTSTR)CastItoXBytes(PortDataDefault), percentPortTransferred); + m_stattree.SetItemText(time_aap_down_dp[mx][i], sText); ++i; if (PortDataTotal != 0 && PortDataOther != 0) percentPortTransferred = 100.0 * PortDataOther / PortDataTotal; else percentPortTransferred = 0; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataOther), percentPortTransferred); - m_stattree.SetItemText(time_aap_down_dp[mx][i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataOther), percentPortTransferred); + m_stattree.SetItemText(time_aap_down_dp[mx][i], sText); ++i; if (PortDataTotal != 0 && PortDataPeerCache != 0) percentPortTransferred = 100.0 * PortDataPeerCache / PortDataTotal; else percentPortTransferred = 0; - cbuffer.Format(_T("%s: %s (%1.1f%%)"), thePrefs.GetPeerCacheShow() ? _T("PeerCache") : (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataPeerCache), percentPortTransferred); - m_stattree.SetItemText(time_aap_down_dp[mx][i], cbuffer); + sText.Format(_T("%s: %s (%1.1f%%)"), thePrefs.GetPeerCacheShow() ? _T("PeerCache") : (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), (LPCTSTR)CastItoXBytes(PortDataPeerCache), percentPortTransferred); + m_stattree.SetItemText(time_aap_down_dp[mx][i], sText); } } // Set Cum Completed Downloads - cbuffer.Format(_T("%s: %I64u"), (LPCTSTR)GetResString(IDS_STATS_COMPDL), (uint64)(thePrefs.GetDownCompletedFiles() * avgModifier[mx])); - m_stattree.SetItemText(time_aap_down[mx][1], cbuffer); + sText.Format(_T("%s: %I64u"), (LPCTSTR)GetResString(IDS_STATS_COMPDL), (uint64)(thePrefs.GetDownCompletedFiles() * avgModifier[mx])); + m_stattree.SetItemText(time_aap_down[mx][1], sText); // Set Cum Download Sessions - uint32 statGoodSessions = (uint32)((thePrefs.GetDownC_SuccessfulSessions() + myStats.a[1]) * avgModifier[mx]); - uint32 statBadSessions = (uint32)(thePrefs.GetDownC_FailedSessions() * avgModifier[mx]); - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_DLSES), statGoodSessions + statBadSessions); - m_stattree.SetItemText(time_aap_down[mx][2], cbuffer); + uint32 statGoodSessions = (uint32)((thePrefs.GetDownC_SuccessfulSessions() + myStats.a[1]) * avgModifier[mx]); + uint32 statBadSessions = (uint32)(thePrefs.GetDownC_FailedSessions() * avgModifier[mx]); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_DLSES), statGoodSessions + statBadSessions); + m_stattree.SetItemText(time_aap_down[mx][2], sText); if (forceUpdate || m_stattree.IsExpanded(time_aap_down[mx][2])) { double percentSessions; // Set Cum Successful Download Sessions @@ -2015,8 +1934,8 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) percentSessions = 100.0 * statGoodSessions / (statGoodSessions + statBadSessions); else percentSessions = 0; - cbuffer.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_SDLSES), statGoodSessions, percentSessions); - m_stattree.SetItemText(time_aap_down_s[mx][0], cbuffer); // Set Successful Sessions + sText.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_SDLSES), statGoodSessions, percentSessions); + m_stattree.SetItemText(time_aap_down_s[mx][0], sText); // Set Successful Sessions // Set Cum Failed Download Sessions if (percentSessions != 0 && statBadSessions > 0) percentSessions = 100 - percentSessions; // There were some good sessions and bad ones... @@ -2024,18 +1943,18 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) percentSessions = 100; // There were bad sessions and no good ones, must be 100% else percentSessions = 0; // No sessions at all, or no bad ones. - cbuffer.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_FDLSES), statBadSessions, percentSessions); - m_stattree.SetItemText(time_aap_down_s[mx][1], cbuffer); + sText.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_FDLSES), statBadSessions, percentSessions); + m_stattree.SetItemText(time_aap_down_s[mx][1], sText); } // Set Cumulative Gained Due To Compression - cbuffer.Format(GetResString(IDS_STATS_GAINCOMP), (LPCTSTR)CastItoXBytes((uint64)(thePrefs.GetSesSavedFromCompression() + thePrefs.GetCumSavedFromCompression()) * avgModifier[mx])); - m_stattree.SetItemText(time_aap_down[mx][3], cbuffer); + sText.Format(GetResString(IDS_STATS_GAINCOMP), (LPCTSTR)CastItoXBytes((uint64)(thePrefs.GetSesSavedFromCompression() + thePrefs.GetCumSavedFromCompression()) * avgModifier[mx])); + m_stattree.SetItemText(time_aap_down[mx][3], sText); // Set Cumulative Lost Due To Corruption - cbuffer.Format(GetResString(IDS_STATS_LOSTCORRUPT), (LPCTSTR)CastItoXBytes((uint64)(thePrefs.GetSesLostFromCorruption() + thePrefs.GetCumLostFromCorruption()) * avgModifier[mx])); - m_stattree.SetItemText(time_aap_down[mx][4], cbuffer); + sText.Format(GetResString(IDS_STATS_LOSTCORRUPT), (LPCTSTR)CastItoXBytes((uint64)(thePrefs.GetSesLostFromCorruption() + thePrefs.GetCumLostFromCorruption()) * avgModifier[mx])); + m_stattree.SetItemText(time_aap_down[mx][4], sText); // Set Cumulative Saved Due To ICH - cbuffer.Format(GetResString(IDS_STATS_ICHSAVED), (uint32)((thePrefs.GetSesPartsSavedByICH() + thePrefs.GetCumPartsSavedByICH()) * avgModifier[mx])); - m_stattree.SetItemText(time_aap_down[mx][5], cbuffer); + sText.Format(GetResString(IDS_STATS_ICHSAVED), (uint32)((thePrefs.GetSesPartsSavedByICH() + thePrefs.GetCumPartsSavedByICH()) * avgModifier[mx])); + m_stattree.SetItemText(time_aap_down[mx][5], sText); uint64 DownOHTotal = theStats.GetDownDataOverheadFileRequest() + theStats.GetDownDataOverheadSourceExchange() @@ -2048,33 +1967,33 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) + theStats.GetDownDataOverheadKadPackets() + theStats.GetDownDataOverheadOtherPackets(); // Total Overhead - cbuffer.Format(GetResString(IDS_TOVERHEAD), (LPCTSTR)CastItoXBytes((uint64)(DownOHTotal + thePrefs.GetDownOverheadTotal()) * avgModifier[mx]), (LPCTSTR)CastItoIShort((uint64)(DownOHTotalPackets + thePrefs.GetDownOverheadTotalPackets()) * avgModifier[mx])); - m_stattree.SetItemText(time_aap_down[mx][6], cbuffer); + sText.Format(GetResString(IDS_TOVERHEAD), (LPCTSTR)CastItoXBytes((uint64)(DownOHTotal + thePrefs.GetDownOverheadTotal()) * avgModifier[mx]), (LPCTSTR)CastItoIShort((uint64)(DownOHTotalPackets + thePrefs.GetDownOverheadTotalPackets()) * avgModifier[mx])); + m_stattree.SetItemText(time_aap_down[mx][6], sText); if (forceUpdate || m_stattree.IsExpanded(time_aap_down[mx][6])) { int i = 0; // File Request Overhead - cbuffer.Format(GetResString(IDS_FROVERHEAD), (LPCTSTR)CastItoXBytes((uint64)(theStats.GetDownDataOverheadFileRequest() + thePrefs.GetDownOverheadFileReq()) * avgModifier[mx]), (LPCTSTR)CastItoIShort((uint64)(theStats.GetDownDataOverheadFileRequestPackets() + thePrefs.GetDownOverheadFileReqPackets()) * avgModifier[mx])); - m_stattree.SetItemText(time_aap_down_oh[mx][i], cbuffer); + sText.Format(GetResString(IDS_FROVERHEAD), (LPCTSTR)CastItoXBytes((uint64)(theStats.GetDownDataOverheadFileRequest() + thePrefs.GetDownOverheadFileReq()) * avgModifier[mx]), (LPCTSTR)CastItoIShort((uint64)(theStats.GetDownDataOverheadFileRequestPackets() + thePrefs.GetDownOverheadFileReqPackets()) * avgModifier[mx])); + m_stattree.SetItemText(time_aap_down_oh[mx][i], sText); ++i; // Source Exchange Overhead - cbuffer.Format(GetResString(IDS_SSOVERHEAD), (LPCTSTR)CastItoXBytes((uint64)(theStats.GetDownDataOverheadSourceExchange() + thePrefs.GetDownOverheadSrcEx()) * avgModifier[mx]), (LPCTSTR)CastItoIShort((uint64)(theStats.GetDownDataOverheadSourceExchangePackets() + thePrefs.GetDownOverheadSrcExPackets()) * avgModifier[mx])); - m_stattree.SetItemText(time_aap_down_oh[mx][i], cbuffer); + sText.Format(GetResString(IDS_SSOVERHEAD), (LPCTSTR)CastItoXBytes((uint64)(theStats.GetDownDataOverheadSourceExchange() + thePrefs.GetDownOverheadSrcEx()) * avgModifier[mx]), (LPCTSTR)CastItoIShort((uint64)(theStats.GetDownDataOverheadSourceExchangePackets() + thePrefs.GetDownOverheadSrcExPackets()) * avgModifier[mx])); + m_stattree.SetItemText(time_aap_down_oh[mx][i], sText); ++i; // Server Overhead - cbuffer.Format(GetResString(IDS_SOVERHEAD) + sText.Format(GetResString(IDS_SOVERHEAD) , (LPCTSTR)CastItoXBytes((uint64)(theStats.GetDownDataOverheadServer() + thePrefs.GetDownOverheadServer()) * avgModifier[mx]) , (LPCTSTR)CastItoIShort((uint64)(theStats.GetDownDataOverheadServerPackets() + + thePrefs.GetDownOverheadServerPackets()) * avgModifier[mx])); - m_stattree.SetItemText(time_aap_down_oh[mx][i], cbuffer); + m_stattree.SetItemText(time_aap_down_oh[mx][i], sText); ++i; // Kad Overhead - cbuffer.Format(GetResString(IDS_KADOVERHEAD) + sText.Format(GetResString(IDS_KADOVERHEAD) , (LPCTSTR)CastItoXBytes((uint64)(theStats.GetDownDataOverheadKad() + thePrefs.GetDownOverheadKad()) * avgModifier[mx]) , (LPCTSTR)CastItoIShort((uint64)(theStats.GetDownDataOverheadKadPackets() + thePrefs.GetDownOverheadKadPackets()) * avgModifier[mx])); - m_stattree.SetItemText(time_aap_down_oh[mx][i], cbuffer); + m_stattree.SetItemText(time_aap_down_oh[mx][i], sText); } } // - End Time Statistics -> Projected Averages -> Time Period -> Downloads Section } // - End Time Statistics -> Projected Averages -> Time Period Sections @@ -2084,18 +2003,18 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) // CLIENTS SECTION - // Note: This section now has dynamic tree items. This technique + // Note: This section has dynamic tree items. This technique // may appear in other areas, however, there is usually an - // advantage to displaying 0 data items. Here, with the versions + // advantage compared to displaying 0 data items. Here, with the versions // being displayed the way they are, it makes sense. // Who wants to stare at totally blank tree items? ;) if (forceUpdate || m_stattree.IsExpanded(h_clients)) { - CMap clientVersionEDonkey; - CMap clientVersionEDonkeyHybrid; - CMap clientVersionEMule; - CMap clientVersionAMule; - uint32 totalclient; - int myStats[NUM_CLIENTLIST_STATS]; + CClientVersionMap clientVersionEDonkey; + CClientVersionMap clientVersionEDonkeyHybrid; + CClientVersionMap clientVersionEMule; + CClientVersionMap clientVersionAMule; + uint32 totalclient; + int myStats[NUM_CLIENTLIST_STATS]; theApp.clientlist->GetStatistics(totalclient , myStats @@ -2104,82 +2023,75 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) , clientVersionEMule , clientVersionAMule); - cbuffer.Format(_T("%s: %u "), (LPCTSTR)GetResString(IDS_CLIENTLIST), totalclient); - m_stattree.SetItemText(cligen[5], cbuffer); + sText.Format(_T("%s: %u "), (LPCTSTR)GetResString(IDS_CLIENTLIST), totalclient); + m_stattree.SetItemText(cligen[5], sText); int SIclients = myStats[12] + myStats[13]; - cbuffer.Format(_T("%s: %i (%.1f%%) : %i (%.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_SECUREIDENT), myStats[12], (SIclients > 0) ? (100.0 * myStats[12] / SIclients) : 0, myStats[13], (SIclients > 0) ? (100.0 * myStats[13] / SIclients) : 0.0); - m_stattree.SetItemText(cligen[3], cbuffer); + sText.Format(_T("%s: %i (%.1f%%) : %i (%.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_SECUREIDENT), myStats[12], (SIclients > 0) ? (100.0 * myStats[12] / SIclients) : 0, myStats[13], (SIclients > 0) ? (100.0 * myStats[13] / SIclients) : 0.0); + m_stattree.SetItemText(cligen[3], sText); double perc = totalclient > 0 ? 100.0 / totalclient : 0.0; - cbuffer.Format(_T("%s: %i (%.1f%%)"), (LPCTSTR)GetResString(IDS_IDLOW), myStats[14], perc*myStats[14]); - m_stattree.SetItemText(cligen[4], cbuffer); + sText.Format(_T("%s: %i (%.1f%%)"), (LPCTSTR)GetResString(IDS_IDLOW), myStats[14], perc * myStats[14]); + m_stattree.SetItemText(cligen[4], sText); // CLIENTS -> CLIENT SOFTWARE SECTION if (forceUpdate || m_stattree.IsExpanded(hclisoft)) { - cbuffer.Format(_T("eMule: %i (%1.1f%%)"), myStats[2], perc*myStats[2]); - m_stattree.SetItemText(clisoft[0], cbuffer); - cbuffer.Format(_T("eD Hybrid: %i (%1.1f%%)"), myStats[4], perc*myStats[4]); - m_stattree.SetItemText(clisoft[1], cbuffer); - cbuffer.Format(_T("eDonkey: %i (%1.1f%%)"), myStats[1], perc*myStats[1]); - m_stattree.SetItemText(clisoft[2], cbuffer); - cbuffer.Format(_T("aMule: %i (%1.1f%%)"), myStats[10], perc*myStats[10]); - m_stattree.SetItemText(clisoft[3], cbuffer); - cbuffer.Format(_T("MLdonkey: %i (%1.1f%%)"), myStats[3], perc*myStats[3]); - m_stattree.SetItemText(clisoft[4], cbuffer); - cbuffer.Format(_T("Shareaza: %i (%1.1f%%)"), myStats[11], perc*myStats[11]); - m_stattree.SetItemText(clisoft[5], cbuffer); - cbuffer.Format(_T("eM Compat: %i (%1.1f%%)"), myStats[5], perc*myStats[5]); - m_stattree.SetItemText(clisoft[6], cbuffer); - cbuffer.Format(GetResString(IDS_STATS_UNKNOWNCLIENT), myStats[0]); - cbuffer.AppendFormat(_T(" (%1.1f%%)"), perc * myStats[0]); - m_stattree.SetItemText(clisoft[7], cbuffer); + sText.Format(_T("eMule: %i (%1.1f%%)"), myStats[2], perc * myStats[2]); + m_stattree.SetItemText(clisoft[0], sText); + sText.Format(_T("eD Hybrid: %i (%1.1f%%)"), myStats[4], perc * myStats[4]); + m_stattree.SetItemText(clisoft[1], sText); + sText.Format(_T("eDonkey: %i (%1.1f%%)"), myStats[1], perc * myStats[1]); + m_stattree.SetItemText(clisoft[2], sText); + sText.Format(_T("aMule: %i (%1.1f%%)"), myStats[10], perc * myStats[10]); + m_stattree.SetItemText(clisoft[3], sText); + sText.Format(_T("MLdonkey: %i (%1.1f%%)"), myStats[3], perc * myStats[3]); + m_stattree.SetItemText(clisoft[4], sText); + sText.Format(_T("Shareaza: %i (%1.1f%%)"), myStats[11], perc * myStats[11]); + m_stattree.SetItemText(clisoft[5], sText); + sText.Format(_T("eM Compat: %i (%1.1f%%)"), myStats[5], perc * myStats[5]); + m_stattree.SetItemText(clisoft[6], sText); + sText.Format(GetResString(IDS_STATS_UNKNOWNCLIENT), myStats[0]); + sText.AppendFormat(_T(" (%1.1f%%)"), perc * myStats[0]); + m_stattree.SetItemText(clisoft[7], sText); // CLIENTS -> CLIENT SOFTWARE -> EMULE SECTION if (forceUpdate || m_stattree.IsExpanded(clisoft[0]) || cli_lastCount[0] == 0) { uint32 verCount = 0; //--- find top 4 eMule client versions --- - uint32 currtopcnt = 0; - uint32 currtopver = 0; uint32 totalOther = 0; for (uint32 i = 0; i < MAX_SUB_CLIENT_VERSIONS; ++i) { + uint32 currtopcnt = 0; + uint32 currtopver = 0; uint32 topver = 0; uint32 topcnt = 0; double topper = 0.0; - for (POSITION pos = clientVersionEMule.GetStartPosition(); pos != NULL;) { - uint32 ver; - uint32 cnt; - clientVersionEMule.GetNextAssoc(pos, ver, cnt); + for (const CClientVersionMap::CPair *pair = clientVersionEMule.PGetFirstAssoc(); pair != NULL; pair = clientVersionEMule.PGetNextAssoc(pair)) { + uint32 ver = pair->key; + uint32 cnt = pair->value; if (currtopcnt < cnt) { topper = (double)cnt / myStats[2]; - topver = ver; - topcnt = cnt; - currtopcnt = cnt; - currtopver = ver; - } else if (currtopcnt == cnt && currtopver < ver) { - topver = ver; - currtopver = ver; - } + topver = currtopver = ver; + topcnt = currtopcnt = cnt; + } else if (currtopcnt == cnt && currtopver < ver) + topver = currtopver = ver; } - currtopcnt = 0; - currtopver = 0; clientVersionEMule.RemoveKey(topver); if (!topcnt) continue; - + UINT verMaj = topver / (100 * 10 * 100); UINT verMin = (topver - (verMaj * 100 * 10 * 100)) / (100 * 10); UINT verUp = (topver - (verMaj * 100 * 10 * 100) - (verMin * 100 * 10)) / (100); if (topver >= MAKE_CLIENT_VERSION(0, 40, 0) || verUp != 0) { if (verUp <= 'z' - 'a') - cbuffer.Format(_T("v%u.%u%c: %u (%1.1f%%)"), verMaj, verMin, _T('a') + verUp, topcnt, topper * 100); + sText.Format(_T("v%u.%u%c: %u (%1.1f%%)"), verMaj, verMin, _T('a') + verUp, topcnt, topper * 100); else - cbuffer.Format(_T("v%u.%u.%u: %u (%1.1f%%)"), verMaj, verMin, verUp, topcnt, topper * 100); + sText.Format(_T("v%u.%u.%u: %u (%1.1f%%)"), verMaj, verMin, verUp, topcnt, topper * 100); } else - cbuffer.Format(_T("v%u.%u: %u (%1.1f%%)"), verMaj, verMin, topcnt, topper * 100); - + sText.Format(_T("v%u.%u: %u (%1.1f%%)"), verMaj, verMin, topcnt, topper * 100); + if (i >= MAX_SUB_CLIENT_VERSIONS / 2) totalOther += topcnt; @@ -2187,17 +2099,17 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) if (i == MAX_SUB_CLIENT_VERSIONS / 2) cli_other[0] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), clisoft[0]); if (i >= MAX_SUB_CLIENT_VERSIONS / 2) - cli_versions[MAX_SUB_CLIENT_VERSIONS * 0 + i] = m_stattree.InsertItem(cbuffer, cli_other[0]); + cli_versions[MAX_SUB_CLIENT_VERSIONS * 0 + i] = m_stattree.InsertItem(sText, cli_other[0]); else - cli_versions[MAX_SUB_CLIENT_VERSIONS * 0 + i] = m_stattree.InsertItem(cbuffer, clisoft[0]); + cli_versions[MAX_SUB_CLIENT_VERSIONS * 0 + i] = m_stattree.InsertItem(sText, clisoft[0]); } else - m_stattree.SetItemText(cli_versions[MAX_SUB_CLIENT_VERSIONS * 0 + i], cbuffer); + m_stattree.SetItemText(cli_versions[MAX_SUB_CLIENT_VERSIONS * 0 + i], sText); ++verCount; } if (verCount > MAX_SUB_CLIENT_VERSIONS / 2) { - cbuffer.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_MINORCLIENTS), totalOther, 100.0 * totalOther / myStats[2]); - m_stattree.SetItemText(cli_other[0], cbuffer); + sText.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_MINORCLIENTS), totalOther, 100.0 * totalOther / myStats[2]); + m_stattree.SetItemText(cli_other[0], sText); } if (verCount < cli_lastCount[0]) for (uint32 i = 0; i < cli_lastCount[0] - verCount; ++i) { @@ -2209,36 +2121,28 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) cli_lastCount[0] = verCount; } // End Clients -> Client Software -> eMule Section - // CLIENTS -> CLIENT SOFTWARE -> eD HYBRID SECTION if (forceUpdate || m_stattree.IsExpanded(clisoft[1]) || cli_lastCount[1] == 0) { uint32 verCount = 0; //--- find top 4 eD Hybrid client versions --- - uint32 currtopcnt = 0; - uint32 currtopver = 0; uint32 totalOther = 0; for (uint32 i = 0; i < MAX_SUB_CLIENT_VERSIONS; ++i) { + uint32 currtopcnt = 0; + uint32 currtopver = 0; uint32 topver = 0; uint32 topcnt = 0; double topper = 0.0; - for (POSITION pos = clientVersionEDonkeyHybrid.GetStartPosition(); pos != NULL;) { - uint32 ver; - uint32 cnt; - clientVersionEDonkeyHybrid.GetNextAssoc(pos, ver, cnt); + for (const CClientVersionMap::CPair *pair = clientVersionEDonkeyHybrid.PGetFirstAssoc(); pair != NULL; pair = clientVersionEDonkeyHybrid.PGetNextAssoc(pair)) { + uint32 ver = pair->key; + uint32 cnt = pair->value; if (currtopcnt < cnt) { topper = (double)cnt / myStats[4]; - topver = ver; - topcnt = cnt; - currtopcnt = cnt; - currtopver = ver; - } else if (currtopcnt == cnt && currtopver < ver) { - topver = ver; - currtopver = ver; - } + topver = currtopver = ver; + topcnt = currtopcnt = cnt; + } else if (currtopcnt == cnt && currtopver < ver) + topver = currtopver = ver; } - currtopcnt = 0; - currtopver = 0; clientVersionEDonkeyHybrid.RemoveKey(topver); if (!topcnt) @@ -2247,7 +2151,7 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) UINT verMaj = topver / (100 * 10 * 100); UINT verMin = (topver - (verMaj * 100 * 10 * 100)) / (100 * 10); UINT verUp = (topver - (verMaj * 100 * 10 * 100) - (verMin * 100 * 10)) / (100); - cbuffer.Format(_T("v%u.%u.%u: %u (%1.1f%%)"), verMaj, verMin, verUp, topcnt, topper * 100); + sText.Format(_T("v%u.%u.%u: %u (%1.1f%%)"), verMaj, verMin, verUp, topcnt, topper * 100); if (i >= MAX_SUB_CLIENT_VERSIONS / 2) totalOther += topcnt; @@ -2256,17 +2160,17 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) if (i == MAX_SUB_CLIENT_VERSIONS / 2) cli_other[1] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), clisoft[1]); if (i >= MAX_SUB_CLIENT_VERSIONS / 2) - cli_versions[MAX_SUB_CLIENT_VERSIONS * 1 + i] = m_stattree.InsertItem(cbuffer, cli_other[1]); + cli_versions[MAX_SUB_CLIENT_VERSIONS * 1 + i] = m_stattree.InsertItem(sText, cli_other[1]); else - cli_versions[MAX_SUB_CLIENT_VERSIONS * 1 + i] = m_stattree.InsertItem(cbuffer, clisoft[1]); + cli_versions[MAX_SUB_CLIENT_VERSIONS * 1 + i] = m_stattree.InsertItem(sText, clisoft[1]); } else - m_stattree.SetItemText(cli_versions[MAX_SUB_CLIENT_VERSIONS * 1 + i], cbuffer); + m_stattree.SetItemText(cli_versions[MAX_SUB_CLIENT_VERSIONS * 1 + i], sText); ++verCount; } if (verCount > MAX_SUB_CLIENT_VERSIONS / 2) { - cbuffer.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_MINORCLIENTS), totalOther, 100.0 * totalOther / myStats[4]); - m_stattree.SetItemText(cli_other[1], cbuffer); + sText.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_MINORCLIENTS), totalOther, 100.0 * totalOther / myStats[4]); + m_stattree.SetItemText(cli_other[1], sText); } if (verCount < cli_lastCount[1]) for (uint32 i = 0; i < cli_lastCount[1] - verCount; ++i) { @@ -2278,45 +2182,37 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) cli_lastCount[1] = verCount; } // End Clients -> Client Software -> eD Hybrid Section - // CLIENTS -> CLIENT SOFTWARE -> EDONKEY SECTION if (forceUpdate || m_stattree.IsExpanded(clisoft[2]) || cli_lastCount[2] == 0) { uint32 verCount = 0; //--- find top 4 eDonkey client versions --- - uint32 currtopcnt = 0; - uint32 currtopver = 0; uint32 totalOther = 0; for (uint32 i = 0; i < MAX_SUB_CLIENT_VERSIONS; ++i) { + uint32 currtopcnt = 0; + uint32 currtopver = 0; uint32 topver = 0; uint32 topcnt = 0; double topper = 0.0; - for (POSITION pos = clientVersionEDonkey.GetStartPosition(); pos != NULL;) { - uint32 ver; - uint32 cnt; - clientVersionEDonkey.GetNextAssoc(pos, ver, cnt); + for (const CClientVersionMap::CPair *pair = clientVersionEDonkey.PGetFirstAssoc(); pair != NULL; pair = clientVersionEDonkey.PGetNextAssoc(pair)) { + uint32 ver = pair->key; + uint32 cnt = pair->value; if (currtopcnt < cnt) { topper = (double)cnt / myStats[1]; - topver = ver; - topcnt = cnt; - currtopcnt = cnt; - currtopver = ver; - } else if (currtopcnt == cnt && currtopver < ver) { - topver = ver; - currtopver = ver; - } + topver = currtopver = ver; + topcnt = currtopcnt = cnt; + } else if (currtopcnt == cnt && currtopver < ver) + topver = currtopver = ver; } - currtopcnt = 0; - currtopver = 0; clientVersionEDonkey.RemoveKey(topver); if (!topcnt) continue; - + UINT verMaj = topver / (100 * 10 * 100); UINT verMin = (topver - (verMaj * 100 * 10 * 100)) / (100 * 10); UINT verUp = (topver - (verMaj * 100 * 10 * 100) - (verMin * 100 * 10)) / (100); - cbuffer.Format(_T("v%u.%u.%u: %u (%1.1f%%)"), verMaj, verMin, verUp, topcnt, topper * 100); + sText.Format(_T("v%u.%u.%u: %u (%1.1f%%)"), verMaj, verMin, verUp, topcnt, topper * 100); if (i >= MAX_SUB_CLIENT_VERSIONS / 2) totalOther += topcnt; @@ -2325,17 +2221,17 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) if (i == MAX_SUB_CLIENT_VERSIONS / 2) cli_other[2] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), clisoft[2]); if (i >= MAX_SUB_CLIENT_VERSIONS / 2) - cli_versions[MAX_SUB_CLIENT_VERSIONS * 2 + i] = m_stattree.InsertItem(cbuffer, cli_other[2]); + cli_versions[MAX_SUB_CLIENT_VERSIONS * 2 + i] = m_stattree.InsertItem(sText, cli_other[2]); else - cli_versions[MAX_SUB_CLIENT_VERSIONS * 2 + i] = m_stattree.InsertItem(cbuffer, clisoft[2]); + cli_versions[MAX_SUB_CLIENT_VERSIONS * 2 + i] = m_stattree.InsertItem(sText, clisoft[2]); } else - m_stattree.SetItemText(cli_versions[MAX_SUB_CLIENT_VERSIONS * 2 + i], cbuffer); + m_stattree.SetItemText(cli_versions[MAX_SUB_CLIENT_VERSIONS * 2 + i], sText); ++verCount; } if (verCount > MAX_SUB_CLIENT_VERSIONS / 2) { - cbuffer.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_MINORCLIENTS), totalOther, 100.0 * totalOther / myStats[1]); - m_stattree.SetItemText(cli_other[2], cbuffer); + sText.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_MINORCLIENTS), totalOther, 100.0 * totalOther / myStats[1]); + m_stattree.SetItemText(cli_other[2], sText); } if (verCount < cli_lastCount[2]) for (uint32 i = 0; i < cli_lastCount[2] - verCount; ++i) { @@ -2347,37 +2243,28 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) cli_lastCount[2] = verCount; } // End Clients -> Client Software -> eDonkey Section - // CLIENTS -> CLIENT SOFTWARE -> AMULE SECTION if (forceUpdate || m_stattree.IsExpanded(clisoft[3]) || cli_lastCount[3] == 0) { uint32 verCount = 0; //--- find top 4 client versions --- - uint32 currtopcnt = 0; - uint32 currtopver = 0; uint32 totalOther = 0; for (uint32 i = 0; i < MAX_SUB_CLIENT_VERSIONS; ++i) { - POSITION pos = clientVersionAMule.GetStartPosition(); + uint32 currtopcnt = 0; + uint32 currtopver = 0; uint32 topver = 0; uint32 topcnt = 0; double topper = 0.0; - while (pos) { - uint32 ver; - uint32 cnt; - clientVersionAMule.GetNextAssoc(pos, ver, cnt); + for (const CClientVersionMap::CPair *pair = clientVersionAMule.PGetFirstAssoc(); pair != NULL; pair = clientVersionAMule.PGetNextAssoc(pair)) { + uint32 ver = pair->key; + uint32 cnt = pair->value; if (currtopcnt < cnt) { topper = (double)cnt / myStats[10]; - topver = ver; - topcnt = cnt; - currtopcnt = cnt; - currtopver = ver; - } else if (currtopcnt == cnt && currtopver < ver) { - topver = ver; - currtopver = ver; - } + topver = currtopver = ver; + topcnt = currtopcnt = cnt; + } else if (currtopcnt == cnt && currtopver < ver) + topver = currtopver = ver; } - currtopcnt = 0; - currtopver = 0; clientVersionAMule.RemoveKey(topver); if (!topcnt) @@ -2387,28 +2274,26 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) UINT verMin = (topver - (verMaj * 100 * 10 * 100)) / (100 * 10); UINT verUp = (topver - (verMaj * 100 * 10 * 100) - (verMin * 100 * 10)) / (100); if (topver >= MAKE_CLIENT_VERSION(0, 40, 0) || verUp != 0) - cbuffer.Format(_T("v%u.%u.%u: %u (%1.1f%%)"), verMaj, verMin, verUp, topcnt, topper * 100); + sText.Format(_T("v%u.%u.%u: %u (%1.1f%%)"), verMaj, verMin, verUp, topcnt, topper * 100); else - cbuffer.Format(_T("v%u.%u: %u (%1.1f%%)"), verMaj, verMin, topcnt, topper * 100); - + sText.Format(_T("v%u.%u: %u (%1.1f%%)"), verMaj, verMin, topcnt, topper * 100); if (i >= MAX_SUB_CLIENT_VERSIONS / 2) totalOther += topcnt; - if (i >= cli_lastCount[3]) { if (i == MAX_SUB_CLIENT_VERSIONS / 2) cli_other[3] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), clisoft[3]); if (i >= MAX_SUB_CLIENT_VERSIONS / 2) - cli_versions[MAX_SUB_CLIENT_VERSIONS * 3 + i] = m_stattree.InsertItem(cbuffer, cli_other[3]); + cli_versions[MAX_SUB_CLIENT_VERSIONS * 3 + i] = m_stattree.InsertItem(sText, cli_other[3]); else - cli_versions[MAX_SUB_CLIENT_VERSIONS * 3 + i] = m_stattree.InsertItem(cbuffer, clisoft[3]); + cli_versions[MAX_SUB_CLIENT_VERSIONS * 3 + i] = m_stattree.InsertItem(sText, clisoft[3]); } else - m_stattree.SetItemText(cli_versions[MAX_SUB_CLIENT_VERSIONS * 3 + i], cbuffer); + m_stattree.SetItemText(cli_versions[MAX_SUB_CLIENT_VERSIONS * 3 + i], sText); ++verCount; } if (verCount > MAX_SUB_CLIENT_VERSIONS / 2) { - cbuffer.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_MINORCLIENTS), totalOther, 100.0 * totalOther / myStats[10]); - m_stattree.SetItemText(cli_other[3], cbuffer); + sText.Format(_T("%s: %u (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_MINORCLIENTS), totalOther, 100.0 * totalOther / myStats[10]); + m_stattree.SetItemText(cli_other[3], sText); } if (verCount < cli_lastCount[3]) for (uint32 i = 0; i < cli_lastCount[3] - verCount; ++i) { @@ -2423,55 +2308,53 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) } // - End Clients -> Client Software Section // CLIENTS -> NETWORK SECTION if (forceUpdate || m_stattree.IsExpanded(hclinet)) { - cbuffer.Format(_T("eD2K: %i (%.1f%%)"), myStats[15], perc*myStats[15]); - m_stattree.SetItemText(clinet[0], cbuffer); - cbuffer.Format(_T("Kad: %i (%.1f%%)"), myStats[16], perc*myStats[16]); - m_stattree.SetItemText(clinet[1], cbuffer); - cbuffer.Format(_T("eD2K/Kad: %i (%.1f%%)"), myStats[17], perc*myStats[17]); - m_stattree.SetItemText(clinet[2], cbuffer); - cbuffer.Format(_T("%s: %i (%.1f%%)"), (LPCTSTR)GetResString(IDS_UNKNOWN), myStats[18], perc*myStats[18]); - m_stattree.SetItemText(clinet[3], cbuffer); + sText.Format(_T("eD2K: %i (%.1f%%)"), myStats[15], perc * myStats[15]); + m_stattree.SetItemText(clinet[0], sText); + sText.Format(_T("Kad: %i (%.1f%%)"), myStats[16], perc * myStats[16]); + m_stattree.SetItemText(clinet[1], sText); + sText.Format(_T("eD2K/Kad: %i (%.1f%%)"), myStats[17], perc * myStats[17]); + m_stattree.SetItemText(clinet[2], sText); + sText.Format(_T("%s: %i (%.1f%%)"), (LPCTSTR)GetResString(IDS_UNKNOWN), myStats[18], perc * myStats[18]); + m_stattree.SetItemText(clinet[3], sText); } // End Clients -> Network Section // CLIENTS -> PORT SECTION if (forceUpdate || m_stattree.IsExpanded(hcliport)) { - cbuffer.Format(_T("%s: %i (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTDEF), myStats[8], myStats[8] > 0 ? (100.0 * myStats[8] / (myStats[8] + myStats[9])) : 0); - m_stattree.SetItemText(cliport[0], cbuffer); - cbuffer.Format(_T("%s: %i (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), myStats[9], myStats[9] > 0 ? (100.0 * myStats[9] / (myStats[8] + myStats[9])) : 0); - m_stattree.SetItemText(cliport[1], cbuffer); + sText.Format(_T("%s: %i (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTDEF), myStats[8], myStats[8] > 0 ? (100.0 * myStats[8] / (myStats[8] + myStats[9])) : 0); + m_stattree.SetItemText(cliport[0], sText); + sText.Format(_T("%s: %i (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PRTOTHER), myStats[9], myStats[9] > 0 ? (100.0 * myStats[9] / (myStats[8] + myStats[9])) : 0); + m_stattree.SetItemText(cliport[1], sText); } // - End Clients -> Port Section // CLIENTS -> FIREWALLED (KAD) SECTION if (forceUpdate || m_stattree.IsExpanded(hclifirewalled)) { if (!Kademlia::CKademlia::IsRunning() || Kademlia::CUDPFirewallTester::IsFirewalledUDP(true)) { - cbuffer.Format(_T("UDP: %s"), (LPCTSTR)GetResString(IDS_KAD_UNKNOWN)); - m_stattree.SetItemText(clifirewalled[0], cbuffer); - cbuffer.Format(_T("TCP: %s"), (LPCTSTR)GetResString(IDS_KAD_UNKNOWN)); - m_stattree.SetItemText(clifirewalled[1], cbuffer); + sText.Format(_T("UDP: %s"), (LPCTSTR)GetResString(IDS_KAD_UNKNOWN)); + m_stattree.SetItemText(clifirewalled[0], sText); + sText.Format(_T("TCP: %s"), (LPCTSTR)GetResString(IDS_KAD_UNKNOWN)); + m_stattree.SetItemText(clifirewalled[1], sText); } else { if (Kademlia::CKademlia::GetPrefs()->StatsGetFirewalledRatio(true) > 0) - cbuffer.Format(_T("UDP: %1.1f%%"), Kademlia::CKademlia::GetPrefs()->StatsGetFirewalledRatio(true) * 100); + sText.Format(_T("UDP: %1.1f%%"), Kademlia::CKademlia::GetPrefs()->StatsGetFirewalledRatio(true) * 100); else - cbuffer.Format(_T("UDP: %s"), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); - m_stattree.SetItemText(clifirewalled[0], cbuffer); + sText.Format(_T("UDP: %s"), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); + m_stattree.SetItemText(clifirewalled[0], sText); if (Kademlia::CKademlia::GetPrefs()->StatsGetFirewalledRatio(false) > 0) - cbuffer.Format(_T("TCP: %1.1f%%"), Kademlia::CKademlia::GetPrefs()->StatsGetFirewalledRatio(false) * 100); + sText.Format(_T("TCP: %1.1f%%"), Kademlia::CKademlia::GetPrefs()->StatsGetFirewalledRatio(false) * 100); else - cbuffer.Format(_T("TCP: %s"), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); - m_stattree.SetItemText(clifirewalled[1], cbuffer); + sText.Format(_T("TCP: %s"), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); + m_stattree.SetItemText(clifirewalled[1], sText); } } // - End Clients -> Firewalled (Kad) Section // General Client Statistics - cbuffer.Format(_T("%s: %i (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PROBLEMATIC), myStats[6], perc*myStats[6]); - m_stattree.SetItemText(cligen[0], cbuffer); - - cbuffer.Format(_T("%s: %i"), (LPCTSTR)GetResString(IDS_BANNED), (int)theApp.clientlist->GetBannedCount()); - m_stattree.SetItemText(cligen[1], cbuffer); - - cbuffer.Format(GetResString(IDS_STATS_FILTEREDCLIENTS), theStats.filteredclients); - m_stattree.SetItemText(cligen[2], cbuffer); + sText.Format(_T("%s: %i (%1.1f%%)"), (LPCTSTR)GetResString(IDS_STATS_PROBLEMATIC), myStats[6], perc * myStats[6]); + m_stattree.SetItemText(cligen[0], sText); + sText.Format(_T("%s: %i"), (LPCTSTR)GetResString(IDS_BANNED), (int)theApp.clientlist->GetBannedCount()); + m_stattree.SetItemText(cligen[1], sText); + sText.Format(GetResString(IDS_STATS_FILTEREDCLIENTS), theStats.filteredclients); + m_stattree.SetItemText(cligen[2], sText); } // - END CLIENTS SECTION @@ -2485,45 +2368,45 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) float servocc; theApp.serverlist->GetStatus(servtotal, servfail, servuser, servfile, servlowiduser, servtuser, servtfile, servocc); // Set working servers value - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_SF_WORKING), (LPCTSTR)CastItoIShort(servtotal - servfail)); - m_stattree.SetItemText(srv[0], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_SF_WORKING), (LPCTSTR)CastItoIShort(servtotal - servfail)); + m_stattree.SetItemText(srv[0], sText); if (forceUpdate || m_stattree.IsExpanded(srv[0])) { // Set users on working servers value - cbuffer.Format(_T("%s: %s; %s: %s (%.1f%%)"), (LPCTSTR)GetResString(IDS_SF_WUSER), (LPCTSTR)CastItoIShort(servuser), (LPCTSTR)GetResString(IDS_IDLOW), (LPCTSTR)CastItoIShort(servlowiduser), servuser ? (servlowiduser * 100.0 / servuser) : 0.0); - m_stattree.SetItemText(srv_w[0], cbuffer); + sText.Format(_T("%s: %s; %s: %s (%.1f%%)"), (LPCTSTR)GetResString(IDS_SF_WUSER), (LPCTSTR)CastItoIShort(servuser), (LPCTSTR)GetResString(IDS_IDLOW), (LPCTSTR)CastItoIShort(servlowiduser), servuser ? (servlowiduser * 100.0 / servuser) : 0.0); + m_stattree.SetItemText(srv_w[0], sText); // Set files on working servers value - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_SF_WFILE), (LPCTSTR)CastItoIShort(servfile)); - m_stattree.SetItemText(srv_w[1], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_SF_WFILE), (LPCTSTR)CastItoIShort(servfile)); + m_stattree.SetItemText(srv_w[1], sText); // Set server occ value - cbuffer.Format(GetResString(IDS_SF_SRVOCC), servocc); - m_stattree.SetItemText(srv_w[2], cbuffer); + sText.Format(GetResString(IDS_SF_SRVOCC), servocc); + m_stattree.SetItemText(srv_w[2], sText); } // Set failed servers value - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_SF_FAIL), (LPCTSTR)CastItoIShort(servfail)); - m_stattree.SetItemText(srv[1], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_SF_FAIL), (LPCTSTR)CastItoIShort(servfail)); + m_stattree.SetItemText(srv[1], sText); // Set deleted servers value - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_SF_DELCOUNT), (LPCTSTR)CastItoIShort(theApp.serverlist->GetDeletedServerCount())); - m_stattree.SetItemText(srv[2], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_SF_DELCOUNT), (LPCTSTR)CastItoIShort(theApp.serverlist->GetDeletedServerCount())); + m_stattree.SetItemText(srv[2], sText); // Set total servers value - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_SF_TOTAL), (LPCTSTR)CastItoIShort(servtotal)); - m_stattree.SetItemText(srv[3], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_SF_TOTAL), (LPCTSTR)CastItoIShort(servtotal)); + m_stattree.SetItemText(srv[3], sText); // Set total users value - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_SF_USER), (LPCTSTR)CastItoIShort(servtuser)); - m_stattree.SetItemText(srv[4], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_SF_USER), (LPCTSTR)CastItoIShort(servtuser)); + m_stattree.SetItemText(srv[4], sText); // Set total files value - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_SF_FILE), (LPCTSTR)CastItoIShort(servtfile)); - m_stattree.SetItemText(srv[5], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_SF_FILE), (LPCTSTR)CastItoIShort(servtfile)); + m_stattree.SetItemText(srv[5], sText); // SERVERS -> RECORDS SECTION if (forceUpdate || m_stattree.IsExpanded(hsrv_records)) { // Set most working servers - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_SVRECWORKING), (LPCTSTR)CastItoIShort(thePrefs.GetSrvrsMostWorkingServers())); - m_stattree.SetItemText(srv_r[0], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_SVRECWORKING), (LPCTSTR)CastItoIShort(thePrefs.GetSrvrsMostWorkingServers())); + m_stattree.SetItemText(srv_r[0], sText); // Set most users online - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_SVRECUSERS), (LPCTSTR)CastItoIShort(thePrefs.GetSrvrsMostUsersOnline())); - m_stattree.SetItemText(srv_r[1], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_SVRECUSERS), (LPCTSTR)CastItoIShort(thePrefs.GetSrvrsMostUsersOnline())); + m_stattree.SetItemText(srv_r[1], sText); // Set most files avail - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_SVRECFILES), (LPCTSTR)CastItoIShort(thePrefs.GetSrvrsMostFilesAvail())); - m_stattree.SetItemText(srv_r[2], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_SVRECFILES), (LPCTSTR)CastItoIShort(thePrefs.GetSrvrsMostFilesAvail())); + m_stattree.SetItemText(srv_r[2], sText); } // - End Servers -> Records Section } // - END SERVERS SECTION @@ -2531,44 +2414,42 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) // SHARED FILES SECTION if (forceUpdate || m_stattree.IsExpanded(h_shared)) { // Set Number of Shared Files - cbuffer.Format(GetResString(IDS_SHAREDFILESCOUNT), (int)theApp.sharedfiles->GetCount()); + sText.Format(GetResString(IDS_SHAREDFILESCOUNT), (int)theApp.sharedfiles->GetCount()); // SLUGFILLER: SafeHash - extra statistics if (theApp.sharedfiles->GetHashingCount()) - cbuffer.AppendFormat(GetResString(IDS_HASHINGFILESCOUNT), theApp.sharedfiles->GetHashingCount()); + sText.AppendFormat(GetResString(IDS_HASHINGFILESCOUNT), theApp.sharedfiles->GetHashingCount()); // SLUGFILLER: SafeHash - m_stattree.SetItemText(shar[0], cbuffer); + m_stattree.SetItemText(shar[0], sText); // Set Average File Size - uint64 bytesLargestFile = 0; - uint64 allsize = theApp.sharedfiles->GetDatasize(bytesLargestFile); // Func returns total share size and sets pointer uint64 to largest single file size - CString cbuffer2; - if (theApp.sharedfiles->GetCount() > 0) - cbuffer2 = CastItoXBytes(allsize / (UINT_PTR)theApp.sharedfiles->GetCount()); - else - cbuffer2 = CastItoXBytes((uint32)0); - cbuffer.Format(GetResString(IDS_SF_AVERAGESIZE), (LPCTSTR)cbuffer2); - m_stattree.SetItemText(shar[1], cbuffer); + uint64 bytesLargestFile; + // Func returns total share size and sets pointer uint64 to largest single file size + uint64 allsize = theApp.sharedfiles->GetDatasize(bytesLargestFile); + INT_PTR iCnt = theApp.sharedfiles->GetCount(); + sText.Format(GetResString(IDS_SF_AVERAGESIZE), (LPCTSTR)CastItoXBytes((iCnt > 0) ? allsize / iCnt : 0)); + m_stattree.SetItemText(shar[1], sText); + // Set Largest File Size - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_LARGESTFILE), (LPCTSTR)CastItoXBytes(bytesLargestFile)); - m_stattree.SetItemText(shar[2], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_LARGESTFILE), (LPCTSTR)CastItoXBytes(bytesLargestFile)); + m_stattree.SetItemText(shar[2], sText); // Set Total Share Size - cbuffer.Format(GetResString(IDS_SF_SIZE), (LPCTSTR)CastItoXBytes(allsize)); - m_stattree.SetItemText(shar[3], cbuffer); + sText.Format(GetResString(IDS_SF_SIZE), (LPCTSTR)CastItoXBytes(allsize)); + m_stattree.SetItemText(shar[3], sText); // SHARED FILES -> RECORDS SECTION if (forceUpdate || m_stattree.IsExpanded(hshar_records)) { // Set Most Files Shared - cbuffer.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_SHRECNUM), thePrefs.GetSharedMostFilesShared()); - m_stattree.SetItemText(shar_r[0], cbuffer); + sText.Format(_T("%s: %u"), (LPCTSTR)GetResString(IDS_STATS_SHRECNUM), thePrefs.GetSharedMostFilesShared()); + m_stattree.SetItemText(shar_r[0], sText); // Set largest avg file size - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_SHRECASIZE), (LPCTSTR)CastItoXBytes(thePrefs.GetSharedLargestAvgFileSize())); - m_stattree.SetItemText(shar_r[1], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_SHRECASIZE), (LPCTSTR)CastItoXBytes(thePrefs.GetSharedLargestAvgFileSize())); + m_stattree.SetItemText(shar_r[1], sText); // Set largest file size - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_LARGESTFILE), (LPCTSTR)CastItoXBytes(thePrefs.GetSharedLargestFileSize())); - m_stattree.SetItemText(shar_r[2], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_LARGESTFILE), (LPCTSTR)CastItoXBytes(thePrefs.GetSharedLargestFileSize())); + m_stattree.SetItemText(shar_r[2], sText); // Set largest share size - cbuffer.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_SHRECSIZE), (LPCTSTR)CastItoXBytes(thePrefs.GetSharedLargestShareSize())); - m_stattree.SetItemText(shar_r[3], cbuffer); + sText.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_STATS_SHRECSIZE), (LPCTSTR)CastItoXBytes(thePrefs.GetSharedLargestShareSize())); + m_stattree.SetItemText(shar_r[3], sText); } // - End Shared Files -> Records Section } // - END SHARED FILES SECTION @@ -2578,33 +2459,25 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) uint64 ui64TotalAdditionalNeededSpace = 0; int iActiveFiles = theApp.downloadqueue->GetDownloadFilesStats(ui64TotalFileSize, ui64TotalLeftToTransfer, ui64TotalAdditionalNeededSpace); - cbuffer.Format(GetResString(IDS_DWTOT_NR), iActiveFiles); - m_stattree.SetItemText(h_total_num_of_dls, cbuffer); - - cbuffer.Format(GetResString(IDS_DWTOT_TSD), (LPCTSTR)CastItoXBytes(ui64TotalFileSize)); - m_stattree.SetItemText(h_total_size_of_dls, cbuffer); + sText.Format(GetResString(IDS_DWTOT_NR), iActiveFiles); + m_stattree.SetItemText(h_total_num_of_dls, sText); + sText.Format(GetResString(IDS_DWTOT_TSD), (LPCTSTR)CastItoXBytes(ui64TotalFileSize)); + m_stattree.SetItemText(h_total_size_of_dls, sText); uint64 ui64TotalTransferred = ui64TotalFileSize - ui64TotalLeftToTransfer; double fPercent = ui64TotalFileSize ? (ui64TotalTransferred * 100.0) / ui64TotalFileSize : 0; - - cbuffer.Format(GetResString(IDS_DWTOT_TCS), (LPCTSTR)CastItoXBytes(ui64TotalTransferred), fPercent); - m_stattree.SetItemText(h_total_size_dld, cbuffer); - - cbuffer.Format(GetResString(IDS_DWTOT_TSL), (LPCTSTR)CastItoXBytes(ui64TotalLeftToTransfer)); - m_stattree.SetItemText(h_total_size_left_to_dl, cbuffer); - - cbuffer.Format(GetResString(IDS_DWTOT_TSN), (LPCTSTR)CastItoXBytes(ui64TotalAdditionalNeededSpace)); - m_stattree.SetItemText(h_total_size_needed, cbuffer); + sText.Format(GetResString(IDS_DWTOT_TCS), (LPCTSTR)CastItoXBytes(ui64TotalTransferred), fPercent); + m_stattree.SetItemText(h_total_size_dld, sText); + sText.Format(GetResString(IDS_DWTOT_TSL), (LPCTSTR)CastItoXBytes(ui64TotalLeftToTransfer)); + m_stattree.SetItemText(h_total_size_left_to_dl, sText); + sText.Format(GetResString(IDS_DWTOT_TSN), (LPCTSTR)CastItoXBytes(ui64TotalAdditionalNeededSpace)); + m_stattree.SetItemText(h_total_size_needed, sText); uint64 ui64TotalFreeSpace = GetFreeTempSpace(-1); - CString buffer2; - buffer2.Format(GetResString(IDS_DWTOT_FS), (LPCTSTR)CastItoXBytes(ui64TotalFreeSpace)); - + sText.Format(GetResString(IDS_DWTOT_FS), (LPCTSTR)CastItoXBytes(ui64TotalFreeSpace)); if (ui64TotalAdditionalNeededSpace > ui64TotalFreeSpace) - cbuffer.Format(GetResString(IDS_NEEDFREEDISKSPACE), (LPCTSTR)buffer2, (LPCTSTR)CastItoXBytes(ui64TotalAdditionalNeededSpace - ui64TotalFreeSpace)); - else - cbuffer = buffer2; - m_stattree.SetItemText(h_total_size_left_on_drive, cbuffer); + sText.AppendFormat(GetResString(IDS_NEEDFREEDISKSPACE), _T(""), (LPCTSTR)CastItoXBytes(ui64TotalAdditionalNeededSpace - ui64TotalFreeSpace)); + m_stattree.SetItemText(h_total_size_left_on_drive, sText); } // - End Set Tree Values @@ -2613,38 +2486,32 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) _CrtMemState memState; _CrtMemCheckpoint(&memState); - cbuffer.Format(_T("%s: %u bytes in %u blocks"), _T("Free"), memState.lSizes[0], memState.lCounts[0]); - m_stattree.SetItemText(debug1, cbuffer); - cbuffer.Format(_T("%s: %u bytes in %u blocks"), _T("Normal"), memState.lSizes[1], memState.lCounts[1]); - m_stattree.SetItemText(debug2, cbuffer); - cbuffer.Format(_T("%s: %u bytes in %u blocks"), _T("CRT"), memState.lSizes[2], memState.lCounts[2]); - m_stattree.SetItemText(debug3, cbuffer); - cbuffer.Format(_T("%s: %u bytes in %u blocks"), _T("Ignore"), memState.lSizes[3], memState.lCounts[3]); - m_stattree.SetItemText(debug4, cbuffer); - cbuffer.Format(_T("%s: %u bytes in %u blocks"), _T("Client"), memState.lSizes[4], memState.lCounts[4]); - m_stattree.SetItemText(debug5, cbuffer); + sText.Format(_T("%s: %Iu bytes in %Iu blocks"), _T("Free"), memState.lSizes[0], memState.lCounts[0]); + m_stattree.SetItemText(debug1, sText); + sText.Format(_T("%s: %Iu bytes in %Iu blocks"), _T("Normal"), memState.lSizes[1], memState.lCounts[1]); + m_stattree.SetItemText(debug2, sText); + sText.Format(_T("%s: %Iu bytes in %Iu blocks"), _T("CRT"), memState.lSizes[2], memState.lCounts[2]); + m_stattree.SetItemText(debug3, sText); + sText.Format(_T("%s: %Iu bytes in %Iu blocks"), _T("Ignore"), memState.lSizes[3], memState.lCounts[3]); + m_stattree.SetItemText(debug4, sText); + sText.Format(_T("%s: %Iu bytes in %Iu blocks"), _T("Client"), memState.lSizes[4], memState.lCounts[4]); + m_stattree.SetItemText(debug5, sText); extern CMap g_allocations; - for (POSITION pos = blockFiles.GetStartPosition(); pos != NULL;) { - const unsigned char *pszFileName; - HTREEITEM *pTag; - blockFiles.GetNextAssoc(pos, pszFileName, pTag); - m_stattree.SetItemText(*pTag, _T("")); - } - for (POSITION pos = g_allocations.GetStartPosition(); pos != NULL;) { - const unsigned char *pszFileName; - UINT count; - g_allocations.GetNextAssoc(pos, pszFileName, count); + for (const CMap::CPair *pair = blockFiles.PGetFirstAssoc(); pair != NULL; pair = blockFiles.PGetNextAssoc(pair)) + m_stattree.SetItemText(*pair->value, _T("")); + + for (const CMap::CPair *pair = g_allocations.PGetFirstAssoc(); pair != NULL; pair = g_allocations.PGetNextAssoc(pair)) { HTREEITEM *pTag; - if (blockFiles.Lookup(pszFileName, pTag) == 0) { + if (blockFiles.Lookup(pair->key, pTag) == 0) { pTag = new HTREEITEM; *pTag = m_stattree.InsertItem(_T("0"), debug2); m_stattree.SetItemData(*pTag, 1); - blockFiles.SetAt(pszFileName, pTag); + blockFiles[pair->key] = pTag; } - cbuffer.Format(_T("%hs : %u blocks"), pszFileName, count); - m_stattree.SetItemText(*pTag, cbuffer); + sText.Format(_T("%hs : %u blocks"), pair->key, pair->value); //count + m_stattree.SetItemText(*pTag, sText); } } #endif @@ -2662,9 +2529,8 @@ void CStatisticsDlg::ShowStatistics(bool forceUpdate) uStart = 1 << (i - 1); uEnd = (i == ALLOC_SLOTS - 1) ? UINT_MAX : (uStart << 1) - 1; } - CString strLabel; - strLabel.Format(_T("Block size %08X-%08X: %s (%1.1f%%)"), uStart, uEnd, (LPCTSTR)CastItoIShort(g_aAllocStats[i], false, 2), ullTotalAllocs != 0 ? g_aAllocStats[i] * 100.0 / ullTotalAllocs : 0.0); - m_stattree.SetItemText(h_allocSizes[i], strLabel); + sText.Format(_T("Block size %08X-%08X: %s (%1.1f%%)"), uStart, uEnd, (LPCTSTR)CastItoIShort(g_aAllocStats[i], false, 2), ullTotalAllocs != 0 ? g_aAllocStats[i] * 100.0 / ullTotalAllocs : 0.0); + m_stattree.SetItemText(h_allocSizes[i], sText); } } #endif @@ -2719,16 +2585,16 @@ void CStatisticsDlg::ShowInterval() m_UploadOMeter.SetXUnits(GetResString(IDS_STOPPED)); m_Statistics.SetXUnits(GetResString(IDS_STOPPED)); } else { - const CString &buffer = CastSecondsToHM(shownSecs); - m_UploadOMeter.SetXUnits(buffer); - m_DownloadOMeter.SetXUnits(buffer); - m_Statistics.SetXUnits(buffer); + const CString &sUnits(CastSecondsToHM(shownSecs)); + m_UploadOMeter.SetXUnits(sUnits); + m_DownloadOMeter.SetXUnits(sUnits); + m_Statistics.SetXUnits(sUnits); } UpdateData(FALSE); } } -void CStatisticsDlg::SetARange(bool SetDownload, int maxValue) +void CStatisticsDlg::SetARange(bool SetDownload, uint32 maxValue) { if (SetDownload) m_DownloadOMeter.SetRanges(0, maxValue); @@ -2741,9 +2607,9 @@ void CStatisticsDlg::Localize() { RepaintMeters(); - CString myBuffer; - myBuffer.Format(GetResString(IDS_STATS_LASTRESETSTATIC), (LPCTSTR)thePrefs.GetStatsLastResetStr(false)); - SetDlgItemText(IDC_STATIC_LASTRESET, myBuffer); + CString sReset; + sReset.Format(GetResString(IDS_STATS_LASTRESETSTATIC), (LPCTSTR)thePrefs.GetStatsLastResetStr(false)); + SetDlgItemText(IDC_STATIC_LASTRESET, sReset); } // End Localize @@ -2761,76 +2627,76 @@ void CStatisticsDlg::CreateMyTree() // Setup Tree h_transfer = m_stattree.InsertItem(GetResString(IDS_FSTAT_TRANSFER), 1, 1); // Transfers Section - CString buffer; - buffer.Format(_T("%s %s"), (LPCTSTR)GetResString(IDS_STATS_SRATIO), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); // Make It Pretty - trans[0] = m_stattree.InsertItem(buffer, h_transfer); // Session Ratio + CString sItem; + sItem.Format(_T("%s %s"), (LPCTSTR)GetResString(IDS_STATS_SRATIO), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); // Make It Pretty + trans[0] = m_stattree.InsertItem(sItem, h_transfer); // Session Ratio - buffer.Format(_T("%s %s"), (LPCTSTR)GetResString(IDS_STATS_FRATIO), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); // Make It Pretty - trans[1] = m_stattree.InsertItem(buffer, h_transfer); // Friend Session Ratio + sItem.Format(_T("%s %s"), (LPCTSTR)GetResString(IDS_STATS_FRATIO), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); // Make It Pretty + trans[1] = m_stattree.InsertItem(sItem, h_transfer); // Friend Session Ratio - buffer.Format(_T("%s %s"), (LPCTSTR)GetResString(IDS_STATS_CRATIO), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); // Make It Pretty - trans[2] = m_stattree.InsertItem(buffer, h_transfer); // Cumulative Ratio + sItem.Format(_T("%s %s"), (LPCTSTR)GetResString(IDS_STATS_CRATIO), (LPCTSTR)GetResString(IDS_FSTAT_WAITING)); // Make It Pretty + trans[2] = m_stattree.InsertItem(sItem, h_transfer); // Cumulative Ratio - h_upload = m_stattree.InsertItem(GetResString(IDS_TW_UPLOADS), 6, 6, h_transfer); // Uploads Section + h_upload = m_stattree.InsertItem(GetResString(IDS_TW_UPLOADS), 6, 6, h_transfer); // Uploads Section h_up_session = m_stattree.InsertItem(GetResString(IDS_STATS_SESSION), 8, 8, h_upload); // Session Section (Uploads) for (unsigned i = 0; i < 6; ++i) up_S[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), h_up_session); //MORPH - Added by Yun.SF3, ZZ Upload System - hup_scb = m_stattree.InsertItem(GetResString(IDS_CLIENTS), up_S[0]); // Clients Section + hup_scb = m_stattree.InsertItem(GetResString(IDS_CLIENTS), up_S[0]); // Clients Section for (unsigned i = 0; i < _countof(up_scb); ++i) up_scb[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hup_scb); - hup_spb = m_stattree.InsertItem(GetResString(IDS_PORT), up_S[0]); // Ports Section + hup_spb = m_stattree.InsertItem(GetResString(IDS_PORT), up_S[0]); // Ports Section for (unsigned i = 0; i < _countof(up_spb); ++i) up_spb[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hup_spb); - hup_ssb = m_stattree.InsertItem(GetResString(IDS_STATS_DATASOURCE), up_S[0]); // Data Source Section + hup_ssb = m_stattree.InsertItem(GetResString(IDS_STATS_DATASOURCE), up_S[0]); // Data Source Section for (unsigned i = 0; i < 2; ++i) up_ssb[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hup_ssb); for (unsigned i = 0; i < 4; ++i) up_ssessions[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), up_S[5]); //MORPH - Added by Yun.SF3, ZZ Upload System - hup_soh = m_stattree.InsertItem(GetResString(IDS_STATS_OVRHD), h_up_session); // Upline Overhead (Session) + hup_soh = m_stattree.InsertItem(GetResString(IDS_STATS_OVRHD), h_up_session); // Upload Overhead (Session) for (unsigned i = 0; i < _countof(up_soh); ++i) up_soh[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hup_soh); h_up_total = m_stattree.InsertItem(GetResString(IDS_STATS_CUMULATIVE), 9, 9, h_upload); // Cumulative Section (Uploads) - up_T[0] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), h_up_total); // Uploaded Data (Total) - hup_tcb = m_stattree.InsertItem(GetResString(IDS_CLIENTS), up_T[0]); // Clients Section + up_T[0] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), h_up_total); // Uploaded Data (Total) + hup_tcb = m_stattree.InsertItem(GetResString(IDS_CLIENTS), up_T[0]); // Clients Section for (unsigned i = 0; i < _countof(up_tcb); ++i) up_tcb[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hup_tcb); - hup_tpb = m_stattree.InsertItem(GetResString(IDS_PORT), up_T[0]); // Ports Section + hup_tpb = m_stattree.InsertItem(GetResString(IDS_PORT), up_T[0]); // Ports Section for (unsigned i = 0; i < _countof(up_tpb); ++i) up_tpb[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hup_tpb); - hup_tsb = m_stattree.InsertItem(GetResString(IDS_STATS_DATASOURCE), up_T[0]); // Data Source Section + hup_tsb = m_stattree.InsertItem(GetResString(IDS_STATS_DATASOURCE), up_T[0]); // Data Source Section for (unsigned i = 0; i < 2; ++i) up_tsb[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hup_tsb); - up_T[1] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), h_up_total); // Upload Sessions (Total) + up_T[1] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), h_up_total); // Upload Sessions (Total) for (unsigned i = 0; i < 4; ++i) up_tsessions[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), up_T[1]); - hup_toh = m_stattree.InsertItem(GetResString(IDS_STATS_OVRHD), h_up_total); // Upline Overhead (Total) + hup_toh = m_stattree.InsertItem(GetResString(IDS_STATS_OVRHD), h_up_total); // Upload Overhead (Total) for (unsigned i = 0; i < _countof(up_toh); ++i) up_toh[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hup_toh); - h_download = m_stattree.InsertItem(GetResString(IDS_TW_DOWNLOADS), 7, 7, h_transfer); // Downloads Section + h_download = m_stattree.InsertItem(GetResString(IDS_TW_DOWNLOADS), 7, 7, h_transfer); // Downloads Section h_down_session = m_stattree.InsertItem(GetResString(IDS_STATS_SESSION), 8, 8, h_download); // Session Section (Downloads) for (unsigned i = 0; i < 8; ++i) down_S[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), h_down_session); - hdown_scb = m_stattree.InsertItem(GetResString(IDS_CLIENTS), down_S[0]); // Clients Section + hdown_scb = m_stattree.InsertItem(GetResString(IDS_CLIENTS), down_S[0]); // Clients Section for (unsigned i = 0; i < _countof(down_scb); ++i) down_scb[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hdown_scb); - hdown_spb = m_stattree.InsertItem(GetResString(IDS_PORT), down_S[0]); // Ports Section + hdown_spb = m_stattree.InsertItem(GetResString(IDS_PORT), down_S[0]); // Ports Section for (unsigned i = 0; i < _countof(down_spb); ++i) down_spb[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hdown_spb); for (unsigned i = 0; i < _countof(down_sources); ++i) down_sources[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), down_S[3]); for (unsigned i = 0; i < 4; ++i) down_ssessions[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), down_S[4]); - hdown_soh = m_stattree.InsertItem(GetResString(IDS_STATS_OVRHD), h_down_session); // Downline Overhead (Session) + hdown_soh = m_stattree.InsertItem(GetResString(IDS_STATS_OVRHD), h_down_session); // Downline Overhead (Session) for (unsigned i = 0; i < _countof(down_soh); ++i) down_soh[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hdown_soh); h_down_total = m_stattree.InsertItem(GetResString(IDS_STATS_CUMULATIVE), 9, 9, h_download);// Cumulative Section (Downloads) for (unsigned i = 0; i < 6; ++i) down_T[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), h_down_total); - hdown_tcb = m_stattree.InsertItem(GetResString(IDS_CLIENTS), down_T[0]); // Clients Section + hdown_tcb = m_stattree.InsertItem(GetResString(IDS_CLIENTS), down_T[0]); // Clients Section for (unsigned i = 0; i < _countof(down_tcb); ++i) down_tcb[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hdown_tcb); - hdown_tpb = m_stattree.InsertItem(GetResString(IDS_PORT), down_T[0]); // Ports Section + hdown_tpb = m_stattree.InsertItem(GetResString(IDS_PORT), down_T[0]); // Ports Section for (unsigned i = 0; i < _countof(down_tpb); ++i) down_tpb[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hdown_tpb); for (unsigned i = 0; i < 4; ++i) @@ -2838,22 +2704,22 @@ void CStatisticsDlg::CreateMyTree() hdown_toh = m_stattree.InsertItem(GetResString(IDS_STATS_OVRHD), h_down_total); // Downline Overhead (Total) for (unsigned i = 0; i < _countof(down_toh); ++i) down_toh[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hdown_toh); - h_connection = m_stattree.InsertItem(GetResString(IDS_CONNECTIONS), 2, 2); // Connection Section + h_connection = m_stattree.InsertItem(GetResString(IDS_CONNECTIONS), 2, 2); // Connection Section h_conn_session = m_stattree.InsertItem(GetResString(IDS_STATS_SESSION), 8, 8, h_connection); // Session Section (Connection) - hconn_sg = m_stattree.InsertItem(GetResString(IDS_STATS_GENERAL), 11, 11, h_conn_session); // General Section (Session) + hconn_sg = m_stattree.InsertItem(GetResString(IDS_STATS_GENERAL), 11, 11, h_conn_session); // General Section (Session) for (unsigned i = 0; i < 5; ++i) conn_sg[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hconn_sg); hconn_su = m_stattree.InsertItem(GetResString(IDS_PW_CON_UPLBL), 6, 6, h_conn_session); // Uploads Section (Session) for (unsigned i = 0; i < 4; ++i) conn_su[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hconn_su); - hconn_sd = m_stattree.InsertItem(GetResString(IDS_PW_CON_DOWNLBL), 7, 7, h_conn_session); // Downloads Section (Session) + hconn_sd = m_stattree.InsertItem(GetResString(IDS_PW_CON_DOWNLBL), 7, 7, h_conn_session); // Downloads Section (Session) for (unsigned i = 0; i < 4; ++i) conn_sd[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hconn_sd); - h_conn_total = m_stattree.InsertItem(GetResString(IDS_STATS_CUMULATIVE), 9, 9, h_connection); // Cumulative Section (Connection) - hconn_tg = m_stattree.InsertItem(GetResString(IDS_STATS_GENERAL), 11, 11, h_conn_total); // General (Total) + h_conn_total = m_stattree.InsertItem(GetResString(IDS_STATS_CUMULATIVE), 9, 9, h_connection);// Cumulative Section (Connection) + hconn_tg = m_stattree.InsertItem(GetResString(IDS_STATS_GENERAL), 11, 11, h_conn_total); // General (Total) for (unsigned i = 0; i < 4; ++i) conn_tg[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hconn_tg); - hconn_tu = m_stattree.InsertItem(GetResString(IDS_PW_CON_UPLBL), 6, 6, h_conn_total); // Uploads (Total) + hconn_tu = m_stattree.InsertItem(GetResString(IDS_PW_CON_UPLBL), 6, 6, h_conn_total); // Uploads (Total) for (unsigned i = 0; i < 3; ++i) conn_tu[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hconn_tu); hconn_td = m_stattree.InsertItem(GetResString(IDS_PW_CON_DOWNLBL), 7, 7, h_conn_total); // Downloads (Total) @@ -2873,9 +2739,9 @@ void CStatisticsDlg::CreateMyTree() for (unsigned i = 0; i < 2; ++i) tvitime_tt[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), tvitime_t[1]); htime_aap = m_stattree.InsertItem(GetResString(IDS_STATS_AVGANDPROJ), 13, 13, h_time); // Projected Averages Section - time_aaph[0] = m_stattree.InsertItem(GetResString(IDS_DAYLY), 14, 14, htime_aap); // Daily Section - time_aaph[1] = m_stattree.InsertItem(GetResString(IDS_STATS_MONTHLY), 15, 15, htime_aap); // Monthly Section - time_aaph[2] = m_stattree.InsertItem(GetResString(IDS_STATS_YEARLY), 16, 16, htime_aap); // Yearly Section + time_aaph[0] = m_stattree.InsertItem(GetResString(IDS_DAILY), 14, 14, htime_aap); // Daily Section + time_aaph[1] = m_stattree.InsertItem(GetResString(IDS_STATS_MONTHLY), 15, 15, htime_aap); // Monthly Section + time_aaph[2] = m_stattree.InsertItem(GetResString(IDS_STATS_YEARLY), 16, 16, htime_aap); // Yearly Section for (int x = 0; x < 3; ++x) { time_aap_hup[x] = m_stattree.InsertItem(GetResString(IDS_TW_UPLOADS), 6, 6, time_aaph[x]); // Upload Section for (unsigned i = 0; i < 3; ++i) @@ -2909,36 +2775,36 @@ void CStatisticsDlg::CreateMyTree() } h_clients = m_stattree.InsertItem(GetResString(IDS_CLIENTS), 3, 3); // Clients Section cligen[5] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), h_clients); - hclisoft = m_stattree.InsertItem(GetResString(IDS_CD_CSOFT), h_clients); // Client Software Section + hclisoft = m_stattree.InsertItem(GetResString(IDS_CD_CSOFT), h_clients); // Client Software Section for (unsigned i = 0; i < 8; ++i) clisoft[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hclisoft); hclinet = m_stattree.InsertItem(GetResString(IDS_NETWORK), h_clients); // Client Network Section for (unsigned i = 0; i < 4; ++i) clinet[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hclinet); - hcliport = m_stattree.InsertItem(GetResString(IDS_PORT), h_clients); // Client Port Section + hcliport = m_stattree.InsertItem(GetResString(IDS_PORT), h_clients); // Client Port Section for (unsigned i = 0; i < 2; ++i) cliport[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hcliport); - CString sFwKAD(GetResString(IDS_FIREWALLED)); - sFwKAD.AppendFormat(_T(" (%s)"), (LPCTSTR)GetResString(IDS_KADEMLIA)); - hclifirewalled = m_stattree.InsertItem(sFwKAD, h_clients); + + sItem.Format(_T("%s (%s)"), (LPCTSTR)GetResString(IDS_FIREWALLED), (LPCTSTR)GetResString(IDS_KADEMLIA)); + hclifirewalled = m_stattree.InsertItem(sItem, h_clients); for (unsigned i = 0; i < 2; ++i) clifirewalled[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hclifirewalled); cligen[4] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), h_clients); cligen[3] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), h_clients); for (unsigned i = 0; i < 3; ++i) cligen[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), h_clients); - h_servers = m_stattree.InsertItem(GetResString(IDS_FSTAT_SERVERS), 4, 4); // Servers section + h_servers = m_stattree.InsertItem(GetResString(IDS_FSTAT_SERVERS), 4, 4); // Servers section for (unsigned i = 0; i < 6; ++i) srv[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), h_servers); // Servers Items for (unsigned i = 0; i < 3; ++i) srv_w[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), srv[0]); // Working Servers Items - hsrv_records = m_stattree.InsertItem(GetResString(IDS_STATS_RECORDS), 10, 10, h_servers); // Servers Records Section + hsrv_records = m_stattree.InsertItem(GetResString(IDS_STATS_RECORDS), 10, 10, h_servers); // Servers Records Section for (unsigned i = 0; i < 3; ++i) - srv_r[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hsrv_records); // Record Items + srv_r[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hsrv_records); // Record Items h_shared = m_stattree.InsertItem(GetResString(IDS_SHAREDFILES), 5, 5); // Shared Files Section for (unsigned i = 0; i < 4; ++i) shar[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), h_shared); - hshar_records = m_stattree.InsertItem(GetResString(IDS_STATS_RECORDS), 10, 10, h_shared); // Shared Records Section + hshar_records = m_stattree.InsertItem(GetResString(IDS_STATS_RECORDS), 10, 10, h_shared); // Shared Records Section for (unsigned i = 0; i < 4; ++i) shar_r[i] = m_stattree.InsertItem(GetResString(IDS_FSTAT_WAITING), hshar_records); h_total_downloads = m_stattree.InsertItem(GetResString(IDS_DWTOT), 17, 17); @@ -2973,9 +2839,8 @@ void CStatisticsDlg::CreateMyTree() uStart = 1 << (i - 1); uEnd = (i == ALLOC_SLOTS - 1) ? UINT_MAX : (uStart << 1) - 1; } - CString strLabel; - strLabel.Format(_T("Block size %08X-%08X: %s (%1.1f%%)"), uStart, uEnd, (LPCTSTR)CastItoIShort(g_aAllocStats[i], false, 2), 0.0); - h_allocSizes[i] = m_stattree.InsertItem(strLabel, h_allocs); + sItem.Format(_T("Block size %08X-%08X: %s (%1.1f%%)"), uStart, uEnd, (LPCTSTR)CastItoIShort(g_aAllocStats[i], false, 2), 0.0); + h_allocSizes[i] = m_stattree.InsertItem(sItem, h_allocs); } #endif diff --git a/srchybrid/StatisticsDlg.h b/srchybrid/StatisticsDlg.h index 0bd410c1..daae2a05 100644 --- a/srchybrid/StatisticsDlg.h +++ b/srchybrid/StatisticsDlg.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -44,7 +44,7 @@ class CStatisticsDlg : public CResizableDialog // -khaos--+++> Optional force update parameter. void ShowStatistics(bool forceUpdate = false); // <-----khaos- - void SetARange(bool SetDownload, int maxValue); + void SetARange(bool SetDownload, uint32 maxValue); void RepaintMeters(); void UpdateConnectionsGraph(); @@ -77,7 +77,7 @@ class CStatisticsDlg : public CResizableDialog HTREEITEM hconn_sg, conn_sg[5], hconn_su, conn_su[4], hconn_sd, conn_sd[4]; // Connection Session Section Headers and Items HTREEITEM hconn_tg, conn_tg[4], hconn_tu, conn_tu[3], hconn_td, conn_td[3]; // Connection Total Section Headers and Items HTREEITEM h_clients, cligen[6], hclisoft, clisoft[8]; - HTREEITEM cli_versions[MAX_CLIENTS_WITH_SUB_VERSION*MAX_SUB_CLIENT_VERSIONS]; + HTREEITEM cli_versions[MAX_CLIENTS_WITH_SUB_VERSION * MAX_SUB_CLIENT_VERSIONS]; HTREEITEM cli_other[MAX_SUB_CLIENT_VERSIONS / 2]; HTREEITEM hclinet, clinet[4]; // Clients Section HTREEITEM hcliport, cliport[2]; // Clients Section diff --git a/srchybrid/StatisticsTree.cpp b/srchybrid/StatisticsTree.cpp index 0ac3ee66..b5832bdc 100644 --- a/srchybrid/StatisticsTree.cpp +++ b/srchybrid/StatisticsTree.cpp @@ -125,7 +125,7 @@ void CStatisticsTree::DoMenu(CPoint doWhere) void CStatisticsTree::DoMenu(CPoint doWhere, UINT nFlags) { - int myFlags = PathFileExists(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + _T("statbkup.ini")) ? MF_STRING : MF_GRAYED; + int myFlags = ::PathFileExists(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + _T("statbkup.ini")) ? MF_STRING : MF_GRAYED; mnuContext.CreatePopupMenu(); mnuContext.AddMenuTitle(GetResString(IDS_STATS_MNUTREETITLE), true); @@ -212,7 +212,7 @@ BOOL CStatisticsTree::OnCommand(WPARAM wParam, LPARAM) case MP_STATTREE_HTMLEXPORT: ExportHTML(); } - return true; + return TRUE; } // If the item is bold it returns true, otherwise @@ -234,8 +234,8 @@ BOOL CStatisticsTree::IsExpanded(HTREEITEM theItem) } // This is a generic function to check if a state is valid or not. -// It accepts a tree item handle and a state/statemask/whatever. -// It then retrieves the state UINT value and does a bitand +// It accepts a tree item handle and a state/state-mask/whatever. +// It then retrieves the state UINT value and does a bit 'and' // with the original input. This should translate into a // boolean result that tells us whether the checked state is // true or not. This is currently unused, but may come in handy @@ -252,20 +252,18 @@ BOOL CStatisticsTree::CheckState(HTREEITEM hItem, UINT state) // EX: CString itemText = GetItemText(myTreeItem); CString CStatisticsTree::GetItemText(HTREEITEM theItem) { + TCHAR szText[1024]; if (theItem != NULL) { TVITEM item; - TCHAR szText[1024]; item.mask = TVIF_TEXT | TVIF_HANDLE; item.hItem = theItem; item.pszText = szText; item.cchTextMax = _countof(szText); + szText[GetItem(&item) ? _countof(szText) - 1 : 0] = _T('\0'); + } else + szText[0] = _T('\0'); - if (GetItem(&item)) { - szText[_countof(szText) - 1] = _T('\0'); - return CString(szText); - } - } - return CString(); + return CString(szText); } // This separates the title from the value in a tree item that has @@ -279,20 +277,20 @@ CString CStatisticsTree::GetItemText(HTREEITEM theItem) // AfxMessageBox("The title is: " + strTitle + "\nThe value is: " + strValue); CString CStatisticsTree::GetItemText(HTREEITEM theItem, int getPart) { + CString fullText; if (theItem != NULL) { - const CString &fullText = GetItemText(theItem); + fullText = GetItemText(theItem); if (!fullText.IsEmpty()) { int posSeparator = fullText.Find(_T(": ")); - if (posSeparator < 1) - return (getPart == GET_TITLE) ? fullText : CString(); - - if (getPart == GET_TITLE) - return fullText.Left(posSeparator); - if (getPart == GET_VALUE) - return fullText.Mid(posSeparator + 2); + if (getPart == GET_TITLE && posSeparator > 0) + fullText.Truncate(posSeparator); + else if (getPart == GET_VALUE && posSeparator >= 0) + fullText.Delete(0, posSeparator + 2); + else + fullText.Empty(); } } - return CString(); + return fullText; } // This is the primary function for generating HTML output of the statistics tree. @@ -313,8 +311,10 @@ CString CStatisticsTree::GetHTML(bool onlyVisible, HTREEITEM theItem, int theIte while (hCurrent != NULL) { CString strItem(GetItemText(hCurrent)); - if (IsBold(hCurrent)) - strItem = _T("") + strItem + _T(""); + if (IsBold(hCurrent)) { + strItem.Insert(0, _T("")); + strItem += _T(""); + } for (int i = 0; i < theItemLevel; ++i) strBuffer += _T("   "); if (theItemLevel == 0) @@ -342,7 +342,7 @@ bool CStatisticsTree::CopyHTML(int copyMode) HTREEITEM selectedItem = GetSelectedItem(); if (selectedItem == NULL) break; - const CString &theHTML = GetHTML(true, selectedItem); + const CString &theHTML(GetHTML(true, selectedItem)); if (theHTML.IsEmpty()) break; theApp.CopyTextToClipboard(theHTML); @@ -350,7 +350,7 @@ bool CStatisticsTree::CopyHTML(int copyMode) return true; case MP_STATTREE_HTMLCOPYVIS: { - const CString &theHTML = GetHTML(); + const CString &theHTML(GetHTML()); if (theHTML.IsEmpty()) break; theApp.CopyTextToClipboard(theHTML); @@ -358,7 +358,7 @@ bool CStatisticsTree::CopyHTML(int copyMode) return true; case MP_STATTREE_HTMLCOPYALL: { - const CString &theHTML = GetHTML(false); + const CString &theHTML(GetHTML(false)); if (theHTML.IsEmpty()) break; theApp.CopyTextToClipboard(theHTML); @@ -406,7 +406,7 @@ bool CStatisticsTree::CopyText(int copyMode) HTREEITEM selectedItem = GetSelectedItem(); if (selectedItem == NULL) break; - const CString &theText = GetText(true, selectedItem); + const CString &theText(GetText(true, selectedItem)); if (theText.IsEmpty()) break; theApp.CopyTextToClipboard(theText); @@ -414,7 +414,7 @@ bool CStatisticsTree::CopyText(int copyMode) return true; case MP_STATTREE_COPYVIS: { - const CString &theText = GetText(); + const CString &theText(GetText()); if (theText.IsEmpty()) break; theApp.CopyTextToClipboard(theText); @@ -422,7 +422,7 @@ bool CStatisticsTree::CopyText(int copyMode) return true; case MP_STATTREE_COPYALL: { - const CString &theText = GetText(false); + const CString &theText(GetText(false)); if (theText.IsEmpty()) break; theApp.CopyTextToClipboard(theText); @@ -514,7 +514,7 @@ void CStatisticsTree::ExportHTML() { // Save/Restore the current directory TCHAR szCurDir[MAX_PATH]; - DWORD dwCurDirLen = GetCurrentDirectory(_countof(szCurDir), szCurDir); + DWORD dwCurDirLen = ::GetCurrentDirectory(_countof(szCurDir), szCurDir); if (dwCurDirLen == 0 || dwCurDirLen >= _countof(szCurDir)) *szCurDir = _T('\0'); @@ -579,8 +579,8 @@ void CStatisticsTree::ExportHTML() _T("stats_14.gif"), _T("stats_15.gif"), _T("stats_16.gif"), _T("stats_17.gif"), _T("stats_hidden.gif"), _T("stats_space.gif"), _T("stats_visible.gif") }; - CString strDst = saveAsDlg.GetPathName().Left(saveAsDlg.GetPathName().GetLength() - saveAsDlg.GetFileName().GetLength());// EC - what if directory name == filename? this should fix this - CString strSrc = thePrefs.GetMuleDirectory(EMULE_WEBSERVERDIR); + CString strDst(saveAsDlg.GetPathName(), saveAsDlg.GetPathName().GetLength() - saveAsDlg.GetFileName().GetLength());// EC - what if directory name == filename? this should fix this + CString strSrc(thePrefs.GetMuleDirectory(EMULE_WEBSERVERDIR)); for (size_t i = 0; i < _countof(s_apcFileNames); ++i) ::CopyFile(strSrc + s_apcFileNames[i], strDst + s_apcFileNames[i], FALSE); diff --git a/srchybrid/Stdafx.h b/srchybrid/Stdafx.h index da1aafeb..cac5d316 100644 --- a/srchybrid/Stdafx.h +++ b/srchybrid/Stdafx.h @@ -86,10 +86,8 @@ #define _ATL_ALL_WARNINGS #define _AFX_ALL_WARNINGS -// Disable some warnings which get fired with /W4 for Windows/MFC/ATL headers -#pragma warning(disable:4127) // conditional expression is constant +// Disable some warnings which get fired with /W4 or /Wall for Windows/MFC/ATL headers -// Disable some warnings which are only generated when using "/Wall" #pragma warning(disable:4061) // enumerate in switch of enum is not explicitly handled by a case label #pragma warning(disable:4062) // enumerate in switch of enum is not handled #pragma warning(disable:4191) // 'type cast' : unsafe conversion from to @@ -102,14 +100,15 @@ #if _MSC_VER>=1400 #pragma warning(disable:4266) // no override available for virtual member function from base ; function is hidden #endif -#if _MSC_VER<1400 -#pragma warning(disable:4529) // forming a pointer-to-member requires explicit use of the address-of operator ('&') and a qualified name -#endif #if _MSC_VER>=1400 #pragma warning(disable:4365) // conversion from 'int' to 'UINT', signed/unsigned mismatch #endif -#pragma warning(disable:4548) // expression before comma has no effect; expected expression with side-effect -#pragma warning(disable:4555) // expression has no effect; expected expression with side-effect +#if _MSC_VER>=1900 +#pragma warning(disable:4435) // Object layout under /vd2 will change due to virtual base +#endif +#if _MSC_VER<1400 +#pragma warning(disable:4529) // forming a pointer-to-member requires explicit use of the address-of operator ('&') and a qualified name +#endif #if _MSC_VER>=1400 #pragma warning(disable:4571) // Informational: catch(...) semantics changed since Visual C++ 7.1; structured exceptions (SEH) are no longer caught #endif @@ -125,22 +124,15 @@ #endif #pragma warning(disable:4820) // bytes padding added after member #pragma warning(disable:4917) // a GUID can only be associated with a class, interface or namespace -#pragma warning(disable:4928) // illegal copy-initialization; more than one user-defined conversion has been implicitly applied -#if _MSC_VER>=1400 -#pragma warning(disable:6211) // Leaking memory due to an exception -#pragma warning(disable:6246) // Local declaration of hides declaration of the same name in outer scope -#pragma warning(disable:6284) // Object passed as parameter when string is required in call to -#pragma warning(disable:6387) // might be '0': this does not adhere to the specification for the function -#pragma warning(disable:6309) // Argument is null: this does not adhere to function specification of -#pragma warning(disable:6255) // _alloca indicates failure by raising a stack overflow exception. +#if _MSC_VER>=1900 +#pragma warning(disable:5026) // move constructor was implicitly defined as deleted +#pragma warning(disable:5027) // move assignment operator was implicitly defined as deleted +#pragma warning(disable:5045) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified +#pragma warning(disable:5220) // a non-static data member with a volatile qualified type no longer implies that compiler generated copy/move constructors and copy/move assignment operators are non trivial #endif -#if _MSC_VER>=1600 -#pragma warning(disable:4987) // nonstandard extension used: 'throw (...)' -#endif #if _MSC_VER>=1400 - // _CRT_SECURE_NO_DEPRECATE - Disable all warnings for not using "_s" functions. // #ifndef _CRT_SECURE_NO_DEPRECATE @@ -173,6 +165,11 @@ #define _USE_32BIT_TIME_T #endif +//Windows XP compatibility requires 'inet_addr' and 'WSAAsyncGetHostByName' (warning C4996) +#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS +#define _WINSOCK_DEPRECATED_NO_WARNINGS +#endif + #endif//_MSC_VER>=1400 #ifdef _DEBUG @@ -244,24 +241,6 @@ #define LVBKIF_FLAG_ALPHABLEND 0x20000000 #endif - -// Enable warnings which were disabled for Windows/MFC/ATL headers -#pragma warning(default:4505) // unreferenced local function has been removed -#pragma warning(default:4127) // conditional expression is constant -#if _MSC_VER<=1310 -#pragma warning(default:4548) // expression before comma has no effect; expected expression with side-effect -#endif -#if _MSC_VER==1310 -#pragma warning(default:4555) // expression has no effect; expected expression with side-effect -#endif - -// when using warning level 4 -#pragma warning(disable:4201) // nonstandard extension used : nameless struct/union (not worth to mess with, it's due to MIDL created code) -#pragma warning(disable:4238) // nonstandard extension used : class rvalue used as lvalue -#if _MSC_VER>=1400 -#pragma warning(disable:4127) // conditional expression is constant -#endif - #include "types.h" #ifdef _DEBUG @@ -275,6 +254,11 @@ typedef CArray CStringAArray; typedef CStringArray CStringWArray; +//replaces str.Mid(idx) when a constant character pointer is required +#define CPTR(str, idx) (&((LPCTSTR)(str))[(idx)]) +#define CPTRA(str, idx) (&((LPCSTR)(str))[(idx)]) +#define CPTRW(str, idx) (&((LPCWSTR)(str))[(idx)]) + #ifdef UNICODE #define _TWINAPI(fname) fname "W" diff --git a/srchybrid/StringConversion.cpp b/srchybrid/StringConversion.cpp index 8ae3bd26..a3deb7a2 100644 --- a/srchybrid/StringConversion.cpp +++ b/srchybrid/StringConversion.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/StringConversion.h b/srchybrid/StringConversion.h index 9938dd54..2c342260 100644 --- a/srchybrid/StringConversion.h +++ b/srchybrid/StringConversion.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/TLSthreading.h b/srchybrid/TLSthreading.h index 41e0ce32..01362773 100644 --- a/srchybrid/TLSthreading.h +++ b/srchybrid/TLSthreading.h @@ -1,6 +1,6 @@ #pragma once -#include "mbedtls/config.h" +#include "mbedtls/build_info.h" #include "mbedtls/threading.h" void threading_mutex_init_alt(mbedtls_threading_mutex_t *mutex) noexcept; diff --git a/srchybrid/TabCtrl.cpp b/srchybrid/TabCtrl.cpp index a73b4904..53964bb6 100644 --- a/srchybrid/TabCtrl.cpp +++ b/srchybrid/TabCtrl.cpp @@ -101,7 +101,7 @@ void TabControl::OnLButtonUp(UINT nFlags, CPoint point) // Stop the dragging process and release the mouse capture // This will eventually call our OnCaptureChanged which stops the dragging if (GetCapture() == this) - ReleaseCapture(); + ::ReleaseCapture(); // Modify the tab control style so that Hot Tracking is re-enabled if (m_bHotTracking) @@ -110,7 +110,7 @@ void TabControl::OnLButtonUp(UINT nFlags, CPoint point) if (m_nSrcTab == m_nDstTab) return; - // Inform Parent about Dragrequest + // Inform Parent about Drag request NMHDR nmh; nmh.code = UM_TABMOVED; nmh.hwndFrom = GetSafeHwnd(); @@ -205,10 +205,11 @@ void TabControl::OnCaptureChanged(CWnd*) // @mfunc Utility member function to draw the (drop) indicator of where the // tab will be inserted. // -bool TabControl::DrawIndicator(CPoint point // @parm Specifies a position (e.g. the mouse pointer position) which - // will be used to determine whether the indicator should be - // painted to the left or right of the indicator. -) +// @parm Specifies a position (e.g. the mouse pointer position) which +// will be used to determine whether the indicator should be +// painted to the left or right of the indicator. +// +bool TabControl::DrawIndicator(CPoint point) { TCHITTESTINFO hitinfo; hitinfo.pt = point; @@ -286,6 +287,7 @@ BOOL TabControl::ReorderTab(unsigned int nSrcTab, unsigned int nDstTab) item.mask = TCIF_IMAGE | TCIF_PARAM | TCIF_TEXT; //| TCIF_STATE; item.pszText = sBuffer; item.cchTextMax = _countof(sBuffer); + BOOL bOK = GetItem(nSrcTab, &item); sBuffer[_countof(sBuffer) - 1] = _T('\0'); ASSERT(bOK); @@ -331,7 +333,7 @@ BOOL TabControl::DragDetectPlus(CWnd *Handle, CPoint p) Handle->SetCapture(); while (!bResult && bDispatch) { MSG Msg; - if (PeekMessage(&Msg, *Handle, 0, 0, PM_REMOVE)) { + if (::PeekMessage(&Msg, *Handle, 0, 0, PM_REMOVE)) switch (Msg.message) { case WM_MOUSEMOVE: bResult = !DragRect.PtInRect(Msg.pt); @@ -342,16 +344,16 @@ BOOL TabControl::DragDetectPlus(CWnd *Handle, CPoint p) bDispatch = FALSE; break; case WM_QUIT: - ReleaseCapture(); + ::ReleaseCapture(); return FALSE; default: - TranslateMessage(&Msg); - DispatchMessage(&Msg); + ::TranslateMessage(&Msg); + ::DispatchMessage(&Msg); } - } else + else ::Sleep(0); } - ReleaseCapture(); + ::ReleaseCapture(); return bResult; } diff --git a/srchybrid/TaskbarNotifier.cpp b/srchybrid/TaskbarNotifier.cpp index 97570a92..f141b679 100644 --- a/srchybrid/TaskbarNotifier.cpp +++ b/srchybrid/TaskbarNotifier.cpp @@ -150,7 +150,7 @@ bool CTaskbarNotifier::LoadConfiguration(LPCTSTR pszFilePath) struct _stat64 st; if (statUTC(pszFilePath, st)) st.st_mtime = -1; // '-1' = missing file - if (m_strConfigFilePath.CompareNoCase(pszFilePath) == 0 && (time_t)st.st_mtime <= m_tConfigFileLastModified) + if (m_strConfigFilePath.CompareNoCase(pszFilePath) == 0 && st.st_mtime <= m_tConfigFileLastModified) return true; Hide(); @@ -181,7 +181,7 @@ bool CTaskbarNotifier::LoadConfiguration(LPCTSTR pszFilePath) int iBmpTransparentBlue = ini.GetInt(_T("BmpTrasparentBlue"), 255); iBmpTransparentBlue = ini.GetInt(_T("BmpTransparentBlue"), iBmpTransparentBlue); - const CString &strFontType = ini.GetString(_T("FontType"), theApp.GetDefaultFontFaceName()); + const CString &strFontType(ini.GetString(_T("FontType"), theApp.GetDefaultFontFaceName())); int iFontSize = ini.GetInt(_T("FontSize"), 8) * 10; m_dwTimeToStay = ini.GetInt(_T("TimeToStay"), 4000); @@ -189,9 +189,9 @@ bool CTaskbarNotifier::LoadConfiguration(LPCTSTR pszFilePath) m_dwTimeToHide = ini.GetInt(_T("TimeToHide"), 200); CString strBmpFilePath; - const CString &strBmpFileName = ini.GetString(_T("BmpFileName"), _T("")); + const CString &strBmpFileName(ini.GetString(_T("BmpFileName"), _T(""))); if (!strBmpFileName.IsEmpty()) - if (PathIsRelative(strBmpFileName)) + if (::PathIsRelative(strBmpFileName)) strBmpFilePath.Format(_T("%s%s"), szConfigDir, (LPCTSTR)strBmpFileName); else strBmpFilePath = strBmpFileName; @@ -447,7 +447,7 @@ void CTaskbarNotifier::Show(LPCTSTR pszCaption, TbnMsg nMsgType, LPCTSTR pszLink // For transparent bitmaps, all animations are disabled. DWORD dwTimeToShow = m_bBitmapAlpha ? 0 : m_dwTimeToShow; if (dwTimeToShow > m_dwTimerPrecision) { - UINT nEvents = max(mini((dwTimeToShow / m_dwTimerPrecision) / 2u, nBitmapSize), 1); //<<-- enkeyDEV(Ottavio84) -Reduced frames of a half- + UINT nEvents = max(mini((dwTimeToShow / m_dwTimerPrecision) / 2, nBitmapSize), 1); //<<-- enkeyDEV(Ottavio84) -Reduced frames of a half- m_dwShowEvents = dwTimeToShow / nEvents; m_nIncrementShow = nBitmapSize / nEvents; } else { diff --git a/srchybrid/TextToSpeech.cpp b/srchybrid/TextToSpeech.cpp index 0e663cfd..e1447cc2 100644 --- a/srchybrid/TextToSpeech.cpp +++ b/srchybrid/TextToSpeech.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -93,9 +93,7 @@ static bool s_bInitialized = false; bool Speak(LPCTSTR pszSay) { #ifdef HAVE_SAPI_H - if (theApp.IsClosing()) - return false; - if (s_bTTSDisabled) + if (s_bTTSDisabled || theApp.IsClosing()) return false; if (!s_bInitialized) { diff --git a/srchybrid/TextToSpeech.h b/srchybrid/TextToSpeech.h index 2146acea..265d732e 100644 --- a/srchybrid/TextToSpeech.h +++ b/srchybrid/TextToSpeech.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/TimeTick.cpp b/srchybrid/TimeTick.cpp index 657da025..e5f70f7f 100644 --- a/srchybrid/TimeTick.cpp +++ b/srchybrid/TimeTick.cpp @@ -8,6 +8,7 @@ #include "stdafx.h" #include "TimeTick.h" +#include "opcodes.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -22,29 +23,24 @@ static char THIS_FILE[] = __FILE__; __int64 CTimeTick::m_nPerformanceFrequency = CTimeTick::GetPerformanceFrequency(); CTimeTick::CTimeTick() - : m_nTimeElapsed() - , m_nTime() + : m_nTime() { } void CTimeTick::Start() { if (m_nPerformanceFrequency) - QueryPerformanceCounter(&m_nTimeElapsed); - m_nTime.QuadPart = 0; + QueryPerformanceCounter(&m_nTime); } float CTimeTick::Tick() { - LARGE_INTEGER nTime; - - if (m_nPerformanceFrequency) { - QueryPerformanceCounter(&nTime); - float nTickTime = GetTimeInMilliSeconds(nTime.QuadPart - m_nTimeElapsed.QuadPart); - m_nTimeElapsed.QuadPart = nTime.QuadPart; - return nTickTime; - } - return 0.0f; + if (!m_nPerformanceFrequency) + return 0.0f; + + LARGE_INTEGER nTime = m_nTime; + QueryPerformanceCounter(&m_nTime); + return GetTimeInMilliSeconds(m_nTime.QuadPart - nTime.QuadPart); } __int64 CTimeTick::GetPerformanceFrequency() @@ -55,5 +51,5 @@ __int64 CTimeTick::GetPerformanceFrequency() float CTimeTick::GetTimeInMilliSeconds(__int64 nTime) { - return (float)nTime * 1000 / m_nPerformanceFrequency; + return SEC2MS(nTime) / (float)m_nPerformanceFrequency; } \ No newline at end of file diff --git a/srchybrid/TimeTick.h b/srchybrid/TimeTick.h index b07498d4..ffa2bee2 100644 --- a/srchybrid/TimeTick.h +++ b/srchybrid/TimeTick.h @@ -31,6 +31,5 @@ class CTimeTick private: static __int64 m_nPerformanceFrequency; - LARGE_INTEGER m_nTimeElapsed; LARGE_INTEGER m_nTime; }; \ No newline at end of file diff --git a/srchybrid/TitleMenu.cpp b/srchybrid/TitleMenu.cpp index bc74720e..676a143d 100644 --- a/srchybrid/TitleMenu.cpp +++ b/srchybrid/TitleMenu.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -149,8 +149,8 @@ void CTitleMenu::DrawItem(LPDRAWITEMSTRUCT lpDIS) if (!g_bLowColorDesktop &&/* m_pfnGradientFill &&*/ m_clLeft != m_clRight) { TRIVERTEX rcVertex[2]; - lpDIS->rcItem.right--; // exclude this point, like FillRect does - lpDIS->rcItem.bottom--; + --lpDIS->rcItem.right; // exclude this point, like FillRect does + --lpDIS->rcItem.bottom; rcVertex[0].x = lpDIS->rcItem.left; rcVertex[0].y = lpDIS->rcItem.top; rcVertex[0].Red = GetRValue(m_clLeft) << 8; // color values from 0x0000 to 0xff00 !!!! @@ -314,13 +314,12 @@ void CTitleMenu::SetMenuBitmap(UINT nFlags, UINT nIDNewItem, LPCTSTR /*lpszNewIt } if (hBmp) { - //MENUITEMINFOEX info = {}; MENUITEMINFO info = {}; info.cbSize = (UINT)sizeof info; info.fMask = MIIM_BITMAP; info.hbmpItem = hBmp; VERIFY(SetMenuItemInfo(nIDNewItem, (MENUITEMINFO*)&info, FALSE)); - m_mapIconNameToBitmap.SetAt(strIconLower, hBmp); + m_mapIconNameToBitmap[strIconLower] = hBmp; } } } else if (!strIconLower.IsEmpty()) { @@ -329,41 +328,14 @@ void CTitleMenu::SetMenuBitmap(UINT nFlags, UINT nIDNewItem, LPCTSTR /*lpszNewIt void *pvIndex; if (m_mapIconNameToIconIdx.Lookup(strIconLower, pvIndex)) { nPos = (int)pvIndex; - m_mapMenuIdToIconIdx.SetAt(nIDNewItem, nPos); + m_mapMenuIdToIconIdx[nIDNewItem] = nPos; } else { HICON hIcon = theApp.LoadIcon(strIconLower); if (hIcon) { nPos = m_ImageList.Add(hIcon); if (nPos >= 0) { - m_mapIconNameToIconIdx.SetAt(strIconLower, (void*)nPos); - m_mapMenuIdToIconIdx.SetAt(nIDNewItem, nPos); - - // It doesn't work to use API checkmark bitmaps in a sufficient way. The size - // of those bitmaps is limited and smaller than our menu item bitmaps. - /*if (nFlags & MF_CHECKED) { - HDC hdcScreen = ::GetDC(HWND_DESKTOP); - if (hdcScreen) { - CDC *pdcScreen = CDC::FromHandle(hdcScreen); - CDC dcMem; - dcMem.CreateCompatibleDC(pdcScreen); - - CBitmap bmpCheckmark; - bmpCheckmark.CreateCompatibleBitmap(pdcScreen, ICONSIZE+4, ICONSIZE+4); - CBitmap *pBmpOld = dcMem.SelectObject(&bmpCheckmark); - static const RECT rc = {0, 0, ICONSIZE + 4, ICONSIZE + 4}; - dcMem.FillSolidRect(&rc, RGB(255, 255, 255)); - m_ImageList.Draw(&dcMem, nPos, CPoint(), ILD_TRANSPARENT); - dcMem.SelectObject(pBmpOld); - - MENUITEMINFO mii = {}; - mii.cbSize = (UINT)sizeof mii; - mii.fMask = MIIM_CHECKMARKS; - mii.hbmpChecked = (HBITMAP)bmpCheckmark.Detach(); // resource leak - VERIFY(SetMenuItemInfo(nIDNewItem, &mii)); - - ::ReleaseDC(HWND_DESKTOP, hdcScreen); - } - }*/ + m_mapIconNameToIconIdx[strIconLower] = (void*)nPos; + m_mapMenuIdToIconIdx[nIDNewItem] = nPos; } VERIFY(::DestroyIcon(hIcon)); } else @@ -414,7 +386,7 @@ void CTitleMenu::DrawMonoIcon(int nIconPos, CPoint nDrawPos, CDC *dc) ULONG_PTR gdiplusToken = 0; Gdiplus::GdiplusStartupInput gdiplusStartupInput; if (Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) == Gdiplus::Ok) { - HICON hIcon = m_ImageList.ExtractIconW(nIconPos); + HICON hIcon = m_IconList.ExtractIconW(nIconPos); if (hIcon) { Gdiplus::Bitmap bmp(hIcon); VERIFY(::DestroyIcon(hIcon)); diff --git a/srchybrid/ToolBarCtrlX.cpp b/srchybrid/ToolBarCtrlX.cpp index 59d17b11..882163ec 100644 --- a/srchybrid/ToolBarCtrlX.cpp +++ b/srchybrid/ToolBarCtrlX.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -37,19 +37,19 @@ void CToolBarCtrlX::DeleteAllButtons() DWORD CToolBarCtrlX::GetBtnStyle(int id) { - TBBUTTONINFO tbbi = {}; + TBBUTTONINFO tbbi; tbbi.cbSize = (UINT)sizeof tbbi; tbbi.dwMask = TBIF_STYLE; - (void)GetButtonInfo(id, &tbbi); - return tbbi.fsStyle; + return (GetButtonInfo(id, &tbbi) < 0 ? 0 : tbbi.fsStyle); } DWORD CToolBarCtrlX::AddBtnStyle(int id, DWORD dwStyle) { - TBBUTTONINFO tbbi = {}; + TBBUTTONINFO tbbi; tbbi.cbSize = (UINT)sizeof tbbi; tbbi.dwMask = TBIF_STYLE; - (void)GetButtonInfo(id, &tbbi); + if (GetButtonInfo(id, &tbbi) < 0) + return 0; DWORD dwOldStyle = tbbi.fsStyle; tbbi.fsStyle |= dwStyle; SetButtonInfo(id, &tbbi); @@ -58,10 +58,11 @@ DWORD CToolBarCtrlX::AddBtnStyle(int id, DWORD dwStyle) DWORD CToolBarCtrlX::RemoveBtnStyle(int id, DWORD dwStyle) { - TBBUTTONINFO tbbi = {}; + TBBUTTONINFO tbbi; tbbi.cbSize = (UINT)sizeof tbbi; tbbi.dwMask = TBIF_STYLE; - (void)GetButtonInfo(id, &tbbi); + if (GetButtonInfo(id, &tbbi) < 0) + return 0; DWORD dwOldStyle = tbbi.fsStyle; tbbi.fsStyle &= ~dwStyle; SetButtonInfo(id, &tbbi); @@ -70,11 +71,10 @@ DWORD CToolBarCtrlX::RemoveBtnStyle(int id, DWORD dwStyle) int CToolBarCtrlX::GetBtnWidth(int nID) { - TBBUTTONINFO tbbi = {}; + TBBUTTONINFO tbbi; tbbi.cbSize = (UINT)sizeof tbbi; tbbi.dwMask = TBIF_SIZE; - (void)GetButtonInfo(nID, &tbbi); - return tbbi.cx; + return (GetButtonInfo(nID, &tbbi) < 0 ? 0 : tbbi.cx); } void CToolBarCtrlX::SetBtnWidth(int nID, int iWidth) @@ -89,19 +89,18 @@ void CToolBarCtrlX::SetBtnWidth(int nID, int iWidth) CString CToolBarCtrlX::GetBtnText(int nID) { TCHAR szString[512]; - TBBUTTONINFO tbbi = {}; + TBBUTTONINFO tbbi; tbbi.cbSize = (UINT)sizeof tbbi; tbbi.dwMask = TBIF_TEXT; tbbi.pszText = szString; tbbi.cchText = _countof(szString); - GetButtonInfo(nID, &tbbi); - szString[_countof(szString) - 1] = _T('\0'); - return szString; + szString[GetButtonInfo(nID, &tbbi) < 0 ? 0 : _countof(szString) - 1] = _T('\0'); + return CString(szString); } void CToolBarCtrlX::SetBtnText(int nID, LPCTSTR pszString) { - TBBUTTONINFO tbbi = {}; + TBBUTTONINFO tbbi; tbbi.cbSize = (UINT)sizeof tbbi; tbbi.dwMask = TBIF_TEXT; tbbi.pszText = const_cast(pszString); @@ -119,7 +118,6 @@ void CToolBarCtrlX::SetPadding(CSize sizPadding) SendMessage(TB_SETPADDING, 0, MAKELPARAM(sizPadding.cx, sizPadding.cy)); } - void CToolBarCtrlX::AdjustFont(int iMaxPointSize, CSize sizButton) { // The toolbar control uses the font which is specified in the current system @@ -176,12 +174,5 @@ void CToolBarCtrlX::RecalcLayout() int CToolBarCtrlX::AddString(const CString &strToAdd) { - int nLen = strToAdd.GetLength(); - TCHAR *apChar = new TCHAR[nLen + 2]; - _tcsncpy(apChar, strToAdd, nLen); - apChar[nLen] = _T('\0'); - apChar[nLen + 1] = _T('\0'); - nLen = AddStrings(apChar); - delete[] apChar; - return nLen; + return AddStrings(strToAdd + _T('\0')); //2 NULs required } \ No newline at end of file diff --git a/srchybrid/ToolBarCtrlX.h b/srchybrid/ToolBarCtrlX.h index c2e0b3cf..827b653e 100644 --- a/srchybrid/ToolBarCtrlX.h +++ b/srchybrid/ToolBarCtrlX.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -20,9 +20,6 @@ class CToolBarCtrlX : public CToolBarCtrl { DECLARE_DYNAMIC(CToolBarCtrlX) public: - CToolBarCtrlX() = default; - virtual ~CToolBarCtrlX() = default; - void AdjustFont(int iMaxPointSize, CSize sizButton); void RecalcLayout(); void DeleteAllButtons(); diff --git a/srchybrid/ToolTipCtrlX.cpp b/srchybrid/ToolTipCtrlX.cpp index 4a82b61b..82553d05 100644 --- a/srchybrid/ToolTipCtrlX.cpp +++ b/srchybrid/ToolTipCtrlX.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -122,7 +122,7 @@ void CToolTipCtrlX::CustomPaint(LPNMTTCUSTOMDRAW pNMCD) // // Windows Vista *with* SP1 // ------------------------ - // The Vista SP1(!) 'TOOLTIP' theme does though *not* offer a bold font. Keep + // The Vista SP1(!) 'TOOLTIP' theme does *not* offer a bold font. Keep // in mind that TTP_STANDARDTITLE does not return a bold font. Keep also in mind // that TTP_STANDARDTITLE is even a *different* font than TTP_STANDARD! // Which means, that TTP_STANDARDTITLE should *not* be used within the same line @@ -135,7 +135,7 @@ void CToolTipCtrlX::CustomPaint(LPNMTTCUSTOMDRAW pNMCD) // ---------- // Can *not* use the 'TOOLTIP' theme at all because it would give us only a (non-bold) // black font on a white tooltip window background. Seems that the 'TOOLTIP' theme under - // WinXP is just using the default Window values (black+white) and does not + // WinXP is just using the default Window values (black + white) and does not // use any of the tooltip specific Window metrics... // bool bUseEmbeddedThemeFonts = false; @@ -526,7 +526,7 @@ BOOL CToolTipCtrlX::OnTTShow(LPNMHDR pNMHDR, LRESULT *pResult) return TRUE; // MFC API: Suppress further routing of this message } - // If the TTN_SHOW notification is not sent to the sub-classed tooltip control, we would lose the + // If the TTN_SHOW notification is not sent to the subclassed tooltip control, we would lose the // exact positioning of in-place tooltips which is performed by the tooltip control by default. // Thus it is important that we tell MFC (not the Windows API in that case) to further route this message. *pResult = FALSE; // Windows API: Perform default positioning diff --git a/srchybrid/ToolTipCtrlX.h b/srchybrid/ToolTipCtrlX.h index f5c3d499..06cb5f4b 100644 --- a/srchybrid/ToolTipCtrlX.h +++ b/srchybrid/ToolTipCtrlX.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -24,7 +24,6 @@ class CToolTipCtrlX : public CToolTipCtrl DECLARE_DYNAMIC(CToolTipCtrlX) public: CToolTipCtrlX(); - virtual ~CToolTipCtrlX() = default; void SetCol1DrawTextFlags(DWORD dwFlags); void SetCol2DrawTextFlags(DWORD dwFlags); diff --git a/srchybrid/ToolbarWnd.cpp b/srchybrid/ToolbarWnd.cpp index 0c64be84..c0712940 100644 --- a/srchybrid/ToolbarWnd.cpp +++ b/srchybrid/ToolbarWnd.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -21,7 +21,6 @@ #include "toolbarwnd.h" #include "HelpIDs.h" #include "OtherFunctions.h" -#include "ToolBarCtrlX.h" #include "MenuCmds.h" #include "DownloadListCtrl.h" #include "TransferDlg.h" @@ -51,65 +50,58 @@ END_MESSAGE_MAP() CToolbarWnd::CToolbarWnd() - : m_pCommandTargetWnd() + : m_hcurMove(::LoadCursor(NULL, IDC_SIZEALL)) // load default windows system cursor (a shared resource) + , m_pCommandTargetWnd() { - m_btnBar = new CToolBarCtrlX; - // load default windows system cursor (a shared resource) - m_hcurMove = ::LoadCursor(NULL, IDC_SIZEALL); -} - -CToolbarWnd::~CToolbarWnd() -{ - delete m_btnBar; } void CToolbarWnd::DoDataExchange(CDataExchange *pDX) { CDialogBar::DoDataExchange(pDX); - DDX_Control(pDX, IDC_DTOOLBAR, *m_btnBar); + DDX_Control(pDX, IDC_DTOOLBAR, m_btnBar); } #define DTOOLBAR_NUM_BUTTONS 18 void CToolbarWnd::FillToolbar() { - m_btnBar->DeleteAllButtons(); + m_btnBar.DeleteAllButtons(); TBBUTTON atb1[DTOOLBAR_NUM_BUTTONS] = {}; - atb1[0].iBitmap = 0; + //atb1[0].iBitmap = 0; atb1[0].idCommand = MP_PRIOLOW; atb1[0].fsState = TBSTATE_WRAP; atb1[0].fsStyle = BTNS_DROPDOWN | BTNS_AUTOSIZE; CString sPrio(GetResString(IDS_PRIORITY)); sPrio.AppendFormat(_T(" (%s)"), (LPCTSTR)GetResString(IDS_DOWNLOAD)); - atb1[0].iString = m_btnBar->AddString(sPrio); + atb1[0].iString = m_btnBar.AddString(sPrio); atb1[1].iBitmap = 1; atb1[1].idCommand = MP_PAUSE; atb1[1].fsState = TBSTATE_WRAP; atb1[1].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; - atb1[1].iString = m_btnBar->AddString(GetResString(IDS_DL_PAUSE)); + atb1[1].iString = m_btnBar.AddString(GetResString(IDS_DL_PAUSE)); atb1[2].iBitmap = 2; atb1[2].idCommand = MP_STOP; atb1[2].fsState = TBSTATE_WRAP; atb1[2].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; - atb1[2].iString = m_btnBar->AddString(GetResString(IDS_DL_STOP)); + atb1[2].iString = m_btnBar.AddString(GetResString(IDS_DL_STOP)); atb1[3].iBitmap = 3; atb1[3].idCommand = MP_RESUME; atb1[3].fsState = TBSTATE_WRAP; atb1[3].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; - atb1[3].iString = m_btnBar->AddString(GetResString(IDS_DL_RESUME)); + atb1[3].iString = m_btnBar.AddString(GetResString(IDS_DL_RESUME)); atb1[4].iBitmap = 4; atb1[4].idCommand = MP_CANCEL; atb1[4].fsState = TBSTATE_WRAP; atb1[4].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; - atb1[4].iString = m_btnBar->AddString(GetResString(IDS_MAIN_BTN_CANCEL)); + atb1[4].iString = m_btnBar.AddString(GetResString(IDS_MAIN_BTN_CANCEL)); ///////////// atb1[5].iBitmap = -1; - atb1[5].idCommand = 0; + //atb1[5].idCommand = 0; atb1[5].fsState = TBSTATE_WRAP; atb1[5].fsStyle = BTNS_SEP; atb1[5].iString = -1; @@ -118,41 +110,41 @@ void CToolbarWnd::FillToolbar() atb1[6].idCommand = MP_OPEN; atb1[6].fsState = TBSTATE_WRAP; atb1[6].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; - atb1[6].iString = m_btnBar->AddString(GetResString(IDS_DL_OPEN)); + atb1[6].iString = m_btnBar.AddString(GetResString(IDS_DL_OPEN)); atb1[7].iBitmap = 6; atb1[7].idCommand = MP_OPENFOLDER; atb1[7].fsState = TBSTATE_WRAP; atb1[7].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; - atb1[7].iString = m_btnBar->AddString(GetResString(IDS_OPENFOLDER)); + atb1[7].iString = m_btnBar.AddString(GetResString(IDS_OPENFOLDER)); atb1[8].iBitmap = 7; atb1[8].idCommand = MP_PREVIEW; atb1[8].fsState = TBSTATE_WRAP; atb1[8].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; - atb1[8].iString = m_btnBar->AddString(GetResString(IDS_DL_PREVIEW)); + atb1[8].iString = m_btnBar.AddString(GetResString(IDS_DL_PREVIEW)); atb1[9].iBitmap = 8; atb1[9].idCommand = MP_METINFO; atb1[9].fsState = TBSTATE_WRAP; atb1[9].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; - atb1[9].iString = m_btnBar->AddString(GetResString(IDS_DL_INFO)); + atb1[9].iString = m_btnBar.AddString(GetResString(IDS_DL_INFO)); atb1[10].iBitmap = 9; atb1[10].idCommand = MP_VIEWFILECOMMENTS; atb1[10].fsState = TBSTATE_WRAP; atb1[10].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; - atb1[10].iString = m_btnBar->AddString(GetResString(IDS_CMT_SHOWALL)); + atb1[10].iString = m_btnBar.AddString(GetResString(IDS_CMT_SHOWALL)); atb1[11].iBitmap = 10; atb1[11].idCommand = MP_SHOWED2KLINK; atb1[11].fsState = TBSTATE_WRAP; atb1[11].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; - atb1[11].iString = m_btnBar->AddString(GetResString(IDS_DL_SHOWED2KLINK)); + atb1[11].iString = m_btnBar.AddString(GetResString(IDS_DL_SHOWED2KLINK)); ///////////// atb1[12].iBitmap = -1; - atb1[12].idCommand = 0; + //atb1[12].idCommand = 0; atb1[12].fsState = TBSTATE_WRAP; atb1[12].fsStyle = BTNS_SEP; atb1[12].iString = -1; @@ -161,23 +153,23 @@ void CToolbarWnd::FillToolbar() atb1[13].idCommand = MP_NEWCAT; atb1[13].fsState = TBSTATE_WRAP; atb1[13].fsStyle = BTNS_DROPDOWN | BTNS_AUTOSIZE; - atb1[13].iString = m_btnBar->AddString(GetResString(IDS_TOCAT)); + atb1[13].iString = m_btnBar.AddString(GetResString(IDS_TOCAT)); atb1[14].iBitmap = 12; atb1[14].idCommand = MP_CLEARCOMPLETED; atb1[14].fsState = TBSTATE_WRAP; atb1[14].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; - atb1[14].iString = m_btnBar->AddString(GetResString(IDS_DL_CLEAR)); + atb1[14].iString = m_btnBar.AddString(GetResString(IDS_DL_CLEAR)); atb1[15].iBitmap = 13; atb1[15].idCommand = MP_SEARCHRELATED; atb1[15].fsState = TBSTATE_WRAP; atb1[15].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; - atb1[15].iString = m_btnBar->AddString(GetResString(IDS_SEARCHRELATED)); + atb1[15].iString = m_btnBar.AddString(GetResString(IDS_SEARCHRELATED)); ///////////// atb1[16].iBitmap = -1; - atb1[16].idCommand = 0; + //atb1[16].idCommand = 0; atb1[16].fsState = TBSTATE_ENABLED | TBSTATE_WRAP; atb1[16].fsStyle = BTNS_SEP; atb1[16].iString = -1; @@ -186,9 +178,9 @@ void CToolbarWnd::FillToolbar() atb1[17].idCommand = MP_FIND; atb1[17].fsState = TBSTATE_ENABLED | TBSTATE_WRAP; atb1[17].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; - atb1[17].iString = m_btnBar->AddString(GetResString(IDS_FIND)); + atb1[17].iString = m_btnBar.AddString(GetResString(IDS_FIND)); - m_btnBar->AddButtons(_countof(atb1), atb1); + m_btnBar.AddButtons(_countof(atb1), atb1); } LRESULT CToolbarWnd::OnInitDialog(WPARAM, LPARAM) @@ -248,21 +240,20 @@ LRESULT CToolbarWnd::OnInitDialog(WPARAM, LPARAM) VERIFY(AddIconGrayscaledToImageList(iml2, CTempIconLoader(_T("CLEARCOMPLETE")))); VERIFY(AddIconGrayscaledToImageList(iml2, CTempIconLoader(_T("KadFileSearch")))); VERIFY(AddIconGrayscaledToImageList(iml2, CTempIconLoader(_T("Search")))); - CImageList *pImlOld = m_btnBar->SetDisabledImageList(&iml2); + CImageList *pImlOld = m_btnBar.SetDisabledImageList(&iml2); iml2.Detach(); if (pImlOld) pImlOld->DeleteImageList(); } - CImageList *pImlOld = m_btnBar->SetImageList(&iml); + CImageList *pImlOld = m_btnBar.SetImageList(&iml); iml.Detach(); if (pImlOld) pImlOld->DeleteImageList(); - m_btnBar->ModifyStyle((theApp.m_ullComCtrlVer >= MAKEDLLVERULL(6, 16, 0, 0)) ? TBSTYLE_TRANSPARENT : 0, 0); - m_btnBar->SetMaxTextRows(0); - - FillToolbar(); + m_btnBar.ModifyStyle((theApp.m_ullComCtrlVer >= MAKEDLLVERULL(6, 16, 0, 0)) ? TBSTYLE_TRANSPARENT : 0, 0); + m_btnBar.SetMaxTextRows(0); + Localize(); return TRUE; } @@ -358,14 +349,14 @@ BOOL CToolbarWnd::OnSetCursor(CWnd *pWnd, UINT nHitTest, UINT message) void CToolbarWnd::OnSize(UINT nType, int cx, int cy) { CDialogBar::OnSize(nType, cx, cy); - if (m_btnBar->m_hWnd == 0) + if (m_btnBar.m_hWnd == 0) return; if (cx >= MIN_HORZ_WIDTH) { CRect rcClient; GetClientRect(&rcClient); CalcInsideRect(rcClient, TRUE); - m_btnBar->MoveWindow(rcClient.left + 1, rcClient.top, rcClient.Width() - 8, 22); + m_btnBar.MoveWindow(rcClient.left + 1, rcClient.top, rcClient.Width() - 8, 22); //int iWidthOpts = rcClient.right - (rcClient.left + m_rcOpts.left); /*HDWP hdwp = BeginDeferWindowPos(0); if (hdwp) { @@ -377,13 +368,13 @@ void CToolbarWnd::OnSize(UINT nType, int cx, int cy) CRect rcClient; GetClientRect(&rcClient); CalcInsideRect(rcClient, FALSE); - m_btnBar->MoveWindow(rcClient.left, rcClient.top + 1, 24, rcClient.Height() - 1); + m_btnBar.MoveWindow(rcClient.left, rcClient.top + 1, 24, rcClient.Height() - 1); } } void CToolbarWnd::OnUpdateCmdUI(CFrameWnd* /*pTarget*/, BOOL /*bDisableIfNoHndler*/) { - if (!theApp.IsClosing() && m_pCommandTargetWnd != NULL) { + if (m_pCommandTargetWnd != NULL && !theApp.IsClosing()) { CList liCommands; if (m_pCommandTargetWnd->ReportAvailableCommands(liCommands)) OnAvailableCommandsChanged(&liCommands); @@ -410,9 +401,7 @@ void CToolbarWnd::Localize() BOOL CToolbarWnd::PreTranslateMessage(MSG *pMsg) { - if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE) - return FALSE; - return CDialogBar::PreTranslateMessage(pMsg); + return (pMsg->message != WM_KEYDOWN || pMsg->wParam != VK_ESCAPE) && CDialogBar::PreTranslateMessage(pMsg); } BOOL CToolbarWnd::OnHelpInfo(HELPINFO*) @@ -423,15 +412,13 @@ BOOL CToolbarWnd::OnHelpInfo(HELPINFO*) void CToolbarWnd::OnAvailableCommandsChanged(CList *liCommands) { - TBBUTTONINFO tbbi = {}; + TBBUTTONINFO tbbi; tbbi.cbSize = (UINT)sizeof tbbi; + tbbi.dwMask = TBIF_COMMAND | TBIF_BYINDEX | TBIF_STATE | TBIF_STYLE; - for (int i = m_btnBar->GetButtonCount(); --i >= 0;) { - tbbi.dwMask = TBIF_COMMAND | TBIF_BYINDEX | TBIF_STATE | TBIF_STYLE; - m_btnBar->GetButtonInfo(i, &tbbi); - if ((tbbi.fsStyle & BTNS_SEP) == 0) - m_btnBar->EnableButton(tbbi.idCommand, static_cast(liCommands->Find(tbbi.idCommand) != NULL)); - } + for (int i = m_btnBar.GetButtonCount(); --i >= 0;) + if (m_btnBar.GetButtonInfo(i, &tbbi) >= 0 && (tbbi.fsStyle & BTNS_SEP) == 0) + m_btnBar.EnableButton(tbbi.idCommand, static_cast(liCommands->Find(tbbi.idCommand) != NULL)); } BOOL CToolbarWnd::OnCommand(WPARAM wParam, LPARAM) @@ -449,13 +436,13 @@ void CToolbarWnd::OnBtnDropDown(LPNMHDR pNMHDR, LRESULT *pResult) TBNOTIFY *tbn = (TBNOTIFY*)pNMHDR; if (tbn->iItem == MP_PRIOLOW) { RECT rc; - m_btnBar->GetItemRect(m_btnBar->CommandToIndex(MP_PRIOLOW), &rc); - m_btnBar->ClientToScreen(&rc); + m_btnBar.GetItemRect(m_btnBar.CommandToIndex(MP_PRIOLOW), &rc); + m_btnBar.ClientToScreen(&rc); m_pCommandTargetWnd->GetPrioMenu()->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, rc.left, rc.bottom, this); } else if (tbn->iItem == MP_NEWCAT) { RECT rc; - m_btnBar->GetItemRect(m_btnBar->CommandToIndex(MP_NEWCAT), &rc); - m_btnBar->ClientToScreen(&rc); + m_btnBar.GetItemRect(m_btnBar.CommandToIndex(MP_NEWCAT), &rc); + m_btnBar.ClientToScreen(&rc); CMenu menu; menu.CreatePopupMenu(); m_pCommandTargetWnd->FillCatsMenu(menu); @@ -495,12 +482,10 @@ void CToolbarWnd::DelayShow(BOOL bShow) void CToolbarWnd::OnSysCommand(UINT nID, LPARAM lParam) { - if (nID == SC_KEYMENU) { - if (lParam == EMULE_HOTMENU_ACCEL) - theApp.emuledlg->SendMessage(WM_COMMAND, IDC_HOTMENU); - else - theApp.emuledlg->SendMessage(WM_SYSCOMMAND, nID, lParam); - return; - } - __super::OnSysCommand(nID, lParam); + if (nID != SC_KEYMENU) + __super::OnSysCommand(nID, lParam); + else if (lParam == EMULE_HOTMENU_ACCEL) + theApp.emuledlg->SendMessage(WM_COMMAND, IDC_HOTMENU); + else + theApp.emuledlg->SendMessage(WM_SYSCOMMAND, nID, lParam); } \ No newline at end of file diff --git a/srchybrid/ToolbarWnd.h b/srchybrid/ToolbarWnd.h index b2977b4b..1bf0150b 100644 --- a/srchybrid/ToolbarWnd.h +++ b/srchybrid/ToolbarWnd.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -17,7 +17,8 @@ #pragma once -class CToolBarCtrlX; +#include "ToolBarCtrlX.h" + class CDownloadListCtrl; class CToolbarWnd : public CDialogBar @@ -31,7 +32,6 @@ class CToolbarWnd : public CDialogBar public: CToolbarWnd(); - virtual ~CToolbarWnd(); void Localize(); void OnAvailableCommandsChanged(CList *liCommands); @@ -43,9 +43,9 @@ class CToolbarWnd : public CDialogBar protected: HCURSOR m_hcurMove; - CSize m_szMRU; - CSize m_szFloat; - CToolBarCtrlX *m_btnBar; + CSize m_szMRU; + CSize m_szFloat; + CToolBarCtrlX m_btnBar; CDownloadListCtrl *m_pCommandTargetWnd; // void SetAllIcons(); diff --git a/srchybrid/TransferDlg.cpp b/srchybrid/TransferDlg.cpp index 08f57a85..e9ff75c6 100644 --- a/srchybrid/TransferDlg.cpp +++ b/srchybrid/TransferDlg.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -19,8 +19,6 @@ #include "emule.h" #include "emuleDlg.h" #include "TransferDlg.h" -#include "TransferWnd.h" -#include "ToolbarWnd.h" #include "OtherFunctions.h" #include "HelpIDs.h" #include "Preferences.h" @@ -47,14 +45,8 @@ BEGIN_MESSAGE_MAP(CTransferDlg, CFrameWnd) END_MESSAGE_MAP() CTransferDlg::CTransferDlg() + : m_pwndTransfer() { - m_pwndToolbar = new CToolbarWnd; - m_pwndTransfer = NULL; -} - -CTransferDlg::~CTransferDlg() -{ - delete m_pwndToolbar; } BOOL CTransferDlg::Create(CWnd *pParent) @@ -82,23 +74,23 @@ int CTransferDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) m_pwndTransfer->ModifyStyle(WS_BORDER, 0); m_pwndTransfer->ModifyStyleEx(WS_EX_CLIENTEDGE, WS_EX_STATICEDGE); - m_pwndToolbar->Create(this, IDD_DOWNLOAD_TOOLBARS + m_wndToolbar.Create(this, IDD_DOWNLOAD_TOOLBARS , WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_SIZE_FIXED | CBRS_SIZE_DYNAMIC | CBRS_GRIPPER , IDBAR_DOWNLOAD_TOOLBAR); - ASSERT(m_pwndToolbar->GetStyle() & WS_CLIPSIBLINGS); - ASSERT(m_pwndToolbar->GetStyle() & WS_CLIPCHILDREN); - m_pwndToolbar->SetWindowText(GetResString(IDS_DOWNLOADCOMMANDS)); - m_pwndToolbar->EnableDocking(CBRS_ALIGN_ANY); + ASSERT(m_wndToolbar.GetStyle() & WS_CLIPSIBLINGS); + ASSERT(m_wndToolbar.GetStyle() & WS_CLIPCHILDREN); + m_wndToolbar.SetWindowText(GetResString(IDS_DOWNLOADCOMMANDS)); + m_wndToolbar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); - DockControlBar(m_pwndToolbar, AFX_IDW_DOCKBAR_LEFT, (LPRECT)NULL); + DockControlBar(&m_wndToolbar, AFX_IDW_DOCKBAR_LEFT, (LPRECT)NULL); m_pwndTransfer->SendMessage(WM_INITIALUPDATE); LoadBarState(DOWNLOAD_TOOLBAR_PROFILE); - DockToolbarWnd(); // Too much bug reports about vanished search parameters window. Force to dock. + DockToolbarWnd(); // Too many bug reports about vanished search parameters window. Force to dock. ShowToolbar(thePrefs.IsDownloadToolbarEnabled()); - m_pwndToolbar->SetCommandTargetWnd(GetDownloadList()); + m_wndToolbar.SetCommandTargetWnd(GetDownloadList()); Localize(); return 0; @@ -113,9 +105,9 @@ void CTransferDlg::OnClose() void CTransferDlg::OnShowWindow(BOOL bShow, UINT nStatus) { CFrameWnd::OnShowWindow(bShow, nStatus); - if (m_pwndToolbar->IsFloating()) { - //ShowControlBar(m_pwndParams, bShow, TRUE); - DockToolbarWnd(); // Too much bug reports about vanished search parameters window. Force to dock. + if (m_wndToolbar.IsFloating()) { + //ShowControlBar(&m_pwndParams, bShow, TRUE); + DockToolbarWnd(); // Too many bug reports about vanished search parameters window. Force to dock. } } @@ -126,18 +118,18 @@ void CTransferDlg::OnSetFocus(CWnd *pOldWnd) void CTransferDlg::DockToolbarWnd() { - if (m_pwndToolbar->IsFloating()) { + if (m_wndToolbar.IsFloating()) { UINT uMRUDockID = AFX_IDW_DOCKBAR_TOP; - if (m_pwndToolbar->m_pDockContext) - uMRUDockID = m_pwndToolbar->m_pDockContext->m_uMRUDockID; - DockControlBar(m_pwndToolbar, uMRUDockID); + if (m_wndToolbar.m_pDockContext) + uMRUDockID = m_wndToolbar.m_pDockContext->m_uMRUDockID; + DockControlBar(&m_wndToolbar, uMRUDockID); } } void CTransferDlg::Localize() { m_pwndTransfer->Localize(); - m_pwndToolbar->Localize(); + m_wndToolbar.Localize(); } void CTransferDlg::OnSysCommand(UINT nID, LPARAM lParam) @@ -175,9 +167,9 @@ BOOL CTransferDlg::OnHelpInfo(HELPINFO*) void CTransferDlg::ShowToolbar(bool bShow) { - if (m_pwndToolbar->IsVisible() != static_cast(bShow)) + if (m_wndToolbar.IsVisible() != static_cast(bShow)) if (thePrefs.IsDownloadToolbarEnabled() || !bShow) - ShowControlBar(m_pwndToolbar, static_cast(bShow), TRUE); + ShowControlBar(&m_wndToolbar, static_cast(bShow), TRUE); } @@ -230,9 +222,9 @@ void CTransferDlg::OnDisableList() m_pwndTransfer->OnDisableList(); } -void CTransferDlg::UpdateListCount(EWnd2 listindex, int iCount) +void CTransferDlg::UpdateListCount(CTransferWnd::EWnd2 listindex, int iCount) { - m_pwndTransfer->UpdateListCount((CTransferWnd::EWnd2)listindex, iCount); + m_pwndTransfer->UpdateListCount(listindex, iCount); } int CTransferDlg::AddCategory(const CString &newtitle, const CString &newincoming, const CString &newcomment, const CString &newautocat, bool addTab) @@ -265,9 +257,4 @@ CDownloadClientsCtrl* CTransferDlg::GetDownloadClientsList() { return &m_pwndTransfer->downloadclientsctrl; } - -CImageList* CTransferDlg::GetClientIconList() const -{ - return &m_pwndTransfer->m_ImageList; -} ////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/srchybrid/TransferDlg.h b/srchybrid/TransferDlg.h index 25b54de5..e7ad9317 100644 --- a/srchybrid/TransferDlg.h +++ b/srchybrid/TransferDlg.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -21,25 +21,15 @@ #include "QueueListCtrl.h" #include "ClientListCtrl.h" #include "DownloadClientsCtrl.h" - -class CTransferWnd; -class CToolbarWnd; +#include "TransferWnd.h" +#include "ToolbarWnd.h" class CTransferDlg : public CFrameWnd { DECLARE_DYNCREATE(CTransferDlg) public: - enum EWnd2 - { - wnd2Downloading = 0, - wnd2Uploading = 1, - wnd2OnQueue = 2, - wnd2Clients = 3 - }; - CTransferDlg(); // protected constructor used by dynamic creation - virtual ~CTransferDlg(); CTransferWnd *m_pwndTransfer; BOOL Create(CWnd *pParent); @@ -55,7 +45,7 @@ class CTransferDlg : public CFrameWnd void ResetTransToolbar(bool bShowToolbar, bool bResetLists = true); void SetToolTipsDelay(DWORD dwDelay); void OnDisableList(); - void UpdateListCount(EWnd2 listindex, int iCount = -1); + void UpdateListCount(CTransferWnd::EWnd2 listindex, int iCount = -1); int AddCategory(const CString &newtitle, const CString &newincoming, const CString &newcomment, const CString &newautocat, bool addTab = true); void ShowToolbar(bool bShow); @@ -64,10 +54,9 @@ class CTransferDlg : public CFrameWnd CQueueListCtrl* GetQueueList(); CClientListCtrl* GetClientList(); CDownloadClientsCtrl* GetDownloadClientsList(); - CImageList* GetClientIconList() const; protected: - CToolbarWnd *m_pwndToolbar; + CToolbarWnd m_wndToolbar; virtual BOOL PreTranslateMessage(MSG *pMsg); void DockToolbarWnd(); diff --git a/srchybrid/TransferWnd.cpp b/srchybrid/TransferWnd.cpp index e1ca4afb..ee3c36a2 100644 --- a/srchybrid/TransferWnd.cpp +++ b/srchybrid/TransferWnd.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -30,8 +30,6 @@ #include "InputBox.h" #include "UserMsgs.h" #include "SharedFileList.h" -#include "DropDownButton.h" -#include "ToolTipCtrlX.h" #include "SharedFilesWnd.h" #include "HelpIDs.h" @@ -86,58 +84,29 @@ END_MESSAGE_MAP() CTransferWnd::CTransferWnd(CWnd* /*pParent =NULL*/) : CResizableFormView(CTransferWnd::IDD) + //, m_pImageList(&CTransferWnd::m_ImageList) + , m_pLastMousePoint(POINT{ -1, -1 }) , m_uWnd2(wnd2Uploading) - , downloadlistactive() + , m_pDragImage() + , m_dwShowListIDC() , m_rightclickindex() , m_nDragIndex() , m_nDropIndex() , m_nLastCatTT(-1) , m_isetcatmenu() , m_bIsDragging() - , m_pDragImage() - , m_pLastMousePoint(POINT{-1, -1}) - , m_dwShowListIDC() + , downloadlistactive() , m_bLayoutInited() { - m_btnWnd1 = new CDropDownButton; - m_btnWnd2 = new CDropDownButton; - m_tooltipCats = new CToolTipCtrlX; - SetImageList(); + //SetImageList(); } CTransferWnd::~CTransferWnd() { - delete m_btnWnd1; - delete m_btnWnd2; - delete m_tooltipCats; ASSERT(m_pDragImage == NULL); delete m_pDragImage; } -void CTransferWnd::SetImageList() -{ - m_ImageList.Create(16, 16, theApp.m_iDfltImageListColorFlags | ILC_MASK, 0, 1); - m_ImageList.Add(CTempIconLoader(_T("ClientEDonkey"))); //0 - eDonkey - m_ImageList.Add(CTempIconLoader(_T("ClientEDonkeyPlus"))); - m_ImageList.Add(CTempIconLoader(_T("ClientCompatible"))); //2 - Compat - m_ImageList.Add(CTempIconLoader(_T("ClientCompatiblePlus"))); - m_ImageList.Add(CTempIconLoader(_T("Friend"))); //4 - friend - m_ImageList.Add(CTempIconLoader(_T("ClientMLDonkey"))); //5 - ML - m_ImageList.Add(CTempIconLoader(_T("ClientMLDonkeyPlus"))); - m_ImageList.Add(CTempIconLoader(_T("ClientEDonkeyHybrid"))); //7 - Hybrid - m_ImageList.Add(CTempIconLoader(_T("ClientEDonkeyHybridPlus"))); - m_ImageList.Add(CTempIconLoader(_T("ClientShareaza"))); //9 - Shareaza - m_ImageList.Add(CTempIconLoader(_T("ClientShareazaPlus"))); - m_ImageList.Add(CTempIconLoader(_T("ClientAMule"))); //11 - amule - m_ImageList.Add(CTempIconLoader(_T("ClientAMulePlus"))); - m_ImageList.Add(CTempIconLoader(_T("ClientLPhant"))); //13 - Lphant - m_ImageList.Add(CTempIconLoader(_T("ClientLPhantPlus"))); - m_ImageList.Add(CTempIconLoader(_T("Server"))); //15 - http source - m_ImageList.SetOverlayImage(m_ImageList.Add(CTempIconLoader(_T("ClientSecureOvl"))), 1); - m_ImageList.SetOverlayImage(m_ImageList.Add(CTempIconLoader(_T("OverlayObfu"))), 2); - m_ImageList.SetOverlayImage(m_ImageList.Add(CTempIconLoader(_T("OverlaySecureObfu"))), 3); -} - void CTransferWnd::OnInitialUpdate() { CResizableFormView::OnInitialUpdate(); @@ -189,19 +158,19 @@ void CTransferWnd::OnInitialUpdate() cat0->strIncomingPath = thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR); cat0->care4all = true; - for (int ix = 0; ix < thePrefs.GetCatCount(); ++ix) - m_dlTab.InsertItem(ix, thePrefs.GetCategory(ix)->strTitle); + for (INT_PTR i = 0; i < thePrefs.GetCatCount(); ++i) + m_dlTab.InsertItem((int)i, thePrefs.GetCategory(i)->strTitle); // create tooltip control for download categories - m_tooltipCats->Create(this, TTS_NOPREFIX); - m_dlTab.SetToolTips(m_tooltipCats); + m_tooltipCats.Create(this, TTS_NOPREFIX); + m_dlTab.SetToolTips(&m_tooltipCats); UpdateCatTabTitles(); UpdateTabToolTips(); - m_tooltipCats->SetMargin(CRect(4, 4, 4, 4)); - m_tooltipCats->SendMessage(TTM_SETMAXTIPWIDTH, 0, SHRT_MAX); // recognize \n chars! - m_tooltipCats->SetDelayTime(TTDT_AUTOPOP, SEC2MS(20)); - m_tooltipCats->SetDelayTime(TTDT_INITIAL, SEC2MS(thePrefs.GetToolTipDelay())); - m_tooltipCats->Activate(TRUE); + m_tooltipCats.SetMargin(CRect(4, 4, 4, 4)); + m_tooltipCats.SendMessage(TTM_SETMAXTIPWIDTH, 0, SHRT_MAX); // recognise \n chars! + m_tooltipCats.SetDelayTime(TTDT_AUTOPOP, SEC2MS(20)); + m_tooltipCats.SetDelayTime(TTDT_INITIAL, SEC2MS(thePrefs.GetToolTipDelay())); + m_tooltipCats.Activate(TRUE); VerifyCatTabSize(); Localize(); @@ -217,8 +186,8 @@ void CTransferWnd::ShowQueueCount(INT_PTR number) void CTransferWnd::DoDataExchange(CDataExchange *pDX) { CResizableFormView::DoDataExchange(pDX); - DDX_Control(pDX, IDC_DOWNLOAD_ICO, *m_btnWnd1); - DDX_Control(pDX, IDC_UPLOAD_ICO, *m_btnWnd2); + DDX_Control(pDX, IDC_DOWNLOAD_ICO, m_btnWnd1); + DDX_Control(pDX, IDC_UPLOAD_ICO, m_btnWnd2); DDX_Control(pDX, IDC_DLTAB, m_dlTab); DDX_Control(pDX, IDC_UPLOADLIST, uploadlistctrl); DDX_Control(pDX, IDC_DOWNLOADLIST, downloadlistctrl); @@ -234,7 +203,7 @@ void CTransferWnd::DoResize(int delta) CSplitterControl::ChangeHeight(&queuelistctrl, -delta, CW_BOTTOMALIGN); CSplitterControl::ChangeHeight(&clientlistctrl, -delta, CW_BOTTOMALIGN); CSplitterControl::ChangeHeight(&downloadclientsctrl, -delta, CW_BOTTOMALIGN); - CSplitterControl::ChangePos(m_btnWnd2, 0, delta); + CSplitterControl::ChangePos(&m_btnWnd2, 0, delta); UpdateSplitterRange(); @@ -292,14 +261,14 @@ void CTransferWnd::UpdateSplitterRange() thePrefs.SetSplitterbarPosition((rcDown.bottom * 100) / rcWnd.Height()); - RemoveAnchor(*m_btnWnd2); + RemoveAnchor(m_btnWnd2); RemoveAnchor(IDC_DOWNLOADLIST); RemoveAnchor(IDC_UPLOADLIST); RemoveAnchor(IDC_QUEUELIST); RemoveAnchor(IDC_CLIENTLIST); RemoveAnchor(IDC_DOWNLOADCLIENTS); - AddAnchor(*m_btnWnd2, ANCHOR(0, thePrefs.GetSplitterbarPosition())); + AddAnchor(m_btnWnd2, ANCHOR(0, thePrefs.GetSplitterbarPosition())); AddAnchor(IDC_DOWNLOADLIST, TOP_LEFT, ANCHOR(100, thePrefs.GetSplitterbarPosition())); AddAnchor(IDC_UPLOADLIST, ANCHOR(0, thePrefs.GetSplitterbarPosition()), BOTTOM_RIGHT); AddAnchor(IDC_QUEUELIST, ANCHOR(0, thePrefs.GetSplitterbarPosition()), BOTTOM_RIGHT); @@ -326,63 +295,71 @@ BOOL CTransferWnd::PreTranslateMessage(MSG *pMsg) { if (theApp.emuledlg->m_pSplashWnd) return FALSE; - if (pMsg->message == WM_KEYDOWN) { + switch (pMsg->message) { + case WM_MOUSEMOVE: + { + CPoint point; + if (::GetCursorPos(&point) && (point.x != m_pLastMousePoint.x || point.y != m_pLastMousePoint.y)) { + m_pLastMousePoint = point; + // handle tooltip updating, when mouse is moved from one item to another + m_nDropIndex = GetTabUnderMouse(point); + if (m_nDropIndex != m_nLastCatTT) { + m_nLastCatTT = m_nDropIndex; + if (m_nDropIndex >= 0) + UpdateTabToolTips(m_nDropIndex); + } + } + } + break; + case WM_KEYDOWN: // Don't handle Ctrl+Tab in this window. It will be handled by main window. if (pMsg->wParam == VK_TAB && GetKeyState(VK_CONTROL) < 0) return FALSE; - } else if (pMsg->message == WM_LBUTTONDBLCLK) { + break; + case WM_LBUTTONDBLCLK: if (pMsg->hwnd == m_dlTab.m_hWnd) { OnDblClickDltab(); return TRUE; } - } else if (pMsg->message == WM_MOUSEMOVE) { - CPoint point; - if (::GetCursorPos(&point) && (point.x != m_pLastMousePoint.x || point.y != m_pLastMousePoint.y)) { - m_pLastMousePoint = point; - // handle tooltip updating, when mouse is moved from one item to another - m_nDropIndex = GetTabUnderMouse(point); - if (m_nDropIndex != m_nLastCatTT) { - m_nLastCatTT = m_nDropIndex; - if (m_nDropIndex >= 0) - UpdateTabToolTips(m_nDropIndex); - } - } - } else if (!thePrefs.GetStraightWindowStyles() && pMsg->message == WM_MBUTTONUP) { - if (downloadlistactive) - downloadlistctrl.ShowSelectedFileDetails(); - else if (m_dwShowListIDC != IDC_DOWNLOADLIST + IDC_UPLOADLIST) { - switch (m_dwShowListIDC) { - case IDC_UPLOADLIST: - uploadlistctrl.ShowSelectedUserDetails(); - break; - case IDC_QUEUELIST: - queuelistctrl.ShowSelectedUserDetails(); - break; - case IDC_CLIENTLIST: - clientlistctrl.ShowSelectedUserDetails(); - break; - case IDC_DOWNLOADCLIENTS: - downloadclientsctrl.ShowSelectedUserDetails(); - break; - default: - ASSERT(0); - } - } else { - switch (m_uWnd2) { - case wnd2OnQueue: - queuelistctrl.ShowSelectedUserDetails(); - break; - case wnd2Uploading: - uploadlistctrl.ShowSelectedUserDetails(); - break; - case wnd2Clients: - clientlistctrl.ShowSelectedUserDetails(); - break; - case wnd2Downloading: - downloadclientsctrl.ShowSelectedUserDetails(); - break; - default: - ASSERT(0); + break; + case WM_MBUTTONUP: + if (!thePrefs.GetStraightWindowStyles()) { + if (downloadlistactive) + downloadlistctrl.ShowSelectedFileDetails(); + else if (m_dwShowListIDC != IDC_DOWNLOADLIST + IDC_UPLOADLIST) { + switch (m_dwShowListIDC) { + case IDC_UPLOADLIST: + uploadlistctrl.ShowSelectedUserDetails(); + break; + case IDC_QUEUELIST: + queuelistctrl.ShowSelectedUserDetails(); + break; + case IDC_CLIENTLIST: + clientlistctrl.ShowSelectedUserDetails(); + break; + case IDC_DOWNLOADCLIENTS: + downloadclientsctrl.ShowSelectedUserDetails(); + break; + default: + ASSERT(0); + } + } else { + switch (m_uWnd2) { + case wnd2OnQueue: + queuelistctrl.ShowSelectedUserDetails(); + break; + case wnd2Uploading: + uploadlistctrl.ShowSelectedUserDetails(); + break; + case wnd2Clients: + clientlistctrl.ShowSelectedUserDetails(); + break; + case wnd2Downloading: + downloadclientsctrl.ShowSelectedUserDetails(); + break; + default: + ASSERT(0); + } } } return TRUE; @@ -393,18 +370,15 @@ BOOL CTransferWnd::PreTranslateMessage(MSG *pMsg) int CTransferWnd::GetItemUnderMouse(CListCtrl &ctrl) { - CPoint pt; + POINT pt; if (::GetCursorPos(&pt)) { ctrl.ScreenToClient(&pt); LVHITTESTINFO hit, subhit; - hit.pt = pt; - subhit.pt = pt; + hit.pt = subhit.pt = pt; ctrl.SubItemHitTest(&subhit); int sel = ctrl.HitTest(&hit); - if (sel != LB_ERR && (hit.flags & LVHT_ONITEM)) { - if (subhit.iSubItem == 0) - return sel; - } + if (sel != LB_ERR && (hit.flags & LVHT_ONITEM) && subhit.iSubItem == 0) + return sel; } return LB_ERR; } @@ -412,82 +386,78 @@ int CTransferWnd::GetItemUnderMouse(CListCtrl &ctrl) void CTransferWnd::UpdateFilesCount(int iCount) { if (m_dwShowListIDC == IDC_DOWNLOADLIST || m_dwShowListIDC == IDC_DOWNLOADLIST + IDC_UPLOADLIST) { - CString strBuffer; - strBuffer.Format(_T("%s (%i)"), (LPCTSTR)GetResString(IDS_TW_DOWNLOADS), iCount); - m_btnWnd1->SetWindowText(strBuffer); + CString strBuffer(GetResString(IDS_TW_DOWNLOADS)); + strBuffer.AppendFormat(_T(" (%i)"), iCount); + m_btnWnd1.SetWindowText(strBuffer); } } void CTransferWnd::UpdateListCount(EWnd2 listindex, int iCount /*=-1*/) { + CString strBuffer; switch (m_dwShowListIDC) { case IDC_DOWNLOADLIST + IDC_UPLOADLIST: - { - if (m_uWnd2 != listindex) - return; - CString strBuffer; - switch (m_uWnd2) { - case wnd2Uploading: - { - uint32 itemCount = (iCount == -1) ? uploadlistctrl.GetItemCount() : iCount; - uint32 activeCount = (uint32)theApp.uploadqueue->GetActiveUploadsCount(); - if (activeCount >= itemCount) - strBuffer.Format(_T(" (%u)"), itemCount); - else - strBuffer.Format(_T(" (%u/%u)"), activeCount, itemCount); - m_btnWnd2->SetWindowText(GetResString(IDS_UPLOADING) + strBuffer); - } - break; - case wnd2OnQueue: - strBuffer.Format(_T(" (%i)"), iCount == -1 ? queuelistctrl.GetItemCount() : iCount); - m_btnWnd2->SetWindowText(GetResString(IDS_ONQUEUE) + strBuffer); - break; - case wnd2Clients: - strBuffer.Format(_T(" (%i)"), iCount == -1 ? clientlistctrl.GetItemCount() : iCount); - m_btnWnd2->SetWindowText(GetResString(IDS_CLIENTLIST) + strBuffer); - break; - case wnd2Downloading: - strBuffer.Format(_T(" (%i)"), iCount == -1 ? downloadclientsctrl.GetItemCount() : iCount); - m_btnWnd2->SetWindowText(GetResString(IDS_DOWNLOADING) + strBuffer); - break; - default: - ASSERT(0); + if (m_uWnd2 != listindex) + return; + switch (m_uWnd2) { + case wnd2Uploading: + { + uint32 itemCount = (iCount < 0) ? uploadlistctrl.GetItemCount() : iCount; + uint32 activeCount = (uint32)theApp.uploadqueue->GetActiveUploadsCount(); + const CString &sUploading(GetResString(IDS_UPLOADING)); + if (activeCount >= itemCount) + strBuffer.Format(_T("%s (%u)"), (LPCTSTR)sUploading, itemCount); + else + strBuffer.Format(_T("%s (%u/%u)"), (LPCTSTR)sUploading, activeCount, itemCount); + m_btnWnd2.SetWindowText(strBuffer); } + break; + case wnd2OnQueue: + strBuffer.Format(_T("%s (%i)"), (LPCTSTR)GetResString(IDS_ONQUEUE), (iCount < 0) ? queuelistctrl.GetItemCount() : iCount); + m_btnWnd2.SetWindowText(strBuffer); + break; + case wnd2Clients: + strBuffer.Format(_T("%s (%i)"), (LPCTSTR)GetResString(IDS_CLIENTLIST), (iCount < 0) ? clientlistctrl.GetItemCount() : iCount); + m_btnWnd2.SetWindowText(strBuffer); + break; + case wnd2Downloading: + strBuffer.Format(_T("%s (%i)"), (LPCTSTR)GetResString(IDS_DOWNLOADING), (iCount < 0) ? downloadclientsctrl.GetItemCount() : iCount); + m_btnWnd2.SetWindowText(strBuffer); + break; + default: + ASSERT(0); } break; case IDC_DOWNLOADLIST: break; case IDC_UPLOADLIST: if (listindex == wnd2Uploading) { - CString strBuffer; - uint32 itemCount = iCount == -1 ? uploadlistctrl.GetItemCount() : iCount; + uint32 itemCount = (iCount < 0) ? uploadlistctrl.GetItemCount() : iCount; uint32 activeCount = (uint32)theApp.uploadqueue->GetActiveUploadsCount(); + const CString &sUploading(GetResString(IDS_UPLOADING)); if (activeCount >= itemCount) - strBuffer.Format(_T(" (%u)"), itemCount); + strBuffer.Format(_T("%s (%u)"), (LPCTSTR)sUploading, itemCount); else - strBuffer.Format(_T(" (%u/%u)"), activeCount, itemCount); - m_btnWnd1->SetWindowText(GetResString(IDS_UPLOADING) + strBuffer); + strBuffer.Format(_T("%s (%u/%u)"), (LPCTSTR)sUploading, activeCount, itemCount); + m_btnWnd1.SetWindowText(strBuffer); } break; case IDC_QUEUELIST: if (listindex == wnd2OnQueue) { - CString strBuffer; - strBuffer.Format(_T(" (%i)"), iCount == -1 ? queuelistctrl.GetItemCount() : iCount); - m_btnWnd1->SetWindowText(GetResString(IDS_ONQUEUE) + strBuffer); + strBuffer.Format(_T("%s (%i)"), (LPCTSTR)GetResString(IDS_ONQUEUE), (iCount < 0) ? queuelistctrl.GetItemCount() : iCount); + m_btnWnd1.SetWindowText(strBuffer); } break; case IDC_CLIENTLIST: if (listindex == wnd2Clients) { - CString strBuffer; - strBuffer.Format(_T(" (%i)"), iCount == -1 ? clientlistctrl.GetItemCount() : iCount); - m_btnWnd1->SetWindowText(GetResString(IDS_CLIENTLIST) + strBuffer); + strBuffer.Format(_T("%s (%i)"), (LPCTSTR)GetResString(IDS_CLIENTLIST), (iCount < 0) ? clientlistctrl.GetItemCount() : iCount); + m_btnWnd1.SetWindowText(strBuffer); } break; case IDC_DOWNLOADCLIENTS: if (listindex == wnd2Downloading) { - CString strBuffer; - strBuffer.Format(_T(" (%i)"), iCount == -1 ? downloadclientsctrl.GetItemCount() : iCount); - m_btnWnd1->SetWindowText(GetResString(IDS_DOWNLOADING) + strBuffer); + strBuffer.Format(_T("%s (%i)"), (LPCTSTR)GetResString(IDS_DOWNLOADING), (iCount < 0) ? downloadclientsctrl.GetItemCount() : iCount); + m_btnWnd1.SetWindowText(strBuffer); } default: /*ASSERT(0)*/; @@ -496,50 +466,53 @@ void CTransferWnd::UpdateListCount(EWnd2 listindex, int iCount /*=-1*/) void CTransferWnd::SwitchUploadList() { - if (m_uWnd2 == wnd2Uploading) { + switch (m_uWnd2) { + case wnd2Uploading: SetWnd2(wnd2Downloading); - queuelistctrl.Hide(); clientlistctrl.Hide(); + queuelistctrl.Hide(); uploadlistctrl.Hide(); downloadclientsctrl.Show(); GetDlgItem(IDC_QUEUE_REFRESH_BUTTON)->ShowWindow(SW_HIDE); - m_btnWnd2->CheckButton(MP_VIEW2_DOWNLOADING); + m_btnWnd2.CheckButton(MP_VIEW2_DOWNLOADING); SetWnd2Icon(w2iDownloading); - } else if (m_uWnd2 == wnd2Downloading) { - SetWnd2(wnd2OnQueue); - if (thePrefs.IsQueueListDisabled()) { - SwitchUploadList(); - return; + break; + case wnd2Downloading: + if (!thePrefs.IsQueueListDisabled()) { + SetWnd2(wnd2OnQueue); + clientlistctrl.Hide(); + downloadclientsctrl.Hide(); + uploadlistctrl.Hide(); + queuelistctrl.Show(); + GetDlgItem(IDC_QUEUE_REFRESH_BUTTON)->ShowWindow(SW_SHOW); + m_btnWnd2.CheckButton(MP_VIEW2_ONQUEUE); + SetWnd2Icon(w2iOnQueue); + break; } - uploadlistctrl.Hide(); - clientlistctrl.Hide(); - downloadclientsctrl.Hide(); - GetDlgItem(IDC_QUEUE_REFRESH_BUTTON)->ShowWindow(SW_SHOW); - queuelistctrl.Show(); - m_btnWnd2->CheckButton(MP_VIEW2_ONQUEUE); - SetWnd2Icon(w2iOnQueue); - } else if (m_uWnd2 == wnd2OnQueue) { - SetWnd2(wnd2Clients); - if (thePrefs.IsKnownClientListDisabled()) { - SwitchUploadList(); - return; + case wnd2OnQueue: + if (!thePrefs.IsKnownClientListDisabled()) { + SetWnd2(wnd2Clients); + downloadclientsctrl.Hide(); + queuelistctrl.Hide(); + uploadlistctrl.Hide(); + clientlistctrl.Show(); + GetDlgItem(IDC_QUEUE_REFRESH_BUTTON)->ShowWindow(SW_HIDE); + m_btnWnd2.CheckButton(MP_VIEW2_CLIENTS); + SetWnd2Icon(w2iClientsKnown); + break; } - uploadlistctrl.Hide(); - queuelistctrl.Hide(); - downloadclientsctrl.Hide(); - clientlistctrl.Show(); - GetDlgItem(IDC_QUEUE_REFRESH_BUTTON)->ShowWindow(SW_HIDE); - m_btnWnd2->CheckButton(MP_VIEW2_CLIENTS); - SetWnd2Icon(w2iClientsKnown); - } else { + case wnd2Clients: SetWnd2(wnd2Uploading); - queuelistctrl.Hide(); clientlistctrl.Hide(); downloadclientsctrl.Hide(); + queuelistctrl.Hide(); uploadlistctrl.Show(); GetDlgItem(IDC_QUEUE_REFRESH_BUTTON)->ShowWindow(SW_HIDE); - m_btnWnd2->CheckButton(MP_VIEW2_UPLOADING); + m_btnWnd2.CheckButton(MP_VIEW2_UPLOADING); SetWnd2Icon(w2iUploading); + break; + default: + ASSERT(0); } UpdateListCount(m_uWnd2); } @@ -553,7 +526,7 @@ void CTransferWnd::ShowWnd2(EWnd2 uWnd2) uploadlistctrl.Hide(); downloadclientsctrl.Show(); GetDlgItem(IDC_QUEUE_REFRESH_BUTTON)->ShowWindow(SW_HIDE); - m_btnWnd2->CheckButton(MP_VIEW2_DOWNLOADING); + m_btnWnd2.CheckButton(MP_VIEW2_DOWNLOADING); SetWnd2Icon(w2iDownloading); } else if (uWnd2 == wnd2OnQueue && !thePrefs.IsQueueListDisabled()) { SetWnd2(uWnd2); @@ -562,7 +535,7 @@ void CTransferWnd::ShowWnd2(EWnd2 uWnd2) downloadclientsctrl.Hide(); queuelistctrl.Show(); GetDlgItem(IDC_QUEUE_REFRESH_BUTTON)->ShowWindow(SW_SHOW); - m_btnWnd2->CheckButton(MP_VIEW2_ONQUEUE); + m_btnWnd2.CheckButton(MP_VIEW2_ONQUEUE); SetWnd2Icon(w2iOnQueue); } else if (uWnd2 == wnd2Clients && !thePrefs.IsKnownClientListDisabled()) { SetWnd2(uWnd2); @@ -571,7 +544,7 @@ void CTransferWnd::ShowWnd2(EWnd2 uWnd2) downloadclientsctrl.Hide(); clientlistctrl.Show(); GetDlgItem(IDC_QUEUE_REFRESH_BUTTON)->ShowWindow(SW_HIDE); - m_btnWnd2->CheckButton(MP_VIEW2_CLIENTS); + m_btnWnd2.CheckButton(MP_VIEW2_CLIENTS); SetWnd2Icon(w2iClientsKnown); } else { SetWnd2(wnd2Uploading); @@ -580,7 +553,7 @@ void CTransferWnd::ShowWnd2(EWnd2 uWnd2) downloadclientsctrl.Hide(); uploadlistctrl.Show(); GetDlgItem(IDC_QUEUE_REFRESH_BUTTON)->ShowWindow(SW_HIDE); - m_btnWnd2->CheckButton(MP_VIEW2_UPLOADING); + m_btnWnd2.CheckButton(MP_VIEW2_UPLOADING); SetWnd2Icon(w2iUploading); } UpdateListCount(m_uWnd2); @@ -596,16 +569,16 @@ void CTransferWnd::OnSysColorChange() { CResizableFormView::OnSysColorChange(); SetAllIcons(); - m_btnWnd1->Invalidate(); - m_btnWnd2->Invalidate(); + m_btnWnd1.Invalidate(); + m_btnWnd2.Invalidate(); } void CTransferWnd::OnSettingChange(UINT uFlags, LPCTSTR lpszSection) { CResizableFormView::OnSettingChange(uFlags, lpszSection); - // It does not work to reset the width of 1st button here. - //m_btnWnd1->SetBtnWidth(IDC_DOWNLOAD_ICO, WND1_BUTTON_WIDTH); - //m_btnWnd2->SetBtnWidth(IDC_UPLOAD_ICO, WND2_BUTTON_WIDTH); + // It does not work out to reset the width of 1st button here. + //m_btnWnd1.SetBtnWidth(IDC_DOWNLOAD_ICO, WND1_BUTTON_WIDTH); + //m_btnWnd2.SetBtnWidth(IDC_UPLOAD_ICO, WND2_BUTTON_WIDTH); } void CTransferWnd::SetAllIcons() @@ -624,7 +597,7 @@ void CTransferWnd::SetWnd1Icons() iml.Add(CTempIconLoader(_T("Download"))); iml.Add(CTempIconLoader(_T("ClientsOnQueue"))); iml.Add(CTempIconLoader(_T("ClientsKnown"))); - CImageList *pImlOld = m_btnWnd1->SetImageList(&iml); + CImageList *pImlOld = m_btnWnd1.SetImageList(&iml); iml.Detach(); if (pImlOld) pImlOld->DeleteImageList(); @@ -638,7 +611,7 @@ void CTransferWnd::SetWnd2Icons() iml.Add(CTempIconLoader(_T("Download"))); iml.Add(CTempIconLoader(_T("ClientsOnQueue"))); iml.Add(CTempIconLoader(_T("ClientsKnown"))); - CImageList *pImlOld = m_btnWnd2->SetImageList(&iml); + CImageList *pImlOld = m_btnWnd2.SetImageList(&iml); iml.Detach(); if (pImlOld) pImlOld->DeleteImageList(); @@ -665,18 +638,18 @@ void CTransferWnd::Localize() void CTransferWnd::LocalizeToolbars() { - m_btnWnd1->SetWindowText(GetResString(IDS_TW_DOWNLOADS)); - m_btnWnd1->SetBtnText(MP_VIEW1_SPLIT_WINDOW, GetResString(IDS_SPLIT_WINDOW)); - m_btnWnd1->SetBtnText(MP_VIEW1_DOWNLOADS, GetResString(IDS_TW_DOWNLOADS)); - m_btnWnd1->SetBtnText(MP_VIEW1_UPLOADING, GetResString(IDS_UPLOADING)); - m_btnWnd1->SetBtnText(MP_VIEW1_DOWNLOADING, GetResString(IDS_DOWNLOADING)); - m_btnWnd1->SetBtnText(MP_VIEW1_ONQUEUE, GetResString(IDS_ONQUEUE)); - m_btnWnd1->SetBtnText(MP_VIEW1_CLIENTS, GetResString(IDS_CLIENTLIST)); - m_btnWnd2->SetWindowText(GetResString(IDS_UPLOADING)); - m_btnWnd2->SetBtnText(MP_VIEW2_UPLOADING, GetResString(IDS_UPLOADING)); - m_btnWnd2->SetBtnText(MP_VIEW2_DOWNLOADING, GetResString(IDS_DOWNLOADING)); - m_btnWnd2->SetBtnText(MP_VIEW2_ONQUEUE, GetResString(IDS_ONQUEUE)); - m_btnWnd2->SetBtnText(MP_VIEW2_CLIENTS, GetResString(IDS_CLIENTLIST)); + m_btnWnd1.SetWindowText(GetResString(IDS_TW_DOWNLOADS)); + m_btnWnd1.SetBtnText(MP_VIEW1_SPLIT_WINDOW, GetResString(IDS_SPLIT_WINDOW)); + m_btnWnd1.SetBtnText(MP_VIEW1_DOWNLOADS, GetResString(IDS_TW_DOWNLOADS)); + m_btnWnd1.SetBtnText(MP_VIEW1_UPLOADING, GetResString(IDS_UPLOADING)); + m_btnWnd1.SetBtnText(MP_VIEW1_DOWNLOADING, GetResString(IDS_DOWNLOADING)); + m_btnWnd1.SetBtnText(MP_VIEW1_ONQUEUE, GetResString(IDS_ONQUEUE)); + m_btnWnd1.SetBtnText(MP_VIEW1_CLIENTS, GetResString(IDS_CLIENTLIST)); + m_btnWnd2.SetWindowText(GetResString(IDS_UPLOADING)); + m_btnWnd2.SetBtnText(MP_VIEW2_UPLOADING, GetResString(IDS_UPLOADING)); + m_btnWnd2.SetBtnText(MP_VIEW2_DOWNLOADING, GetResString(IDS_DOWNLOADING)); + m_btnWnd2.SetBtnText(MP_VIEW2_ONQUEUE, GetResString(IDS_ONQUEUE)); + m_btnWnd2.SetBtnText(MP_VIEW2_CLIENTS, GetResString(IDS_CLIENTLIST)); } void CTransferWnd::OnBnClickedQueueRefreshButton() @@ -812,7 +785,7 @@ void CTransferWnd::OnLvnBeginDragDownloadList(LPNMHDR pNMHDR, LRESULT *pResult) if (reinterpret_cast(downloadlistctrl.GetItemData(iSel))->type != FILE_TYPE) return; - LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); m_nDragIndex = pNMLV->iItem; ASSERT(m_pDragImage == NULL); @@ -863,7 +836,7 @@ void CTransferWnd::OnMouseMove(UINT nFlags, CPoint point) void CTransferWnd::OnLButtonUp(UINT /*nFlags*/, CPoint /*point*/) { if (m_bIsDragging) { - ReleaseCapture(); + ::ReleaseCapture(); m_bIsDragging = false; m_pDragImage->DragLeave(GetDesktopWindow()); m_pDragImage->EndDrag(); @@ -871,7 +844,7 @@ void CTransferWnd::OnLButtonUp(UINT /*nFlags*/, CPoint /*point*/) m_pDragImage = NULL; if (m_nDropIndex >= 0 && (downloadlistctrl.curTab == 0 || (UINT)m_nDropIndex != downloadlistctrl.curTab)) { - // for multiselections + // for multi-selections CTypedPtrList selectedList; for (POSITION pos = downloadlistctrl.GetFirstSelectedItemPosition(); pos != NULL;) { int index = downloadlistctrl.GetNextSelectedItem(pos); @@ -933,7 +906,7 @@ BOOL CTransferWnd::OnCommand(WPARAM wParam, LPARAM) case MP_CAT_EDIT: { m_nLastCatTT = -1; - const CString &oldincpath = thePrefs.GetCatPath(m_rightclickindex); + const CString &oldincpath(thePrefs.GetCatPath(m_rightclickindex)); CCatDialog dialog(m_rightclickindex); if (dialog.DoModal() == IDOK) { EditCatTabLabel(m_rightclickindex, thePrefs.GetCategory(m_rightclickindex)->strTitle); @@ -941,7 +914,7 @@ BOOL CTransferWnd::OnCommand(WPARAM wParam, LPARAM) theApp.emuledlg->searchwnd->UpdateCatTabs(); downloadlistctrl.UpdateCurrentCategoryView(); thePrefs.SaveCats(); - if (CompareDirectory(oldincpath, thePrefs.GetCatPath(m_rightclickindex))) + if (!EqualPaths(oldincpath, thePrefs.GetCatPath(m_rightclickindex))) theApp.emuledlg->sharedfileswnd->Reload(); } } @@ -1077,13 +1050,12 @@ void CTransferWnd::EditCatTabLabel(int index, CString newlabel) m_dlTab.GetItem(index, &tabitem); tabitem.mask = TCIF_TEXT; - newlabel.Replace(_T("&"), _T("&&")); - - if (!index) + if (index) + DupAmpersand(newlabel); + else newlabel.Empty(); if (!index || thePrefs.GetCatFilter(index) > 0) { - if (index) newlabel += _T(" ("); @@ -1107,15 +1079,13 @@ void CTransferWnd::EditCatTabLabel(int index, CString newlabel) if (pos == NULL) break; } - CString title(newlabel); int count; downloadlistctrl.GetCompleteDownloads(index, count); - newlabel.Format(_T("%s %i/%i"), (LPCTSTR)title, dwl, count); + newlabel.AppendFormat(_T(" %i/%i"), dwl, count); } - tabitem.pszText = newlabel.LockBuffer(); + tabitem.pszText = const_cast((LPCTSTR)newlabel); m_dlTab.SetItem(index, &tabitem); - newlabel.UnlockBuffer(); VerifyCatTabSize(); } @@ -1123,18 +1093,17 @@ void CTransferWnd::EditCatTabLabel(int index, CString newlabel) int CTransferWnd::AddCategory(const CString &newtitle, const CString &newincoming, const CString &newcomment, const CString &newautocat, bool addTab) { Category_Struct *newcat = new Category_Struct; - newcat->strTitle = newtitle; - newcat->prio = PR_NORMAL; newcat->strIncomingPath = newincoming; + newcat->strTitle = newtitle; newcat->strComment = newcomment; - newcat->regexp.Empty(); - newcat->ac_regexpeval = false; newcat->autocat = newautocat; - newcat->downloadInAlphabeticalOrder = FALSE; + newcat->color = CLR_NONE; + newcat->prio = PR_NORMAL; newcat->filter = 0; newcat->filterNeg = false; newcat->care4all = false; - newcat->color = CLR_NONE; + newcat->ac_regexpeval = false; + newcat->downloadInAlphabeticalOrder = false; int index = (int)thePrefs.AddCat(newcat); if (addTab) @@ -1147,7 +1116,7 @@ int CTransferWnd::AddCategory(const CString &newtitle, const CString &newincomin int CTransferWnd::AddCategoryInteractive() { m_nLastCatTT = -1; - int newindex = AddCategory(_T("?"), thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR), _T(""), _T(""), false); + int newindex = AddCategory(CString(_T("?")), thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR), CString(), CString(), false); CCatDialog dialog(newindex); if (dialog.DoModal() == IDOK) { theApp.emuledlg->searchwnd->UpdateCatTabs(); @@ -1156,7 +1125,7 @@ int CTransferWnd::AddCategoryInteractive() EditCatTabLabel(newindex); thePrefs.SaveCats(); VerifyCatTabSize(); - if (CompareDirectory(thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR), thePrefs.GetCatPath(newindex))) + if (!EqualPaths(thePrefs.GetMuleDirectory(EMULE_INCOMINGDIR), thePrefs.GetCatPath(newindex))) theApp.emuledlg->sharedfileswnd->Reload(); return newindex; } @@ -1198,25 +1167,25 @@ void CTransferWnd::OnLvnKeydownDownloadList(LPNMHDR pNMHDR, LRESULT *pResult) void CTransferWnd::UpdateTabToolTips(int tab) { if (tab == -1) { - for (int i = m_tooltipCats->GetToolCount(); --i >= 0;) - m_tooltipCats->DelTool(&m_dlTab, i); + for (int i = m_tooltipCats.GetToolCount(); --i >= 0;) + m_tooltipCats.DelTool(&m_dlTab, i); for (int i = 0; i < m_dlTab.GetItemCount(); ++i) { RECT r; m_dlTab.GetItemRect(i, &r); - VERIFY(m_tooltipCats->AddTool(&m_dlTab, GetTabStatistic(i), &r, i + 1)); + VERIFY(m_tooltipCats.AddTool(&m_dlTab, GetTabStatistic(i), &r, i + 1)); } } else { RECT r; m_dlTab.GetItemRect(tab, &r); - m_tooltipCats->DelTool(&m_dlTab, tab + 1); - VERIFY(m_tooltipCats->AddTool(&m_dlTab, GetTabStatistic(tab), &r, tab + 1)); + m_tooltipCats.DelTool(&m_dlTab, tab + 1); + VERIFY(m_tooltipCats.AddTool(&m_dlTab, GetTabStatistic(tab), &r, tab + 1)); } } void CTransferWnd::SetToolTipsDelay(DWORD dwDelay) { - m_tooltipCats->SetDelayTime(TTDT_INITIAL, dwDelay); + m_tooltipCats.SetDelayTime(TTDT_INITIAL, dwDelay); CToolTipCtrl *tooltip = downloadlistctrl.GetToolTips(); if (tooltip) @@ -1244,8 +1213,7 @@ CString CTransferWnd::GetTabStatistic(int tab) speed += pFile->GetDatarate() / 1024.0F; size += (uint64)pFile->GetFileSize(); trsize += (uint64)pFile->GetCompletedSize(); - if (!pFile->IsAllocating()) - disksize += (uint64)pFile->GetRealFileSize(); + disksize += (uint64)pFile->GetRealFileSize(); err += static_cast(pFile->GetStatus() == PS_ERROR); paus += static_cast(pFile->GetStatus() == PS_PAUSED); } @@ -1269,9 +1237,9 @@ CString CTransferWnd::GetTabStatistic(int tab) uid = IDS_PRIONORMAL; } - CString title; - title.Format(_T("%s: %i\n\n%s: %i\n%s: %i\n%s: %i\n%s: %i\n\n%s: %s\n\n%s: %.1f %s\n%s: %s/%s\n%s%s") TOOLTIP_AUTOFORMAT_SUFFIX - , (LPCTSTR)GetResString(IDS_FILES), count + compl + CString title(GetResString(IDS_FILES)); + title.AppendFormat(_T(": %i\n\n%s: %i\n%s: %i\n%s: %i\n%s: %i\n\n%s: %s\n\n%s: %.1f %s\n%s: %s/%s\n%s%s") TOOLTIP_AUTOFORMAT_SUFFIX + , count + compl , (LPCTSTR)GetResString(IDS_DOWNLOADING), dwl , (LPCTSTR)GetResString(IDS_PAUSED), paus , (LPCTSTR)GetResString(IDS_ERRORLIKE), err @@ -1315,7 +1283,7 @@ void CTransferWnd::OnTabMovement(LPNMHDR, LRESULT*) // move category of completed files downloadlistctrl.MoveCompletedfilesCat(from, to); - // of the tabcontrol itself + // of the tab control itself m_dlTab.ReorderTab(from, to); UpdateCatTabTitles(); @@ -1349,7 +1317,7 @@ void CTransferWnd::VerifyCatTabSize() int left = wp.rcNormalPosition.right - size - 4; RECT rcBtn1; - m_btnWnd1->GetWindowRect(&rcBtn1); + m_btnWnd1.GetWindowRect(&rcBtn1); ScreenToClient(&rcBtn1); wp.rcNormalPosition.left = (left >= rcBtn1.right + 10) ? left : rcBtn1.right + 10; @@ -1360,12 +1328,14 @@ void CTransferWnd::VerifyCatTabSize() CString CTransferWnd::GetCatTitle(int catid) { - static const int idscat[19] = { + static const int idscat[19] = + { IDS_ALL, IDS_ALLOTHERS, IDS_STATUS_NOTCOMPLETED, IDS_DL_TRANSFCOMPL, IDS_WAITING , IDS_DOWNLOADING, IDS_ERRORLIKE, IDS_PAUSED, IDS_SEENCOMPL, 0 , IDS_VIDEO, IDS_AUDIO, IDS_SEARCH_ARC, IDS_SEARCH_CDIMG, IDS_SEARCH_DOC - , IDS_SEARCH_PICS, IDS_SEARCH_PRG, 0, IDS_REGEXPRESSION}; - + , IDS_SEARCH_PICS, IDS_SEARCH_PRG, 0, IDS_REGEXPRESSION + }; + catid = (catid >= 0 && catid < 17) ? idscat[catid] : 0; return catid ? GetResString((UINT)catid) : CString(_T('?')); } @@ -1399,20 +1369,20 @@ void CTransferWnd::OnBnClickedChangeView() void CTransferWnd::SetWnd1Icon(EWnd1Icon iIcon) { - TBBUTTONINFO tbbi = {}; + TBBUTTONINFO tbbi; tbbi.cbSize = (UINT)sizeof tbbi; tbbi.dwMask = TBIF_IMAGE; tbbi.iImage = iIcon; - m_btnWnd1->SetButtonInfo((int)::GetWindowLongPtr(*m_btnWnd1, GWLP_ID), &tbbi); + m_btnWnd1.SetButtonInfo((int)::GetWindowLongPtr(m_btnWnd1, GWLP_ID), &tbbi); } void CTransferWnd::SetWnd2Icon(EWnd2Icon iIcon) { - TBBUTTONINFO tbbi = {}; + TBBUTTONINFO tbbi; tbbi.cbSize = (UINT)sizeof tbbi; tbbi.dwMask = TBIF_IMAGE; tbbi.iImage = iIcon; - m_btnWnd2->SetButtonInfo((int)::GetWindowLongPtr(*m_btnWnd2, GWLP_ID), &tbbi); + m_btnWnd2.SetButtonInfo((int)::GetWindowLongPtr(m_btnWnd2, GWLP_ID), &tbbi); } void CTransferWnd::ShowList(uint32 dwListIDC) @@ -1428,7 +1398,7 @@ void CTransferWnd::ShowList(uint32 dwListIDC) rcDown.bottom = rcWnd.bottom - WND1_BUTTON_HEIGHT; m_wndSplitter.DestroyWindow(); RemoveAnchor(dwListIDC); - m_btnWnd2->ShowWindow(SW_HIDE); + m_btnWnd2.ShowWindow(SW_HIDE); m_dwShowListIDC = dwListIDC; uploadlistctrl.ShowWindow((m_dwShowListIDC == IDC_UPLOADLIST) ? SW_SHOW : SW_HIDE); @@ -1444,35 +1414,35 @@ void CTransferWnd::ShowList(uint32 dwListIDC) case IDC_DOWNLOADLIST: downloadlistctrl.MoveWindow(&rcDown); downloadlistctrl.ShowFilesCount(); - m_btnWnd1->CheckButton(MP_VIEW1_DOWNLOADS); + m_btnWnd1.CheckButton(MP_VIEW1_DOWNLOADS); SetWnd1Icon(w1iDownloadFiles); thePrefs.SetTransferWnd1(1); break; case IDC_UPLOADLIST: uploadlistctrl.MoveWindow(&rcDown); UpdateListCount(wnd2Uploading); - m_btnWnd1->CheckButton(MP_VIEW1_UPLOADING); + m_btnWnd1.CheckButton(MP_VIEW1_UPLOADING); SetWnd1Icon(w1iUploading); thePrefs.SetTransferWnd1(2); break; case IDC_QUEUELIST: queuelistctrl.MoveWindow(&rcDown); UpdateListCount(wnd2OnQueue); - m_btnWnd1->CheckButton(MP_VIEW1_ONQUEUE); + m_btnWnd1.CheckButton(MP_VIEW1_ONQUEUE); SetWnd1Icon(w1iOnQueue); thePrefs.SetTransferWnd1(3); break; case IDC_DOWNLOADCLIENTS: downloadclientsctrl.MoveWindow(&rcDown); UpdateListCount(wnd2Downloading); - m_btnWnd1->CheckButton(MP_VIEW1_DOWNLOADING); + m_btnWnd1.CheckButton(MP_VIEW1_DOWNLOADING); SetWnd1Icon(w1iDownloading); thePrefs.SetTransferWnd1(4); break; case IDC_CLIENTLIST: clientlistctrl.MoveWindow(&rcDown); UpdateListCount(wnd2Clients); - m_btnWnd1->CheckButton(MP_VIEW1_CLIENTS); + m_btnWnd1.CheckButton(MP_VIEW1_CLIENTS); SetWnd1Icon(w1iClientsKnown); thePrefs.SetTransferWnd1(5); break; @@ -1489,7 +1459,7 @@ void CTransferWnd::ShowSplitWindow(bool bReDraw) if (!bReDraw && m_dwShowListIDC == IDC_DOWNLOADLIST + IDC_UPLOADLIST) return; - m_btnWnd1->CheckButton(MP_VIEW1_SPLIT_WINDOW); + m_btnWnd1.CheckButton(MP_VIEW1_SPLIT_WINDOW); SetWnd1Icon(w1iDownloadFiles); CRect rcWnd; @@ -1521,7 +1491,7 @@ void CTransferWnd::ShowSplitWindow(bool bReDraw) downloadclientsctrl.MoveWindow(&rcDown); CRect rcBtn2; - m_btnWnd2->GetWindowRect(rcBtn2); + m_btnWnd2.GetWindowRect(rcBtn2); ScreenToClient(rcBtn2); RECT rcSpl; rcSpl.left = rcBtn2.right + 8; @@ -1533,22 +1503,22 @@ void CTransferWnd::ShowSplitWindow(bool bReDraw) m_wndSplitter.SetDrawBorder(true); } else m_wndSplitter.MoveWindow(&rcSpl, TRUE); - m_btnWnd2->MoveWindow(rcBtn2.left, rcSpl.top - (WND_SPLITTER_YOFF - 1) - 5, rcBtn2.Width(), WND2_BUTTON_HEIGHT); + m_btnWnd2.MoveWindow(rcBtn2.left, rcSpl.top - (WND_SPLITTER_YOFF - 1) - 5, rcBtn2.Width(), WND2_BUTTON_HEIGHT); DoResize(0); m_dwShowListIDC = IDC_DOWNLOADLIST + IDC_UPLOADLIST; downloadlistctrl.ShowFilesCount(); - m_btnWnd2->ShowWindow(SW_SHOW); + m_btnWnd2.ShowWindow(SW_SHOW); theApp.emuledlg->transferwnd->ShowToolbar(true); - RemoveAnchor(*m_btnWnd2); + RemoveAnchor(m_btnWnd2); RemoveAnchor(IDC_DOWNLOADLIST); RemoveAnchor(IDC_UPLOADLIST); RemoveAnchor(IDC_QUEUELIST); RemoveAnchor(IDC_DOWNLOADCLIENTS); RemoveAnchor(IDC_CLIENTLIST); - AddAnchor(*m_btnWnd2, ANCHOR(0, thePrefs.GetSplitterbarPosition())); + AddAnchor(m_btnWnd2, ANCHOR(0, thePrefs.GetSplitterbarPosition())); AddAnchor(IDC_DOWNLOADLIST, TOP_LEFT, ANCHOR(100, thePrefs.GetSplitterbarPosition())); AddAnchor(IDC_UPLOADLIST, ANCHOR(0, thePrefs.GetSplitterbarPosition()), BOTTOM_RIGHT); AddAnchor(IDC_QUEUELIST, ANCHOR(0, thePrefs.GetSplitterbarPosition()), BOTTOM_RIGHT); @@ -1601,7 +1571,7 @@ void CTransferWnd::OnWnd1BtnDropDown(LPNMHDR, LRESULT*) menu.AppendMenu(MF_STRING | (m_dwShowListIDC == IDC_CLIENTLIST ? MF_GRAYED : 0), MP_VIEW1_CLIENTS, GetResString(IDS_CLIENTLIST), _T("ClientsKnown")); RECT rcBtn1; - m_btnWnd1->GetWindowRect(&rcBtn1); + m_btnWnd1.GetWindowRect(&rcBtn1); menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, rcBtn1.left, rcBtn1.bottom, this); } @@ -1619,42 +1589,42 @@ void CTransferWnd::OnWnd2BtnDropDown(LPNMHDR, LRESULT*) menu.AppendMenu(MF_STRING | (m_uWnd2 == wnd2Clients ? MF_GRAYED : 0), MP_VIEW2_CLIENTS, GetResString(IDS_CLIENTLIST), _T("ClientsKnown")); RECT rcBtn2; - m_btnWnd2->GetWindowRect(&rcBtn2); + m_btnWnd2.GetWindowRect(&rcBtn2); menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, rcBtn2.left, rcBtn2.bottom, this); } void CTransferWnd::ResetTransToolbar(bool bShowToolbar, bool bResetLists) { - if (m_btnWnd1->m_hWnd) - RemoveAnchor(*m_btnWnd1); - if (m_btnWnd2->m_hWnd) - RemoveAnchor(*m_btnWnd2); + if (m_btnWnd1.m_hWnd) + RemoveAnchor(m_btnWnd1); + if (m_btnWnd2.m_hWnd) + RemoveAnchor(m_btnWnd2); CRect rcBtn1; - m_btnWnd1->GetWindowRect(rcBtn1); + m_btnWnd1.GetWindowRect(rcBtn1); ScreenToClient(rcBtn1); //rcBtn1.left = WND1_BUTTON_XOFF; rcBtn1.top = WND1_BUTTON_YOFF; rcBtn1.right = rcBtn1.left + WND1_BUTTON_WIDTH + (bShowToolbar ? WND1_NUM_BUTTONS * DFLT_TOOLBAR_BTN_WIDTH : 0); rcBtn1.bottom = rcBtn1.top + WND1_BUTTON_HEIGHT; - m_btnWnd1->Init(!bShowToolbar); - m_btnWnd1->MoveWindow(&rcBtn1); + m_btnWnd1.Init(!bShowToolbar); + m_btnWnd1.MoveWindow(&rcBtn1); SetWnd1Icons(); RECT rcBtn2; - m_btnWnd2->GetWindowRect(&rcBtn2); + m_btnWnd2.GetWindowRect(&rcBtn2); ScreenToClient(&rcBtn2); //rcBtn2.left = WND2_BUTTON_XOFF; rcBtn2.right = rcBtn2.left + WND2_BUTTON_WIDTH + (bShowToolbar ? WND2_NUM_BUTTONS * DFLT_TOOLBAR_BTN_WIDTH : 0); rcBtn2.bottom = rcBtn2.top + WND2_BUTTON_HEIGHT; - m_btnWnd2->Init(!bShowToolbar); - m_btnWnd2->MoveWindow(&rcBtn2); + m_btnWnd2.Init(!bShowToolbar); + m_btnWnd2.MoveWindow(&rcBtn2); SetWnd2Icons(); if (bShowToolbar) { // Vista: Remove the TBSTYLE_TRANSPARENT to avoid flickering (can be done only after the toolbar was initially created with TBSTYLE_TRANSPARENT !?) - m_btnWnd1->ModifyStyle((theApp.m_ullComCtrlVer >= MAKEDLLVERULL(6, 16, 0, 0)) ? TBSTYLE_TRANSPARENT : 0, TBSTYLE_TOOLTIPS); - m_btnWnd1->SetExtendedStyle(m_btnWnd1->GetExtendedStyle() | TBSTYLE_EX_MIXEDBUTTONS); + m_btnWnd1.ModifyStyle((theApp.m_ullComCtrlVer >= MAKEDLLVERULL(6, 16, 0, 0)) ? TBSTYLE_TRANSPARENT : 0, TBSTYLE_TOOLTIPS); + m_btnWnd1.SetExtendedStyle(m_btnWnd1.GetExtendedStyle() | TBSTYLE_EX_MIXEDBUTTONS); TBBUTTON atb1[1 + WND1_NUM_BUTTONS] = {}; atb1[0].iBitmap = w1iDownloadFiles; @@ -1698,13 +1668,13 @@ void CTransferWnd::ResetTransToolbar(bool bShowToolbar, bool bResetLists) atb1[6].fsState = thePrefs.IsKnownClientListDisabled() ? 0 : TBSTATE_ENABLED; atb1[6].fsStyle = BTNS_BUTTON | BTNS_CHECKGROUP | BTNS_AUTOSIZE; atb1[6].iString = -1; - m_btnWnd1->AddButtons(_countof(atb1), atb1); + m_btnWnd1.AddButtons(_countof(atb1), atb1); TBBUTTONINFO tbbi = {}; tbbi.cbSize = (UINT)sizeof tbbi; tbbi.dwMask = TBIF_SIZE | TBIF_BYINDEX; tbbi.cx = WND1_BUTTON_WIDTH; - m_btnWnd1->SetButtonInfo(0, &tbbi); + m_btnWnd1.SetButtonInfo(0, &tbbi); // 'GetMaxSize' does not work properly under: // - Win98SE with COMCTL32 v5.80 @@ -1716,17 +1686,17 @@ void CTransferWnd::ResetTransToolbar(bool bShowToolbar, bool bResetLists) // Although it would be better to call it to adapt for system metrics basically. if (theApp.m_ullComCtrlVer > MAKEDLLVERULL(5, 81, 0, 0)) { CSize size; - m_btnWnd1->GetMaxSize(&size); - m_btnWnd1->GetWindowRect(&rcBtn1); + m_btnWnd1.GetMaxSize(&size); + m_btnWnd1.GetWindowRect(&rcBtn1); ScreenToClient(&rcBtn1); // the with of the toolbar should already match the needed size (see comment above) ASSERT(size.cx == rcBtn1.Width()); - m_btnWnd1->MoveWindow(rcBtn1.left, rcBtn1.top, size.cx, rcBtn1.Height()); + m_btnWnd1.MoveWindow(rcBtn1.left, rcBtn1.top, size.cx, rcBtn1.Height()); } /*---*/ // Vista: Remove the TBSTYLE_TRANSPARENT to avoid flickering (can be done only after the toolbar was initially created with TBSTYLE_TRANSPARENT !?) - m_btnWnd2->ModifyStyle((theApp.m_ullComCtrlVer >= MAKEDLLVERULL(6, 16, 0, 0)) ? TBSTYLE_TRANSPARENT : 0, TBSTYLE_TOOLTIPS); - m_btnWnd2->SetExtendedStyle(m_btnWnd2->GetExtendedStyle() | TBSTYLE_EX_MIXEDBUTTONS); + m_btnWnd2.ModifyStyle((theApp.m_ullComCtrlVer >= MAKEDLLVERULL(6, 16, 0, 0)) ? TBSTYLE_TRANSPARENT : 0, TBSTYLE_TOOLTIPS); + m_btnWnd2.SetExtendedStyle(m_btnWnd2.GetExtendedStyle() | TBSTYLE_EX_MIXEDBUTTONS); TBBUTTON atb2[1 + WND2_NUM_BUTTONS] = {}; atb2[0].iBitmap = w2iUploading; @@ -1758,13 +1728,13 @@ void CTransferWnd::ResetTransToolbar(bool bShowToolbar, bool bResetLists) atb2[4].fsState = thePrefs.IsKnownClientListDisabled() ? 0 : TBSTATE_ENABLED; atb2[4].fsStyle = BTNS_BUTTON | BTNS_CHECKGROUP | BTNS_AUTOSIZE; atb2[4].iString = -1; - m_btnWnd2->AddButtons(_countof(atb2), atb2); + m_btnWnd2.AddButtons(_countof(atb2), atb2); memset(&tbbi, 0, sizeof tbbi); tbbi.cbSize = (UINT)sizeof tbbi; tbbi.dwMask = TBIF_SIZE | TBIF_BYINDEX; tbbi.cx = WND2_BUTTON_WIDTH; - m_btnWnd2->SetButtonInfo(0, &tbbi); + m_btnWnd2.SetButtonInfo(0, &tbbi); // 'GetMaxSize' does not work properly under: // - Win98SE with COMCTL32 v5.80 @@ -1776,28 +1746,28 @@ void CTransferWnd::ResetTransToolbar(bool bShowToolbar, bool bResetLists) // Although it would be better to call it to adapt for system metrics basically. if (theApp.m_ullComCtrlVer > MAKEDLLVERULL(5, 81, 0, 0)) { SIZE size; - m_btnWnd2->GetMaxSize(&size); + m_btnWnd2.GetMaxSize(&size); CRect rc; - m_btnWnd2->GetWindowRect(&rc); + m_btnWnd2.GetWindowRect(&rc); ScreenToClient(&rc); // the with of the toolbar should already match the needed size (see comment above) ASSERT(size.cx == rc.Width()); - m_btnWnd2->MoveWindow(rc.left, rc.top, size.cx, rc.Height()); + m_btnWnd2.MoveWindow(rc.left, rc.top, size.cx, rc.Height()); } } else { // Vista: Remove the TBSTYLE_TRANSPARENT to avoid flickering (can be done only after the toolbar was initially created with TBSTYLE_TRANSPARENT !?) - m_btnWnd1->ModifyStyle(TBSTYLE_TOOLTIPS | ((theApp.m_ullComCtrlVer >= MAKEDLLVERULL(6, 16, 0, 0)) ? TBSTYLE_TRANSPARENT : 0), 0); - m_btnWnd1->SetExtendedStyle(m_btnWnd1->GetExtendedStyle() & ~TBSTYLE_EX_MIXEDBUTTONS); - m_btnWnd1->RecalcLayout(true); + m_btnWnd1.ModifyStyle(TBSTYLE_TOOLTIPS | ((theApp.m_ullComCtrlVer >= MAKEDLLVERULL(6, 16, 0, 0)) ? TBSTYLE_TRANSPARENT : 0), 0); + m_btnWnd1.SetExtendedStyle(m_btnWnd1.GetExtendedStyle() & ~TBSTYLE_EX_MIXEDBUTTONS); + m_btnWnd1.RecalcLayout(true); // Vista: Remove the TBSTYLE_TRANSPARENT to avoid flickering (can be done only after the toolbar was initially created with TBSTYLE_TRANSPARENT !?) - m_btnWnd2->ModifyStyle(TBSTYLE_TOOLTIPS | ((theApp.m_ullComCtrlVer >= MAKEDLLVERULL(6, 16, 0, 0)) ? TBSTYLE_TRANSPARENT : 0), 0); - m_btnWnd2->SetExtendedStyle(m_btnWnd2->GetExtendedStyle() & ~TBSTYLE_EX_MIXEDBUTTONS); - m_btnWnd2->RecalcLayout(true); + m_btnWnd2.ModifyStyle(TBSTYLE_TOOLTIPS | ((theApp.m_ullComCtrlVer >= MAKEDLLVERULL(6, 16, 0, 0)) ? TBSTYLE_TRANSPARENT : 0), 0); + m_btnWnd2.SetExtendedStyle(m_btnWnd2.GetExtendedStyle() & ~TBSTYLE_EX_MIXEDBUTTONS); + m_btnWnd2.RecalcLayout(true); } - AddAnchor(*m_btnWnd1, TOP_LEFT); - AddAnchor(*m_btnWnd2, ANCHOR(0, thePrefs.GetSplitterbarPosition())); + AddAnchor(m_btnWnd1, TOP_LEFT); + AddAnchor(m_btnWnd2, ANCHOR(0, thePrefs.GetSplitterbarPosition())); if (bResetLists) { LocalizeToolbars(); @@ -1841,7 +1811,7 @@ void CTransferWnd::OnPaint() ScreenToClient(&rcDown); RECT rcBtn2; - m_btnWnd2->GetWindowRect(&rcBtn2); + m_btnWnd2.GetWindowRect(&rcBtn2); ScreenToClient(&rcBtn2); // splitter paint update @@ -1856,10 +1826,10 @@ void CTransferWnd::OnPaint() } // Workaround to solve a glitch with WM_SETTINGCHANGE message - if (m_btnWnd1->m_hWnd && m_btnWnd1->GetBtnWidth(IDC_DOWNLOAD_ICO) != WND1_BUTTON_WIDTH) - m_btnWnd1->SetBtnWidth(IDC_DOWNLOAD_ICO, WND1_BUTTON_WIDTH); - if (m_btnWnd2->m_hWnd && m_btnWnd2->GetBtnWidth(IDC_UPLOAD_ICO) != WND2_BUTTON_WIDTH) - m_btnWnd2->SetBtnWidth(IDC_UPLOAD_ICO, WND2_BUTTON_WIDTH); + if (m_btnWnd1.m_hWnd && m_btnWnd1.GetBtnWidth(IDC_DOWNLOAD_ICO) != WND1_BUTTON_WIDTH) + m_btnWnd1.SetBtnWidth(IDC_DOWNLOAD_ICO, WND1_BUTTON_WIDTH); + if (m_btnWnd2.m_hWnd && m_btnWnd2.GetBtnWidth(IDC_UPLOAD_ICO) != WND2_BUTTON_WIDTH) + m_btnWnd2.SetBtnWidth(IDC_UPLOAD_ICO, WND2_BUTTON_WIDTH); } void CTransferWnd::OnSysCommand(UINT nID, LPARAM lParam) diff --git a/srchybrid/TransferWnd.h b/srchybrid/TransferWnd.h index cf4f7fb6..d5cc1436 100644 --- a/srchybrid/TransferWnd.h +++ b/srchybrid/TransferWnd.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2005 Merkur ( devs@emule-project.net / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( devs@emule-project.net / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -23,9 +23,7 @@ #include "QueueListCtrl.h" #include "ClientListCtrl.h" #include "DownloadClientsCtrl.h" - -class CDropDownButton; -class CToolTipCtrlX; +#include "DropDownButton.h" class CTransferWnd : public CResizableFormView { @@ -54,6 +52,7 @@ class CTransferWnd : public CResizableFormView w2iClientsKnown }; +public: enum EWnd2 { wnd2Downloading = 0, @@ -61,10 +60,6 @@ class CTransferWnd : public CResizableFormView wnd2OnQueue = 2, wnd2Clients = 3 }; - //Client icons for all windows in EWnd2 enumeration - CImageList m_ImageList; - void SetImageList(); -public: explicit CTransferWnd(CWnd *pParent = NULL); // standard constructor virtual ~CTransferWnd(); CTransferWnd(const CTransferWnd&) = delete; @@ -90,22 +85,22 @@ class CTransferWnd : public CResizableFormView CDownloadClientsCtrl downloadclientsctrl; protected: + POINT m_pLastMousePoint; CSplitterControl m_wndSplitter; - EWnd2 m_uWnd2; - bool downloadlistactive; - CDropDownButton *m_btnWnd1; - CDropDownButton *m_btnWnd2; + CDropDownButton m_btnWnd2; + CDropDownButton m_btnWnd1; + CToolTipCtrlX m_tooltipCats; TabControl m_dlTab; + EWnd2 m_uWnd2; + CImageList *m_pDragImage; + uint32 m_dwShowListIDC; int m_rightclickindex; int m_nDragIndex; int m_nDropIndex; int m_nLastCatTT; int m_isetcatmenu; bool m_bIsDragging; - CImageList *m_pDragImage; - POINT m_pLastMousePoint; - uint32 m_dwShowListIDC; - CToolTipCtrlX *m_tooltipCats; + bool downloadlistactive; bool m_bLayoutInited; void ShowWnd2(EWnd2 uWnd2); diff --git a/srchybrid/TrayDialog.cpp b/srchybrid/TrayDialog.cpp index d8d4ecb3..0d73a891 100644 --- a/srchybrid/TrayDialog.cpp +++ b/srchybrid/TrayDialog.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -84,11 +84,11 @@ void CTrayDialog::OnDestroy() CTrayDialogBase::OnDestroy(); // shouldn't that be done before passing the message to DefWinProc? - if (m_nidIconData.hWnd && m_nidIconData.uID > 0 && TrayIsVisible()) + if (m_nidIconData.hWnd && m_nidIconData.uID > 0 && TrayIconVisible()) VERIFY(Shell_NotifyIcon(NIM_DELETE, &m_nidIconData)); } -bool CTrayDialog::TrayIsVisible() +bool CTrayDialog::TrayIconVisible() { return m_bTrayIconVisible; } @@ -142,6 +142,13 @@ bool CTrayDialog::TrayHide() return bSuccess; } +void CTrayDialog::TrayReset() +{ + Shell_NotifyIcon(NIM_DELETE, &m_nidIconData); //fix for DPI change as it keeps the icon + if (m_bTrayIconVisible) + TrayShow(); +} + BOOL CTrayDialog::TrayUpdate() { BOOL bSuccess = FALSE; @@ -186,17 +193,13 @@ LRESULT CTrayDialog::OnTrayNotify(WPARAM wParam, LPARAM lParam) if (wParam != 1u) //check ID return 0; - CPoint pt; + POINT pt; switch (lParam) { case WM_MOUSEMOVE: - ::GetCursorPos(&pt); - ClientToScreen(&pt); - OnTrayMouseMove(pt); + OnTrayMouseMove(); break; case WM_LBUTTONDOWN: - ::GetCursorPos(&pt); - ClientToScreen(&pt); - OnTrayLButtonDown(pt); + OnTrayLButtonDown(); break; case WM_LBUTTONUP: // Handle the WM_LBUTTONUP only if we know that there was also an according @@ -214,22 +217,17 @@ LRESULT CTrayDialog::OnTrayNotify(WPARAM wParam, LPARAM lParam) break; case WM_LBUTTONDBLCLK: KillSingleClickTimer(); - ::GetCursorPos(&pt); - ClientToScreen(&pt); - OnTrayLButtonDblClk(pt); + OnTrayLButtonDblClk(); break; case WM_RBUTTONUP: case WM_CONTEXTMENU: KillSingleClickTimer(); ::GetCursorPos(&pt); - //ClientToScreen(&pt); OnTrayRButtonUp(pt); break; case WM_RBUTTONDBLCLK: KillSingleClickTimer(); - ::GetCursorPos(&pt); - ClientToScreen(&pt); - OnTrayRButtonDblClk(pt); + OnTrayRButtonDblClk(); } return 1; } @@ -249,7 +247,7 @@ void CTrayDialog::OnTimer(UINT_PTR nIDEvent) TRACE("%s: nIDEvent=%u\n", __FUNCTION__, nIDEvent); // Kill that timer before calling 'OnTrayLButtonUp' which may create the MiniMule window asynchronously! KillSingleClickTimer(); - OnTrayLButtonUp(CPoint()); + OnTrayLButtonUp(); } else CDialogMinTrayBtn::OnTimer(nIDEvent); } @@ -287,33 +285,43 @@ void CTrayDialog::OnTrayRButtonUp(CPoint) { } -void CTrayDialog::OnTrayLButtonDown(CPoint) +void CTrayDialog::OnTrayLButtonDown() { + /*POINT pt; + ::GetCursorPos(&pt); + ClientToScreen(&pt);*/ m_uLButtonDown = 1; } -void CTrayDialog::OnTrayLButtonUp(CPoint) +void CTrayDialog::OnTrayLButtonUp() { } -void CTrayDialog::OnTrayLButtonDblClk(CPoint) +void CTrayDialog::OnTrayLButtonDblClk() { + /*POINT pt; + ::GetCursorPos(&pt); + ClientToScreen(&pt);*/ m_uLButtonDown = 2; } -void CTrayDialog::OnTrayRButtonDblClk(CPoint) +void CTrayDialog::OnTrayRButtonDblClk() { + /*POINT pt; + ::GetCursorPos(&pt); + ClientToScreen(&pt);*/ } -void CTrayDialog::OnTrayMouseMove(CPoint) +void CTrayDialog::OnTrayMouseMove() { + /*POINT pt; + ::GetCursorPos(&pt); + ClientToScreen(&pt);*/ } LRESULT CTrayDialog::OnTaskBarCreated(WPARAM, LPARAM) { - Shell_NotifyIcon(NIM_DELETE, &m_nidIconData); //fix for DPI change as it keeps icon - if (m_bTrayIconVisible) - TrayShow(); + TrayReset(); return 0; } diff --git a/srchybrid/TrayDialog.h b/srchybrid/TrayDialog.h index 86a4f85d..38bd5812 100644 --- a/srchybrid/TrayDialog.h +++ b/srchybrid/TrayDialog.h @@ -17,23 +17,23 @@ class CTrayDialog : public CDialogMinTrayBtn BOOL TrayUpdate(); bool TrayShow(); bool TrayHide(); + void TrayReset(); void TraySetToolTip(LPCTSTR lpszToolTip); void TraySetIcon(HICON hIcon, bool bDelete = false); void TraySetIcon(UINT nResourceID); void TraySetIcon(LPCTSTR lpszResourceName); - bool TrayIsVisible(); + bool TrayIconVisible(); virtual void TrayMinimizeToTrayChange(); virtual void RestoreWindow(); - virtual void OnTrayLButtonDown(CPoint); - virtual void OnTrayLButtonUp(CPoint); - virtual void OnTrayLButtonDblClk(CPoint); - virtual void OnTrayRButtonUp(CPoint); - virtual void OnTrayRButtonDblClk(CPoint); - virtual void OnTrayMouseMove(CPoint); + virtual void OnTrayLButtonDown(); + virtual void OnTrayLButtonUp(); + virtual void OnTrayLButtonDblClk(); + virtual void OnTrayRButtonUp(CPoint); //parameter used in the overriding method + virtual void OnTrayRButtonDblClk(); + virtual void OnTrayMouseMove(); protected: - bool *m_pbMinimizeToTray; HICON m_hPrevIconDelete; CMenu m_mnuTrayMenu; diff --git a/srchybrid/TrayMenuBtn.cpp b/srchybrid/TrayMenuBtn.cpp index 85446745..18649079 100644 --- a/srchybrid/TrayMenuBtn.cpp +++ b/srchybrid/TrayMenuBtn.cpp @@ -51,9 +51,9 @@ void CTrayMenuBtn::OnMouseMove(UINT nFlags, CPoint point) if (pParent) pParent->SetCapture(); else - ReleaseCapture(); + ::ReleaseCapture(); } else - ReleaseCapture(); + ::ReleaseCapture(); m_bMouseOver = false; } @@ -72,7 +72,7 @@ void CTrayMenuBtn::OnLButtonUp(UINT nFlags, CPoint point) if (pParent) pParent->PostMessage(WM_COMMAND, MAKEWPARAM(m_nBtnID, BN_CLICKED), reinterpret_cast(m_hWnd)); } else { - ReleaseCapture(); + ::ReleaseCapture(); m_bMouseOver = false; Invalidate(); } diff --git a/srchybrid/TreeOptionsCtrl.cpp b/srchybrid/TreeOptionsCtrl.cpp index 6cde9194..7ef6971e 100644 --- a/srchybrid/TreeOptionsCtrl.cpp +++ b/srchybrid/TreeOptionsCtrl.cpp @@ -74,7 +74,7 @@ History: PJN / 21-04-1999 Added full support for enabling / disabling all the it PJN / 24-09-2002 1. Updated documentation which incorrectly stated that the parent of a check box item must be a group item as inserted with InsertGroup. Thanks to Kgl Christoph for spotting this. - 2. Fixed an issue with "IMPLEMENT_DYNAMIC(CDateTimeCtrl..." not being declared propertly. + 2. Fixed an issue with "IMPLEMENT_DYNAMIC(CDateTimeCtrl..." not being declared properly. Some users reported that it worked OK, while others said that my fix was causing link problems. The problem should be sorted out for good now. Thanks to Kgl Christoph for reporting this. @@ -146,7 +146,7 @@ to maintain a single distribution point for the source code. #include "stdafx.h" #include "resource.h" #ifndef _SHLOBJ_H_ -#pragma message("To avoid this message, please put shlobj.h in your pre compiled header (normally stdafx.h)") +#pragma message("To avoid this message, please put shlobj.h in your precompiled header (normally stdafx.h)") #include #endif #include "TreeOptionsCtrl.h" @@ -228,6 +228,7 @@ CTreeOptionsCtrl::~CTreeOptionsCtrl() ASSERT(m_pButton == NULL); ASSERT(m_pDateTime == NULL); ASSERT(m_pIPAddress == NULL); + (void)TREE_OPTIONS_STATIC_ID; //suppress warning C5264 } LRESULT CTreeOptionsCtrl::OnSetFocusToChild(WPARAM, LPARAM) @@ -393,12 +394,12 @@ void CTreeOptionsCtrl::OnLButtonDown(UINT nFlags, CPoint point) if (!hItem) uFlags = 0; - //If the mouse was over the label, icon or to the left or right of the item? + //If the mouse was over the icon, label or to the left or right of the item? BOOL bHit; if (m_bToggleOverIconOnly) - bHit = uFlags == TVHT_ONITEMICON; + bHit = (uFlags == TVHT_ONITEMICON); else - bHit = (uFlags & TVHT_ONITEM) || (uFlags & TVHT_ONITEMINDENT) || (uFlags & TVHT_ONITEMRIGHT); + bHit = (uFlags & (TVHT_ONITEM | TVHT_ONITEMINDENT | TVHT_ONITEMRIGHT)); if (bHit) { if (IsCheckBox(hItem)) { @@ -953,16 +954,16 @@ BOOL CTreeOptionsCtrl::AddComboBox(HTREEITEM hItem, CRuntimeClass *pRuntimeClass CString CTreeOptionsCtrl::GetComboText(HTREEITEM hItem) const { - const CString &sText = GetItemText(hItem); + const CString &sText(GetItemText(hItem)); int nSeparator = sText.Find(m_sSeparator); - if (nSeparator >= 0) - return sText.Right(sText.GetLength() - nSeparator - m_sSeparator.GetLength()); - return CString(); + if (nSeparator < 0) + return CString(); + return sText.Right(sText.GetLength() - nSeparator - m_sSeparator.GetLength()); } void CTreeOptionsCtrl::RemoveChildControlText(HTREEITEM hItem) { - CString sText = GetItemText(hItem); + CString sText(GetItemText(hItem)); int nSeparator = sText.Find(m_sSeparator); if (nSeparator >= 0) sText.Truncate(nSeparator); @@ -971,7 +972,7 @@ void CTreeOptionsCtrl::RemoveChildControlText(HTREEITEM hItem) void CTreeOptionsCtrl::SetComboText(HTREEITEM hItem, const CString &sComboText) { - CString sText = GetItemText(hItem); + CString sText(GetItemText(hItem)); int nSeparator = sText.Find(m_sSeparator); if (nSeparator < 0) sText += m_sSeparator; @@ -1642,8 +1643,8 @@ BOOL CTreeOptionsCtrl::OnNmClick(LPNMHDR, LRESULT *pResult) void CTreeOptionsCtrl::OnKillFocus(CWnd *pNewWnd) { //Clean up any controls currently open if we are losing focus to something else - BOOL bForeignWnd = (m_hControlItem && (pNewWnd != m_pCombo) && (pNewWnd != m_pEdit) && - (pNewWnd != m_pDateTime) && (pNewWnd != m_pIPAddress) && (pNewWnd != m_pButton)); + BOOL bForeignWnd = (m_hControlItem && (pNewWnd != m_pCombo) && (pNewWnd != m_pEdit) + && (pNewWnd != m_pDateTime) && (pNewWnd != m_pIPAddress) && (pNewWnd != m_pButton)); if (bForeignWnd && m_pCombo) bForeignWnd = !m_pCombo->IsRelatedWnd(pNewWnd); if (bForeignWnd && m_pDateTime) @@ -1758,7 +1759,7 @@ void CTreeOptionsCtrl::SetDateTime(HTREEITEM hItem, const SYSTEMTIME &st) CTreeOptionsDateCtrl *pTempDateTime = static_cast(pItemData->m_pRuntimeClass1->CreateObject()); ASSERT(pTempDateTime); ASSERT(pTempDateTime->IsKindOf(RUNTIME_CLASS(CTreeOptionsDateCtrl))); //Your class must be derived from CTreeOptionsDateCtrl - const CString &sDateTime = pTempDateTime->GetDisplayText(st); + const CString &sDateTime(pTempDateTime->GetDisplayText(st)); SetEditText(hItem, sDateTime); delete pTempDateTime; } @@ -2130,9 +2131,9 @@ void CTreeOptionsIPAddressCtrl::OnKillFocus(CWnd *pNewWnd) CString CTreeOptionsIPAddressCtrl::GetDisplayText(DWORD dwAddress) { CString sAddress; - sAddress.Format(_T("%lu.%lu.%lu.%lu"), (dwAddress >> 24) & 0xFF, - (dwAddress >> 16) & 0xFF, (dwAddress >> 8) & 0xFF, - (dwAddress & 0xFF)); + sAddress.Format(_T("%lu.%lu.%lu.%lu") + , (dwAddress >> 24) & 0xFF, (dwAddress >> 16) & 0xFF + , (dwAddress >> 8) & 0xFF, dwAddress & 0xFF); return sAddress; } @@ -2153,22 +2154,8 @@ BOOL CTreeOptionsIPAddressCtrl::IsRelatedWnd(CWnd *pChild) - - - - - - IMPLEMENT_DYNCREATE(CTreeOptionsBooleanCombo, CTreeOptionsCombo) -CTreeOptionsBooleanCombo::CTreeOptionsBooleanCombo() -{ -} - -CTreeOptionsBooleanCombo::~CTreeOptionsBooleanCombo() -{ -} - BEGIN_MESSAGE_MAP(CTreeOptionsBooleanCombo, CTreeOptionsCombo) //{{AFX_MSG_MAP(CTreeOptionsBooleanCombo) ON_WM_CREATE() @@ -2206,10 +2193,6 @@ CTreeOptionsEdit::CTreeOptionsEdit() { } -CTreeOptionsEdit::~CTreeOptionsEdit() -{ -} - BEGIN_MESSAGE_MAP(CTreeOptionsEdit, CEdit) //{{AFX_MSG_MAP(CTreeOptionsEdit) ON_WM_CHAR() @@ -2288,11 +2271,11 @@ void CTreeOptionsEdit::BrowseForFolder(const CString &sInitialFolder) ASSERT(m_pTreeCtrl); //Bring up a standard directory chooser dialog - TCHAR sDisplayName[_MAX_PATH]; + TCHAR sDisplayName[MAX_PATH]; BROWSEINFO bi; bi.hwndOwner = m_pTreeCtrl->GetSafeHwnd(); bi.pidlRoot = NULL; - const CString &sCaption = GetBrowseForFolderCaption(); + const CString &sCaption(GetBrowseForFolderCaption()); bi.lpszTitle = sCaption; bi.pszDisplayName = sDisplayName; bi.ulFlags = BIF_RETURNONLYFSDIRS; @@ -2302,7 +2285,7 @@ void CTreeOptionsEdit::BrowseForFolder(const CString &sInitialFolder) if (pItemIDList) { //Retrieve the path and update on screen - TCHAR sPath[_MAX_PATH]; + TCHAR sPath[MAX_PATH]; if (SHGetPathFromIDList(pItemIDList, sPath)) SetWindowText(sPath); @@ -2324,7 +2307,7 @@ void CTreeOptionsEdit::BrowseForFile(const CString &sInitialFile) CTreeOptionsFileDialog dlg(TRUE, NULL, sInitialFile, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, GetFileExtensionFilter(), m_pTreeCtrl); //Modify the title to the desired value - const CString &sCaption = GetBrowseForFileCaption(); + const CString &sCaption(GetBrowseForFileCaption()); dlg.m_ofn.lpstrTitle = sCaption; //bring up the dialog and if hit OK set the text in this control to the new filename @@ -2398,10 +2381,6 @@ CTreeOptionsBrowseButton::CTreeOptionsBrowseButton() { } -CTreeOptionsBrowseButton::~CTreeOptionsBrowseButton() -{ -} - BEGIN_MESSAGE_MAP(CTreeOptionsBrowseButton, CButton) //{{AFX_MSG_MAP(CTreeOptionsBrowseButton) ON_WM_KILLFOCUS() @@ -2611,21 +2590,16 @@ END_MESSAGE_MAP() void CTreeOptionsFileDialog::OnInitDone() { - CString sText; + CStringA sText; if (!sText.LoadString(IDS_TREEOPTIONS_OK)) ASSERT(0); - LPTSTR pszBuffer = sText.GetBuffer(sText.GetLength()); - //modify the text on the IDOK button to OK - CommDlg_OpenSave_SetControlText(GetParent()->m_hWnd, IDOK, pszBuffer); - - sText.ReleaseBuffer(); + CommDlg_OpenSave_SetControlText(GetParent()->m_hWnd, IDOK, (LPCSTR)sText); } - void DDX_TreeCheck(CDataExchange *pDX, int nIDC, HTREEITEM hItem, BOOL &bCheck) { HWND hWndCtrl = pDX->PrepareCtrl(nIDC); @@ -2777,12 +2751,8 @@ void DDX_TreeBoolean(CDataExchange *pDX, int nIDC, HTREEITEM hItem, BOOL &bValue { //Convert from the boolean to a string if we are transferring to the control CString sText; - if (!pDX->m_bSaveAndValidate) { - if (bValue) - VERIFY(sText.LoadString(IDS_TREEOPTIONS_TRUE)); - else - VERIFY(sText.LoadString(IDS_TREEOPTIONS_FALSE)); - } + if (!pDX->m_bSaveAndValidate) + VERIFY(sText.LoadString(bValue ? IDS_TREEOPTIONS_TRUE : IDS_TREEOPTIONS_FALSE)); //Pass the buck to the combo DDX function DDX_TreeCombo(pDX, nIDC, hItem, sText); @@ -2791,10 +2761,7 @@ void DDX_TreeBoolean(CDataExchange *pDX, int nIDC, HTREEITEM hItem, BOOL &bValue if (pDX->m_bSaveAndValidate) { CString sCompare; VERIFY(sCompare.LoadString(IDS_TREEOPTIONS_TRUE)); - if (sText == sCompare) - bValue = TRUE; - else - bValue = FALSE; + bValue = (sText == sCompare); } } @@ -2805,9 +2772,9 @@ HTREEITEM CTreeOptionsCtrl::CopyItem(HTREEITEM hItem, HTREEITEM htiNewParent, HT tvstruct.item.hItem = hItem; tvstruct.item.mask = TVIF_CHILDREN | TVIF_HANDLE | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; GetItem(&tvstruct.item); - CString sText = GetItemText(hItem); + CString sText(GetItemText(hItem)); tvstruct.item.cchTextMax = sText.GetLength(); - tvstruct.item.pszText = sText.GetBuffer(tvstruct.item.cchTextMax); + tvstruct.item.pszText = const_cast((LPCTSTR)sText); if (tvstruct.item.lParam) tvstruct.item.lParam = (LPARAM)new CTreeOptionsItemData(*(reinterpret_cast(tvstruct.item.lParam))); diff --git a/srchybrid/TreeOptionsCtrl.h b/srchybrid/TreeOptionsCtrl.h index 88c38e9d..5efccbf2 100644 --- a/srchybrid/TreeOptionsCtrl.h +++ b/srchybrid/TreeOptionsCtrl.h @@ -50,7 +50,6 @@ class CTreeOptionsCombo : public CComboBox public: //Constructors / Destructors CTreeOptionsCombo(); - virtual ~CTreeOptionsCombo() = default; protected: //Misc methods @@ -84,11 +83,6 @@ class CTreeOptionsCombo : public CComboBox //Class which represents a combo box which allows a Font Name to be specified class CTreeOptionsFontNameCombo : public CTreeOptionsCombo { -public: - //Constructors / Destructors - CTreeOptionsFontNameCombo() = default; - virtual ~CTreeOptionsFontNameCombo() = default; - protected: //{{AFX_VIRTUAL(CTreeOptionsFontNameCombo) //}}AFX_VIRTUAL @@ -110,11 +104,6 @@ class CTreeOptionsFontNameCombo : public CTreeOptionsCombo //Class which represents a combo box which allows a True / False value to be specified class CTreeOptionsBooleanCombo : public CTreeOptionsCombo { -public: - //Constructors / Destructors - CTreeOptionsBooleanCombo(); - virtual ~CTreeOptionsBooleanCombo(); - protected: //{{AFX_VIRTUAL(CTreeOptionsBooleanCombo) //}}AFX_VIRTUAL @@ -140,7 +129,6 @@ class CTreeOptionsEdit : public CEdit public: //Constructors / Destructors CTreeOptionsEdit(); - virtual ~CTreeOptionsEdit(); protected: //Misc methods @@ -186,7 +174,6 @@ class CTreeOptionsSpinCtrl : public CSpinButtonCtrl public: //Constructors / Destructors CTreeOptionsSpinCtrl(); - virtual ~CTreeOptionsSpinCtrl() = default; protected: //Misc methods @@ -221,7 +208,6 @@ class CTreeOptionsBrowseButton : public CButton public: //Constructors / Destructors CTreeOptionsBrowseButton(); - virtual ~CTreeOptionsBrowseButton(); protected: //Misc methods @@ -262,7 +248,7 @@ class CTreeOptionsBrowseButton : public CButton -//Class which is used for browsing for filenames +//Class which is used for browsing for file names class CTreeOptionsFileDialog : public CFileDialog { public: diff --git a/srchybrid/TreeOptionsCtrlEx.cpp b/srchybrid/TreeOptionsCtrlEx.cpp index 229b9840..b041ec3a 100644 --- a/srchybrid/TreeOptionsCtrlEx.cpp +++ b/srchybrid/TreeOptionsCtrlEx.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -248,13 +248,13 @@ void CTreeOptionsCtrlEx::OnCreateImageList() static const int iBmpHeight = 16; static const int iBitmaps = 13; CBitmap bmpControls; - if (bmpControls.CreateCompatibleBitmap(pDCScreen, iBmpWidth*iBitmaps, iBmpHeight)) { + if (bmpControls.CreateCompatibleBitmap(pDCScreen, iBmpWidth * iBitmaps, iBmpHeight)) { if (m_ilTree.Create(iBmpWidth, iBmpHeight, m_uImageListColorFlags | ILC_MASK, 0, 1)) { CDC dcMem; if (dcMem.CreateCompatibleDC(pDCScreen)) { HTHEME hTheme = (g_xpStyle.IsThemeActive() && g_xpStyle.IsAppThemed()) ? g_xpStyle.OpenThemeData(NULL, L"BUTTON") : NULL; CBitmap *pOldBmp = dcMem.SelectObject(&bmpControls); - dcMem.FillSolidRect(0, 0, iBmpWidth*iBitmaps, iBmpHeight, ::GetSysColor(COLOR_WINDOW)); + dcMem.FillSolidRect(0, 0, iBmpWidth * iBitmaps, iBmpHeight, ::GetSysColor(COLOR_WINDOW)); //int iCtrlWidth = iBmpWidth - 2; //int iCtrlHeight = iBmpHeight - 2; @@ -387,13 +387,11 @@ void CTreeOptionsCtrlEx::HandleChildControlLosingFocus() void CTreeOptionsCtrlEx::SetEditLabel(HTREEITEM hItem, const CString &rstrLabel) { - const CString &rstrSep(GetTextSeparator()); - const CString &strItemText(GetItemText(hItem)); - CString strData; - int nSeparator = strItemText.Find(rstrSep); - if (nSeparator >= 0) - strData = strItemText.Mid(nSeparator + rstrSep.GetLength()); - SetItemText(hItem, rstrLabel + rstrSep + strData); + CString sItemText(GetItemText(hItem)); + int nSeparator = sItemText.Find(GetTextSeparator()); + sItemText.Delete(0, nSeparator < 0 ? INT_MAX : nSeparator); + sItemText.Insert(0, rstrLabel); + SetItemText(hItem, sItemText); } void CTreeOptionsCtrlEx::OnDestroy() diff --git a/srchybrid/TreeOptionsCtrlEx.h b/srchybrid/TreeOptionsCtrlEx.h index 04118151..dd3a5a29 100644 --- a/srchybrid/TreeOptionsCtrlEx.h +++ b/srchybrid/TreeOptionsCtrlEx.h @@ -8,7 +8,7 @@ typedef struct } TREEOPTSCTRLNOTIFY; -// pre defined treeview image list indices +// predefined treeview image list indices #define TREEOPTSCTRLIMG_EDIT 11 @@ -19,7 +19,6 @@ class CTreeOptionsCtrlEx : public CTreeOptionsCtrl { public: explicit CTreeOptionsCtrlEx(UINT uImageListColorFlags = ILC_COLOR); - virtual ~CTreeOptionsCtrlEx() = default; void SetEditLabel(HTREEITEM hItem, const CString &rstrLabel); void UpdateCheckBoxGroup(HTREEITEM hItem); @@ -64,7 +63,6 @@ class CNumTreeOptionsEdit : public CTreeOptionsEdit : m_bSelf(false) { } - virtual ~CNumTreeOptionsEdit() = default; virtual DWORD GetWindowStyle() { return CTreeOptionsEdit::GetWindowStyle() | ES_NUMBER; } @@ -90,7 +88,6 @@ class CTreeOptionsEditEx : public CTreeOptionsEdit : m_bSelf(false) { } - virtual ~CTreeOptionsEditEx() = default; protected: bool m_bSelf; diff --git a/srchybrid/TreePropSheet.cpp b/srchybrid/TreePropSheet.cpp index 6a2ccdeb..631f9b82 100644 --- a/srchybrid/TreePropSheet.cpp +++ b/srchybrid/TreePropSheet.cpp @@ -53,40 +53,33 @@ IMPLEMENT_DYNAMIC(CTreePropSheet, CPropertySheet) const UINT CTreePropSheet::s_unPageTreeId = 0x7EEE; +void CTreePropSheet::init() +{ + m_pwndPageTree = NULL; + m_pFrame = NULL; + m_bTreeViewMode = TRUE; + m_bPageTreeSelChangedActive = FALSE; + m_bPageCaption = FALSE; + m_bTreeImages = FALSE; + m_nPageTreeWidth = 150; +} + CTreePropSheet::CTreePropSheet() : CPropertySheet() - , m_bTreeViewMode(TRUE) - , m_pwndPageTree() - , m_pFrame() - , m_bPageTreeSelChangedActive() - , m_bPageCaption() - , m_bTreeImages() - , m_nPageTreeWidth(150) { + init(); } CTreePropSheet::CTreePropSheet(UINT nIDCaption, CWnd *pParentWnd, UINT iSelectPage) : CPropertySheet(nIDCaption, pParentWnd, iSelectPage) - , m_bTreeViewMode(TRUE) - , m_pwndPageTree() - , m_pFrame() - , m_bPageTreeSelChangedActive() - , m_bPageCaption() - , m_bTreeImages() - , m_nPageTreeWidth(150) { + init(); } CTreePropSheet::CTreePropSheet(LPCTSTR pszCaption, CWnd *pParentWnd, UINT iSelectPage) : CPropertySheet(pszCaption, pParentWnd, iSelectPage) - , m_bTreeViewMode(TRUE) - , m_pwndPageTree() - , m_pFrame() - , m_bPageTreeSelChangedActive() - , m_bPageCaption() - , m_bTreeImages() - , m_nPageTreeWidth(150) { + init(); } ///////////////////////////////////////////////////////////////////// @@ -208,7 +201,7 @@ BOOL CTreePropSheet::DestroyPageIcon(CPropertyPage *pPage) CString CTreePropSheet::GenerateEmptyPageMessage(LPCTSTR lpszEmptyPageMessage, LPCTSTR lpszCaption) { - CString strMsg; + CString strMsg; strMsg.Format(lpszEmptyPageMessage, lpszCaption); return strMsg; } @@ -228,15 +221,12 @@ CPropPageFrame* CTreePropSheet::CreatePageFrame() void CTreePropSheet::MoveChildWindows(int nDx, int nDy) { - CWnd *pWnd = GetWindow(GW_CHILD); - while (pWnd) { - CRect rect; + CRect rect; + for (CWnd *pWnd = GetWindow(GW_CHILD); pWnd; pWnd = pWnd->GetNextWindow()) { pWnd->GetWindowRect(rect); ScreenToClient(rect); rect.OffsetRect(nDx, nDy); pWnd->MoveWindow(rect); - - pWnd = pWnd->GetNextWindow(); } } @@ -288,7 +278,7 @@ void CTreePropSheet::RefillPageTree() // insert tree items for (int nPage = 0; nPage < nPageCount; ++nPage) { // Get title and image of the page - CString strPagePath; + CString strPagePath; TCITEM ti = {}; ti.mask = TCIF_TEXT | TCIF_IMAGE; @@ -324,14 +314,11 @@ HTREEITEM CTreePropSheet::CreatePageTreeItem(LPCTSTR lpszPath, HTREEITEM hParent // Check if an item with the given text does already exist HTREEITEM hItem = NULL; - HTREEITEM hChild = m_pwndPageTree->GetChildItem(hParent); - while (hChild) { + for (HTREEITEM hChild = m_pwndPageTree->GetChildItem(hParent); hChild; hChild = m_pwndPageTree->GetNextItem(hChild, TVGN_NEXT)) if (m_pwndPageTree->GetItemText(hChild) == strTopMostItem) { hItem = hChild; break; } - hChild = m_pwndPageTree->GetNextItem(hChild, TVGN_NEXT); - } // If item with that text does not already exist, create a new one if (!hItem) { @@ -355,7 +342,7 @@ CString CTreePropSheet::SplitPageTreePath(CString &strRest) for (;;) { nSeparatorPos = strRest.Find(_T("::"), nSeparatorPos); if (nSeparatorPos < 0) { - CString strItem(strRest); + CString strItem(strRest); strRest.Empty(); return strItem; } @@ -370,7 +357,7 @@ CString CTreePropSheet::SplitPageTreePath(CString &strRest) } } - CString strItem(strRest.Left(nSeparatorPos)); + CString strItem(strRest, nSeparatorPos); strItem.Replace(_T("\\::"), _T("::")); strItem.Replace(_T("\\\\"), _T("\\")); strRest.Delete(0, nSeparatorPos + 2); @@ -426,7 +413,7 @@ HTREEITEM CTreePropSheet::GetPageTreeItem(int nPage, HTREEITEM hRoot /* = TVI_RO // we are performing a simple linear search here, because we are // expecting only little data HTREEITEM hItem = hRoot; - while (hItem) { + for (; hItem; hItem = m_pwndPageTree->GetNextItem(hItem, TVGN_NEXT)) { if (m_pwndPageTree->GetItemData(hItem) == (DWORD_PTR)nPage) break; if (m_pwndPageTree->ItemHasChildren(hItem)) { @@ -434,7 +421,6 @@ HTREEITEM CTreePropSheet::GetPageTreeItem(int nPage, HTREEITEM hRoot /* = TVI_RO if (hResult) return hResult; } - hItem = m_pwndPageTree->GetNextItem(hItem, TVGN_NEXT); } // we've found nothing, if we arrive here @@ -460,7 +446,7 @@ void CTreePropSheet::UpdateCaption() HTREEITEM hItem = m_pwndPageTree->GetSelectedItem(); if (!hItem) return; - CString strCaption = m_pwndPageTree->GetItemText(hItem); + CString strCaption(m_pwndPageTree->GetItemText(hItem)); // if empty page, then update empty page message if (!bRealPage) @@ -477,14 +463,12 @@ void CTreePropSheet::UpdateCaption() return; } + HICON hIcon = NULL; if (m_bTreeImages) { // get image from tree int nImage; m_pwndPageTree->GetItemImage(hItem, nImage, nImage); - HICON hIcon = m_Images.ExtractIcon(nImage); - m_pFrame->SetCaption(strCaption, hIcon); - if (hIcon) - ::DestroyIcon(hIcon); + hIcon = m_Images.ExtractIcon(nImage); } else if (bRealPage) { // get image from hidden (original) tab provided by the original // implementation @@ -492,18 +476,13 @@ void CTreePropSheet::UpdateCaption() if (pImages) { TCITEM ti = {}; ti.mask = TCIF_IMAGE; - - HICON hIcon = NULL; if (pTabCtrl->GetItem((int)m_pwndPageTree->GetItemData(hItem), &ti)) hIcon = pImages->ExtractIcon(ti.iImage); - - m_pFrame->SetCaption(strCaption, hIcon); - if (hIcon) - ::DestroyIcon(hIcon); - } else - m_pFrame->SetCaption(strCaption); - } else - m_pFrame->SetCaption(strCaption); + } + } + m_pFrame->SetCaption(strCaption, hIcon); + if (hIcon) + ::DestroyIcon(hIcon); } void CTreePropSheet::ActivatePreviousPage() @@ -581,20 +560,14 @@ void CTreePropSheet::ActivateNextPage() if (!hItem) return; - HTREEITEM hNextItem = NULL; - if ((hNextItem = m_pwndPageTree->GetChildItem(hItem)) != NULL) - ; - else if ((hNextItem = m_pwndPageTree->GetNextSiblingItem(hItem)) != NULL) - ; - else if (m_pwndPageTree->GetParentItem(hItem)) { - while (!hNextItem) { + HTREEITEM hNextItem = m_pwndPageTree->GetChildItem(hItem); + if (!hNextItem) + while ((hNextItem = m_pwndPageTree->GetNextSiblingItem(hItem)) == NULL) { hItem = m_pwndPageTree->GetParentItem(hItem); if (!hItem) break; - - hNextItem = m_pwndPageTree->GetNextSiblingItem(hItem); } - } + if (!hNextItem) // no next item -- so cycle to the first item diff --git a/srchybrid/TreePropSheet.h b/srchybrid/TreePropSheet.h index b92bb74e..8b145e67 100644 --- a/srchybrid/TreePropSheet.h +++ b/srchybrid/TreePropSheet.h @@ -66,12 +66,12 @@ class /*AFX_EXT_CLASS*/ CTreePropSheet : public CPropertySheet { DECLARE_DYNAMIC(CTreePropSheet) + void init(); // Construction/Destruction public: CTreePropSheet(); explicit CTreePropSheet(UINT nIDCaption, CWnd *pParentWnd = NULL, UINT iSelectPage = 0); explicit CTreePropSheet(LPCTSTR pszCaption, CWnd *pParentWnd = NULL, UINT iSelectPage = 0); - virtual ~CTreePropSheet() = default; // Operations public: @@ -194,7 +194,7 @@ class /*AFX_EXT_CLASS*/ CTreePropSheet : public CPropertySheet image as an icon from the given image list and assign the icon-handle to the hIcon property of the pages PROPSHEETPAGE structure (m_psp) and modify the structures flags, so that the - image will be recognized. + image will be recognised. You need to call this method for a page, before adding the page to a property sheet. @@ -323,7 +323,7 @@ class /*AFX_EXT_CLASS*/ CTreePropSheet : public CPropertySheet method will return "Appearance" and after the call strRest will be "Toolbars::Customize". */ - CString SplitPageTreePath(CString &strRest); + static CString SplitPageTreePath(CString &strRest); /** Tries to deactivate the current page, and hides it if successful, @@ -415,8 +415,18 @@ class /*AFX_EXT_CLASS*/ CTreePropSheet : public CPropertySheet // Properties private: - /** TRUE if we should use the tree control instead of the tab ctrl. */ - BOOL m_bTreeViewMode; + /** Images to be displayed in the tree control. */ + CImageList m_Images; + + /** Default images. */ + CImageList m_DefaultImages; + + /** + Message to be displayed on empty pages. May contain a "%s" + placeholder which will be replaced by the caption of the empty + page. + */ + CString m_strEmptyPageMessage; /** The tree control */ CTreeCtrl *m_pwndPageTree; @@ -424,6 +434,9 @@ class /*AFX_EXT_CLASS*/ CTreePropSheet : public CPropertySheet /** The frame around the pages */ CPropPageFrame *m_pFrame; + /** TRUE if we should use the tree control instead of the tab ctrl. */ + BOOL m_bTreeViewMode; + /** TRUE, if a tree item selection by OnPageTreeSelChanged() is performed currently. @@ -436,19 +449,6 @@ class /*AFX_EXT_CLASS*/ CTreePropSheet : public CPropertySheet /** TRUE if images should be displayed in the tree. */ BOOL m_bTreeImages; - /** Images to be displayed in the tree control. */ - CImageList m_Images; - - /** Default images. */ - CImageList m_DefaultImages; - - /** - Message to be displayed on empty pages. May contain a "%s" - placeholder which will be replaced by the caption of the empty - page. - */ - CString m_strEmptyPageMessage; - /** The width of the page tree control in pixels. */ int m_nPageTreeWidth; diff --git a/srchybrid/TreePropSheetPgFrameDef.cpp b/srchybrid/TreePropSheetPgFrameDef.cpp index a8fbca3a..2b489eb2 100644 --- a/srchybrid/TreePropSheetPgFrameDef.cpp +++ b/srchybrid/TreePropSheetPgFrameDef.cpp @@ -188,7 +188,7 @@ void CPropPageFrameDefault::DrawCaption(CDC *pDc, CRect rect, LPCTSTR lpszCaptio void CPropPageFrameDefault::FillGradientRectH(CDC *pDc, const CRect &rect, COLORREF clrLeft, COLORREF clrRight) { - // pre calculation + // precalculation int nSteps = rect.Width() + 1; int nRRange = GetRValue(clrRight) - GetRValue(clrLeft); int nGRange = GetGValue(clrRight) - GetGValue(clrLeft); diff --git a/srchybrid/UDPSocket.cpp b/srchybrid/UDPSocket.cpp index 65e1e462..1d9e2370 100644 --- a/srchybrid/UDPSocket.cpp +++ b/srchybrid/UDPSocket.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -93,7 +93,8 @@ struct SServerDNSRequest CTypedPtrList m_aPackets; }; -#define WM_DNSLOOKUPDONE (WM_USER+0x101) // does not need to be placed in "UserMsgs.h" +//Safer to keep all message codes different (see also AsyncSocketEx.h and UserMsgs.h) +#define WM_DNSLOOKUPDONE (WM_USER+0x106) BEGIN_MESSAGE_MAP(CUDPSocketWnd, CWnd) ON_MESSAGE(WM_DNSLOOKUPDONE, OnDNSLookupDone) @@ -156,8 +157,8 @@ void CUDPSocket::OnReceive(int nErrorCode) if (length != SOCKET_ERROR) { int nPayLoadLen = length; CServer *pServer = theApp.serverlist->GetServerByIPUDP(sockAddr.sin_addr.s_addr, ntohs(sockAddr.sin_port), true); - if (pServer != NULL && thePrefs.IsServerCryptLayerUDPEnabled() && - ((pServer->GetServerKeyUDP() != 0 && pServer->SupportsObfuscationUDP()) || (pServer->GetCryptPingReplyPending() && pServer->GetChallenge() != 0))) + if (pServer != NULL && thePrefs.IsServerCryptLayerUDPEnabled() + && ((pServer->GetServerKeyUDP() != 0 && pServer->SupportsObfuscationUDP()) || (pServer->GetCryptPingReplyPending() && pServer->GetChallenge() != 0))) { // TODO uint32 dwKey; @@ -166,8 +167,8 @@ void CUDPSocket::OnReceive(int nErrorCode) else dwKey = pServer->GetServerKeyUDP(); - ASSERT(dwKey != 0); - nPayLoadLen = DecryptReceivedServer(buffer, length, &pBuffer, dwKey, sockAddr.sin_addr.s_addr); + ASSERT(dwKey); + nPayLoadLen = DecryptReceivedServer(buffer, length, &pBuffer, dwKey, sockAddr); if (nPayLoadLen == length) DebugLogWarning(_T("Expected encrypted packet, but received unencrypted from server %s, UDPKey %u, Challenge: %u"), (LPCTSTR)pServer->GetListName(), pServer->GetServerKeyUDP(), pServer->GetChallenge()); else if (thePrefs.GetDebugServerUDPLevel() > 0) @@ -242,7 +243,7 @@ bool CUDPSocket::ProcessPacket(const BYTE *packet, UINT size, UINT opcode, uint3 uint8 protocol = data.ReadUInt8(); --iLeft; if (protocol != OP_EDONKEYPROT) { - data.Seek(-1, SEEK_CUR); + data.Seek(-1, CFile::current); ++iLeft; break; } @@ -250,7 +251,7 @@ bool CUDPSocket::ProcessPacket(const BYTE *packet, UINT size, UINT opcode, uint3 uint8 opcode1 = data.ReadUInt8(); --iLeft; if (opcode1 != OP_GLOBSEARCHRES) { - data.Seek(-2, SEEK_CUR); + data.Seek(-2, CFile::current); iLeft += 2; break; } @@ -270,7 +271,7 @@ bool CUDPSocket::ProcessPacket(const BYTE *packet, UINT size, UINT opcode, uint3 int iLeft; int iDbgPacket = 1; do { - uchar fileid[16]; + uchar fileid[MDX_DIGEST_SIZE]; data.ReadHash16(fileid); if (thePrefs.GetDebugServerUDPLevel() > 0) Debug(_T("ServerUDPMessage from %-21s - OP_GlobFoundSources(%u); %s\n"), (LPCTSTR)ipstr(nIP, nUDPPort - 4), iDbgPacket++, (LPCTSTR)DbgGetFileInfo(fileid)); @@ -280,7 +281,7 @@ bool CUDPSocket::ProcessPacket(const BYTE *packet, UINT size, UINT opcode, uint3 else { // skip sources for that file UINT count = data.ReadUInt8(); - data.Seek(count * (4 + 2ull), SEEK_CUR); + data.Seek(count * (4 + 2ull), CFile::current); } // check if there is another source packet @@ -289,7 +290,7 @@ bool CUDPSocket::ProcessPacket(const BYTE *packet, UINT size, UINT opcode, uint3 uint8 protocol = data.ReadUInt8(); --iLeft; if (protocol != OP_EDONKEYPROT) { - data.Seek(-1, SEEK_CUR); + data.Seek(-1, CFile::current); ++iLeft; break; } @@ -297,7 +298,7 @@ bool CUDPSocket::ProcessPacket(const BYTE *packet, UINT size, UINT opcode, uint3 uint8 opcode2 = data.ReadUInt8(); --iLeft; if (opcode2 != OP_GLOBFOUNDSOURCES) { - data.Seek(-2, SEEK_CUR); + data.Seek(-2, CFile::current); iLeft += 2; break; } @@ -446,10 +447,10 @@ bool CUDPSocket::ProcessPacket(const BYTE *packet, UINT size, UINT opcode, uint3 if (size >= 8 && PeekUInt16(packet) == INV_SERV_DESC_LEN) { if (pServer->GetDescReqChallenge() != 0 && PeekUInt32(packet) == pServer->GetDescReqChallenge()) { pServer->SetDescReqChallenge(0); - srvinfo.Seek(sizeof(uint32), SEEK_SET); // skip challenge + srvinfo.Seek(sizeof(uint32), CFile::begin); // skip challenge for (uint32 uTags = srvinfo.ReadUInt32(); uTags > 0; --uTags) { - CTag tag(&srvinfo, true/*pServer->GetUnicodeSupport()*/); + CTag tag(srvinfo, true/*pServer->GetUnicodeSupport()*/); if (tag.GetNameID() == ST_SERVERNAME && tag.IsStr()) pServer->SetListName(tag.GetStr()); else if (tag.GetNameID() == ST_DESCRIPTION && tag.IsStr()) @@ -457,7 +458,7 @@ bool CUDPSocket::ProcessPacket(const BYTE *packet, UINT size, UINT opcode, uint3 else if (tag.GetNameID() == ST_DYNIP && tag.IsStr()) { // Verify that we really received a DN. if (inet_addr((CStringA)tag.GetStr()) == INADDR_NONE) { - const CString &strOldDynIP = pServer->GetDynIP(); + const CString &strOldDynIP(pServer->GetDynIP()); pServer->SetDynIP(tag.GetStr()); // If a dynIP-server changed its address or, if this is the // first time we get the dynIP-address for a server which we @@ -489,8 +490,8 @@ bool CUDPSocket::ProcessPacket(const BYTE *packet, UINT size, UINT opcode, uint3 ; // ignore this packet } } else { - const CString &strName = srvinfo.ReadString(true/*pServer->GetUnicodeSupport()*/); - const CString &strDesc = srvinfo.ReadString(true/*pServer->GetUnicodeSupport()*/); + const CString &strName(srvinfo.ReadString(true/*pServer->GetUnicodeSupport()*/)); + const CString &strDesc(srvinfo.ReadString(true/*pServer->GetUnicodeSupport()*/)); pServer->SetDescription(strDesc); pServer->SetListName(strName); } @@ -690,7 +691,7 @@ SocketSentBytes CUDPSocket::SendControlData(uint32 maxNumberOfBytesToSend, uint3 sendLocker.Unlock(); - return SocketSentBytes{0, sentBytes, true}; + return SocketSentBytes{ 0, sentBytes, true }; // <-- ZZ:UploadBandWithThrottler (UDP) } @@ -729,13 +730,13 @@ void CUDPSocket::SendBuffer(uint32 nIP, uint16 nPort, BYTE *pPacket, UINT uSize) void CUDPSocket::SendPacket(Packet *packet, CServer *pServer, uint16 nSpecialPort, BYTE *pInRawPacket, uint32 nRawLen) { - // Just for safety. Ensure that there are no stalled DNS queries and/or packets - // hanging endlessly in the queue. - DWORD dwNow = ::GetTickCount(); + // Just for safety. + // Ensure that there are no stalled DNS queries and/or packets hanging endlessly in the queue. + const DWORD curTick = ::GetTickCount(); for (POSITION pos = m_aDNSReqs.GetHeadPosition(); pos != NULL;) { POSITION posPrev = pos; const SServerDNSRequest *pDNSReq = m_aDNSReqs.GetNext(pos); - if (dwNow >= pDNSReq->m_dwCreated + MIN2MS(2)) { + if (curTick >= pDNSReq->m_dwCreated + MIN2MS(2)) { delete pDNSReq; m_aDNSReqs.RemoveAt(posPrev); } @@ -770,7 +771,7 @@ void CUDPSocket::SendPacket(Packet *packet, CServer *pServer, uint16 nSpecialPor } if (!nPort) nPort = pServer->GetPort() + 4; - ASSERT(nPort != 0); + ASSERT(nPort); // Do we need to resolve the DN of this server? CStringA pszHostAddressA(pServer->GetAddress()); @@ -790,8 +791,8 @@ void CUDPSocket::SendPacket(Packet *packet, CServer *pServer, uint16 nSpecialPor // Create a new DNS query for this server SServerDNSRequest *pDNSReq = new SServerDNSRequest(0, new CServer(pServer)); - pDNSReq->m_hDNSTask = WSAAsyncGetHostByName(m_hWndResolveMessage, WM_DNSLOOKUPDONE, - pszHostAddressA, pDNSReq->m_DnsHostBuffer, sizeof pDNSReq->m_DnsHostBuffer); + pDNSReq->m_hDNSTask = WSAAsyncGetHostByName(m_hWndResolveMessage, WM_DNSLOOKUPDONE + , pszHostAddressA, pDNSReq->m_DnsHostBuffer, sizeof pDNSReq->m_DnsHostBuffer); if (pDNSReq->m_hDNSTask == NULL) { if (thePrefs.GetVerbose()) DebugLogWarning(_T("Error: Server UDP socket: Failed to resolve address for '%s' - %s"), (LPCSTR)pServer->GetAddress(), (LPCTSTR)GetErrorMessage(CAsyncSocket::GetLastError(), 1)); diff --git a/srchybrid/UDPSocket.h b/srchybrid/UDPSocket.h index cbb533e6..5654b575 100644 --- a/srchybrid/UDPSocket.h +++ b/srchybrid/UDPSocket.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/UPnPImpl.cpp b/srchybrid/UPnPImpl.cpp index b5631da0..0f3527e6 100644 --- a/srchybrid/UPnPImpl.cpp +++ b/srchybrid/UPnPImpl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/UPnPImpl.h b/srchybrid/UPnPImpl.h index 2dc88eb6..3bfd8dd9 100644 --- a/srchybrid/UPnPImpl.h +++ b/srchybrid/UPnPImpl.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/UPnPImplMiniLib.cpp b/srchybrid/UPnPImplMiniLib.cpp index 9c41ae15..700200ae 100644 --- a/srchybrid/UPnPImplMiniLib.cpp +++ b/srchybrid/UPnPImplMiniLib.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -21,9 +21,9 @@ #include "UPnPImplMiniLib.h" #include "Log.h" #include "Otherfunctions.h" -#include "miniupnpc\miniupnpc.h" -#include "miniupnpc\upnpcommands.h" -#include "miniupnpc\upnperrors.h" +#include "miniupnpc\include\miniupnpc.h" +#include "miniupnpc\include\upnpcommands.h" +#include "miniupnpc\include\upnperrors.h" #include "opcodes.h" @@ -147,7 +147,7 @@ void CUPnPImplMiniLib::DeletePorts(bool bSkipLock) void CUPnPImplMiniLib::StartDiscovery(uint16 nTCPPort, uint16 nUDPPort, uint16 nTCPWebPort) { DebugLog(_T("Using MiniUPnPLib based implementation")); - DebugLog(_T("miniupnpc (c) 2005-2021 Thomas Bernard - http://miniupnp.free.fr/")); + DebugLog(_T("miniupnpc (c) 2005-2023 Thomas Bernard - http://miniupnp.free.fr/")); GetOldPorts(); m_nUDPPort = nUDPPort; m_nTCPPort = nTCPPort; @@ -221,7 +221,7 @@ int CUPnPImplMiniLib::CStartDiscoveryThread::Run() { if (!m_pOwner->m_bCheckAndRefresh) { int error = 0; - UPNPDev *structDeviceList = upnpDiscover(2000, thePrefs.m_pszBindAddrA, NULL, 0, 0, 2, &error); + UPNPDev *structDeviceList = upnpDiscover(2000, thePrefs.GetBindAddrA(), NULL, 0, 0, 2, &error); if (structDeviceList == NULL) { DebugLog(_T("UPNP: No Internet Gateway Devices found, aborting: %d"), error); m_pOwner->m_bUPnPPortsForwarded = TRIS_FALSE; diff --git a/srchybrid/UPnPImplMiniLib.h b/srchybrid/UPnPImplMiniLib.h index 0462d283..2eaef385 100644 --- a/srchybrid/UPnPImplMiniLib.h +++ b/srchybrid/UPnPImplMiniLib.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/UPnPImplWinServ.cpp b/srchybrid/UPnPImplWinServ.cpp index 522f5316..f1efb24f 100644 --- a/srchybrid/UPnPImplWinServ.cpp +++ b/srchybrid/UPnPImplWinServ.cpp @@ -5,7 +5,7 @@ // This file is part of SHAREAZA (www.shareaza.com) // // this file is part of eMule -// Copyright (C)2007 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +// Copyright (C)2007-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -40,15 +40,6 @@ static char THIS_FILE[] = __FILE__; CUPnPImplWinServ::CUPnPImplWinServ() : m_bUPnPDeviceConnected(TRIS_FALSE) - , m_pfnOpenSCManager() - , m_pfnOpenService() - , m_pfnQueryServiceStatusEx() - , m_pfnCloseServiceHandle() - , m_pfnStartService() - , m_pfnControlService() - , m_pfGetBestInterface() - , m_pfGetIpAddrTable() - , m_pfGetIfEntry() , m_pDevices() , m_pServices() , m_pDeviceFinder() @@ -56,8 +47,6 @@ CUPnPImplWinServ::CUPnPImplWinServ() , m_pServiceCallback() , m_sLocalIP() , m_sExternalIP() - , m_hADVAPI32_DLL() - , m_hIPHLPAPI_DLL() , m_nAsyncFindHandle() , m_bCOM() , m_bPortIsFree(true) @@ -77,26 +66,8 @@ void CUPnPImplWinServ::Init() { if (!m_bInited) { DebugLog(_T("Using Windows Service based UPnP Implementation")); - m_hADVAPI32_DLL = LoadLibrary(_T("Advapi32.dll")); - if (m_hADVAPI32_DLL != 0) { - (FARPROC&)m_pfnOpenSCManager = GetProcAddress(m_hADVAPI32_DLL, "OpenSCManagerW"); - (FARPROC&)m_pfnOpenService = GetProcAddress(m_hADVAPI32_DLL, "OpenServiceW"); - (FARPROC&)m_pfnQueryServiceStatusEx = GetProcAddress(m_hADVAPI32_DLL, "QueryServiceStatusEx"); - (FARPROC&)m_pfnCloseServiceHandle = GetProcAddress(m_hADVAPI32_DLL, "CloseServiceHandle"); - (FARPROC&)m_pfnStartService = GetProcAddress(m_hADVAPI32_DLL, "StartServiceW"); - (FARPROC&)m_pfnControlService = GetProcAddress(m_hADVAPI32_DLL, "ControlService"); - } - m_hIPHLPAPI_DLL = LoadLibrary(_T("iphlpapi.dll")); - if (m_hIPHLPAPI_DLL != 0) { - (FARPROC&)m_pfGetBestInterface = GetProcAddress(m_hIPHLPAPI_DLL, "GetBestInterface"); - (FARPROC&)m_pfGetIpAddrTable = GetProcAddress(m_hIPHLPAPI_DLL, "GetIpAddrTable"); - (FARPROC&)m_pfGetIfEntry = GetProcAddress(m_hIPHLPAPI_DLL, "GetIfEntry"); - } - if (m_pfGetBestInterface == NULL || m_pfGetIpAddrTable == NULL || m_pfGetIfEntry == NULL) { - DebugLogError(_T("Failed to load functions from iphlpapi.dll for UPnP")); - ASSERT(0); - } - m_bCOM = SUCCEEDED(CoInitialize(NULL)); + HRESULT hr = CoInitialize(NULL); + m_bCOM = SUCCEEDED(hr); // S_OK or S_FALSE m_pDeviceFinder = CreateFinderInstance(); m_pServiceCallback = new CServiceCallback(*this); m_pDeviceFinderCallback = new CDeviceFinderCallback(*this); @@ -119,14 +90,6 @@ FinderPointer CUPnPImplWinServ::CreateFinderInstance() CUPnPImplWinServ::~CUPnPImplWinServ() { - if (m_hADVAPI32_DLL != 0) { - FreeLibrary(m_hADVAPI32_DLL); - m_hADVAPI32_DLL = 0; - } - if (m_hIPHLPAPI_DLL != 0) { - FreeLibrary(m_hIPHLPAPI_DLL); - m_hIPHLPAPI_DLL = 0; - } m_pDevices.clear(); m_pServices.clear(); @@ -158,48 +121,39 @@ bool CUPnPImplWinServ::IsReady() Init(); bool bResult = false; - if (m_pfnOpenSCManager && m_pfnOpenService - && m_pfnQueryServiceStatusEx && m_pfnCloseServiceHandle && m_pfnStartService) - { - // Open a handle to the Service Control Manager database - SC_HANDLE schSCManager = m_pfnOpenSCManager( - NULL, // local machine - NULL, // ServicesActive database - GENERIC_READ); // for enumeration and status lookup - if (schSCManager == NULL) - return false; + // Open a handle to the Service Control Manager data for enumeration and status lookup + SC_HANDLE schSCManager = OpenSCManager(NULL, NULL, GENERIC_READ); - SC_HANDLE schService = m_pfnOpenService(schSCManager, _T("upnphost"), GENERIC_READ); - if (schService == NULL) { - m_pfnCloseServiceHandle(schSCManager); - return false; - } + if (schSCManager == NULL) + return false; + + SC_HANDLE schService = OpenService(schSCManager, _T("upnphost"), GENERIC_READ); + if (schService == NULL) { + CloseServiceHandle(schSCManager); + return false; + } + + SERVICE_STATUS_PROCESS ssStatus; + DWORD nBytesNeeded; - SERVICE_STATUS_PROCESS ssStatus; - DWORD nBytesNeeded; + if (QueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssStatus, sizeof ssStatus, &nBytesNeeded)) + if (ssStatus.dwCurrentState == SERVICE_RUNNING) + bResult = true; + CloseServiceHandle(schService); - if (m_pfnQueryServiceStatusEx(schService, SC_STATUS_PROCESS_INFO, - (LPBYTE)&ssStatus, sizeof(SERVICE_STATUS_PROCESS), &nBytesNeeded)) - { - if (ssStatus.dwCurrentState == SERVICE_RUNNING) + if (!bResult) { + schService = OpenService(schSCManager, _T("upnphost"), SERVICE_START); + if (schService) { + // Only power users have the right to start service, thus try to start it here + if (StartService(schService, 0, NULL)) { bResult = true; - } - m_pfnCloseServiceHandle(schService); - - if (!bResult) { - schService = m_pfnOpenService(schSCManager, _T("upnphost"), SERVICE_START); - if (schService) { - // Power users have only right to start service, thus try to start it here - if (m_pfnStartService(schService, 0, NULL)) { - bResult = true; - m_bServiceStartedByEmule = true; - } - m_pfnCloseServiceHandle(schService); + m_bServiceStartedByEmule = true; } + CloseServiceHandle(schService); } - m_pfnCloseServiceHandle(schSCManager); } + CloseServiceHandle(schSCManager); if (!bResult) Log(GetResString(IDS_UPNP_NOSERVICE)); @@ -210,30 +164,30 @@ bool CUPnPImplWinServ::IsReady() void CUPnPImplWinServ::StopUPnPService() { ASSERT(m_bServiceStartedByEmule); - if (m_bInited && m_pfnOpenService && m_pfnCloseServiceHandle && m_pfnControlService && m_pfnOpenSCManager) { + if (m_bInited) { m_bServiceStartedByEmule = false; // Open a handle to the Service Control Manager database - SC_HANDLE schSCManager = m_pfnOpenSCManager( - NULL, // local machine - NULL, // ServicesActive database - GENERIC_READ); // for enumeration and status lookup + SC_HANDLE schSCManager = OpenSCManager( + NULL // local machine + , NULL // ServicesActive database + , GENERIC_READ); // for enumeration and status lookup if (schSCManager == NULL) return; - SC_HANDLE schService = m_pfnOpenService(schSCManager, _T("upnphost"), SERVICE_STOP); + SC_HANDLE schService = OpenService(schSCManager, _T("upnphost"), SERVICE_STOP); if (schService) { SERVICE_STATUS structServiceStatus; - if (m_pfnControlService(schService, SERVICE_CONTROL_STOP, &structServiceStatus) != 0) + if (ControlService(schService, SERVICE_CONTROL_STOP, &structServiceStatus) != 0) DebugLog(_T("Shutting down UPnP Service: Succeeded")); else DebugLogWarning(_T("Shutting down UPnP Service: Failed, ErrorCode: %u"), ::GetLastError()); - m_pfnCloseServiceHandle(schService); + CloseServiceHandle(schService); } else DebugLogWarning(_T("Shutting down UPnP Service: Unable to open service")); - m_pfnCloseServiceHandle(schSCManager); + CloseServiceHandle(schSCManager); } } @@ -402,7 +356,7 @@ void CUPnPImplWinServ::RemoveDevice(CComBSTR bsUDN) = std::find_if(m_pDevices.begin(), m_pDevices.end(), FindDevice(bsUDN)); if (device != m_pDevices.end()) { - DebugLog(_T("Device removed: %ls"), (LPCWSTR)bsUDN); + DebugLog(_T("Device removed: %s"), (LPCTSTR)bsUDN); m_pDevices.erase(device); } } @@ -451,7 +405,7 @@ HRESULT CUPnPImplWinServ::GetDeviceServices(DevicePointer pDevice) return E_POINTER; m_pServices.clear(); - _com_ptr_t<_com_IIID > pServices = NULL; + _com_ptr_t<_com_IIID > pServices; HRESULT hr = pDevice->get_Services(&pServices); if (FAILED(hr)) { @@ -459,14 +413,14 @@ HRESULT CUPnPImplWinServ::GetDeviceServices(DevicePointer pDevice) return hr; } - LONG nCount = 0; + LONG nCount; hr = pServices->get_Count(&nCount); if (FAILED(hr)) { UPnPMessage(hr); return hr; } - if (nCount == 0) { + if (nCount <= 0) { // Should we ask a user to disable auto-detection? DebugLog(_T("Found no services for the current UPnP device.")); return hr; @@ -510,7 +464,7 @@ HRESULT CUPnPImplWinServ::SaveServices(EnumUnknownPtr pEU, const LONG nTotalItem break; } - DebugLog(_T("Found UPnP service: %ls"), (LPCWSTR)bsServiceId); + DebugLog(_T("Found UPnP service: %s"), (LPCTSTR)bsServiceId); m_pServices.push_back(pService); bsServiceId.Empty(); } @@ -526,7 +480,7 @@ HRESULT CUPnPImplWinServ::MapPort(const ServicePointer &service) if (FAILED(hr)) return UPnPMessage(hr); - CString strServiceId(bsServiceId); + const CString strServiceId(bsServiceId); if (m_bADSL) // not a very reliable way to detect ADSL, since WANEthLinkC* is optional if (m_bUPnPPortsForwarded == TRIS_TRUE) { // another physical device or the setup was ran again manually @@ -600,6 +554,7 @@ HRESULT CUPnPImplWinServ::MapPort(const ServicePointer &service) } return S_OK; } + void CUPnPImplWinServ::StartPortMapping() { for (std::vector::const_iterator Iter = m_pServices.begin(); Iter != m_pServices.end(); ++Iter) @@ -614,6 +569,7 @@ void CUPnPImplWinServ::StartPortMapping() MapPort(*Iter); } } + void CUPnPImplWinServ::DeletePorts() { if (!m_bInited) @@ -627,71 +583,49 @@ void CUPnPImplWinServ::DeletePorts() // Finds a local IP address routable from UPnP device CString CUPnPImplWinServ::GetLocalRoutableIP(ServicePointer pService) { + CString strLocalIP; CString strExternalIP; HRESULT hr = InvokeAction(pService, _T("GetExternalIPAddress"), NULL, strExternalIP); - int nEqualPos = strExternalIP.Find('='); - strExternalIP = strExternalIP.Mid(nEqualPos + 1).Trim('|'); + strExternalIP.Delete(0, strExternalIP.Find('=') + 1); + strExternalIP.Trim('|'); if (FAILED(hr) || strExternalIP.IsEmpty()) - return CString(); + return strLocalIP; DWORD nInterfaceIndex = 0; DWORD ip = inet_addr((CStringA)strExternalIP); // Get the interface through which the UPnP device has a route - HRESULT hrRes = (HRESULT)-1; - if (m_pfGetBestInterface != NULL) - try { // just to be sure; another call from iphlpapi used earlier in eMule seemed to crash on some systems according to dumps - hrRes = m_pfGetBestInterface(ip, &nInterfaceIndex); - } catch (...) { - ASSERT(0); - } + hr = GetBestInterface(ip, &nInterfaceIndex); - if (ip == INADDR_NONE || hrRes != NO_ERROR) - return CString(); + if (hr != NO_ERROR || ip == INADDR_NONE) + return strLocalIP; MIB_IFROW ifRow = {}; ifRow.dwIndex = nInterfaceIndex; - hrRes = (HRESULT)-1; - if (m_pfGetIfEntry != NULL) - try { // just to be sure; another call from iphlpapi used earlier in eMule seemed to crash on some systems according to dumps - hrRes = m_pfGetIfEntry(&ifRow); - } catch (...) { - ASSERT(0); - } - - if (hrRes != NO_ERROR) - return CString(); + hr = GetIfEntry(&ifRow); + if (hr != NO_ERROR) + return strLocalIP; // Take an IP address table char mib[sizeof(MIB_IPADDRTABLE) + 32 * sizeof(MIB_IPADDRROW)]; ULONG nSize = sizeof mib; PMIB_IPADDRTABLE ipAddr = (PMIB_IPADDRTABLE)mib; - hrRes = (HRESULT)-1; - if (m_pfGetIpAddrTable != NULL) - try { // just to be sure; another call from iphlpapi used earlier in eMule seemed to crash on some systems according to dumps - hrRes = m_pfGetIpAddrTable(ipAddr, &nSize, FALSE); - } catch (...) { - ASSERT(0); - } - - if (hrRes != NO_ERROR) - return CString(); + hr = GetIpAddrTable(ipAddr, &nSize, FALSE); + if (hr != NO_ERROR) + return strLocalIP; DWORD nCount = ipAddr->dwNumEntries; - CString strLocalIP; // Look for IP associated with the interface in the address table // Loopback addresses are functional for ICS? (at least Windows maps them fine) - for (DWORD nIf = 0; nIf < nCount; ++nIf) { + for (DWORD nIf = 0; nIf < nCount; ++nIf) if (ipAddr->table[nIf].dwIndex == nInterfaceIndex) { ip = ipAddr->table[nIf].dwAddr; - strLocalIP.Format(_T("%lu.%lu.%lu.%lu") - , (ip & 0xff), ((ip >> 8) & 0xff), ((ip >> 16) & 0xff), (ip >> 24)); + strLocalIP = ipstr(ip); break; } - } if (!strLocalIP.IsEmpty() && !strExternalIP.IsEmpty()) DebugLog(_T("UPnP route: %s->%s"), (LPCTSTR)strLocalIP, (LPCTSTR)strExternalIP); @@ -699,8 +633,8 @@ CString CUPnPImplWinServ::GetLocalRoutableIP(ServicePointer pService) return strLocalIP; } -// Walks through all port mappings and searches for "eMule" string. -// Deletes when it has the same IP as local, otherwise quits and sets +// Walk through all port mappings and search for "eMule" string. +// Delete when it has the same IP as local, otherwise quit and set // m_bPortIsFree to false after 10 attempts to use a random port; // this member will be used to determine if we have to create new port maps. void CUPnPImplWinServ::DeleteExistingPortMappings(ServicePointer pService) @@ -709,15 +643,16 @@ void CUPnPImplWinServ::DeleteExistingPortMappings(ServicePointer pService) return; // Port mappings are numbered starting from 0 without gaps between; // So, we will loop until we get an empty string or failure as a result. - CString strInArgs; USHORT nEntry = 0; // PortMappingNumberOfEntries is of type VT_UI2 //int nAttempts = 10; - // ICS returns computer name instead of IP, thus we need to compare not IPs - TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1] = {}; - DWORD nMaxLen = MAX_COMPUTERNAME_LENGTH + 1; - GetComputerName(szComputerName, &nMaxLen); + // ICS returns computer name instead of IP, thus we need to compare names, not IPs + TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD nMaxLen = _countof(szComputerName); + if (!GetComputerName(szComputerName, &nMaxLen)) + *szComputerName = _T('\0'); + CString strInArgs; CString strActionResult; HRESULT hr; do { @@ -768,12 +703,10 @@ void CUPnPImplWinServ::DeleteExistingPortMappings(ServicePointer pService) { break; } - if (_tcsstr(oTokens[4], m_sLocalIP) != NULL || stristr(oTokens[4], szComputerName) != NULL) { CString str; - hrDel = InvokeAction(pService, _T("DeletePortMapping"), - strHost + strPort + strProtocol, str); + hrDel = InvokeAction(pService, _T("DeletePortMapping"), strHost + strPort + strProtocol, str); if (FAILED(hrDel)) UPnPMessage(hrDel); else @@ -850,8 +783,8 @@ void CUPnPImplWinServ::CreatePortMappings(ServicePointer pService) // Invoke the action for the selected service. // OUT arguments or return value is packed in strResult. -HRESULT CUPnPImplWinServ::InvokeAction(ServicePointer pService, - CComBSTR action, LPCTSTR pszInArgString, CString &strResult) +HRESULT CUPnPImplWinServ::InvokeAction(ServicePointer pService + , CComBSTR action, LPCTSTR pszInArgString, CString &strResult) { if (pService == NULL || action == NULL) return E_POINTER; @@ -950,7 +883,6 @@ INT_PTR CUPnPImplWinServ::CreateVarFromString(const CString &strArgs, VARIANT ** } CArray oTokens; - for (int iPos = 0; iPos >= 0;) { const CString &sToken(strArgs.Tokenize(_T("|"), iPos)); if (!sToken.IsEmpty()) @@ -958,7 +890,7 @@ INT_PTR CUPnPImplWinServ::CreateVarFromString(const CString &strArgs, VARIANT ** } INT_PTR nArgs = oTokens.GetCount(); - *pppVars = new VARIANT*[nArgs](); + *pppVars = new VARIANT*[nArgs]{}; bool bInvalid = false; CString strType, strValue; @@ -967,7 +899,7 @@ INT_PTR CUPnPImplWinServ::CreateVarFromString(const CString &strArgs, VARIANT ** int nEqualPos = sToken.Find('='); // Malformed string test - if (nEqualPos == -1) { + if (nEqualPos < 0) { bInvalid = true; break; } @@ -1157,16 +1089,16 @@ HRESULT __stdcall CDeviceFinderCallback::QueryInterface(REFIID iid, LPVOID *ppvO ULONG __stdcall CDeviceFinderCallback::AddRef() { - return InterlockedIncrement(&m_lRefCount); -}; + return ::InterlockedIncrement(&m_lRefCount); +} ULONG __stdcall CDeviceFinderCallback::Release() { - LONG lRefCount = InterlockedDecrement(&m_lRefCount); + LONG lRefCount = ::InterlockedDecrement(&m_lRefCount); if (!lRefCount) delete this; return lRefCount; -}; +} //////////////////////////////////////////////////////////////////////////////// // CServiceCallback @@ -1188,7 +1120,7 @@ HRESULT __stdcall CServiceCallback::StateVariableChanged(IUPnPService *pService, if (FAILED(hr)) return UPnPMessage(hr); - CString strValue(varValue.bstrVal); + const CString strValue(varValue.bstrVal); // Re-examine state variable change only when discovery was finished // We are not interested in the initial values; we will request them explicitly @@ -1215,7 +1147,7 @@ HRESULT __stdcall CServiceCallback::ServiceInstanceDied(IUPnPService *pService) HRESULT hr = pService->get_Id(&bsServiceId); if (SUCCEEDED(hr)) { - DebugLogError(_T("UPnP service %ls died"), (LPCWSTR)bsServiceId); + DebugLogError(_T("UPnP service %s died"), (LPCTSTR)bsServiceId); return hr; } @@ -1227,28 +1159,27 @@ HRESULT __stdcall CServiceCallback::QueryInterface(REFIID iid, LPVOID *ppvObject if (NULL == ppvObject) return E_POINTER; + if (IsEqualIID(iid, IID_IUnknown) || IsEqualIID(iid, IID_IUPnPServiceCallback)) { + *ppvObject = static_cast(this); + AddRef(); + return S_OK; + } *ppvObject = NULL; - - if (!IsEqualIID(iid, IID_IUnknown) && !IsEqualIID(iid, IID_IUPnPServiceCallback)) - return E_NOINTERFACE; - - *ppvObject = static_cast(this); - AddRef(); - return S_OK; -}; + return E_NOINTERFACE; +} ULONG __stdcall CServiceCallback::AddRef() { - return static_cast(InterlockedIncrement(&m_lRefCount)); -}; + return static_cast(::InterlockedIncrement(&m_lRefCount)); +} ULONG __stdcall CServiceCallback::Release() { - LONG lRefCount = InterlockedDecrement(&m_lRefCount); + LONG lRefCount = ::InterlockedDecrement(&m_lRefCount); if (0 == lRefCount) delete this; return static_cast(lRefCount); -}; +} //////////////////////////////////////////////////////////////////////////////// // Prints the appropriate UPnP error text @@ -1327,6 +1258,7 @@ CString translateUPnPResult(HRESULT hr) } return CString(p); } + HRESULT UPnPMessage(HRESULT hr) { CString strError(translateUPnPResult(hr)); diff --git a/srchybrid/UPnPImplWinServ.h b/srchybrid/UPnPImplWinServ.h index 849607a1..cab9d31d 100644 --- a/srchybrid/UPnPImplWinServ.h +++ b/srchybrid/UPnPImplWinServ.h @@ -5,7 +5,7 @@ // This file is part of SHAREAZA (www.shareaza.com) // // this file is part of eMule -// Copyright (C)2007 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +// Copyright (C)2007-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -82,7 +82,7 @@ class CUPnPImplWinServ : public CUPnPImpl return UPNP_IMPL_WINDOWSERVICE; } - // No Support for Refreshing for this (fallback) implementation yet - in many cases where it would be needed (router reset etc) + // No Support for Refreshing in this (fallback) implementation yet - in many cases where it would be needed (router reset etc) // the windows side of the implementation tends to get bugged until reboot anyway. Still might get added later virtual bool CheckAndRefresh() { @@ -103,27 +103,16 @@ class CUPnPImplWinServ : public CUPnPImpl m_bAsyncFindRunning = false; } MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); + while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); } return m_bAsyncFindRunning; } + TRISTATE m_bUPnPDeviceConnected; // Implementation - // API functions - SC_HANDLE(WINAPI *m_pfnOpenSCManager)(LPCTSTR, LPCTSTR, DWORD); - SC_HANDLE(WINAPI *m_pfnOpenService)(SC_HANDLE, LPCTSTR, DWORD); - BOOL(WINAPI *m_pfnQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE, DWORD, LPDWORD); - BOOL(WINAPI *m_pfnCloseServiceHandle)(SC_HANDLE); - BOOL(WINAPI *m_pfnStartService)(SC_HANDLE, DWORD, LPCTSTR*); - BOOL(WINAPI *m_pfnControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS); - - TGetBestInterface m_pfGetBestInterface; - TGetIpAddrTable m_pfGetIpAddrTable; - TGetIfEntry m_pfGetIfEntry; - static FinderPointer CreateFinderInstance(); struct FindDevice : private std::unary_function { @@ -177,8 +166,6 @@ class CUPnPImplWinServ : public CUPnPImpl CString m_sLocalIP; CString m_sExternalIP; - HMODULE m_hADVAPI32_DLL; - HMODULE m_hIPHLPAPI_DLL; DWORD m_tLastEvent; // When the last event was received? LONG m_nAsyncFindHandle; bool m_bCOM; @@ -208,13 +195,14 @@ class CDeviceFinderCallback STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release(); +protected: + virtual ~CDeviceFinderCallback() = default; // implementation private: HRESULT __stdcall DeviceAdded(LONG nFindData, IUPnPDevice *pDevice); HRESULT __stdcall DeviceRemoved(LONG nFindData, BSTR bsUDN); HRESULT __stdcall SearchComplete(LONG nFindData); -private: CUPnPImplWinServ &m_instance; LONG m_lRefCount; }; @@ -233,12 +221,13 @@ class CServiceCallback : public IUPnPServiceCallback STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release(); +protected: + virtual ~CServiceCallback() = default; // implementation private: HRESULT __stdcall StateVariableChanged(IUPnPService *pService, LPCWSTR pszStateVarName, VARIANT varValue); HRESULT __stdcall ServiceInstanceDied(IUPnPService *pService); -private: CUPnPImplWinServ &m_instance; LONG m_lRefCount; }; \ No newline at end of file diff --git a/srchybrid/UPnPImplWrapper.cpp b/srchybrid/UPnPImplWrapper.cpp index 4df1f02d..238189a3 100644 --- a/srchybrid/UPnPImplWrapper.cpp +++ b/srchybrid/UPnPImplWrapper.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -38,6 +38,7 @@ CUPnPImplWrapper::CUPnPImplWrapper() m_liAvailable.AddTail(new CUPnPImplNone()); Init(); } + CUPnPImplWrapper::~CUPnPImplWrapper() { while (!m_liAvailable.IsEmpty()) @@ -46,6 +47,7 @@ CUPnPImplWrapper::~CUPnPImplWrapper() delete m_liUsed.RemoveHead(); m_pActiveImpl = NULL; } + void CUPnPImplWrapper::Init() { ASSERT(!m_liAvailable.IsEmpty()); diff --git a/srchybrid/UPnPImplWrapper.h b/srchybrid/UPnPImplWrapper.h index 1e978b5c..8b176422 100644 --- a/srchybrid/UPnPImplWrapper.h +++ b/srchybrid/UPnPImplWrapper.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/URLClient.cpp b/srchybrid/URLClient.cpp index 2fe0e619..82d7ce06 100644 --- a/srchybrid/URLClient.cpp +++ b/srchybrid/URLClient.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -52,6 +52,7 @@ void CUrlClient::SetRequestFile(CPartFile *pReqFile) if (m_reqfile) { m_nPartCount = m_reqfile->GetPartCount(); m_abyPartStatus = new uint8[m_nPartCount]; + ASSERT(m_nPartCount); memset(m_abyPartStatus, 1, m_nPartCount); m_bCompleteSource = true; } @@ -119,7 +120,7 @@ bool CUrlClient::SetUrl(LPCTSTR pszUrl, uint32 nIP) // if (m_nConnectIP == INADDR_NONE) // m_nConnectIP = 0; m_nUserIDHybrid = htonl(m_nConnectIP); - ASSERT(m_nUserIDHybrid != 0); + ASSERT(m_nUserIDHybrid); m_nUserPort = Url.nPort; return true; } @@ -133,9 +134,9 @@ bool CUrlClient::SendHttpBlockRequests() { m_dwLastBlockReceived = ::GetTickCount(); if (m_reqfile == NULL) - throw CString(_T("Failed to send block requests - No 'reqfile' attached")); + throwCStr(_T("Failed to send block requests - No 'reqfile' attached")); - CreateBlockRequests(PARTSIZE / EMBLOCKSIZE, PARTSIZE / EMBLOCKSIZE); + CreateBlockRequests(PARTSIZE / EMBLOCKSIZE); if (m_PendingBlocks_list.IsEmpty()) { SetDownloadState(DS_NONEEDEDPARTS); SwapToAnotherFile(_T("A4AF for NNP file. UrlClient::SendHttpBlockRequests()"), true, false, false, NULL, true, true); @@ -154,10 +155,8 @@ bool CUrlClient::SendHttpBlockRequests() m_uReqEnd = pending->block->EndOffset; else { bMergeBlocks = false; - m_reqfile->RemoveBlockFromList(pending->block->StartOffset, pending->block->EndOffset); - delete pending->block; - delete pending; m_PendingBlocks_list.RemoveAt(posLast); + ClearPendingBlockRequest(pending); } } @@ -229,7 +228,7 @@ bool CUrlClient::Disconnected(LPCTSTR pszReason, bool bFromSocket) { CHttpClientDownSocket *s = static_cast(socket); - TRACE(_T("%hs: HttpState=%u, Reason=%s\n"), __FUNCTION__, s == NULL ? -1 : s->GetHttpState(), pszReason); + TRACE(_T("%hs: HttpState=%u, Reason=%s\n"), __FUNCTION__, (s ? s->GetHttpState() : -1), pszReason); // TODO: This is a mess. if (s && (s->GetHttpState() == HttpStateRecvExpected || s->GetHttpState() == HttpStateRecvBody)) m_fileReaskTimes.RemoveKey(m_reqfile); // ZZ:DownloadManager (one re-ask timestamp for each file) @@ -239,11 +238,11 @@ bool CUrlClient::Disconnected(LPCTSTR pszReason, bool bFromSocket) bool CUrlClient::ProcessHttpDownResponse(const CStringAArray &astrHeaders) { if (m_reqfile == NULL) - throw CString(_T("Failed to process received HTTP data block - No 'reqfile' attached")); + throwCStr(_T("Failed to process received HTTP data block - No 'reqfile' attached")); if (astrHeaders.IsEmpty()) - throw CString(_T("Unexpected HTTP response - No headers available")); + throwCStr(_T("Unexpected HTTP response - No headers available")); - const CStringA &rstrHdr = astrHeaders[0]; + const CStringA &rstrHdr(astrHeaders[0]); UINT uHttpMajVer, uHttpMinVer, uHttpStatusCode; if (sscanf(rstrHdr, "HTTP/%u.%u %u", &uHttpMajVer, &uHttpMinVer, &uHttpStatusCode) != 3) { CString strError; @@ -308,12 +307,12 @@ bool CUrlClient::ProcessHttpDownResponse(const CStringAArray &astrHeaders) if (bNewLocation) { if (++m_iRedirected >= 3) - throw CString(_T("Max. HTTP redirection count exceeded")); + throwCStr(_T("Max. HTTP redirection count exceeded")); // the tricky part socket->Safe_Delete(); // mark our parent object for getting deleted! if (!TryToConnect(true)) // replace our parent object with a new one - throw CString(_T("Failed to connect to redirected URL")); + throwCStr(_T("Failed to connect to redirected URL")); return false; // tell our old parent object (which was marked as to get deleted // and which is no longer attached to us) to disconnect. } @@ -321,7 +320,7 @@ bool CUrlClient::ProcessHttpDownResponse(const CStringAArray &astrHeaders) if (!bValidContentRange) { if (thePrefs.GetDebugClientTCPLevel() <= 0) DebugHttpHeaders(astrHeaders); - throw CString(_T("Unexpected HTTP response - No valid HTTP content range found")); + throwCStr(_T("Unexpected HTTP response - No valid HTTP content range found")); } SetDownloadState(DS_DOWNLOADING); @@ -352,7 +351,7 @@ void CUpDownClient::ProcessHttpBlockPacket(const BYTE *pucData, UINT uSize) else p = NULL; if (p) - throw CString(p); + throwCStr(p); uint64 nStartPos = m_nUrlStartPos; uint64 nEndPos = m_nUrlStartPos + uSize; @@ -363,12 +362,12 @@ void CUpDownClient::ProcessHttpBlockPacket(const BYTE *pucData, UINT uSize) // Debug(" Start=%I64u End=%I64u Size=%u %s\n", nStartPos, nEndPos, size, (LPCTSTR)DbgGetFileInfo(m_reqfile->GetFileHash())); if (!(GetDownloadState() == DS_DOWNLOADING || GetDownloadState() == DS_NONEEDEDPARTS)) - throw CString(_T("Failed to process HTTP data block - Invalid download state")); + throwCStr(_T("Failed to process HTTP data block - Invalid download state")); m_dwLastBlockReceived = ::GetTickCount(); if (nEndPos <= nStartPos) - throw CString(_T("Failed to process HTTP data block - Invalid block start/end offsets")); + throwCStr(_T("Failed to process HTTP data block - Invalid block start/end offsets")); thePrefs.Add2SessionTransferData(GetClientSoft(), (UINT)((GetClientSoft() == SO_URL) ? -2 : -1), false, false, uSize); m_nDownDataRateMS += uSize; @@ -387,17 +386,16 @@ void CUpDownClient::ProcessHttpBlockPacket(const BYTE *pucData, UINT uSize) } m_nLastBlockOffset = nStartPos; - uint32 lenWritten = m_reqfile->WriteToBuffer(uSize, pucData, nStartPos, nEndPos, cur_block->block, this); + uint32 lenWritten = m_reqfile->WriteToBuffer(uSize, pucData, nStartPos, nEndPos, cur_block->block, this, true); if (lenWritten > 0) { m_nTransferredDown += uSize; m_nCurSessionPayloadDown += lenWritten; + cur_block->block->transferred += lenWritten; SetTransferredDownMini(); if (nEndPos >= cur_block->block->EndOffset) { - m_reqfile->RemoveBlockFromList(cur_block->block->StartOffset, cur_block->block->EndOffset); - delete cur_block->block; - delete cur_block; m_PendingBlocks_list.RemoveAt(posLast); + ClearPendingBlockRequest(cur_block); if (m_PendingBlocks_list.IsEmpty()) { if (thePrefs.GetDebugClientTCPLevel() > 0) diff --git a/srchybrid/URLClient.h b/srchybrid/URLClient.h index f2f36550..6bd1dd03 100644 --- a/srchybrid/URLClient.h +++ b/srchybrid/URLClient.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -27,7 +27,6 @@ class CUrlClient : public CUpDownClient public: CUrlClient(); - virtual ~CUrlClient() = default; bool SetUrl(LPCTSTR pszUrl, uint32 nIP = 0); diff --git a/srchybrid/UpdownClient.h b/srchybrid/UpdownClient.h index 463b52be..1a6afc86 100644 --- a/srchybrid/UpdownClient.h +++ b/srchybrid/UpdownClient.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -38,15 +38,6 @@ enum EUTF8str : uint8; struct Pending_Block_Struct { - Pending_Block_Struct() - : block() - , zStream() - , totalUnzipped() - , fZStreamError() - , fRecovered() - , fQueued() - { - } Requested_Block_Struct *block; struct z_stream_s *zStream; // Barry - Used to unzip packets UINT totalUnzipped; // Barry - This holds the total unzipped bytes for all packets so far @@ -58,8 +49,8 @@ struct Pending_Block_Struct #pragma pack(push, 1) struct Requested_File_Struct { - uchar fileid[16]; - uint32 lastasked; + uchar fileid[MDX_DIGEST_SIZE]; + DWORD lastasked; uint8 badrequests; }; #pragma pack(pop) @@ -71,7 +62,7 @@ struct PartFileStamp }; #define MAKE_CLIENT_VERSION(mjr, min, upd) \ - ((UINT)(mjr)*100U*10U*100U + (UINT)(min)*100U*10U + (UINT)(upd)*100U) + ((((UINT)(mjr)*100U + (UINT)(min))*10U + (UINT)(upd))*100U) class CUpDownClient : public CObject { @@ -107,13 +98,13 @@ class CUpDownClient : public CObject //Only use this when you know the real IP or when your clearing it. void SetIP(uint32 val) { m_dwUserIP = val; m_nConnectIP = val; } - inline bool HasLowID() const { return (m_nUserIDHybrid < 16777216u); } //0x01000000u + inline bool HasLowID() const { return ::IsLowID(m_nUserIDHybrid); } uint32 GetConnectIP() const { return m_nConnectIP; } void SetConnectIP(uint32 val) { m_nConnectIP = val; } uint16 GetUserPort() const { return m_nUserPort; } void SetUserPort(uint16 val) { m_nUserPort = val; } - UINT GetTransferredUp() const { return m_nTransferredUp; } - UINT GetTransferredDown() const { return m_nTransferredDown; } + uint64 GetTransferredUp() const { return m_nTransferredUp; } + uint64 GetTransferredDown() const { return m_nTransferredDown; } uint32 GetServerIP() const { return m_dwServerIP; } void SetServerIP(uint32 nIP) { m_dwServerIP = nIP; } uint16 GetServerPort() const { return m_nServerPort; } @@ -141,7 +132,7 @@ class CUpDownClient : public CObject bool SupportPeerCache() const { return m_fPeerCache; } bool SupportsLargeFiles() const { return m_fSupportsLargeFiles; } bool SupportsFileIdentifiers() const { return m_fSupportsFileIdent; } - bool IsEmuleClient() const { return m_byEmuleVersion!=0; } + bool IsEmuleClient() const { return m_byEmuleVersion != 0; } uint8 GetSourceExchange1Version() const { return m_bySourceExchange1Ver; } bool SupportsSourceExchange2() const { return m_fSupportsSourceEx2; } CClientCredits* Credits() const { return credits; } @@ -172,11 +163,11 @@ class CUpDownClient : public CObject void CheckQueueRankFlood(); bool Compare(const CUpDownClient *tocomp, bool bIgnoreUserhash = false) const; void ResetFileStatusInfo(); - uint32 GetLastSrcReqTime() const { return m_dwLastSourceRequest; } + DWORD GetLastSrcReqTime() const { return m_dwLastSourceRequest; } void SetLastSrcReqTime() { m_dwLastSourceRequest = ::GetTickCount(); } - uint32 GetLastSrcAnswerTime() const { return m_dwLastSourceAnswer; } + DWORD GetLastSrcAnswerTime() const { return m_dwLastSourceAnswer; } void SetLastSrcAnswerTime() { m_dwLastSourceAnswer = ::GetTickCount(); } - uint32 GetLastAskedForSources() const { return m_dwLastAskedForSources; } + DWORD GetLastAskedForSources() const { return m_dwLastAskedForSources; } void SetLastAskedForSources() { m_dwLastAskedForSources = ::GetTickCount(); } bool GetFriendSlot() const; void SetFriendSlot(bool bNV) { m_bFriendSlot = bNV; } @@ -191,7 +182,7 @@ class CUpDownClient : public CObject bool SendBuddyPingPong() { return ::GetTickCount() >= m_dwLastBuddyPingPongTime; } bool AllowIncomeingBuddyPingPong() { return ::GetTickCount() >= m_dwLastBuddyPingPongTime + MIN2MS(3); } void SetLastBuddyPingPongTime() { m_dwLastBuddyPingPongTime = ::GetTickCount() + MIN2MS(10); } - void ProcessFirewallCheckUDPRequest(CSafeMemFile *data); + void ProcessFirewallCheckUDPRequest(CSafeMemFile &data); void SendSharedDirectories(); // secure ident @@ -206,7 +197,7 @@ class CUpDownClient : public CObject void InfoPacketsReceived(); bool HasPassedSecureIdent(bool bPassIfUnavailable) const; // preview - void SendPreviewRequest(const CAbstractFile *pForFile); + void SendPreviewRequest(const CAbstractFile &rForFile); void SendPreviewAnswer(const CKnownFile *pForFile, CxImage **imgFrames, uint8 nCount); void ProcessPreviewReq(const uchar *pachPacket, uint32 nSize); void ProcessPreviewAnswer(const uchar *pachPacket, uint32 nSize); @@ -233,12 +224,12 @@ class CUpDownClient : public CObject // Upload EUploadState GetUploadState() const { return m_eUploadState; } void SetUploadState(EUploadState eNewState); - uint32 GetWaitStartTime() const; + DWORD GetWaitStartTime() const; void SetWaitStartTime(); void ClearWaitStartTime(); - uint32 GetWaitTime() const { return m_dwUploadTime - GetWaitStartTime(); } + DWORD GetWaitTime() const { return m_dwUploadTime - GetWaitStartTime(); } bool IsDownloading() const { return (m_eUploadState == US_UPLOADING); } - UINT GetDatarate() const { return m_nUpDatarate; } + UINT GetUploadDatarate() const { return m_nUpDatarate; } UINT GetScore(bool sysvalue, bool isdownloading = false, bool onlybasevalue = false) const; void AddReqBlock(Requested_Block_Struct *reqblock, bool bSignalIOThread); DWORD GetUpStartTime() const { return m_dwUploadTime; } @@ -247,42 +238,40 @@ class CUpDownClient : public CObject void SendHashsetPacket(const uchar *pData, uint32 nSize, bool bFileIdentifiers); const uchar* GetUploadFileID() const { return requpfileid; } void SetUploadFileID(CKnownFile *newreqfile); - uint32 UpdateUploadingStatisticsData(); + void UpdateUploadingStatisticsData(); void SendRankingInfo(); void SendCommentInfo(/*const */CKnownFile *file); void AddRequestCount(const uchar *fileid); void UnBan(); void Ban(LPCTSTR pszReason = NULL); UINT GetAskedCount() const { return m_cAsked; } - void AddAskedCount() { ++m_cAsked; } + void IncrementAskedCount() { ++m_cAsked; } void SetAskedCount(UINT m_cInAsked) { m_cAsked = m_cInAsked; } void FlushSendBlocks(); // call this when you stop upload, or the socket might be not able to send - uint32 GetLastUpRequest() const { return m_dwLastUpRequest; } + DWORD GetLastUpRequest() const { return m_dwLastUpRequest; } void SetLastUpRequest() { m_dwLastUpRequest = ::GetTickCount(); } void SetCollectionUploadSlot(bool bValue); bool HasCollectionUploadSlot() const { return m_bCollectionUploadSlot; } - UINT GetSessionUp() const { return m_nTransferredUp - m_nCurSessionUp; } + uint64 GetSessionUp() const { return m_nTransferredUp - m_nCurSessionUp; } void ResetSessionUp() { m_nCurSessionUp = m_nTransferredUp; m_addedPayloadQueueSession = 0; m_nCurQueueSessionPayloadUp = 0; } - UINT GetSessionDown() const { return m_nTransferredDown - m_nCurSessionDown; } - UINT GetSessionPayloadDown() const { return m_nCurSessionPayloadDown; } + uint64 GetSessionDown() const { return m_nTransferredDown - m_nCurSessionDown; } + uint64 GetSessionPayloadDown() const { return m_nCurSessionPayloadDown; } void ResetSessionDown() { m_nCurSessionDown = m_nTransferredDown; m_nCurSessionPayloadDown = 0; } - UINT GetQueueSessionPayloadUp() const { return m_nCurQueueSessionPayloadUp; } // Data uploaded/transmitted - UINT GetQueueSessionUploadAdded() const { return m_addedPayloadQueueSession; } // Data put into upload buffers - UINT GetPayloadInBuffer() const { return m_addedPayloadQueueSession - m_nCurQueueSessionPayloadUp; } - void SetQueueSessionUploadAdded(UINT uVal) { m_addedPayloadQueueSession = uVal; } + uint64 GetQueueSessionPayloadUp() const { return m_nCurQueueSessionPayloadUp; } // Data uploaded/transmitted + uint64 GetQueueSessionUploadAdded() const { return m_addedPayloadQueueSession; } // Data put into upload buffers + uint64 GetPayloadInBuffer() const { return m_addedPayloadQueueSession - m_nCurQueueSessionPayloadUp; } + void SetQueueSessionUploadAdded(uint64 uVal) { m_addedPayloadQueueSession = uVal; } bool ProcessExtendedInfo(CSafeMemFile *data, CKnownFile *tempreqfile); uint16 GetUpPartCount() const { return m_nUpPartCount; } void DrawUpStatusBar(CDC *dc, const CRect &rect, bool onlygreyrect, bool bFlat) const; - bool IsUpPartAvailable(UINT iPart) const { - return (iPart >= m_nUpPartCount || !m_abyUpPartStatus) ? false : m_abyUpPartStatus[iPart] != 0; - } + bool IsUpPartAvailable(UINT uPart) const { return (m_abyUpPartStatus && uPart < m_nUpPartCount && m_abyUpPartStatus[uPart]); } uint8* GetUpPartStatus() const { return m_abyUpPartStatus; } float GetCombinedFilePrioAndCredit(); uint8 GetDataCompressionVersion() const { return m_byDataCompVer; } @@ -290,13 +279,13 @@ class CUpDownClient : public CObject /////////////////////////////////////////////////////////////////////////////////////////////////////////// // Download UINT GetAskedCountDown() const { return m_cDownAsked; } - void AddAskedCountDown() { ++m_cDownAsked; } + void IncrementAskedCountDown() { ++m_cDownAsked; } void SetAskedCountDown(UINT cInDownAsked) { m_cDownAsked = cInDownAsked; } EDownloadState GetDownloadState() const { return m_eDownloadState; } void SetDownloadState(EDownloadState nNewState, LPCTSTR pszReason = _T("Unspecified")); - DWORD GetLastAskedTime(const CPartFile *partFile = NULL) const; - void SetLastAskedTime() { m_fileReaskTimes.SetAt(m_reqfile, ::GetTickCount()); } - bool IsPartAvailable(UINT iPart) const { return m_abyPartStatus && iPart < m_nPartCount && m_abyPartStatus[iPart] != 0; } + DWORD GetLastAskedTime(const CPartFile *pFile = NULL) const; + void SetLastAskedTime() { m_fileReaskTimes[m_reqfile] = ::GetTickCount(); } + bool IsPartAvailable(UINT uPart) const { return m_abyPartStatus && uPart < m_nPartCount && m_abyPartStatus[uPart]; } uint8* GetPartStatus() const { return m_abyPartStatus; } uint16 GetPartCount() const { return m_nPartCount; } UINT GetDownloadDatarate() const { return m_nDownDatarate; } @@ -313,11 +302,12 @@ class CUpDownClient : public CObject void ProcessHashSet(const uchar *packet, uint32 size, bool bFileIdentifiers); void ProcessAcceptUpload(); bool AddRequestForAnotherFile(CPartFile *file); - void CreateBlockRequests(int iMinBlocks, int iMaxBlocks); + void CreateBlockRequests(int blockCount); virtual void SendBlockRequests(); virtual bool SendHttpBlockRequests(); virtual void ProcessBlockPacket(const uchar *packet, uint32 size, bool packed, bool bI64Offsets); virtual void ProcessHttpBlockPacket(const BYTE *pucData, UINT uSize); + void ClearPendingBlockRequest(const Pending_Block_Struct *pending); void ClearDownloadBlockRequests(); void SendOutOfPartReqsAndAddToWaitingQueue(); UINT CalculateDownloadRate(); @@ -325,9 +315,9 @@ class CUpDownClient : public CObject bool SwapToAnotherFile(LPCTSTR reason, bool bIgnoreNoNeeded, bool ignoreSuspensions, bool bRemoveCompletely, CPartFile *toFile = NULL, bool allowSame = true, bool isAboutToAsk = false, bool debug = false); // ZZ:DownloadManager void DontSwapTo(/*const*/ CPartFile *file); bool IsSwapSuspended(const CPartFile *file, const bool allowShortReaskTime = false, const bool fileIsNNP = false) /*const*/; // ZZ:DownloadManager - uint32 GetTimeUntilReask() const; - uint32 GetTimeUntilReask(const CPartFile *file) const; - uint32 GetTimeUntilReask(const CPartFile *file, const bool allowShortReaskTime, const bool useGivenNNP = false, const bool givenNNP = false) const; + DWORD GetTimeUntilReask() const; + DWORD GetTimeUntilReask(const CPartFile *file) const; + DWORD GetTimeUntilReask(const CPartFile *file, const bool allowShortReaskTime, const bool useGivenNNP = false, const bool givenNNP = false) const; void UDPReaskACK(uint16 nNewQR); void UDPReaskFNF(); void UDPReaskForDownload(); @@ -361,9 +351,9 @@ class CUpDownClient : public CObject void SetChatState(const EChatState nNewS) { m_eChatstate = nNewS; } EChatCaptchaState GetChatCaptchaState() const { return m_eChatCaptchaState; } void SetChatCaptchaState(const EChatCaptchaState nNewS) { m_eChatCaptchaState = nNewS; } - void ProcessChatMessage(CSafeMemFile *data, uint32 nLength); + void ProcessChatMessage(CSafeMemFile &data, uint32 nLength); void SendChatMessage(const CString &strMessage); - void ProcessCaptchaRequest(CSafeMemFile *data); + void ProcessCaptchaRequest(CSafeMemFile &data); void ProcessCaptchaReqRes(uint8 nStatus); // message filtering uint8 GetMessagesReceived() const { return m_cMessagesReceived; } @@ -426,10 +416,10 @@ class CUpDownClient : public CObject const CString& DbgGetMuleInfo() const { return m_strMuleInfo; } // ZZ:DownloadManager --> - const bool IsInNoNeededList(const CPartFile *fileToCheck) const; - const bool SwapToRightFile(CPartFile *SwapTo, CPartFile *cur_file, bool ignoreSuspensions, bool SwapToIsNNPFile, bool curFileisNNPFile, bool &wasSkippedDueToSourceExchange, bool doAgressiveSwapping = false, bool debug = false); - const DWORD getLastTriedToConnectTime() const { return m_dwLastTriedToConnect; } - void setLastTriedToConnectTime() { m_dwLastTriedToConnect = ::GetTickCount(); } + bool IsInNoNeededList(const CPartFile *fileToCheck) const; + bool SwapToRightFile(CPartFile *SwapTo, CPartFile *cur_file, bool ignoreSuspensions, bool SwapToIsNNPFile, bool curFileisNNPFile, bool &wasSkippedDueToSourceExchange, bool doAgressiveSwapping = false, bool debug = false); + DWORD GetLastTriedToConnectTime() const { return m_dwLastTriedToConnect; } + void SetLastTriedToConnectTime() { m_dwLastTriedToConnect = ::GetTickCount(); } // <-- ZZ:DownloadManager #ifdef _DEBUG @@ -491,8 +481,8 @@ class CUpDownClient : public CObject EPeerCacheUpState m_ePeerCacheUpState; // base - bool ProcessHelloTypePacket(CSafeMemFile *data); - void SendHelloTypePacket(CSafeMemFile *data); + bool ProcessHelloTypePacket(CSafeMemFile &data); + void SendHelloTypePacket(CSafeMemFile &data); void SendFirewallCheckUDPRequest(); void SendHashSetRequest(); @@ -536,9 +526,9 @@ class CUpDownClient : public CObject uint32 m_dwLastSignatureIP; CString m_strClientSoftware; CString m_strModVersion; - uint32 m_dwLastSourceRequest; - uint32 m_dwLastSourceAnswer; - uint32 m_dwLastAskedForSources; + DWORD m_dwLastSourceRequest; + DWORD m_dwLastSourceAnswer; + DWORD m_dwLastAskedForSources; uint32 m_uSearchID; int m_iFileListRequested; CString m_strFileComment; @@ -556,7 +546,7 @@ class CUpDownClient : public CObject uint8 m_cCaptchasSent; uint32 m_nBuddyIP; - uint32 m_dwLastBuddyPingPongTime; + DWORD m_dwLastBuddyPingPongTime; uchar m_achBuddyID[MDX_DIGEST_SIZE]; CString m_strHelloInfo; CString m_strMuleInfo; @@ -582,23 +572,23 @@ class CUpDownClient : public CObject // int GetFilePrioAsNumber() const; - UINT m_nTransferredUp; + uint64 m_nTransferredUp; + uint64 m_nCurSessionUp; + uint64 m_nCurSessionDown; + uint64 m_nCurQueueSessionPayloadUp; + uint64 m_addedPayloadQueueSession; DWORD m_dwUploadTime; + DWORD m_dwLastUpRequest; UINT m_cAsked; - uint32 m_dwLastUpRequest; - UINT m_nCurSessionUp; - UINT m_nCurSessionDown; - UINT m_nCurQueueSessionPayloadUp; - UINT m_addedPayloadQueueSession; + UINT m_slotNumber; + uchar requpfileid[MDX_DIGEST_SIZE]; uint16 m_nUpPartCount; uint16 m_nUpCompleteSourcesCount; - uchar requpfileid[16]; - UINT m_slotNumber; bool m_bCollectionUploadSlot; typedef struct { - UINT datalen; + uint32 datalen; DWORD timestamp; } TransferredData; CTypedPtrList m_RequestedFiles_list; @@ -610,12 +600,12 @@ class CUpDownClient : public CObject CAICHHash *m_pReqFileAICHHash; uint8 *m_abyPartStatus; CString m_strClientFilename; - UINT m_cDownAsked; - UINT m_nTransferredDown; - UINT m_nCurSessionPayloadDown; - DWORD m_dwDownStartTime; + uint64 m_nTransferredDown; + uint64 m_nCurSessionPayloadDown; uint64 m_nLastBlockOffset; - uint32 m_dwLastBlockReceived; + DWORD m_dwDownStartTime; + DWORD m_dwLastBlockReceived; + UINT m_cDownAsked; UINT m_nTotalUDPPackets; UINT m_nFailedUDPPackets; UINT m_nRemoteQueueRank; @@ -639,17 +629,17 @@ class CUpDownClient : public CObject ////////////////////////////////////////////////////////// // Upload data rate computation // - UINT m_nUpDatarate; - UINT m_nSumForAvgUpDataRate; CList m_AverageUDR_list; + UINT m_nUpDatarate; + uint64 m_nSumForAvgUpDataRate; ////////////////////////////////////////////////////////// // Download data rate computation // + CList m_AverageDDR_list; UINT m_nDownDatarate; UINT m_nDownDataRateMS; - UINT m_nSumForAvgDownDataRate; - CList m_AverageDDR_list; + uint64 m_nSumForAvgDownDataRate; ////////////////////////////////////////////////////////// // GUI helpers @@ -657,10 +647,11 @@ class CUpDownClient : public CObject static CBarShader s_StatusBar; static CBarShader s_UpStatusBar; CTypedPtrList m_PendingBlocks_list; - CMap m_fileReaskTimes; // ZZ:DownloadManager (one re-ask timestamp for each file) + typedef CMap CFileReaskTimesMap; + CFileReaskTimesMap m_fileReaskTimes; // ZZ:DownloadManager (one re-ask timestamp for each file) DWORD m_lastRefreshedDLDisplay; DWORD m_lastRefreshedULDisplay; - uint32 m_random_update_wait; + DWORD m_random_update_wait; // using bit fields for less important flags, to save some bytes UINT m_fHashsetRequestingMD4 : 1, // we have sent a hashset request to this client in the current connection diff --git a/srchybrid/UploadBandwidthThrottler.cpp b/srchybrid/UploadBandwidthThrottler.cpp index 8d5f9c9d..d8225c13 100644 --- a/srchybrid/UploadBandwidthThrottler.cpp +++ b/srchybrid/UploadBandwidthThrottler.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -38,15 +38,13 @@ static char THIS_FILE[] = __FILE__; * The constructor starts the thread. */ UploadBandwidthThrottler::UploadBandwidthThrottler() + : m_eventThreadEnded(FALSE, TRUE) + , m_eventPaused(TRUE, TRUE) + , m_SentBytesSinceLastCall() + , m_SentBytesSinceLastCallOverhead() + , m_highestNumberOfFullyActivatedSlots() + , m_bRun(true) { - m_SentBytesSinceLastCall = 0; - m_SentBytesSinceLastCallOverhead = 0; - m_highestNumberOfFullyActivatedSlots = 0; - - threadEndedEvent = new CEvent(FALSE, TRUE); - pauseEvent = new CEvent(TRUE, TRUE); - - doRun = true; AfxBeginThread(RunProc, (LPVOID)this); } @@ -56,8 +54,6 @@ UploadBandwidthThrottler::UploadBandwidthThrottler() UploadBandwidthThrottler::~UploadBandwidthThrottler() { EndThread(); - delete threadEndedEvent; - delete pauseEvent; } /** @@ -119,20 +115,20 @@ INT_PTR UploadBandwidthThrottler::GetHighestNumberOfFullyActivatedSlotsSinceLast } /** - * Add a socket to the list of sockets that have upload slots. The main thread will + * Add a socket to the list of sockets with an upload slot. The main thread will * continuously call send on these sockets, to give them chance to work off their queues. * The sockets are called in the order they exist in the list, so the top socket (index 0) - * will be given a chance first to use bandwidth, and then the next socket (index 1) etc. + * will be given a chance to use bandwidth first, then the next socket (index 1) etc. * * It is possible to add a socket several times to the list without removing it in between, * but that should be avoided. * - * @param index insert the socket at this place in the list. An index that is higher than the - * current number of sockets in the list will mean that the socket should be inserted - * last in the list. + * @param index insert the socket at this place in the list. An index that is higher than the + * current number of sockets in the list will mean that the socket should be added + * last to the list. * - * @param socket the address to the socket that should be added to the list. If the address is NULL, - * this method will do nothing. + * @param socket the address of the socket that should be inserted into the list. If the address + * is NULL, this method will do nothing. */ void UploadBandwidthThrottler::AddToStandardList(INT_PTR index, ThrottledFileSocket *socket) { @@ -197,29 +193,28 @@ bool UploadBandwidthThrottler::RemoveFromStandardListNoLock(ThrottledFileSocket /** * Notifies the send thread that it should try to call controlpacket send -* for the supplied socket. It is allowed to call this method several times +* for the given socket. It is allowed to call this method several times * for the same socket, without having controlpacket send called for the socket -* first. The duplicate entries are never filtered, since it incurs less cpu +* first. The duplicate entries are never filtered, since it incurs less CPU * overhead to simply call Send() in the socket for each double. Send() will * already have done its work when the second Send() is called, and will just -* return with little cpu overhead. +* return with little CPU overhead. * * @param socket address to the socket that requests to have controlpacket send * to be called on it */ void UploadBandwidthThrottler::QueueForSendingControlPacket(ThrottledControlSocket *socket, const bool hasSent) { - // Get critical section - tempQueueLocker.Lock(); + if (m_bRun) { + tempQueueLocker.Lock(); // Get critical section - if (doRun) if (hasSent) m_TempControlQueueFirst_list.AddTail(socket); else m_TempControlQueue_list.AddTail(socket); - // End critical section - tempQueueLocker.Unlock(); + tempQueueLocker.Unlock(); // End critical section + } } /** @@ -231,7 +226,7 @@ void UploadBandwidthThrottler::QueueForSendingControlPacket(ThrottledControlSock */ void UploadBandwidthThrottler::RemoveFromAllQueuesNoLock(ThrottledControlSocket *socket) { - if (doRun) { + if (m_bRun) { // Remove this socket from control packet queue for (POSITION pos = m_ControlQueue_list.GetHeadPosition(); pos != NULL;) { POSITION todel = pos; @@ -260,18 +255,16 @@ void UploadBandwidthThrottler::RemoveFromAllQueuesNoLock(ThrottledControlSocket void UploadBandwidthThrottler::RemoveFromAllQueues(ThrottledFileSocket *socket) { - // Get critical section - sendLocker.Lock(); + if (m_bRun) { + sendLocker.Lock(); // Get critical section - if (doRun) { RemoveFromAllQueuesNoLock(socket); // And remove it from upload slots RemoveFromStandardListNoLock(socket); - } - // End critical section - sendLocker.Unlock(); + sendLocker.Unlock(); // End critical section + } } void UploadBandwidthThrottler::RemoveFromAllQueuesLocked(ThrottledControlSocket *socket) @@ -288,25 +281,23 @@ void UploadBandwidthThrottler::RemoveFromAllQueuesLocked(ThrottledControlSocket */ void UploadBandwidthThrottler::EndThread() { - sendLocker.Lock(); + //the flag is never checked in the thread loop, no need to get locks // signal the thread to stop looping and exit. - doRun = false; - - sendLocker.Unlock(); + m_bRun = false; Pause(false); // wait for the thread to signal that it has stopped looping. - threadEndedEvent->Lock(); + m_eventThreadEnded.Lock(); } void UploadBandwidthThrottler::Pause(bool paused) { if (paused) - pauseEvent->ResetEvent(); + m_eventPaused.ResetEvent(); else - pauseEvent->SetEvent(); + m_eventPaused.SetEvent(); } uint32 UploadBandwidthThrottler::GetSlotLimit(uint32 currentUpSpeed) @@ -369,7 +360,7 @@ UINT UploadBandwidthThrottler::RunInternal() sint64 realBytesToSpend = 0; INT_PTR rememberedSlotCounter = 0; - uint32 nEstiminatedLimit = 0; + uint32 nEstiminatedDataRate = 0; int nSlotsBusyLevel = 0; DWORD nUploadStartTime = 0; uint32 numberOfConsecutiveUpChanges = 0; @@ -377,32 +368,35 @@ UINT UploadBandwidthThrottler::RunInternal() uint32 changesCount = 0; uint32 loopsCount = 0; - DWORD lastLoopTick = timeGetTime(); - DWORD lastTickReachedBandwidth = lastLoopTick; - while (doRun) { - pauseEvent->Lock(); + DWORD lastLoopTick, lastTickReachedBandwidth; + lastTickReachedBandwidth = lastLoopTick = timeGetTime(); + while (m_bRun) { + m_eventPaused.Lock(); DWORD timeSinceLastLoop = timeGetTime() - lastLoopTick; - // Get current speed from UploadSpeedSense + // Get the current speed from UploadSpeedSense uint32 allowedDataRate = theApp.lastCommonRouteFinder->GetUpload(); // check busy level for all the slots (WSAEWOULDBLOCK status) uint32 nBusy = 0; uint32 nCanSend = 0; sendLocker.Lock(); - m_eventNewDataAvailable.ResetEvent(); + m_eventDataAvailable.ResetEvent(); m_eventSocketAvailable.ResetEvent(); - for (INT_PTR i = mini(GetStandardListSize(), (INT_PTR)max(GetSlotLimit(theApp.uploadqueue->GetDatarate()), 3u)); --i >= 0;) - if (m_StandardOrder_list[i] != NULL && m_StandardOrder_list[i]->HasQueues()) { + for (INT_PTR i = mini(GetStandardListSize(), (INT_PTR)max(GetSlotLimit(theApp.uploadqueue->GetDatarate()), 3u)); --i >= 0;) { + ThrottledFileSocket *pSocket = m_StandardOrder_list[i]; + if (pSocket != NULL && pSocket->HasQueues()) { ++nCanSend; - nBusy += static_cast(m_StandardOrder_list[i]->IsBusyExtensiveCheck()); + nBusy += static_cast(pSocket->IsBusyExtensiveCheck()); } + } sendLocker.Unlock(); - // if this is kept, the loop above can be optimized a little (don't count nCanSend, just use nCanSend = GetSlotLimit(theApp.uploadqueue->GetDatarate()) - //if(theApp.uploadqueue) + // if this is kept, the loop above can be optimized a little (don't count nCanSend, + // just use nCanSend = GetSlotLimit(theApp.uploadqueue->GetDatarate()) + //if (theApp.uploadqueue) // nCanSend = max(nCanSend, GetSlotLimit(theApp.uploadqueue->GetDatarate())); // When no upload limit has been set in options, try to guess a good upload limit. @@ -412,125 +406,118 @@ UINT UploadBandwidthThrottler::RunInternal() // theApp.QueueDebugLogLine(false,_T("Throttler: busy: %i/%i nSlotsBusyLevel: %i Guessed limit: %0.5f changesCount: %i loopsCount: %i"), nBusy, nCanSend, nSlotsBusyLevel, nEstiminatedLimit/1024.0f, changesCount, loopsCount); if (nCanSend > 0) { //float fBusyFraction = nBusy / (float)nCanSend; - //conditions were: "fBusyFraction > 0.75f" and "fBusyFraction < 0.25f" - const int iBusyFraction = (nBusy << 5)/ nCanSend; //the limits would be 24 and 8 + //the limits were: "fBusyFraction > 0.75f" and "fBusyFraction < 0.25f" + const int iBusyFraction = (nBusy << 5) / nCanSend; //now the limits will be 24 and 8 if (nBusy > 2 && iBusyFraction > 24 && nSlotsBusyLevel < 255) { ++nSlotsBusyLevel; ++changesCount; if (thePrefs.GetVerbose() && lotsOfLog && nSlotsBusyLevel % 25 == 0) - theApp.QueueDebugLogLine(false, _T("Throttler: nSlotsBusyLevel: %i Guessed limit: %0.5f changesCount: %i loopsCount: %i"), nSlotsBusyLevel, nEstiminatedLimit / 1024.0f, changesCount, loopsCount); + theApp.QueueDebugLogLine(false, _T("Throttler: nSlotsBusyLevel: %i Guessed limit: %0.5f changesCount: %i loopsCount: %i"), nSlotsBusyLevel, nEstiminatedDataRate / 1024.0f, changesCount, loopsCount); } else if ((nBusy <= 2 || iBusyFraction < 8) && nSlotsBusyLevel > -255) { --nSlotsBusyLevel; ++changesCount; if (thePrefs.GetVerbose() && lotsOfLog && nSlotsBusyLevel % 25 == 0) - theApp.QueueDebugLogLine(false, _T("Throttler: nSlotsBusyLevel: %i Guessed limit: %0.5f changesCount %i loopsCount: %i"), nSlotsBusyLevel, nEstiminatedLimit / 1024.0f, changesCount, loopsCount); + theApp.QueueDebugLogLine(false, _T("Throttler: nSlotsBusyLevel: %i Guessed limit: %0.5f changesCount %i loopsCount: %i"), nSlotsBusyLevel, nEstiminatedDataRate / 1024.0f, changesCount, loopsCount); } } if (nUploadStartTime == 0) { if (GetStandardListSize() >= 3) nUploadStartTime = timeGetTime(); - } else if (timeGetTime() >= nUploadStartTime + SEC2MS(60)) { - if (theApp.uploadqueue) { - if (nEstiminatedLimit == 0) { // no autolimit was set yet - if (nSlotsBusyLevel >= 250) { // sockets indicated that the BW limit has been reached - nEstiminatedLimit = theApp.uploadqueue->GetDatarate(); - if (nEstiminatedLimit < allowedDataRate) - allowedDataRate = nEstiminatedLimit; - nSlotsBusyLevel = -200; - if (thePrefs.GetVerbose() && estimateChangedLog) - theApp.QueueDebugLogLine(false, _T("Throttler: Set initial estimated limit to %0.5f changesCount: %i loopsCount: %i"), nEstiminatedLimit / 1024.0f, changesCount, loopsCount); - changesCount = 0; - loopsCount = 0; - } - } else { - if (nSlotsBusyLevel > 250) { - if (changesCount > 500 || (changesCount > 300 && loopsCount > 1000) || loopsCount > 2000) - numberOfConsecutiveDownChanges = 0; - - ++numberOfConsecutiveDownChanges; - uint32 changeDelta = CalculateChangeDelta(numberOfConsecutiveDownChanges); - - // Don't lower speed below 1 KiB/s - if (nEstiminatedLimit < changeDelta + 1024) - changeDelta = (nEstiminatedLimit > 1024) ? nEstiminatedLimit - 1024 : 0; - - ASSERT(nEstiminatedLimit >= changeDelta + 1024); - nEstiminatedLimit -= changeDelta; - - if (thePrefs.GetVerbose() && estimateChangedLog) - theApp.QueueDebugLogLine(false, _T("Throttler: REDUCED limit #%i with %i bytes to: %0.5f changesCount: %i loopsCount: %i"), numberOfConsecutiveDownChanges, changeDelta, nEstiminatedLimit / 1024.0f, changesCount, loopsCount); - - numberOfConsecutiveUpChanges = 0; - nSlotsBusyLevel = 0; - changesCount = 0; - loopsCount = 0; - } else if (nSlotsBusyLevel < -250) { - if (changesCount > 500 || (changesCount > 300 && loopsCount > 1000) || loopsCount > 2000) - numberOfConsecutiveUpChanges = 0; - - ++numberOfConsecutiveUpChanges; - uint32 changeDelta = CalculateChangeDelta(numberOfConsecutiveUpChanges); - - // Don't raise speed unless we are under current allowedDataRate - if (nEstiminatedLimit + changeDelta > allowedDataRate) - changeDelta = (nEstiminatedLimit < allowedDataRate) ? allowedDataRate - nEstiminatedLimit : 0; - - ASSERT(nEstiminatedLimit < allowedDataRate && nEstiminatedLimit + changeDelta <= allowedDataRate || nEstiminatedLimit >= allowedDataRate && changeDelta == 0); - nEstiminatedLimit += changeDelta; - - if (thePrefs.GetVerbose() && estimateChangedLog) - theApp.QueueDebugLogLine(false, _T("Throttler: INCREASED limit #%i with %i bytes to: %0.5f changesCount: %i loopsCount: %i"), numberOfConsecutiveUpChanges, changeDelta, nEstiminatedLimit / 1024.0f, changesCount, loopsCount); + } else if (timeGetTime() >= nUploadStartTime + SEC2MS(60) && theApp.uploadqueue) { + if (nEstiminatedDataRate == 0) { // no auto limit was set yet + if (nSlotsBusyLevel >= 250) { // sockets indicated that the BW limit has been reached + nEstiminatedDataRate = theApp.uploadqueue->GetDatarate(); + nSlotsBusyLevel = -200; + if (thePrefs.GetVerbose() && estimateChangedLog) + theApp.QueueDebugLogLine(false, _T("Throttler: Set initial estimated limit to %0.5f changesCount: %i loopsCount: %i"), nEstiminatedDataRate / 1024.0f, changesCount, loopsCount); + changesCount = 0; + loopsCount = 0; + } + } else if (nSlotsBusyLevel > 250) { + if (changesCount > 500 || (changesCount > 300 && loopsCount > 1000) || loopsCount > 2000) + numberOfConsecutiveDownChanges = 0; + else + ++numberOfConsecutiveDownChanges; + uint32 changeDelta = CalculateChangeDelta(numberOfConsecutiveDownChanges); + + // Don't lower speed below 1 KiB/s + if (nEstiminatedDataRate < changeDelta + 1024) + changeDelta = (nEstiminatedDataRate > 1024) ? nEstiminatedDataRate - 1024 : 0; + + ASSERT(nEstiminatedDataRate >= changeDelta + 1024); + nEstiminatedDataRate -= changeDelta; + + if (thePrefs.GetVerbose() && estimateChangedLog) + theApp.QueueDebugLogLine(false, _T("Throttler: REDUCED limit #%i with %i bytes to: %0.5f changesCount: %i loopsCount: %i"), numberOfConsecutiveDownChanges, changeDelta, nEstiminatedDataRate / 1024.0f, changesCount, loopsCount); + + numberOfConsecutiveUpChanges = 0; + nSlotsBusyLevel = 0; + changesCount = 0; + loopsCount = 0; + } else if (nSlotsBusyLevel < -250) { + if (changesCount > 500 || (changesCount > 300 && loopsCount > 1000) || loopsCount > 2000) + numberOfConsecutiveUpChanges = 0; + else + ++numberOfConsecutiveUpChanges; + uint32 changeDelta = CalculateChangeDelta(numberOfConsecutiveUpChanges); + nEstiminatedDataRate += changeDelta; + // Don't raise speed unless we are under current allowedDataRate + if (nEstiminatedDataRate > allowedDataRate) { + if (estimateChangedLog) + changeDelta = nEstiminatedDataRate - allowedDataRate; //for logs only + nEstiminatedDataRate = allowedDataRate; + } - numberOfConsecutiveDownChanges = 0; - nSlotsBusyLevel = 0; - changesCount = 0; - loopsCount = 0; - } + if (thePrefs.GetVerbose() && estimateChangedLog) + theApp.QueueDebugLogLine(false, _T("Throttler: INCREASED limit #%i with %i bytes to: %0.5f changesCount: %i loopsCount: %i"), numberOfConsecutiveUpChanges, changeDelta, nEstiminatedDataRate / 1024.0f, changesCount, loopsCount); - if (nEstiminatedLimit < allowedDataRate) - allowedDataRate = nEstiminatedLimit; - } + numberOfConsecutiveDownChanges = 0; + nSlotsBusyLevel = 0; + changesCount = 0; + loopsCount = 0; } + + if (allowedDataRate > nEstiminatedDataRate) + allowedDataRate = nEstiminatedDataRate; } if (nCanSend == nBusy && GetStandardListSize() > 0 && nSlotsBusyLevel < 125) { nSlotsBusyLevel = 125; if (thePrefs.GetVerbose() && lotsOfLog) - theApp.QueueDebugLogLine(false, _T("Throttler: nSlotsBusyLevel: %i Guessed limit: %0.5f changesCount %i loopsCount: %i (set due to all slots busy)"), nSlotsBusyLevel, nEstiminatedLimit / 1024.0f, changesCount, loopsCount); + theApp.QueueDebugLogLine(false, _T("Throttler: nSlotsBusyLevel: %i Guessed limit: %0.5f changesCount %i loopsCount: %i (set due to all slots busy)"), nSlotsBusyLevel, nEstiminatedDataRate / 1024.0f, changesCount, loopsCount); } } uint32 minFragSize; uint32 doubleSendSize; - if (allowedDataRate < 6 * 1024) { - minFragSize = 536; - doubleSendSize = minFragSize; // don't send two packets at a time at very low speeds to give a smoother upload - } else { + if (allowedDataRate < 6 * 1024) + doubleSendSize = minFragSize = 536; // send one packet at a time at very low speeds for a smoother upload + else { minFragSize = 1300; doubleSendSize = minFragSize * 2; // send two packets at a time so they can share an ACK } #define TIME_BETWEEN_UPLOAD_LOOPS 1 DWORD sleepTime; - if (allowedDataRate == _UI32_MAX || realBytesToSpend >= 1000 || (allowedDataRate == 0 && nEstiminatedLimit == 0)) - // we could send at once, but sleep a while to not suck up all cpu + if (allowedDataRate == _UI32_MAX || realBytesToSpend >= 1000 || (allowedDataRate == 0 && nEstiminatedDataRate == 0)) + // we could send at once, but sleep a while to not suck up all CPU sleepTime = TIME_BETWEEN_UPLOAD_LOOPS; else { if (allowedDataRate == 0) - sleepTime = (DWORD)ceil((doubleSendSize * 1000.0) / nEstiminatedLimit); + sleepTime = (DWORD)ceil((doubleSendSize * 1000) / (double)nEstiminatedDataRate); else // sleep for just as long as we need to get back to having one byte to send - sleepTime = (DWORD)ceil((1000.0 - realBytesToSpend) / allowedDataRate); + sleepTime = (DWORD)ceil((1000 - realBytesToSpend) / (double)allowedDataRate); if (sleepTime < TIME_BETWEEN_UPLOAD_LOOPS) sleepTime = TIME_BETWEEN_UPLOAD_LOOPS; } if (timeSinceLastLoop < sleepTime) { DWORD dwSleep = sleepTime - timeSinceLastLoop; if (nCanSend == 0) { - if (theApp.m_pUploadDiskIOThread != NULL) - theApp.m_pUploadDiskIOThread->SocketNeedsMoreData(); - ::WaitForSingleObject(m_eventNewDataAvailable, dwSleep); + if (theApp.uploadqueue->GetUploadQueueLength() > 0 && theApp.m_pUploadDiskIOThread) + theApp.m_pUploadDiskIOThread->WakeUpCall(); + ::WaitForSingleObject(m_eventDataAvailable, dwSleep); } else if (nCanSend == nBusy) ::WaitForSingleObject(m_eventSocketAvailable, dwSleep); else @@ -549,12 +536,12 @@ UINT UploadBandwidthThrottler::RunInternal() bytesToSpend = realBytesToSpend / SEC2MS(1); } else if (_I64_MAX / timeSinceLastLoop > (sint64)allowedDataRate && _I64_MAX - allowedDataRate * (sint64)timeSinceLastLoop > realBytesToSpend) { if (timeSinceLastLoop >= sleepTime + SEC2MS(2)) { - theApp.QueueDebugLogLine(false, _T("UploadBandwidthThrottler: Time since last loop too long. time: %ims wanted: %ims Max: %ims"), timeSinceLastLoop, sleepTime, sleepTime + 2000); + theApp.QueueDebugLogLine(false, _T("UploadBandwidthThrottler: Time since last loop too long. time: %ims wanted: %ims Max: %ims"), timeSinceLastLoop, sleepTime, sleepTime + SEC2MS(2)); timeSinceLastLoop = sleepTime + SEC2MS(2); } - realBytesToSpend += allowedDataRate * (uint64)timeSinceLastLoop; + realBytesToSpend += allowedDataRate * (sint64)timeSinceLastLoop; bytesToSpend = realBytesToSpend / SEC2MS(1); } else { realBytesToSpend = _I64_MAX; @@ -586,16 +573,18 @@ UINT UploadBandwidthThrottler::RunInternal() uint64 spentOverhead = 0; bool bNeedMoreData = false; // Send any queued up control packets first - while ((bytesToSpend > 0 && spentBytes < (uint64)bytesToSpend || allowedDataRate == 0 && spentBytes < 500) && (!m_ControlQueueFirst_list.IsEmpty() || !m_ControlQueue_list.IsEmpty())) { + while ((bytesToSpend > 0 && spentBytes < (uint64)bytesToSpend || allowedDataRate == 0 && spentBytes < 500) + && (!m_ControlQueueFirst_list.IsEmpty() || !m_ControlQueue_list.IsEmpty())) + { ThrottledControlSocket *socket; if (!m_ControlQueueFirst_list.IsEmpty()) socket = m_ControlQueueFirst_list.RemoveHead(); - else { - if (m_ControlQueue_list.IsEmpty()) - break; + else if (!m_ControlQueue_list.IsEmpty()) socket = m_ControlQueue_list.RemoveHead(); - } + else + break; + if (socket != NULL) { SocketSentBytes socketSentBytes = socket->SendControlData(allowedDataRate > 0 ? (uint32)(bytesToSpend - spentBytes) : 1u, minFragSize); spentBytes += socketSentBytes.sentBytesStandardPackets; @@ -630,9 +619,7 @@ UINT UploadBandwidthThrottler::RunInternal() // Equal bandwidth for all slots uint32 targetDataRate = theApp.uploadqueue->GetTargetClientDataRate(true); - INT_PTR maxSlot = GetStandardListSize(); - if (maxSlot > (INT_PTR)(allowedDataRate / targetDataRate)) - maxSlot = allowedDataRate / targetDataRate; + INT_PTR maxSlot = min(GetStandardListSize(), (INT_PTR)(allowedDataRate / targetDataRate)); if (maxSlot > m_highestNumberOfFullyActivatedSlots) m_highestNumberOfFullyActivatedSlots = maxSlot; @@ -645,11 +632,13 @@ UINT UploadBandwidthThrottler::RunInternal() if (socket != NULL) { if (!socket->IsBusyQuickCheck()) { SocketSentBytes socketSentBytes = socket->SendFileAndControlData(mini(max((uint32)doubleSendSize, (uint32)(bytesToSpend / maxSlot)), (uint32)(bytesToSpend - spentBytes)), doubleSendSize); - spentBytes += socketSentBytes.sentBytesStandardPackets; + if (socketSentBytes.sentBytesStandardPackets > 0) { + spentBytes += socketSentBytes.sentBytesStandardPackets; + if (!socket->IsEnoughFileDataQueued(EMBLOCKSIZE)) + bNeedMoreData = true; + } spentBytes += socketSentBytes.sentBytesControlPackets; spentOverhead += socketSentBytes.sentBytesControlPackets; - if (socketSentBytes.sentBytesStandardPackets > 0 && !socket->IsEnoughFileDataQueued(EMBLOCKSIZE)) - bNeedMoreData = true; } } else theApp.QueueDebugLogLine(false, _T("There was a NULL socket in the UploadBandwidthThrottler Standard list (equal-for-all)! Prevented usage. Index: %u Size: %u"), (unsigned)rememberedSlotCounter, (unsigned)GetStandardListSize()); @@ -657,7 +646,7 @@ UINT UploadBandwidthThrottler::RunInternal() ++rememberedSlotCounter; } - // Any bandwidth that hasn't been used yet are used first to last. + // Any bandwidth that hasn't been used yet is used first to last. for (INT_PTR slotCounter = 0; slotCounter < GetStandardListSize() && bytesToSpend > 0 && spentBytes < (uint64)bytesToSpend; ++slotCounter) { ThrottledFileSocket *socket = m_StandardOrder_list[slotCounter]; @@ -671,7 +660,7 @@ UINT UploadBandwidthThrottler::RunInternal() if (socketSentBytes.sentBytesStandardPackets > 0 && !socket->IsEnoughFileDataQueued(EMBLOCKSIZE)) bNeedMoreData = true; - if (slotCounter + 1 > m_highestNumberOfFullyActivatedSlots && (lastSpentBytes < bytesToSpendTemp || lastSpentBytes >= doubleSendSize)) // || lastSpentBytes > 0 && spentBytes == bytesToSpend )) + if (slotCounter >= m_highestNumberOfFullyActivatedSlots && (lastSpentBytes < bytesToSpendTemp || lastSpentBytes >= doubleSendSize)) // || lastSpentBytes > 0 && spentBytes == bytesToSpend )) m_highestNumberOfFullyActivatedSlots = slotCounter + 1; } } else @@ -681,21 +670,19 @@ UINT UploadBandwidthThrottler::RunInternal() // If we couldn't spend all allocated bandwidth this loop, some of it is allowed to be saved // and used the next loop - sint64 newRealBytesToSpend = -(((sint64)GetStandardListSize() + 1) * minFragSize) * 1000; + sint64 newRealBytesToSpend = -((sint64)GetStandardListSize() + 1) * minFragSize * SEC2MS(1); if (realBytesToSpend < newRealBytesToSpend) { realBytesToSpend = newRealBytesToSpend; lastTickReachedBandwidth = thisLoopTick; - } else { - if (realBytesToSpend > 999) { - realBytesToSpend = 999; - if (thisLoopTick - lastTickReachedBandwidth > max(500, timeSinceLastLoop) * 2) { - m_highestNumberOfFullyActivatedSlots = GetStandardListSize() + 1; - lastTickReachedBandwidth = thisLoopTick; - //theApp.QueueDebugLogLine(false, _T("UploadBandwidthThrottler: Throttler requests new slot due to bw not reached. m_highestNumberOfFullyActivatedSlots: %i GetStandardListSize(): %i tick: %i"), m_highestNumberOfFullyActivatedSlots, GetStandardListSize(), thisLoopTick); - } - } else + } else if (realBytesToSpend > 999) { + realBytesToSpend = 999; + if (thisLoopTick >= lastTickReachedBandwidth + max(500, timeSinceLastLoop) * 2) { + m_highestNumberOfFullyActivatedSlots = GetStandardListSize() + 1; lastTickReachedBandwidth = thisLoopTick; - } + //theApp.QueueDebugLogLine(false, _T("UploadBandwidthThrottler: Throttler requests new slot due to bw not reached. m_highestNumberOfFullyActivatedSlots: %i GetStandardListSize(): %i tick: %i"), m_highestNumberOfFullyActivatedSlots, GetStandardListSize(), thisLoopTick); + } + } else + lastTickReachedBandwidth = thisLoopTick; // save info about how much bandwidth we've managed to use since the last time someone polled us about used bandwidth m_SentBytesSinceLastCall += spentBytes; @@ -703,34 +690,33 @@ UINT UploadBandwidthThrottler::RunInternal() sendLocker.Unlock(); - if (bNeedMoreData && theApp.m_pUploadDiskIOThread != NULL) - theApp.m_pUploadDiskIOThread->SocketNeedsMoreData(); + if (bNeedMoreData && theApp.uploadqueue->GetUploadQueueLength() > 0 && theApp.m_pUploadDiskIOThread) + theApp.m_pUploadDiskIOThread->WakeUpCall(); } } - threadEndedEvent->SetEvent(); - + sendLocker.Lock(); tempQueueLocker.Lock(); m_TempControlQueue_list.RemoveAll(); m_TempControlQueueFirst_list.RemoveAll(); tempQueueLocker.Unlock(); - sendLocker.Lock(); m_ControlQueue_list.RemoveAll(); m_StandardOrder_list.RemoveAll(); sendLocker.Unlock(); + m_eventThreadEnded.SetEvent(); return 0; } void UploadBandwidthThrottler::NewUploadDataAvailable() { - if (doRun) - m_eventNewDataAvailable.SetEvent(); + if (m_bRun) + m_eventDataAvailable.SetEvent(); } void UploadBandwidthThrottler::SocketAvailable() { - if (doRun) + if (m_bRun) m_eventSocketAvailable.SetEvent(); } \ No newline at end of file diff --git a/srchybrid/UploadBandwidthThrottler.h b/srchybrid/UploadBandwidthThrottler.h index 5a2f54ca..e10b55f0 100644 --- a/srchybrid/UploadBandwidthThrottler.h +++ b/srchybrid/UploadBandwidthThrottler.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -66,14 +66,14 @@ class UploadBandwidthThrottler : CCriticalSection sendLocker; CCriticalSection tempQueueLocker; - CEvent *threadEndedEvent; - CEvent *pauseEvent; - CEvent m_eventNewDataAvailable; + CEvent m_eventThreadEnded; + CEvent m_eventPaused; + CEvent m_eventDataAvailable; CEvent m_eventSocketAvailable; uint64 m_SentBytesSinceLastCall; uint64 m_SentBytesSinceLastCallOverhead; INT_PTR m_highestNumberOfFullyActivatedSlots; - volatile bool doRun; + volatile bool m_bRun; }; \ No newline at end of file diff --git a/srchybrid/UploadClient.cpp b/srchybrid/UploadClient.cpp index 0d98575e..7bb5330d 100644 --- a/srchybrid/UploadClient.cpp +++ b/srchybrid/UploadClient.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -31,7 +31,6 @@ #include "ListenSocket.h" #include "PeerCacheSocket.h" #include "ServerConnect.h" -#include "OtherFunctions.h" #include "SafeFile.h" #include "DownloadQueue.h" #include "emuledlg.h" @@ -54,24 +53,21 @@ CBarShader CUpDownClient::s_UpStatusBar(16); void CUpDownClient::DrawUpStatusBar(CDC *dc, const CRect &rect, bool onlygreyrect, bool bFlat) const { - COLORREF crNeither; - COLORREF crNextSending; - COLORREF crBoth; - COLORREF crSending; + COLORREF crNeither, crNextSending, crBoth, crSending; if (GetSlotNumber() <= (UINT)theApp.uploadqueue->GetActiveUploadsCount() || (GetUploadState() != US_UPLOADING && GetUploadState() != US_CONNECTING)) { - crNeither = RGB(224, 224, 224); - crNextSending = RGB(255, 208, 0); - crBoth = bFlat ? RGB(0, 0, 0) : RGB(104, 104, 104); - crSending = RGB(0, 150, 0); + crNeither = RGB(224, 224, 224); //light grey + crNextSending = RGB(255, 208, 0); //dark yellow + crBoth = bFlat ? RGB(0, 0, 0) : RGB(104, 104, 104); //black : very dark gray + crSending = RGB(0, 150, 0); //dark green } else { // grayed out - crNeither = RGB(248, 248, 248); - crNextSending = RGB(255, 244, 191); - crBoth = /*bFlat ? RGB(191, 191, 191) :*/ RGB(191, 191, 191); - crSending = RGB(191, 229, 191); + crNeither = RGB(248, 248, 248); //very light grey + crNextSending = RGB(255, 244, 191); //pale yellow + crBoth = /*bFlat ? RGB(191, 191, 191) :*/ RGB(191, 191, 191); //mid-grey + crSending = RGB(191, 229, 191); //pale green } // wistily: UpStatusFix @@ -90,7 +86,7 @@ void CUpDownClient::DrawUpStatusBar(CDC *dc, const CRect &rect, bool onlygreyrec s_UpStatusBar.FillRange(i * PARTSIZE, i * PARTSIZE + PARTSIZE, crBoth); UploadingToClient_Struct *pUpClientStruct = theApp.uploadqueue->GetUploadingClientStructByClient(this); -// ASSERT( pUpClientStruct != NULL || theApp.uploadqueue->IsOnUploadQueue((CUpDownClient*)this) != NULL); + //ASSERT(pUpClientStruct != NULL || theApp.uploadqueue->IsOnUploadQueue((CUpDownClient*)this) != NULL); if (pUpClientStruct != NULL) { CSingleLock lockBlockLists(&pUpClientStruct->m_csBlockListsLock, TRUE); ASSERT(lockBlockLists.IsLocked()); @@ -98,15 +94,15 @@ void CUpDownClient::DrawUpStatusBar(CDC *dc, const CRect &rect, bool onlygreyrec if (!pUpClientStruct->m_BlockRequests_queue.IsEmpty()) { block = pUpClientStruct->m_BlockRequests_queue.GetHead(); if (block) { - uint32 start = (uint32)(block->StartOffset / PARTSIZE); - s_UpStatusBar.FillRange(start * PARTSIZE, start * PARTSIZE + PARTSIZE, crNextSending); + uint64 start = (block->StartOffset / PARTSIZE) * PARTSIZE; + s_UpStatusBar.FillRange(start, start + PARTSIZE, crNextSending); } } if (!pUpClientStruct->m_DoneBlocks_list.IsEmpty()) { block = pUpClientStruct->m_DoneBlocks_list.GetHead(); if (block) { - uint32 start = (uint32)(block->StartOffset / PARTSIZE); - s_UpStatusBar.FillRange(start * PARTSIZE, start * PARTSIZE + PARTSIZE, crNextSending); + uint64 start = (block->StartOffset / PARTSIZE) * PARTSIZE; + s_UpStatusBar.FillRange(start, start + PARTSIZE, crNextSending); } for (POSITION pos = pUpClientStruct->m_DoneBlocks_list.GetHeadPosition();pos != 0;) { block = pUpClientStruct->m_DoneBlocks_list.GetNext(pos); @@ -137,13 +133,13 @@ void CUpDownClient::SetUploadState(EUploadState eNewState) } } -/** +/* * Gets the queue score multiplier for this client, taking into consideration client's credits * and the requested file's priority. */ float CUpDownClient::GetCombinedFilePrioAndCredit() { - if (credits == 0) { + if (!credits) { ASSERT(IsKindOf(RUNTIME_CLASS(CUrlClient))); return 0.0F; } @@ -151,7 +147,7 @@ float CUpDownClient::GetCombinedFilePrioAndCredit() return 10.0f * credits->GetScoreRatio(GetIP()) * GetFilePrioAsNumber(); } -/** +/* * Gets the file multiplier for the file this client has requested. */ int CUpDownClient::GetFilePrioAsNumber() const @@ -164,31 +160,25 @@ int CUpDownClient::GetFilePrioAsNumber() const // sometimes a client asks for 2 files and there is no way to decide, which file the // client finally gets. so it could happen that he is queued first because of a // high prio file, but then asks for something completely different. - int filepriority = 10; // standard switch (currequpfile->GetUpPriority()) { case PR_VERYHIGH: - filepriority = 18; - break; + return 18; case PR_HIGH: - filepriority = 9; - break; + return 9; case PR_LOW: - filepriority = 6; - break; + return 6; case PR_VERYLOW: - filepriority = 2; - break; - case PR_NORMAL: - default: - filepriority = 7; - break; + return 2; + //case PR_NORMAL: + //default: + // break; } - return filepriority; + return 7; } -/** - * Gets the current waiting score for this client, taking into consideration waiting - * time, priority of requested file, and the client's credits. +/* + * Gets the current waiting score for this client, taking into consideration + * waiting time, priority of requested file, and the client's credits. */ uint32 CUpDownClient::GetScore(bool sysvalue, bool isdownloading, bool onlybasevalue) const { @@ -216,30 +206,27 @@ uint32 CUpDownClient::GetScore(bool sysvalue, bool isdownloading, bool onlybasev if (sysvalue && HasLowID() && !(socket && socket->IsConnected())) return 0; - int filepriority = GetFilePrioAsNumber(); - - // calculate score, based on waitingtime and other factors - float fBaseValue; + // calculate score, based on waiting time and other factors + DWORD dwBaseValue; if (onlybasevalue) - fBaseValue = 100; + dwBaseValue = SEC2MS(100); else if (!isdownloading) - fBaseValue = (::GetTickCount() - GetWaitStartTime()) / SEC2MS(1.0f); + dwBaseValue = ::GetTickCount() - GetWaitStartTime(); else { // we don't want one client to download forever - // the first 15 min download time counts as 15 min waiting time and you get a 15 min bonus - // while you are in the first 15 min :) - // (to avoid 20 sec downloads) after this the score won't raise any more - fBaseValue = (float)(m_dwUploadTime - GetWaitStartTime()); - //ASSERT ( m_dwUploadTime-GetWaitStartTime() >= 0 ); //oct 28, 02: changed this from "> 0" to ">= 0" -> // 02-Okt-2006 []: ">=0" is always true! - fBaseValue += MIN2MS(::GetTickCount() >= m_dwUploadTime + MIN2MS(15) ? 15.0f : 30.0f); - fBaseValue /= SEC2MS(1); - } - if (thePrefs.UseCreditSystem()) { - float modif = credits->GetScoreRatio(GetIP()); - fBaseValue *= modif; + // the first 15 min download time counts as 15 min waiting time and you get + // a 15 min bonus while you are in the first 15 min :) + // (to avoid 20 sec downloads) after this the score won't rise any more + dwBaseValue = m_dwUploadTime - GetWaitStartTime(); + dwBaseValue += MIN2MS(::GetTickCount() >= m_dwUploadTime + MIN2MS(15) ? 15 : 30); + //ASSERT ( m_dwUploadTime - GetWaitStartTime() >= 0 ); //oct 28, 02: changed this from "> 0" to ">= 0" -> // 02-Okt-2006 []: ">=0" is always true! } + float fBaseValue = dwBaseValue / SEC2MS(1.0f); + if (thePrefs.UseCreditSystem()) + fBaseValue *= credits->GetScoreRatio(GetIP()); + if (!onlybasevalue) - fBaseValue *= filepriority / 10.0f; + fBaseValue *= GetFilePrioAsNumber() / 10.0f; if ((IsEmuleClient() || GetClientSoft() < 10) && m_byEmuleVersion <= 0x19) fBaseValue *= 0.5f; @@ -258,7 +245,9 @@ bool CUpDownClient::ProcessExtendedInfo(CSafeMemFile *data, CKnownFile *tempreqf uint16 nED2KUpPartCount = data->ReadUInt16(); if (!nED2KUpPartCount) { m_nUpPartCount = tempreqfile->GetPartCount(); - m_abyUpPartStatus = new uint8[m_nUpPartCount](); + if (!m_nUpPartCount) + return false; + m_abyUpPartStatus = new uint8[m_nUpPartCount]{}; } else { if (tempreqfile->GetED2KPartCount() != nED2KUpPartCount) { //We already checked if we are talking about the same file. So if we get here, something really strange happened! @@ -267,14 +256,14 @@ bool CUpDownClient::ProcessExtendedInfo(CSafeMemFile *data, CKnownFile *tempreqf } m_nUpPartCount = tempreqfile->GetPartCount(); m_abyUpPartStatus = new uint8[m_nUpPartCount]; - for (uint16 done = 0; done != m_nUpPartCount;) { + for (UINT done = 0; done < m_nUpPartCount;) { uint8 toread = data->ReadUInt8(); - for (UINT i = 0; i != 8; ++i) { + for (UINT i = 0; i < 8; ++i) { m_abyUpPartStatus[done] = (toread >> i) & 1; -// We may want to use this for another feature. -// if (m_abyUpPartStatus[done] && !tempreqfile->IsComplete(done * PARTSIZE, done * PARTSIZE + PARTSIZE - 1)) -// bPartsNeeded = true; - if (++done == m_nUpPartCount) + //We may want to use this for another feature. + //if (m_abyUpPartStatus[done] && !tempreqfile->IsComplete((uint16)done)) + // bPartsNeeded = true; + if (++done >= m_nUpPartCount) break; } } @@ -294,14 +283,15 @@ void CUpDownClient::SetUploadFileID(CKnownFile *newreqfile) { CKnownFile *oldreqfile = theApp.downloadqueue->GetFileByID(requpfileid); //We use the knownfile list because we may have unshared the file. - //But we always check the download list first because that person may have decided to re-download that file. - //Which will replace the object in the knownfile list if completed. + //But we always check the download list first because that person may re-download + //this file, which will replace the object in the knownfile list if completed. if (oldreqfile == NULL) oldreqfile = theApp.knownfiles->FindKnownFileByID(requpfileid); else { - // In some _very_ rare cases it is possible that we have different files with the same hash in the downloads list - // as well as in the shared list (re-downloading an unshared file, then re-sharing it before the first part has been downloaded) - // to make sure that in no case a deleted client object is left on the list, we need to double-check + // In some _very_ rare cases it is possible that we have different files with the same hash + // in the downloads list as well as in the shared list (re-downloading an unshared file, + // then re-sharing it before the first part has been downloaded) + // to make sure that in no case a deleted client object remains on the list, we do double check // TODO: Fix the whole issue properly CKnownFile *pCheck = theApp.sharedfiles->GetFileByID(requpfileid); if (pCheck != NULL && pCheck != oldreqfile) { @@ -333,7 +323,7 @@ static INT_PTR dbgLastQueueCount = 0; void CUpDownClient::AddReqBlock(Requested_Block_Struct *reqblock, bool bSignalIOThread) { // do _all_ sanity checks on the requested block here, than put it on the block list for the client - // UploadDiskIPThread will handle those later on + // UploadDiskIOThread will handle those later on if (reqblock != NULL) { if (GetUploadState() != US_UPLOADING) { @@ -346,8 +336,8 @@ void CUpDownClient::AddReqBlock(Requested_Block_Struct *reqblock, bool bSignalIO if (HasCollectionUploadSlot()) { CKnownFile *pDownloadingFile = theApp.sharedfiles->GetFileByID(reqblock->FileID); if (pDownloadingFile != NULL) { - if (!(CCollection::HasCollectionExtention(pDownloadingFile->GetFileName()) && pDownloadingFile->GetFileSize() < (uint64)MAXPRIORITYCOLL_SIZE)) { - AddDebugLogLine(DLP_HIGH, false, _T("UploadClient: Client tried to add req block for non collection while having a collection slot! Prevented req blocks from being added. %s"), (LPCTSTR)DbgGetClientInfo()); + if (!CCollection::HasCollectionExtention(pDownloadingFile->GetFileName()) || pDownloadingFile->GetFileSize() > (uint64)MAXPRIORITYCOLL_SIZE) { + AddDebugLogLine(DLP_HIGH, false, _T("UploadClient: Client tried to add req block for non-collection while having a collection slot! Prevented req blocks from being added. %s"), (LPCTSTR)DbgGetClientInfo()); delete reqblock; return; } @@ -375,14 +365,14 @@ void CUpDownClient::AddReqBlock(Requested_Block_Struct *reqblock, bool bSignalIO return; } - if (srcfile->IsPartFile() && !static_cast(srcfile)->IsComplete(reqblock->StartOffset, reqblock->EndOffset - 1, true)) { + if (srcfile->IsPartFile() && !static_cast(srcfile)->IsCompleteBDSafe(reqblock->StartOffset, reqblock->EndOffset - 1)) { DebugLogWarning(_T("AddReqBlock: %s, %s"), (LPCTSTR)GetResString(IDS_ERR_INCOMPLETEBLOCK), (LPCTSTR)DbgGetClientInfo(), (LPCTSTR)srcfile->GetFileName()); delete reqblock; return; } if (reqblock->StartOffset >= reqblock->EndOffset || reqblock->EndOffset > srcfile->GetFileSize()) { - DebugLogError(_T("AddReqBlock: Invalid Blockrequests (negative or bytes to read, read after EOF), %s, %s"), (LPCTSTR)DbgGetClientInfo(), (LPCTSTR)srcfile->GetFileName()); + DebugLogError(_T("AddReqBlock: Invalid Block requests (negative or bytes to read, read after EOF), %s, %s"), (LPCTSTR)DbgGetClientInfo(), (LPCTSTR)srcfile->GetFileName()); delete reqblock; return; } @@ -429,24 +419,24 @@ void CUpDownClient::AddReqBlock(Requested_Block_Struct *reqblock, bool bSignalIO , (LPCTSTR)CastItoXBytes(GetQueueSessionUploadAdded() - (GetQueueSessionPayloadUp() + socket->GetSentPayloadSinceLastCall(false)), false, false, 2) , socket->DbgGetStdQueueCount(), (LPCTSTR)CastItoXBytes((uint32)theApp.m_pUploadDiskIOThread->dbgDataReadPending, false, false, 2) ,_T('?')); */ - theApp.m_pUploadDiskIOThread->NewBlockRequestsAvailable(); + theApp.m_pUploadDiskIOThread->WakeUpCall(); } } -uint32 CUpDownClient::UpdateUploadingStatisticsData() +void CUpDownClient::UpdateUploadingStatisticsData() { - DWORD curTick = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); - uint64 sentBytesCompleteFile = 0; - uint64 sentBytesPartFile = 0; + uint32 sentBytesCompleteFile = 0; + uint32 sentBytesPartFile = 0; - if (GetFileUploadSocket() && (m_ePeerCacheUpState != PCUS_WAIT_CACHE_REPLY)) { - CEMSocket *s = GetFileUploadSocket(); + CEMSocket *sock = GetFileUploadSocket(); + if (sock && (m_ePeerCacheUpState != PCUS_WAIT_CACHE_REPLY)) { UINT uUpStatsPort; if (m_pPCUpSocket && IsUploadingToPeerCache()) { uUpStatsPort = UINT_MAX; - // Check if filedata has been sent via the normal socket since the last call. + // Check if file data has been sent via the normal socket since the last call. uint64 sentBytesCompleteFileNormalSocket = socket->GetSentBytesCompleteFileSinceLastCallAndReset(); uint64 sentBytesPartFileNormalSocket = socket->GetSentBytesPartFileSinceLastCallAndReset(); @@ -458,16 +448,16 @@ uint32 CUpDownClient::UpdateUploadingStatisticsData() // Extended statistics information based on which client software and which port we sent this data to... // This also updates the grand total for sent bytes, etc. And where this data came from. - sentBytesCompleteFile = s->GetSentBytesCompleteFileSinceLastCallAndReset(); - sentBytesPartFile = s->GetSentBytesPartFileSinceLastCallAndReset(); - thePrefs.Add2SessionTransferData(GetClientSoft(), uUpStatsPort, false, true, (UINT)sentBytesCompleteFile, (IsFriend() && GetFriendSlot())); - thePrefs.Add2SessionTransferData(GetClientSoft(), uUpStatsPort, true, true, (UINT)sentBytesPartFile, (IsFriend() && GetFriendSlot())); + sentBytesCompleteFile = (uint32)sock->GetSentBytesCompleteFileSinceLastCallAndReset(); + sentBytesPartFile = (uint32)sock->GetSentBytesPartFileSinceLastCallAndReset(); + thePrefs.Add2SessionTransferData(GetClientSoft(), uUpStatsPort, false, true, sentBytesCompleteFile, (IsFriend() && GetFriendSlot())); + thePrefs.Add2SessionTransferData(GetClientSoft(), uUpStatsPort, true, true, sentBytesPartFile, (IsFriend() && GetFriendSlot())); - m_nTransferredUp = (UINT)(m_nTransferredUp + sentBytesCompleteFile + sentBytesPartFile); - credits->AddUploaded((uint32)(sentBytesCompleteFile + sentBytesPartFile), GetIP()); + m_nTransferredUp += sentBytesCompleteFile + sentBytesPartFile; + credits->AddUploaded(sentBytesCompleteFile + sentBytesPartFile, GetIP()); - uint64 sentBytesPayload = s->GetSentPayloadSinceLastCall(true); - m_nCurQueueSessionPayloadUp = (UINT)(m_nCurQueueSessionPayloadUp + sentBytesPayload); + uint32 sentBytesPayload = sock->GetSentPayloadSinceLastCall(true); + m_nCurQueueSessionPayloadUp += sentBytesPayload; // on some rare cases (namely switching upload files while still data is in the send queue), // we count some bytes for the wrong file, but fixing it (and not counting data only based on @@ -475,48 +465,37 @@ uint32 CUpDownClient::UpdateUploadingStatisticsData() CKnownFile *pCurrentUploadFile = theApp.sharedfiles->GetFileByID(GetUploadFileID()); if (pCurrentUploadFile != NULL) pCurrentUploadFile->statistic.AddTransferred(sentBytesPayload); -// else -// ASSERT( false ); //fired after deleting shared files which had uploads in the current eMule run. Closing messagebox did not cause any problems. - - // increase the sockets buffer on fast uploads. Even though this check should rather be - // in the throttler thread, its better to do it here because we can access the client's - // download rate and the throttler can't - if (GetDatarate() > 100 * 1024) - s->UseBigSendBuffer(); + //else + // ASSERT(0); //fired after deleting shared files which had uploads in the current eMule session. Closing this messagebox caused no issues. } - if (sentBytesCompleteFile + sentBytesPartFile > 0 || - m_AverageUDR_list.IsEmpty() || curTick >= m_AverageUDR_list.GetTail().timestamp + SEC2MS(1)) { - // Store how much data we've transferred this round, + const uint32 sentBytesFile = sentBytesCompleteFile + sentBytesPartFile; + if (sentBytesFile > 0 || m_AverageUDR_list.IsEmpty() || curTick >= m_AverageUDR_list.GetTail().timestamp + SEC2MS(1)) { + // Store how much data we've transferred in this round, // to be able to calculate average speed later - // keep sum of all values in list up to date - TransferredData newitem = {(UINT)(sentBytesCompleteFile + sentBytesPartFile), curTick}; + // keep up to date the sum of all values in the list + TransferredData newitem = {sentBytesFile, curTick}; m_AverageUDR_list.AddTail(newitem); - m_nSumForAvgUpDataRate = (UINT)(m_nSumForAvgUpDataRate + sentBytesCompleteFile + sentBytesPartFile); + m_nSumForAvgUpDataRate += sentBytesFile; } - // remove to old values in list - while (!m_AverageUDR_list.IsEmpty() && curTick >= m_AverageUDR_list.GetHead().timestamp + SEC2MS(10)) { - // keep sum of all values in list up to date + // remove old entries from the list and adjust the sum of all values + while (!m_AverageUDR_list.IsEmpty() && curTick >= m_AverageUDR_list.GetHead().timestamp + SEC2MS(10)) m_nSumForAvgUpDataRate -= m_AverageUDR_list.RemoveHead().datalen; - } // Calculate average speed for this slot if (!m_AverageUDR_list.IsEmpty() && curTick > m_AverageUDR_list.GetHead().timestamp && GetUpStartTimeDelay() > SEC2MS(2)) - m_nUpDatarate = (UINT)(SEC2MS((uint64)m_nSumForAvgUpDataRate) / (curTick - m_AverageUDR_list.GetHead().timestamp)); + m_nUpDatarate = (UINT)(SEC2MS(m_nSumForAvgUpDataRate) / (curTick - m_AverageUDR_list.GetHead().timestamp)); else - // not enough values to calculate trustworthy speed - m_nUpDatarate = 0; + m_nUpDatarate = 0; // not enough data to calculate trustworthy speed // Check if it's time to update the display. - if (curTick >= m_lastRefreshedULDisplay + MINWAIT_BEFORE_ULDISPLAY_WINDOWUPDATE + (uint32)(rand() * 800 / RAND_MAX)) { + if (curTick >= m_lastRefreshedULDisplay + MINWAIT_BEFORE_ULDISPLAY_WINDOWUPDATE + rand() % 800) { // Update display theApp.emuledlg->transferwnd->GetUploadList()->RefreshClient(this); theApp.emuledlg->transferwnd->GetClientList()->RefreshClient(this); m_lastRefreshedULDisplay = curTick; } - - return (uint32)(sentBytesCompleteFile + sentBytesPartFile); } void CUpDownClient::SendOutOfPartReqsAndAddToWaitingQueue() @@ -536,7 +515,7 @@ void CUpDownClient::SendOutOfPartReqsAndAddToWaitingQueue() theApp.uploadqueue->AddClientToQueue(this, true); } -/** +/* * See description for CEMSocket::TruncateQueues(). */ void CUpDownClient::FlushSendBlocks() // call this when you stop upload, or the socket might be not able to send @@ -552,7 +531,7 @@ void CUpDownClient::SendHashsetPacket(const uchar *pData, uint32 nSize, bool bFi if (bFileIdentifiers) { CSafeMemFile data(pData, nSize); CFileIdentifierSA fileIdent; - if (!fileIdent.ReadIdentifier(&data)) + if (!fileIdent.ReadIdentifier(data)) throw _T("Bad FileIdentifier (OP_HASHSETREQUEST2)"); CKnownFile *file = theApp.sharedfiles->GetFileByIdentifier(fileIdent, false); if (file == NULL) { @@ -568,12 +547,12 @@ void CUpDownClient::SendHashsetPacket(const uchar *pData, uint32 nSize, bool bFi return; } const CFileIdentifier &fileid = file->GetFileIdentifier(); - fileid.WriteIdentifier(&fileResponse); + fileid.WriteIdentifier(fileResponse); // even if we don't happen to have an AICH hashset yet for some reason we send a proper (possibly empty) response - fileid.WriteHashSetsToPacket(&fileResponse, bMD4, bAICH); + fileid.WriteHashSetsToPacket(fileResponse, bMD4, bAICH); if (thePrefs.GetDebugClientTCPLevel() > 0) DebugSend("OP_HashSetAnswer", this, fileid.GetMD4Hash()); - packet = new Packet(&fileResponse, OP_EMULEPROT, OP_HASHSETANSWER2); + packet = new Packet(fileResponse, OP_EMULEPROT, OP_HASHSETANSWER2); } else { if (nSize != 16) { ASSERT(0); @@ -584,10 +563,10 @@ void CUpDownClient::SendHashsetPacket(const uchar *pData, uint32 nSize, bool bFi CheckFailedFileIdReqs(pData); throw GetResString(IDS_ERR_REQ_FNF) + _T(" (SendHashsetPacket)"); } - file->GetFileIdentifier().WriteMD4HashsetToFile(&fileResponse); + file->GetFileIdentifier().WriteMD4HashsetToFile(fileResponse); if (thePrefs.GetDebugClientTCPLevel() > 0) DebugSend("OP_HashSetAnswer", this, pData); - packet = new Packet(&fileResponse, OP_EDONKEYPROT, OP_HASHSETANSWER); + packet = new Packet(fileResponse, OP_EDONKEYPROT, OP_HASHSETANSWER); } theStats.AddUpDataOverheadFileRequest(packet->size); SendPacket(packet); @@ -616,7 +595,7 @@ void CUpDownClient::SendCommentInfo(/*const */CKnownFile *file) m_bCommentDirty = false; UINT rating = file->GetFileRating(); - const CString &desc = file->GetFileComment(); + const CString &desc(file->GetFileComment()); if (rating == 0 && desc.IsEmpty()) return; @@ -625,7 +604,7 @@ void CUpDownClient::SendCommentInfo(/*const */CKnownFile *file) data.WriteLongString(desc, GetUnicodeSupport()); if (thePrefs.GetDebugClientTCPLevel() > 0) DebugSend("OP_FileDesc", this, file->GetFileHash()); - Packet *packet = new Packet(&data, OP_EMULEPROT); + Packet *packet = new Packet(data, OP_EMULEPROT); packet->opcode = OP_FILEDESC; theStats.AddUpDataOverheadFileRequest(packet->size); SendPacket(packet); @@ -633,25 +612,25 @@ void CUpDownClient::SendCommentInfo(/*const */CKnownFile *file) void CUpDownClient::AddRequestCount(const uchar *fileid) { + const DWORD curTick = ::GetTickCount(); + for (POSITION pos = m_RequestedFiles_list.GetHeadPosition(); pos != NULL;) { Requested_File_Struct *cur_struct = m_RequestedFiles_list.GetNext(pos); if (md4equ(cur_struct->fileid, fileid)) { - if (::GetTickCount() < cur_struct->lastasked + MIN_REQUESTTIME && !GetFriendSlot()) { - if (GetDownloadState() != DS_DOWNLOADING) - cur_struct->badrequests++; + if (curTick < cur_struct->lastasked + MIN_REQUESTTIME && !GetFriendSlot()) { + cur_struct->badrequests += static_cast(GetDownloadState() != DS_DOWNLOADING); if (cur_struct->badrequests == BADCLIENTBAN) Ban(); - } else { - if (cur_struct->badrequests) - cur_struct->badrequests--; - } - cur_struct->lastasked = ::GetTickCount(); + } else + cur_struct->badrequests -= static_cast(cur_struct->badrequests > 0); + + cur_struct->lastasked = curTick; return; } } Requested_File_Struct *new_struct = new Requested_File_Struct; md4cpy(new_struct->fileid, fileid); - new_struct->lastasked = ::GetTickCount(); + new_struct->lastasked = curTick; new_struct->badrequests = 0; m_RequestedFiles_list.AddHead(new_struct); } @@ -692,13 +671,13 @@ void CUpDownClient::Ban(LPCTSTR pszReason) socket->ShutDown(CAsyncSocket::receives); // let the socket timeout, since we don't want to risk to delete the client right now. This isn't actually perfect, could be changed later } -uint32 CUpDownClient::GetWaitStartTime() const +DWORD CUpDownClient::GetWaitStartTime() const { if (credits == NULL) { ASSERT(0); return 0; } - uint32 dwResult = credits->GetSecureWaitStartTime(GetIP()); + DWORD dwResult = credits->GetSecureWaitStartTime(GetIP()); if (dwResult > m_dwUploadTime && IsDownloading()) { //this happens only if two clients with invalid securehash are in the queue - if at all dwResult = m_dwUploadTime - 1; diff --git a/srchybrid/UploadDiskIOThread.cpp b/srchybrid/UploadDiskIOThread.cpp index 814db4da..0f1ae103 100644 --- a/srchybrid/UploadDiskIOThread.cpp +++ b/srchybrid/UploadDiskIOThread.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -16,11 +16,10 @@ //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "StdAfx.h" +#include "updownclient.h" #include "uploaddiskiothread.h" -#include "otherfunctions.h" #include "emule.h" #include "UploadQueue.h" -#include "updownclient.h" #include "sharedfilelist.h" #include "partfile.h" #include "knownfile.h" @@ -40,161 +39,166 @@ static char THIS_FILE[] = __FILE__; #endif -#define SLOT_COMPRESSIONCHECK_DATARATE (150 * 1024) // Data rate for a single client from which we start to check if we need to disable compression -#define MAX_FINISHED_REQUESTS_COMPRESSION 15 // Max waiting finished requests before disabling compression (if total upload > SLOT_COMPRESSIONCHECK_DATARATE) -#define BIGBUFFER_MINDATARATE (75 * 1024) +#define SLOT_COMPRESSION_DATARATE (1000 * 1024) // Data rate for a single client from which we start to check if we need to disable compression +#define BIGBUFFER_MINDATARATE (75 * 1024) IMPLEMENT_DYNCREATE(CUploadDiskIOThread, CWinThread) CUploadDiskIOThread::CUploadDiskIOThread() - : dbgDataReadPending() - , m_eventAsyncIOFinished(FALSE, TRUE) - , m_bSignalThrottler() + : m_eventThreadEnded(FALSE, TRUE) + , m_hPort() , m_bRun() + , m_bSignalThrottler() +#ifdef _DEBUG + , dbgDataReadPending() +#endif { ASSERT(theApp.uploadqueue != NULL); - m_eventThreadEnded = new CEvent(FALSE, TRUE); AfxBeginThread(RunProc, (LPVOID)this); } CUploadDiskIOThread::~CUploadDiskIOThread() { + ASSERT(!m_hPort); ASSERT(!m_bRun); - delete m_eventThreadEnded; } - UINT AFX_CDECL CUploadDiskIOThread::RunProc(LPVOID pParam) { DbgSetThreadName("UploadDiskIOThread"); InitThreadLocale(); - return (pParam == NULL) ? 1 : static_cast(pParam)->RunInternal(); + return pParam ? static_cast(pParam)->RunInternal() : 1; } - void CUploadDiskIOThread::EndThread() { m_bRun = false; - m_eventNewBlockRequests.PulseEvent(); - m_eventThreadEnded->Lock(); + PostQueuedCompletionStatus(m_hPort, 0, 0, NULL); + m_eventThreadEnded.Lock(); } UINT CUploadDiskIOThread::RunInternal() { - m_bRun = true; - bool bCheckForPendingIOOnly = false; - while (m_bRun) { - if (!bCheckForPendingIOOnly) { - m_eventNewBlockRequests.ResetEvent(); - m_eventSocketNeedsData.ResetEvent(); - CCriticalSection *pcsUploadListRead = NULL; - const CUploadingPtrList &rUploadList = theApp.uploadqueue->GetUploadListTS(&pcsUploadListRead); - CSingleLock lockUploadListRead(pcsUploadListRead, TRUE); - ASSERT(lockUploadListRead.IsLocked()); - - for (POSITION pos = rUploadList.GetHeadPosition(); pos != NULL;) { - UploadingToClient_Struct *pCurUploadingClientStruct = rUploadList.GetNext(pos); - const CUpDownClient *cur_client = pCurUploadingClientStruct->m_pClient; - if (cur_client->socket != NULL && cur_client->socket->IsConnected() - && (!cur_client->IsUploadingToPeerCache() || cur_client->m_pPCUpSocket != NULL)) - { - StartCreateNextBlockPackage(pCurUploadingClientStruct); - } - } - lockUploadListRead.Unlock(); - } + m_hPort = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 1); + if (!m_hPort) + return ::GetLastError(); - // check if any pending requests have finished - m_eventAsyncIOFinished.SetEvent(); // Windows doesn't like finished Overlapped results with non-signaled events. But we don't want to create an event for each our reads (which would be the suggested solution) - for (POSITION pos = m_listPendingIO.GetHeadPosition(); pos != NULL;) { - POSITION pos2 = pos; - OverlappedEx_Struct *pCurPendingIO = m_listPendingIO.GetNext(pos); - DWORD dwRead; - if (GetOverlappedResult(pCurPendingIO->pFileStruct->hFile, &pCurPendingIO->oOverlap, &dwRead, FALSE)) { - m_listPendingIO.RemoveAt(pos2); - // we add it to a list instead of processing it directly because we need to know how many finished IOs - // we have to decide if we can use compression or need to speedup later on - pCurPendingIO->dwRead = dwRead; - m_listFinishedIO.AddTail(pCurPendingIO); - } else { - DWORD nError = ::GetLastError(); - if (nError != ERROR_IO_PENDING && nError != ERROR_IO_INCOMPLETE) { - theApp.QueueDebugLogLineEx(LOG_ERROR, _T("IO Error: GetOverlappedResult: %s"), (LPCTSTR)GetErrorMessage(nError)); - m_listPendingIO.RemoveAt(pos2); - // calling it with an error will cause it to clean up the mess - ReadCompletionRoutine(1, 0, pCurPendingIO); - } - } - } - m_eventAsyncIOFinished.ResetEvent(); - // work down all the finished IOs - while (!m_listFinishedIO.IsEmpty()) - ReadCompletionRoutine(0, 0, m_listFinishedIO.RemoveHead()); - - // if we put new data on some socket, tell the throttler + DWORD dwRead = 0; + ULONG_PTR completionKey = 0; + OverlappedRead_Struct *pCurIO = NULL; + m_bRun = true; + while (m_bRun + && ::GetQueuedCompletionStatus(m_hPort, &dwRead, &completionKey, (LPOVERLAPPED*)&pCurIO, INFINITE) + && completionKey) + { + //start new I/O + CCriticalSection *pcsUploadListRead = NULL; + const CUploadingPtrList &rUploadList = theApp.uploadqueue->GetUploadListTS(&pcsUploadListRead); + pcsUploadListRead->Lock(); + for (POSITION pos = rUploadList.GetHeadPosition(); pos != NULL;) + StartCreateNextBlockPackage(rUploadList.GetNext(pos)); + pcsUploadListRead->Unlock(); + + //completed I/O + do { + if (!completionKey) + break; + if (completionKey != (ULONG_PTR)(~0)) //wake up call + ReadCompletionRoutine(dwRead, pCurIO); + } while (::GetQueuedCompletionStatus(m_hPort, &dwRead, &completionKey, (LPOVERLAPPED*)&pCurIO, 0)); + + //thread termination + if (!completionKey) // && !dwRead && !pCurIO) + break; + + // if we have put a new data on any socket, tell the throttler if (m_bSignalThrottler && theApp.uploadBandwidthThrottler != NULL) { theApp.uploadBandwidthThrottler->NewUploadDataAvailable(); m_bSignalThrottler = false; } - - HANDLE aEvents[3] = {m_eventAsyncIOFinished, m_eventNewBlockRequests, m_eventSocketNeedsData}; - DWORD nRes = ::WaitForMultipleObjects(_countof(aEvents), aEvents, FALSE, 500); - ASSERT(nRes != WAIT_FAILED); - bCheckForPendingIOOnly = (nRes == WAIT_OBJECT_0); } - // cleanup - signal all open files to cancel all their pending operations - for (POSITION pos = m_listOpenFiles.GetHeadPosition(); pos != NULL;) - if (CancelIo(m_listOpenFiles.GetNext(pos)->hFile)) - ::WaitForSingleObject(m_eventAsyncIOFinished, SEC2MS(1)); //should be INFINITE, but event is reused - else { - theApp.QueueDebugLogLineEx(LOG_ERROR, _T("CUploadDiskIOThread cleanup, CancelIO failed!")); - ASSERT(0); - } + m_bRun = false; //set non-running state in case of an I/O port error + //Improper termination of asynchronous I/O follows... + //close file handles to release the I/O completion port while (!m_listPendingIO.IsEmpty()) - ReadCompletionRoutine(1, 0, m_listPendingIO.RemoveHead()); + ReadCompletionRoutine(0, m_listPendingIO.RemoveHead()); - if (!m_listOpenFiles.IsEmpty()) { - theApp.QueueDebugLogLineEx(LOG_ERROR, _T("CUploadDiskIOThread cleanup, failed to cleanup all pending operations (file handles still in use)")); - ASSERT(0); - } - m_eventThreadEnded->SetEvent(); + ::CloseHandle(m_hPort); + m_hPort = 0; + + m_eventThreadEnded.SetEvent(); return 0; } -// todo: main thread, check for fileid, check for error +bool CUploadDiskIOThread::AssociateFile(CKnownFile *pFile) +{ + ASSERT(m_hPort && m_bRun); + if (pFile && pFile->m_hRead == INVALID_HANDLE_VALUE && !pFile->bNoNewReads) { + CString fullname = (pFile->IsPartFile()) + ? RemoveFileExtension(static_cast(pFile)->GetFullName()) + : pFile->GetFilePath(); + pFile->m_hRead = ::CreateFile(fullname, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_SEQUENTIAL_SCAN, NULL); + if (pFile->m_hRead == INVALID_HANDLE_VALUE) { + DebugLogError(_T("Failed to open \"%s\" for overlapped read: %s"), (LPCTSTR)fullname, (LPCTSTR)GetErrorMessage(::GetLastError(), 1)); + return false; + } + if (m_hPort != ::CreateIoCompletionPort(pFile->m_hRead, m_hPort, (ULONG_PTR)pFile, 0)) { + DebugLogError(_T("Failed to associate \"%s\" with reading IOCP: %s"), (LPCTSTR)fullname, (LPCTSTR)GetErrorMessage(::GetLastError(), 1)); + DissociateFile(pFile); + return false; + } + pFile->bCompress = ShouldCompressBasedOnFilename(fullname); + } + return true; +} + +void CUploadDiskIOThread::DissociateFile(CKnownFile *pFile) +{ + ASSERT(pFile); + if (pFile->m_hRead != INVALID_HANDLE_VALUE) { + VERIFY(::CloseHandle(pFile->m_hRead)); + pFile->m_hRead = INVALID_HANDLE_VALUE; + } +} void CUploadDiskIOThread::StartCreateNextBlockPackage(UploadingToClient_Struct *pUploadClientStruct) { - // when calling this function we already have a lock to the uploadlist (so pUploadClientStruct and its members are safe in terms of not getting deleted/changed) - // now also get a lock to the Block lists + if (pUploadClientStruct->m_bIOError || pUploadClientStruct->m_BlockRequests_queue.IsEmpty()) + return; + // when calling this function we already have a lock on the uploadlist + // (so pUploadClientStruct and its members are safe in terms of not getting deleted/changed) + CUpDownClient *pClient = pUploadClientStruct->m_pClient; + CClientReqSocket *pSock = pClient->socket; + if (pSock == NULL + || !pSock->IsConnected() + || (pClient->IsUploadingToPeerCache() && pClient->m_pPCUpSocket == NULL)) + { + return; + } + + // now also get a lock on the Block lists CSingleLock lockBlockLists(&pUploadClientStruct->m_csBlockListsLock, TRUE); - // See if we can do an early return. There may be no new blocks to load from disk and add to buffer, or buffer may be large enough already. + // See if we can do an early return. + // There may be no new blocks to load from disk and add to buffer, or buffer may be large enough already. - uint32 nCurQueueSessionPayloadUp = pUploadClientStruct->m_pClient->GetQueueSessionPayloadUp(); + uint64 nCurQueueSessionPayloadUp = pClient->GetQueueSessionPayloadUp(); // GetQueueSessionPayloadUp is probably outdated so also add the value reported by the sockets as sent - CClientReqSocket *pSock = pUploadClientStruct->m_pClient->socket; - if (pSock != NULL) - nCurQueueSessionPayloadUp += (uint32)pSock->GetSentPayloadSinceLastCall(false); - uint32 addedPayloadQueueSession = pUploadClientStruct->m_pClient->GetQueueSessionUploadAdded(); - - // buffer at least 1 block (180KB) on normal uploads and 5 blocks (~900KB) on fast uploads - bool bFastUpload = pUploadClientStruct->m_pClient->GetDatarate() > BIGBUFFER_MINDATARATE; - const uint32 nBufferLimit = bFastUpload ? ((5 * EMBLOCKSIZE) + 1) : (EMBLOCKSIZE + 1); + nCurQueueSessionPayloadUp += pSock->GetSentPayloadSinceLastCall(false); + uint64 addedPayloadQueueSession = pClient->GetQueueSessionUploadAdded(); + // buffer at least 1 block (180KB) for normal uploads, and 5 blocks (~900KB) for fast uploads + const uint32 nBufferLimit = (pClient->GetUploadDatarate() > BIGBUFFER_MINDATARATE) ? (5 * EMBLOCKSIZE + 1) : (EMBLOCKSIZE + 1); - if (pUploadClientStruct->m_BlockRequests_queue.IsEmpty() // There are no new blocks requested - || (addedPayloadQueueSession > nCurQueueSessionPayloadUp && addedPayloadQueueSession - nCurQueueSessionPayloadUp >= nBufferLimit)) - { + if (addedPayloadQueueSession > nCurQueueSessionPayloadUp && addedPayloadQueueSession - nCurQueueSessionPayloadUp >= nBufferLimit) return; // the buffered data is large enough already - } try { - // Buffer new data if current buffer is less than nBufferLimit Bytes + // Get more data if currently buffered was less than nBufferLimit Bytes while (!pUploadClientStruct->m_BlockRequests_queue.IsEmpty() && (addedPayloadQueueSession <= nCurQueueSessionPayloadUp || addedPayloadQueueSession - nCurQueueSessionPayloadUp < nBufferLimit)) { Requested_Block_Struct *currentblock = pUploadClientStruct->m_BlockRequests_queue.GetHead(); - if (!md4equ(currentblock->FileID, pUploadClientStruct->m_pClient->GetUploadFileID())) { + if (!md4equ(currentblock->FileID, pClient->GetUploadFileID())) { // the UploadFileID differs. That's normally not a problem, we just switch it, but // we don't want to do so in this thread for synchronization issues. So return and wait // until the main thread which checks the block request periodically does so. @@ -203,342 +207,262 @@ void CUploadDiskIOThread::StartCreateNextBlockPackage(UploadingToClient_Struct * return; } - // fetch a lock for the shared files list, makes also sure the file object doesn't gets deleted while we access it - // other active Locks: UploadList, m_csBlockListsLock - CSingleLock lockSharedFiles(&theApp.sharedfiles->m_mutWriteList, TRUE); - CKnownFile *srcfile = theApp.sharedfiles->GetFileByID(currentblock->FileID); - if (srcfile == NULL) - throw GetResString(IDS_ERR_REQ_FNF); - - CSyncHelper lockFile; - CString fullname; - if (srcfile->IsPartFile() && static_cast(srcfile)->GetStatus() != PS_COMPLETE) { - // Do not access a part file, if it is currently moved into the incoming directory. - // Because the moving of part file into the incoming directory may take a noticeable - // amount of time, we can not wait for 'm_FileCompleteMutex' and block the main thread. - if (!static_cast(srcfile)->m_FileCompleteMutex.Lock(0))// just do a quick test of the mutex's state and return if it's locked. - return; - lockFile.m_pFile = &static_cast(srcfile)->m_FileCompleteMutex; - fullname = RemoveFileExtension(static_cast(srcfile)->GetFullName()); - } else - fullname.Format(_T("%s\\%s"), (LPCTSTR)srcfile->GetPath(), (LPCTSTR)srcfile->GetFileName()); + CKnownFile *pFile = theApp.sharedfiles->GetFileByID(currentblock->FileID); + if (pFile == NULL) + throwCStr(_T("CUploadDiskIOThread::StartCreateNextBlockPackage: shared file not found")); + if (pFile->bNoNewReads) //should be moving to incoming + return; // we already have done all important sanity checks for the block request in the main thread when adding it; just redo some quick important ones + if (currentblock->StartOffset >= currentblock->EndOffset || currentblock->EndOffset > pFile->GetFileSize()) + throwCStr(_T("Invalid Block Offsets")); uint64 uTogo = currentblock->EndOffset - currentblock->StartOffset; - if (currentblock->StartOffset >= currentblock->EndOffset || currentblock->EndOffset > srcfile->GetFileSize()) - throw _T("Invalid Block Offsets"); if (uTogo > EMBLOCKSIZE * 3) throw GetResString(IDS_ERR_LARGEREQBLOCK); - //DWORD togo = (DWORD)i64uTogo; - - // check if we already have a handle for this shared file and if so use it. - // Our checks above make sure we don't continue using a file - // that user might have removed from his share - OpenOvFile_Struct *pOpenOvFileStruct = NULL; - for (POSITION pos = m_listOpenFiles.GetHeadPosition(); pos != NULL;) { - OpenOvFile_Struct *pCurOpenOvFileStruct = m_listOpenFiles.GetNext(pos); - if (md4equ(pCurOpenOvFileStruct->ucMD4FileHash, currentblock->FileID)) { - pOpenOvFileStruct = pCurOpenOvFileStruct; - break; - } - } - if (pOpenOvFileStruct == NULL) { - DWORD dwShare; // FILE_SHARE_DELETE allows the user to delete files (or complete partfiles) even while we still have our read handle (which stays valid of course) - if (thePrefs.GetWindowsVersion() >= _WINVER_2K_) // might work on NT4 too, but I can't test and who is using it still anyway ;), so lets go the safe way - dwShare = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE; - else - dwShare = FILE_SHARE_WRITE | FILE_SHARE_READ; - // regardless if partfile or sharedfile, we acquire a new file handle to read the data later on - HANDLE hFile = ::CreateFile(fullname, GENERIC_READ, dwShare, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_SEQUENTIAL_SCAN, NULL); - if (hFile == INVALID_HANDLE_VALUE) - throw GetResString(IDS_ERR_OPEN); - - pOpenOvFileStruct = new OpenOvFile_Struct; - md4cpy(pOpenOvFileStruct->ucMD4FileHash, currentblock->FileID); - pOpenOvFileStruct->hFile = hFile; - pOpenOvFileStruct->nInUse = 0; // we increase it later right before the right call - pOpenOvFileStruct->bStatsIsPartfile = srcfile->IsPartFile(); - pOpenOvFileStruct->bCompress = ShouldCompressBasedOnFilename(fullname); - pOpenOvFileStruct->uFileSize = (uint64)srcfile->GetFileSize(); - m_listOpenFiles.AddTail(pOpenOvFileStruct); - } - // some cleanup - // release the partfile if we have locked it, our file handle works as lock against moving instead (or even better we don't need a lock at all on modern OS) - if (lockFile.m_pFile != NULL) { - lockFile.m_pFile->Unlock(); - lockFile.m_pFile = NULL; - } - // we now have all informations we need, so release the sharedfileslist - lockSharedFiles.Unlock(); - srcfile = NULL; // not safe any more - - // now for the actual reading - OverlappedEx_Struct *pstructOverlappedEx = new OverlappedEx_Struct; - ASSERT((sizeof pstructOverlappedEx->oOverlap) == sizeof(OVERLAPPED)); - pstructOverlappedEx->oOverlap.Internal = 0; - pstructOverlappedEx->oOverlap.InternalHigh = 0; - pstructOverlappedEx->oOverlap.Offset = LODWORD(currentblock->StartOffset); - pstructOverlappedEx->oOverlap.OffsetHigh = HIDWORD(currentblock->StartOffset); - pstructOverlappedEx->oOverlap.hEvent = m_eventAsyncIOFinished; - pstructOverlappedEx->pFileStruct = pOpenOvFileStruct; - pstructOverlappedEx->pUploadClientStruct = pUploadClientStruct; - pstructOverlappedEx->uStartOffset = currentblock->StartOffset; - pstructOverlappedEx->uEndOffset = currentblock->EndOffset; - pstructOverlappedEx->pBuffer = new byte[(size_t)uTogo]; - pstructOverlappedEx->dwRead = 0; - pstructOverlappedEx->pFileStruct->nInUse++; - - if (!::ReadFile(pstructOverlappedEx->pFileStruct->hFile, pstructOverlappedEx->pBuffer, (DWORD)uTogo, NULL, (LPOVERLAPPED)pstructOverlappedEx)) { + if (!AssociateFile(pFile)) + throwCStr(_T("StartCreateNextBlockPackage: cannot open CKnownFile")); + + // initiate read + OverlappedRead_Struct *pOverlappedRead = new OverlappedRead_Struct; + pOverlappedRead->oOverlap.Internal = 0; + pOverlappedRead->oOverlap.InternalHigh = 0; + //pOverlappedRead->oOverlap.Offset = LODWORD(currentblock->StartOffset); + //pOverlappedRead->oOverlap.OffsetHigh = HIDWORD(currentblock->StartOffset); + *(uint64*)&pOverlappedRead->oOverlap.Offset = currentblock->StartOffset; + pOverlappedRead->oOverlap.hEvent = 0; + pOverlappedRead->pFile = pFile; + pOverlappedRead->pUploadClientStruct = pUploadClientStruct; + pOverlappedRead->uStartOffset = currentblock->StartOffset; + pOverlappedRead->uEndOffset = currentblock->EndOffset; + pOverlappedRead->pBuffer = new byte[(size_t)uTogo]; + + if (!::ReadFile(pFile->m_hRead, pOverlappedRead->pBuffer, (DWORD)uTogo, NULL, (LPOVERLAPPED)pOverlappedRead)) { DWORD dwError = ::GetLastError(); if (dwError != ERROR_IO_PENDING) { - ReleaseOvOpenFile(pstructOverlappedEx->pFileStruct); - delete[] pstructOverlappedEx->pBuffer; - delete pstructOverlappedEx; + delete[] pOverlappedRead->pBuffer; + delete pOverlappedRead; - if (dwError == ERROR_INVALID_USER_BUFFER || dwError == ERROR_NOT_ENOUGH_MEMORY) { + if (dwError == ERROR_INVALID_USER_BUFFER || dwError == ERROR_NOT_ENOUGH_MEMORY || dwError == ERROR_NOT_ENOUGH_QUOTA) { theApp.QueueDebugLogLineEx(LOG_WARNING, _T("ReadFile failed, possibly too many pending requests, trying again later")); return; // make this a recoverable error, as it might just be that we have too many requests in which case we just need to wait } - throw _T("ReadFileEx Error: ") + GetErrorMessage(::GetLastError()); + throw _T("ReadFile Error: ") + GetErrorMessage(::GetLastError()); } - m_listPendingIO.AddTail(pstructOverlappedEx); - } else { - // read succeeded immediately without an async operation - GetOverlappedResult(pstructOverlappedEx->pFileStruct->hFile, &pstructOverlappedEx->oOverlap, &pstructOverlappedEx->dwRead, FALSE); - m_listFinishedIO.AddTail(pstructOverlappedEx); } - dbgDataReadPending += (uint32)uTogo; + ++pFile->nInUse; + pOverlappedRead->pos = m_listPendingIO.AddTail(pOverlappedRead); + DEBUG_ONLY(dbgDataReadPending += uTogo); - addedPayloadQueueSession += (uint32)uTogo; - pUploadClientStruct->m_pClient->SetQueueSessionUploadAdded(addedPayloadQueueSession); + addedPayloadQueueSession += uTogo; + pClient->SetQueueSessionUploadAdded(addedPayloadQueueSession); pUploadClientStruct->m_DoneBlocks_list.AddHead(pUploadClientStruct->m_BlockRequests_queue.RemoveHead()); } + return; //no errors } catch (const CString &error) { - theApp.QueueDebugLogLineEx(LOG_ERROR, GetResString(IDS_ERR_CLIENTERRORED), pUploadClientStruct->m_pClient->GetUserName(), (LPCTSTR)error); - pUploadClientStruct->m_bIOError = true; // will let the main thread remove this client from the list + theApp.QueueDebugLogLineEx(LOG_ERROR, GetResString(IDS_ERR_CLIENTERRORED), pClient->GetUserName(), (LPCTSTR)error); } catch (CFileException *e) { TCHAR szError[MAX_PATH + 256]; GetExceptionMessage(*e, szError, _countof(szError)); - theApp.QueueDebugLogLineEx(LOG_ERROR, _T("Failed to create upload package for %s - %s"), pUploadClientStruct->m_pClient->GetUserName(), szError); + theApp.QueueDebugLogLineEx(LOG_ERROR, _T("Failed to create upload package for %s - %s"), pClient->GetUserName(), szError); e->Delete(); - pUploadClientStruct->m_bIOError = true; // will let the main thread remove this client from the list } + pUploadClientStruct->m_bIOError = true; // will let remove this client from the list in the main thread } -void CUploadDiskIOThread::ReadCompletionRoutine(DWORD dwErrorCode, DWORD dwBytesRead, OverlappedEx_Struct *pOverlappedExStruct) +void CUploadDiskIOThread::ReadCompletionRoutine(DWORD dwRead, const OverlappedRead_Struct *pOvRead) { - if (pOverlappedExStruct == NULL) { + if (pOvRead == NULL) { ASSERT(0); return; } - if (m_bRun) { - if (dwBytesRead == 0) - dwBytesRead = pOverlappedExStruct->dwRead; - bool bError = dwErrorCode != 0; - if (!bError && dwBytesRead != pOverlappedExStruct->uEndOffset - pOverlappedExStruct->uStartOffset) { - theApp.QueueDebugLogLineEx(LOG_ERROR, _T("ReadCompletionRoutine: Didn't read requested data count - wanted: %u, read: %u") - , (uint32)(pOverlappedExStruct->uEndOffset - pOverlappedExStruct->uStartOffset), dwBytesRead); - bError = true; - } - dbgDataReadPending -= (uint32)(pOverlappedExStruct->uEndOffset - pOverlappedExStruct->uStartOffset); - // check if the clientstruct is still in the uploadlist (otherwise it is a deleted pointer) - CCriticalSection *pcsUploadListRead = NULL; - const CUploadingPtrList &rUploadList = theApp.uploadqueue->GetUploadListTS(&pcsUploadListRead); - CSingleLock lockUploadListRead(pcsUploadListRead, TRUE); - ASSERT(lockUploadListRead.IsLocked()); - bool bFound = (rUploadList.Find(pOverlappedExStruct->pUploadClientStruct) != NULL); - if (!bFound) { - theApp.QueueDebugLogLineEx(LOG_WARNING, _T("ReadCompletionRoutine: Client not found in uploadlist any more when reading finished, discarding block")); - bError = true; - } + ASSERT(pOvRead->pFile && pOvRead->pos); - // all important prechecks done, create the packets - if (!bError) { - // keep the uploadlist lock for working with the client object - // instead of sending the packets directly, we store them and send them after we have released the uploadlist lock - // just to be sure there isn't any deadlock chance (now or in future version, also it doesn't costs us anything) - CPacketList packetsList; - - bool bPeerCache = pOverlappedExStruct->pUploadClientStruct->m_pClient->IsUploadingToPeerCache(); - CClientReqSocket *pSocket = bPeerCache ? pOverlappedExStruct->pUploadClientStruct->m_pClient->m_pPCUpSocket : pOverlappedExStruct->pUploadClientStruct->m_pClient->socket; - if (pSocket == NULL || !(bPeerCache || pSocket->IsConnected())) - theApp.QueueDebugLogLineEx(LOG_ERROR, _T("ReadCompletionRoutine: Client has no connected socket, %s"), (LPCTSTR)pOverlappedExStruct->pUploadClientStruct->m_pClient->DbgGetClientInfo(true)); - else { - // figure out if we need to disable compression. If the data rate is high enough, the socket indicates that it needs more data - // and we have requests pending, its time to disable it - bool bUseCompression = false; - // first the static check to see if we could at all - if (!bPeerCache && pOverlappedExStruct->pFileStruct->bCompress && pOverlappedExStruct->pUploadClientStruct->m_pClient->GetDataCompressionVersion() == 1 && !pOverlappedExStruct->pUploadClientStruct->m_bDisableCompression) { - // now the dynamic ones to check if its fine for this upload slot - if (m_listFinishedIO.GetCount() > MAX_FINISHED_REQUESTS_COMPRESSION && theApp.uploadqueue->GetDatarate() > SLOT_COMPRESSIONCHECK_DATARATE) { - pOverlappedExStruct->pUploadClientStruct->m_bDisableCompression = true; - if (thePrefs.GetVerbose()) - theApp.QueueDebugLogLine(false, _T("Disabled compression for upload slot because of too many unprocessed finished IO requests (%u), client: %s"), m_listFinishedIO.GetCount(), (LPCTSTR)pOverlappedExStruct->pUploadClientStruct->m_pClient->DbgGetClientInfo(true)); - } else if (pOverlappedExStruct->pUploadClientStruct->m_pClient->GetDatarate() > SLOT_COMPRESSIONCHECK_DATARATE && !pSocket->HasQueues(true) && !pSocket->IsBusyQuickCheck()) { - pOverlappedExStruct->pUploadClientStruct->m_bDisableCompression = true; - if (thePrefs.GetVerbose()) - theApp.QueueDebugLogLine(false, _T("Disabled compression for upload slot because socket is starving for data, client: %s"), (LPCTSTR)pOverlappedExStruct->pUploadClientStruct->m_pClient->DbgGetClientInfo(true)); - } else - bUseCompression = true; - } + --pOvRead->pFile->nInUse; - CString strDbgClientInfo; - if (thePrefs.GetDebugClientTCPLevel() > 0) - strDbgClientInfo = pOverlappedExStruct->pUploadClientStruct->m_pClient->DbgGetClientInfo(true); - if (bPeerCache) { - CreatePeerCachePackets(pOverlappedExStruct->pBuffer, pOverlappedExStruct->uStartOffset - , pOverlappedExStruct->uEndOffset, pOverlappedExStruct->pFileStruct->uFileSize - , pOverlappedExStruct->pFileStruct->bStatsIsPartfile, packetsList, pOverlappedExStruct->pFileStruct->ucMD4FileHash - , pOverlappedExStruct->pUploadClientStruct->m_pClient); - } else if (bUseCompression) { - CreatePackedPackets(pOverlappedExStruct->pBuffer, pOverlappedExStruct->uStartOffset - , pOverlappedExStruct->uEndOffset, pOverlappedExStruct->pFileStruct->bStatsIsPartfile, packetsList - , pOverlappedExStruct->pFileStruct->ucMD4FileHash, strDbgClientInfo); - } else { - CreateStandardPackets(pOverlappedExStruct->pBuffer, pOverlappedExStruct->uStartOffset - , pOverlappedExStruct->uEndOffset, pOverlappedExStruct->pFileStruct->bStatsIsPartfile, packetsList - , pOverlappedExStruct->pFileStruct->ucMD4FileHash, strDbgClientInfo); + CKnownFile *pKnownFile = pOvRead->pFile; + if (m_bRun) { + m_listPendingIO.RemoveAt(pOvRead->pos); + bool bReadError = !dwRead; + if (bReadError) + Debug(_T(" Completed read, dwRead=0\n")); + else if (dwRead != pOvRead->uEndOffset - pOvRead->uStartOffset) { + theApp.QueueDebugLogLineEx(LOG_ERROR, _T("ReadCompletionRoutine: Didn't read requested data count - wanted: %lu, read: %lu") + , (DWORD)(pOvRead->uEndOffset - pOvRead->uStartOffset), dwRead); + bReadError = true; + } + if (pKnownFile->m_hRead != INVALID_HANDLE_VALUE) { //discard data from closed files + UploadingToClient_Struct *pStruct = pOvRead->pUploadClientStruct; + DEBUG_ONLY(dbgDataReadPending -= pOvRead->uEndOffset - pOvRead->uStartOffset); + // check if the client struct is still in the upload list (otherwise it is a deleted pointer) + CCriticalSection *pcsUploadListRead = NULL; + const CUploadingPtrList &rUploadList = theApp.uploadqueue->GetUploadListTS(&pcsUploadListRead); + CSingleLock lockUploadListRead(pcsUploadListRead, TRUE); + ASSERT(lockUploadListRead.IsLocked()); + bool bFound = (rUploadList.Find(pStruct) != NULL); + + // all important prechecks done, create the packets + if (bFound && !bReadError) { + // Keep the uploadlist locked while working with the client object. + // Instead of sending the packets immediately, we store them + // and send after we have released the uploadlist lock - + // just to be sure there is no chance of a deadlock (now or in future version, also it doesn't cost us much) + CPacketList packetsList; + CUpDownClient *pClient = pStruct->m_pClient; + bool bPeerCache = pClient->IsUploadingToPeerCache(); + CClientReqSocket *pSocket = bPeerCache ? pClient->m_pPCUpSocket : pClient->socket; + if (pSocket && (bPeerCache || pSocket->IsConnected())) { + // Try to use compression whenever possible (see CreatePackedPackets notes) + if (bPeerCache) + CreatePeerCachePackets(*pOvRead, packetsList); + else if (pKnownFile->bCompress) + CreatePackedPackets(*pOvRead, packetsList); + else + CreateStandardPackets(*pOvRead, packetsList); + + m_bSignalThrottler = true; + } else + theApp.QueueDebugLogLineEx(LOG_ERROR, _T("ReadCompletionRoutine: Client has no connected socket, %s"), (LPCTSTR)pClient->DbgGetClientInfo(true)); + + lockUploadListRead.Unlock(); + + // now send out all packets we have made. By default, our socket object is not safe + // to use now either, because we have no lock on itself (to make sure it is not deleted) + // however the way we handle sockets, they cannot get deleted directly (takes 10s), + // so this isn't a problem in our case + while (!packetsList.IsEmpty() && pSocket != NULL) { + Packet *packet = packetsList.RemoveHead(); + pSocket->SendPacket(packet, false, packet->uStatsPayLoad); } - m_bSignalThrottler = true; - } - - lockUploadListRead.Unlock(); - - // now send out all packets we made. By default, our socket object is not safe to use neither now, because we have no lock on itself (to make sure it is not deleted) - // however the way we handle sockets, they cannot get deleted directly (takes 10s), so this isn't a problem in our case - while (!packetsList.IsEmpty() && pSocket != NULL) { - Packet *packet = packetsList.RemoveHead(); - pSocket->SendPacket(packet, false, packet->uStatsPayLoad); + } else { // bReadError is true + if (bFound) + pStruct->m_bIOError = true; + else + theApp.QueueDebugLogLineEx(LOG_WARNING, _T("ReadCompletionRoutine: Client not found in uploadlist when reading finished; discarding block")); + lockUploadListRead.Unlock(); } - } else { // bError - if (bFound) - pOverlappedExStruct->pUploadClientStruct->m_bIOError = true; - lockUploadListRead.Unlock(); } - } + } else if (pKnownFile) + DissociateFile(pKnownFile); // cleanup - ReleaseOvOpenFile(pOverlappedExStruct->pFileStruct); - delete[] pOverlappedExStruct->pBuffer; - delete pOverlappedExStruct; -} - -bool CUploadDiskIOThread::ReleaseOvOpenFile(OpenOvFile_Struct *pOpenOvFileStruct) -{ - POSITION pos = m_listOpenFiles.Find(pOpenOvFileStruct); - if (pos) { - pOpenOvFileStruct->nInUse--; - if (pOpenOvFileStruct->nInUse == 0) { - VERIFY(::CloseHandle(pOpenOvFileStruct->hFile)); - m_listOpenFiles.RemoveAt(pos); - delete pOpenOvFileStruct; - } - return true; - } - ASSERT(0); - return false; + delete[] pOvRead->pBuffer; + delete pOvRead; } bool CUploadDiskIOThread::ShouldCompressBasedOnFilename(const CString &strFileName) { - int pos = strFileName.ReverseFind(_T('.')); - if (pos < 0) - return true; - const CString &strExt(strFileName.Mid(pos + 1).MakeLower()); + LPCTSTR pDot = ::PathFindExtension(strFileName); + CString strExt(pDot + static_cast(*pDot != _T('\0'))); + strExt.MakeLower(); if (strExt == _T("avi")) return !thePrefs.GetDontCompressAvi(); - return strExt != _T("zip") && strExt != _T("7z") && strExt != _T("rar") && strExt != _T("cbz") && strExt != _T("cbr") && strExt != _T("ace") && strExt != _T("ogm"); + return strExt != _T("zip") && strExt != _T("rar") && strExt != _T("7z") && strExt != _T("cbz") && strExt != _T("cbr") && strExt != _T("ace") && strExt != _T("ogm"); } -void CUploadDiskIOThread::CreateStandardPackets(byte *pbyData, uint64 uStartOffset, uint64 uEndOffset, bool bFromPF, CPacketList &rOutPacketList, const uchar *pucMD4FileHash, const CString &strDbgClientInfo) +void CUploadDiskIOThread::CreateStandardPackets(const OverlappedRead_Struct &OverlappedRead, CPacketList &rOutPacketList) { - uint32 togo = (uint32)(uEndOffset - uStartOffset); - CMemFile memfile((BYTE*)pbyData, togo); - uint32 nPacketSize = (togo > 10240u) ? togo / (togo / 10240u) : togo; - + const uchar *pucMD4FileHash = OverlappedRead.pFile->GetFileHash(); + bool bIsPartFile = OverlappedRead.pFile->IsPartFile(); + CString sDbgClientInfo; + if (thePrefs.GetDebugClientTCPLevel() > 0) + sDbgClientInfo = OverlappedRead.pUploadClientStruct->m_pClient->DbgGetClientInfo(true); + + uint32 togo = (uint32)(OverlappedRead.uEndOffset - OverlappedRead.uStartOffset); + CMemFile memfile((BYTE*)OverlappedRead.pBuffer, togo); while (togo) { - if (togo < nPacketSize * 2) - nPacketSize = togo; - ASSERT(nPacketSize); + uint32 nPacketSize = (togo < 13000) ? togo : 10240u; togo -= nPacketSize; - uint64 endpos = (uEndOffset - togo); - uint64 statpos = endpos - nPacketSize; + uint64 endpos = OverlappedRead.uEndOffset - togo; + uint64 startpos = endpos - nPacketSize; + LPCTSTR sOp; Packet *packet; - if (statpos > _UI32_MAX || endpos > _UI32_MAX) { - packet = new Packet(OP_SENDINGPART_I64, nPacketSize + 32, OP_EMULEPROT, bFromPF); + if (endpos > _UI32_MAX) { + packet = new Packet(OP_SENDINGPART_I64, nPacketSize + 32, OP_EMULEPROT, bIsPartFile); md4cpy(&packet->pBuffer[0], pucMD4FileHash); - PokeUInt64(&packet->pBuffer[16], statpos); + PokeUInt64(&packet->pBuffer[16], startpos); PokeUInt64(&packet->pBuffer[24], endpos); memfile.Read(&packet->pBuffer[32], nPacketSize); theStats.AddUpDataOverheadFileRequest(32); + sOp = _T("OP_SendingPart_I64"); } else { - packet = new Packet(OP_SENDINGPART, nPacketSize + 24, OP_EDONKEYPROT, bFromPF); + packet = new Packet(OP_SENDINGPART, nPacketSize + 24, OP_EDONKEYPROT, bIsPartFile); md4cpy(&packet->pBuffer[0], pucMD4FileHash); - PokeUInt32(&packet->pBuffer[16], (uint32)statpos); + PokeUInt32(&packet->pBuffer[16], (uint32)startpos); PokeUInt32(&packet->pBuffer[20], (uint32)endpos); memfile.Read(&packet->pBuffer[24], nPacketSize); theStats.AddUpDataOverheadFileRequest(24); + sOp = _T("OP_SendingPart"); } if (thePrefs.GetDebugClientTCPLevel() > 0) { - Debug(_T(">>> %-20hs to %s; %s\n"), _T("OP_SendingPart"), (LPCTSTR)strDbgClientInfo, (LPCTSTR)md4str(pucMD4FileHash)); - Debug(_T(" Start=%I64u End=%I64u Size=%u\n"), statpos, endpos, nPacketSize); + Debug(_T(">>> %-20s to %s; %s\n"), sOp, (LPCTSTR)sDbgClientInfo, (LPCTSTR)md4str(pucMD4FileHash)); + Debug(_T(" Start=%I64u End=%I64u Size=%u\n"), startpos, endpos, nPacketSize); } packet->uStatsPayLoad = nPacketSize; rOutPacketList.AddTail(packet); } } -void CUploadDiskIOThread::CreatePackedPackets(byte *pbyData, uint64 uStartOffset, uint64 uEndOffset, bool bFromPF, CPacketList &rOutPacketList, const uchar *pucMD4FileHash, const CString &strDbgClientInfo) +void CUploadDiskIOThread::CreatePackedPackets(const OverlappedRead_Struct &OverlappedRead, CPacketList &rOutPacketList) { + const uint64 uStartOffset = OverlappedRead.uStartOffset; + const uint64 uEndOffset = OverlappedRead.uEndOffset; + const uchar *pucMD4FileHash = OverlappedRead.pFile->GetFileHash(); + bool bIsPartFile = OverlappedRead.pFile->IsPartFile(); + uint32 togo = (uint32)(uEndOffset - uStartOffset); uLongf newsize = togo + 300; BYTE *output = new BYTE[newsize]; - int result = compress2(output, &newsize, pbyData, togo, 9); - if (result != Z_OK || togo <= newsize) { + + // Use the lowest compression level 1 instead of the highest 9 because typically for 10240 blocks: + // - compressed size difference is usually small enough (~4% for .exe, .avi, .pdf and 12% for .c text) + // - time was 1.5-2.5 better + // Of course, throughput of the deflate() routine depends on processor and data bytes, + // but should not be the bottleneck because 50-70 MB/s rates were seen when using one CPU core. + if (compress2(output, &newsize, OverlappedRead.pBuffer, togo, 1) != Z_OK || togo <= newsize) { delete[] output; - CreateStandardPackets(pbyData, uStartOffset, uEndOffset, bFromPF, rOutPacketList, pucMD4FileHash, strDbgClientInfo); + CreateStandardPackets(OverlappedRead, rOutPacketList); return; } + CString sDbgClientInfo; + if (thePrefs.GetDebugClientTCPLevel() > 0) + sDbgClientInfo = OverlappedRead.pUploadClientStruct->m_pClient->DbgGetClientInfo(true); + CMemFile memfile(output, newsize); uint32 oldSize = togo; togo = newsize; - uint32 nPacketSize = (togo > 10240u) ? togo / (togo / 10240u) : togo; uint32 totalPayloadSize = 0; while (togo) { - if (togo < nPacketSize * 2) - nPacketSize = togo; - ASSERT(nPacketSize); + uint32 nPacketSize = (togo < 13000) ? togo : 10240u; togo -= nPacketSize; - uint64 statpos = uStartOffset; Packet *packet; - if (uStartOffset > UINT32_MAX || uEndOffset > UINT32_MAX) { - packet = new Packet(OP_COMPRESSEDPART_I64, nPacketSize + 28, OP_EMULEPROT, bFromPF); + LPCTSTR sOp; + if (uEndOffset > UINT32_MAX) { + packet = new Packet(OP_COMPRESSEDPART_I64, nPacketSize + 28, OP_EMULEPROT, bIsPartFile); md4cpy(&packet->pBuffer[0], pucMD4FileHash); - PokeUInt64(&packet->pBuffer[16], statpos); + PokeUInt64(&packet->pBuffer[16], uStartOffset); PokeUInt32(&packet->pBuffer[24], newsize); memfile.Read(&packet->pBuffer[28], nPacketSize); + sOp = _T("OP_CompressedPart_I64"); } else { - packet = new Packet(OP_COMPRESSEDPART, nPacketSize + 24, OP_EMULEPROT, bFromPF); + packet = new Packet(OP_COMPRESSEDPART, nPacketSize + 24, OP_EMULEPROT, bIsPartFile); md4cpy(&packet->pBuffer[0], pucMD4FileHash); - PokeUInt32(&packet->pBuffer[16], (uint32)statpos); + PokeUInt32(&packet->pBuffer[16], (uint32)uStartOffset); PokeUInt32(&packet->pBuffer[20], newsize); memfile.Read(&packet->pBuffer[24], nPacketSize); + sOp = _T("OP_CompressedPart"); } if (thePrefs.GetDebugClientTCPLevel() > 0) { - Debug(_T(">>> %-20hs to %s; %s\n"), _T("OP_CompressedPart"), (LPCTSTR)strDbgClientInfo, (LPCTSTR)md4str(pucMD4FileHash)); - Debug(_T(" Start=%I64u BlockSize=%u Size=%u\n"), statpos, newsize, nPacketSize); + Debug(_T(">>> %-20s to %s; %s\n"), sOp, (LPCTSTR)sDbgClientInfo, (LPCTSTR)md4str(pucMD4FileHash)); + Debug(_T(" Start=%I64u BlockSize=%u Size=%u\n"), uStartOffset, newsize, nPacketSize); } // approximate payload size - uint32 payloadSize = nPacketSize * oldSize / newsize; - - if (togo == 0 && totalPayloadSize + payloadSize < oldSize) - payloadSize = oldSize - totalPayloadSize; + uint32 payloadSize = togo ? nPacketSize * oldSize / newsize : oldSize - totalPayloadSize; totalPayloadSize += payloadSize; @@ -546,23 +470,25 @@ void CUploadDiskIOThread::CreatePackedPackets(byte *pbyData, uint64 uStartOffset packet->uStatsPayLoad = payloadSize; rOutPacketList.AddTail(packet); } + memfile.Close(); delete[] output; } // not tested for the new threaded upload, if we ever use the PeerCache code again, take a look before -void CUploadDiskIOThread::CreatePeerCachePackets(byte *pbyData, uint64 uStartOffset, uint64 uEndOffset, uint64 uFilesize, bool bFromPF, CPacketList &rOutPacketList, const uchar* /*pucMD4FileHash*/, CUpDownClient *pClient) +void CUploadDiskIOThread::CreatePeerCachePackets(const OverlappedRead_Struct &OverlappedRead, CPacketList &rOutPacketList) { - uint32 togo = (uint32)(uEndOffset - uStartOffset); - uint32 nPacketSize = (togo > 10240) ? togo / (togo / 10240u) : togo; + byte *pbyData = OverlappedRead.pBuffer; + uint64 uFileSize = (uint64)OverlappedRead.pFile->GetFileSize(); + bool bIsPartFile = OverlappedRead.pFile->IsPartFile(); + uint32 togo = (uint32)(OverlappedRead.uEndOffset - OverlappedRead.uStartOffset); + CUpDownClient *pClient = OverlappedRead.pUploadClientStruct->m_pClient; + ASSERT(uFileSize); while (togo) { - if (togo < nPacketSize * 2) - nPacketSize = togo; - ASSERT(nPacketSize); + uint32 nPacketSize = (togo < 13000) ? togo : 10240u; togo -= nPacketSize; - ASSERT(uFilesize != 0); - CSafeMemFile dataHttp(10240u); + CSafeMemFile dataHttp(nPacketSize + 512); //additional space for an http header if (pClient->GetHttpSendState() == 0) { CStringA str; str.Format("HTTP/1.0 206\r\n" @@ -571,44 +497,37 @@ void CUploadDiskIOThread::CreatePeerCachePackets(byte *pbyData, uint64 uStartOff "Content-Length: %u\r\n" "Server: eMule/%S\r\n" "\r\n" - , uStartOffset, uEndOffset - 1, uFilesize - , (unsigned)(uEndOffset - uStartOffset) + , OverlappedRead.uStartOffset, OverlappedRead.uEndOffset - 1, uFileSize + , (unsigned)(OverlappedRead.uEndOffset - OverlappedRead.uStartOffset) , (LPCTSTR)theApp.m_strCurVersionLong); dataHttp.Write((LPCSTR)str, str.GetLength()); theStats.AddUpDataOverheadFileRequest((uint32)dataHttp.GetLength()); pClient->SetHttpSendState(1); - /*if (thePrefs.GetDebugClientTCPLevel() > 0){ - DebugSend("PeerCache-HTTP", this, pucMD4FileHash); - Debug(_T(" %hs\n"), str); + /*if (thePrefs.GetDebugClientTCPLevel() > 0) { + DebugSend("PeerCache-HTTP", this, pucMD4FileHash); + Debug(_T(" %hs\n"), str); }*/ } dataHttp.Write(pbyData, nPacketSize); pbyData += nPacketSize; - /*if (thePrefs.GetDebugClientTCPLevel() > 1){ - DebugSend("PeerCache-HTTP data", this, GetUploadFileID()); - Debug(_T(" Start=%I64u End=%I64u Size=%u\n"), statpos, endpos, nPacketSize); + /*if (thePrefs.GetDebugClientTCPLevel() > 1) { + DebugSend("PeerCache-HTTP data", this, GetUploadFileID()); + Debug(_T(" Start=%I64u End=%I64u Size=%u\n"), startpos, endpos, nPacketSize); }*/ - UINT uRawPacketSize = (UINT)dataHttp.GetLength(); - LPBYTE pRawPacketData = dataHttp.Detach(); - CRawPacket *packet = new CRawPacket((char*)pRawPacketData, uRawPacketSize, bFromPF); + char *pRawPacketData = (char*)dataHttp.Detach(); + CRawPacket *packet = new CRawPacket(pRawPacketData, (UINT)dataHttp.GetLength(), bIsPartFile); packet->uStatsPayLoad = nPacketSize; rOutPacketList.AddTail(packet); free(pRawPacketData); } } -void CUploadDiskIOThread::NewBlockRequestsAvailable() -{ - if (m_bRun) - m_eventNewBlockRequests.SetEvent(); -} - -void CUploadDiskIOThread::SocketNeedsMoreData() +void CUploadDiskIOThread::WakeUpCall() { if (m_bRun) - m_eventSocketNeedsData.SetEvent(); + PostQueuedCompletionStatus(m_hPort, 0, (ULONG_PTR)(~0), NULL); } \ No newline at end of file diff --git a/srchybrid/UploadDiskIOThread.h b/srchybrid/UploadDiskIOThread.h index 2b0a4589..ebc53d5e 100644 --- a/srchybrid/UploadDiskIOThread.h +++ b/srchybrid/UploadDiskIOThread.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -17,34 +17,23 @@ #pragma once -struct OpenOvFile_Struct -{ - uchar ucMD4FileHash[16]; - uint64 uFileSize; - HANDLE hFile; - uint32 nInUse; - bool bStatsIsPartfile; - bool bCompress; -}; +class Packet; +class CUpDownClient; +typedef CTypedPtrList CPacketList; struct UploadingToClient_Struct; -class CUploadDiskIOThread; -struct OverlappedEx_Struct + +struct OverlappedRead_Struct { OVERLAPPED oOverlap; // must be the first member - OpenOvFile_Struct *pFileStruct; + CKnownFile *pFile; UploadingToClient_Struct *pUploadClientStruct; uint64 uStartOffset; uint64 uEndOffset; BYTE *pBuffer; - DWORD dwRead; + POSITION pos; }; -class Packet; -typedef CTypedPtrList CPacketList; - -class CUpDownClient; - class CUploadDiskIOThread : public CWinThread { DECLARE_DYNCREATE(CUploadDiskIOThread) @@ -54,51 +43,30 @@ class CUploadDiskIOThread : public CWinThread CUploadDiskIOThread(const CUploadDiskIOThread&) = delete; CUploadDiskIOThread& operator=(const CUploadDiskIOThread&) = delete; - void NewBlockRequestsAvailable(); - void SocketNeedsMoreData(); - void EndThread(); - static bool ShouldCompressBasedOnFilename(const CString &strFileName); - - uint32 dbgDataReadPending; -protected: - + void EndThread(); //completionkey == 0 + void WakeUpCall(); //completionkey == (ULONG_PTR)(~0) + static void DissociateFile(CKnownFile *pFile); private: static UINT AFX_CDECL RunProc(LPVOID pParam); UINT RunInternal(); + bool AssociateFile(CKnownFile *pFile); + static bool ShouldCompressBasedOnFilename(const CString &strFileName); void StartCreateNextBlockPackage(UploadingToClient_Struct *pUploadClientStruct); - bool ReleaseOvOpenFile(OpenOvFile_Struct *pOpenOvFileStruct); - void ReadCompletionRoutine(DWORD dwErrorCode, DWORD dwBytesRead, OverlappedEx_Struct *pOverlappedExStruct); - - static void CreateStandardPackets(byte *pbyData, uint64 uStartOffset, uint64 uEndOffset, bool bFromPF, CPacketList &rOutPacketList, const uchar *pucMD4FileHash, const CString &strDbgClientInfo); - static void CreatePackedPackets(byte *pbyData, uint64 uStartOffset, uint64 uEndOffset, bool bFromPF, CPacketList &rOutPacketList, const uchar *pucMD4FileHash, const CString &strDbgClientInfo); - static void CreatePeerCachePackets(byte *pbyData, uint64 uStartOffset, uint64 uEndOffset, uint64 uFilesize, bool bFromPF, CPacketList &rOutPacketList, const uchar *pucMD4FileHash, CUpDownClient *pClient); - - CEvent *m_eventThreadEnded; - CEvent m_eventNewBlockRequests; - CEvent m_eventAsyncIOFinished; - CEvent m_eventSocketNeedsData; - CTypedPtrList m_listOpenFiles; - CTypedPtrList m_listPendingIO; - CTypedPtrList m_listFinishedIO; - bool m_bSignalThrottler; - volatile bool m_bRun; -}; + void ReadCompletionRoutine(DWORD dwRead, const OverlappedRead_Struct *pOvRead); -class CSyncHelper -{ -public: - CSyncHelper() - : m_pFile() - { - } + static void CreatePackedPackets(const OverlappedRead_Struct &OverlappedRead, CPacketList &rOutPacketList); + static void CreatePeerCachePackets(const OverlappedRead_Struct &OverlappedRead, CPacketList &rOutPacketList); + static void CreateStandardPackets(const OverlappedRead_Struct &OverlappedRead, CPacketList &rOutPacketList); - ~CSyncHelper() - { - if (m_pFile) - m_pFile->Unlock(); - } + CEvent m_eventThreadEnded; + CTypedPtrList m_listPendingIO; - CSyncObject *m_pFile; + HANDLE m_hPort; + volatile bool m_bRun; + bool m_bSignalThrottler; +#ifdef _DEBUG + uint64 dbgDataReadPending; +#endif }; \ No newline at end of file diff --git a/srchybrid/UploadListCtrl.cpp b/srchybrid/UploadListCtrl.cpp index 54c0f2ef..a6e53748 100644 --- a/srchybrid/UploadListCtrl.cpp +++ b/srchybrid/UploadListCtrl.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -19,7 +19,7 @@ #include "UploadListCtrl.h" #include "TransferWnd.h" #include "TransferDlg.h" -#include "otherfunctions.h" +#include "UpDownClient.h" #include "MenuCmds.h" #include "ClientDetailDialog.h" #include "KademliaWnd.h" @@ -28,13 +28,11 @@ #include "MemDC.h" #include "KnownFile.h" #include "SharedFileList.h" -#include "UpDownClient.h" #include "ClientCredits.h" #include "ChatWnd.h" #include "kademlia/kademlia/Kademlia.h" #include "kademlia/net/KademliaUDPListener.h" #include "UploadQueue.h" -#include "ToolTipCtrlX.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -57,16 +55,10 @@ END_MESSAGE_MAP() CUploadListCtrl::CUploadListCtrl() : CListCtrlItemWalk(this) { - m_tooltip = new CToolTipCtrlX; SetGeneralPurposeFind(true); SetSkinKey(_T("UploadsLv")); } -CUploadListCtrl::~CUploadListCtrl() -{ - delete m_tooltip; -} - void CUploadListCtrl::Init() { SetPrefsKey(_T("UploadListCtrl")); @@ -74,26 +66,26 @@ void CUploadListCtrl::Init() CToolTipCtrl *tooltip = GetToolTips(); if (tooltip) { - m_tooltip->SubclassWindow(tooltip->m_hWnd); + m_tooltip.SubclassWindow(tooltip->m_hWnd); tooltip->ModifyStyle(0, TTS_NOPREFIX); - tooltip->SetDelayTime(TTDT_AUTOPOP, 20000); + tooltip->SetDelayTime(TTDT_AUTOPOP, SEC2MS(20)); tooltip->SetDelayTime(TTDT_INITIAL, SEC2MS(thePrefs.GetToolTipDelay())); } - InsertColumn(0, GetResString(IDS_QL_USERNAME), LVCFMT_LEFT, DFLT_CLIENTNAME_COL_WIDTH); - InsertColumn(1, GetResString(IDS_FILE), LVCFMT_LEFT, DFLT_FILENAME_COL_WIDTH); - InsertColumn(2, GetResString(IDS_DL_SPEED), LVCFMT_RIGHT,DFLT_DATARATE_COL_WIDTH); - InsertColumn(3, GetResString(IDS_DL_TRANSF), LVCFMT_RIGHT,DFLT_DATARATE_COL_WIDTH); - InsertColumn(4, GetResString(IDS_WAITED), LVCFMT_LEFT, 60); - InsertColumn(5, GetResString(IDS_UPLOADTIME), LVCFMT_LEFT, 80); - InsertColumn(6, GetResString(IDS_STATUS), LVCFMT_LEFT, 100); - InsertColumn(7, GetResString(IDS_UPSTATUS), LVCFMT_LEFT, DFLT_PARTSTATUS_COL_WIDTH); + InsertColumn(0, _T(""), LVCFMT_LEFT, DFLT_CLIENTNAME_COL_WIDTH); //IDS_QL_USERNAME + InsertColumn(1, _T(""), LVCFMT_LEFT, DFLT_FILENAME_COL_WIDTH); //IDS_FILE + InsertColumn(2, _T(""), LVCFMT_RIGHT,DFLT_DATARATE_COL_WIDTH); //IDS_DL_SPEED + InsertColumn(3, _T(""), LVCFMT_RIGHT,DFLT_DATARATE_COL_WIDTH); //IDS_DL_TRANSF + InsertColumn(4, _T(""), LVCFMT_LEFT, 60); //IDS_WAITED + InsertColumn(5, _T(""), LVCFMT_LEFT, 80); //IDS_UPLOADTIME + InsertColumn(6, _T(""), LVCFMT_LEFT, 100); //IDS_STATUS + InsertColumn(7, _T(""), LVCFMT_LEFT, DFLT_PARTSTATUS_COL_WIDTH); //IDS_UPSTATUS SetAllIcons(); Localize(); LoadSettings(); SetSortArrow(); - SortItems(SortProc, GetSortItem() + (GetSortAscending() ? 0 : 100)); + SortItems(SortProc, MAKELONG(GetSortItem(), !GetSortAscending())); } void CUploadListCtrl::Localize() @@ -104,15 +96,7 @@ void CUploadListCtrl::Localize() , IDS_UPLOADTIME, IDS_STATUS, IDS_UPSTATUS }; - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); - HDITEM hdi; - hdi.mask = HDI_TEXT; - - for (int i = 0; i < _countof(uids); ++i) { - CString strRes(GetResString(uids[i])); - hdi.pszText = const_cast((LPCTSTR)strRes); - pHeaderCtrl->SetItem(i, &hdi); - } + LocaliseHeaderCtrl(uids, _countof(uids)); } void CUploadListCtrl::OnSysColorChange() @@ -124,70 +108,69 @@ void CUploadListCtrl::OnSysColorChange() void CUploadListCtrl::SetAllIcons() { ApplyImageList(NULL); - m_pImageList = theApp.emuledlg->transferwnd->GetClientIconList(); // Apply the image list also to the listview control, even if we use our own 'DrawItem'. // This is needed to give the listview control a chance to initialize the row height. ASSERT((GetStyle() & LVS_SHAREIMAGELISTS) != 0); + m_pImageList = &theApp.emuledlg->GetClientIconList(); VERIFY(ApplyImageList(*m_pImageList) == NULL); } void CUploadListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { - if (theApp.IsClosing() || !lpDrawItemStruct->itemData) + if (!lpDrawItemStruct->itemData || theApp.IsClosing()) return; - CMemoryDC dc(CDC::FromHandle(lpDrawItemStruct->hDC), &lpDrawItemStruct->rcItem); + CRect rcItem(lpDrawItemStruct->rcItem); + CMemoryDC dc(CDC::FromHandle(lpDrawItemStruct->hDC), rcItem); BOOL bCtrlFocused; InitItemMemDC(dc, lpDrawItemStruct, bCtrlFocused); - CRect rcItem(lpDrawItemStruct->rcItem); - CRect rcClient; + RECT rcClient; GetClientRect(&rcClient); const CUpDownClient *client = reinterpret_cast(lpDrawItemStruct->itemData); if (client->GetSlotNumber() > (UINT)theApp.uploadqueue->GetActiveUploadsCount()) dc.SetTextColor(::GetSysColor(COLOR_GRAYTEXT)); - CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); + const CHeaderCtrl *pHeaderCtrl = GetHeaderCtrl(); int iCount = pHeaderCtrl->GetItemCount(); - rcItem.right = rcItem.left - sm_iLabelOffset; - rcItem.left += sm_iIconOffset; + LONG itemLeft = rcItem.left; + LONG iIconY = max((rcItem.Height() - 15) / 2, 0); for (int iCurrent = 0; iCurrent < iCount; ++iCurrent) { int iColumn = pHeaderCtrl->OrderToIndex(iCurrent); - if (!IsColumnHidden(iColumn)) { - UINT uDrawTextAlignment; - int iColumnWidth = GetColumnWidth(iColumn, uDrawTextAlignment); - rcItem.right += iColumnWidth; - if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) { - const CString &sItem(GetItemDisplayText(client, iColumn)); - switch (iColumn) { - case 0: - { - int iImage; - UINT uOverlayImage; - client->GetDisplayImage(iImage, uOverlayImage); - - int iIconPosY = (rcItem.Height() > 16) ? ((rcItem.Height() - 16) / 2) : 1; - POINT point = {rcItem.left, rcItem.top + iIconPosY}; - m_pImageList->Draw(dc, iImage, point, ILD_NORMAL | INDEXTOOVERLAYMASK(uOverlayImage)); - - rcItem.left += 16 + sm_iLabelOffset; - dc.DrawText(sItem, -1, &rcItem, MLC_DT_TEXT | uDrawTextAlignment); - rcItem.left -= 16; - rcItem.right -= sm_iSubItemInset; - } - break; - case 7: - ++rcItem.top; - --rcItem.bottom; - client->DrawUpStatusBar(dc, &rcItem, false, thePrefs.UseFlatBar()); - ++rcItem.bottom; - --rcItem.top; - break; - default: - dc.DrawText(sItem, -1, &rcItem, MLC_DT_TEXT | uDrawTextAlignment); + if (IsColumnHidden(iColumn)) + continue; + + UINT uDrawTextAlignment; + int iColumnWidth = GetColumnWidth(iColumn, uDrawTextAlignment); + rcItem.left = itemLeft; + rcItem.right = itemLeft + iColumnWidth; + if (rcItem.left < rcItem.right && HaveIntersection(rcClient, rcItem)) { + const CString &sItem(GetItemDisplayText(client, iColumn)); + switch (iColumn) { + case 0: //user name + { + int iImage; + UINT uOverlayImage; + client->GetDisplayImage(iImage, uOverlayImage); + + rcItem.left += sm_iIconOffset; + const POINT point = { rcItem.left, rcItem.top + iIconY }; + m_pImageList->Draw(dc, iImage, point, ILD_NORMAL | INDEXTOOVERLAYMASK(uOverlayImage)); + rcItem.left += 16 + sm_iLabelOffset - sm_iSubItemInset; } + default: //any text column + rcItem.left += sm_iSubItemInset; + rcItem.right -= sm_iSubItemInset; + dc.DrawText(sItem, -1, &rcItem, MLC_DT_TEXT | uDrawTextAlignment); + break; + case 7: //upload status bar + ++rcItem.top; + --rcItem.bottom; + client->DrawUpStatusBar(dc, &rcItem, false, thePrefs.UseFlatBar()); + ++rcItem.bottom; + --rcItem.top; } - rcItem.left += iColumnWidth; } + itemLeft += iColumnWidth; } DrawFocusRect(dc, &lpDrawItemStruct->rcItem, lpDrawItemStruct->itemState & ODS_FOCUS, bCtrlFocused, lpDrawItemStruct->itemState & ODS_SELECTED); @@ -211,7 +194,7 @@ CString CUploadListCtrl::GetItemDisplayText(const CUpDownClient *client, int iS } break; case 2: - sText = CastItoXBytes(client->GetDatarate(), false, true); + sText = CastItoXBytes(client->GetUploadDatarate(), false, true); break; case 3: // NOTE: If you change (add/remove) anything which is displayed here, update also the sorting part. @@ -240,16 +223,16 @@ CString CUploadListCtrl::GetItemDisplayText(const CUpDownClient *client, int iS void CUploadListCtrl::OnLvnGetDispInfo(LPNMHDR pNMHDR, LRESULT *pResult) { if (!theApp.IsClosing()) { - // Although we have an owner drawn listview control we store the text for the primary item in the listview, to be - // capable of quick searching those items via the keyboard. Because our listview items may change their contents, - // we do this via a text callback function. The listview control will send us the LVN_DISPINFO notification if - // it needs to know the contents of the primary item. + // Although we have an owner drawn listview control we store the text for the primary item in the + // listview, to be capable of quick searching those items via the keyboard. Because our listview + // items may change their contents, we do this via a text callback function. The listview control + // will send us the LVN_DISPINFO notification if it needs to know the contents of the primary item. // - // But, the listview control sends this notification all the time, even if we do not search for an item. At least - // this notification is only sent for the visible items and not for all items in the list. Though, because this - // function is invoked *very* often, do *NOT* put any time consuming code in here. + // But, the listview control sends this notification all the time, even if we do not search for an item. + // At least this notification is only sent for the visible items and not for all items in the list. + // Though, because this function is invoked *very* often, do *NOT* put any time consuming code in here. // - // Vista: That callback is used to get the strings for the label tips for the sub(!) items. + // Vista: That callback is used to get the strings for the label tips for the sub(!)-items. // const LVITEMW &rItem = reinterpret_cast(pNMHDR)->item; if (rItem.mask & LVIF_TEXT) { @@ -297,10 +280,10 @@ void CUploadListCtrl::OnLvnGetInfoTip(LPNMHDR pNMHDR, LRESULT *pResult) void CUploadListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) { - NMLISTVIEW *pNMListView = reinterpret_cast(pNMHDR); + const LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); bool sortAscending; - if (GetSortItem() != pNMListView->iSubItem) { - switch (pNMListView->iSubItem) { + if (GetSortItem() != pNMLV->iSubItem) { + switch (pNMLV->iSubItem) { case 2: // Data rate case 3: // Session Up case 4: // Wait Time @@ -314,10 +297,9 @@ void CUploadListCtrl::OnLvnColumnClick(LPNMHDR pNMHDR, LRESULT *pResult) sortAscending = !GetSortAscending(); // Sort table - UpdateSortHistory(pNMListView->iSubItem + (sortAscending ? 0 : 100)); - SetSortArrow(pNMListView->iSubItem, sortAscending); - SortItems(SortProc, pNMListView->iSubItem + (sortAscending ? 0 : 100)); - + UpdateSortHistory(MAKELONG(pNMLV->iSubItem, !sortAscending)); + SetSortArrow(pNMLV->iSubItem, sortAscending); + SortItems(SortProc, MAKELONG(pNMLV->iSubItem, !sortAscending)); *pResult = 0; } @@ -325,16 +307,14 @@ int CALLBACK CUploadListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lP { const CUpDownClient *item1 = reinterpret_cast(lParam1); const CUpDownClient *item2 = reinterpret_cast(lParam2); - LPARAM iColumn = (lParamSort >= 100) ? lParamSort - 100 : lParamSort; + int iResult = 0; - switch (iColumn) { + switch (LOWORD(lParamSort)) { case 0: if (item1->GetUserName() && item2->GetUserName()) iResult = CompareLocaleStringNoCase(item1->GetUserName(), item2->GetUserName()); - else if (item1->GetUserName() == NULL) - iResult = 1; // place clients with no usernames at bottom - else if (item2->GetUserName() == NULL) - iResult = -1; // place clients with no usernames at bottom + else if (item1->GetUserName() == NULL || item2->GetUserName() == NULL) + iResult = 1; // place clients with no user names at the bottom break; case 1: { @@ -347,7 +327,7 @@ int CALLBACK CUploadListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lP } break; case 2: - iResult = CompareUnsigned(item1->GetDatarate(), item2->GetDatarate()); + iResult = CompareUnsigned(item1->GetUploadDatarate(), item2->GetUploadDatarate()); break; case 3: iResult = CompareUnsigned(item1->GetSessionUp(), item2->GetSessionUp()); @@ -367,14 +347,14 @@ int CALLBACK CUploadListCtrl::SortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lP iResult = CompareUnsigned(item1->GetUpPartCount(), item2->GetUpPartCount()); } - if (lParamSort >= 100) + if (HIWORD(lParamSort)) iResult = -iResult; - //call secondary sortorder, if this one results in equal + //call secondary sort order, if the first one resulted as equal if (iResult == 0) { - int dwNextSort = theApp.emuledlg->transferwnd->m_pwndTransfer->uploadlistctrl.GetNextSortOrder((int)lParamSort); - if (dwNextSort != -1) - iResult = SortProc(lParam1, lParam2, dwNextSort); + LPARAM iNextSort = theApp.emuledlg->transferwnd->m_pwndTransfer->uploadlistctrl.GetNextSortOrder(lParamSort); + if (iNextSort != -1) + iResult = SortProc(lParam1, lParam2, iNextSort); } return iResult; @@ -450,7 +430,7 @@ BOOL CUploadListCtrl::OnCommand(WPARAM wParam, LPARAM) Kademlia::CKademlia::Bootstrap(ntohl(client->GetIP()), client->GetKadPort()); } } - return true; + return TRUE; } void CUploadListCtrl::AddClient(const CUpDownClient *client) @@ -481,19 +461,17 @@ void CUploadListCtrl::RemoveClient(const CUpDownClient *client) void CUploadListCtrl::RefreshClient(const CUpDownClient *client) { - if (theApp.IsClosing() - || theApp.emuledlg->activewnd != theApp.emuledlg->transferwnd - || !theApp.emuledlg->transferwnd->m_pwndTransfer->uploadlistctrl.IsWindowVisible()) + if (theApp.emuledlg->activewnd == theApp.emuledlg->transferwnd + && !theApp.IsClosing() + && theApp.emuledlg->transferwnd->m_pwndTransfer->uploadlistctrl.IsWindowVisible()) { - return; + LVFINDINFO find; + find.flags = LVFI_PARAM; + find.lParam = (LPARAM)client; + int iItem = FindItem(&find); + if (iItem >= 0) + Update(iItem); } - - LVFINDINFO find; - find.flags = LVFI_PARAM; - find.lParam = (LPARAM)client; - int iItem = FindItem(&find); - if (iItem >= 0) - Update(iItem); } void CUploadListCtrl::ShowSelectedUserDetails() diff --git a/srchybrid/UploadListCtrl.h b/srchybrid/UploadListCtrl.h index e1192da5..563803f0 100644 --- a/srchybrid/UploadListCtrl.h +++ b/srchybrid/UploadListCtrl.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -17,17 +17,17 @@ #pragma once #include "MuleListCtrl.h" #include "ListCtrlItemWalk.h" +#include "ToolTipCtrlX.h" class CUpDownClient; -class CToolTipCtrlX; class CUploadListCtrl : public CMuleListCtrl, public CListCtrlItemWalk { DECLARE_DYNAMIC(CUploadListCtrl) + CImageList *m_pImageList; public: CUploadListCtrl(); - virtual ~CUploadListCtrl(); CUploadListCtrl(const CUploadListCtrl&) = delete; CUploadListCtrl& operator=(const CUploadListCtrl&) = delete; @@ -41,8 +41,7 @@ class CUploadListCtrl : public CMuleListCtrl, public CListCtrlItemWalk void ShowSelectedUserDetails(); protected: - CImageList *m_pImageList; - CToolTipCtrlX *m_tooltip; + CToolTipCtrlX m_tooltip; void SetAllIcons(); CString GetItemDisplayText(const CUpDownClient *client, int iSubItem) const; diff --git a/srchybrid/UploadQueue.cpp b/srchybrid/UploadQueue.cpp index 229fc6fc..f5ebedbf 100644 --- a/srchybrid/UploadQueue.cpp +++ b/srchybrid/UploadQueue.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -69,6 +69,7 @@ CUploadQueue::CUploadQueue() , failedupcount() , totaluploadtime() , m_nLastStartUpload() + , m_dwRemovedClientByScore(::GetTickCount()) , m_imaxscore() , m_dwLastCalculatedAverageCombinedFilePrioAndCredit() , m_fAverageCombinedFilePrioAndCredit() @@ -80,13 +81,12 @@ CUploadQueue::CUploadQueue() , m_dwLastResortedUploadSlots() , m_bStatisticsWaitingListDirty(true) { - VERIFY((h_timer = ::SetTimer(0, 0, 100, UploadTimer)) != 0); + VERIFY((h_timer = ::SetTimer(NULL, 0, 100, UploadTimer)) != 0); if (thePrefs.GetVerbose() && !h_timer) AddDebugLogLine(true, _T("Failed to create 'upload queue' timer - %s"), (LPCTSTR)GetErrorMessage(::GetLastError())); counter = 0; statsave = 0; i2Secs = 0; - m_dwRemovedClientByScore = ::GetTickCount(); } CUploadQueue::~CUploadQueue() @@ -111,14 +111,14 @@ CUpDownClient* CUploadQueue::FindBestClientInQueue() uint32 bestlowscore = 0; CUpDownClient *newclient = NULL; CUpDownClient *lowclient = NULL; - DWORD tNow = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); for (POSITION pos = waitinglist.GetHeadPosition(); pos != NULL;) { POSITION pos2 = pos; CUpDownClient *cur_client = waitinglist.GetNext(pos); //While we are going through this list. Lets check if a client appears to have left the network. ASSERT(cur_client->GetLastUpRequest()); - if ((tNow >= cur_client->GetLastUpRequest() + MAX_PURGEQUEUETIME) || !theApp.sharedfiles->GetFileByID(cur_client->GetUploadFileID())) { + if ((curTick >= cur_client->GetLastUpRequest() + MAX_PURGEQUEUETIME) || !theApp.sharedfiles->GetFileByID(cur_client->GetUploadFileID())) { //This client has either not been seen in a long time, or we no longer share the file he wanted any more. cur_client->ClearWaitStartTime(); RemoveFromWaitingQueue(pos2, true); @@ -169,32 +169,26 @@ void CUploadQueue::InsertInUploadingList(UploadingToClient_Struct *pNewClientUpl // Add it last theApp.uploadBandwidthThrottler->AddToStandardList(uploadinglist.GetCount(), pNewClientUploadStruct->m_pClient->GetFileUploadSocket()); - if (bNoLocking) - uploadinglist.AddTail(pNewClientUploadStruct); - else { + if (!bNoLocking) m_csUploadListMainThrdWriteOtherThrdsRead.Lock(); - uploadinglist.AddTail(pNewClientUploadStruct); + uploadinglist.AddTail(pNewClientUploadStruct); + if (!bNoLocking) m_csUploadListMainThrdWriteOtherThrdsRead.Unlock(); - } + pNewClientUploadStruct->m_pClient->SetSlotNumber((UINT)uploadinglist.GetCount()); } bool CUploadQueue::AddUpNextClient(LPCTSTR pszReason, CUpDownClient *directadd) { - CUpDownClient *newclient; + CUpDownClient *newclient = directadd; // select next client or use given client - if (directadd) - newclient = directadd; - else { + if (newclient == NULL) { newclient = FindBestClientInQueue(); - if (newclient) { - RemoveFromWaitingQueue(newclient, true); - theApp.emuledlg->transferwnd->ShowQueueCount(waitinglist.GetCount()); - } + if (newclient == NULL) + return false; } - - if (newclient == NULL) - return false; + RemoveFromWaitingQueue(newclient, true); + theApp.emuledlg->transferwnd->ShowQueueCount(waitinglist.GetCount()); if (!thePrefs.TransferFullChunks()) UpdateMaxClientScore(); // refresh score caching, now that the highest score is removed @@ -250,10 +244,7 @@ void CUploadQueue::UpdateActiveClientsInfo(DWORD curTick) AddDebugLogLine(false, _T("UploadQueue: Error! Throttler has more slots than UploadQueue! Throttler: %i UploadQueue: %i Tick: %i"), theApp.uploadBandwidthThrottler->GetStandardListSize(), uploadinglist.GetCount(), ::GetTickCount()); }*/ - if (tempHighest > uploadinglist.GetCount() + 1) - tempHighest = uploadinglist.GetCount() + 1; - - m_iHighestNumberOfFullyActivatedSlotsSinceLastCall = tempHighest; + m_iHighestNumberOfFullyActivatedSlotsSinceLastCall = min(tempHighest, uploadinglist.GetCount() + 1); // save some data about number of fully active clients int tempMaxRemoved = 0; @@ -306,8 +297,7 @@ void CUploadQueue::UpdateActiveClientsInfo(DWORD curTick) */ void CUploadQueue::Process() { - DWORD curTick = ::GetTickCount(); - + const DWORD curTick = ::GetTickCount(); UpdateActiveClientsInfo(curTick); if (ForceNewClient()) @@ -337,20 +327,26 @@ void CUploadQueue::Process() cur_client->SendOutOfPartReqsAndAddToWaitingQueue(); continue; } + // Increase the sockets buffer for fast uploads (was in UpdateUploadingStatisticsData()). + // This should be done in the throttling thread, but the throttler + // does not have access to the client's download rate + if (cur_client->GetUploadDatarate() > 100 * 1024) { + CEMSocket *sock = cur_client->GetFileUploadSocket(); + if (sock && (cur_client->m_ePeerCacheUpState != PCUS_WAIT_CACHE_REPLY)) + sock->UseBigSendBuffer(); + } - // check if the file id of the topmost block request matches with out current upload file, otherwise the IO thread will - // wait for us (only for this client of course) to fix it for cross-thread sync reasons + // check if the file id of the topmost block request matches the current upload file, otherwise + // the IO thread will wait for us (only for this client of course) to fix it for cross-thread sync reasons CSingleLock lockBlockLists(&pCurClientStruct->m_csBlockListsLock, TRUE); ASSERT(lockBlockLists.IsLocked()); // be careful what functions to call while having locks, RemoveFromUploadQueue could, // for example, lead to a deadlock here because it tries to get the uploadlist lock, // while the IO thread tries to fetch the uploadlist lock and then the blocklist lock - if (!pCurClientStruct->m_BlockRequests_queue.IsEmpty() - && !md4equ(((Requested_Block_Struct*)pCurClientStruct->m_BlockRequests_queue.GetHead())->FileID, cur_client->GetUploadFileID())) - { - Requested_Block_Struct *pHeadBlock = pCurClientStruct->m_BlockRequests_queue.GetHead(); + if (!pCurClientStruct->m_BlockRequests_queue.IsEmpty()) { + const Requested_Block_Struct *pHeadBlock = pCurClientStruct->m_BlockRequests_queue.GetHead(); if (!md4equ(pHeadBlock->FileID, cur_client->GetUploadFileID())) { - uchar aucNewID[16]; + uchar aucNewID[MDX_DIGEST_SIZE]; md4cpy(aucNewID, pHeadBlock->FileID); lockBlockLists.Unlock(); @@ -359,7 +355,7 @@ void CUploadQueue::Process() if (pCurrentUploadFile != NULL) cur_client->SetUploadFileID(pCurrentUploadFile); else - RemoveFromUploadQueue(cur_client, _T("Requested FileID in blockrequest not found in sharedfiles"), true); + RemoveFromUploadQueue(cur_client, _T("Requested FileID in block request not found in shared files"), true); } } } @@ -377,8 +373,8 @@ void CUploadQueue::Process() // Save time between each speed snapshot average_tick_list.AddTail(curTick); - // don't save more than 30 secs of data - while (average_tick_list.GetCount() > 3 && !average_friend_dr_list.IsEmpty() && ::GetTickCount() >= average_tick_list.GetHead() + SEC2MS(30)) { + // keep no more than 30 secs of data + while (average_tick_list.GetCount() > 3 && !average_friend_dr_list.IsEmpty() && curTick >= average_tick_list.GetHead() + SEC2MS(30)) { m_average_dr_sum -= average_dr_list.RemoveHead(); average_friend_dr_list.RemoveHead(); average_tick_list.RemoveHead(); @@ -403,15 +399,17 @@ bool CUploadQueue::AcceptNewClient(INT_PTR curUploadSlots) const if (curUploadSlots < max(MIN_UP_CLIENTS_ALLOWED, 4)) return true; + if (curUploadSlots >= MAX_UP_CLIENTS_ALLOWED) + return false; uint32 MaxSpeed; if (thePrefs.IsDynUpEnabled()) - MaxSpeed = theApp.lastCommonRouteFinder->GetUpload() / 1024u; + MaxSpeed = theApp.lastCommonRouteFinder->GetUpload() / 1024; else MaxSpeed = thePrefs.GetMaxUpload(); uint32 TargetRate = GetTargetClientDataRate(false); - if (curUploadSlots >= (INT_PTR)mini(datarate / GetTargetClientDataRate(true), MaxSpeed * 1024u / TargetRate)) + if (curUploadSlots >= (INT_PTR)(datarate / GetTargetClientDataRate(true)) || curUploadSlots >= (INT_PTR)(MaxSpeed * 1024 / TargetRate)) return false; return MaxSpeed != UNLIMITED @@ -451,7 +449,7 @@ bool CUploadQueue::ForceNewClient(bool allowEmptyWaitingQueue) uint32 MaxSpeed; if (thePrefs.IsDynUpEnabled()) - MaxSpeed = theApp.lastCommonRouteFinder->GetUpload() / 1024u; + MaxSpeed = theApp.lastCommonRouteFinder->GetUpload() / 1024; else MaxSpeed = thePrefs.GetMaxUpload(); @@ -471,23 +469,23 @@ bool CUploadQueue::ForceNewClient(bool allowEmptyWaitingQueue) } else { uint32 nMaxSlots; if (MaxSpeed > 25) - nMaxSlots = max((MaxSpeed * 1024u) / upPerClient, (uint32)(MIN_UP_CLIENTS_ALLOWED + 3)); + nMaxSlots = max((MaxSpeed * 1024) / upPerClient, (uint32)(MIN_UP_CLIENTS_ALLOWED + 3)); else if (MaxSpeed > 16) nMaxSlots = MIN_UP_CLIENTS_ALLOWED + 2; else if (MaxSpeed > 9) nMaxSlots = MIN_UP_CLIENTS_ALLOWED + 1; else nMaxSlots = MIN_UP_CLIENTS_ALLOWED; - //AddLogLine(true,"maxslots=%u, upPerClient=%u, datarateslot=%u|%u|%u",nMaxSlots,upPerClient,datarate/UPLOAD_CHECK_CLIENT_DR, datarate, UPLOAD_CHECK_CLIENT_DR); + //AddLogLine(true, "maxslots=%u, upPerClient=%u, datarateslot=%u|%u|%u", nMaxSlots, upPerClient, datarate / UPLOAD_CHECK_CLIENT_DR, datarate, UPLOAD_CHECK_CLIENT_DR); if ((uint32)curUploadSlots < nMaxSlots) return true; } /* - if(m_iHighestNumberOfFullyActivatedSlotsSinceLastCall > uploadinglist.GetCount()) { + if (m_iHighestNumberOfFullyActivatedSlotsSinceLastCall > uploadinglist.GetCount()) { // uploadThrottler requests another slot. If throttler says it needs another slot, we will allow more slots // than what we require ourself. Never allow more slots than to give each slot high enough average transfer speed, though (checked above). - //if(thePrefs.GetLogUlDlEvents() && !waitinglist.IsEmpty()) + //if (thePrefs.GetLogUlDlEvents() && !waitinglist.IsEmpty()) // AddDebugLogLine(false, _T("UploadQueue: Added new slot since throttler needs it. m_iHighestNumberOfFullyActivatedSlotsSinceLastCall: %i uploadinglist.GetCount(): %i tick: %i"), m_iHighestNumberOfFullyActivatedSlotsSinceLastCall, uploadinglist.GetCount(), ::GetTickCount()); return true; } @@ -559,7 +557,7 @@ void CUploadQueue::AddClientToQueue(CUpDownClient *client, bool bIgnoreTimelimit { return; } - client->AddAskedCount(); + client->IncrementAskedCount(); client->SetLastUpRequest(); if (!bIgnoreTimelimit) client->AddRequestCount(client->GetUploadFileID()); @@ -652,7 +650,7 @@ void CUploadQueue::AddClientToQueue(CUpDownClient *client, bool bIgnoreTimelimit client->SetCollectionUploadSlot(false); // cap the list - // the queue limit in prefs is only a soft limit. Hard limit is 25% higher, to let in + // the queue limit in prefs is only a soft limit. Hard limit is higher up to 25% to accept // powershare clients and other high ranking clients after soft limit has been reached INT_PTR softQueueLimit = thePrefs.GetQueueSize(); INT_PTR hardQueueLimit = softQueueLimit + max(softQueueLimit, 800) / 4; @@ -692,17 +690,17 @@ void CUploadQueue::AddClientToQueue(CUpDownClient *client, bool bIgnoreTimelimit float CUploadQueue::GetAverageCombinedFilePrioAndCredit() { - DWORD curTick = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); if (curTick >= m_dwLastCalculatedAverageCombinedFilePrioAndCredit + SEC2MS(5)) { m_dwLastCalculatedAverageCombinedFilePrioAndCredit = curTick; // TODO: is there a risk of overflow? I don't think so... - double sum = 0; + float sum = 0; for (POSITION pos = waitinglist.GetHeadPosition(); pos != NULL;) sum += waitinglist.GetNext(pos)->GetCombinedFilePrioAndCredit(); - m_fAverageCombinedFilePrioAndCredit = (float)(sum / waitinglist.GetCount()); + m_fAverageCombinedFilePrioAndCredit = sum / waitinglist.GetCount(); } return m_fAverageCombinedFilePrioAndCredit; @@ -837,18 +835,18 @@ bool CUploadQueue::CheckForTimeOver(const CUpDownClient *client) return true; } - // Cache current client score - const uint32 score = client->GetScore(true, true); - - // Check if another client has a bigger score - if (score < GetMaxClientScore() && ::GetTickCount() >= m_dwRemovedClientByScore) { - if (thePrefs.GetLogUlDlEvents()) - AddDebugLogLine(DLP_VERYLOW, false, _T("%s: Upload session ended due to score."), client->GetUserName()); - //Set timer to prevent too many upload slots getting kicked due to score. - //Upload slots are delayed by a min of 1 sec and the max score is reset every 5 sec. - //So, I choose 6 secs to make sure the max score it updated before doing this again. - m_dwRemovedClientByScore = ::GetTickCount() + SEC2MS(6); - return true; + // Check if another client has a higher score than the current client + if (client->GetScore(true, true) < GetMaxClientScore()) { + const DWORD curTick = ::GetTickCount(); + if (curTick >= m_dwRemovedClientByScore) { + if (thePrefs.GetLogUlDlEvents()) + AddDebugLogLine(DLP_VERYLOW, false, _T("%s: Upload session ended due to score."), client->GetUserName()); + //Set timer to prevent too many upload slots getting kicked due to score. + //Upload slots are delayed by at least 1 sec, and the max score is reset every 5 sec. + //So, I choose 6 secs to make sure the max score was updated before doing this again. + m_dwRemovedClientByScore = curTick + SEC2MS(6); + return true; + } } } @@ -892,17 +890,21 @@ VOID CALLBACK CUploadQueue::UploadTimer(HWND /*hwnd*/, UINT /*uMsg*/, UINT_PTR / // Elandal: ThreadSafeLogging <-- // ZZ:UploadSpeedSense --> - theApp.lastCommonRouteFinder->SetPrefs(thePrefs.IsDynUpEnabled() - , theApp.uploadqueue->GetDatarate() - , thePrefs.GetMinUpload() * 1024 - , ((thePrefs.GetMaxUpload() != 0) ? thePrefs.GetMaxUpload() : thePrefs.GetMaxGraphUploadRate(false)) * 1024 - , thePrefs.IsDynUpUseMillisecondPingTolerance() - , (thePrefs.GetDynUpPingTolerance() > 100) ? ((thePrefs.GetDynUpPingTolerance() - 100) / 100.0) : 0 - , thePrefs.GetDynUpPingToleranceMilliseconds() - , thePrefs.GetDynUpGoingUpDivider() - , thePrefs.GetDynUpGoingDownDivider() - , thePrefs.GetDynUpNumberOfPings() - , 20); // PENDING: Hard coded min pLowestPingAllowed + struct CurrentParamStruct cur; + cur.dPingTolerance = (thePrefs.GetDynUpPingTolerance() > 100) ? ((thePrefs.GetDynUpPingTolerance() - 100) / 100.0) : 0; + cur.uCurUpload = theApp.uploadqueue->GetDatarate(); + cur.uMinUpload = thePrefs.GetMinUpload(); + cur.uMaxUpload = (thePrefs.GetMaxUpload() ? thePrefs.GetMaxUpload() : thePrefs.GetMaxGraphUploadRate(false)); + cur.uPingToleranceMilliseconds = thePrefs.GetDynUpPingToleranceMilliseconds(); + cur.uGoingUpDivider = thePrefs.GetDynUpGoingUpDivider(); + cur.uGoingDownDivider = thePrefs.GetDynUpGoingDownDivider(); + cur.uNumberOfPingsForAverage = thePrefs.GetDynUpNumberOfPings(); + cur.uLowestInitialPingAllowed = 20; // PENDING: Hard coded min pLowestPingAllowed + cur.bUseMillisecondPingTolerance = thePrefs.IsDynUpUseMillisecondPingTolerance(); + cur.bEnabled = thePrefs.IsDynUpEnabled(); + + if (theApp.lastCommonRouteFinder->SetPrefs(cur)) + theApp.emuledlg->SetStatusBarPartsSize(); // ZZ:UploadSpeedSense <-- theApp.uploadqueue->Process(); @@ -1014,7 +1016,7 @@ VOID CALLBACK CUploadQueue::UploadTimer(HWND /*hwnd*/, UINT /*uMsg*/, UINT_PTR / if (thePrefs.IsSchedulerEnabled()) theApp.scheduler->Check(); - theApp.emuledlg->transferwnd->UpdateListCount(CTransferDlg::wnd2Uploading, -1); + theApp.emuledlg->transferwnd->UpdateListCount(CTransferWnd::wnd2Uploading, -1); } // *** 60 seconds ********************************************* @@ -1060,9 +1062,9 @@ CUpDownClient* CUploadQueue::GetNextClient(const CUpDownClient *lastclient) cons void CUploadQueue::UpdateDatarates() { // Calculate average data rate - const DWORD tick = ::GetTickCount(); - if (tick >= m_lastCalculatedDataRateTick + 500) { - m_lastCalculatedDataRateTick = tick; + const DWORD curTick = ::GetTickCount(); + if (curTick >= m_lastCalculatedDataRateTick + 500) { + m_lastCalculatedDataRateTick = curTick; if (average_dr_list.GetCount() >= 2 && average_tick_list.GetTail() > average_tick_list.GetHead()) { DWORD duration = average_tick_list.GetTail() - average_tick_list.GetHead(); @@ -1079,9 +1081,9 @@ uint32 CUploadQueue::GetToNetworkDatarate() const void CUploadQueue::ReSortUploadSlots(bool force) { - const DWORD tick = ::GetTickCount(); - if (force || tick >= m_dwLastResortedUploadSlots + SEC2MS(10)) { - m_dwLastResortedUploadSlots = tick; + const DWORD curTick = ::GetTickCount(); + if (force || curTick >= m_dwLastResortedUploadSlots + SEC2MS(10)) { + m_dwLastResortedUploadSlots = curTick; theApp.uploadBandwidthThrottler->Pause(true); @@ -1118,7 +1120,7 @@ uint32 CUploadQueue::GetWaitingUserForFileCount(const CSimpleArray &ra m_bStatisticsWaitingListDirty = false; uint32 nResult = 0; - for (POSITION pos = waitinglist.GetHeadPosition(); pos != NULL; ) { + for (POSITION pos = waitinglist.GetHeadPosition(); pos != NULL;) { const CUpDownClient *cur_client = waitinglist.GetNext(pos); for (int i = raFiles.GetSize(); --i >= 0;) nResult += static_cast(md4equ(static_cast(raFiles[i])->GetFileHash(), cur_client->GetUploadFileID())); @@ -1133,7 +1135,7 @@ uint32 CUploadQueue::GetDatarateForFile(const CSimpleArray &raFiles) c const CUpDownClient *cur_client = uploadinglist.GetNext(pos)->m_pClient; for (int i = raFiles.GetSize(); --i >= 0;) if (md4equ(static_cast(raFiles[i])->GetFileHash(), cur_client->GetUploadFileID())) - nResult += cur_client->GetDatarate(); + nResult += cur_client->GetUploadDatarate(); } return nResult; } diff --git a/srchybrid/UploadQueue.h b/srchybrid/UploadQueue.h index 63573c1b..9772dd62 100644 --- a/srchybrid/UploadQueue.h +++ b/srchybrid/UploadQueue.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -108,11 +108,10 @@ class CUploadQueue uint32 GetMaxClientScore() const { return m_imaxscore; } void UpdateActiveClientsInfo(DWORD curTick); - void InsertInUploadingList(CUpDownClient *newclient, bool bNoLocking = false); - void InsertInUploadingList(UploadingToClient_Struct *pNewClientUploadStruct, bool bNoLocking = false); + void InsertInUploadingList(CUpDownClient *newclient, bool bNoLocking); + void InsertInUploadingList(UploadingToClient_Struct *pNewClientUploadStruct, bool bNoLocking); float GetAverageCombinedFilePrioAndCredit(); - // By BadWolf - Accurate Speed Measurement typedef struct { @@ -137,7 +136,7 @@ class CUploadQueue uint32 successfullupcount; uint32 failedupcount; uint32 totaluploadtime; - uint32 m_nLastStartUpload; + DWORD m_nLastStartUpload; uint32 m_dwRemovedClientByScore; uint32 m_imaxscore; diff --git a/srchybrid/UserMsgs.h b/srchybrid/UserMsgs.h index eb26f75e..3804442c 100644 --- a/srchybrid/UserMsgs.h +++ b/srchybrid/UserMsgs.h @@ -4,16 +4,16 @@ enum EUserWndMessages { // *) Do *NOT* place any message *before* WM_FIRST_EMULE_USER_MSG !! - // *) Do *NOT* use any WM_USER messages in the range WM_USER - WM_USER+0x100 !! - UM_FIRST_EMULE_USER_MSG = (WM_USER + 0x100 + 1), + // *) Do *NOT* use any WM_USER messages in the range WM_USER - WM_USER+0x104 !! (AsyncSocketEx) + UM_FIRST_EMULE_USER_MSG = (WM_USER + 0x110 + 1), // Taskbar - UM_TASKBARNOTIFIERCLICKED, + UM_TASKBARNOTIFIERCLICKED, //+2 UM_TRAY_ICON_NOTIFY_MESSAGE, UM_CLOSE_MINIMULE, // Web Server - WEB_GUI_INTERACTION, + WEB_GUI_INTERACTION, //+5 WEB_CLEAR_COMPLETED, WEB_FILE_RENAME, WEB_ADDDOWNLOADS, @@ -21,22 +21,22 @@ enum EUserWndMessages WEB_ADDREMOVEFRIEND, // VC - UM_VERSIONCHECK_RESPONSE, + UM_VERSIONCHECK_RESPONSE, //+11 // PC - UM_PEERCACHE_RESPONSE, + UM_PEERCACHE_RESPONSE, //+12 - UM_CLOSETAB, + UM_CLOSETAB, //+13 UM_QUERYTAB, UM_DBLCLICKTAB, - UM_CPN_SELCHANGE, + UM_CPN_SELCHANGE, //+16 UM_CPN_DROPDOWN, UM_CPN_CLOSEUP, UM_CPN_SELENDOK, UM_CPN_SELENDCANCEL, - UM_MEDIA_INFO_RESULT, + UM_MEDIA_INFO_RESULT, //+21 UM_ITEMSTATECHANGED, UM_SPN_SIZED, UM_TABMOVED, @@ -47,5 +47,5 @@ enum EUserWndMessages UM_ARCHIVESCANDONE, // UPnP - UM_UPNP_RESULT + UM_UPNP_RESULT //+30 }; diff --git a/srchybrid/Version.cpp b/srchybrid/Version.cpp index 31f00858..8cd1363f 100644 --- a/srchybrid/Version.cpp +++ b/srchybrid/Version.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/Version.h b/srchybrid/Version.h index 00f5b707..4e893c00 100644 --- a/srchybrid/Version.h +++ b/srchybrid/Version.h @@ -19,19 +19,20 @@ // ... // // Fields: -// major number (e.g. 0) -// minor number (e.g. 30) +// major number (e.g. 0) +// minor number (e.g. 30) // update number (e.g. 0='a' 1='b' 2='c' 3='d' 4='e' 5='f' ...) -// build number; currently not used +// build number (1 or higher) // // Currently used: // .. is used for the displayed version (GUI) and the version check number // . is used for the protocol(!) version -// +// ------- +// not used for any checks in the program #define VERSION_MJR 0 -#define VERSION_MIN 60 -#define VERSION_UPDATE 3 -#define VERSION_BUILD 1 +#define VERSION_MIN 70 +#define VERSION_UPDATE 0 +#define VERSION_BUILD 9 #ifdef _M_X64 #define VERSION_X64 _T(" x64") #else diff --git a/srchybrid/WebServer.cpp b/srchybrid/WebServer.cpp index 1457386b..f5e2c377 100644 --- a/srchybrid/WebServer.cpp +++ b/srchybrid/WebServer.cpp @@ -43,6 +43,11 @@ static char THIS_FILE[] = __FILE__; #endif +#ifdef UNICODE +#define _tcreate_locale _wcreate_locale +#else +#define _tcreate_locale _create_locale +#endif // !UNICODE #define HTTPInit "Server: eMule\r\nConnection: close\r\nContent-Type: text/html\r\n" #define HTTPInitGZ HTTPInit "Content-Encoding: gzip\r\n" @@ -79,7 +84,6 @@ static BOOL WSsearchColumnHidden[4]; CWebServer::CWebServer() : m_Templates() , m_uCurIP() - , m_nStartTempDisabledTime() , m_iSearchSortby(3) , m_nIntruderDetect() , m_bServerWorking() @@ -145,16 +149,17 @@ void CWebServer::_SaveWIConfigArray(BOOL *array, int size, LPCTSTR key) bool CWebServer::ReloadTemplates() { - TCHAR *sPrevLocale = _tsetlocale(LC_TIME, NULL); - - _tsetlocale(LC_TIME, _T("English")); - CTime t = CTime::GetCurrentTime(); - m_Params.sLastModified = t.FormatGmt("%a, %d %b %Y %H:%M:%S GMT"); + //Last-Modified: , :: GMT + //Day and month names must be 3 English letters, 30 characters total. + _locale_t locale = _tcreate_locale(LC_TIME, _T("en-US")); + TCHAR szTime[32]; + time_t t = time(NULL); + if (!_tcsftime_l(szTime, _countof(szTime), _T("%a, %d %b %Y %H:%M:%S GMT"), gmtime(&t), locale)) + *szTime = _T('\0'); + m_Params.sLastModified = szTime; m_Params.sETag = MD5Sum(m_Params.sLastModified).GetHashString(); - _tsetlocale(LC_TIME, sPrevLocale); const CString &sFile(thePrefs.GetTemplate()); - CStdioFile file; if (file.Open(sFile, CFile::modeRead | CFile::shareDenyWrite | CFile::typeText)) { CString sAll, sLine; @@ -270,7 +275,6 @@ void CWebServer::StartServer() if (m_bServerWorking) { StartSockets(this); m_nIntruderDetect = 0; - m_nStartTempDisabledTime = 0; m_bIsTempDisabled = false; } } else @@ -314,7 +318,7 @@ void CWebServer::_RemoveFromStatic(const CString &sIP, int nPort) } -void CWebServer::AddStatsLine(UpDown line) +void CWebServer::AddStatsLine(const UpDown &line) { m_Params.PointsForWeb.Add(line); if (m_Params.PointsForWeb.GetCount() > WEB_GRAPH_WIDTH) @@ -351,7 +355,7 @@ void CWebServer::_ProcessURL(const ThreadData &Data) if (pThis == NULL) return; - SetThreadLocale(thePrefs.GetLanguageID()); + InitThreadLocale(); //(0.29b)////////////////////////////////////////////////////////////////// // Here we are in real trouble! We are accessing the entire emule main thread @@ -372,9 +376,9 @@ void CWebServer::_ProcessURL(const ThreadData &Data) // check for being banned int myfaults = 0; - DWORD now = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); for (INT_PTR i = pThis->m_Params.badlogins.GetCount(); --i >= 0;) { - if (now >= pThis->m_Params.badlogins[i].timestamp + MIN2MS(15)) + if (curTick >= pThis->m_Params.badlogins[i].timestamp + MIN2MS(15)) pThis->m_Params.badlogins.RemoveAt(i); // remove outdated entries else if (pThis->m_Params.badlogins[i].datalen == myip) @@ -388,7 +392,7 @@ void CWebServer::_ProcessURL(const ThreadData &Data) bool justAddLink = false; bool login = false; - CString sSession = _ParseURL(Data.sURL, _T("ses")); + CString sSession(_ParseURL(Data.sURL, _T("ses"))); long lSession = _tstol(sSession); if (_ParseURL(Data.sURL, _T("w")) == _T("password")) { @@ -405,7 +409,7 @@ void CWebServer::_ProcessURL(const ThreadData &Data) ses.admin = true; ses.startTime = CTime::GetCurrentTime(); ses.lSession = lSession = (long)(rand() >> 1); - ses.lastcat = 0 - thePrefs.GetCatFilter(0); + ses.lastcat = -thePrefs.GetCatFilter(0); pThis->m_Params.Sessions.Add(ses); } @@ -427,7 +431,7 @@ void CWebServer::_ProcessURL(const ThreadData &Data) } else { LogWarning(LOG_STATUSBAR, GetResString(IDS_WEB_BADLOGINATTEMPT) + _T(" (%s)"), (LPCTSTR)ip); - BadLogin newban = {myip, now}; // save failed attempt (ip,time) + BadLogin newban = {myip, curTick}; // save failed attempt (ip,time) pThis->m_Params.badlogins.Add(newban); if (++myfaults > 4) { Data.pSocket->SendContent(HTTPInit, _GetPlainResString(IDS_ACCESSDENIED)); @@ -442,15 +446,13 @@ void CWebServer::_ProcessURL(const ThreadData &Data) pThis->m_Params.badlogins.RemoveAt(i); } - TCHAR *gzipOut = NULL; - DWORD gzipLen = 0; - - CString Out; sSession.Format(_T("%ld"), lSession); - if (_ParseURL(Data.sURL, _T("w")) == _T("logout")) _RemoveSession(Data, lSession); + TCHAR *gzipOut = NULL; + DWORD gzipLen = 0; + CString Out; if (_IsLoggedIn(Data, lSession)) { bool bAdmin = _IsSessionAdmin(Data, sSession); if (_ParseURL(Data.sURL, _T("w")) == _T("close") && bAdmin && thePrefs.GetWebAdminAllowedHiLevFunc()) { @@ -564,25 +566,24 @@ void CWebServer::_ProcessURL(const ThreadData &Data) Out += _GetGraphs(Data); else if (sPage == _T("log")) Out += _GetLog(Data); - if (sPage == _T("sinfo")) + else if (sPage == _T("sinfo")) Out += _GetServerInfo(Data); - if (sPage == _T("debuglog")) + else if (sPage == _T("debuglog")) Out += _GetDebugLog(Data); - if (sPage == _T("myinfo")) + else if (sPage == _T("myinfo")) Out += _GetMyInfo(Data); - if (sPage == _T("stats")) + else if (sPage == _T("stats")) Out += _GetStats(Data); - if (sPage == _T("kad")) + else if (sPage == _T("kad")) Out += _GetKadDlg(Data); - if (sPage == _T("options")) { + else if (sPage == _T("options")) { isUseGzip = false; Out += _GetPreferences(Data); - } - Out += _GetFooter(Data); - - if (sPage.IsEmpty()) + } else if (sPage.IsEmpty()) isUseGzip = false; + Out += _GetFooter(Data); + if (isUseGzip) { bool bOk = false; try { @@ -682,7 +683,7 @@ CString CWebServer::_GetHeader(const ThreadData &Data, long lSession) CString sSession; sSession.Format(_T("%ld"), lSession); - CString Out = pThis->m_Templates.sHeader; + CString Out(pThis->m_Templates.sHeader); Out.Replace(_T("[CharSet]"), HTTPENCODING); // Auto-refresh code @@ -695,9 +696,8 @@ CString CWebServer::_GetHeader(const ThreadData &Data, long lSession) else sRefresh.Format(_T("%d"), SEC2MS(thePrefs.GetWebPageRefresh())); - CString swCommand; - swCommand.Format(_T("%s&cat=%s&dummy=%d") - , (LPCTSTR)_ParseURL(Data.sURL, _T("w")), (LPCTSTR)_ParseURL(Data.sURL, _T("cat")), rand()); + CString swCommand(_ParseURL(Data.sURL, _T("w"))); + swCommand.AppendFormat(_T("&cat=%s&dummy=%d"), (LPCTSTR)_ParseURL(Data.sURL, _T("cat")), rand()); Out.Replace(_T("[admin]"), (bAdmin && thePrefs.GetWebAdminAllowedHiLevFunc()) ? _T("admin") : _T("")); Out.Replace(_T("[Session]"), sSession); @@ -760,7 +760,6 @@ CString CWebServer::_GetHeader(const ThreadData &Data, long lSession) Out.Replace(_T("[PriorityRelease]"), _GetPlainResString(IDS_PRIORELEASE)); Out.Replace(_T("[PriorityAuto]"), _GetPlainResString(IDS_PRIOAUTO)); - CString HTTPConState, HTTPConText, HTTPHelp; CString HTTPHelpU(_T('0')); CString HTTPHelpM(_T('0')); CString HTTPHelpV(_T('0')); @@ -769,6 +768,7 @@ CString CWebServer::_GetHeader(const ThreadData &Data, long lSession) bool disconnectissued = (sCmd == _T("disconnect")); bool connectissued = (sCmd == _T("connect")); + CString HTTPConState, HTTPConText, HTTPHelp; if ((theApp.serverconnect->IsConnecting() && !disconnectissued) || connectissued) { HTTPConState = _T("connecting"); HTTPConText = _GetPlainResString(IDS_CONNECTING); @@ -968,7 +968,7 @@ CString CWebServer::_GetServerList(const ThreadData &Data) _SaveWIConfigArray(WSserverColumnHidden, _countof(WSserverColumnHidden), _T("serverColumnHidden")); } - CString strTmp = _ParseURL(Data.sURL, _T("sortreverse")); + CString strTmp(_ParseURL(Data.sURL, _T("sortreverse"))); const CString &sSort(_ParseURL(Data.sURL, _T("sort"))); if (!sSort.IsEmpty()) { @@ -1005,7 +1005,7 @@ CString CWebServer::_GetServerList(const ThreadData &Data) if (!strTmp.IsEmpty()) pThis->m_Params.bServerSortReverse = (strTmp == _T("true")); - CString Out = pThis->m_Templates.sServerList; + CString Out(pThis->m_Templates.sServerList); Out.Replace(_T("[AddServerBox]"), sAddServerBox); Out.Replace(_T("[Session]"), sSession); @@ -1224,12 +1224,12 @@ CString CWebServer::_GetServerList(const ThreadData &Data) qsort_s(ServerArray.GetData(), ServerArray.GetCount(), sizeof(ServerEntry), &_ServerCmp, &prm); // Displaying - CString sList, HTTPProcessData, sServerPort, ed2k; - CString OutE = pThis->m_Templates.sServerLine; // List Entry Templates + CString OutE(pThis->m_Templates.sServerLine); // List Entry Templates OutE.Replace(_T("[admin]"), bAdmin ? _T("admin") : _T("")); OutE.Replace(_T("[session]"), sSession); + CString sList, HTTPProcessData, sServerPort, ed2k; for (INT_PTR i = 0; i < ServerArray.GetCount(); ++i) { const ServerEntry &cur_srv(ServerArray[i]); HTTPProcessData = OutE; // Copy Entry Line to Temp @@ -1272,12 +1272,12 @@ CString CWebServer::_GetServerList(const ThreadData &Data) HTTPProcessData.Replace(_T("[Servername]"), s); } else HTTPProcessData.Replace(_T("[Servername]"), cur_srv.sServerName); - + if (WSserverColumnHidden[1]) HTTPProcessData.Replace(_T("[Address]"), _T("")); else { - CString sAddr; - sAddr.Format(_T("%s:%d"), (LPCTSTR)cur_srv.sServerIP, cur_srv.nServerPort); + CString sAddr(cur_srv.sServerIP); + sAddr.AppendFormat(_T(":%d"), cur_srv.nServerPort); HTTPProcessData.Replace(_T("[Address]"), sAddr); } if (WSserverColumnHidden[2]) @@ -1288,7 +1288,7 @@ CString CWebServer::_GetServerList(const ThreadData &Data) HTTPProcessData.Replace(_T("[Description]"), s); } else HTTPProcessData.Replace(_T("[Description]"), cur_srv.sServerDescription); - + if (WSserverColumnHidden[3]) HTTPProcessData.Replace(_T("[Ping]"), _T("")); else { @@ -1326,9 +1326,8 @@ CString CWebServer::_GetServerList(const ThreadData &Data) if (WSserverColumnHidden[8]) HTTPProcessData.Replace(_T("[Limit]"), _T("")); else { - CString strTemp; - strTemp.Format(_T("%s (%s)"), (LPCTSTR)CastItoIShort(cur_srv.nServerSoftLimit), - (LPCTSTR)CastItoIShort(cur_srv.nServerHardLimit)); + CString strTemp(CastItoIShort(cur_srv.nServerSoftLimit)); + strTemp.AppendFormat(_T(" (%s)"), (LPCTSTR)CastItoIShort(cur_srv.nServerHardLimit)); HTTPProcessData.Replace(_T("[Limit]"), strTemp); } if (WSserverColumnHidden[9]) @@ -1339,7 +1338,7 @@ CString CWebServer::_GetServerList(const ThreadData &Data) HTTPProcessData.Replace(_T("[Version]"), s); } else HTTPProcessData.Replace(_T("[Version]"), cur_srv.sServerVersion); - + HTTPProcessData.Replace(_T("[ServerState]"), cur_srv.sServerState); sList += HTTPProcessData; } @@ -1375,7 +1374,7 @@ CString CWebServer::_GetTransferList(const ThreadData &Data) CString Out; if (thePrefs.GetCatCount() > 1) - _InsertCatBox(Out, cat, CString(), true, true, sSession, CString()); + _InsertCatBox(Out, cat, _T(""), true, true, sSession, CString()); else Out.Replace(_T("[CATBOX]"), _T("")); @@ -1394,7 +1393,7 @@ CString CWebServer::_GetTransferList(const ThreadData &Data) } } - CString HTTPTemp = _ParseURL(Data.sURL, _T("ed2k")); + CString HTTPTemp(_ParseURL(Data.sURL, _T("ed2k"))); if (bAdmin && !HTTPTemp.IsEmpty()) theApp.emuledlg->SendMessage(WEB_ADDDOWNLOADS, (WPARAM)(LPCTSTR)HTTPTemp, cat); @@ -1493,7 +1492,7 @@ CString CWebServer::_GetTransferList(const ThreadData &Data) } } - CString strTmp = _ParseURL(Data.sURL, _T("sortreverse")); + HTTPTemp = _ParseURL(Data.sURL, _T("sortreverse")); const CString &sSort(_ParseURL(Data.sURL, _T("sort"))); if (!sSort.IsEmpty()) { @@ -1547,8 +1546,8 @@ CString CWebServer::_GetTransferList(const ThreadData &Data) } else if (sSort == _T("qscore")) pThis->m_Params.QueueSort = QU_SORT_SCORE; - if (!strTmp.IsEmpty()) - bDirection = (strTmp.CompareNoCase(_T("true")) == 0); + if (!HTTPTemp.IsEmpty()) + bDirection = (HTTPTemp.CompareNoCase(_T("true")) == 0); switch (sSort[0]) { case _T('d'): @@ -1562,23 +1561,9 @@ CString CWebServer::_GetTransferList(const ThreadData &Data) } } - HTTPTemp = _ParseURL(Data.sURL, _T("showuploadqueue")); - if (HTTPTemp == _T("true")) - pThis->m_Params.bShowUploadQueue = true; - else if (HTTPTemp == _T("false")) - pThis->m_Params.bShowUploadQueue = false; - - HTTPTemp = _ParseURL(Data.sURL, _T("showuploadqueuebanned")); - if (HTTPTemp == _T("true")) - pThis->m_Params.bShowUploadQueueBanned = true; - else if (HTTPTemp == _T("false")) - pThis->m_Params.bShowUploadQueueBanned = false; - - HTTPTemp = _ParseURL(Data.sURL, _T("showuploadqueuefriend")); - if (HTTPTemp == _T("true")) - pThis->m_Params.bShowUploadQueueFriend = true; - else if (HTTPTemp == _T("false")) - pThis->m_Params.bShowUploadQueueFriend = false; + _SetBoolean(pThis->m_Params.bShowUploadQueue, Data.sURL, _T("showuploadqueue")); + _SetBoolean(pThis->m_Params.bShowUploadQueueBanned, Data.sURL, _T("showuploadqueuebanned")); + _SetBoolean(pThis->m_Params.bShowUploadQueueFriend, Data.sURL, _T("showuploadqueuefriend")); Out += pThis->m_Templates.sTransferImages; Out += pThis->m_Templates.sTransferList; @@ -1588,211 +1573,211 @@ CString CWebServer::_GetTransferList(const ThreadData &Data) Out.Replace(_T("[UploadFooter]"), pThis->m_Templates.sTransferUpFooter); _InsertCatBox(Out, cat, pThis->m_Templates.sCatArrow, true, true, sSession, _T("")); - strTmp = (pThis->m_Params.bDownloadSortReverse) ? _T("&sortreverse=false") : _T("&sortreverse=true"); + HTTPTemp = (pThis->m_Params.bDownloadSortReverse) ? _T("&sortreverse=false") : _T("&sortreverse=true"); if (pThis->m_Params.DownloadSort == DOWN_SORT_STATE) - Out.Replace(_T("[SortDState]"), strTmp); + Out.Replace(_T("[SortDState]"), HTTPTemp); else Out.Replace(_T("[SortDState]"), _T("")); if (pThis->m_Params.DownloadSort == DOWN_SORT_TYPE) - Out.Replace(_T("[SortDType]"), strTmp); + Out.Replace(_T("[SortDType]"), HTTPTemp); else Out.Replace(_T("[SortDType]"), _T("")); if (pThis->m_Params.DownloadSort == DOWN_SORT_NAME) - Out.Replace(_T("[SortDName]"), strTmp); + Out.Replace(_T("[SortDName]"), HTTPTemp); else Out.Replace(_T("[SortDName]"), _T("")); if (pThis->m_Params.DownloadSort == DOWN_SORT_SIZE) - Out.Replace(_T("[SortDSize]"), strTmp); + Out.Replace(_T("[SortDSize]"), HTTPTemp); else Out.Replace(_T("[SortDSize]"), _T("")); if (pThis->m_Params.DownloadSort == DOWN_SORT_TRANSFERRED) - Out.Replace(_T("[SortDTransferred]"), strTmp); + Out.Replace(_T("[SortDTransferred]"), HTTPTemp); else Out.Replace(_T("[SortDTransferred]"), _T("")); if (pThis->m_Params.DownloadSort == DOWN_SORT_SPEED) - Out.Replace(_T("[SortDSpeed]"), strTmp); + Out.Replace(_T("[SortDSpeed]"), HTTPTemp); else Out.Replace(_T("[SortDSpeed]"), _T("")); if (pThis->m_Params.DownloadSort == DOWN_SORT_PROGRESS) - Out.Replace(_T("[SortDProgress]"), strTmp); + Out.Replace(_T("[SortDProgress]"), HTTPTemp); else Out.Replace(_T("[SortDProgress]"), _T("")); if (pThis->m_Params.DownloadSort == DOWN_SORT_SOURCES) - Out.Replace(_T("[SortDSources]"), strTmp); + Out.Replace(_T("[SortDSources]"), HTTPTemp); else Out.Replace(_T("[SortDSources]"), _T("")); if (pThis->m_Params.DownloadSort == DOWN_SORT_PRIORITY) - Out.Replace(_T("[SortDPriority]"), strTmp); + Out.Replace(_T("[SortDPriority]"), HTTPTemp); else Out.Replace(_T("[SortDPriority]"), _T("")); if (pThis->m_Params.DownloadSort == DOWN_SORT_CATEGORY) - Out.Replace(_T("[SortDCategory]"), strTmp); + Out.Replace(_T("[SortDCategory]"), HTTPTemp); else Out.Replace(_T("[SortDCategory]"), _T("")); - strTmp = (pThis->m_Params.bUploadSortReverse) ? _T("&sortreverse=false") : _T("&sortreverse=true"); + HTTPTemp = (pThis->m_Params.bUploadSortReverse) ? _T("&sortreverse=false") : _T("&sortreverse=true"); if (pThis->m_Params.UploadSort == UP_SORT_CLIENT) - Out.Replace(_T("[SortUClient]"), strTmp); + Out.Replace(_T("[SortUClient]"), HTTPTemp); else Out.Replace(_T("[SortUClient]"), _T("")); if (pThis->m_Params.UploadSort == UP_SORT_USER) - Out.Replace(_T("[SortUUser]"), strTmp); + Out.Replace(_T("[SortUUser]"), HTTPTemp); else Out.Replace(_T("[SortUUser]"), _T("")); if (pThis->m_Params.UploadSort == UP_SORT_VERSION) - Out.Replace(_T("[SortUVersion]"), strTmp); + Out.Replace(_T("[SortUVersion]"), HTTPTemp); else Out.Replace(_T("[SortUVersion]"), _T("")); if (pThis->m_Params.UploadSort == UP_SORT_FILENAME) - Out.Replace(_T("[SortUFilename]"), strTmp); + Out.Replace(_T("[SortUFilename]"), HTTPTemp); else Out.Replace(_T("[SortUFilename]"), _T("")); if (pThis->m_Params.UploadSort == UP_SORT_TRANSFERRED) - Out.Replace(_T("[SortUTransferred]"), strTmp); + Out.Replace(_T("[SortUTransferred]"), HTTPTemp); else Out.Replace(_T("[SortUTransferred]"), _T("")); if (pThis->m_Params.UploadSort == UP_SORT_SPEED) - Out.Replace(_T("[SortUSpeed]"), strTmp); + Out.Replace(_T("[SortUSpeed]"), HTTPTemp); else Out.Replace(_T("[SortUSpeed]"), _T("")); const TCHAR *pcSortIcon = (pThis->m_Params.bDownloadSortReverse) ? pThis->m_Templates.sUpArrow : pThis->m_Templates.sDownArrow; - _GetPlainResString(strTmp, IDS_DL_FILENAME); + _GetPlainResString(HTTPTemp, IDS_DL_FILENAME); if (WSdownloadColumnHidden[0]) { Out.Replace(_T("[DFilenameI]"), _T("")); Out.Replace(_T("[DFilename]"), _T("")); } else { Out.Replace(_T("[DFilenameI]"), (pThis->m_Params.DownloadSort == DOWN_SORT_NAME) ? pcSortIcon : _T("")); - Out.Replace(_T("[DFilename]"), strTmp); + Out.Replace(_T("[DFilename]"), HTTPTemp); } - Out.Replace(_T("[DFilenameM]"), strTmp); + Out.Replace(_T("[DFilenameM]"), HTTPTemp); - _GetPlainResString(strTmp, IDS_DL_SIZE); + _GetPlainResString(HTTPTemp, IDS_DL_SIZE); if (WSdownloadColumnHidden[1]) { Out.Replace(_T("[DSizeI]"), _T("")); Out.Replace(_T("[DSize]"), _T("")); } else { Out.Replace(_T("[DSizeI]"), (pThis->m_Params.DownloadSort == DOWN_SORT_SIZE) ? pcSortIcon : _T("")); - Out.Replace(_T("[DSize]"), strTmp); + Out.Replace(_T("[DSize]"), HTTPTemp); } - Out.Replace(_T("[DSizeM]"), strTmp); + Out.Replace(_T("[DSizeM]"), HTTPTemp); - _GetPlainResString(strTmp, IDS_DL_TRANSFCOMPL); + _GetPlainResString(HTTPTemp, IDS_DL_TRANSFCOMPL); if (WSdownloadColumnHidden[2]) { Out.Replace(_T("[DTransferredI]"), _T("")); Out.Replace(_T("[DTransferred]"), _T("")); } else { Out.Replace(_T("[DTransferredI]"), (pThis->m_Params.DownloadSort == DOWN_SORT_TRANSFERRED) ? pcSortIcon : _T("")); - Out.Replace(_T("[DTransferred]"), strTmp); + Out.Replace(_T("[DTransferred]"), HTTPTemp); } - Out.Replace(_T("[DTransferredM]"), strTmp); + Out.Replace(_T("[DTransferredM]"), HTTPTemp); - _GetPlainResString(strTmp, IDS_DL_PROGRESS); + _GetPlainResString(HTTPTemp, IDS_DL_PROGRESS); if (WSdownloadColumnHidden[3]) { Out.Replace(_T("[DProgressI]"), _T("")); Out.Replace(_T("[DProgress]"), _T("")); } else { Out.Replace(_T("[DProgressI]"), (pThis->m_Params.DownloadSort == DOWN_SORT_PROGRESS) ? pcSortIcon : _T("")); - Out.Replace(_T("[DProgress]"), strTmp); + Out.Replace(_T("[DProgress]"), HTTPTemp); } - Out.Replace(_T("[DProgressM]"), strTmp); + Out.Replace(_T("[DProgressM]"), HTTPTemp); - _GetPlainResString(strTmp, IDS_DL_SPEED); + _GetPlainResString(HTTPTemp, IDS_DL_SPEED); if (WSdownloadColumnHidden[4]) { Out.Replace(_T("[DSpeedI]"), _T("")); Out.Replace(_T("[DSpeed]"), _T("")); } else { Out.Replace(_T("[DSpeedI]"), (pThis->m_Params.DownloadSort == DOWN_SORT_SPEED) ? pcSortIcon : _T("")); - Out.Replace(_T("[DSpeed]"), strTmp); + Out.Replace(_T("[DSpeed]"), HTTPTemp); } - Out.Replace(_T("[DSpeedM]"), strTmp); + Out.Replace(_T("[DSpeedM]"), HTTPTemp); - _GetPlainResString(strTmp, IDS_DL_SOURCES); + _GetPlainResString(HTTPTemp, IDS_DL_SOURCES); if (WSdownloadColumnHidden[5]) { Out.Replace(_T("[DSourcesI]"), _T("")); Out.Replace(_T("[DSources]"), _T("")); } else { Out.Replace(_T("[DSourcesI]"), (pThis->m_Params.DownloadSort == DOWN_SORT_SOURCES) ? pcSortIcon : _T("")); - Out.Replace(_T("[DSources]"), strTmp); + Out.Replace(_T("[DSources]"), HTTPTemp); } - Out.Replace(_T("[DSourcesM]"), strTmp); + Out.Replace(_T("[DSourcesM]"), HTTPTemp); - _GetPlainResString(strTmp, IDS_PRIORITY); + _GetPlainResString(HTTPTemp, IDS_PRIORITY); if (WSdownloadColumnHidden[6]) { Out.Replace(_T("[DPriorityI]"), _T("")); Out.Replace(_T("[DPriority]"), _T("")); } else { Out.Replace(_T("[DPriorityI]"), (pThis->m_Params.DownloadSort == DOWN_SORT_PRIORITY) ? pcSortIcon : _T("")); - Out.Replace(_T("[DPriority]"), strTmp); + Out.Replace(_T("[DPriority]"), HTTPTemp); } - Out.Replace(_T("[DPriorityM]"), strTmp); + Out.Replace(_T("[DPriorityM]"), HTTPTemp); - _GetPlainResString(strTmp, IDS_CAT); + _GetPlainResString(HTTPTemp, IDS_CAT); if (WSdownloadColumnHidden[7]) { Out.Replace(_T("[DCategoryI]"), _T("")); Out.Replace(_T("[DCategory]"), _T("")); } else { Out.Replace(_T("[DCategoryI]"), (pThis->m_Params.DownloadSort == DOWN_SORT_CATEGORY) ? pcSortIcon : _T("")); - Out.Replace(_T("[DCategory]"), strTmp); + Out.Replace(_T("[DCategory]"), HTTPTemp); } - Out.Replace(_T("[DCategoryM]"), strTmp); + Out.Replace(_T("[DCategoryM]"), HTTPTemp); // add 8th columns here pcSortIcon = (pThis->m_Params.bUploadSortReverse) ? pThis->m_Templates.sUpArrow : pThis->m_Templates.sDownArrow; - _GetPlainResString(strTmp, IDS_QL_USERNAME); + _GetPlainResString(HTTPTemp, IDS_QL_USERNAME); if (WSuploadColumnHidden[0]) { Out.Replace(_T("[UUserI]"), _T("")); Out.Replace(_T("[UUser]"), _T("")); } else { Out.Replace(_T("[UUserI]"), (pThis->m_Params.UploadSort == UP_SORT_USER) ? pcSortIcon : _T("")); - Out.Replace(_T("[UUser]"), strTmp); + Out.Replace(_T("[UUser]"), HTTPTemp); } - Out.Replace(_T("[UUserM]"), strTmp); + Out.Replace(_T("[UUserM]"), HTTPTemp); - _GetPlainResString(strTmp, IDS_CD_VERSION); + _GetPlainResString(HTTPTemp, IDS_CD_VERSION); if (WSuploadColumnHidden[1]) { Out.Replace(_T("[UVersionI]"), _T("")); Out.Replace(_T("[UVersion]"), _T("")); } else { Out.Replace(_T("[UVersionI]"), (pThis->m_Params.UploadSort == UP_SORT_VERSION) ? pcSortIcon : _T("")); - Out.Replace(_T("[UVersion]"), strTmp); + Out.Replace(_T("[UVersion]"), HTTPTemp); } - Out.Replace(_T("[UVersionM]"), strTmp); + Out.Replace(_T("[UVersionM]"), HTTPTemp); - _GetPlainResString(strTmp, IDS_DL_FILENAME); + _GetPlainResString(HTTPTemp, IDS_DL_FILENAME); if (WSuploadColumnHidden[2]) { Out.Replace(_T("[UFilenameI]"), _T("")); Out.Replace(_T("[UFilename]"), _T("")); } else { Out.Replace(_T("[UFilenameI]"), (pThis->m_Params.UploadSort == UP_SORT_FILENAME) ? pcSortIcon : _T("")); - Out.Replace(_T("[UFilename]"), strTmp); + Out.Replace(_T("[UFilename]"), HTTPTemp); } - Out.Replace(_T("[UFilenameM]"), strTmp); + Out.Replace(_T("[UFilenameM]"), HTTPTemp); - _GetPlainResString(strTmp, IDS_STATS_SRATIO); + _GetPlainResString(HTTPTemp, IDS_STATS_SRATIO); if (WSuploadColumnHidden[3]) { Out.Replace(_T("[UTransferredI]"), _T("")); Out.Replace(_T("[UTransferred]"), _T("")); } else { Out.Replace(_T("[UTransferredI]"), (pThis->m_Params.UploadSort == UP_SORT_TRANSFERRED) ? pcSortIcon : _T("")); - Out.Replace(_T("[UTransferred]"), strTmp); + Out.Replace(_T("[UTransferred]"), HTTPTemp); } - Out.Replace(_T("[UTransferredM]"), strTmp); + Out.Replace(_T("[UTransferredM]"), HTTPTemp); - _GetPlainResString(strTmp, IDS_DL_SPEED); + _GetPlainResString(HTTPTemp, IDS_DL_SPEED); if (WSuploadColumnHidden[4]) { Out.Replace(_T("[USpeedI]"), _T("")); Out.Replace(_T("[USpeed]"), _T("")); } else { Out.Replace(_T("[USpeedI]"), (pThis->m_Params.UploadSort == UP_SORT_SPEED) ? pcSortIcon : _T("")); - Out.Replace(_T("[USpeed]"), strTmp); + Out.Replace(_T("[USpeed]"), HTTPTemp); } - Out.Replace(_T("[USpeedM]"), strTmp); + Out.Replace(_T("[USpeedM]"), HTTPTemp); Out.Replace(_T("[DownloadList]"), _GetPlainResString(IDS_TW_DOWNLOADS)); Out.Replace(_T("[UploadList]"), _GetPlainResString(IDS_TW_UPLOADS)); @@ -1929,7 +1914,7 @@ CString CWebServer::_GetTransferList(const ThreadData &Data) dFile.nFilePrio = pPartFile->GetDownPriority(); int pCat = pPartFile->GetCategory(); - CString strCategory = thePrefs.GetCategory(pCat)->strTitle; + CString strCategory(thePrefs.GetCategory(pCat)->strTitle); strCategory.Replace(_T("'"), _T("\\'")); dFile.sCategory = strCategory; @@ -1962,7 +1947,7 @@ CString CWebServer::_GetTransferList(const ThreadData &Data) UploadUsers dUser; const CUpDownClient &cur_client(*theApp.uploadqueue->GetNextFromUploadList(pos)); dUser.sUserHash = md4str(cur_client.GetUserHash()); - if (cur_client.GetDatarate() > 0) { + if (cur_client.GetUploadDatarate() > 0) { dUser.sActive = _T("downloading"); dUser.sClientState = _T("uploading"); } else { @@ -1975,7 +1960,7 @@ CString CWebServer::_GetTransferList(const ThreadData &Data) dUser.sFileInfo.Replace(_T("\n"), _T("
")); dUser.sFileInfo.Replace(_T("'"), _T("’")); - dUser.sClientSoft = _GetClientversionImage(cur_client); + _GetClientversionImage(cur_client, dUser.sClientSoft); if (cur_client.IsBanned()) dUser.sClientExtra = _T("banned"); @@ -1987,20 +1972,18 @@ CString CWebServer::_GetTransferList(const ThreadData &Data) dUser.sClientExtra = _T("none"); CString cname(cur_client.GetUserName()); - if (cname.GetLength() > SHORT_LENGTH_MIN) - dUser.sUserName = _SpecialChars(cname.Left(SHORT_LENGTH_MIN - 3)) + _T("..."); - else - dUser.sUserName = _SpecialChars(cname); + if (cname.GetLength() > SHORT_LENGTH_MIN) { + cname.Truncate(SHORT_LENGTH_MIN - 3); + cname += _T("..."); + } + dUser.sUserName = _SpecialChars(cname); CKnownFile *file = theApp.sharedfiles->GetFileByID(cur_client.GetUploadFileID()); - if (file) - dUser.sFileName = _SpecialChars(file->GetFileName()); - else - dUser.sFileName = _GetPlainResString(IDS_REQ_UNKNOWNFILE); + dUser.sFileName = file ? _SpecialChars(file->GetFileName()) : _GetPlainResString(IDS_REQ_UNKNOWNFILE); dUser.nTransferredDown = cur_client.GetTransferredDown(); dUser.nTransferredUp = cur_client.GetTransferredUp(); - int iDataRate = cur_client.GetDatarate(); - dUser.nDataRate = ((iDataRate == -1) ? 0 : iDataRate); + UINT uDataRate = cur_client.GetUploadDatarate(); + dUser.nDataRate = (uDataRate == UNLIMITED) ? 0 : uDataRate; dUser.sClientNameVersion = cur_client.GetClientSoftVer(); UploadArray.Add(dUser); } @@ -2049,8 +2032,10 @@ void CWebServer::_MakeTransferList(CString &Out, CWebServer *pThis, const Thread } CString usn(cur_client.GetUserName()); - if (usn.GetLength() > SHORT_LENGTH_MIN) - usn = usn.Left(SHORT_LENGTH_MIN - 3) + _T("..."); + if (usn.GetLength() > SHORT_LENGTH_MIN) { + usn.Truncate(SHORT_LENGTH_MIN - 3); + usn += _T("..."); + } dUser.sUserName = _SpecialChars(usn); dUser.sClientNameVersion = cur_client.GetClientSoftVer(); @@ -2060,7 +2045,8 @@ void CWebServer::_MakeTransferList(CString &Out, CWebServer *pThis, const Thread dUser.sClientStateSpecial = _T("connecting"); dUser.nScore = cur_client.GetScore(false); - dUser.sClientSoft = _GetClientversionImage(cur_client); + _GetClientversionImage(cur_client, dUser.sClientSoft); + dUser.sUserHash = md4str(cur_client.GetUserHash()); //SyruS CQArray-Sorting setting sIndex according to param switch (pThis->m_Params.QueueSort) { @@ -2100,7 +2086,7 @@ void CWebServer::_MakeTransferList(CString &Out, CWebServer *pThis, const Thread || (nCountQueueFriend > 0 && pThis->m_Params.bShowUploadQueueFriend)) { #ifdef _DEBUG - DWORD dwStart = ::GetTickCount(); + const DWORD dwStart = ::GetTickCount(); #endif QueueArray.QuickSort(pThis->m_Params.bQueueSortReverse); #ifdef _DEBUG @@ -2108,12 +2094,12 @@ void CWebServer::_MakeTransferList(CString &Out, CWebServer *pThis, const Thread #endif } - CString sDownList, HTTPProcessData; - CString HTTPTemp; + CString HTTPProcessData; + CString sDownList, HTTPTemp; LPCTSTR pcTmp; double fTotalSize = 0, fTotalTransferred = 0, fTotalSpeed = 0; - CString OutE = pThis->m_Templates.sTransferDownLine; + CString OutE(pThis->m_Templates.sTransferDownLine); for (INT_PTR i = 0; i < FilesArray->GetCount(); ++i) { const DownloadFiles &downf((*FilesArray)[i]); HTTPProcessData = OutE; @@ -2152,10 +2138,8 @@ void CWebServer::_MakeTransferList(CString &Out, CWebServer *pThis, const Thread HTTPProcessData.Replace(_T("[!ISACTIVE_END]"), _T("-->")); } - CString ed2k = downf.sED2kLink; //ed2klink + CString ed2k(downf.sED2kLink); //ed2klink ed2k.Replace(_T("'"), _T("’")); - CString fname = downf.sFileNameJS; //filename - CString state = downf.sFileState; CString fsize; //file size fsize.Format(_T("%I64u"), downf.m_qwFileSize); const CString &session(_ParseURL(Data.sURL, _T("ses"))); @@ -2187,9 +2171,9 @@ void CWebServer::_MakeTransferList(CString &Out, CWebServer *pThis, const Thread HTTPProcessData.Replace(_T("[finfo]"), strFinfo); HTTPProcessData.Replace(_T("[fcomments]"), downf.iComment ? _T("yes") : _T("")); HTTPProcessData.Replace(_T("[ed2k]"), _SpecialChars(ed2k)); - HTTPProcessData.Replace(_T("[DownState]"), state); + HTTPProcessData.Replace(_T("[DownState]"), downf.sFileState); HTTPProcessData.Replace(_T("[isgetflc]"), isgetflc); - HTTPProcessData.Replace(_T("[fname]"), _SpecialChars(fname)); + HTTPProcessData.Replace(_T("[fname]"), _SpecialChars(downf.sFileNameJS)); HTTPProcessData.Replace(_T("[fsize]"), fsize); HTTPProcessData.Replace(_T("[session]"), session); HTTPProcessData.Replace(_T("[filehash]"), downf.sFileHash); @@ -2220,12 +2204,12 @@ void CWebServer::_MakeTransferList(CString &Out, CWebServer *pThis, const Thread HTTPProcessData.Replace(_T("[ShortFileName]"), downf.sFileName.Left(SHORT_LENGTH_MAX - 3) + _T("...")); else HTTPProcessData.Replace(_T("[ShortFileName]"), downf.sFileName); - + HTTPProcessData.Replace(_T("[FileInfo]"), strFileInfo); fTotalSize += downf.m_qwFileSize; HTTPProcessData.Replace(_T("[2]"), WSdownloadColumnHidden[1] ? _T("") : (LPCTSTR)CastItoXBytes(downf.m_qwFileSize)); - + if (WSdownloadColumnHidden[2]) HTTPProcessData.Replace(_T("[3]"), _T("")); else if (downf.m_qwFileTransferred > 0) { @@ -2292,11 +2276,11 @@ void CWebServer::_MakeTransferList(CString &Out, CWebServer *pThis, const Thread Out.Replace(_T("[PROGRESSBARWIDTHVAL]"), HTTPTemp); fTotalSize = fTotalTransferred = fTotalSpeed = 0; - CString sUpList; OutE = pThis->m_Templates.sTransferUpLine; OutE.Replace(_T("[admin]"), bAdmin ? _T("admin") : _T("")); + CString sUpList; for (INT_PTR i = 0; i < UploadArray->GetCount(); ++i) { const UploadUsers &ulu((*UploadArray)[i]); HTTPProcessData = OutE; @@ -2348,11 +2332,10 @@ void CWebServer::_MakeTransferList(CString &Out, CWebServer *pThis, const Thread Out.Replace(_T("[UploadQueue]"), pThis->m_Templates.sTransferUpQueueShow); Out.Replace(_T("[UploadQueueList]"), _GetPlainResString(IDS_ONQUEUE)); - CString sQueue; - OutE = pThis->m_Templates.sTransferUpQueueLine; OutE.Replace(_T("[admin]"), bAdmin ? _T("admin") : _T("")); + CString sQueue; for (INT_PTR i = 0; i < QueueArray.GetCount(); ++i) { if (QueueArray[i].sClientExtra == _T("none")) { HTTPProcessData = OutE; @@ -2388,10 +2371,9 @@ void CWebServer::_MakeTransferList(CString &Out, CWebServer *pThis, const Thread Out.Replace(_T("[UploadQueueBanned]"), pThis->m_Templates.sTransferUpQueueBannedShow); Out.Replace(_T("[UploadQueueBannedList]"), _GetPlainResString(IDS_BANNED)); - CString sQueueBanned; - OutE = pThis->m_Templates.sTransferUpQueueBannedLine; + CString sQueueBanned; for (INT_PTR i = 0; i < QueueArray.GetCount(); ++i) { if (QueueArray[i].sClientExtra == _T("banned")) { HTTPProcessData = OutE; @@ -2428,10 +2410,9 @@ void CWebServer::_MakeTransferList(CString &Out, CWebServer *pThis, const Thread Out.Replace(_T("[UploadQueueFriend]"), pThis->m_Templates.sTransferUpQueueFriendShow); Out.Replace(_T("[UploadQueueFriendList]"), _GetPlainResString(IDS_IRC_ADDTOFRIENDLIST)); - CString sQueueFriend; - OutE = pThis->m_Templates.sTransferUpQueueFriendLine; + CString sQueueFriend; for (INT_PTR i = 0; i < QueueArray.GetCount(); ++i) { if (QueueArray[i].sClientExtra == _T("friend")) { HTTPProcessData = OutE; @@ -2488,7 +2469,7 @@ void CWebServer::_MakeTransferList(CString &Out, CWebServer *pThis, const Thread Out.Replace(_T("[ShowUploadQueueListBanned]"), _GetPlainResString(IDS_WEB_SHOW_UPLOAD_QUEUE_BANNED)); Out.Replace(_T("[ShowUploadQueueListFriend]"), _GetPlainResString(IDS_WEB_SHOW_UPLOAD_QUEUE_FRIEND)); - CString strTmp = (pThis->m_Params.bQueueSortReverse) ? _T("&sortreverse=false") : _T("&sortreverse=true"); + CString strTmp(pThis->m_Params.bQueueSortReverse ? _T("&sortreverse=false") : _T("&sortreverse=true")); if (pThis->m_Params.QueueSort == QU_SORT_CLIENT) Out.Replace(_T("[SortQClient]"), strTmp); @@ -2511,7 +2492,7 @@ void CWebServer::_MakeTransferList(CString &Out, CWebServer *pThis, const Thread else Out.Replace(_T("[SortQScore]"), _T("")); - CString pcSortIcon = (pThis->m_Params.bQueueSortReverse) ? pThis->m_Templates.sUpArrow : pThis->m_Templates.sDownArrow; + CString pcSortIcon(pThis->m_Params.bQueueSortReverse ? pThis->m_Templates.sUpArrow : pThis->m_Templates.sDownArrow); _GetPlainResString(strTmp, IDS_QL_USERNAME); if (WSqueueColumnHidden[0]) { @@ -2570,6 +2551,15 @@ void CWebServer::_MakeTransferList(CString &Out, CWebServer *pThis, const Thread Out.Replace(_T("[ScoreTitleM]"), strTmp); } +void CWebServer::_SetBoolean(bool &var, const CString &URL, LPCTSTR pFieldname) +{ + const CString &sBool(_ParseURL(URL, pFieldname)); + if (sBool == _T("true")) + var = true; + else if (sBool == _T("false")) + var = false; +} + CString CWebServer::_GetSharedFilesList(const ThreadData &Data) { CWebServer *pThis = reinterpret_cast(Data.pThis); @@ -2580,7 +2570,7 @@ CString CWebServer::_GetSharedFilesList(const ThreadData &Data) bool bAdmin = _IsSessionAdmin(Data, sSession); const CString &strSort(_ParseURL(Data.sURL, _T("sort"))); - CString strTmp = _ParseURL(Data.sURL, _T("sortreverse")); + CString strTmp(_ParseURL(Data.sURL, _T("sortreverse"))); if (!strSort.IsEmpty()) { bool bDirection = false; @@ -2617,35 +2607,36 @@ CString CWebServer::_GetSharedFilesList(const ThreadData &Data) if (!strTmp.IsEmpty()) pThis->m_Params.bSharedSortReverse = (strTmp == _T("true")); - if (!_ParseURL(Data.sURL, _T("hash")).IsEmpty() && !_ParseURL(Data.sURL, _T("prio")).IsEmpty() && bAdmin) { - CString hash = _ParseURL(Data.sURL, _T("hash")); - uchar fileid[MDX_DIGEST_SIZE]; - if (hash.GetLength() == 32 && DecodeBase16(hash, hash.GetLength(), fileid, _countof(fileid))) { - CKnownFile *cur_file = theApp.sharedfiles->GetFileByID(fileid); - - if (cur_file != 0) { - const CString &sPrio(_ParseURL(Data.sURL, _T("prio"))); - uint8 uPrio; - if (sPrio == _T("verylow")) - uPrio = PR_VERYLOW; - else if (sPrio == _T("low")) - uPrio = PR_LOW; - else if (sPrio == _T("normal")) - uPrio = PR_NORMAL; - else if (sPrio == _T("high")) - uPrio = PR_HIGH; - else if (sPrio == _T("release")) - uPrio = PR_VERYHIGH; - else //if (sPrio == _T("auto")) - uPrio = PR_AUTO; - if (uPrio == PR_AUTO) { - cur_file->SetAutoUpPriority(true); - cur_file->UpdateAutoUpPriority(); - } else { - cur_file->SetAutoUpPriority(false); - cur_file->SetUpPriority(uPrio); + if (bAdmin) { + CString hash(_ParseURL(Data.sURL, _T("hash"))); + const CString &sPrio(_ParseURL(Data.sURL, _T("prio"))); + if (!hash.IsEmpty() && !sPrio.IsEmpty()) { + uchar fileid[MDX_DIGEST_SIZE]; + if (hash.GetLength() == 32 && DecodeBase16(hash, hash.GetLength(), fileid, _countof(fileid))) { + CKnownFile *pFile = theApp.sharedfiles->GetFileByID(fileid); + if (pFile != NULL) { + uint8 uPrio; + if (sPrio == _T("verylow")) + uPrio = PR_VERYLOW; + else if (sPrio == _T("low")) + uPrio = PR_LOW; + else if (sPrio == _T("normal")) + uPrio = PR_NORMAL; + else if (sPrio == _T("high")) + uPrio = PR_HIGH; + else if (sPrio == _T("release")) + uPrio = PR_VERYHIGH; + else //if (sPrio == _T("auto")) + uPrio = PR_AUTO; + if (uPrio == PR_AUTO) { + pFile->SetAutoUpPriority(true); + pFile->UpdateAutoUpPriority(); + } else { + pFile->SetAutoUpPriority(false); + pFile->SetUpPriority(uPrio); + } + SendMessage(theApp.emuledlg->m_hWnd, WEB_GUI_INTERACTION, WEBGUIIA_UPD_SFUPDATE, (LPARAM)pFile); } - SendMessage(theApp.emuledlg->m_hWnd, WEB_GUI_INTERACTION, WEBGUIIA_UPD_SFUPDATE, (LPARAM)cur_file); } } } @@ -2659,10 +2650,9 @@ CString CWebServer::_GetSharedFilesList(const ThreadData &Data) if (_ParseURL(Data.sURL, _T("reload")) == _T("true")) SendMessage(theApp.emuledlg->m_hWnd, WEB_GUI_INTERACTION, WEBGUIIA_SHARED_FILES_RELOAD, 0); - CString Out = pThis->m_Templates.sSharedList; - strTmp = (pThis->m_Params.bSharedSortReverse) ? _T("false") : _T("true"); + CString Out(pThis->m_Templates.sSharedList); //State sorting link if (pThis->m_Params.SharedSort == SHARED_SORT_STATE) Out.Replace(_T("[SortState]"), _T("sort=state&sortreverse=") + strTmp); @@ -2734,8 +2724,8 @@ CString CWebServer::_GetSharedFilesList(const ThreadData &Data) Out.Replace(_T("[SortAccepts]"), _T("&sort=accepts&sortreverse=false")); if (_ParseURL(Data.sURL, _T("reload")) == _T("true")) { - CString strResultLog = _SpecialChars(theApp.emuledlg->GetLastLogEntry()); //Pick-up last line of the log - strResultLog = strResultLog.TrimRight(_T('\n')); + //Pick-up last line of the log + CString strResultLog(_SpecialChars(theApp.emuledlg->GetLastLogEntry().TrimRight(_T('\n')))); int iStringIndex = strResultLog.ReverseFind(_T('\n')); if (iStringIndex > 0) strResultLog.Delete(0, iStringIndex); @@ -2829,7 +2819,7 @@ CString CWebServer::_GetSharedFilesList(const ThreadData &Data) Out.Replace(_T("[Session]"), sSession); Out.Replace(_T("[SharedList]"), _GetPlainResString(IDS_SHAREDFILES)); - CString OutE = pThis->m_Templates.sSharedLine; + CString OutE(pThis->m_Templates.sSharedLine); CArray SharedArray; @@ -2947,7 +2937,7 @@ CString CWebServer::_GetSharedFilesList(const ThreadData &Data) CString ed2k(SharedArray[i].sED2kLink); //ed2klink ed2k.Replace(_T("'"), _T("’")); - CString hash(SharedArray[i].sFileHash); //hash + const CString &hash(SharedArray[i].sFileHash); //hash CString fname(SharedArray[i].sFileName); //filename fname.Replace(_T("'"), _T("’")); @@ -3040,7 +3030,7 @@ CString CWebServer::_GetGraphs(const ThreadData &Data) if (pThis == NULL) return CString(); - CString Out = pThis->m_Templates.sGraphs; + CString Out(pThis->m_Templates.sGraphs); CString strGraphDownload, strGraphUpload, strGraphCons; LPCTSTR pszFmt = _T("%u"); @@ -3069,9 +3059,9 @@ CString CWebServer::_GetGraphs(const ThreadData &Data) Out.Replace(_T("[ScaleTime]"), (LPCTSTR)CastSecondsToHM(((time_t)thePrefs.GetTrafficOMeterInterval()) * WEB_GRAPH_WIDTH)); CString s1; - s1.Format(_T("%i"), thePrefs.GetMaxGraphDownloadRate() + 4); + s1.Format(_T("%u"), thePrefs.GetMaxGraphDownloadRate() + 4); Out.Replace(_T("[MaxDownload]"), s1); - s1.Format(_T("%i"), thePrefs.GetMaxGraphUploadRate(true) + 4); + s1.Format(_T("%u"), thePrefs.GetMaxGraphUploadRate(true) + 4); Out.Replace(_T("[MaxUpload]"), s1); s1.Format(_T("%u"), thePrefs.GetMaxConnections() + 20); Out.Replace(_T("[MaxConnections]"), s1); @@ -3089,38 +3079,38 @@ CString CWebServer::_GetAddServerBox(const ThreadData &Data) if (!_IsSessionAdmin(Data, sSession)) return CString(); - CString resultlog = _SpecialChars(theApp.emuledlg->GetLastLogEntry()); //Pick-up last line of the log + CString resultlog(_SpecialChars(theApp.emuledlg->GetLastLogEntry())); //Pick-up last line of the log - CString Out = pThis->m_Templates.sAddServerBox; + CString Out(pThis->m_Templates.sAddServerBox); if (_ParseURL(Data.sURL, _T("addserver")) == _T("true")) { - const CString &strServerAddress(_ParseURL(Data.sURL, _T("serveraddr")).Trim()); - const CString &strServerPort(_ParseURL(Data.sURL, _T("serverport")).Trim()); - if (!strServerAddress.IsEmpty() && !strServerPort.IsEmpty()) { - CString strServerName = _ParseURL(Data.sURL, _T("servername")).Trim(); - if (strServerName.IsEmpty()) + CString strServerAddress(_ParseURL(Data.sURL, _T("serveraddr"))); + CString strServerPort(_ParseURL(Data.sURL, _T("serverport"))); + if (!strServerAddress.Trim().IsEmpty() && !strServerPort.Trim().IsEmpty()) { + CString strServerName(_ParseURL(Data.sURL, _T("servername"))); + if (strServerName.Trim().IsEmpty()) strServerName = strServerAddress; - CServer *nsrv = new CServer((uint16)_tstoi(strServerPort), strServerAddress); - nsrv->SetListName(strServerName); - if (!theApp.emuledlg->serverwnd->serverlistctrl.AddServer(nsrv, true)) { - delete nsrv; + CServer *srv = new CServer((uint16)_tstoi(strServerPort), strServerAddress); + srv->SetListName(strServerName); + if (!theApp.emuledlg->serverwnd->serverlistctrl.AddServer(srv, true)) { + delete srv; Out.Replace(_T("[Message]"), _GetPlainResString(IDS_ERROR)); } else { const CString &sPrio(_ParseURL(Data.sURL, _T("priority"))); if (sPrio == _T("low")) - nsrv->SetPreference(PR_LOW); + srv->SetPreference(PR_LOW); else if (sPrio == _T("normal")) - nsrv->SetPreference(PR_NORMAL); + srv->SetPreference(PR_NORMAL); else if (sPrio == _T("high")) - nsrv->SetPreference(PR_HIGH); + srv->SetPreference(PR_HIGH); - SendMessage(theApp.emuledlg->m_hWnd, WEB_GUI_INTERACTION, WEBGUIIA_UPDATESERVER, (LPARAM)nsrv); + SendMessage(theApp.emuledlg->m_hWnd, WEB_GUI_INTERACTION, WEBGUIIA_UPDATESERVER, (LPARAM)srv); if (_ParseURL(Data.sURL, _T("addtostatic")) == _T("true")) { _AddToStatic(_ParseURL(Data.sURL, _T("serveraddr")), _tstoi(_ParseURL(Data.sURL, _T("serverport")))); resultlog.AppendFormat(_T("
%s"), (LPCTSTR)_SpecialChars(theApp.emuledlg->GetLastLogEntry())); //Pick-up last line of the log } - resultlog = resultlog.TrimRight(_T('\n')); - resultlog = resultlog.Mid(resultlog.ReverseFind(_T('\n'))); + resultlog.TrimRight(_T('\n')); + resultlog.Delete(0, resultlog.ReverseFind(_T('\n'))); Out.Replace(_T("[Message]"), resultlog); if (_ParseURL(Data.sURL, _T("connectnow")) == _T("true")) _ConnectToServer(_ParseURL(Data.sURL, _T("serveraddr")), _tstoi(_ParseURL(Data.sURL, _T("serverport")))); @@ -3132,8 +3122,8 @@ CString CWebServer::_GetAddServerBox(const ThreadData &Data) SendMessage(theApp.emuledlg->m_hWnd, WEB_GUI_INTERACTION, WEBGUIIA_UPDATESERVERMETFROMURL, (LPARAM)(LPCTSTR)url); resultlog = _SpecialChars(theApp.emuledlg->GetLastLogEntry()); - resultlog = resultlog.TrimRight(_T('\n')); - resultlog = resultlog.Mid(resultlog.ReverseFind(_T('\n'))); + resultlog.TrimRight(_T('\n')); + resultlog.Delete(0, resultlog.ReverseFind(_T('\n'))); Out.Replace(_T("[Message]"), resultlog); } else Out.Replace(_T("[Message]"), _T("")); @@ -3152,17 +3142,13 @@ CString CWebServer::_GetAddServerBox(const ThreadData &Data) Out.Replace(_T("[UpdateServerMetFromURL]"), _GetPlainResString(IDS_SV_MET)); Out.Replace(_T("[URL]"), _GetPlainResString(IDS_SV_URL)); Out.Replace(_T("[Apply]"), _GetPlainResString(IDS_PW_APPLY)); - //if (bAdmin) { - was checked on entry + //for admin only (verified on entry) CString s; s.Format(_T("?ses=%s&w=server&c=disconnect"), (LPCTSTR)sSession); Out.Replace(_T("[URL_Disconnect]"), s); s.Format(_T("?ses=%s&w=server&c=connect"), (LPCTSTR)sSession); Out.Replace(_T("[URL_Connect]"), s); - //} else { - // const CString &s(_GetPermissionDenied()); - // Out.Replace(_T("[URL_Disconnect]"), s); - // Out.Replace(_T("[URL_Connect]"), s); - //} + Out.Replace(_T("[Disconnect]"), _GetPlainResString(IDS_IRC_DISCONNECT)); Out.Replace(_T("[Connect]"), _GetPlainResString(IDS_CONNECTTOANYSERVER)); Out.Replace(_T("[ServerOptions]"), _GetPlainResString(IDS_CONNECTION)); @@ -3199,7 +3185,7 @@ CString CWebServer::_GetServerInfo(const ThreadData &Data) const CString &sSession(_ParseURL(Data.sURL, _T("ses"))); - CString Out = pThis->m_Templates.sServerInfo; + CString Out(pThis->m_Templates.sServerInfo); if (_ParseURL(Data.sURL, _T("clear")) == _T("yes") && _IsSessionAdmin(Data, sSession)) theApp.emuledlg->ResetServerInfo(); @@ -3219,7 +3205,7 @@ CString CWebServer::_GetDebugLog(const ThreadData &Data) const CString &sSession(_ParseURL(Data.sURL, _T("ses"))); - CString Out = pThis->m_Templates.sDebugLog; + CString Out(pThis->m_Templates.sDebugLog); if (_ParseURL(Data.sURL, _T("clear")) == _T("yes") && _IsSessionAdmin(Data, sSession)) theApp.emuledlg->ResetDebugLog(); @@ -3238,7 +3224,7 @@ CString CWebServer::_GetMyInfo(const ThreadData &Data) return CString(); //(void)_ParseURL(Data.sURL, _T("ses")); - CString Out = pThis->m_Templates.sMyInfoLog; + CString Out(pThis->m_Templates.sMyInfoLog); Out.Replace(_T("[MYINFOLOG]"), theApp.emuledlg->serverwnd->GetMyInfoString()); @@ -3258,12 +3244,12 @@ CString CWebServer::_GetKadDlg(const ThreadData &Data) }*/ const CString &sSession(_ParseURL(Data.sURL, _T("ses"))); - CString Out = pThis->m_Templates.sKad; + CString Out(pThis->m_Templates.sKad); if (_IsSessionAdmin(Data, sSession)) { if (!_ParseURL(Data.sURL, _T("bootstrap")).IsEmpty()) { - CString dest; - dest.Format(_T("%s:%s"), (LPCTSTR)_ParseURL(Data.sURL, _T("ip")), (LPCTSTR)_ParseURL(Data.sURL, _T("port"))); + CString dest(_ParseURL(Data.sURL, _T("ip"))); + dest.AppendFormat(_T(":%s"), (LPCTSTR)_ParseURL(Data.sURL, _T("port"))); SendMessage(theApp.emuledlg->m_hWnd, WEB_GUI_INTERACTION, WEBGUIIA_KAD_BOOTSTRAP, (LPARAM)(LPCTSTR)dest); } @@ -3329,7 +3315,7 @@ CString CWebServer::_GetStats(const ThreadData &Data) // refresh statistics SendMessage(theApp.emuledlg->m_hWnd, WEB_GUI_INTERACTION, WEBGUIIA_SHOWSTATISTICS, 1); - CString Out = pThis->m_Templates.sStats; + CString Out(pThis->m_Templates.sStats); // eklmn: new stats Out.Replace(_T("[Stats]"), theApp.emuledlg->statisticswnd->m_stattree.GetHTMLForExport()); @@ -3344,11 +3330,11 @@ CString CWebServer::_GetPreferences(const ThreadData &Data) const CString &sSession(_ParseURL(Data.sURL, _T("ses"))); - CString Out = pThis->m_Templates.sPreferences; + CString Out(pThis->m_Templates.sPreferences); Out.Replace(_T("[Session]"), sSession); if ((_ParseURL(Data.sURL, _T("saveprefs")) == _T("true")) && _IsSessionAdmin(Data, sSession)) { - CString strTmp = _ParseURL(Data.sURL, _T("gzip")); + CString strTmp(_ParseURL(Data.sURL, _T("gzip"))); if (strTmp == _T("true") || strTmp == _T("on")) thePrefs.SetWebUseGzip(true); else if (strTmp == _T("false") || strTmp.IsEmpty()) @@ -3387,7 +3373,6 @@ CString CWebServer::_GetPreferences(const ThreadData &Data) Out.Replace(_T("[UseGzipVal]"), thePrefs.GetWebUseGzip() ? _T("checked") : _T("")); CString sRefresh; - sRefresh.Format(_T("%d"), thePrefs.GetWebPageRefresh()); Out.Replace(_T("[RefreshVal]"), sRefresh); @@ -3439,10 +3424,10 @@ CString CWebServer::_GetPreferences(const ThreadData &Data) sT.Format(_T("%u"), thePrefs.GetMaxUpload() == UNLIMITED ? 0 : thePrefs.GetMaxUpload()); Out.Replace(_T("[MaxUpVal]"), sT); - sT.Format(_T("%i"), thePrefs.GetMaxGraphDownloadRate()); + sT.Format(_T("%u"), thePrefs.GetMaxGraphDownloadRate()); Out.Replace(_T("[MaxCapDownVal]"), sT); - sT.Format(_T("%i"), thePrefs.GetMaxGraphUploadRate(true)); + sT.Format(_T("%u"), thePrefs.GetMaxGraphUploadRate(true)); Out.Replace(_T("[MaxCapUpVal]"), sT); return Out; @@ -3455,7 +3440,7 @@ CString CWebServer::_GetLoginScreen(const ThreadData &Data) return CString(); //(void)_ParseURL(Data.sURL, _T("ses")); - CString Out = pThis->m_Templates.sLogin; + CString Out(pThis->m_Templates.sLogin); Out.Replace(_T("[CharSet]"), HTTPENCODING); Out.Replace(_T("[eMuleAppName]"), _T("eMule")); @@ -3600,7 +3585,7 @@ CString CWebServer::_GetPermissionDenied() CString CWebServer::_GetPlainResString(UINT nID, bool noquote) { - CString sRet = GetResString(nID); + CString sRet(GetResString(nID)); sRet.Remove(_T('&')); if (noquote) { sRet.Replace(_T("'"), _T("’")); @@ -3649,7 +3634,7 @@ CString CWebServer::_GetDownloadGraph(const ThreadData &Data, const CString &fil Out += _T("
"); Out.AppendFormat(pThis->m_Templates.sProgressbarImgs, barcolours[0], pThis->m_Templates.iProgressbarWidth); } else { - const CStringA &s_ChunkBar = pPartFile->GetProgressString(pThis->m_Templates.iProgressbarWidth); + const CStringA &s_ChunkBar(pPartFile->GetProgressString(pThis->m_Templates.iProgressbarWidth)); // and now make a graph out of the array - need to be in a progressive way int compl = static_cast((pThis->m_Templates.iProgressbarWidth / 100.0) * pPartFile->GetPercentCompleted()); @@ -3686,7 +3671,7 @@ CString CWebServer::_GetSearch(const ThreadData &Data) const CString &sSession(_ParseURL(Data.sURL, _T("ses"))); bool bSessionAdmin = _IsSessionAdmin(Data, sSession); - CString Out = pThis->m_Templates.sSearch; + CString Out(pThis->m_Templates.sSearch); if (!_ParseURL(Data.sURL, _T("downloads")).IsEmpty() && bSessionAdmin) { const CString &downloads(_ParseURLArray(Data.sURL, _T("downloads"))); @@ -3750,7 +3735,7 @@ CString CWebServer::_GetSearch(const ThreadData &Data) pParams->eType = SearchTypeEd2kServer; - CString strResponse = _GetPlainResString(IDS_SW_SEARCHINGINFO); + CString strResponse(_GetPlainResString(IDS_SW_SEARCHINGINFO)); try { if (pParams->eType != SearchTypeKademlia) { if (!theApp.emuledlg->searchwnd->DoNewEd2kSearch(pParams)) { @@ -3776,14 +3761,14 @@ CString CWebServer::_GetSearch(const ThreadData &Data) Out.Replace(_T("[Message]"), _GetPlainResString(b ? IDS_SW_REFETCHRES : IDS_ACCESSDENIED)); } - CString sSort = _ParseURL(Data.sURL, _T("sort")); + CString sSort(_ParseURL(Data.sURL, _T("sort"))); if (!sSort.IsEmpty()) pThis->m_iSearchSortby = _tstoi(sSort); sSort = _ParseURL(Data.sURL, _T("sortAsc")); if (!sSort.IsEmpty()) pThis->m_bSearchAsc = _tstoi(sSort) != 0; - CString result = pThis->m_Templates.sSearchHeader; + CString result(pThis->m_Templates.sSearchHeader); CQArray SearchFileArray; theApp.searchlist->GetWebList(&SearchFileArray, pThis->m_iSearchSortby); @@ -3958,24 +3943,24 @@ INT_PTR CWebServer::UpdateSessionCount() return m_Params.Sessions.GetCount(); } -void CWebServer::_InsertCatBox(CString &Out, int preselect, const CString &boxlabel, bool jump, bool extraCats, const CString &sSession, const CString &sFileHash, bool ed2kbox) +void CWebServer::_InsertCatBox(CString &Out, int preselect, LPCTSTR boxlabel, bool jump, bool extraCats, const CString &sSession, const CString &sFileHash, bool ed2kbox) { CString tempBuf; tempBuf.Format(_T("
%s
"); Out.Replace(ed2kbox ? _T("[CATBOXED2K]") : _T("[CATBOX]"), tempBuf); @@ -3984,30 +3969,30 @@ void CWebServer::_InsertCatBox(CString &Out, int preselect, const CString &boxla CString tempBuff4; CString tempBuff; - for (int i = 0; i < thePrefs.GetCatCount(); ++i) { + for (INT_PTR i = 0; i < thePrefs.GetCatCount(); ++i) { + CString strCategory(i ? thePrefs.GetCategory(i)->strTitle : GetResString(IDS_ALL)); if (i == preselect) { tempBuff3 = _T("checked.gif"); - tempBuff4 = (i ? thePrefs.GetCategory(i)->strTitle : GetResString(IDS_ALL)); + tempBuff4 = strCategory; } else tempBuff3 = _T("checked_no.gif"); - CString strCategory(i ? thePrefs.GetCategory(i)->strTitle : GetResString(IDS_ALL)); strCategory.Replace(_T("'"), _T("\\'")); tempBuff.AppendFormat(_T("
") - , (LPCTSTR)sSession, i, tempBuff3, (LPCTSTR)strCategory); + , (LPCTSTR)sSession, (int)i, tempBuff3, (LPCTSTR)strCategory); } if (extraCats) { tempBuff += _T(""); for (int i = 1; i < 16; ++i) { - if ((0 - i) == preselect) { + if (-i == preselect) { tempBuff3 = _T("checked.gif"); - tempBuff4 = _GetSubCatLabel(0 - i); + tempBuff4 = _GetSubCatLabel(-i); } else tempBuff3 = _T("checked_no.gif"); tempBuff.AppendFormat(_T("") - , (LPCTSTR)sSession, 0 - i, tempBuff3, (LPCTSTR)_GetSubCatLabel(0 - i)); + , (LPCTSTR)sSession, -i, tempBuff3, (LPCTSTR)_GetSubCatLabel(-i)); } } Out.Replace(_T("[CatBox]"), tempBuff); @@ -4025,13 +4010,13 @@ void CWebServer::_InsertCatBox(CString &Out, int preselect, const CString &boxla } tempBuff.Empty(); // For each user category index... - for (int i = 0; i < thePrefs.GetCatCount(); ++i) { + for (INT_PTR i = 0; i < thePrefs.GetCatCount(); ++i) { CString strCategory(i ? thePrefs.GetCategory(i)->strTitle : GetResString(IDS_CAT_UNASSIGN)); strCategory.Replace(_T("'"), _T("\\'")); tempBuff3 = (i == preselect) ? _T("checked.gif") : _T("checked_no.gif"); tempBuff.AppendFormat(_T("") - , (LPCTSTR)sSession, (LPCTSTR)sFileHash, i, (LPCTSTR)tempBuff3, (LPCTSTR)strCategory); + , (LPCTSTR)sSession, (LPCTSTR)sFileHash, (int)i, (LPCTSTR)tempBuff3, (LPCTSTR)strCategory); } Out.Replace(_T("[SetCatBox]"), tempBuff); @@ -4042,14 +4027,14 @@ CString CWebServer::_GetSubCatLabel(int cat) if (cat >= 0 || cat < -16) return CString(_T('?')); - static const UINT ids[16] = + static const UINT uids[16] = { IDS_ALLOTHERS, IDS_STATUS_NOTCOMPLETED, IDS_DL_TRANSFCOMPL, IDS_WAITING , IDS_DOWNLOADING, IDS_ERRORLIKE, IDS_PAUSED, IDS_SEENCOMPL , IDS_VIDEO, IDS_AUDIO, IDS_SEARCH_ARC, IDS_SEARCH_CDIMG , IDS_SEARCH_DOC, IDS_SEARCH_PICS, IDS_SEARCH_PRG, IDS_SEARCH_EMULECOLLECTION }; - return _GetPlainResString(ids[-cat - 1]); + return _GetPlainResString(uids[-cat - 1]); } CString CWebServer::_GetRemoteLinkAddedOk(const ThreadData &Data) @@ -4128,14 +4113,13 @@ void CWebServer::_ProcessFileReq(const ThreadData &Data) const CWebServer *pThis = reinterpret_cast(Data.pThis); if (pThis == NULL) return; - CString filename(Data.sURL); CString contenttype; - CString ext(filename.Right(5).MakeLower()); - int i = ext.ReverseFind(_T('.')); - ext.Delete(0, i); - if (i >= 0 && ext.GetLength() > 2) { - ext.Delete(0, 1); + CString filename(Data.sURL); + LPCTSTR pDot = ::PathFindExtension(filename); + if (CPTR(filename, filename.GetLength()) > pDot + 2) { //at least 2 characters + CString ext(pDot + 1); //skip the dot + ext.MakeLower(); if (ext == _T("bmp") || ext == _T("gif") || ext == _T("jpeg") || ext == _T("jpg") || ext == _T("png")) contenttype.Format(_T("Content-Type: image/%s\r\n"), (LPCTSTR)ext); //DonQ - additional file types @@ -4206,9 +4190,9 @@ CString CWebServer::_GetWebImageNameForFileType(const CString &filename) CString CWebServer::_GetClientSummary(const CUpDownClient &client) { - CString buffer; + CString buffer(GetResString(IDS_CD_UNAME)); // name - buffer.Format(_T("%s %s\n"), (LPCTSTR)GetResString(IDS_CD_UNAME), client.GetUserName()); + buffer.AppendFormat(_T(" %s\n"), client.GetUserName()); // client version buffer.AppendFormat(_T("%s: %s\n"), (LPCTSTR)GetResString(IDS_CD_CSOFT), (LPCTSTR)client.GetClientSoftVer()); @@ -4219,7 +4203,7 @@ CString CWebServer::_GetClientSummary(const CUpDownClient &client) if (file) buffer += file->GetFileName(); - // transfering time + // transferring time buffer.AppendFormat(_T("\n\n%s: %s\n"), (LPCTSTR)GetResString(IDS_UPLOADTIME), (LPCTSTR)CastSecondsToHM(client.GetUpStartTimeDelay() / SEC2MS(1))); // transferred data (up, down, global, session) @@ -4230,36 +4214,36 @@ CString CWebServer::_GetClientSummary(const CUpDownClient &client) return buffer; } -CString CWebServer::_GetClientversionImage(const CUpDownClient &client) +void CWebServer::_GetClientversionImage(const CUpDownClient &client, TCHAR pSoft[2]) { - TCHAR c; switch (client.GetClientSoft()) { case SO_EMULE: case SO_OLDEMULE: - c = _T('1'); + *pSoft = _T('1'); break; case SO_EDONKEYHYBRID: - c = _T('h'); + *pSoft = _T('h'); break; case SO_AMULE: - c = _T('a'); + *pSoft = _T('a'); break; case SO_SHAREAZA: - c = _T('s'); + *pSoft = _T('s'); break; case SO_MLDONKEY: - c = _T('m'); + *pSoft = _T('m'); break; case SO_LPHANT: - c = _T('l'); + *pSoft = _T('l'); break; case SO_URL: - c = _T('u'); + *pSoft = _T('u'); break; - default: //SO_EDONKEY - c = _T('0'); + //case SO_EDONKEY: + default: + *pSoft = _T('0'); } - return CString(c); + pSoft[1] = _T('\0'); } CString CWebServer::_GetCommentlist(const ThreadData &Data) @@ -4271,14 +4255,14 @@ CString CWebServer::_GetCommentlist(const ThreadData &Data) return CString(); const CWebServer *pThis = reinterpret_cast(Data.pThis); - CString Out = pThis->m_Templates.sCommentList; + CString Out(pThis->m_Templates.sCommentList); - CString comments; - comments.Format(_T("%s: %s"), (LPCTSTR)GetResString(IDS_COMMENT), (LPCTSTR)pPartFile->GetFileName()); + CString comments(GetResString(IDS_COMMENT)); + comments.AppendFormat(_T(": %s"), (LPCTSTR)pPartFile->GetFileName()); Out.Replace(_T("[COMMENTS]"), comments); CString commentlines; - // prepare commentsinfo-string + // prepare comments info string for (POSITION pos = pPartFile->srclist.GetHeadPosition(); pos != NULL;) { const CUpDownClient *cur_src = pPartFile->srclist.GetNext(pos); if (cur_src->HasFileRating() || !cur_src->GetFileComment().IsEmpty()) @@ -4328,10 +4312,10 @@ int AFX_CDECL CWebServer::_DownloadCmp(void *prm, void const *pv1, void const *p iOrd = p1.sFileName.CompareNoCase(p2.sFileName); break; case DOWN_SORT_SIZE: - iOrd = CompareUnsigned64(p1.m_qwFileSize, p2.m_qwFileSize); + iOrd = CompareUnsigned(p1.m_qwFileSize, p2.m_qwFileSize); break; case DOWN_SORT_TRANSFERRED: - iOrd = CompareUnsigned64(p1.m_qwFileTransferred, p2.m_qwFileTransferred); + iOrd = CompareUnsigned(p1.m_qwFileTransferred, p2.m_qwFileTransferred); break; case DOWN_SORT_SPEED: iOrd = p1.lFileSpeed - p2.lFileSpeed; @@ -4417,13 +4401,13 @@ int AFX_CDECL CWebServer::_SharedCmp(void *prm, void const *pv1, void const *pv2 iOrd = p1.sFileName.CompareNoCase(p2.sFileName); break; case SHARED_SORT_SIZE: - iOrd = CompareUnsigned64(p1.m_qwFileSize, p2.m_qwFileSize); + iOrd = CompareUnsigned(p1.m_qwFileSize, p2.m_qwFileSize); break; case SHARED_SORT_TRANSFERRED: - iOrd = CompareUnsigned64(p1.nFileTransferred, p2.nFileTransferred); + iOrd = CompareUnsigned(p1.nFileTransferred, p2.nFileTransferred); break; case SHARED_SORT_ALL_TIME_TRANSFERRED: - iOrd = CompareUnsigned64(p1.nFileAllTimeTransferred, p2.nFileAllTimeTransferred); + iOrd = CompareUnsigned(p1.nFileAllTimeTransferred, p2.nFileAllTimeTransferred); break; case SHARED_SORT_REQUESTS: iOrd = p1.nFileRequests - p2.nFileRequests; @@ -4456,7 +4440,7 @@ int AFX_CDECL CWebServer::_UploadCmp(void *prm, void const *pv1, void const *pv2 int iOrd; switch ((UploadSort)((SortParams*)prm)->eSort) { case UP_SORT_CLIENT: - iOrd = p1.sClientSoft.CompareNoCase(p2.sClientSoft); + iOrd = *p1.sClientSoft - *p2.sClientSoft; break; case UP_SORT_USER: iOrd = p1.sUserName.CompareNoCase(p2.sUserName); @@ -4468,7 +4452,7 @@ int AFX_CDECL CWebServer::_UploadCmp(void *prm, void const *pv1, void const *pv2 iOrd = p1.sFileName.CompareNoCase(p2.sFileName); break; case UP_SORT_TRANSFERRED: - iOrd = p1.nTransferredUp - p2.nTransferredUp; + iOrd = CompareUnsigned(p1.nTransferredUp, p2.nTransferredUp); break; case UP_SORT_SPEED: iOrd = p1.nDataRate - p2.nDataRate; diff --git a/srchybrid/WebServer.h b/srchybrid/WebServer.h index 67727cf7..ef0bff1f 100644 --- a/srchybrid/WebServer.h +++ b/srchybrid/WebServer.h @@ -88,21 +88,21 @@ typedef struct CString sUserHash; CString sActive; CString sFileInfo; - CString sClientSoft; CString sClientExtra; CString sUserName; CString sFileName; CString sClientNameVersion; - uint32 nTransferredDown; - uint32 nTransferredUp; + uint64 nTransferredDown; + uint64 nTransferredUp; int nDataRate; + TCHAR sClientSoft[2]; } UploadUsers; typedef struct { CString sClientExtra; CString sClientNameVersion; - CString sClientSoft; +// LPCTSTR sClientSoft; CString sClientSoftSpecial; CString sClientState; CString sClientStateSpecial; @@ -111,6 +111,7 @@ typedef struct CString sUserHash; CString sUserName; uint32 nScore; + TCHAR sClientSoft[2]; } QueueUsers; struct SortParams @@ -309,7 +310,7 @@ class CWebServer void StartServer(); void StopServer(); void RestartSockets(); - void AddStatsLine(UpDown line); + void AddStatsLine(const UpDown &line); bool ReloadTemplates(); INT_PTR GetSessionCount() { return m_Params.Sessions.GetCount(); } bool IsRunning() const { return m_bServerWorking; } @@ -358,19 +359,20 @@ class CWebServer static bool _IsSessionAdmin(const ThreadData &Data, const CString &strSsessionID); static CString _GetPermissionDenied(); static CString _GetDownloadGraph(const ThreadData &Data, const CString &filehash); - static void _InsertCatBox(CString &Out, int preselect, const CString &boxlabel, bool jump, bool extraCats, const CString &sSession, const CString &sFileHash, bool ed2kbox = false); + static void _InsertCatBox(CString &Out, int preselect, LPCTSTR boxlabel, bool jump, bool extraCats, const CString &sSession, const CString &sFileHash, bool ed2kbox = false); static CString _GetSubCatLabel(int cat); static CString _GetRemoteLinkAddedOk(const ThreadData &Data); static CString _GetRemoteLinkAddedFailed(const ThreadData &Data); static void _SetLastUserCat(const ThreadData &Data, long lSession, int cat); static int _GetLastUserCat(const ThreadData &Data, long lSession); static void _MakeTransferList(CString &Out, CWebServer *pThis, const ThreadData &Data, void *FilesArray, void *UploadArray, bool bAdmin); + static void _SetBoolean(bool &var, const CString &URL, LPCTSTR pFieldname); static void _SaveWIConfigArray(BOOL *array, int size, LPCTSTR key); static CString _GetWebImageNameForFileType(const CString &filename); static CString _GetClientSummary(const CUpDownClient &client); static CString _GetMyInfo(const ThreadData &Data); - static CString _GetClientversionImage(const CUpDownClient &client); + static void _GetClientversionImage(const CUpDownClient &client, TCHAR pSoft[2]); bool _GetIsTempDisabled() const { return m_bIsTempDisabled; } //never used @@ -384,7 +386,6 @@ class CWebServer GlobalParams m_Params; WebTemplates m_Templates; u_long m_uCurIP; - uint32 m_nStartTempDisabledTime; int m_iSearchSortby; uint16 m_nIntruderDetect; bool m_bServerWorking; diff --git a/srchybrid/WebSocket.cpp b/srchybrid/WebSocket.cpp index c407c947..5138fb90 100644 --- a/srchybrid/WebSocket.cpp +++ b/srchybrid/WebSocket.cpp @@ -44,28 +44,28 @@ void CWebSocket::SetParent(CWebServer *pParent) m_pParent = pParent; } -void CWebSocket::OnRequestReceived(const char *pHeader, DWORD dwHeaderLen, const char *pData, DWORD dwDataLen, const in_addr &inad) +void CWebSocket::OnRequestReceived(const char *pHeader, DWORD dwHeaderLen, const char *pData, DWORD dwDataLen, const in_addr inad) { CStringA sHeader(pHeader, dwHeaderLen); CStringA sURL; - if (sHeader.Left(3) == "GET") + if (strncmp(sHeader, "GET", 3) == 0) sURL = sHeader.Trim(); - else if (sHeader.Left(4) == "POST") { + else if (strncmp(sHeader, "POST", 4) == 0) { CStringA sData(pData, dwDataLen); sURL = '?' + sData.Trim(); // '?' to imitate GET syntax for ParseURL } - if (sURL.Find(' ') >= 0) - sURL = sURL.Mid(sURL.Find(' ') + 1, sURL.GetLength()); - if (sURL.Find(' ') >= 0) - sURL = sURL.Left(sURL.Find(' ')); + sURL.Delete(0, sURL.Find(' ') + 1); + int i = sURL.Find(' '); + if (i >= 0) + sURL.Truncate(i); bool filereq = sURL.GetLength() >= 3 && sURL.Find("..") < 0; // prevent file access in the eMule's webserver folder if (filereq) { CStringA ext(sURL.Right(5).MakeLower()); - int i = ext.ReverseFind('.'); + i = ext.ReverseFind('.') + 1; ext.Delete(0, i); - filereq = i >= 0 && ext.GetLength() > 2 && (ext == ".gif" || ext == ".jpg" || ext == ".png" - || ext == ".ico" || ext == ".css" || ext == ".bmp" || ext == ".js" || ext == ".jpeg"); + filereq = (i > 0) && ext.GetLength() > 1 && (ext == "gif" || ext == "jpg" || ext == "png" + || ext == "ico" || ext == "css" || ext == "bmp" || ext == "js" || ext == "jpeg"); } ThreadData Data; Data.sURL = sURL; @@ -81,7 +81,7 @@ void CWebSocket::OnRequestReceived(const char *pHeader, DWORD dwHeaderLen, const Disconnect(); } -void CWebSocket::OnReceived(void *pData, DWORD dwSize, const in_addr &inad) +void CWebSocket::OnReceived(void *pData, DWORD dwSize, const in_addr inad) { static const DWORD SIZE_PRESERVE = 0x1000u; @@ -263,7 +263,7 @@ void CWebSocket::Disconnect() m_bCanSend = false; if (m_pTail) try { - // push an empty chunk as a tail + // push an empty chunk as the tail m_pTail->m_pNext = new CChunk(); } catch (...) { } @@ -275,9 +275,9 @@ void CWebSocket::Disconnect() UINT AFX_CDECL WebSocketAcceptedFunc(LPVOID pD) { DbgSetThreadName("WebSocketAccepted"); + InitThreadLocale(); srand((unsigned)time(NULL)); - InitThreadLocale(); const SocketData *pData = static_cast(pD); CWebServer *pThis = static_cast(pData->pThis); @@ -431,9 +431,9 @@ UINT AFX_CDECL WebSocketAcceptedFunc(LPVOID pD) UINT AFX_CDECL WebSocketListeningFunc(LPVOID pThis) { DbgSetThreadName("WebSocketListening"); + InitThreadLocale(); srand((unsigned)time(NULL)); - InitThreadLocale(); SOCKET hSocket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0); if (INVALID_SOCKET != hSocket) { @@ -509,12 +509,12 @@ int StartSSL() mbedtls_ssl_config_init(&conf); mbedtls_ctr_drbg_init(&ctr_drbg); mbedtls_entropy_init(&entropy); - int ret = mbedtls_x509_crt_parse_file(&srvcert, thePrefs.GetWebCertPath()); + int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (unsigned char*)pers, strlen(pers)); if (!ret) { - mbedtls_pk_init(&pkey); - ret = mbedtls_pk_parse_keyfile(&pkey, thePrefs.GetWebKeyPath(), NULL); + ret = mbedtls_x509_crt_parse_file(&srvcert, thePrefs.GetWebCertPath()); if (!ret) { - ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (unsigned char*)pers, strlen(pers)); + mbedtls_pk_init(&pkey); + ret = mbedtls_pk_parse_keyfile(&pkey, thePrefs.GetWebKeyPath(), NULL, mbedtls_ctr_drbg_random, &ctr_drbg); if (!ret) { ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); if (!ret) { diff --git a/srchybrid/WebSocket.h b/srchybrid/WebSocket.h index 461b39f7..083ab741 100644 --- a/srchybrid/WebSocket.h +++ b/srchybrid/WebSocket.h @@ -1,6 +1,6 @@ #pragma once -#include "mbedtls/config.h" +#include "mbedtls/build_info.h" #include "mbedtls/ssl.h" class CWebServer; @@ -40,7 +40,7 @@ class CWebSocket bool m_bCanSend; bool m_bValid; - void OnReceived(void *pData, DWORD dwSize, const in_addr &inad); // must be implemented + void OnReceived(void *pData, DWORD dwSize, const in_addr inad); // must be implemented void SendData(const void *pData, DWORD dwDataSize); void SendData(LPCSTR szText) { SendData(szText, (DWORD)strlen(szText)); } void SendContent(LPCSTR szStdResponse, const void *pContent, DWORD dwContentSize); @@ -48,5 +48,5 @@ class CWebSocket void SendReply(LPCSTR szReply); void Disconnect(); - void OnRequestReceived(const char *pHeader, DWORD dwHeaderLen, const char *pData, DWORD dwDataLen, const in_addr &inad); + void OnRequestReceived(const char *pHeader, DWORD dwHeaderLen, const char *pData, DWORD dwDataLen, const in_addr inad); }; \ No newline at end of file diff --git a/srchybrid/Wizard.cpp b/srchybrid/Wizard.cpp index 9967c2b3..0ebeb848 100644 --- a/srchybrid/Wizard.cpp +++ b/srchybrid/Wizard.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -36,8 +36,6 @@ IMPLEMENT_DYNAMIC(CConnectionWizardDlg, CDialog) BEGIN_MESSAGE_MAP(CConnectionWizardDlg, CDialog) ON_BN_CLICKED(IDC_WIZ_APPLY_BUTTON, OnBnClickedApply) ON_BN_CLICKED(IDC_WIZ_CANCEL_BUTTON, OnBnClickedCancel) - ON_BN_CLICKED(IDC_WIZ_XP_RADIO, OnBnClickedWizRadioOsNtxp) - ON_BN_CLICKED(IDC_WIZ_ME_RADIO, OnBnClickedWizRadioUs98me) ON_BN_CLICKED(IDC_WIZ_LOWDOWN_RADIO, OnBnClickedWizLowdownloadRadio) ON_BN_CLICKED(IDC_WIZ_MEDIUMDOWN_RADIO, OnBnClickedWizMediumdownloadRadio) ON_BN_CLICKED(IDC_WIZ_HIGHDOWN_RADIO, OnBnClickedWizHighdownloadRadio) @@ -47,7 +45,6 @@ END_MESSAGE_MAP() CConnectionWizardDlg::CConnectionWizardDlg(CWnd *pParent /*=NULL*/) : CDialog(CConnectionWizardDlg::IDD, pParent) , m_icoWnd() - , m_iOS() , m_iTotalDownload() { } @@ -61,8 +58,8 @@ CConnectionWizardDlg::~CConnectionWizardDlg() void CConnectionWizardDlg::DoDataExchange(CDataExchange *pDX) { CDialog::DoDataExchange(pDX); + //DDX_Radio(pDX, IDC_WIZ_XP_RADIO, m_iOS); DDX_Control(pDX, IDC_PROVIDERS, m_provider); - DDX_Radio(pDX, IDC_WIZ_XP_RADIO, m_iOS); DDX_Radio(pDX, IDC_WIZ_LOWDOWN_RADIO, m_iTotalDownload); } @@ -81,31 +78,31 @@ void CConnectionWizardDlg::OnBnClickedApply() return; } - int download = (int)GetDlgItemInt(IDC_WIZ_TRUEDOWNLOAD_BOX, NULL, TRUE); - if (download < 0) { + UINT download = GetDlgItemInt(IDC_WIZ_TRUEDOWNLOAD_BOX, NULL, TRUE); + if (download <= 0) { GetDlgItem(IDC_WIZ_TRUEDOWNLOAD_BOX)->SetFocus(); return; } - int upload = (int)GetDlgItemInt(IDC_WIZ_TRUEUPLOAD_BOX, NULL, TRUE); - if (upload < 0) { + UINT upload = GetDlgItemInt(IDC_WIZ_TRUEUPLOAD_BOX, NULL, TRUE); + if (upload <= 0) { GetDlgItem(IDC_WIZ_TRUEUPLOAD_BOX)->SetFocus(); return; } if (IsDlgButtonChecked(IDC_KBITS)) { - upload = (((upload / 8) * 1000) + 512) / 1024; - download = (((download / 8) * 1000) + 512) / 1024; + upload = (upload / 8 * 1000 + 512) / 1024; + download = (download / 8 * 1000 + 512) / 1024; } else { - upload = ((upload * 1000) + 512) / 1024; - download = ((download * 1000) + 512) / 1024; + upload = (upload * 1000 + 512) / 1024; + download = (download * 1000 + 512) / 1024; } thePrefs.maxGraphDownloadRate = download; thePrefs.maxGraphUploadRate = upload; if (upload > 0 && download > 0) { - thePrefs.m_maxupload = (uint32)((upload * 4) / 5); + thePrefs.m_maxupload = upload * 4 / 5; if (upload < 4 && download > upload * 3) { thePrefs.m_maxdownload = thePrefs.m_maxupload * 3; download = upload * 3; @@ -116,28 +113,21 @@ void CConnectionWizardDlg::OnBnClickedApply() thePrefs.m_maxdownload = thePrefs.m_maxupload * 5; download = upload * 5; } else - thePrefs.m_maxdownload = (uint32)(download * 9 / 10); + thePrefs.m_maxdownload = download * 9 / 10; theApp.emuledlg->statisticswnd->SetARange(false, thePrefs.maxGraphUploadRate); theApp.emuledlg->statisticswnd->SetARange(true, thePrefs.maxGraphDownloadRate); - if (m_iOS == 1) - thePrefs.maxconnections = 50; - else { - if (upload <= 7) - thePrefs.maxconnections = 80; - else if (upload < 12) - thePrefs.maxconnections = 200; - else if (upload < 25) - thePrefs.maxconnections = 400; - else if (upload < 37) - thePrefs.maxconnections = 600; - else - thePrefs.maxconnections = 800; - } - - if (m_iOS == 1) - download /= 2; + if (upload <= 7) + thePrefs.maxconnections = 80; + else if (upload < 12) + thePrefs.maxconnections = 200; + else if (upload < 25) + thePrefs.maxconnections = 400; + else if (upload < 37) + thePrefs.maxconnections = 600; + else + thePrefs.maxconnections = 800; static const UINT srcperfile[5][3] = { @@ -171,16 +161,6 @@ void CConnectionWizardDlg::OnBnClickedCancel() CDialog::OnCancel(); } -void CConnectionWizardDlg::OnBnClickedWizRadioOsNtxp() -{ - m_iOS = 0; -} - -void CConnectionWizardDlg::OnBnClickedWizRadioUs98me() -{ - m_iOS = 1; -} - void CConnectionWizardDlg::OnBnClickedWizLowdownloadRadio() { m_iTotalDownload = 0; @@ -209,16 +189,6 @@ BOOL CConnectionWizardDlg::OnInitDialog() SetIcon(m_icoWnd = theApp.LoadIcon(_T("Wizard")), FALSE); - switch (thePrefs.GetWindowsVersion()) { - case _WINVER_95_: - case _WINVER_98_: - case _WINVER_ME_: - m_iOS = 1; - break; - default: - m_iOS = 0; - } - CheckRadioButton(IDC_WIZ_XP_RADIO, IDC_WIZ_ME_RADIO, m_iOS ? IDC_WIZ_ME_RADIO : IDC_WIZ_XP_RADIO); CheckRadioButton(IDC_WIZ_LOWDOWN_RADIO, IDC_WIZ_HIGHDOWN_RADIO, IDC_WIZ_LOWDOWN_RADIO); CheckRadioButton(IDC_KBITS, IDC_KBYTES, IDC_KBITS); @@ -230,27 +200,63 @@ BOOL CConnectionWizardDlg::OnInitDialog() m_provider.InsertColumn(2, GetResString(IDS_WIZ_UP), LVCFMT_LEFT, 85); m_provider.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP); - m_provider.InsertItem(0, GetResString(IDS_UNKNOWN));m_provider.SetItemText(0, 1, _T(""));m_provider.SetItemText(0, 2, _T("")); - m_provider.InsertItem(1, GetResString(IDS_WIZARD_CUSTOM));m_provider.SetItemText(1, 1, GetResString(IDS_WIZARD_ENTERBELOW));m_provider.SetItemText(1, 2, GetResString(IDS_WIZARD_ENTERBELOW)); - m_provider.InsertItem(2, _T("56-k Modem"));m_provider.SetItemText(2, 1, _T("56"));m_provider.SetItemText(2, 2, _T("56")); - m_provider.InsertItem(3, _T("ISDN"));m_provider.SetItemText(3, 1, _T("64"));m_provider.SetItemText(3, 2, _T("64")); - m_provider.InsertItem(4, _T("ISDN 2x"));m_provider.SetItemText(4, 1, _T("128"));m_provider.SetItemText(4, 2, _T("128")); - - m_provider.InsertItem(5, _T("T DSL 1000 (T,Arcor,Freenet,1&1)"));m_provider.SetItemText(5, 1, _T("1024"));m_provider.SetItemText(5, 2, _T("128")); - m_provider.InsertItem(6, _T("T DSL 1500 (T)"));m_provider.SetItemText(6, 1, _T("1536"));m_provider.SetItemText(6, 2, _T("192")); - m_provider.InsertItem(7, _T("T DSL 2000 (T,Arcor,Freenet,Tiscali,Alice)"));m_provider.SetItemText(7, 1, _T("2048"));m_provider.SetItemText(7, 2, _T("192")); - m_provider.InsertItem(8, _T("Versatel DSL 2000"));m_provider.SetItemText(8, 1, _T("2048"));m_provider.SetItemText(8, 2, _T("384")); - - m_provider.InsertItem(9, _T("T-DSL 3000 (T,Arcor)"));m_provider.SetItemText(9, 1, _T("3072"));m_provider.SetItemText(9, 2, _T("384")); - m_provider.InsertItem(10, _T("T DSL 6000 (T,Arcor)"));m_provider.SetItemText(10, 1, _T("6016"));m_provider.SetItemText(10, 2, _T("576")); - m_provider.InsertItem(11, _T(" DSL 6000 (Tiscali,Freenet,1&1)"));m_provider.SetItemText(11, 1, _T("6016"));m_provider.SetItemText(11, 2, _T("572")); - m_provider.InsertItem(12, _T(" DSL 6000 (Lycos,Alice)"));m_provider.SetItemText(12, 1, _T("6016"));m_provider.SetItemText(12, 2, _T("512")); - m_provider.InsertItem(13, _T("Versatel DSL 6000"));m_provider.SetItemText(13, 1, _T("6144"));m_provider.SetItemText(13, 2, _T("512")); - - m_provider.InsertItem(14, _T("Cable"));m_provider.SetItemText(14, 1, _T("187"));m_provider.SetItemText(14, 2, _T("32")); - m_provider.InsertItem(15, _T("Cable"));m_provider.SetItemText(15, 1, _T("187"));m_provider.SetItemText(15, 2, _T("64")); - m_provider.InsertItem(16, _T("T1"));m_provider.SetItemText(16, 1, _T("1500"));m_provider.SetItemText(16, 2, _T("1500")); - m_provider.InsertItem(17, _T("T3+"));m_provider.SetItemText(17, 1, _T("44 Mbps"));m_provider.SetItemText(17, 2, _T("44 Mbps")); + m_provider.InsertItem(0, GetResString(IDS_UNKNOWN)); + m_provider.SetItemText(0, 1, _T("")); + m_provider.SetItemText(0, 2, _T("")); + m_provider.InsertItem(1, GetResString(IDS_WIZARD_CUSTOM)); + m_provider.SetItemText(1, 1, GetResString(IDS_WIZARD_ENTERBELOW)); + m_provider.SetItemText(1, 2, GetResString(IDS_WIZARD_ENTERBELOW)); + m_provider.InsertItem(2, _T("V.92 Modem")); + m_provider.SetItemText(2, 1, _T("56")); + m_provider.SetItemText(2, 2, _T("48")); + m_provider.InsertItem(3, _T("ISDN")); + m_provider.SetItemText(3, 1, _T("64")); + m_provider.SetItemText(3, 2, _T("64")); + m_provider.InsertItem(4, _T("ISDN 2x")); + m_provider.SetItemText(4, 1, _T("128")); + m_provider.SetItemText(4, 2, _T("128")); + + m_provider.InsertItem(5, _T("T DSL 1000 (T,Arcor,Freenet,1&1)")); + m_provider.SetItemText(5, 1, _T("1024")); + m_provider.SetItemText(5, 2, _T("128")); + m_provider.InsertItem(6, _T("T DSL 1500 (T)")); + m_provider.SetItemText(6, 1, _T("1536")); + m_provider.SetItemText(6, 2, _T("192")); + m_provider.InsertItem(7, _T("T DSL 2000 (T,Arcor,Freenet,Tiscali,Alice)")); + m_provider.SetItemText(7, 1, _T("2048")); + m_provider.SetItemText(7, 2, _T("192")); + m_provider.InsertItem(8, _T("Versatel DSL 2000")); + m_provider.SetItemText(8, 1, _T("2048")); + m_provider.SetItemText(8, 2, _T("384")); + + m_provider.InsertItem(9, _T("T-DSL 3000 (T,Arcor)")); + m_provider.SetItemText(9, 1, _T("3072")); + m_provider.SetItemText(9, 2, _T("384")); + m_provider.InsertItem(10, _T("T DSL 6000 (T,Arcor)")); + m_provider.SetItemText(10, 1, _T("6016")); + m_provider.SetItemText(10, 2, _T("576")); + m_provider.InsertItem(11, _T(" DSL 6000 (Tiscali,Freenet,1&1)")); + m_provider.SetItemText(11, 1, _T("6016")); + m_provider.SetItemText(11, 2, _T("572")); + m_provider.InsertItem(12, _T(" DSL 6000 (Lycos,Alice)")); + m_provider.SetItemText(12, 1, _T("6016")); + m_provider.SetItemText(12, 2, _T("512")); + m_provider.InsertItem(13, _T("Versatel DSL 6000")); + m_provider.SetItemText(13, 1, _T("6144")); + m_provider.SetItemText(13, 2, _T("512")); + + m_provider.InsertItem(14, _T("Cable")); + m_provider.SetItemText(14, 1, _T("187")); + m_provider.SetItemText(14, 2, _T("32")); + m_provider.InsertItem(15, _T("Cable")); + m_provider.SetItemText(15, 1, _T("187")); + m_provider.SetItemText(15, 2, _T("64")); + m_provider.InsertItem(16, _T("T1")); + m_provider.SetItemText(16, 1, _T("1500")); + m_provider.SetItemText(16, 2, _T("1500")); + m_provider.InsertItem(17, _T("T3+")); + m_provider.SetItemText(17, 1, _T("44 Mbps")); + m_provider.SetItemText(17, 2, _T("44 Mbps")); m_provider.SetSelectionMark(0); m_provider.SetItemState(0, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); @@ -273,12 +279,12 @@ void CConnectionWizardDlg::OnNmClickProviders(LPNMHDR, LRESULT *pResult) }; static const UINT aup[18] = { - 0, 0, 33u, 64u, 128u, 128u, 192u, 192u, 384u, 384u, 576u, 572u, 512u, 512u, 32u, 64u, 1500u, 44000u + 0, 0, 48u, 64u, 128u, 128u, 192u, 192u, 384u, 384u, 576u, 572u, 512u, 512u, 32u, 64u, 1500u, 44000u }; UINT up, down; - if (i == 1) { - down = ((thePrefs.maxGraphDownloadRate * 1024) + 500) / 1000 * 8; - up = ((thePrefs.GetMaxGraphUploadRate(true) * 1024) + 500) / 1000 * 8; + if (i == 1) { //this is 'custom'; convert to kilobits + down = (thePrefs.maxGraphDownloadRate * 1024 + 500) / 1000 * 8; + up = (thePrefs.GetMaxGraphUploadRate(true) * 1024 + 500) / 1000 * 8; } else { down = adown[i]; up = aup[i]; @@ -306,7 +312,7 @@ void CConnectionWizardDlg::Localize() void CConnectionWizardDlg::SetCustomItemsActivation() { - BOOL bActive = m_provider.GetSelectionMark() == 1; + BOOL bActive = (m_provider.GetSelectionMark() == 1); GetDlgItem(IDC_WIZ_TRUEUPLOAD_BOX)->EnableWindow(bActive); GetDlgItem(IDC_WIZ_TRUEDOWNLOAD_BOX)->EnableWindow(bActive); GetDlgItem(IDC_KBITS)->EnableWindow(bActive); diff --git a/srchybrid/Wizard.h b/srchybrid/Wizard.h index 7cd935e4..5e4d679d 100644 --- a/srchybrid/Wizard.h +++ b/srchybrid/Wizard.h @@ -18,7 +18,6 @@ class CConnectionWizardDlg : public CDialog protected: HICON m_icoWnd; CListCtrl m_provider; - int m_iOS; int m_iTotalDownload; void SetCustomItemsActivation(); @@ -32,8 +31,6 @@ class CConnectionWizardDlg : public CDialog afx_msg void OnBnClickedWizHighdownloadRadio(); afx_msg void OnBnClickedWizLowdownloadRadio(); afx_msg void OnBnClickedWizMediumdownloadRadio(); - afx_msg void OnBnClickedWizRadioOsNtxp(); - afx_msg void OnBnClickedWizRadioUs98me(); afx_msg void OnBnClickedWizResetButton(); afx_msg void OnNmClickProviders(LPNMHDR, LRESULT *pResult); }; \ No newline at end of file diff --git a/srchybrid/ZIPFile.cpp b/srchybrid/ZIPFile.cpp index 5cf20797..775820e6 100644 --- a/srchybrid/ZIPFile.cpp +++ b/srchybrid/ZIPFile.cpp @@ -170,20 +170,15 @@ BOOL CZIPFile::LocateCentralDirectory() SetFilePointer(m_hFile, -(LONG)sizeof pBuffer, NULL, FILE_END); if (!::ReadFile(m_hFile, pBuffer, sizeof pBuffer, &nBuffer, NULL)) return FALSE; - if (nBuffer < sizeof(ZIP_DIRECTORY_LOC)) - return FALSE; ZIP_DIRECTORY_LOC *pLoc = NULL; - - for (DWORD nScan = 4; nScan < nBuffer; ++nScan) { - DWORD *pnSignature = (DWORD*)(pBuffer + nBuffer - nScan); - + for (INT_PTR nScan = nBuffer - sizeof(ZIP_DIRECTORY_LOC) + 1; --nScan >= 0;) { + DWORD *pnSignature = (DWORD*)&pBuffer[nScan]; if (*pnSignature == 0x06054b50) { pLoc = (ZIP_DIRECTORY_LOC*)pnSignature; break; } } - if (pLoc == NULL) return FALSE; ASSERT(pLoc->nSignature == 0x06054b50); @@ -307,8 +302,7 @@ BOOL CZIPFile::SeekToFile(File *pFile) return FALSE; ZIP_LOCAL_FILE pLocal; - DWORD nRead = 0; - + DWORD nRead; VERIFY(::ReadFile(m_hFile, &pLocal, sizeof pLocal, &nRead, NULL)); if (nRead != sizeof pLocal) return FALSE; @@ -363,10 +357,11 @@ BOOL CZIPFile::File::PrepareToDecompress(LPVOID pStream) } DWORD nSource = (DWORD)m_nCompressedSize; + DWORD rSource; BYTE *pSource = new BYTE[nSource]; - ::ReadFile(m_pZIP->m_hFile, pSource, nSource, &nSource, NULL); + ::ReadFile(m_pZIP->m_hFile, pSource, nSource, &rSource, NULL); - if (nSource != (DWORD)m_nCompressedSize) { + if (nSource != rSource) { inflateEnd(&pStream); delete[] pSource; return NULL; @@ -406,8 +401,7 @@ BOOL CZIPFile::File::Extract(LPCTSTR pszFile) z_stream pStream; HANDLE hFile; - hFile = ::CreateFile(pszFile, GENERIC_WRITE, 0, NULL, CREATE_NEW, - FILE_ATTRIBUTE_NORMAL, NULL); + hFile = ::CreateFile(pszFile, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) return FALSE; @@ -428,7 +422,7 @@ BOOL CZIPFile::File::Extract(LPCTSTR pszFile) pStream.avail_in = (DWORD)min(m_nCompressedSize - nCompressed, BUFFER_IN_SIZE); pStream.next_in = pBufferIn; - DWORD nRead = 0; + DWORD nRead; VERIFY(::ReadFile(m_pZIP->m_hFile, pBufferIn, pStream.avail_in, &nRead, NULL)); if (nRead != pStream.avail_in) break; @@ -443,8 +437,9 @@ BOOL CZIPFile::File::Extract(LPCTSTR pszFile) if (pStream.avail_out < BUFFER_OUT_SIZE) { DWORD nWrite = BUFFER_OUT_SIZE - pStream.avail_out; - ::WriteFile(hFile, pBufferOut, nWrite, &nWrite, NULL); - if (nWrite != BUFFER_OUT_SIZE - pStream.avail_out) + DWORD nWritten; + ::WriteFile(hFile, pBufferOut, nWrite, &nWritten, NULL); + if (nWritten != nWrite) break; nUncompressed += nWrite; } @@ -456,7 +451,7 @@ BOOL CZIPFile::File::Extract(LPCTSTR pszFile) } else while (nUncompressed < m_nSize) { DWORD nChunk = (DWORD)min(m_nSize - nUncompressed, BUFFER_OUT_SIZE); - DWORD nProcess = 0; + DWORD nProcess; VERIFY(::ReadFile(m_pZIP->m_hFile, pBufferOut, nChunk, &nProcess, NULL)); if (nChunk != nProcess) diff --git a/srchybrid/emule.rc b/srchybrid/emule.rc index 95e61bb7..a310cbdf 100644 --- a/srchybrid/emule.rc +++ b/srchybrid/emule.rc @@ -107,7 +107,7 @@ BEGIN CONTROL "",IDC_MYINFOLIST,"RichEdit20W",ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,372,176,130,106,WS_EX_STATICEDGE ICON "",IDC_SERVLST_ICO,5,5,20,20,SS_NOTIFY CONTROL "Servers:",IDC_SERVLIST_TEXT,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,18,6,91,8 - CONTROL "",IDC_SERVLIST,"SysListView32",LVS_REPORT | LVS_OWNERDRAWFIXED | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,5,17,358,159 + CONTROL "",IDC_SERVLIST,"SysListView32",LVS_REPORT | LVS_OWNERDRAWFIXED | LVS_SHAREIMAGELISTS | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,5,17,358,159 CONTROL "",IDC_SPLITTER_SERVER,"Static",SS_BLACKFRAME | NOT WS_VISIBLE,4,179,357,4 CONTROL "",IDC_TAB3,"SysTabControl32",WS_TABSTOP,5,194,358,96 PUSHBUTTON "Reset",IDC_LOGRESET,318,183,45,12 @@ -296,7 +296,7 @@ BEGIN PUSHBUTTON "Button1",IDC_FNC,176,43,48,12 CONTROL "Try to transfer full chunks to all uploads",IDC_FULLCHUNKTRANS, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,70,209,10 - CONTROL "Try to Download preview chunks first.",IDC_PREVIEWPRIO, + CONTROL "Try to download preview chunks first.",IDC_PREVIEWPRIO, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,80,209,10 CONTROL "IDS_PF_WATCHCB",IDC_WATCHCB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,90,209,10 CONTROL "Use advanced calculation method for remaining time",IDC_PF_TIMECALC, @@ -365,12 +365,12 @@ BEGIN GROUPBOX "Max. connections:",IDC_MAXCONN_FRM,110,132,117,40 GROUPBOX "Capacities:",IDC_CAPACITIES_FRM,4,2,67,70 CONTROL "Download",IDC_DCAP_LBL,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,11,13,58,8 - LTEXT "kB/s",IDC_KBS2,45,25,22,8 - LTEXT "kB/s",IDC_KBS3,45,54,22,8 + LTEXT "KB/s",IDC_KBS2,45,25,22,8 + LTEXT "KB/s",IDC_KBS3,45,54,22,8 CONTROL "Upload",IDC_UCAP_LBL,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,11,42,58,8 GROUPBOX "Limits:",IDC_LIMITS_FRM,77,2,149,70 - RTEXT "kB/s",IDC_KBS1,176,13,44,8 - RTEXT "kB/s",IDC_KBS4,176,43,44,8 + RTEXT "KB/s",IDC_KBS1,176,13,44,8 + RTEXT "KB/s",IDC_KBS4,176,43,44,8 LTEXT "Hard limit",IDC_MAXSRCHARD_LBL,11,143,82,8 LTEXT "UDP",IDC_UDPPORTLABEL,11,103,16,8 LTEXT "Static",IDC_MAXCONLABEL,117,143,86,8 @@ -386,23 +386,20 @@ STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSM CAPTION "Wizard" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN - CONTROL "Win2K/XP/Vista+",IDC_WIZ_XP_RADIO,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,14,17,77,10 - CONTROL "Win95/98/ME",IDC_WIZ_ME_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,107,17,77,10 - CONTROL "1-5",IDC_WIZ_LOWDOWN_RADIO,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,14,48,40,10 - CONTROL "6-15",IDC_WIZ_MEDIUMDOWN_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,107,48,40,10 - CONTROL "16+",IDC_WIZ_HIGHDOWN_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,200,48,40,10 - CONTROL "",IDC_PROVIDERS,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_GROUP | WS_TABSTOP,14,79,228,85 + GROUPBOX "Concurrent Downloads",IDC_WIZ_CONCURENTDOWN_FRAME,7,7,242,25 + CONTROL "1-5",IDC_WIZ_LOWDOWN_RADIO,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,14,17,40,10 + CONTROL "6-15",IDC_WIZ_MEDIUMDOWN_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,107,17,40,10 + CONTROL "16+",IDC_WIZ_HIGHDOWN_RADIO,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,200,17,40,10 + CONTROL "",IDC_PROVIDERS,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_GROUP | WS_TABSTOP,14,49,228,112 + GROUPBOX "Connection Type",IDC_WIZ_HOTBUTTON_FRAME,7,37,242,161 + RTEXT "True Upload Bandwidth",IDC_WIZ_TRUEUPLOAD_TEXT,14,181,116,8 EDITTEXT IDC_WIZ_TRUEDOWNLOAD_BOX,133,166,40,12,ES_AUTOHSCROLL + RTEXT "True Download Bandwidth",IDC_WIZ_TRUEDOWNLOAD_TEXT,14,168,116,8 EDITTEXT IDC_WIZ_TRUEUPLOAD_BOX,133,179,40,12,ES_AUTOHSCROLL CONTROL "Kbit/s",IDC_KBITS,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,176,168,66,11 CONTROL "KB/s",IDC_KBYTES,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,176,180,66,11 DEFPUSHBUTTON "Apply",IDC_WIZ_APPLY_BUTTON,136,204,55,14,WS_GROUP PUSHBUTTON "Cancel",IDC_WIZ_CANCEL_BUTTON,194,204,56,14 - GROUPBOX "Operating System",IDC_WIZ_OS_FRAME,7,7,242,25 - GROUPBOX "Concurrent Downloads",IDC_WIZ_CONCURENTDOWN_FRAME,7,37,242,25 - GROUPBOX "Connection Type",IDC_WIZ_HOTBUTTON_FRAME,7,67,242,131 - RTEXT "True Upload Bandwidth",IDC_WIZ_TRUEUPLOAD_TEXT,14,181,116,8 - RTEXT "True Download Bandwidth",IDC_WIZ_TRUEDOWNLOAD_TEXT,14,168,116,8 END IDD_IRC DIALOGEX 0, 35, 511, 289 @@ -430,6 +427,8 @@ BEGIN ICON "",IDC_FILES_ICO,5,5,20,20,SS_NOTIFY CONTROL "",IDC_SHAREDDIRSTREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,5,33,114,252 EDITTEXT IDC_SHAREDFILES_FILTER,5,17,114,14,ES_MULTILINE | ES_AUTOHSCROLL + ICON "",IDC_SF_FICON,124,273,20,20 + LTEXT "",IDC_SF_FNAME,144,275,340,8 END IDD_PPG_NOTIFY DIALOGEX 0, 0, 231, 241 @@ -870,7 +869,7 @@ BEGIN CONTROL "eD2K",IDC_WIZARD_NETWORK_ED2K,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,8,14,144,10 CONTROL "Kad",IDC_WIZARD_NETWORK_KADEMLIA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,158,14,145,10 GROUPBOX "eD2K Setting",IDC_WIZARD_ED2K,0,38,317,63 - CONTROL "Do you want eMule to connect using Safe Connect?\n\nTurning this feature off allows eMule to connect to servers a little faster, but can cause you to get more false lowID connects.",IDC_SAFESERVERCONNECT, + CONTROL "Do you want eMule to connect using Safe Connect?\n\nTurning this feature off allows eMule to connect to servers a little faster, but can cause you to get more false low ID connects.",IDC_SAFESERVERCONNECT, "Button",BS_AUTOCHECKBOX | BS_TOP | BS_MULTILINE | WS_TABSTOP,8,53,289,45 END @@ -909,7 +908,7 @@ BEGIN EDITTEXT IDC_BOOTSTRAPPORT,458,57,40,12,ES_AUTOHSCROLL | ES_NUMBER CONTROL "from connected clients",IDC_RADCLIENTS,"Button",BS_AUTORADIOBUTTON,364,97,134,8 PUSHBUTTON "BootStrap",IDC_BOOTSTRAPBUTTON,430,107,68,13 - CONTROL "",IDC_SEARCHLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_OWNERDRAWFIXED | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,5,193,501,93 + CONTROL "",IDC_KADSEARCHLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_OWNERDRAWFIXED | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,5,193,501,93 CONTROL "",IDC_CONTACTLIST,"SysListView32",LVS_REPORT | LVS_OWNERDRAWFIXED | LVS_ALIGNLEFT | NOT WS_VISIBLE | WS_BORDER | WS_TABSTOP,5,17,349,162 LTEXT "IP or Address:",IDC_SSTATIC4,376,47,74,8 LTEXT "Port:",IDC_SSTATIC7,458,47,40,8 @@ -953,7 +952,7 @@ BEGIN CONTROL "Static",IDC_DDOWNTOTAL,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_GROUP,110,135,53,8 RTEXT "Uploaded (this session):",IDC_STATIC45,163,113,90,8,0 CONTROL "Static",IDC_DDUP,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_GROUP,256,113,51,8 - RTEXT "Average Uploadrate:",IDC_STATIC46,163,124,90,8,0 + RTEXT "Average Upload rate:",IDC_STATIC46,163,124,90,8,0 CONTROL "Static",IDC_DAVUR,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_GROUP,256,124,50,8 RTEXT "Uploaded total:",IDC_STATIC47,163,135,90,8,0 CONTROL "Static",IDC_DUPTOTAL,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_GROUP,256,135,50,8 @@ -962,7 +961,7 @@ BEGIN CONTROL "Static",IDC_DRATIO,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_GROUP,110,166,53,8 RTEXT "Rating (total):",IDC_STATIC52,19,177,87,8,0 CONTROL "Static",IDC_DRATING,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_GROUP,110,177,53,8 - RTEXT "Uploadqueue Score:",IDC_STATIC53,19,188,87,8,0 + RTEXT "Upload queue Score:",IDC_STATIC53,19,188,87,8,0 CONTROL "Static",IDC_DSCORE,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_GROUP,110,188,105,8 RTEXT "Currently downloading:",IDC_STATIC48,19,102,87,8,0 CONTROL "Static",IDC_UPLOADING,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_GROUP,110,102,202,8 @@ -1004,7 +1003,7 @@ BEGIN CONTROL "Static",IDC_HASHSET,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_GROUP,269,97,62,8 CONTROL "Sources:",IDC_FD_X7,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,11,122,72,8,WS_EX_RIGHT CONTROL "Static",IDC_SOURCECOUNT,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_GROUP,89,122,231,8 - CONTROL "Datarate:",IDC_FD_X13,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,11,132,72,8,WS_EX_RIGHT + CONTROL "Data rate:",IDC_FD_X13,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,11,132,72,8,WS_EX_RIGHT CONTROL "Static",IDC_DATARATE,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_GROUP,89,132,231,8 CONTROL "Transferred:",IDC_FD_X14,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,11,142,72,8,WS_EX_RIGHT CONTROL "Static",IDC_TRANSFERRED,"Static",SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_GROUP,89,142,70,8 @@ -1029,7 +1028,7 @@ BEGIN GROUPBOX "General",IDC_FD_X0,4,2,333,108 GROUPBOX "Transfer",IDC_FD_X6,4,111,333,66 GROUPBOX "Dates",IDC_FD_X8,4,177,333,55 - CONTROL "Filetype:",IDC_FD_X10,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,11,73,72,8,WS_EX_RIGHT + CONTROL "File type:",IDC_FD_X10,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,11,73,72,8,WS_EX_RIGHT CONTROL "FileType-ID and warning",IDC_FD_X11,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,89,73,224,8 END @@ -1138,15 +1137,15 @@ BEGIN CONTROL "&Name:",IDC_MSTATIC3,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,0,0,63,8 EDITTEXT IDC_SEARCHNAME,0,8,183,12,ES_AUTOHSCROLL PUSHBUTTON "v",IDC_DD,183,8,11,12,BS_CENTER - CONTROL "T&ype",IDC_MSTATIC7,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,0,30,60,8 - CONTROL "",IDC_TYPESEARCH,"ComboBoxEx32",CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP,0,39,66,118 - CONTROL "Method:",IDC_METH,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,70,30,70,8 - CONTROL "",IDC_COMBO1,"ComboBoxEx32",CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP,68,39,80,78 - PUSHBUTTON "&Reset",IDC_SEARCH_RESET,150,38,45,15 + CONTROL "T&ype",IDC_MSTATIC7,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,0,25,60,8 + CONTROL "",IDC_TYPESEARCH,"ComboBoxEx32",CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP,0,34,66,118 + CONTROL "Method:",IDC_METH,"Static",SS_LEFTNOWORDWRAP | WS_GROUP,70,25,70,8 + CONTROL "",IDC_COMBO1,"ComboBoxEx32",CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP,68,34,80,78 + PUSHBUTTON "&Reset",IDC_SEARCH_RESET,150,33,45,15 CONTROL "",IDC_SEARCH_OPTS,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,258,0,220,55,WS_EX_LEFTSCROLLBAR - DEFPUSHBUTTON "&Start",IDC_STARTS,198,0,58,14 - PUSHBUTTON "More",IDC_MORE,198,19,58,14,WS_DISABLED - PUSHBUTTON "Cance&l",IDC_CANCELS,198,39,58,15,WS_DISABLED + DEFPUSHBUTTON "&Start",IDC_STARTS,198,0,58,15 + PUSHBUTTON "More",IDC_MORE,198,19,58,15,WS_DISABLED + PUSHBUTTON "Cance&l",IDC_CANCELS,198,38,58,15,WS_DISABLED END IDD_NETWORK_INFO DIALOGEX 0, 0, 291, 165 @@ -1603,9 +1602,9 @@ BEGIN IDC_SMTPAUTH, 0x403, 5, 0 0x6f4e, 0x656e, "\000" IDC_SMTPAUTH, 0x403, 6, 0 -0x4f4c, 0x4947, 0x004e, - IDC_SMTPAUTH, 0x403, 6, 0 0x4c50, 0x4941, 0x004e, + IDC_SMTPAUTH, 0x403, 6, 0 +0x4f4c, 0x4947, 0x004e, 0 END @@ -1867,6 +1866,7 @@ BEGIN IDS_LD_ADDHTML "Add HTML-Tags" IDS_AUTHMETHOD "Authentication method" IDS_ENABLEIMPORTPARTS "Enable Import parts" + IDS_ERR_REGEXP "Bad regular expression" END STRINGTABLE @@ -2285,7 +2285,7 @@ BEGIN IDS_GLOBALSEARCH "Global (Servers)" IDS_METHOD "Method" IDS_UNDO "Undo" - IDS_DAYLY "Daily" + IDS_DAILY "Daily" IDS_DAY_MO_FR "Mon-Fri" END @@ -3000,10 +3000,10 @@ BEGIN IDS_SHAREDREQ1 "User %s (%u) requested your list of shared directories -> %s" IDS_SHAREDREQ2 "User %s (%u) requested your list of shared files for directory '%s' -> %s" IDS_SHAREDANSW "User %s (%u) shares directory '%s'" - IDS_SHAREDANSW2 "User %s (%u) sent not requested list of shared directories - ignored" + IDS_SHAREDANSW2 "User %s (%u) sent unrequested list of shared directories - ignored" IDS_SHAREDINFO1 "User %s (%u) sent list of shared files for directory '%s'" IDS_SHAREDINFO2 "User %s (%u) finished sending lists of shared files" - IDS_SHAREDANSW3 "User %s (%u) sent not requested list of shared files for directory '%s' - ignored" + IDS_SHAREDANSW3 "User %s (%u) sent unrequested list of shared files for directory '%s' - ignored" IDS_SHAREDREQDENIED "User %s (%u) denied access to list of shared directories/files" IDS_AUTOCLEANUPFN "Auto cleanup file names of new downloads" IDS_ONNEWDOWNLOAD "Initializations" @@ -3183,7 +3183,7 @@ BEGIN IDS_USS_STARTING "UploadSpeedSense: Done with preparations. Starting control of upload speed. (First 60 seconds will be in fast reaction mode)" IDS_A4AF "Source Handling" IDS_IMPORTPARTS_STOP "Stop Import parts to file" - IDS_AUTOCAT_LABEL "Auto cat-assignment (pattern, separated by |)" + IDS_AUTOCAT_LABEL "Auto cat. assignment (separate patterns with |)" IDS_SHOWEXTSETTINGS "Show more controls (advanced mode controls)" IDS_TREEOPTIONS_TRUE "True" IDS_DELETEAFTERFILEOP "File '%s' will be deleted after the current operation was completed" @@ -3340,7 +3340,7 @@ BEGIN IDS_MINLENGTH "Min. Length [hh:mm:ss]" IDS_EM_HELP "&Help" IDS_WRN_FRIENDDUPLIPPORT "Friend not added.\r\n\r\nThere is already a friend with same IP address and port available." - IDS_DYNUP "Upload SpeedSense" + IDS_DYNUP "Upload SpeedSense (not recommended)" IDS_KADOVERHEAD "Kad Overhead (Packets): %s (%s)" IDS_FIND "Find..." IDS_LOG_BANNED_CLIENTS "Log banned clients" diff --git a/srchybrid/emule.sln b/srchybrid/emule.sln index fdb6d4de..e70267d3 100644 --- a/srchybrid/emule.sln +++ b/srchybrid/emule.sln @@ -22,7 +22,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "id3lib", "..\id3lib\libprj\ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libpng", "..\libpng\projects\visualc\libpng.vcxproj", "{E27AB0B5-84CC-47E8-8F43-34C4F3FDA71E}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mbedTLS", "..\mbedtls\visualc\VS2010\mbedTLS.vcxproj", "{46CF2D25-6A36-4189-B59C-E4815388E554}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mbedTLS", "..\mbedtls\visualc\VS2013\mbedTLS.vcxproj", "{46CF2D25-6A36-4189-B59C-E4815388E554}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniupnpc", "..\miniupnpc\msvc\miniupnpc.vcxproj", "{D28CE435-CB33-4BAE-8A52-C6EF915956F5}" EndProject diff --git a/srchybrid/emule.vcxproj b/srchybrid/emule.vcxproj index f39cdfc9..6a78f475 100644 --- a/srchybrid/emule.vcxproj +++ b/srchybrid/emule.vcxproj @@ -61,7 +61,7 @@ - .;..;..\id3lib\include;..\mbedtls\include;..\mbedtls\crypto\include;$(VC_ATLMFC_SourcePath);$(UniversalCRTSdkDir)Include\10.0.19041.0\um\;$(UniversalCRTSdkDir)Include\10.0.19041.0\shared + .;..;..\id3lib\include;..\mbedtls\include;..\mbedtls\crypto\include;$(VC_ATLMFC_SourcePath);$(UniversalCRTSdkDir)Include\10.0.22621.0\um\;$(UniversalCRTSdkDir)Include\10.0.22621.0\shared; /Zc:throwingNew EnableFastChecks true @@ -71,13 +71,10 @@ MultiThreadedDebug EnableAllWarnings - - $(IntDir);$(UniversalCRTSdkDir)Include\10.0.19041.0\um\;$(UniversalCRTSdkDir)Include\10.0.19041.0\shared\;$(VC_IncludePath);%(AdditionalIncludeDirectories) - - ADSIId.lib;crypt32.lib;iphlpapi.lib;version.lib;winmm.lib;ws2_32.lib;..\cryptopp\$(Platform)\$(Configuration)\cryptlib.lib;..\cximage\$(Platform)\$(Configuration)\cximage.lib;..\id3lib\libprj\$(Platform)\$(Configuration)\id3lib.lib;..\libpng\projects\visualc\$(Platform)\$(Configuration)\libpng.lib;..\mbedtls\visualc\vs2010\$(Platform)\$(Configuration)\mbedtls.lib;..\miniupnpc\msvc\$(Platform)\$(Configuration)\miniupnpc.lib;..\resizablelib\$(Platform)\$(Configuration)\resizablelib.lib;..\zlib\contrib\vstudio\vc\$(Platform)\$(Configuration)\zlib.lib;%(AdditionalDependencies) + ADSIId.lib;crypt32.lib;iphlpapi.lib;version.lib;winmm.lib;ws2_32.lib;..\cryptopp\$(Platform)\$(Configuration)\cryptlib.lib;..\cximage\$(Platform)\$(Configuration)\cximage.lib;..\id3lib\libprj\$(Platform)\$(Configuration)\id3lib.lib;..\libpng\projects\visualc\$(Platform)\$(Configuration)\libpng.lib;..\mbedtls\visualc\vs2013\$(Platform)\$(Configuration)\mbedtls.lib;..\miniupnpc\msvc\$(Platform)\$(Configuration)\miniupnpc.lib;..\resizablelib\$(Platform)\$(Configuration)\resizablelib.lib;..\zlib\contrib\vstudio\vc\$(Platform)\$(Configuration)\zlib.lib;%(AdditionalDependencies) /safeseh - gdiplus.dll;oleacc.dll;ws2_32.dll;%(DelayLoadDLLs) + gdiplus.dll;msimg32.dll;oleacc.dll;ws2_32.dll;%(DelayLoadDLLs) mpr.lib;rasapi32.lib;secur32.lib;sensapi.lib;vfw32.lib;%(IgnoreSpecificDefaultLibraries) true false @@ -90,7 +87,7 @@ - .;..;..\id3lib\include;..\mbedtls\include;..\mbedtls\crypto\include;$(VC_ATLMFC_SourcePath);$(UniversalCRTSdkDir)Include\10.0.19041.0\um\;$(UniversalCRTSdkDir)Include\10.0.19041.0\shared + .;..;..\id3lib\include;..\mbedtls\include;..\mbedtls\crypto\include;$(VC_ATLMFC_SourcePath);$(UniversalCRTSdkDir)Include\10.0.22621.0\um\;$(UniversalCRTSdkDir)Include\10.0.22621.0\shared; /Zc:throwingNew EnableFastChecks true @@ -100,15 +97,14 @@ MultiThreadedDebug EnableAllWarnings - - $(IntDir);$(UniversalCRTSdkDir)Include\10.0.19041.0\um\;$(UniversalCRTSdkDir)Include\10.0.19041.0\shared\;$(VC_IncludePath);%(AdditionalIncludeDirectories) - - ADSIId.lib;crypt32.lib;iphlpapi.lib;version.lib;winmm.lib;ws2_32.lib;..\cryptopp\$(Platform)\$(Configuration)\cryptlib.lib;..\cximage\$(Platform)\$(Configuration)\cximage.lib;..\id3lib\libprj\$(Platform)\$(Configuration)\id3lib.lib;..\libpng\projects\visualc\$(Platform)\$(Configuration)\libpng.lib;..\mbedtls\visualc\vs2010\$(Platform)\$(Configuration)\mbedtls.lib;..\miniupnpc\msvc\$(Platform)\$(Configuration)\miniupnpc.lib;..\resizablelib\$(Platform)\$(Configuration)\resizablelib.lib;..\zlib\contrib\vstudio\vc\$(Platform)\$(Configuration)\zlib.lib;%(AdditionalDependencies) - gdiplus.dll;oleacc.dll;ws2_32.dll;%(DelayLoadDLLs) + ADSIId.lib;crypt32.lib;iphlpapi.lib;version.lib;winmm.lib;ws2_32.lib;..\cryptopp\$(Platform)\$(Configuration)\cryptlib.lib;..\cximage\$(Platform)\$(Configuration)\cximage.lib;..\id3lib\libprj\$(Platform)\$(Configuration)\id3lib.lib;..\libpng\projects\visualc\$(Platform)\$(Configuration)\libpng.lib;..\mbedtls\visualc\vs2013\$(Platform)\$(Configuration)\mbedtls.lib;..\miniupnpc\msvc\$(Platform)\$(Configuration)\miniupnpc.lib;..\resizablelib\$(Platform)\$(Configuration)\resizablelib.lib;..\zlib\contrib\vstudio\vc\$(Platform)\$(Configuration)\zlib.lib;%(AdditionalDependencies) + gdiplus.dll;msimg32.dll;oleacc.dll;ws2_32.dll;%(DelayLoadDLLs) mpr.lib;rasapi32.lib;secur32.lib;sensapi.lib;vfw32.lib;%(IgnoreSpecificDefaultLibraries) false Windows + + res/$(TargetName)$(Platform).manifest %(AdditionalManifestFiles) @@ -117,22 +113,19 @@ - .;..;..\id3lib\include;..\mbedtls\include;..\mbedtls\crypto\include;$(VC_ATLMFC_SourcePath);$(UniversalCRTSdkDir)Include\10.0.19041.0\um\;$(UniversalCRTSdkDir)Include\10.0.19041.0\shared + .;..;..\id3lib\include;..\mbedtls\include;..\mbedtls\crypto\include;$(VC_ATLMFC_SourcePath);$(UniversalCRTSdkDir)Include\10.0.22621.0\um\;$(UniversalCRTSdkDir)Include\10.0.22621.0\shared; /Zc:throwingNew true true true Use - ID3LIB_LINKOPTION=1;MINIUPNP_STATICLIB;SUPPORT_LARGE_FILES;XP_BUILD;NDEBUG;%(PreprocessorDefinitions) + ID3LIB_LINKOPTION=1;MINIUPNP_STATICLIB;SUPPORT_LARGE_FILES;NDEBUG;XP_BUILD;%(PreprocessorDefinitions) EnableAllWarnings - - $(IntDir);$(UniversalCRTSdkDir)Include\10.0.19041.0\um\;$(UniversalCRTSdkDir)Include\10.0.19041.0\shared\;$(VC_IncludePath);%(AdditionalIncludeDirectories) - - ADSIId.lib;crypt32.lib;iphlpapi.lib;version.lib;winmm.lib;ws2_32.lib;..\cryptopp\$(Platform)\$(Configuration)\cryptlib.lib;..\cximage\$(Platform)\$(Configuration)\cximage.lib;..\id3lib\libprj\$(Platform)\$(Configuration)\id3lib.lib;..\libpng\projects\visualc\$(Platform)\$(Configuration)\libpng.lib;..\mbedtls\visualc\vs2010\$(Platform)\$(Configuration)\mbedtls.lib;..\miniupnpc\msvc\$(Platform)\$(Configuration)\miniupnpc.lib;..\resizablelib\$(Platform)\$(Configuration)\resizablelib.lib;..\zlib\contrib\vstudio\vc\$(Platform)\$(Configuration)\zlib.lib;%(AdditionalDependencies) + ADSIId.lib;crypt32.lib;iphlpapi.lib;version.lib;winmm.lib;ws2_32.lib;..\cryptopp\$(Platform)\$(Configuration)\cryptlib.lib;..\cximage\$(Platform)\$(Configuration)\cximage.lib;..\id3lib\libprj\$(Platform)\$(Configuration)\id3lib.lib;..\libpng\projects\visualc\$(Platform)\$(Configuration)\libpng.lib;..\mbedtls\visualc\vs2013\$(Platform)\$(Configuration)\mbedtls.lib;..\miniupnpc\msvc\$(Platform)\$(Configuration)\miniupnpc.lib;..\resizablelib\$(Platform)\$(Configuration)\resizablelib.lib;..\zlib\contrib\vstudio\vc\$(Platform)\$(Configuration)\zlib.lib;%(AdditionalDependencies) /safeseh - gdiplus.dll;oleacc.dll;ws2_32.dll;%(DelayLoadDLLs) + gdiplus.dll;msimg32.dll;oleacc.dll;ws2_32.dll;%(DelayLoadDLLs) true mpr.lib;rasapi32.lib;secur32.lib;sensapi.lib;vfw32.lib;%(IgnoreSpecificDefaultLibraries) true @@ -146,21 +139,18 @@ - .;..;..\id3lib\include;..\mbedtls\include;..\mbedtls\crypto\include;$(VC_ATLMFC_SourcePath);$(UniversalCRTSdkDir)Include\10.0.19041.0\um\;$(UniversalCRTSdkDir)Include\10.0.19041.0\shared + .;..;..\id3lib\include;..\mbedtls\include;..\mbedtls\crypto\include;$(VC_ATLMFC_SourcePath);$(UniversalCRTSdkDir)Include\10.0.22621.0\um\;$(UniversalCRTSdkDir)Include\10.0.22621.0\shared; /Zc:throwingNew true true true Use - ID3LIB_LINKOPTION=1;MINIUPNP_STATICLIB;SUPPORT_LARGE_FILES;XP_BUILD;NDEBUG;%(PreprocessorDefinitions) + ID3LIB_LINKOPTION=1;MINIUPNP_STATICLIB;SUPPORT_LARGE_FILES;NDEBUG;XP_BUILD;%(PreprocessorDefinitions) EnableAllWarnings - - $(IntDir);$(UniversalCRTSdkDir)Include\10.0.19041.0\um\;$(UniversalCRTSdkDir)Include\10.0.19041.0\shared\;$(VC_IncludePath);%(AdditionalIncludeDirectories) - - ADSIId.lib;crypt32.lib;iphlpapi.lib;version.lib;winmm.lib;ws2_32.lib;..\cryptopp\$(Platform)\$(Configuration)\cryptlib.lib;..\cximage\$(Platform)\$(Configuration)\cximage.lib;..\id3lib\libprj\$(Platform)\$(Configuration)\id3lib.lib;..\libpng\projects\visualc\$(Platform)\$(Configuration)\libpng.lib;..\mbedtls\visualc\vs2010\$(Platform)\$(Configuration)\mbedtls.lib;..\miniupnpc\msvc\$(Platform)\$(Configuration)\miniupnpc.lib;..\resizablelib\$(Platform)\$(Configuration)\resizablelib.lib;..\zlib\contrib\vstudio\vc\$(Platform)\$(Configuration)\zlib.lib;%(AdditionalDependencies) - gdiplus.dll;oleacc.dll;ws2_32.dll;%(DelayLoadDLLs) + ADSIId.lib;crypt32.lib;iphlpapi.lib;version.lib;winmm.lib;ws2_32.lib;..\cryptopp\$(Platform)\$(Configuration)\cryptlib.lib;..\cximage\$(Platform)\$(Configuration)\cximage.lib;..\id3lib\libprj\$(Platform)\$(Configuration)\id3lib.lib;..\libpng\projects\visualc\$(Platform)\$(Configuration)\libpng.lib;..\mbedtls\visualc\vs2013\$(Platform)\$(Configuration)\mbedtls.lib;..\miniupnpc\msvc\$(Platform)\$(Configuration)\miniupnpc.lib;..\resizablelib\$(Platform)\$(Configuration)\resizablelib.lib;..\zlib\contrib\vstudio\vc\$(Platform)\$(Configuration)\zlib.lib;%(AdditionalDependencies) + gdiplus.dll;msimg32.dll;oleacc.dll;ws2_32.dll;%(DelayLoadDLLs) mpr.lib;rasapi32.lib;secur32.lib;sensapi.lib;vfw32.lib;%(IgnoreSpecificDefaultLibraries) true true @@ -173,7 +163,7 @@ - .;..;..\id3lib\include;..\mbedtls\include;..\mbedtls\crypto\include;$(VC_ATLMFC_SourcePath);$(UniversalCRTSdkDir)Include\10.0.19041.0\um\;$(UniversalCRTSdkDir)Include\10.0.19041.0\shared + .;..;..\id3lib\include;..\mbedtls\include;..\mbedtls\crypto\include;$(VC_ATLMFC_SourcePath);$(UniversalCRTSdkDir)Include\10.0.22621.0\um\;$(UniversalCRTSdkDir)Include\10.0.22621.0\shared; /Zc:throwingNew EnableFastChecks true @@ -183,13 +173,10 @@ MultiThreadedDebug EnableAllWarnings - - $(IntDir);$(UniversalCRTSdkDir)Include\10.0.19041.0\um\;$(UniversalCRTSdkDir)Include\10.0.19041.0\shared\;$(VC_IncludePath);%(AdditionalIncludeDirectories) - - ADSIId.lib;crypt32.lib;iphlpapi.lib;version.lib;winmm.lib;ws2_32.lib;..\cryptopp\$(Platform)\Debug\cryptlib.lib;..\cximage\$(Platform)\Debug\cximage.lib;..\id3lib\libprj\$(Platform)\Debug\id3lib.lib;..\libpng\projects\visualc\$(Platform)\Debug\libpng.lib;..\mbedtls\visualc\vs2010\$(Platform)\Debug\mbedtls.lib;..\miniupnpc\msvc\$(Platform)\Debug\miniupnpc.lib;..\resizablelib\$(Platform)\Debug\resizablelib.lib;..\zlib\contrib\vstudio\vc\$(Platform)\Debug\zlib.lib;%(AdditionalDependencies) + ADSIId.lib;crypt32.lib;iphlpapi.lib;version.lib;winmm.lib;ws2_32.lib;..\cryptopp\$(Platform)\Debug\cryptlib.lib;..\cximage\$(Platform)\Debug\cximage.lib;..\id3lib\libprj\$(Platform)\Debug\id3lib.lib;..\libpng\projects\visualc\$(Platform)\Debug\libpng.lib;..\mbedtls\visualc\vs2013\$(Platform)\Debug\mbedtls.lib;..\miniupnpc\msvc\$(Platform)\Debug\miniupnpc.lib;..\resizablelib\$(Platform)\Debug\resizablelib.lib;..\zlib\contrib\vstudio\vc\$(Platform)\Debug\zlib.lib;%(AdditionalDependencies) /safeseh - gdiplus.dll;oleacc.dll;ws2_32.dll;%(DelayLoadDLLs) + gdiplus.dll;msimg32.dll;oleacc.dll;ws2_32.dll;%(DelayLoadDLLs) mpr.lib;rasapi32.lib;secur32.lib;sensapi.lib;vfw32.lib;%(IgnoreSpecificDefaultLibraries) true false @@ -202,7 +189,7 @@ - .;..;..\id3lib\include;..\mbedtls\include;..\mbedtls\crypto\include;$(VC_ATLMFC_SourcePath);$(UniversalCRTSdkDir)Include\10.0.19041.0\um\;$(UniversalCRTSdkDir)Include\10.0.19041.0\shared + .;..;..\id3lib\include;..\mbedtls\include;..\mbedtls\crypto\include;$(VC_ATLMFC_SourcePath);$(UniversalCRTSdkDir)Include\10.0.22621.0\um\;$(UniversalCRTSdkDir)Include\10.0.22621.0\shared; /Zc:throwingNew EnableFastChecks true @@ -212,12 +199,9 @@ MultiThreadedDebug EnableAllWarnings - - $(IntDir);$(UniversalCRTSdkDir)Include\10.0.19041.0\um\;$(UniversalCRTSdkDir)Include\10.0.19041.0\shared\;$(VC_IncludePath);%(AdditionalIncludeDirectories) - - ADSIId.lib;crypt32.lib;iphlpapi.lib;version.lib;winmm.lib;ws2_32.lib;..\cryptopp\$(Platform)\Debug\cryptlib.lib;..\cximage\$(Platform)\Debug\cximage.lib;..\id3lib\libprj\$(Platform)\Debug\id3lib.lib;..\libpng\projects\visualc\$(Platform)\Debug\libpng.lib;..\mbedtls\visualc\vs2010\$(Platform)\Debug\mbedtls.lib;..\miniupnpc\msvc\$(Platform)\Debug\miniupnpc.lib;..\resizablelib\$(Platform)\Debug\resizablelib.lib;..\zlib\contrib\vstudio\vc\$(Platform)\Debug\zlib.lib;%(AdditionalDependencies) - gdiplus.dll;oleacc.dll;ws2_32.dll;%(DelayLoadDLLs) + ADSIId.lib;crypt32.lib;iphlpapi.lib;version.lib;winmm.lib;ws2_32.lib;..\cryptopp\$(Platform)\Debug\cryptlib.lib;..\cximage\$(Platform)\Debug\cximage.lib;..\id3lib\libprj\$(Platform)\Debug\id3lib.lib;..\libpng\projects\visualc\$(Platform)\Debug\libpng.lib;..\mbedtls\visualc\vs2013\$(Platform)\Debug\mbedtls.lib;..\miniupnpc\msvc\$(Platform)\Debug\miniupnpc.lib;..\resizablelib\$(Platform)\Debug\resizablelib.lib;..\zlib\contrib\vstudio\vc\$(Platform)\Debug\zlib.lib;%(AdditionalDependencies) + gdiplus.dll;msimg32.dll;oleacc.dll;ws2_32.dll;%(DelayLoadDLLs) mpr.lib;rasapi32.lib;secur32.lib;sensapi.lib;vfw32.lib;%(IgnoreSpecificDefaultLibraries) false Windows @@ -375,6 +359,7 @@ + @@ -670,6 +655,7 @@ + diff --git a/srchybrid/emule_site_config.h b/srchybrid/emule_site_config.h index 7277dae5..a4227dca 100644 --- a/srchybrid/emule_site_config.h +++ b/srchybrid/emule_site_config.h @@ -12,7 +12,14 @@ #ifdef XP_BUILD #define _WIN32_WINNT _WIN32_WINNT_WINXP #define NTDDI_VERSION NTDDI_WINXP +#define XP_NOEXCEPT noexcept +#else //XP_BUILD +#if _MSC_VER<1937 //before VS2022 17.7 +#define XP_NOEXCEPT noexcept +#else +#define XP_NOEXCEPT #endif +#endif //XP_BUILD ////////////////////////////////////////////////////////////////////////////// // Visual Studio 2003 @@ -121,9 +128,10 @@ #endif ////////////////////////////////////////////////////////////////////////////// -// Visual Studio 2012, 2013, 2015, 2017, 2019 +// Visual Studio 2012, 2013, 2015, 2017, 2019, 2022 ////////////////////////////////////////////////////////////////////////////// -// VS2012==1700, VS2013==1800, VS2015==1900, VS2017==1910-1916, VS2019==???? +// VS2012==1700, VS2013==1800, +// VS2015==1900, VS2017==1910-1916, VS2019==1920-1929, VS2022==1930-???? #if _MSC_VER>=1700 #define HAVE_VISTA_SDK // shipped with Windows SDK @@ -135,7 +143,8 @@ #undef HAVE_SAPI_H #endif//HAVE_VISTA_SDK -// 'qedit.h' file is not shipped after VS200 +// 'qedit.h' file was shipped in VS2003 +// In VS2005 or VS2008 it was a part of Vista SDK and required an additional file 'ddraw.h' #if !defined(HAVE_VISTA_SDK) || !defined(HAVE_DIRECTX_SDK) #undef HAVE_QEDIT_H #endif//!defined(HAVE_VISTA_SDK) || !defined(HAVE_DIRECTX_SDK) diff --git a/srchybrid/kademlia/io/BufferedFileIO.cpp b/srchybrid/kademlia/io/BufferedFileIO.cpp index d509f18d..65f24f53 100644 --- a/srchybrid/kademlia/io/BufferedFileIO.cpp +++ b/srchybrid/kademlia/io/BufferedFileIO.cpp @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ diff --git a/srchybrid/kademlia/io/BufferedFileIO.h b/srchybrid/kademlia/io/BufferedFileIO.h index ff8fd730..f9583200 100644 --- a/srchybrid/kademlia/io/BufferedFileIO.h +++ b/srchybrid/kademlia/io/BufferedFileIO.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ diff --git a/srchybrid/kademlia/io/ByteIO.cpp b/srchybrid/kademlia/io/ByteIO.cpp index a8eb8182..3e0903da 100644 --- a/srchybrid/kademlia/io/ByteIO.cpp +++ b/srchybrid/kademlia/io/ByteIO.cpp @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ diff --git a/srchybrid/kademlia/io/ByteIO.h b/srchybrid/kademlia/io/ByteIO.h index da9fdf97..1be73b9f 100644 --- a/srchybrid/kademlia/io/ByteIO.h +++ b/srchybrid/kademlia/io/ByteIO.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ diff --git a/srchybrid/kademlia/io/DataIO.cpp b/srchybrid/kademlia/io/DataIO.cpp index 349a2c34..562769b2 100644 --- a/srchybrid/kademlia/io/DataIO.cpp +++ b/srchybrid/kademlia/io/DataIO.cpp @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -81,9 +81,9 @@ uint64 CDataIO::ReadUInt64() return uRetVal; } -void CDataIO::ReadUInt128(CUInt128 *puValue) +void CDataIO::ReadUInt128(const CUInt128 &uValue) { - ReadArray(puValue->GetDataPtr(), sizeof(uint32) * 4); + ReadArray(uValue.GetDataPtr(), sizeof(uint32) * 4); } float CDataIO::ReadFloat() @@ -145,7 +145,7 @@ CKadTag* CDataIO::ReadTag(bool bOptACP) CKadTag *pRetVal = NULL; char *pcName = NULL; byte byType = 0; - uint16 uLenName = 0; + uint32 uLenName = 0; try { byType = ReadByte(); uLenName = ReadUInt16(); @@ -229,12 +229,10 @@ CKadTag* CDataIO::ReadTag(bool bOptACP) return pRetVal; } -void CDataIO::ReadTagList(TagList *pTaglist, bool bOptACP) +void CDataIO::ReadTagList(TagList &rTaglist, bool bOptACP) { - for (uint32 uCount = ReadByte(); uCount > 0; --uCount) { - CKadTag *pTag = ReadTag(bOptACP); - pTaglist->push_back(pTag); - } + for (uint32 uCount = ReadByte(); uCount > 0; --uCount) + rTaglist.push_back(ReadTag(bOptACP)); } void CDataIO::WriteByte(byte byVal) @@ -283,58 +281,58 @@ void CDataIO::WriteBsob(const BYTE *pbyValue, uint8 uSize) WriteArray(pbyValue, uSize); } -void CDataIO::WriteTag(const CKadTag *pTag) +void CDataIO::WriteTag(const CKadTag &Tag) { try { uint8 uType; - if (pTag->m_type == TAGTYPE_UINT) { - if (pTag->GetInt() <= 0xFFu) + if (Tag.m_type == TAGTYPE_UINT) { + if (Tag.GetInt() <= _UI8_MAX) uType = TAGTYPE_UINT8; - else if (pTag->GetInt() <= 0xFFFFu) + else if (Tag.GetInt() <= _UI16_MAX) uType = TAGTYPE_UINT16; - else if (pTag->GetInt() <= 0xFFFFFFFFu) + else if (Tag.GetInt() <= _UI32_MAX) uType = TAGTYPE_UINT32; else uType = TAGTYPE_UINT64; } else - uType = pTag->m_type; + uType = Tag.m_type; WriteByte(uType); - const CKadTagNameString &name = pTag->m_name; + const CKadTagNameString &name = Tag.m_name; WriteUInt16((uint16)name.GetLength()); WriteArray((LPCSTR)name, name.GetLength()); switch (uType) { case TAGTYPE_HASH: // Do NOT use this to transfer any tags for at least half a year!! - WriteHash(pTag->GetHash()); + WriteHash(Tag.GetHash()); ASSERT(0); break; case TAGTYPE_STRING: { - CUnicodeToUTF8 utf8(pTag->GetStr()); + CUnicodeToUTF8 utf8(Tag.GetStr()); WriteUInt16((uint16)utf8.GetLength()); WriteArray(utf8, utf8.GetLength()); } break; case TAGTYPE_UINT64: - WriteUInt64(pTag->GetInt()); + WriteUInt64(Tag.GetInt()); break; case TAGTYPE_UINT32: - WriteUInt32((uint32)pTag->GetInt()); + WriteUInt32((uint32)Tag.GetInt()); break; case TAGTYPE_UINT16: - WriteUInt16((uint16)pTag->GetInt()); + WriteUInt16((uint16)Tag.GetInt()); break; case TAGTYPE_UINT8: - WriteUInt8((uint8)pTag->GetInt()); + WriteUInt8((uint8)Tag.GetInt()); break; case TAGTYPE_FLOAT32: - WriteFloat(pTag->GetFloat()); + WriteFloat(Tag.GetFloat()); break; case TAGTYPE_BSOB: - WriteBsob(pTag->GetBsob(), pTag->GetBsobSize()); + WriteBsob(Tag.GetBsob(), Tag.GetBsobSize()); } } catch (CIOException *ioe) { AddDebugLogLine(false, _T("Exception in CDataIO:writeTag (IO Error(%i))"), ioe->m_iCause); @@ -347,27 +345,27 @@ void CDataIO::WriteTag(const CKadTag *pTag) void CDataIO::WriteTag(LPCSTR szName, uint64 uValue) { - WriteTag(&CKadTagUInt64(szName, uValue)); + WriteTag(CKadTagUInt64(szName, uValue)); } void CDataIO::WriteTag(LPCSTR szName, uint32 uValue) { - WriteTag(&CKadTagUInt32(szName, uValue)); + WriteTag(CKadTagUInt32(szName, uValue)); } void CDataIO::WriteTag(LPCSTR szName, uint16 uValue) { - WriteTag(&CKadTagUInt16(szName, uValue)); + WriteTag(CKadTagUInt16(szName, uValue)); } void CDataIO::WriteTag(LPCSTR szName, uint8 uValue) { - WriteTag(&CKadTagUInt8(szName, uValue)); + WriteTag(CKadTagUInt8(szName, uValue)); } void CDataIO::WriteTag(LPCSTR szName, float fValue) { - WriteTag(&CKadTagFloat(szName, fValue)); + WriteTag(CKadTagFloat(szName, fValue)); } void CDataIO::WriteTagList(const TagList &tagList) @@ -375,7 +373,7 @@ void CDataIO::WriteTagList(const TagList &tagList) ASSERT(tagList.size() <= 0xFF); WriteByte((uint8)tagList.size()); for (TagList::const_iterator itTagList = tagList.begin(); itTagList != tagList.end(); ++itTagList) - WriteTag(*itTagList); + WriteTag(**itTagList); } void CDataIO::WriteString(const CStringW &strVal) @@ -385,17 +383,6 @@ void CDataIO::WriteString(const CStringW &strVal) WriteArray(utf8, utf8.GetLength()); } -namespace Kademlia -{ - void deleteTagListEntries(TagList *pTaglist) - { - while (!pTaglist->empty()) { - delete pTaglist->front(); - pTaglist->pop_front(); - } - } -} - static WCHAR s_awcLowerMap[0x10000]; bool CKademlia::InitUnicode(HMODULE hInst) @@ -434,7 +421,7 @@ bool CKademlia::InitUnicode(HMODULE hInst) void gen_wclwrtab() { FILE *fpt = fopen("wclwrtab_gen.txt", "wb"); - fputwc(0xFEFFui16, fpt); + fputwc(u'\xFEFF', fpt); int iDiffs = 0; FILE *fp = fopen("wclwrtab.bin", "wb"); @@ -468,7 +455,7 @@ void use_wclwrtab(const char *fname) fp = NULL; FILE *fpt = fopen("wclwrtab_use.txt", "wb"); - fputwc(0xFEFFui16, fpt); + fputwc(u'\xFEFF', fpt); int iDiffs = 0; for (UINT ch = 0; ch < 0x10000; ++ch) { WCHAR wch = ch; @@ -483,52 +470,64 @@ void use_wclwrtab(const char *fname) printf("Diffs=%u\n", iDiffs); }*/ -void KadTagStrMakeLower(CKadTagValueString &rwstr) +namespace Kademlia { - // NOTE: We can *not* use any locale dependent string functions here. All clients in the network - // have to use the same character mapping whereby it actually does not matter if they 'understand' - // the strings or not -- they just have to use the same mapping. That's why we hardcode - // to 'LANG_ENGLISH' here! Note also, using 'LANG_ENGLISH' is not the same as using the "C" locale. - // The "C" locale would only handle ASCII-7 characters while the 'LANG_ENGLISH' locale also handles - // chars from 0x80-0xFF and more. - //rwstr.MakeLower(); + void deleteTagListEntries(TagList &rTaglist) + { + while (!rTaglist.empty()) { + delete rTaglist.back(); + rTaglist.pop_back(); + } + } + + void KadTagStrMakeLower(CKadTagValueString &rwstr) + { + // NOTE: We can *not* use any locale dependent string functions here. All clients + // in the network have to use the same character mapping whereby it actually does + // not matter if they 'understand' the strings or not -- they just have to use + // the same mapping. That's why we hardcode to 'LANG_ENGLISH' here! Note also, using + // 'LANG_ENGLISH' is not the same as using the "C" locale. The "C" locale would only + // handle ASCII-7 characters while the 'LANG_ENGLISH' locale also handles chars + // from 0x80-0xFF and more. + //rwstr.MakeLower(); #if 0 - //PROBLEM: LCMapStringW does not work on Win9x (the string is not changed and LCMapStringW returns 0!) - // Possible solution: use a pre-computed static character map. - int iLen = rwstr.GetLength(); - LPWSTR pwsz = rwstr.GetBuffer(iLen); - int iSize = LCMapStringW(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), - LCMAP_LOWERCASE, pwsz, -1, pwsz, iLen + 1); - ASSERT(iSize - 1 == iLen); - rwstr.ReleaseBuffer(iLen); + //PROBLEM: LCMapStringW does not work on Win9x (the string is not changed and LCMapStringW returns 0!) + // Possible solution: use a pre-computed static character map. + int iLen = rwstr.GetLength(); + LPWSTR pwsz = rwstr.GetBuffer(iLen); + int iSize = LCMapStringW(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), + LCMAP_LOWERCASE, pwsz, -1, pwsz, iLen + 1); + ASSERT(iSize - 1 == iLen); + rwstr.ReleaseBuffer(iLen); #else - // NOTE: It's very important that the Unicode->LowerCase map already was initialized! - if (s_awcLowerMap[L'A'] != L'a') { - AfxMessageBox(_T("Kad Unicode lower case character map not initialized!")); - exit(1); - } + // NOTE: It's very important that the Unicode->LowerCase map already was initialized! + if (s_awcLowerMap[L'A'] != L'a') { + AfxMessageBox(_T("Kad Unicode lower case character map not initialized!")); + exit(1); + } - int iLen = rwstr.GetLength(); - LPWSTR pwsz = rwstr.GetBuffer(iLen); - while ((*pwsz = s_awcLowerMap[*pwsz]) != L'\0') - ++pwsz; - rwstr.ReleaseBuffer(iLen); + int iLen = rwstr.GetLength(); + LPWSTR pwsz = rwstr.GetBuffer(iLen); + while ((*pwsz = s_awcLowerMap[*pwsz]) != L'\0') + ++pwsz; + rwstr.ReleaseBuffer(iLen); #endif -} - -int KadTagStrCompareNoCase(LPCWSTR dst, LPCWSTR src) noexcept -{ - // NOTE: It's very important that the Unicode->LowerCase map already was initialized! - if (s_awcLowerMap[L'A'] != L'a') { - AfxMessageBox(_T("Kad Unicode lower case character map not initialized!")); - exit(1); } - WCHAR d, s; - do { - d = s_awcLowerMap[*dst++]; - s = s_awcLowerMap[*src++]; - } while (d != L'\0' && (d == s)); - return (int)(d - s); + bool EqualKadTagStr(LPCWSTR dst, LPCWSTR src) noexcept + { + // NOTE: It's very important that the Unicode->LowerCase map already was initialized! + if (s_awcLowerMap[L'A'] != L'a') { + AfxMessageBox(_T("Kad Unicode lower case character map not initialized!")); + exit(1); + } + + WCHAR d, s; + do { + d = s_awcLowerMap[*dst++]; + s = s_awcLowerMap[*src++]; + } while (d != L'\0' && d == s); + return (d == s); + } } \ No newline at end of file diff --git a/srchybrid/kademlia/io/DataIO.h b/srchybrid/kademlia/io/DataIO.h index e74e076e..faeb587a 100644 --- a/srchybrid/kademlia/io/DataIO.h +++ b/srchybrid/kademlia/io/DataIO.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -41,14 +41,13 @@ namespace Kademlia uint16 ReadUInt16(); uint32 ReadUInt32(); uint64 ReadUInt64(); - void ReadUInt128(CUInt128 *puValue); + void ReadUInt128(const CUInt128 &uValue); void ReadHash(BYTE *pbyValue); BYTE* ReadBsob(uint8 *puSize); float ReadFloat(); CStringW ReadStringUTF8(bool bOptACP = false); - void WriteString(const CStringW &strVal); CKadTag* ReadTag(bool bOptACP = false); - void ReadTagList(TagList *pTaglist, bool bOptACP = false); + void ReadTagList(TagList &rTaglist, bool bOptACP = false); void WriteByte(byte byVal); void WriteUInt8(uint8 uVal); void WriteUInt16(uint16 uVal); @@ -58,15 +57,18 @@ namespace Kademlia void WriteHash(const BYTE *pbyValue); void WriteBsob(const BYTE *pbyValue, uint8 uSize); void WriteFloat(float fVal); - void WriteTag(const CKadTag *pTag); + void WriteTag(const CKadTag &Tag); void WriteTag(LPCSTR szName, uint8 uValue); void WriteTag(LPCSTR szName, uint16 uValue); void WriteTag(LPCSTR szName, uint32 uValue); void WriteTag(LPCSTR szName, uint64 uValue); void WriteTag(LPCSTR szName, float fValue); void WriteTagList(const TagList &tagList); + void WriteString(const CStringW &strVal); virtual void ReadArray(LPVOID lpResult, uint32 uByteCount) = 0; virtual void WriteArray(LPCVOID lpVal, uint32 uByteCount) = 0; virtual UINT GetAvailable() const = 0; + protected: + virtual ~CDataIO() = default; }; } \ No newline at end of file diff --git a/srchybrid/kademlia/io/FileIO.cpp b/srchybrid/kademlia/io/FileIO.cpp index df2d314b..38d16fed 100644 --- a/srchybrid/kademlia/io/FileIO.cpp +++ b/srchybrid/kademlia/io/FileIO.cpp @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ diff --git a/srchybrid/kademlia/io/FileIO.h b/srchybrid/kademlia/io/FileIO.h index 5b5ef148..a7f13353 100644 --- a/srchybrid/kademlia/io/FileIO.h +++ b/srchybrid/kademlia/io/FileIO.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ diff --git a/srchybrid/kademlia/io/IOException.cpp b/srchybrid/kademlia/io/IOException.cpp index 158cd80f..0da09f1d 100644 --- a/srchybrid/kademlia/io/IOException.cpp +++ b/srchybrid/kademlia/io/IOException.cpp @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -55,5 +55,5 @@ BOOL CIOException::GetErrorMessage(LPTSTR lpszError, UINT uMaxError, PUINT pnHel if (pnHelpContext != NULL) *pnHelpContext = 0; - return true; + return TRUE; } diff --git a/srchybrid/kademlia/io/IOException.h b/srchybrid/kademlia/io/IOException.h index 65ce7af1..fb76b5c3 100644 --- a/srchybrid/kademlia/io/IOException.h +++ b/srchybrid/kademlia/io/IOException.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ diff --git a/srchybrid/kademlia/kademlia/Defines.h b/srchybrid/kademlia/kademlia/Defines.h index e007f0e9..ae200845 100644 --- a/srchybrid/kademlia/kademlia/Defines.h +++ b/srchybrid/kademlia/kademlia/Defines.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -29,7 +29,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ diff --git a/srchybrid/kademlia/kademlia/Entry.cpp b/srchybrid/kademlia/kademlia/Entry.cpp index 3a7a4302..7474b209 100644 --- a/srchybrid/kademlia/kademlia/Entry.cpp +++ b/srchybrid/kademlia/kademlia/Entry.cpp @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -58,17 +58,13 @@ CEntry::CEntry() CEntry::~CEntry() { - while (!m_listTag.empty()) { - delete *m_listTag.begin(); - m_listTag.pop_front(); - } + deleteTagListEntries(m_listTag); } CEntry* CEntry::Copy() { CEntry *pEntry = new CEntry(); - for (POSITION pos = m_listFileNames.GetHeadPosition(); pos != NULL;) - pEntry->m_listFileNames.AddTail(m_listFileNames.GetNext(pos)); + pEntry->m_listFileNames.AddTail(&m_listFileNames); pEntry->m_uIP = m_uIP; pEntry->m_uKeyID.SetValue(m_uKeyID); @@ -94,7 +90,7 @@ bool CEntry::GetIntTagValue(const CKadTagNameString &strTagName, uint64 &rValue, { for (TagList::const_iterator itTagList = m_listTag.begin(); itTagList != m_listTag.end(); ++itTagList) { const CKadTag *pTag = *itTagList; - if (pTag->IsInt() && !pTag->m_name.Compare(strTagName)) { + if (pTag->IsInt() && pTag->m_name.Compare(strTagName) == 0) { rValue = pTag->GetInt(); return true; } @@ -102,7 +98,7 @@ bool CEntry::GetIntTagValue(const CKadTagNameString &strTagName, uint64 &rValue, if (bIncludeVirtualTags) // SizeTag is not stored any more, but queried in some places - if (!strTagName.Compare(TAG_FILESIZE)) { + if (strTagName.Compare(TAG_FILESIZE) == 0) { rValue = m_uSize; return true; } @@ -115,7 +111,7 @@ CKadTagValueString CEntry::GetStrTagValue(const CKadTagNameString &strTagName) c { for (TagList::const_iterator itTagList = m_listTag.begin(); itTagList != m_listTag.end(); ++itTagList) { const CKadTag *pTag = *itTagList; - if (!pTag->m_name.Compare(strTagName) && pTag->IsStr()) + if (pTag->IsStr() && pTag->m_name.Compare(strTagName) == 0) return pTag->GetStr(); } return CKadTagValueString(); @@ -127,7 +123,7 @@ void CEntry::SetFileName(const CKadTagValueString &strName) ASSERT(0); m_listFileNames.RemoveAll(); } - m_listFileNames.AddHead(structFileNameEntry{strName, 1}); + m_listFileNames.AddHead(structFileNameEntry{ strName, 1 }); } CKadTagValueString CEntry::GetCommonFileName() const @@ -178,25 +174,24 @@ void CEntry::WriteTagListInc(CDataIO *pData, uint32 nIncreaseTagNumber) const CKadTagValueString &strCommonFileName(GetCommonFileName()); if (!strCommonFileName.IsEmpty()) { ASSERT(uCount > m_listTag.size()); - pData->WriteTag(&CKadTagStr(TAG_FILENAME, strCommonFileName)); + pData->WriteTag(CKadTagStr(TAG_FILENAME, strCommonFileName)); } if (m_uSize != 0) { ASSERT(uCount > m_listTag.size()); - CKadTagUInt tag(TAG_FILESIZE, m_uSize); - pData->WriteTag(&tag); + pData->WriteTag(CKadTagUInt(TAG_FILESIZE, m_uSize)); } for (TagList::const_iterator itTagList = m_listTag.begin(); itTagList != m_listTag.end(); ++itTagList) - pData->WriteTag(*itTagList); + pData->WriteTag(**itTagList); } void CEntry::AddTag(CKadTag *pTag, uint32 uDbgSourceIP) { // Filter tags which are for sending query results only and should never be stored (or even worse sent within the taglist) - if (!pTag->m_name.Compare(TAG_KADAICHHASHRESULT)) { + if (pTag->m_name.Compare(TAG_KADAICHHASHRESULT) == 0) { DebugLogWarning(_T("Received result tag TAG_KADAICHHASHRESULT on publishing, filtered, source %s"), (LPCTSTR)ipstr(htonl(uDbgSourceIP))); delete pTag; - } else if (!pTag->m_name.Compare(TAG_PUBLISHINFO)) { + } else if (pTag->m_name.Compare(TAG_PUBLISHINFO) == 0) { DebugLogWarning(_T("Received result tag TAG_PUBLISHINFO on publishing, filtered, source %s"), (LPCTSTR)ipstr(htonl(uDbgSourceIP))); delete pTag; } else @@ -265,16 +260,15 @@ bool CKeyEntry::SearchTermsMatch(const SSearchTerm &rSearchTerm) const // of the filename and thus does not need to get published nor stored explicitly, int iExt = m_strSearchTermCacheCommonFileNameLowerCase.ReverseFind(_T('.')); if (iExt >= 0) { - if (KadTagStrCompareNoCase((LPCWSTR)m_strSearchTermCacheCommonFileNameLowerCase + iExt + 1, rSearchTerm.m_pTag->GetStr()) == 0) + if (EqualKadTagStr(CPTRW(m_strSearchTermCacheCommonFileNameLowerCase, iExt + 1), rSearchTerm.m_pTag->GetStr())) return true; } - } else { + } else for (TagList::const_iterator itTagList = m_listTag.begin(); itTagList != m_listTag.end(); ++itTagList) { const CKadTag *pTag = *itTagList; if (pTag->IsStr() && rSearchTerm.m_pTag->m_name.Compare(pTag->m_name) == 0) - return KadTagStrCompareNoCase(pTag->GetStr(), rSearchTerm.m_pTag->GetStr()) == 0; + return EqualKadTagStr(pTag->GetStr(), rSearchTerm.m_pTag->GetStr()); } - } } return false; } @@ -338,7 +332,7 @@ void CKeyEntry::AdjustGlobalPublishTracking(uint32 uIP, bool bIncrease, const CS else --nCount; if (bFound || bIncrease) - s_mapGlobalPublishIPs.SetAt(uIP & ~0xFF, nCount); + s_mapGlobalPublishIPs[uIP & ~0xFF] = nCount; else ASSERT(0); //LOGTODO @@ -351,7 +345,7 @@ void CKeyEntry::MergeIPsAndFilenames(CKeyEntry *pFromEntry) // this is called when replacing a stored entry with a refreshed one. // we want to take over the tracked IPs, AICHHash and the different file names from the old entry, // the rest is still "overwritten" with the refreshed values. This might be not perfect - // for the tag list in some cases, but we cant afford to store hundreds of tag lists + // for the tag list in some cases, but we can't afford to store hundreds of tag lists // to figure out the best one like we do for the filenames now if (m_pliPublishingIPs != NULL) { // This instance needs to be a new entry, otherwise we don't want/need to merge ASSERT(pFromEntry == NULL); @@ -392,13 +386,13 @@ void CKeyEntry::MergeIPsAndFilenames(CKeyEntry *pFromEntry) structPublishingIP Cur = m_pliPublishingIPs->GetNext(pos); if (Cur.m_uIP == m_uIP) { bRefresh = true; - if ((time(NULL) < Cur.m_tLastPublish) + (KADEMLIAREPUBLISHTIMES - HR2S(1))) { + const time_t tNow = time(NULL); + if ((tNow < Cur.m_tLastPublish) + (KADEMLIAREPUBLISHTIMES - HR2S(1))) { DEBUG_ONLY(DebugLog(_T("KadEntryTracking: FastRefresh publish, ip: %s"), (LPCTSTR)ipstr(htonl(m_uIP)))); bFastRefresh = true; // refreshed faster than expected, will not count into filename popularity index } - Cur.m_tLastPublish = time(NULL); + Cur.m_tLastPublish = tNow; m_pliPublishingIPs->RemoveAt(pos2); - m_pliPublishingIPs->AddTail(Cur); // Has the AICH Hash this publisher reported changed? if (pNewAICHHash != NULL) { if (Cur.m_wAICHHashIdx == _UI16_MAX) { @@ -414,6 +408,7 @@ void CKeyEntry::MergeIPsAndFilenames(CKeyEntry *pFromEntry) AddRemoveAICHHash(m_aAICHHashes[Cur.m_wAICHHashIdx], false); Cur.m_wAICHHashIdx = _UI16_MAX; } + m_pliPublishingIPs->AddTail(Cur); break; } } @@ -422,16 +417,15 @@ void CKeyEntry::MergeIPsAndFilenames(CKeyEntry *pFromEntry) dwLastTrustValueCalc = pFromEntry->dwLastTrustValueCalc; // copy over the different names, if they differ from the one we have right now - ASSERT(m_listFileNames.GetCount() == 1); // we should have only one name here, since its the entry from one sinlge source + ASSERT(m_listFileNames.GetCount() == 1); // we should have only one name here, since its the entry from one single source const structFileNameEntry &structCurrentName(m_listFileNames.IsEmpty() ? structFileNameEntry() : m_listFileNames.RemoveHead()); bool bDuplicate = false; for (POSITION pos = pFromEntry->m_listFileNames.GetHeadPosition(); pos != NULL;) { structFileNameEntry structNameToCopy = pFromEntry->m_listFileNames.GetNext(pos); - if (KadTagStrCompareNoCase(structCurrentName.m_fileName, structNameToCopy.m_fileName) == 0) { + if (EqualKadTagStr(structCurrentName.m_fileName, structNameToCopy.m_fileName)) { // the filename of our new entry matches with our old, increase the popularity index for the old one bDuplicate = true; - if (!bFastRefresh) - structNameToCopy.m_uPopularityIndex++; + structNameToCopy.m_uPopularityIndex += static_cast(!bFastRefresh); } m_listFileNames.AddTail(structNameToCopy); } @@ -440,7 +434,7 @@ void CKeyEntry::MergeIPsAndFilenames(CKeyEntry *pFromEntry) } // it's done if this was a refresh, otherwise update the global track map if (!bRefresh) { - ASSERT(m_uIP != 0); + ASSERT(m_uIP); uint16 nAICHHashIdx = pNewAICHHash ? AddRemoveAICHHash(*pNewAICHHash, true) : _UI16_MAX; structPublishingIP add = {time(NULL), m_uIP, nAICHHashIdx}; m_pliPublishingIPs->AddTail(add); @@ -547,7 +541,7 @@ void CKeyEntry::WritePublishTrackingDataToFile(CDataIO *pData) // Write AICH Hashes and map them to a new cleaned up index without unreferenced hashes uint16 nNewIdxPos = 0; INT_PTR asize = m_aAICHHashes.GetCount(); - CArray aNewIndexes; + CArray aNewIndexes; aNewIndexes.SetSize(asize); for (int i = 0; i < asize; ++i) aNewIndexes[i] = (m_anAICHHashPopularity[i] > 0) ? nNewIdxPos++ : _UI16_MAX; @@ -566,7 +560,7 @@ void CKeyEntry::WritePublishTrackingDataToFile(CDataIO *pData) pData->WriteUInt32((uint32)m_pliPublishingIPs->GetCount()); for (POSITION pos = m_pliPublishingIPs->GetHeadPosition(); pos != NULL;) { const structPublishingIP &rCur = m_pliPublishingIPs->GetNext(pos); - ASSERT(rCur.m_uIP != 0); + ASSERT(rCur.m_uIP); pData->WriteUInt32(rCur.m_uIP); pData->WriteUInt32((uint32)rCur.m_tLastPublish); uint16 nIdx = _UI16_MAX; @@ -590,7 +584,7 @@ void CKeyEntry::ReadPublishTrackingDataFromFile(CDataIO *pData, bool bIncludesAI ASSERT(m_anAICHHashPopularity.IsEmpty()); if (bIncludesAICH) { CAICHHash hash; - for (uint16 i = pData->ReadUInt16(); i-- > 0;) { //hash count + for (UINT i = pData->ReadUInt16(); i-- > 0;) { //hash count pData->ReadArray(hash.GetRawHash(), CAICHHash::GetHashSize()); m_aAICHHashes.Add(hash); m_anAICHHashPopularity.Add(0); @@ -613,7 +607,7 @@ void CKeyEntry::ReadPublishTrackingDataFromFile(CDataIO *pData, bool bIncludesAI for (uint32 i = 0; i < nIPCount; ++i) { structPublishingIP sToAdd; sToAdd.m_uIP = pData->ReadUInt32(); - ASSERT(sToAdd.m_uIP != 0); + ASSERT(sToAdd.m_uIP); sToAdd.m_tLastPublish = pData->ReadUInt32(); ASSERT(nDbgLastTime <= sToAdd.m_tLastPublish); // should always be sorted oldest first nDbgLastTime = sToAdd.m_tLastPublish; @@ -627,7 +621,7 @@ void CKeyEntry::ReadPublishTrackingDataFromFile(CDataIO *pData, bool bIncludesAI DebugLogError(_T("CKeyEntry::ReadPublishTrackingDataFromFile - Out of Index AICH Hash index value while loading keywords")); sToAdd.m_wAICHHashIdx = _UI16_MAX; } else - m_anAICHHashPopularity[sToAdd.m_wAICHHashIdx]++; + ++m_anAICHHashPopularity[sToAdd.m_wAICHHashIdx]; } } else sToAdd.m_wAICHHashIdx = _UI16_MAX; @@ -675,12 +669,11 @@ void CKeyEntry::WriteTagListWithPublishInfo(CDataIO *pData) // this is supposed to get used in later versions as an indicator for the user how valid this result is (of course this tag // alone cannot be trusted 100%, because we could be a bad node, but it's a part of the puzzle) uint32 uTrust = (uint16)(GetTrustValue() * 100); - uint32 uPublishers = m_pliPublishingIPs->GetCount() % 256; - uint32 uNames = m_listFileNames.GetCount() % 256; + uint32 uPublishers = (uint32)(m_pliPublishingIPs->GetCount() % 256); + uint32 uNames = (uint32)(m_listFileNames.GetCount() % 256); // 32 bit tag: uint32 uTagValue = (uNames << 24) | (uPublishers << 16) | (uTrust << 0); - const CKadTagUInt tag(TAG_PUBLISHINFO, uTagValue); - pData->WriteTag(&tag); + pData->WriteTag(CKadTagUInt(TAG_PUBLISHINFO, uTagValue)); // Last but not least the AICH Hash tag, containing all reported (hopefully, exactly 1) AICH hashes // for this file together with the count of publishers who reported it @@ -706,7 +699,7 @@ void CKeyEntry::WriteTagListWithPublishInfo(CDataIO *pData) for (j = 0; nWritten < byCount && j < m_aAICHHashes.GetCount(); ++j) { if (m_anAICHHashPopularity[j] > 0) { fileAICHTag.WriteUInt8(m_anAICHHashPopularity[j]); - m_aAICHHashes[j].Write(&fileAICHTag); + m_aAICHHashes[j].Write(fileAICHTag); ++nWritten; } } @@ -714,8 +707,7 @@ void CKeyEntry::WriteTagListWithPublishInfo(CDataIO *pData) ASSERT(fileAICHTag.GetLength() <= 255); uint8 nSize = (uint8)fileAICHTag.GetLength(); BYTE *byBuffer = fileAICHTag.Detach(); - const CKadTagBsob tag1(TAG_KADAICHHASHRESULT, byBuffer, nSize); - pData->WriteTag(&tag1); + pData->WriteTag(CKadTagBsob(TAG_KADAICHHASHRESULT, byBuffer, nSize)); free(byBuffer); } } @@ -731,7 +723,7 @@ uint16 CKeyEntry::AddRemoveAICHHash(const CAICHHash &hash, bool bAdd) if (m_anAICHHashPopularity[i] > 0) --m_anAICHHashPopularity[i]; //else - // ASSERT( false ); + // ASSERT(0); } return (uint16)i; } diff --git a/srchybrid/kademlia/kademlia/Entry.h b/srchybrid/kademlia/kademlia/Entry.h index 5dbcc986..3c4e3e23 100644 --- a/srchybrid/kademlia/kademlia/Entry.h +++ b/srchybrid/kademlia/kademlia/Entry.h @@ -19,7 +19,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -107,11 +107,11 @@ namespace Kademlia static void AdjustGlobalPublishTracking(uint32 uIP, bool bIncrease, const CString &strDbgReason); float m_fTrustValue; - CArray m_anAICHHashPopularity; + CArray m_anAICHHashPopularity; CArray m_aAICHHashes; static CMap s_mapGlobalPublishIPs; // tracks count of publishings for each 255.255.255.0/28 subnet CList *m_pliPublishingIPs; - uint32 dwLastTrustValueCalc; + DWORD dwLastTrustValueCalc; private: bool SearchTermsMatch(const SSearchTerm &rSearchTerm) const; CKadTagValueString m_strSearchTermCacheCommonFileNameLowerCase; // contains a valid value only while 'SearchTermsMatch' is running. diff --git a/srchybrid/kademlia/kademlia/Error.h b/srchybrid/kademlia/kademlia/Error.h index eabb9888..57984015 100644 --- a/srchybrid/kademlia/kademlia/Error.h +++ b/srchybrid/kademlia/kademlia/Error.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ diff --git a/srchybrid/kademlia/kademlia/Indexed.cpp b/srchybrid/kademlia/kademlia/Indexed.cpp index 7302f27e..f418cb95 100644 --- a/srchybrid/kademlia/kademlia/Indexed.cpp +++ b/srchybrid/kademlia/kademlia/Indexed.cpp @@ -21,7 +21,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -53,7 +53,9 @@ CString CIndexed::m_sKeyFileName; CString CIndexed::m_sSourceFileName; CString CIndexed::m_sLoadFileName; +#ifdef _DEBUG static LPCTSTR const strLoadingInProgress = _T("CIndexed member function call failed because the data loading still in progress"); +#endif CIndexed::CIndexed() : m_uTotalIndexSource() @@ -67,10 +69,10 @@ CIndexed::CIndexed() m_mapNotes.InitHashTable(1031); m_mapLoad.InitHashTable(1031); m_mapSources.InitHashTable(1031); - const CString &confdir = thePrefs.GetMuleDirectory(EMULE_CONFIGDIR); - m_sSourceFileName = confdir + _T("src_index.dat"); - m_sKeyFileName = confdir + _T("key_index.dat"); - m_sLoadFileName = confdir + _T("load_index.dat"); + const CString &confdir(thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); + m_sSourceFileName.Format(_T("%s") _T("src_index.dat"), (LPCTSTR)confdir); + m_sKeyFileName.Format(_T("%s") _T("key_index.dat"), (LPCTSTR)confdir); + m_sLoadFileName.Format(_T("%s") _T("load_index.dat"), (LPCTSTR)confdir); m_tNextClean = time(NULL) + MIN2S(30); ReadFile(); } @@ -86,7 +88,7 @@ void CIndexed::ReadFile() CIndexed::~CIndexed() { if (!m_bDataLoaded) { - // the user clicked on disconnect/close just after he started kad (and probably just before posting in the forum that emule doesn't works :P ) + // the user clicked on disconnect/close just after he started kad (and probably just before posting in the forum that emule doesn't work :P ) // while the loading thread is still busy. First tell the thread to abort its loading, afterwards wait for it to terminate // and then delete all loaded items without writing them to the files (as they are incomplete and unchanged) m_bAbortLoading = true; @@ -99,12 +101,12 @@ CIndexed::~CIndexed() for (POSITION pos = m_mapSources.GetStartPosition(); pos != NULL;) { SrcHash *pCurrSrcHash; m_mapSources.GetNextAssoc(pos, key1, pCurrSrcHash); - CKadSourcePtrList *keyHashSrcMap = &pCurrSrcHash->ptrlistSource; - for (POSITION pos2 = keyHashSrcMap->GetHeadPosition(); pos2 != NULL;) { - Source *pCurrSource = keyHashSrcMap->GetNext(pos2); - CKadEntryPtrList *srcEntryList = &pCurrSource->ptrlEntryList; - while (!srcEntryList->IsEmpty()) - delete srcEntryList->RemoveHead(); + CKadSourcePtrList &keyHashSrcMap(pCurrSrcHash->ptrlistSource); + for (POSITION pos2 = keyHashSrcMap.GetHeadPosition(); pos2 != NULL;) { + Source *pCurrSource = keyHashSrcMap.GetNext(pos2); + CKadEntryPtrList &srcEntryList = pCurrSource->ptrlEntryList; + while (!srcEntryList.IsEmpty()) + delete srcEntryList.RemoveHead(); delete pCurrSource; } delete pCurrSrcHash; @@ -119,13 +121,13 @@ CIndexed::~CIndexed() for (POSITION pos = m_mapKeyword.GetStartPosition(); pos != NULL;) { KeyHash *pCurrKeyHash; m_mapKeyword.GetNextAssoc(pos, key1, pCurrKeyHash); - CSourceKeyMap *keySrcKeyMap = &pCurrKeyHash->mapSource; + CSourceKeyMap &keySrcKeyMap = pCurrKeyHash->mapSource; CCKey key2; - for (POSITION pos2 = keySrcKeyMap->GetStartPosition(); pos2 != NULL;) { + for (POSITION pos2 = keySrcKeyMap.GetStartPosition(); pos2 != NULL;) { Source *pCurrSource; - keySrcKeyMap->GetNextAssoc(pos2, key2, pCurrSource); - for (CKadEntryPtrList *srcEntryList = &pCurrSource->ptrlEntryList; !srcEntryList->IsEmpty();) { - CKeyEntry *pCurrName = static_cast(srcEntryList->RemoveHead()); + keySrcKeyMap.GetNextAssoc(pos2, key2, pCurrSource); + for (CKadEntryPtrList &srcEntryList = pCurrSource->ptrlEntryList; !srcEntryList.IsEmpty();) { + CKeyEntry *pCurrName = static_cast(srcEntryList.RemoveHead()); ASSERT(pCurrName->IsKeyEntry()); pCurrName->DirtyDeletePublishData(); delete pCurrName; @@ -143,7 +145,7 @@ CIndexed::~CIndexed() CBufferedFileIO fileLoad; if (fileLoad.Open(m_sLoadFileName, CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyWrite)) { - setvbuf(fileLoad.m_pStream, NULL, _IOFBF, 32768); + ::setvbuf(fileLoad.m_pStream, NULL, _IOFBF, 32768); static const uint32 uVersion = 1; fileLoad.WriteUInt32(uVersion); fileLoad.WriteUInt32((uint32)time(NULL)); @@ -163,7 +165,7 @@ CIndexed::~CIndexed() CBufferedFileIO fileSource; if (fileSource.Open(m_sSourceFileName, CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyWrite)) { - setvbuf(fileSource.m_pStream, NULL, _IOFBF, 32768); + ::setvbuf(fileSource.m_pStream, NULL, _IOFBF, 32768); static const uint32 uVersion = 2; fileSource.WriteUInt32(uVersion); fileSource.WriteUInt32((uint32)(time(NULL) + KADEMLIAREPUBLISHTIMES)); @@ -173,15 +175,15 @@ CIndexed::~CIndexed() SrcHash *pCurrSrcHash; m_mapSources.GetNextAssoc(pos, key1, pCurrSrcHash); fileSource.WriteUInt128(pCurrSrcHash->uKeyID); - CKadSourcePtrList *keyHashSrcMap = &pCurrSrcHash->ptrlistSource; - fileSource.WriteUInt32((uint32)keyHashSrcMap->GetCount()); - while (!keyHashSrcMap->IsEmpty()) { - Source *pCurrSource = keyHashSrcMap->RemoveHead(); + CKadSourcePtrList &keyHashSrcList(pCurrSrcHash->ptrlistSource); + fileSource.WriteUInt32((uint32)keyHashSrcList.GetCount()); + while (!keyHashSrcList.IsEmpty()) { + Source *pCurrSource = keyHashSrcList.RemoveHead(); fileSource.WriteUInt128(pCurrSource->uSourceID); - CKadEntryPtrList *srcEntryList = &pCurrSource->ptrlEntryList; - fileSource.WriteUInt32((uint32)srcEntryList->GetCount()); - while (!srcEntryList->IsEmpty()) { - CEntry *pCurrName = srcEntryList->RemoveHead(); + CKadEntryPtrList &srcEntryList = pCurrSource->ptrlEntryList; + fileSource.WriteUInt32((uint32)srcEntryList.GetCount()); + while (!srcEntryList.IsEmpty()) { + CEntry *pCurrName = srcEntryList.RemoveTail(); fileSource.WriteUInt32((uint32)pCurrName->m_tLifetime); pCurrName->WriteTagList(&fileSource); delete pCurrName; @@ -197,7 +199,7 @@ CIndexed::~CIndexed() CBufferedFileIO fileKey; if (fileKey.Open(m_sKeyFileName, CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyWrite)) { - setvbuf(fileKey.m_pStream, NULL, _IOFBF, 32768); + ::setvbuf(fileKey.m_pStream, NULL, _IOFBF, 32768); uint32 uVersion = 4; fileKey.WriteUInt32(uVersion); fileKey.WriteUInt32((uint32)(time(NULL) + KADEMLIAREPUBLISHTIMEK)); @@ -208,16 +210,16 @@ CIndexed::~CIndexed() KeyHash *pCurrKeyHash; m_mapKeyword.GetNextAssoc(pos, key1, pCurrKeyHash); fileKey.WriteUInt128(pCurrKeyHash->uKeyID); - CSourceKeyMap *keySrcKeyMap = &pCurrKeyHash->mapSource; - fileKey.WriteUInt32((uint32)keySrcKeyMap->GetCount()); - for (POSITION pos2 = keySrcKeyMap->GetStartPosition(); pos2 != NULL;) { + CSourceKeyMap &keySrcKeyMap = pCurrKeyHash->mapSource; + fileKey.WriteUInt32((uint32)keySrcKeyMap.GetCount()); + for (POSITION pos2 = keySrcKeyMap.GetStartPosition(); pos2 != NULL;) { Source *pCurrSource; - keySrcKeyMap->GetNextAssoc(pos2, key2, pCurrSource); + keySrcKeyMap.GetNextAssoc(pos2, key2, pCurrSource); fileKey.WriteUInt128(pCurrSource->uSourceID); - CKadEntryPtrList *srcEntryList = &pCurrSource->ptrlEntryList; - fileKey.WriteUInt32((uint32)srcEntryList->GetCount()); - while (!srcEntryList->IsEmpty()) { - CKeyEntry *pCurrName = static_cast(srcEntryList->RemoveHead()); + CKadEntryPtrList &srcEntryList = pCurrSource->ptrlEntryList; + fileKey.WriteUInt32((uint32)srcEntryList.GetCount()); + while (!srcEntryList.IsEmpty()) { + CKeyEntry *pCurrName = static_cast(srcEntryList.RemoveTail()); ASSERT(pCurrName->IsKeyEntry()); fileKey.WriteUInt32((uint32)pCurrName->m_tLifetime); pCurrName->WritePublishTrackingDataToFile(&fileKey); @@ -265,11 +267,11 @@ CIndexed::~CIndexed() void CIndexed::Clean() { static LONG cleaning = 0; - if (InterlockedExchange(&cleaning, 1)) + if (::InterlockedExchange(&cleaning, 1)) return; //already cleaning time_t tNow = time(NULL); if (tNow < m_tNextClean) { - InterlockedExchange(&cleaning, 0); + ::InterlockedExchange(&cleaning, 0); return; } @@ -314,10 +316,10 @@ void CIndexed::Clean() for (POSITION pos = m_mapSources.GetStartPosition(); pos != NULL;) { SrcHash *pCurrSrcHash; m_mapSources.GetNextAssoc(pos, key1, pCurrSrcHash); - for (POSITION pos2 = pCurrSrcHash->ptrlistSource.GetHeadPosition(); pos2 != NULL; ) { + for (POSITION pos2 = pCurrSrcHash->ptrlistSource.GetHeadPosition(); pos2 != NULL;) { POSITION pos3 = pos2; Source *pCurrSource = pCurrSrcHash->ptrlistSource.GetNext(pos2); - for (POSITION pos4 = pCurrSource->ptrlEntryList.GetHeadPosition(); pos4 != NULL; ) { + for (POSITION pos4 = pCurrSource->ptrlEntryList.GetHeadPosition(); pos4 != NULL;) { POSITION pos5 = pos4; CEntry *pCurrName = pCurrSource->ptrlEntryList.GetNext(pos4); ++uTotalSource; @@ -346,7 +348,7 @@ void CIndexed::Clean() AddDebugLogLine(false, _T("Exception in CIndexed::Clean")); ASSERT(0); } - InterlockedExchange(&cleaning, 0); + ::InterlockedExchange(&cleaning, 0); } bool CIndexed::AddKeyword(const CUInt128 &uKeyID, const CUInt128 &uSourceID, Kademlia::CKeyEntry *pEntry, uint8 &uLoad, bool bIgnoreThreadLock) @@ -382,8 +384,8 @@ bool CIndexed::AddKeyword(const CUInt128 &uKeyID, const CUInt128 &uSourceID, Kad pCurrSource->ptrlEntryList.AddHead(pEntry); pCurrKeyHash = new KeyHash; pCurrKeyHash->uKeyID.SetValue(uKeyID); - pCurrKeyHash->mapSource.SetAt(CCKey(pCurrSource->uSourceID.GetData()), pCurrSource); - m_mapKeyword.SetAt(CCKey(pCurrKeyHash->uKeyID.GetData()), pCurrKeyHash); + pCurrKeyHash->mapSource[CCKey(pCurrSource->uSourceID.GetData())] = pCurrSource; + m_mapKeyword[CCKey(pCurrKeyHash->uKeyID.GetData())] = pCurrKeyHash; uLoad = 1; ++m_uTotalIndexKeyword; return true; @@ -426,16 +428,16 @@ bool CIndexed::AddKeyword(const CUInt128 &uKeyID, const CUInt128 &uSourceID, Kad ++m_uTotalIndexKeyword; pEntry->MergeIPsAndFilenames(NULL); //IpTracking init } - uLoad = (uint8)((uIndexTotal * 100) / KADEMLIAMAXINDEX); + uLoad = (uint8)(uIndexTotal * 100 / KADEMLIAMAXINDEX); pCurrSource->ptrlEntryList.AddHead(pEntry); } else { pCurrSource = new Source; pCurrSource->uSourceID.SetValue(uSourceID); pEntry->MergeIPsAndFilenames(NULL); //IpTracking init pCurrSource->ptrlEntryList.AddHead(pEntry); - pCurrKeyHash->mapSource.SetAt(CCKey(pCurrSource->uSourceID.GetData()), pCurrSource); + pCurrKeyHash->mapSource[CCKey(pCurrSource->uSourceID.GetData())] = pCurrSource; ++m_uTotalIndexKeyword; - uLoad = (uint8)((uIndexTotal * 100) / KADEMLIAMAXINDEX); + uLoad = (uint8)(uIndexTotal * 100 / KADEMLIAMAXINDEX); } return true; } @@ -467,29 +469,29 @@ bool CIndexed::AddSources(const CUInt128 &uKeyID, const CUInt128 &uSourceID, Kad pCurrSrcHash = new SrcHash; pCurrSrcHash->uKeyID.SetValue(uKeyID); pCurrSrcHash->ptrlistSource.AddHead(pCurrSource); - m_mapSources.SetAt(CCKey(pCurrSrcHash->uKeyID.GetData()), pCurrSrcHash); + m_mapSources[CCKey(pCurrSrcHash->uKeyID.GetData())] = pCurrSrcHash; ++m_uTotalIndexSource; uLoad = 1; return true; } INT_PTR uSize = pCurrSrcHash->ptrlistSource.GetCount(); - for (POSITION pos = pCurrSrcHash->ptrlistSource.GetHeadPosition(); pos != NULL; ) { - Source *pCurrSource = pCurrSrcHash->ptrlistSource.GetNext(pos); - if (pCurrSource->ptrlEntryList.IsEmpty()) { + for (POSITION pos = pCurrSrcHash->ptrlistSource.GetHeadPosition(); pos != NULL;) { + Source &rCurrSource(*pCurrSrcHash->ptrlistSource.GetNext(pos)); + if (rCurrSource.ptrlEntryList.IsEmpty()) { //This should never happen! - pCurrSource->ptrlEntryList.AddHead(pEntry); + rCurrSource.ptrlEntryList.AddHead(pEntry); ASSERT(0); - uLoad = (uint8)((uSize * 100) / KADEMLIAMAXSOURCEPERFILE); + uLoad = (uint8)(uSize * 100 / KADEMLIAMAXSOURCEPERFILE); ++m_uTotalIndexSource; return true; } - CEntry *pCurrEntry = pCurrSource->ptrlEntryList.GetHead(); + CEntry *pCurrEntry = rCurrSource.ptrlEntryList.GetHead(); ASSERT(pCurrEntry != NULL); if (pCurrEntry->m_uIP == pEntry->m_uIP && (pCurrEntry->m_uTCPPort == pEntry->m_uTCPPort || pCurrEntry->m_uUDPPort == pEntry->m_uUDPPort)) { - delete pCurrSource->ptrlEntryList.RemoveHead(); - pCurrSource->ptrlEntryList.AddHead(pEntry); - uLoad = (uint8)((uSize * 100) / KADEMLIAMAXSOURCEPERFILE); + delete rCurrSource.ptrlEntryList.RemoveHead(); + rCurrSource.ptrlEntryList.AddHead(pEntry); + uLoad = (uint8)(uSize * 100 / KADEMLIAMAXSOURCEPERFILE); return true; } } @@ -506,7 +508,7 @@ bool CIndexed::AddSources(const CUInt128 &uKeyID, const CUInt128 &uSourceID, Kad pCurrSource->ptrlEntryList.AddHead(pEntry); pCurrSrcHash->ptrlistSource.AddHead(pCurrSource); ++m_uTotalIndexSource; - uLoad = (uint8)((uSize * 100) / KADEMLIAMAXSOURCEPERFILE); + uLoad = (uint8)(uSize * 100 / KADEMLIAMAXSOURCEPERFILE); } return true; } @@ -533,14 +535,14 @@ bool CIndexed::AddNotes(const CUInt128 &uKeyID, const CUInt128 &uSourceID, Kadem pCurrNoteHash = new SrcHash; pCurrNoteHash->uKeyID.SetValue(uKeyID); pCurrNoteHash->ptrlistSource.AddHead(pCurrNote); - m_mapNotes.SetAt(CCKey(pCurrNoteHash->uKeyID.GetData()), pCurrNoteHash); + m_mapNotes[CCKey(pCurrNoteHash->uKeyID.GetData())] = pCurrNoteHash; uLoad = 1; ++m_uTotalIndexNotes; return true; } INT_PTR uSize = pCurrNoteHash->ptrlistSource.GetCount(); - for (POSITION pos = pCurrNoteHash->ptrlistSource.GetHeadPosition(); pos != NULL; ) { + for (POSITION pos = pCurrNoteHash->ptrlistSource.GetHeadPosition(); pos != NULL;) { Source *pCurrNote = pCurrNoteHash->ptrlistSource.GetNext(pos); if (pCurrNote->ptrlEntryList.IsEmpty()) { //This should never happen! @@ -589,12 +591,11 @@ bool CIndexed::AddLoad(const CUInt128 &uKeyID, time_t uTime, bool bIgnoreThreadL if (time(NULL) > uTime) return false; - Load *pLoad; - if (m_mapLoad.Lookup(CCKey(uKeyID.GetData()), pLoad)) + if (m_mapLoad.PLookup(CCKey(uKeyID.GetData()))) return false; - pLoad = new Load{uKeyID, uTime}; - m_mapLoad.SetAt(CCKey(pLoad->uKeyID.GetData()), pLoad); + Load *pLoad = new Load{ uKeyID, uTime }; + m_mapLoad[CCKey(pLoad->uKeyID.GetData())] = pLoad; ++m_uTotalIndexLoad; return true; } @@ -649,7 +650,7 @@ void CIndexed::SendValidKeywordResult(const CUInt128 &uKeyID, const SSearchTerm pCurrName->WriteTagListWithPublishInfo(&byIOTmp); if (byIO.GetUsed() + byIOTmp.GetUsed() > UDP_KAD_MAXFRAGMENT && iUnsentCount > 0) { - uint32 uLen = sizeof byPacket - byIO.GetAvailable(); + uint32 uLen = (uint32)(sizeof byPacket - byIO.GetAvailable()); PokeUInt16(pbyCountPos, (uint16)iUnsentCount); CKademlia::GetUDPListener()->SendPacket(byPacket, uLen, uIP, uPort, senderUDPKey, NULL); byIO.Reset(); @@ -676,7 +677,7 @@ void CIndexed::SendValidKeywordResult(const CUInt128 &uKeyID, const SSearchTerm } if (iUnsentCount > 0) { - uint32 uLen = sizeof byPacket - byIO.GetAvailable(); + uint32 uLen = (uint32)(sizeof byPacket - byIO.GetAvailable()); PokeUInt16(pbyCountPos, (uint16)iUnsentCount); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_SEARCH_RES", uIP, uPort); @@ -729,7 +730,7 @@ void CIndexed::SendValidSourceResult(const CUInt128 &uKeyID, uint32 uIP, uint16 pCurrName->WriteTagList(&byIOTmp); ++iCount; if (byIO.GetUsed() + byIOTmp.GetUsed() > UDP_KAD_MAXFRAGMENT && iUnsentCount > 0) { - uint32 uLen = sizeof byPacket - byIO.GetAvailable(); + uint32 uLen = (uint32)(sizeof byPacket - byIO.GetAvailable()); PokeUInt16(pbyCountPos, (uint16)iUnsentCount); CKademlia::GetUDPListener()->SendPacket(byPacket, uLen, uIP, uPort, senderUDPKey, NULL); byIO.Reset(); @@ -752,7 +753,7 @@ void CIndexed::SendValidSourceResult(const CUInt128 &uKeyID, uint32 uIP, uint16 } if (iUnsentCount > 0) { - uint32 uLen = sizeof byPacket - byIO.GetAvailable(); + uint32 uLen = (uint32)(sizeof byPacket - byIO.GetAvailable()); PokeUInt16(pbyCountPos, (uint16)iUnsentCount); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_SEARCH_RES", uIP, uPort); @@ -792,7 +793,7 @@ void CIndexed::SendValidNoteResult(const CUInt128 &uKeyID, uint32 uIP, uint16 uP int iUnsentCount = 0; CByteIO byIOTmp(bySmallBuffer, sizeof bySmallBuffer); int iCount = 0; - for (POSITION pos = pCurrNoteHash->ptrlistSource.GetHeadPosition(); pos != NULL && iCount < iMaxResults; ) { + for (POSITION pos = pCurrNoteHash->ptrlistSource.GetHeadPosition(); pos != NULL && iCount < iMaxResults;) { const Source *pCurrNote = pCurrNoteHash->ptrlistSource.GetNext(pos); if (!pCurrNote->ptrlEntryList.IsEmpty()) { CEntry *pCurrName = pCurrNote->ptrlEntryList.GetHead(); @@ -801,7 +802,7 @@ void CIndexed::SendValidNoteResult(const CUInt128 &uKeyID, uint32 uIP, uint16 uP pCurrName->WriteTagList(&byIOTmp); ++iCount; if (byIO.GetUsed() + byIOTmp.GetUsed() > UDP_KAD_MAXFRAGMENT && iUnsentCount > 0) { - uint32 uLen = sizeof byPacket - byIO.GetAvailable(); + uint32 uLen = (uint32)(sizeof byPacket - byIO.GetAvailable()); PokeUInt16(pbyCountPos, (uint16)iUnsentCount); CKademlia::GetUDPListener()->SendPacket(byPacket, uLen, uIP, uPort, senderUDPKey, NULL); byIO.Reset(); @@ -823,7 +824,7 @@ void CIndexed::SendValidNoteResult(const CUInt128 &uKeyID, uint32 uIP, uint16 uP } } if (iUnsentCount > 0) { - uint32 uLen = sizeof byPacket - byIO.GetAvailable(); + uint32 uLen = (uint32)(sizeof byPacket - byIO.GetAvailable()); PokeUInt16(pbyCountPos, (uint16)iUnsentCount); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_SEARCH_RES", uIP, uPort); @@ -917,13 +918,13 @@ int CIndexed::CLoadDataThread::Run() if (!m_pOwner->m_bAbortLoading) { CBufferedFileIO fileLoad; if (fileLoad.Open(m_sLoadFileName, CFile::modeRead | CFile::typeBinary | CFile::shareDenyWrite)) { - setvbuf(fileLoad.m_pStream, NULL, _IOFBF, 32768); + ::setvbuf(fileLoad.m_pStream, NULL, _IOFBF, 32768); uint32 uVersion = fileLoad.ReadUInt32(); if (uVersion < 2) { //time_t tSaveTime = fileLoad.ReadUInt32(); - fileLoad.Seek(sizeof(uint32), SEEK_CUR); //skip save time + fileLoad.Seek(sizeof(uint32), CFile::current); //skip save time for (uint32 uNumLoad = fileLoad.ReadUInt32(); uNumLoad && !m_pOwner->m_bAbortLoading; --uNumLoad) { - fileLoad.ReadUInt128(&uKeyID); + fileLoad.ReadUInt128(uKeyID); if (m_pOwner->AddLoad(uKeyID, (time_t)fileLoad.ReadUInt32(), true)) ++uTotalLoad; } @@ -936,18 +937,18 @@ int CIndexed::CLoadDataThread::Run() if (!m_pOwner->m_bAbortLoading) { CBufferedFileIO fileKey; if (fileKey.Open(m_sKeyFileName, CFile::modeRead | CFile::typeBinary | CFile::shareDenyWrite)) { - setvbuf(fileKey.m_pStream, NULL, _IOFBF, 32768); + ::setvbuf(fileKey.m_pStream, NULL, _IOFBF, 32768); uint32 uVersion = fileKey.ReadUInt32(); if (uVersion < 5) { time_t tSaveTime = fileKey.ReadUInt32(); if (tSaveTime > time(NULL)) { - fileKey.ReadUInt128(&uID); + fileKey.ReadUInt128(uID); if (Kademlia::CKademlia::GetPrefs()->GetKadID() == uID) { for (uint32 uNumKeys = fileKey.ReadUInt32(); uNumKeys && !m_pOwner->m_bAbortLoading; --uNumKeys) { - fileKey.ReadUInt128(&uKeyID); + fileKey.ReadUInt128(uKeyID); for (uint32 uNumSource = fileKey.ReadUInt32(); uNumSource && !m_pOwner->m_bAbortLoading; --uNumSource) { - fileKey.ReadUInt128(&uSourceID); + fileKey.ReadUInt128(uSourceID); for (uint32 uNumName = fileKey.ReadUInt32(); uNumName && !m_pOwner->m_bAbortLoading; --uNumName) { CKeyEntry *pToAdd = new Kademlia::CKeyEntry(); pToAdd->m_uKeyID.SetValue(uKeyID); @@ -997,7 +998,7 @@ int CIndexed::CLoadDataThread::Run() if (!m_pOwner->m_bAbortLoading) { CBufferedFileIO fileSource; if (fileSource.Open(m_sSourceFileName, CFile::modeRead | CFile::typeBinary | CFile::shareDenyWrite)) { - setvbuf(fileSource.m_pStream, NULL, _IOFBF, 32768); + ::setvbuf(fileSource.m_pStream, NULL, _IOFBF, 32768); uint32 uTotalSource = 0; uint32 uVersion = fileSource.ReadUInt32(); @@ -1005,9 +1006,9 @@ int CIndexed::CLoadDataThread::Run() time_t tSaveTime = fileSource.ReadUInt32(); if (tSaveTime > time(NULL)) { for (uint32 uNumKeys = fileSource.ReadUInt32(); uNumKeys && !m_pOwner->m_bAbortLoading; --uNumKeys) { - fileSource.ReadUInt128(&uKeyID); + fileSource.ReadUInt128(uKeyID); for (uint32 uNumSource = fileSource.ReadUInt32(); uNumSource && !m_pOwner->m_bAbortLoading; --uNumSource) { - fileSource.ReadUInt128(&uSourceID); + fileSource.ReadUInt128(uSourceID); for (uint32 uNumName = fileSource.ReadUInt32(); uNumName && !m_pOwner->m_bAbortLoading; --uNumName) { CEntry *pToAdd = new Kademlia::CEntry(); pToAdd->m_bSource = true; diff --git a/srchybrid/kademlia/kademlia/Indexed.h b/srchybrid/kademlia/kademlia/Indexed.h index b5e4b499..f5cb6120 100644 --- a/srchybrid/kademlia/kademlia/Indexed.h +++ b/srchybrid/kademlia/kademlia/Indexed.h @@ -21,7 +21,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ diff --git a/srchybrid/kademlia/kademlia/Kademlia.cpp b/srchybrid/kademlia/kademlia/Kademlia.cpp index 706374b2..68d50b8e 100644 --- a/srchybrid/kademlia/kademlia/Kademlia.cpp +++ b/srchybrid/kademlia/kademlia/Kademlia.cpp @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -130,7 +130,7 @@ void CKademlia::Start(CPrefs *pPrefs) // Init bootstrap time. m_tBootstrap = 0; // Init our random seed. - srand((UINT)tNow); + //srand((unsigned)tNow); not needed, KAD is in the main thread // Create our Kad objects. m_pInstance = new CKademlia(); m_pInstance->m_pPrefs = pPrefs; @@ -235,7 +235,8 @@ void CKademlia::Process() CContact *pContact = GetRoutingZone()->GetRandomContact(3, KADEMLIA_VERSION6_49aBETA); if (pContact != NULL) { DEBUG_ONLY(DebugLog(_T("Requesting our external port from %s"), (LPCTSTR)ipstr(pContact->GetNetIP()))); - GetUDPListener()->SendNullPacket(KADEMLIA2_PING, pContact->GetIPAddress(), pContact->GetUDPPort(), pContact->GetUDPKey(), &pContact->GetClientID()); + const CUInt128 uTargetID(pContact->GetClientID()); + GetUDPListener()->SendNullPacket(KADEMLIA2_PING, pContact->GetIPAddress(), pContact->GetUDPPort(), pContact->GetUDPKey(), &uTargetID); } else DEBUG_ONLY(DebugLogWarning(_T("No valid client for requesting external port available"))); m_tExternPortLookup = tNow + 15; @@ -291,7 +292,8 @@ void CKademlia::Process() m_tBootstrap = tNow; m_bootstrapping = true; DebugLog(_T("Trying to Bootstrap Kad from %s, Distance: %s, Version: %u, %u Contacts left"), (LPCTSTR)ipstr(pContact->GetNetIP()), (LPCTSTR)pContact->GetDistance().ToHexString(), pContact->GetVersion(), s_liBootstrapList.GetCount()); - m_pInstance->m_pUDPListener->Bootstrap(pContact->GetIPAddress(), pContact->GetUDPPort(), pContact->GetVersion(), &pContact->GetClientID()); + const CUInt128 uTargetID(pContact->GetClientID()); + m_pInstance->m_pUDPListener->Bootstrap(pContact->GetIPAddress(), pContact->GetUDPPort(), pContact->GetVersion(), &uTargetID); delete pContact; theApp.emuledlg->kademliawnd->StartUpdateContacts(); } else if (m_bootstrapping) { @@ -330,12 +332,8 @@ bool CKademlia::IsFirewalled() uint32 CKademlia::GetKademliaUsers(bool bNewMethod) { - if (m_pInstance && m_pInstance->m_pPrefs) { - if (bNewMethod) - return CalculateKadUsersNew(); - else - return m_pInstance->m_pPrefs->GetKademliaUsers(); - } + if (m_pInstance && m_pInstance->m_pPrefs) + return bNewMethod ? CalculateKadUsersNew() : m_pInstance->m_pPrefs->GetKademliaUsers(); return 0; } @@ -556,7 +554,7 @@ uint32 CKademlia::CalculateKadUsersNew() // produce a usable number. To avoid drifts caused by a single (or more) really close or really // far away hits, we do use median-average instead - // doesn't works well if we have no files to index and nothing to download and the numbers seems + // doesn't work well if we have no files to index and nothing to download and the numbers seems // to be a bit too low compared to our other method. So lets stay with the old one for now, // but keeps this here as an alternative @@ -564,7 +562,7 @@ uint32 CKademlia::CalculateKadUsersNew() return 0; CList liMedian; - for (POSITION pos = m_liStatsEstUsersProbes.GetHeadPosition(); pos != NULL; ) { + for (POSITION pos = m_liStatsEstUsersProbes.GetHeadPosition(); pos != NULL;) { uint32 nProbe = m_liStatsEstUsersProbes.GetNext(pos); bool bInserted = false; for (POSITION pos2 = liMedian.GetHeadPosition(); pos2 != NULL;) { @@ -584,7 +582,7 @@ uint32 CKademlia::CalculateKadUsersNew() liMedian.RemoveTail(); } uint64 nMedian = 0; - for (POSITION pos = liMedian.GetHeadPosition(); pos != NULL; ) + for (POSITION pos = liMedian.GetHeadPosition(); pos != NULL;) nMedian += liMedian.GetNext(pos); nMedian /= liMedian.GetCount(); diff --git a/srchybrid/kademlia/kademlia/Kademlia.h b/srchybrid/kademlia/kademlia/Kademlia.h index 21573427..31693d45 100644 --- a/srchybrid/kademlia/kademlia/Kademlia.h +++ b/srchybrid/kademlia/kademlia/Kademlia.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ diff --git a/srchybrid/kademlia/kademlia/Prefs.cpp b/srchybrid/kademlia/kademlia/Prefs.cpp index 0ee2694b..a57970d6 100644 --- a/srchybrid/kademlia/kademlia/Prefs.cpp +++ b/srchybrid/kademlia/kademlia/Prefs.cpp @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -101,10 +101,10 @@ void CPrefs::ReadFile() CSafeBufferedFile file; CFileException fexp; if (file.Open(m_sFilename, CFile::modeRead | CFile::osSequentialScan | CFile::typeBinary | CFile::shareDenyWrite, &fexp)) { - setvbuf(file.m_pStream, NULL, _IOFBF, 16384); + ::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); m_uIP = file.ReadUInt32(); file.ReadUInt16(); - file.ReadUInt128(&m_uClientID); + file.ReadUInt128(m_uClientID); // get rid of invalid kad IDs which may have been stored by older versions if (m_uClientID == 0) m_uClientID.SetValueRandom(); @@ -124,10 +124,10 @@ void CPrefs::WriteFile() CSafeBufferedFile file; CFileException fexp; if (file.Open(m_sFilename, CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyWrite, &fexp)) { - setvbuf(file.m_pStream, NULL, _IOFBF, 16384); + ::setvbuf(file.m_pStream, NULL, _IOFBF, 16384); file.WriteUInt32(m_uIP); file.WriteUInt16(0); //This is no longer used. - file.WriteUInt128(&m_uClientID); + file.WriteUInt128(m_uClientID); file.WriteUInt8(0); //This is to tell older clients there are no tags. file.Close(); } @@ -177,7 +177,7 @@ bool CPrefs::GetFirewalled() const } void CPrefs::SetFirewalled() { - //We are checking our firewall state. Let keep a snapshot of our + //We are checking our firewall state. Let's keep a snapshot of our //current state to prevent false reports during the recheck. m_bLastFirewallState = (m_uFirewalled < 2); m_uFirewalled = 0; @@ -233,14 +233,14 @@ void CPrefs::SetKademliaFiles() m_uKademliaFiles = nKadAverage * m_uKademliaUsers; } -void CPrefs::GetKadID(CUInt128 *puID) const +void CPrefs::GetKadID(CUInt128 &uID) const { - puID->SetValue(m_uClientID); + uID.SetValue(m_uClientID); } -void CPrefs::GetKadID(CString *psID) const +void CPrefs::GetKadID(CString &sID) const { - m_uClientID.ToHexString(psID); + m_uClientID.ToHexString(sID); } void CPrefs::SetKadID(const CUInt128 &puID) @@ -253,14 +253,14 @@ CUInt128 CPrefs::GetKadID() const return m_uClientID; } -void CPrefs::GetClientHash(CUInt128 *puID) const +void CPrefs::GetClientHash(CUInt128 &uID) const { - puID->SetValue(m_uClientHash); + uID.SetValue(m_uClientHash); } -void CPrefs::GetClientHash(CString *psID) const +void CPrefs::GetClientHash(CString &sID) const { - m_uClientHash.ToHexString(psID); + m_uClientHash.ToHexString(sID); } void CPrefs::SetClientHash(const CUInt128 &puID) diff --git a/srchybrid/kademlia/kademlia/Prefs.h b/srchybrid/kademlia/kademlia/Prefs.h index e006e582..55a2d115 100644 --- a/srchybrid/kademlia/kademlia/Prefs.h +++ b/srchybrid/kademlia/kademlia/Prefs.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -39,12 +39,12 @@ namespace Kademlia CPrefs(); ~CPrefs(); - void GetKadID(CUInt128 *puID) const; - void GetKadID(CString *psID) const; + void GetKadID(CUInt128 &uID) const; + void GetKadID(CString &sID) const; void SetKadID(const CUInt128 &puID); CUInt128 GetKadID() const; - void GetClientHash(CUInt128 *puID) const; - void GetClientHash(CString *psID) const; + void GetClientHash(CUInt128 &uID) const; + void GetClientHash(CString &sID) const; void SetClientHash(const CUInt128 &puID); CUInt128 GetClientHash() const; uint32 GetIPAddress() const; @@ -120,8 +120,8 @@ namespace Kademlia bool m_bLastFirewallState; bool m_bUseExternKadPort; uint16 m_nExternKadPort; - CArray m_anExternPortIPs; - CArray m_anExternPorts; + CArray m_anExternPortIPs; + CArray m_anExternPorts; uint32 m_nStatsUDPOpenNodes; uint32 m_nStatsUDPFirewalledNodes; uint32 m_nStatsTCPOpenNodes; diff --git a/srchybrid/kademlia/kademlia/Search.cpp b/srchybrid/kademlia/kademlia/Search.cpp index 5afc9b16..9a06282c 100644 --- a/srchybrid/kademlia/kademlia/Search.cpp +++ b/srchybrid/kademlia/kademlia/Search.cpp @@ -1,6 +1,6 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) -Copyright (C)2004-2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) +Copyright (C)2004-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -24,7 +24,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -69,7 +69,14 @@ using namespace Kademlia; //void DebugSend(LPCTSTR pszMsg, uint32 uIP, uint16 uUDPPort); CSearch::CSearch() - : m_bStoping() + : m_uTarget() + , m_uClosestDistantFound() + , m_pSearchTerm() + , pNodeSpecialSearchRequester() + , pRequestedMoreNodesContact() + , m_pucSearchTermsData() + , m_uLastResponse(time(NULL)) + , m_tCreated(m_uLastResponse) , m_uType(_UI32_MAX) , m_uAnswers() , m_uTotalRequestAnswers() @@ -78,15 +85,9 @@ CSearch::CSearch() , m_uTotalLoadResponses() , m_uSearchID(_UI32_MAX) , m_uSearchTermsDataSize() - , m_pucSearchTermsData() - , m_pSearchTerm() - , pNodeSpecialSearchRequester() - , m_uTarget() - , m_uClosestDistantFound() - , pRequestedMoreNodesContact() + , m_bStoping() { m_pLookupHistory = new CLookupHistory(); - m_tCreated = m_uLastResponse = time(NULL); theApp.emuledlg->kademliawnd->searchList->SearchAdd(this); } @@ -118,7 +119,7 @@ CSearch::~CSearch() // Remove search from GUI theApp.emuledlg->kademliawnd->searchList->SearchRem(this); - // delete/deref search history (will delete itself if not used by the GUI) + // delete and dereference search history (will delete itself if not used by the GUI) if (m_pLookupHistory != NULL) { m_pLookupHistory->SetSearchDeleted(); m_pLookupHistory = NULL; @@ -149,9 +150,9 @@ CSearch::~CSearch() itInUseMap->second->DecUse(); // Delete any temp contacts. - for (ContactList::const_iterator itDeleteList = m_listDelete.begin(); itDeleteList != m_listDelete.end(); ++itDeleteList) - if (!(*itDeleteList)->InUse()) - delete *itDeleteList; + for (ContactArray::const_iterator itContact = m_listDelete.begin(); itContact != m_listDelete.end(); ++itContact) + if (!(*itContact)->InUse()) + delete *itContact; // Check if this search was contacting an overloaded node and adjust time of next time we use that node. if (CKademlia::IsRunning() && GetNodeLoad() > 20 && GetSearchType() == CSearch::STOREKEYWORD) @@ -168,7 +169,7 @@ void CSearch::Go() if (m_mapPossible.empty()) { CUInt128 uDistance(CKademlia::GetPrefs()->GetKadID()); uDistance.Xor(m_uTarget); - CKademlia::GetRoutingZone()->GetClosestTo(3, m_uTarget, uDistance, 50, &m_mapPossible, true, true); + CKademlia::GetRoutingZone()->GetClosestTo(3, m_uTarget, uDistance, 50, m_mapPossible, true, true); for (ContactMap::const_iterator itPossibleMap = m_mapPossible.begin(); itPossibleMap != m_mapPossible.end(); ++itPossibleMap) m_pLookupHistory->ContactReceived(itPossibleMap->second, NULL, itPossibleMap->first, false); @@ -316,11 +317,10 @@ void CSearch::JumpStart() } } -void CSearch::ProcessResponse(uint32 uFromIP, uint16 uFromPort, ContactList *plistResults) +void CSearch::ProcessResponse(uint32 uFromIP, uint16 uFromPort, const ContactArray &rlistResults) { // Remember the contacts to be deleted when finished - for (ContactList::const_iterator itContactList = plistResults->begin(); itContactList != plistResults->end(); ++itContactList) - m_listDelete.push_back(*itContactList); + m_listDelete.insert(m_listDelete.end(), rlistResults.begin(), rlistResults.end()); m_uLastResponse = time(NULL); @@ -336,41 +336,39 @@ void CSearch::ProcessResponse(uint32 uFromIP, uint16 uFromPort, ContactList *pli } } - // Make sure the node is not sending more results than we requested, which is not only a protocol violation, - // but most likely a malicious answer - if (plistResults->size() > GetRequestContactCount() && !(pRequestedMoreNodesContact == pFromContact && plistResults->size() <= KADEMLIA_FIND_VALUE_MORE)) { + // Make sure the node is not sending more results than we requested, which is not only + // a protocol violation, but most likely a malicious answer + if (rlistResults.size() > GetRequestContactCount() && !(pRequestedMoreNodesContact == pFromContact && rlistResults.size() <= KADEMLIA_FIND_VALUE_MORE)) { DebugLogWarning(_T("Node %s sent more contacts than requested on a routing query, ignoring response"), (LPCTSTR)ipstr(htonl(uFromIP))); - delete plistResults; return; } - if (m_uType == NODEFWCHECKUDP) { - ++m_uAnswers; - // Results are not passed to the search and not much point in changing this, but make sure we show on the graph that the contact responded - m_pLookupHistory->ContactReceived(NULL, pFromContact, CUInt128(), true); - theApp.emuledlg->kademliawnd->UpdateSearchGraph(m_pLookupHistory); - delete plistResults; - // Update search on the GUI. - theApp.emuledlg->kademliawnd->searchList->SearchRef(this); - return; - } - // Not interested in responses for FIND_NODE. - // Once we get a results we stop the search. - // These contacts are added to contacts by UDPListener. - if (m_uType == NODE) { + if (m_uType == NODE || m_uType == NODEFWCHECKUDP) { // Note we got an answer ++m_uAnswers; - // Add contacts to the History for GUI purposes - for (ContactList::const_iterator itResultsList = plistResults->begin(); itResultsList != plistResults->end(); ++itResultsList) { - CUInt128 uDistance((*itResultsList)->GetClientID().Xor(m_uTarget)); - m_pLookupHistory->ContactReceived(*itResultsList, pFromContact, uDistance, uDistance < uFromDistance, true); + + if (m_uType == NODE) { + // Not interested in responses for FIND_NODE. + // Once we get the results, we stop the search. + // These contacts are added to contacts by UDPListener. + + // Add contacts to the History for GUI + for (ContactArray::const_iterator itResultsList = rlistResults.begin(); itResultsList != rlistResults.end(); ++itResultsList) { + CUInt128 uDistance((*itResultsList)->GetClientID().Xor(m_uTarget)); + m_pLookupHistory->ContactReceived(*itResultsList, pFromContact, uDistance, uDistance < uFromDistance, true); + } + theApp.emuledlg->kademliawnd->UpdateSearchGraph(m_pLookupHistory); + // We clear the possible list to force the search to stop. + // We do this so the user has time to see the visualised results. + m_mapPossible.clear(); + } else { + // Results are not passed to the search and not much point in changing this, + // but make sure we show on the graph that the contact responded + m_pLookupHistory->ContactReceived(NULL, pFromContact, CUInt128(), true); + theApp.emuledlg->kademliawnd->UpdateSearchGraph(m_pLookupHistory); } - theApp.emuledlg->kademliawnd->UpdateSearchGraph(m_pLookupHistory); - // We clear the possible list to force the search to stop. - // We do this so the user has time to visually see the results. - m_mapPossible.clear(); - delete plistResults; - // Update search on the GUI. + + // Update search in the GUI. theApp.emuledlg->kademliawnd->searchList->SearchRef(this); return; } @@ -383,9 +381,9 @@ void CSearch::ProcessResponse(uint32 uFromIP, uint16 uFromPort, ContactList *pli mapReceivedIPs[uFromIP] = 1; // A node is not allowed to answer with contacts to itself mapReceivedSubnets[uFromIP & ~0xFF] = 1; // Loop through their responses - for (ContactList::const_iterator itResultsList = plistResults->begin(); itResultsList != plistResults->end(); ++itResultsList) { + for (ContactArray::const_iterator itContact = rlistResults.begin(); itContact != rlistResults.end(); ++itContact) { // Get next result - CContact *pContact = *itResultsList; + CContact *pContact = *itContact; // Calc distance from this result to the target. CUInt128 uDistance(pContact->GetClientID()); @@ -421,7 +419,7 @@ void CSearch::ProcessResponse(uint32 uFromIP, uint16 uFromPort, ContactList *pli , (LPCTSTR)ipstr(htonl(subnetIP)), (LPCTSTR)ipstr(pFromContact->GetNetIP())); continue; } - it->second++; + ++it->second; } // Add to possible @@ -467,7 +465,6 @@ void CSearch::ProcessResponse(uint32 uFromIP, uint16 uFromPort, ContactList *pli } catch (...) { AddDebugLogLine(false, _T("Exception in CSearch::ProcessResponse")); } - delete plistResults; } void CSearch::StorePacket() @@ -491,7 +488,7 @@ void CSearch::StorePacket() case FILE: { CSafeMemFile m_pfileSearchTerms; - m_pfileSearchTerms.WriteUInt128(&m_uTarget); + m_pfileSearchTerms.WriteUInt128(m_uTarget); if (pFromContact->GetVersion() >= KADEMLIA_VERSION3_47b) { // Find file we are storing info about. uchar ucharFileid[MDX_DIGEST_SIZE]; @@ -509,16 +506,16 @@ void CSearch::StorePacket() DebugSend("KADEMLIA2_SEARCH_SOURCE_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort()); if (pFromContact->GetVersion() >= KADEMLIA_VERSION6_49aBETA) { CUInt128 uClientID = pFromContact->GetClientID(); - CKademlia::GetUDPListener()->SendPacket(&m_pfileSearchTerms, KADEMLIA2_SEARCH_SOURCE_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), pFromContact->GetUDPKey(), &uClientID); + CKademlia::GetUDPListener()->SendPacket(m_pfileSearchTerms, KADEMLIA2_SEARCH_SOURCE_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), pFromContact->GetUDPKey(), &uClientID); } else { - CKademlia::GetUDPListener()->SendPacket(&m_pfileSearchTerms, KADEMLIA2_SEARCH_SOURCE_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); + CKademlia::GetUDPListener()->SendPacket(m_pfileSearchTerms, KADEMLIA2_SEARCH_SOURCE_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); ASSERT(CKadUDPKey() == pFromContact->GetUDPKey()); } } else { m_pfileSearchTerms.WriteUInt8(1); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA_SEARCH_REQ(File)", pFromContact->GetIPAddress(), pFromContact->GetUDPPort()); - CKademlia::GetUDPListener()->SendPacket(&m_pfileSearchTerms, KADEMLIA_SEARCH_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); + CKademlia::GetUDPListener()->SendPacket(m_pfileSearchTerms, KADEMLIA_SEARCH_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); } // Inc total request answers ++m_uTotalRequestAnswers; @@ -531,7 +528,7 @@ void CSearch::StorePacket() //JOHNTODO -- We cannot pre-create these packets as we do not know // beforehand if we are talking to Kad1.0 or Kad2.0 CSafeMemFile m_pfileSearchTerms; - m_pfileSearchTerms.WriteUInt128(&m_uTarget); + m_pfileSearchTerms.WriteUInt128(m_uTarget); if (pFromContact->GetVersion() >= KADEMLIA_VERSION3_47b) { if (m_uSearchTermsDataSize == 0) { // JOHNTODO - Need to add ability to change start position. @@ -559,16 +556,16 @@ void CSearch::StorePacket() if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_SEARCH_KEY_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort()); CUInt128 uClientID = pFromContact->GetClientID(); - CKademlia::GetUDPListener()->SendPacket(&m_pfileSearchTerms, KADEMLIA2_SEARCH_KEY_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), pFromContact->GetUDPKey(), &uClientID); + CKademlia::GetUDPListener()->SendPacket(m_pfileSearchTerms, KADEMLIA2_SEARCH_KEY_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), pFromContact->GetUDPKey(), &uClientID); } else if (pFromContact->GetVersion() >= KADEMLIA_VERSION3_47b) { if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_SEARCH_KEY_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort()); - CKademlia::GetUDPListener()->SendPacket(&m_pfileSearchTerms, KADEMLIA2_SEARCH_KEY_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); + CKademlia::GetUDPListener()->SendPacket(m_pfileSearchTerms, KADEMLIA2_SEARCH_KEY_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); ASSERT(CKadUDPKey() == pFromContact->GetUDPKey()); } else { if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA_SEARCH_REQ(KEYWORD)", pFromContact->GetIPAddress(), pFromContact->GetUDPPort()); - CKademlia::GetUDPListener()->SendPacket(&m_pfileSearchTerms, KADEMLIA_SEARCH_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); + CKademlia::GetUDPListener()->SendPacket(m_pfileSearchTerms, KADEMLIA_SEARCH_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); } // Inc total request answers ++m_uTotalRequestAnswers; @@ -580,7 +577,7 @@ void CSearch::StorePacket() { // Write complete packet CSafeMemFile m_pfileSearchTerms; - m_pfileSearchTerms.WriteUInt128(&m_uTarget); + m_pfileSearchTerms.WriteUInt128(m_uTarget); if (pFromContact->GetVersion() >= KADEMLIA_VERSION3_47b) { // Find file we are storing info about. @@ -596,16 +593,16 @@ void CSearch::StorePacket() DebugSend("KADEMLIA2_SEARCH_NOTES_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort()); if (pFromContact->GetVersion() >= KADEMLIA_VERSION6_49aBETA) { CUInt128 uClientID = pFromContact->GetClientID(); - CKademlia::GetUDPListener()->SendPacket(&m_pfileSearchTerms, KADEMLIA2_SEARCH_NOTES_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), pFromContact->GetUDPKey(), &uClientID); + CKademlia::GetUDPListener()->SendPacket(m_pfileSearchTerms, KADEMLIA2_SEARCH_NOTES_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), pFromContact->GetUDPKey(), &uClientID); } else { - CKademlia::GetUDPListener()->SendPacket(&m_pfileSearchTerms, KADEMLIA2_SEARCH_NOTES_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); + CKademlia::GetUDPListener()->SendPacket(m_pfileSearchTerms, KADEMLIA2_SEARCH_NOTES_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); ASSERT(CKadUDPKey() == pFromContact->GetUDPKey()); } } else { - m_pfileSearchTerms.WriteUInt128(&CKademlia::GetPrefs()->GetKadID()); + m_pfileSearchTerms.WriteUInt128(CKademlia::GetPrefs()->GetKadID()); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA_SEARCH_NOTES_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort()); - CKademlia::GetUDPListener()->SendPacket(&m_pfileSearchTerms, KADEMLIA_SEARCH_NOTES_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); + CKademlia::GetUDPListener()->SendPacket(m_pfileSearchTerms, KADEMLIA_SEARCH_NOTES_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); } // Inc total request answers ++m_uTotalRequestAnswers; @@ -700,14 +697,13 @@ void CSearch::StorePacket() // Update search in the GUI theApp.emuledlg->kademliawnd->searchList->SearchRef(this); // Delete all tags. - for (TagList::const_iterator itTagList = listTag.begin(); itTagList != listTag.end(); ++itTagList) - delete *itTagList; + deleteTagListEntries(listTag); } break; case STOREKEYWORD: { // Try to store keywords to a Node. - int iCount = static_cast(m_listFileIDs.size()); + INT_PTR iCount = m_listFileIDs.GetSize(); // As a safeguard, check to see if we already stored to the Max Nodes if (iCount <= 0 || m_uAnswers > SEARCHSTOREKEYWORD_TOTAL) { PrepareToStop(); @@ -716,15 +712,15 @@ void CSearch::StorePacket() if (iCount > 150) iCount = 150; - for (UIntList::const_iterator itListFileID = m_listFileIDs.begin(); iCount > 0 && itListFileID != m_listFileIDs.end();) { + for (INT_PTR i = 0; i < iCount;) { uchar ucharFileid[MDX_DIGEST_SIZE]; uint16 iPacketCount = 0; byte byPacket[1024 * 50]; CByteIO byIO(byPacket, sizeof(byPacket)); byIO.WriteUInt128(m_uTarget); byIO.WriteUInt16(0); // Will be corrected before sending. - while ((iPacketCount < 50) && (itListFileID != m_listFileIDs.end())) { - CUInt128 iID = *itListFileID++; + for (; iPacketCount < 50 && i < m_listFileIDs.GetSize(); ++i) { + const CUInt128 &iID(m_listFileIDs[i]); iID.ToByteArray(ucharFileid); CKnownFile *pFile = theApp.sharedfiles->GetFileByID(ucharFileid); if (pFile) { @@ -746,11 +742,11 @@ void CSearch::StorePacket() if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_PUBLISH_KEY_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort()); CUInt128 uClientID = pFromContact->GetClientID(); - CKademlia::GetUDPListener()->SendPacket(byPacket, sizeof(byPacket) - byIO.GetAvailable(), KADEMLIA2_PUBLISH_KEY_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), pFromContact->GetUDPKey(), &uClientID); + CKademlia::GetUDPListener()->SendPacket(byPacket, (uint32)(sizeof byPacket - byIO.GetAvailable()), KADEMLIA2_PUBLISH_KEY_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), pFromContact->GetUDPKey(), &uClientID); } else if (pFromContact->GetVersion() >= KADEMLIA_VERSION2_47a) { if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_PUBLISH_KEY_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort()); - CKademlia::GetUDPListener()->SendPacket(byPacket, sizeof(byPacket) - byIO.GetAvailable(), KADEMLIA2_PUBLISH_KEY_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); + CKademlia::GetUDPListener()->SendPacket(byPacket, (uint32)(sizeof byPacket - byIO.GetAvailable()), KADEMLIA2_PUBLISH_KEY_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); ASSERT(CKadUDPKey() == pFromContact->GetUDPKey()); } else ASSERT(0); @@ -782,7 +778,7 @@ void CSearch::StorePacket() // Create our taglist TagList listTag; listTag.push_back(new CKadTagStr(TAG_FILENAME, pFile->GetFileName())); - if (pFile->GetFileRating() != 0) + if (pFile->GetFileRating() > 0) listTag.push_back(new CKadTagUInt(TAG_FILERATING, pFile->GetFileRating())); if (!pFile->GetFileComment().IsEmpty()) listTag.push_back(new CKadTagStr(TAG_DESCRIPTION, pFile->GetFileComment())); @@ -795,11 +791,11 @@ void CSearch::StorePacket() if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_PUBLISH_NOTES_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort()); CUInt128 uClientID = pFromContact->GetClientID(); - CKademlia::GetUDPListener()->SendPacket(byPacket, (sizeof byPacket) - byIO.GetAvailable(), KADEMLIA2_PUBLISH_NOTES_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), pFromContact->GetUDPKey(), &uClientID); + CKademlia::GetUDPListener()->SendPacket(byPacket, (uint32)(sizeof byPacket - byIO.GetAvailable()), KADEMLIA2_PUBLISH_NOTES_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), pFromContact->GetUDPKey(), &uClientID); } else if (pFromContact->GetVersion() >= KADEMLIA_VERSION2_47a) { if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_PUBLISH_NOTES_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort()); - CKademlia::GetUDPListener()->SendPacket(byPacket, (sizeof byPacket) - byIO.GetAvailable(), KADEMLIA2_PUBLISH_NOTES_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); + CKademlia::GetUDPListener()->SendPacket(byPacket, (uint32)(sizeof byPacket - byIO.GetAvailable()), KADEMLIA2_PUBLISH_NOTES_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); ASSERT(CKadUDPKey() == pFromContact->GetUDPKey()); } else ASSERT(0); @@ -808,8 +804,7 @@ void CSearch::StorePacket() // Update search in the GUI theApp.emuledlg->kademliawnd->searchList->SearchRef(this); // Delete all tags. - for (TagList::const_iterator itTagList = listTag.begin(); itTagList != listTag.end(); ++itTagList) - delete *itTagList; + deleteTagListEntries(listTag); } break; case FINDBUDDY: @@ -823,9 +818,9 @@ void CSearch::StorePacket() CSafeMemFile m_pfileSearchTerms; // Send the ID we used to find our buddy. Used for checks later and allows users to callback someone if they change buddies. - m_pfileSearchTerms.WriteUInt128(&m_uTarget); + m_pfileSearchTerms.WriteUInt128(m_uTarget); // Send client hash so they can do a callback. - m_pfileSearchTerms.WriteUInt128(&CKademlia::GetPrefs()->GetClientHash()); + m_pfileSearchTerms.WriteUInt128(CKademlia::GetPrefs()->GetClientHash()); // Send client port so they can do a callback m_pfileSearchTerms.WriteUInt16(thePrefs.GetPort()); @@ -835,9 +830,9 @@ void CSearch::StorePacket() DebugSend("KADEMLIA_FINDBUDDY_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort()); if (pFromContact->GetVersion() >= KADEMLIA_VERSION6_49aBETA) { CUInt128 uClientID = pFromContact->GetClientID(); - CKademlia::GetUDPListener()->SendPacket(&m_pfileSearchTerms, KADEMLIA_FINDBUDDY_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), pFromContact->GetUDPKey(), &uClientID); + CKademlia::GetUDPListener()->SendPacket(m_pfileSearchTerms, KADEMLIA_FINDBUDDY_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), pFromContact->GetUDPKey(), &uClientID); } else { - CKademlia::GetUDPListener()->SendPacket(&m_pfileSearchTerms, KADEMLIA_FINDBUDDY_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); + CKademlia::GetUDPListener()->SendPacket(m_pfileSearchTerms, KADEMLIA_FINDBUDDY_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); ASSERT(CKadUDPKey() == pFromContact->GetUDPKey()); } // Inc total request answers @@ -857,11 +852,11 @@ void CSearch::StorePacket() CSafeMemFile fileIO(34); // This is the ID the person we want to contact used to find a buddy. - fileIO.WriteUInt128(&m_uTarget); - if (m_listFileIDs.size() != 1) - throw CString(_T("Kademlia.CSearch.ProcessResponse: m_listFileIDs.size() != 1")); + fileIO.WriteUInt128(m_uTarget); + if (m_listFileIDs.GetSize() != 1) + throwCStr(_T("Kademlia.CSearch.StorePacket: m_listFileIDs.size() != 1")); // Currently, we limit they type of callbacks for sources. We must know a file it person has for it to work. - fileIO.WriteUInt128(&m_listFileIDs.front()); + fileIO.WriteUInt128(m_listFileIDs[0]); // Send our port so the callback works. fileIO.WriteUInt16(thePrefs.GetPort()); // Send packet @@ -869,9 +864,9 @@ void CSearch::StorePacket() DebugSend("KADEMLIA_CALLBACK_REQ", pFromContact->GetIPAddress(), pFromContact->GetUDPPort()); if (pFromContact->GetVersion() >= KADEMLIA_VERSION6_49aBETA) { CUInt128 uClientID = pFromContact->GetClientID(); - CKademlia::GetUDPListener()->SendPacket(&fileIO, KADEMLIA_CALLBACK_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), pFromContact->GetUDPKey(), &uClientID); + CKademlia::GetUDPListener()->SendPacket(fileIO, KADEMLIA_CALLBACK_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), pFromContact->GetUDPKey(), &uClientID); } else { - CKademlia::GetUDPListener()->SendPacket(&fileIO, KADEMLIA_CALLBACK_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); + CKademlia::GetUDPListener()->SendPacket(fileIO, KADEMLIA_CALLBACK_REQ, pFromContact->GetIPAddress(), pFromContact->GetUDPPort(), CKadUDPKey(), NULL); ASSERT(CKadUDPKey() == pFromContact->GetUDPKey()); } // Inc total request answers @@ -891,19 +886,19 @@ void CSearch::StorePacket() } } -void CSearch::ProcessResult(const CUInt128 &uAnswer, TagList *plistInfo, uint32 uFromIP, uint16 uFromPort) +void CSearch::ProcessResult(const CUInt128 &uAnswer, TagList &rlistInfo, uint32 uFromIP, uint16 uFromPort) { // We received a result, process it based on type. uint32 iAnswerBefore = m_uAnswers; switch (m_uType) { case FILE: - ProcessResultFile(uAnswer, plistInfo); + ProcessResultFile(uAnswer, rlistInfo); break; case KEYWORD: - ProcessResultKeyword(uAnswer, plistInfo, uFromIP, uFromPort); + ProcessResultKeyword(uAnswer, rlistInfo, uFromIP, uFromPort); break; case NOTES: - ProcessResultNotes(uAnswer, plistInfo); + ProcessResultNotes(uAnswer, rlistInfo); } if (iAnswerBefore < m_uAnswers) { m_pLookupHistory->ContactRespondedKeyword(uFromIP, uFromPort, m_uAnswers - iAnswerBefore); @@ -913,7 +908,7 @@ void CSearch::ProcessResult(const CUInt128 &uAnswer, TagList *plistInfo, uint32 theApp.emuledlg->kademliawnd->searchList->SearchRef(this); } -void CSearch::ProcessResultFile(const CUInt128 &uAnswer, TagList *plistInfo) +void CSearch::ProcessResultFile(const CUInt128 &uAnswer, TagList &rlistInfo) { // Process a possible source to a file. // Set of data we could receive from the result. @@ -927,34 +922,31 @@ void CSearch::ProcessResultFile(const CUInt128 &uAnswer, TagList *plistInfo) CUInt128 uBuddy; uint8 byCryptOptions = 0; // 0 = not supported - for (TagList::const_iterator itInfoList = plistInfo->begin(); itInfoList != plistInfo->end(); ++itInfoList) { - CKadTag *pTag = *itInfoList; - if (!pTag->m_name.Compare(TAG_SOURCETYPE)) - uType = (uint8)pTag->GetInt(); - else if (!pTag->m_name.Compare(TAG_SOURCEIP)) - uIP = (uint32)pTag->GetInt(); - else if (!pTag->m_name.Compare(TAG_SOURCEPORT)) - uTCPPort = (uint16)pTag->GetInt(); - else if (!pTag->m_name.Compare(TAG_SOURCEUPORT)) - uUDPPort = (uint16)pTag->GetInt(); - else if (!pTag->m_name.Compare(TAG_SERVERIP)) - uBuddyIP = (uint32)pTag->GetInt(); - else if (!pTag->m_name.Compare(TAG_SERVERPORT)) - uBuddyPort = (uint16)pTag->GetInt(); - //else if (!pTag->m_name.Compare(TAG_CLIENTLOWID)) - // uClientID = pTag->GetInt(); - else if (!pTag->m_name.Compare(TAG_BUDDYHASH)) { + for (TagList::const_iterator itInfoList = rlistInfo.begin(); itInfoList != rlistInfo.end(); ++itInfoList) { + const CKadTag &cTag(**itInfoList); + if (cTag.m_name == TAG_SOURCETYPE) + uType = (uint8)cTag.GetInt(); + else if (cTag.m_name == TAG_SOURCEIP) + uIP = (uint32)cTag.GetInt(); + else if (cTag.m_name == TAG_SOURCEPORT) + uTCPPort = (uint16)cTag.GetInt(); + else if (cTag.m_name == TAG_SOURCEUPORT) + uUDPPort = (uint16)cTag.GetInt(); + else if (cTag.m_name == TAG_SERVERIP) + uBuddyIP = (uint32)cTag.GetInt(); + else if (cTag.m_name == TAG_SERVERPORT) + uBuddyPort = (uint16)cTag.GetInt(); + //else if (cTag.m_name == TAG_CLIENTLOWID) + // uClientID = cTag.GetInt(); + else if (cTag.m_name == TAG_BUDDYHASH) { uchar ucharBuddyHash[MDX_DIGEST_SIZE]; - if (pTag->IsStr() && strmd4(pTag->GetStr(), ucharBuddyHash)) + if (cTag.IsStr() && strmd4(cTag.GetStr(), ucharBuddyHash)) md4cpy(uBuddy.GetDataPtr(), ucharBuddyHash); else TRACE("+++ Invalid TAG_BUDDYHASH tag\n"); - } else if (!pTag->m_name.Compare(TAG_ENCRYPTION)) - byCryptOptions = (uint8)pTag->GetInt(); - - delete pTag; + } else if (cTag.m_name == TAG_ENCRYPTION) + byCryptOptions = (uint8)cTag.GetInt(); } - delete plistInfo; // Process source based on its type. Currently only one method is needed to process all types. switch (uType) { @@ -970,106 +962,76 @@ void CSearch::ProcessResultFile(const CUInt128 &uAnswer, TagList *plistInfo) } } -void CSearch::ProcessResultNotes(const CUInt128 &uAnswer, TagList *plistInfo) +void CSearch::ProcessResultNotes(const CUInt128 &uAnswer, TagList &rlistInfo) { // Process a received Note to a file. // Create a Note and set the ID's. - CEntry *pEntry = new CEntry(); - pEntry->m_uKeyID.SetValue(m_uTarget); - pEntry->m_uSourceID.SetValue(uAnswer); - // Create flag to determine if we keep this note. - bool bFilterComment = false; - - // Loops through tags and pull wanted into. Currently we only keep Filename, Rating, Comment. - for (TagList::const_iterator itInfoList = plistInfo->begin(); itInfoList != plistInfo->end(); ++itInfoList) { - CKadTag *pTag = *itInfoList; - if (!pTag->m_name.Compare(TAG_SOURCEIP)) { - pEntry->m_uIP = (uint32)pTag->GetInt(); - delete pTag; - } else if (!pTag->m_name.Compare(TAG_SOURCEPORT)) { - pEntry->m_uTCPPort = (uint16)pTag->GetInt(); - delete pTag; - } else if (!pTag->m_name.Compare(TAG_FILENAME) || !pTag->m_name.Compare(TAG_DESCRIPTION)) { + CEntry cEntry; + cEntry.m_uKeyID.SetValue(m_uTarget); + cEntry.m_uSourceID.SetValue(uAnswer); + + // Loop through tags and pull wanted into. Currently we only keep Filename, Rating, Comment. + for (TagList::iterator itInfoList = rlistInfo.begin(); itInfoList != rlistInfo.end(); ++itInfoList) { + const CKadTag &cTag(**itInfoList); + if (cTag.m_name == TAG_SOURCEIP) + cEntry.m_uIP = (uint32)cTag.GetInt(); + else if (cTag.m_name == TAG_SOURCEPORT) + cEntry.m_uTCPPort = (uint16)cTag.GetInt(); + else if (cTag.m_name == TAG_FILENAME || cTag.m_name == TAG_DESCRIPTION) { const CString &cfilter(thePrefs.GetCommentFilter()); // Run the filter against the comment as well as against the filename since both values could be misused if (!cfilter.IsEmpty()) { - CString strCommentLower(pTag->GetStr()); + CString strCommentLower(cTag.GetStr()); // Verified Locale Dependency: Locale dependent string conversion (OK) strCommentLower.MakeLower(); for (int iPos = 0; iPos >= 0;) { const CString &strFilter(cfilter.Tokenize(_T("|"), iPos)); // comment filters are already in lower case, compare with temp. lower cased received comment - if (!strFilter.IsEmpty() && strCommentLower.Find(strFilter) >= 0) { - bFilterComment = true; - break; - } + if (!strFilter.IsEmpty() && strCommentLower.Find(strFilter) >= 0) + return; } } - if (!pTag->m_name.Compare(TAG_FILENAME)) { - pEntry->SetFileName(pTag->GetStr()); - delete pTag; - } else { - ASSERT(!pTag->m_name.Compare(TAG_DESCRIPTION)); - if (pTag->GetStr().GetLength() > MAXFILECOMMENTLEN) { - CKadTagStr *pReplace = new CKadTagStr(pTag->m_name, pTag->GetStr().Left(MAXFILECOMMENTLEN)); - delete pTag; - pTag = pReplace; - } - pEntry->AddTag(pTag); + if (cTag.m_name == TAG_FILENAME) + cEntry.SetFileName(cTag.GetStr()); + else { + ASSERT(cTag.m_name == TAG_DESCRIPTION); + if (cTag.GetStr().GetLength() <= MAXFILECOMMENTLEN) { + cEntry.AddTag(*itInfoList); //move pointer + *itInfoList = NULL; //do not delete this tag + } else + cEntry.AddTag(new CKadTagStr(cTag.m_name, cTag.GetStr().Left(MAXFILECOMMENTLEN))); } - } else if (!pTag->m_name.Compare(TAG_FILERATING)) - pEntry->AddTag(pTag); - else - delete pTag; - } - delete plistInfo; - - // If we think this should be filtered, delete the note. - if (bFilterComment) { - delete pEntry; - return; + } else if (cTag.m_name == TAG_FILERATING) { + cEntry.AddTag(*itInfoList); //move pointer + *itInfoList = NULL; //do not delete this tag + } } uchar ucharFileid[MDX_DIGEST_SIZE]; m_uTarget.ToByteArray(ucharFileid); // Add notes to any searches we have done. - // The returned entry object will never be attached - // to anything. So you can delete the entry object - // at any time after this call. - bool bFlag = theApp.searchlist->AddNotes(pEntry, ucharFileid); + bool bAddedToSearches = theApp.searchlist->AddNotes(cEntry, ucharFileid); // Check if this hash is in our shared files. CAbstractFile *pFile = static_cast(theApp.sharedfiles->GetFileByID(ucharFileid)); - // If we didn't find a file in the shares check if it's in our download queue. + // If we didn't find a file in the shares, check in our download queue. if (!pFile) pFile = static_cast(theApp.downloadqueue->GetFileByID(ucharFileid)); - // If we found a file try to add the Note to the file. - if (pFile && pFile->AddNote(pEntry)) { + // If we have found a file, try to add the Note to the file - + // though pFile->AddNote still may fail + if ((pFile && pFile->AddNote(cEntry)) || bAddedToSearches) { // Inc the number of answers. ++m_uAnswers; // Update the search in the GUI theApp.emuledlg->kademliawnd->searchList->SearchRef(this); - // We do note delete the NOTE in this case. - return; } - - // It is possible that pFile->AddNote can fail even if we found a File. - if (bFlag) { - // Inc the number of answers. - ++m_uAnswers; - // Update the search in the GUI - theApp.emuledlg->kademliawnd->searchList->SearchRef(this); - } - - // We always delete the entry object if pFile->AddNote fails. - delete pEntry; } -void CSearch::ProcessResultKeyword(const CUInt128 &uAnswer, TagList *plistInfo, uint32 uFromIP, uint16 uFromPort) +void CSearch::ProcessResultKeyword(const CUInt128 &uAnswer, TagList &rlistInfo, uint32 uFromIP, uint16 uFromPort) { // Find the contact who sent the answer - we need to know its protocol version // Special publish answer tags need to be filtered based on its remote protocol version, @@ -1105,53 +1067,52 @@ void CSearch::ProcessResultKeyword(const CUInt128 &uAnswer, TagList *plistInfo, uint32 uAvailability = 0; uint32 uPublishInfo = 0; CArray aAICHHashes; - CArray aAICHHashPopularity; + CArray aAICHHashPopularity; // Flags that are set if we want this keyword. bool bFileName = false; bool bFileSize = false; - for (TagList::const_iterator itInfoList = plistInfo->begin(); itInfoList != plistInfo->end(); ++itInfoList) { - CKadTag *pTag = *itInfoList; - - if (!pTag->m_name.Compare(TAG_FILENAME)) { + for (TagList::const_iterator itInfoList = rlistInfo.begin(); itInfoList != rlistInfo.end(); ++itInfoList) { + const CKadTag &cTag(**itInfoList); + if (cTag.m_name == TAG_FILENAME) { // Set flag based on last tag we saw. - sName = pTag->GetStr(); + sName = cTag.GetStr(); bFileName = !sName.IsEmpty(); - } else if (!pTag->m_name.Compare(TAG_FILESIZE)) { - if (pTag->IsBsob() && pTag->GetBsobSize() == 8) - uSize = *((uint64*)pTag->GetBsob()); + } else if (cTag.m_name == TAG_FILESIZE) { + if (cTag.IsBsob() && cTag.GetBsobSize() == 8) + uSize = *((uint64*)cTag.GetBsob()); else - uSize = pTag->GetInt(); + uSize = cTag.GetInt(); // Set flag based on last tag we saw. bFileSize = (uSize > 0); - } else if (!pTag->m_name.Compare(TAG_FILETYPE)) - sType = pTag->GetStr(); - else if (!pTag->m_name.Compare(TAG_FILEFORMAT)) - sFormat = pTag->GetStr(); - else if (!pTag->m_name.Compare(TAG_MEDIA_ARTIST)) - sArtist = pTag->GetStr(); - else if (!pTag->m_name.Compare(TAG_MEDIA_ALBUM)) - sAlbum = pTag->GetStr(); - else if (!pTag->m_name.Compare(TAG_MEDIA_TITLE)) - sTitle = pTag->GetStr(); - else if (!pTag->m_name.Compare(TAG_MEDIA_LENGTH)) - uLength = (uint32)pTag->GetInt(); - else if (!pTag->m_name.Compare(TAG_MEDIA_BITRATE)) - uBitrate = (uint32)pTag->GetInt(); - else if (!pTag->m_name.Compare(TAG_MEDIA_CODEC)) - sCodec = pTag->GetStr(); - else if (!pTag->m_name.Compare(TAG_SOURCES)) { + } else if (cTag.m_name == TAG_FILETYPE) + sType = cTag.GetStr(); + else if (cTag.m_name == TAG_FILEFORMAT) + sFormat = cTag.GetStr(); + else if (cTag.m_name == TAG_MEDIA_ARTIST) + sArtist = cTag.GetStr(); + else if (cTag.m_name == TAG_MEDIA_ALBUM) + sAlbum = cTag.GetStr(); + else if (cTag.m_name == TAG_MEDIA_TITLE) + sTitle = cTag.GetStr(); + else if (cTag.m_name == TAG_MEDIA_LENGTH) + uLength = (uint32)cTag.GetInt(); + else if (cTag.m_name == TAG_MEDIA_BITRATE) + uBitrate = (uint32)cTag.GetInt(); + else if (cTag.m_name == TAG_MEDIA_CODEC) + sCodec = cTag.GetStr(); + else if (cTag.m_name == TAG_SOURCES) { // Some rouge client was setting an invalid availability, just set it to 0 - uAvailability = (uint32)pTag->GetInt(); + uAvailability = (uint32)cTag.GetInt(); if (uAvailability > 65500) uAvailability = 0; - } else if (!pTag->m_name.Compare(TAG_PUBLISHINFO)) { + } else if (cTag.m_name == TAG_PUBLISHINFO) { if (uFromKadVersion >= KADEMLIA_VERSION6_49aBETA) { // we don't keep this as a tag, but as a member property of the search file, // because we only need its information in the search list and don't want to carry // the tag over when downloading the file (and maybe even wrongly publishing it) - uPublishInfo = (uint32)pTag->GetInt(); + uPublishInfo = (uint32)cTag.GetInt(); /* #ifdef _DEBUG uint32 byDifferentNames = (uPublishInfo >> 24) & 0xFF; @@ -1163,15 +1124,15 @@ void CSearch::ProcessResultKeyword(const CUInt128 &uAnswer, TagList *plistInfo, } else DebugLogWarning(_T("ProcessResultKeyword: Received special publish tag (TAG_PUBLISHINFO) from node (version %u, ip: %s) which is not aware of it, filtering") , uFromKadVersion, (LPCTSTR)ipstr(htonl(uFromIP))); - } else if (!pTag->m_name.Compare(TAG_KADAICHHASHRESULT)) { - if (uFromKadVersion >= KADEMLIA_VERSION9_50a && pTag->IsBsob()) { - CSafeMemFile fileAICHTag(pTag->GetBsob(), pTag->GetBsobSize()); + } else if (cTag.m_name == TAG_KADAICHHASHRESULT) { + if (uFromKadVersion >= KADEMLIA_VERSION9_50a && cTag.IsBsob()) { + CSafeMemFile fileAICHTag(cTag.GetBsob(), cTag.GetBsobSize()); try { for (uint8 byCount = fileAICHTag.ReadUInt8(); byCount > 0; --byCount) { uint8 byPopularity = fileAICHTag.ReadUInt8(); if (byPopularity > 0) { aAICHHashPopularity.Add(byPopularity); - aAICHHashes.Add(CAICHHash(&fileAICHTag)); + aAICHHashes.Add(CAICHHash(fileAICHTag)); } } } catch (CFileException *pError) { @@ -1184,9 +1145,7 @@ void CSearch::ProcessResultKeyword(const CUInt128 &uAnswer, TagList *plistInfo, DebugLogWarning(_T("ProcessResultKeyword: Received special publish tag (TAG_KADAICHHASHRESULT) from node (version %u, ip: %s) which is not aware of it, filtering") , uFromKadVersion, (LPCTSTR)ipstr(htonl(uFromIP))); } - delete pTag; } - delete plistInfo; // If we don't have a valid filename or file size, drop this keyword. if (!bFileName || !bFileSize) @@ -1194,13 +1153,13 @@ void CSearch::ProcessResultKeyword(const CUInt128 &uAnswer, TagList *plistInfo, // Check that this result matches the original criteria WordList listTestWords; - CSearchManager::GetWords(sName, &listTestWords); + CSearchManager::GetWords(sName, listTestWords); CKadTagValueString keyword; for (WordList::const_iterator itWordListWords = m_listWords.begin(); itWordListWords != m_listWords.end(); ++itWordListWords) { keyword = *itWordListWords; bool bInterested = false; for (WordList::const_iterator itWordListTestWords = listTestWords.begin(); itWordListTestWords != listTestWords.end(); ++itWordListTestWords) - if (!KadTagStrCompareNoCase(keyword, *itWordListTestWords)) { + if (EqualKadTagStr(keyword, *itWordListTestWords)) { bInterested = true; break; } @@ -1258,9 +1217,9 @@ void CSearch::SendFindValue(CContact *pContact, bool bReAskMore) fileIO.WriteUInt8(byContactCount); // Put the target we want into the packet. - fileIO.WriteUInt128(&m_uTarget); + fileIO.WriteUInt128(m_uTarget); // Add the ID of the contact we are contacting for sanity checks on the other end. - fileIO.WriteUInt128(&pContact->GetClientID()); + fileIO.WriteUInt128(pContact->GetClientID()); // Inc the number of packets sent. ++m_uKadPacketSent; // Update the search for the GUI. @@ -1271,9 +1230,9 @@ void CSearch::SendFindValue(CContact *pContact, bool bReAskMore) theApp.emuledlg->kademliawnd->UpdateSearchGraph(m_pLookupHistory); if (pContact->GetVersion() >= KADEMLIA_VERSION6_49aBETA) { CUInt128 uClientID = pContact->GetClientID(); - CKademlia::GetUDPListener()->SendPacket(&fileIO, KADEMLIA2_REQ, pContact->GetIPAddress(), pContact->GetUDPPort(), pContact->GetUDPKey(), &uClientID); + CKademlia::GetUDPListener()->SendPacket(fileIO, KADEMLIA2_REQ, pContact->GetIPAddress(), pContact->GetUDPPort(), pContact->GetUDPKey(), &uClientID); } else { - CKademlia::GetUDPListener()->SendPacket(&fileIO, KADEMLIA2_REQ, pContact->GetIPAddress(), pContact->GetUDPPort(), CKadUDPKey(), NULL); + CKademlia::GetUDPListener()->SendPacket(fileIO, KADEMLIA2_REQ, pContact->GetIPAddress(), pContact->GetUDPPort(), CKadUDPKey(), NULL); ASSERT(CKadUDPKey() == pContact->GetUDPKey()); } if (thePrefs.GetDebugClientKadUDPLevel() > 0) { @@ -1328,12 +1287,12 @@ void CSearch::AddFileID(const CUInt128 &uID) { // Add a file hash to the search list. // This is used mainly for storing keywords, but was also reused for storing notes. - m_listFileIDs.push_back(uID); + m_listFileIDs.Add(uID); } static INT_PTR GetMetaDataWords(CStringArray &rastrWords, const CString &rstrData) { - // Create a list of the 'words' found in 'data'. This is similar but though not equal + // Create a list of the 'words' found in 'data'. This is somewhat similar // to the 'CSearchManager::GetWords' function which needs to follow some other rules. for (int iPos = 0; iPos >= 0;) { const CString &strWord(rstrData.Tokenize(g_aszInvKadKeywordChars, iPos)); @@ -1377,13 +1336,11 @@ void CSearch::PreparePacketForTags(CByteIO *byIO, CKnownFile *pFile, uint8 byTar if (pFile && byIO) { // Name, Size listTag.push_back(new CKadTagStr(TAG_FILENAME, pFile->GetFileName())); - //if (pFile->GetFileSize() > OLD_MAX_EMULE_FILE_SIZE) - //{ + //if (pFile->GetFileSize() > OLD_MAX_EMULE_FILE_SIZE) { // // TODO: As soon as we drop Kad1 support, we should switch to Int64 tags (we could do now already for kad2 nodes only but no advantage in that) // uint64 uSize = (uint64)pFile->GetFileSize(); // listTag.push_back(new CKadTagBsob(TAG_FILESIZE, (BYTE*)&uSize, sizeof(uint64))); - //} - //else + //} else listTag.push_back(new CKadTagUInt(TAG_FILESIZE, (uint64)pFile->GetFileSize())); listTag.push_back(new CKadTagUInt(TAG_SOURCES, pFile->m_nCompleteSourcesCount)); @@ -1400,16 +1357,11 @@ void CSearch::PreparePacketForTags(CByteIO *byIO, CKnownFile *pFile, uint8 byTar // file format (filename extension) // 21-Sep-2006 []: TAG_FILEFORMAT is no longer explicitly published nor stored as - // it is already part of the filename. - //int iExt = pFile->GetFileName().ReverseFind(_T('.')); - //if (iExt >= 0) { - // CString strExt(pFile->GetFileName().Mid(iExt)); - // if (!strExt.IsEmpty()) { - // strExt = strExt.Mid(1); - // if (!strExt.IsEmpty()) - // listTag.push_back(new CKadTagStr(TAG_FILEFORMAT, strExt)); - // } - //} + // it is already a part of the filename. + /*LPCTSTR pDot = ::PathFindExtension(pFile->GetFileName()); + if (pDot && pDot[1]) // not empty + listTag.push_back(new CKadTagStr(TAG_FILEFORMAT, CString(pDot + 1))); + */ // additional meta data (Artist, Album, Codec, Length, ...) // only send verified meta data to nodes @@ -1462,7 +1414,7 @@ void CSearch::PreparePacketForTags(CByteIO *byIO, CKnownFile *pFile, uint8 byTar } byIO->WriteTagList(listTag); } else { - //If we get here. Bad things happen. Will fix this later if it is a real issue. + //If we get here, bad things happened. Will fix this later if it is a real issue. ASSERT(0); } } catch (CIOException *ioe) { @@ -1471,8 +1423,7 @@ void CSearch::PreparePacketForTags(CByteIO *byIO, CKnownFile *pFile, uint8 byTar } catch (...) { AddDebugLogLine(false, _T("Exception in CSearch::PreparePacketForTags")); } - for (TagList::const_iterator itTagList = listTag.begin(); itTagList != listTag.end(); ++itTagList) - delete *itTagList; + deleteTagListEntries(listTag); } uint32 CSearch::GetNodeLoad() const @@ -1481,80 +1432,37 @@ uint32 CSearch::GetNodeLoad() const return m_uTotalLoadResponses ? m_uTotalLoad / m_uTotalLoadResponses : 0; } -uint32 CSearch::GetSearchID() const -{ - return m_uSearchID; -} -uint32 CSearch::GetSearchType() const -{ - return m_uType; -} void CSearch::SetSearchType(uint32 uVal) { m_uType = uVal; m_pLookupHistory->SetSearchType(uVal); } -void CSearch::SetTargetID(const CUInt128 &uVal) -{ - m_uTarget = uVal; -} - uint32 CSearch::GetAnswers() const { - if (m_listFileIDs.empty()) + if (m_listFileIDs.IsEmpty()) return m_uAnswers; // If we sent more then one packet per node, we have to average the answers for the real count. - return (uint32)(m_uAnswers / ((m_listFileIDs.size() + 49) / 50)); + return (uint32)(m_uAnswers / ((m_listFileIDs.GetSize() + 49) / 50)); } -uint32 CSearch::GetKadPacketSent() const -{ - return m_uKadPacketSent; -} - -uint32 CSearch::GetRequestAnswer() const +void CSearch::UpdateNodeLoad(uint8 uLoad) { - return m_uTotalRequestAnswers; + // Since all nodes do not return a load value, keep track of total responses and total load. + m_uTotalLoad += uLoad; + ++m_uTotalLoadResponses; } -const CStringW& CSearch::GetGUIName() const +const CStringW& Kademlia::CSearch::GetGUIName() const { return m_pLookupHistory->GetGUIName(); } -void CSearch::SetGUIName(LPCWSTR sGUIName) +void Kademlia::CSearch::SetGUIName(LPCWSTR sGUIName) { m_pLookupHistory->SetGUIName(sGUIName); } -CUInt128 CSearch::GetTarget() const -{ - return m_uTarget; -} - -bool CSearch::Stoping() const -{ - return m_bStoping; -} - -uint32 CSearch::GetNodeLoadResponse() const -{ - return m_uTotalLoadResponses; -} - -uint32 CSearch::GetNodeLoadTotal() const -{ - return m_uTotalLoad; -} - -void CSearch::UpdateNodeLoad(uint8 uLoad) -{ - // Since all nodes do not return a load value, keep track of total responses and total load. - m_uTotalLoad += uLoad; - ++m_uTotalLoadResponses; -} - void CSearch::SetSearchTermData(uint32 uSearchTermDataSize, LPBYTE pucSearchTermsData) { m_uSearchTermsDataSize = uSearchTermDataSize; diff --git a/srchybrid/kademlia/kademlia/Search.h b/srchybrid/kademlia/kademlia/Search.h index 4ee9b666..1df39209 100644 --- a/srchybrid/kademlia/kademlia/Search.h +++ b/srchybrid/kademlia/kademlia/Search.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -38,37 +38,37 @@ struct SSearchTerm; namespace Kademlia { - void deleteTagListEntries(TagList *plistTag); class CByteIO; class CKadClientSearcher; class CLookupHistory; + class CSearch { friend class CSearchManager; public: - uint32 GetSearchID() const; - uint32 GetSearchType() const; - void SetSearchType(uint32 uVal); - void SetTargetID(const CUInt128 &uVal); - CUInt128 GetTarget() const; - uint32 GetAnswers() const; - uint32 GetKadPacketSent() const; - uint32 GetRequestAnswer() const; - uint32 GetNodeLoad() const; - uint32 GetNodeLoadResponse() const; - uint32 GetNodeLoadTotal() const; - const CStringW& GetGUIName() const; - void SetGUIName(LPCWSTR sGUIName); - void SetSearchTermData(uint32 uSearchTermDataSize, LPBYTE pucSearchTermsData); - static CString GetTypeName(uint32 uType); + uint32 GetSearchID() const { return m_uSearchID; }; + uint32 GetSearchType() const { return m_uType; }; + void SetSearchType(uint32 uVal); + void SetTargetID(const CUInt128 &uVal) { m_uTarget = uVal; }; + CUInt128 GetTarget() const { return m_uTarget; }; + uint32 GetAnswers() const; + uint32 GetKadPacketSent() const { return m_uKadPacketSent; }; + uint32 GetRequestAnswer() const { return m_uTotalRequestAnswers; }; + uint32 GetNodeLoad() const; + uint32 GetNodeLoadResponse() const { return m_uTotalLoadResponses; }; + uint32 GetNodeLoadTotal() const { return m_uTotalLoad; }; + const CStringW& GetGUIName() const; + void SetGUIName(LPCWSTR sGUIName); + void SetSearchTermData(uint32 uSearchTermDataSize, LPBYTE pucSearchTermsData); + static CString GetTypeName(uint32 uType); - void AddFileID(const CUInt128 &uID); + void AddFileID(const CUInt128 &uID); static void PreparePacketForTags(CByteIO *byIO, CKnownFile *pFile, uint8 byTargetKadVersion); - bool Stoping() const; - void UpdateNodeLoad(uint8 uLoad); + bool Stoping() const { return m_bStoping; }; + void UpdateNodeLoad(uint8 uLoad); CKadClientSearcher* GetNodeSpecialSearchRequester() const { return pNodeSpecialSearchRequester; } - void SetNodeSpecialSearchRequester(CKadClientSearcher *pNew) { pNodeSpecialSearchRequester = pNew; } + void SetNodeSpecialSearchRequester(CKadClientSearcher *pNew) { pNodeSpecialSearchRequester = pNew; } CLookupHistory* GetLookupHistory() const { return m_pLookupHistory; } enum @@ -94,45 +94,46 @@ namespace Kademlia private: void Go(); - void ProcessResponse(uint32 uFromIP, uint16 uFromPort, ContactList *plistResults); - void ProcessResult(const CUInt128 &uAnswer, TagList *plistInfo, uint32 uFromIP, uint16 uFromPort); - void ProcessResultFile(const CUInt128 &uAnswer, TagList *plistInfo); - void ProcessResultKeyword(const CUInt128 &uAnswer, TagList *plistInfo, uint32 uFromIP, uint16 uFromPort); - void ProcessResultNotes(const CUInt128 &uAnswer, TagList *plistInfo); + void ProcessResponse(uint32 uFromIP, uint16 uFromPort, const ContactArray &rlistResults); + void ProcessResult(const CUInt128 &uAnswer, TagList &rlistInfo, uint32 uFromIP, uint16 uFromPort); + void ProcessResultFile(const CUInt128 &uAnswer, TagList &rlistInfo); + void ProcessResultKeyword(const CUInt128 &uAnswer, TagList &rlistInfo, uint32 uFromIP, uint16 uFromPort); + void ProcessResultNotes(const CUInt128 &uAnswer, TagList &rlistInfo); void JumpStart(); void SendFindValue(CContact *pContact, bool bReAskMore = false); void PrepareToStop(); void StorePacket(); uint8 GetRequestContactCount() const; - bool m_bStoping; - time_t m_tCreated; - uint32 m_uType; - uint32 m_uAnswers; - uint32 m_uTotalRequestAnswers; - uint32 m_uKadPacketSent; //Used for gui reasons. May not be needed later. - uint32 m_uTotalLoad; - uint32 m_uTotalLoadResponses; - time_t m_uLastResponse; - uint32 m_uSearchID; - uint32 m_uSearchTermsDataSize; - LPBYTE m_pucSearchTermsData; - SSearchTerm *m_pSearchTerm; // cached from m_pucSearchTermsData, used for verifying results later on - CKadClientSearcher *pNodeSpecialSearchRequester; // used to callback on result for NODESPECIAL searches - CUInt128 m_uTarget; WordList m_listWords; UIntList m_listFileIDs; + std::map m_mapResponded; ContactMap m_mapPossible; ContactMap m_mapTried; - std::map m_mapResponded; ContactMap m_mapBest; - ContactList m_listDelete; ContactMap m_mapInUse; + ContactArray m_listDelete; + CUInt128 m_uTarget; CUInt128 m_uClosestDistantFound; // not used for the search itself, but for statistical data collecting + SSearchTerm *m_pSearchTerm; // cached from m_pucSearchTermsData, used for verifying results later on + CKadClientSearcher *pNodeSpecialSearchRequester; // used to callback on result for NODESPECIAL searches CLookupHistory *m_pLookupHistory; CContact *pRequestedMoreNodesContact; + LPBYTE m_pucSearchTermsData; + time_t m_uLastResponse; + time_t m_tCreated; + uint32 m_uType; + uint32 m_uAnswers; + uint32 m_uTotalRequestAnswers; + uint32 m_uKadPacketSent; //Used for GUI, but might not be needed later. + uint32 m_uTotalLoad; + uint32 m_uTotalLoadResponses; + uint32 m_uSearchID; + uint32 m_uSearchTermsDataSize; + bool m_bStoping; }; } + void KadGetKeywordHash(const Kademlia::CKadTagValueString &rstrKeywordW, Kademlia::CUInt128 *puKadID); void KadGetKeywordHash(const CStringA &rstrKeywordA, Kademlia::CUInt128 *puKadID); CStringA KadGetKeywordBytes(const Kademlia::CKadTagValueString &rstrKeywordW); \ No newline at end of file diff --git a/srchybrid/kademlia/kademlia/SearchManager.cpp b/srchybrid/kademlia/kademlia/SearchManager.cpp index b2f7366b..d19e90e5 100644 --- a/srchybrid/kademlia/kademlia/SearchManager.cpp +++ b/srchybrid/kademlia/kademlia/SearchManager.cpp @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -116,62 +116,54 @@ bool CSearchManager::StartSearch(CSearch *pSearch) CSearch* CSearchManager::PrepareFindKeywords(LPCWSTR szKeyword, UINT uSearchTermsSize, LPBYTE pucSearchTermsData) { // Create a keyword search object. + CString strError; CSearch *pSearch = new CSearch; try { // Set search to a keyword type. pSearch->SetSearchType(CSearch::KEYWORD); // Make sure we have a keyword list. - GetWords(szKeyword, &pSearch->m_listWords); - if (pSearch->m_listWords.empty()) { - delete pSearch; - throw GetResString(IDS_KAD_SEARCH_KEYWORD_TOO_SHORT); - } - - // Get the targetID based on the primary keyword. - CKadTagValueString wstrKeyword = pSearch->m_listWords.front(); - KadGetKeywordHash(wstrKeyword, &pSearch->m_uTarget); - - // Verify that we are not already searching for this target. - if (AlreadySearchingFor(pSearch->m_uTarget)) { - delete pSearch; - CString strError; - strError.Format(GetResString(IDS_KAD_SEARCH_KEYWORD_ALREADY_SEARCHING), (LPCTSTR)wstrKeyword); - throw strError; + GetWords(szKeyword, pSearch->m_listWords); + if (pSearch->m_listWords.empty()) + strError = GetResString(IDS_KAD_SEARCH_KEYWORD_TOO_SHORT); + else { + // Get the targetID based on the primary keyword. + CKadTagValueString wstrKeyword = pSearch->m_listWords.front(); + KadGetKeywordHash(wstrKeyword, &pSearch->m_uTarget); + + // Verify that we are not already searching for this target. + if (AlreadySearchingFor(pSearch->m_uTarget)) + strError.Format(GetResString(IDS_KAD_SEARCH_KEYWORD_ALREADY_SEARCHING), (LPCTSTR)wstrKeyword); + else { + pSearch->SetSearchTermData(uSearchTermsSize, pucSearchTermsData); + pSearch->SetGUIName(szKeyword); + // Inc our searchID + pSearch->m_uSearchID = ++m_uNextID; + // Insert search into map. + m_mapSearches[pSearch->m_uTarget] = pSearch; + // Start search. + pSearch->Go(); + return pSearch; + } } - - pSearch->SetSearchTermData(uSearchTermsSize, pucSearchTermsData); - pSearch->SetGUIName(szKeyword); - // Inc our searchID - pSearch->m_uSearchID = ++m_uNextID; - // Insert search into map. - m_mapSearches[pSearch->m_uTarget] = pSearch; - // Start search. - pSearch->Go(); } catch (CIOException *ioe) { - CString strError; strError.Format(_T("IO-Exception in %hs: Error %i"), __FUNCTION__, ioe->m_iCause); ioe->Delete(); - delete pSearch; - throw strError; } catch (CFileException *e) { TCHAR szError[MAX_CFEXP_ERRORMSG]; e->m_strFileName = _T("search packet"); GetExceptionMessage(*e, szError, _countof(szError)); - CString strError; strError.Format(_T("Exception in %hs: %s"), __FUNCTION__, szError); e->Delete(); - delete pSearch; - throw strError; } catch (const CString&) { + delete pSearch; throw; } catch (...) { - CString strError; strError.Format(_T("Unknown exception in %hs"), __FUNCTION__); - delete pSearch; - throw strError; } - return pSearch; + delete pSearch; + throw strError; + //return NULL; } CSearch* CSearchManager::PrepareLookup(uint32 uType, bool bStart, const CUInt128 &uID) @@ -205,17 +197,15 @@ CSearch* CSearchManager::PrepareLookup(uint32 uType, bool bStart, const CUInt128 m_mapSearches[pSearch->m_uTarget] = pSearch; pSearch->Go(); } + return pSearch; } catch (CIOException *ioe) { AddDebugLogLine(false, _T("Exception in CSearchManager::PrepareLookup (IO error(%i))"), ioe->m_iCause); ioe->Delete(); - delete pSearch; - return NULL; } catch (...) { AddDebugLogLine(false, _T("Exception in CSearchManager::PrepareLookup")); - delete pSearch; - return NULL; } - return pSearch; + delete pSearch; + return NULL; } void CSearchManager::FindNode(const CUInt128 &uID, bool bComplete) @@ -242,7 +232,7 @@ bool CSearchManager::IsFWCheckUDPSearch(const CUInt128 &uTarget) return itSearchMap->second->GetSearchType() == CSearch::NODEFWCHECKUDP; } -void CSearchManager::GetWords(LPCWSTR sz, WordList *plistWords) +void CSearchManager::GetWords(LPCWSTR sz, WordList &rlistWords) { size_t uChars = 0; size_t uBytes = 0; @@ -259,16 +249,16 @@ void CSearchManager::GetWords(LPCWSTR sz, WordList *plistWords) uBytes = KadGetKeywordBytes(sWord).GetLength(); if (uBytes >= 3) { KadTagStrMakeLower(sWord); - plistWords->remove(sWord); - plistWords->push_back(sWord); + rlistWords.remove(sWord); + rlistWords.push_back(sWord); } szS += uChars; szS += static_cast(uChars < wcslen(szS)); } // if the last word we have added, contains 3 chars (and 3 bytes), in almost all cases it's a file's extension. - if (plistWords->size() > 1 && (uChars == 3 && uBytes == 3)) - plistWords->pop_back(); + if (rlistWords.size() > 1 && (uChars == 3 && uBytes == 3)) + rlistWords.pop_back(); } void CSearchManager::JumpStart() @@ -328,7 +318,6 @@ void CSearchManager::JumpStart() CKademlia::GetPrefs()->SetPublish(true); } break; - case CSearch::STOREFILE: if (tNow >= pSearch->m_tCreated + SEARCHSTOREFILE_LIFETIME) bDel = true; @@ -425,22 +414,21 @@ void CSearchManager::ProcessPublishResult(const CUInt128 &uTarget, const uint8 u } // Inc the number of answers. - pSearch->m_uAnswers++; + ++pSearch->m_uAnswers; // Update the search for the GUI theApp.emuledlg->kademliawnd->searchList->SearchRef(pSearch); } -void CSearchManager::ProcessResponse(const CUInt128 &uTarget, uint32 uFromIP, uint16 uFromPort, ContactList *plistResults) +void CSearchManager::ProcessResponse(const CUInt128 &uTarget, uint32 uFromIP, uint16 uFromPort, ContactArray &rlistResults) { // We got a response to a kad lookup. SearchMap::const_iterator itSearchMap = m_mapSearches.find(uTarget); if (itSearchMap != m_mapSearches.end() && itSearchMap->second != NULL) - itSearchMap->second->ProcessResponse(uFromIP, uFromPort, plistResults); + itSearchMap->second->ProcessResponse(uFromIP, uFromPort, rlistResults); else { // This search was deleted before this response, delete contacts and abort - for (ContactList::const_iterator itContactList = plistResults->begin(); itContactList != plistResults->end(); ++itContactList) - delete *itContactList; - delete plistResults; + for (ContactArray::const_iterator itContact = rlistResults.begin(); itContact != rlistResults.end(); ++itContact) + delete *itContact; } } @@ -451,25 +439,21 @@ uint8 CSearchManager::GetExpectedResponseContactCount(const CUInt128 &uTarget) return (itSearchMap == m_mapSearches.end()) ? 0 : itSearchMap->second->GetRequestContactCount(); } -void CSearchManager::ProcessResult(const CUInt128 &uTarget, const CUInt128 &uAnswer, TagList *plistInfo, uint32 uFromIP, uint16 uFromPort) +void CSearchManager::ProcessResult(const CUInt128 &uTarget, const CUInt128 &uAnswer, TagList &rlistInfo, uint32 uFromIP, uint16 uFromPort) { // We have results for a request for info. SearchMap::const_iterator itSearchMap = m_mapSearches.find(uTarget); if (itSearchMap != m_mapSearches.end() && itSearchMap->second != NULL) - itSearchMap->second->ProcessResult(uAnswer, plistInfo, uFromIP, uFromPort); - else { - // This search was deleted before these results, delete contacts and abort - for (TagList::const_iterator itTagList = plistInfo->begin(); itTagList != plistInfo->end(); ++itTagList) - delete *itTagList; - delete plistInfo; - } + itSearchMap->second->ProcessResult(uAnswer, rlistInfo, uFromIP, uFromPort); + else // This search was deleted before these results; delete contacts and abort + deleteTagListEntries(rlistInfo); } bool CSearchManager::FindNodeSpecial(const CUInt128 &uID, CKadClientSearcher *pRequester) { // Do a node lookup. CString strDbgID; - uID.ToHexString(&strDbgID); + uID.ToHexString(strDbgID); DebugLog(_T("Starting NODESPECIAL Kad Search for %s"), (LPCTSTR)strDbgID); CSearch *pSearch = new CSearch; pSearch->SetSearchType(CSearch::NODESPECIAL); @@ -490,14 +474,14 @@ bool CSearchManager::FindNodeFWCheckUDP() return StartSearch(pSearch); } -void CSearchManager::CancelNodeSpecial(CKadClientSearcher *pRequester) +void CSearchManager::CancelNodeSpecial(const CKadClientSearcher *pRequester) { // Stop a specific nodespecial search for (SearchMap::const_iterator itSearchMap = m_mapSearches.begin(); itSearchMap != m_mapSearches.end(); ++itSearchMap) { - CSearch *pSearch = itSearchMap->second; - if (pSearch->GetNodeSpecialSearchRequester() == pRequester) { - pSearch->SetNodeSpecialSearchRequester(NULL); - pSearch->PrepareToStop(); + CSearch &Search = *itSearchMap->second; + if (Search.GetNodeSpecialSearchRequester() == pRequester) { + Search.SetNodeSpecialSearchRequester(NULL); + Search.PrepareToStop(); return; } } diff --git a/srchybrid/kademlia/kademlia/SearchManager.h b/srchybrid/kademlia/kademlia/SearchManager.h index 243b4a39..2ed446b3 100644 --- a/srchybrid/kademlia/kademlia/SearchManager.h +++ b/srchybrid/kademlia/kademlia/SearchManager.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,13 +23,14 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ #pragma once #include "kademlia/routing/Maps.h" +#include "kademlia/kademlia/Tag.h" #define INV_KAD_KEYWORD_CHARS " ()[]{}<>,._-!?:;\\/\"" extern LPCSTR g_aszInvKadKeywordCharsA; @@ -38,10 +39,9 @@ extern LPCWSTR g_awszInvKadKeywordChars; namespace Kademlia { - void deleteTagListEntries(TagList *plistTag); - class CRoutingZone; class CKadClientSearcher; + class CSearchManager { friend class CRoutingZone; @@ -56,11 +56,11 @@ namespace Kademlia // Will return unique search id, returns zero if already searching for this keyword. static CSearch* PrepareFindKeywords(LPCWSTR szKeyword, UINT uSearchTermsSize, LPBYTE pucSearchTermsData); static bool StartSearch(CSearch *pSearch); - static void ProcessResponse(const CUInt128 &uTarget, uint32 uFromIP, uint16 uFromPort, ContactList *plistResults); + static void ProcessResponse(const CUInt128 &uTarget, uint32 uFromIP, uint16 uFromPort, ContactArray &rlistResults); static uint8 GetExpectedResponseContactCount(const CUInt128 &uTarget); - static void ProcessResult(const CUInt128 &uTarget, const CUInt128 &uAnswer, TagList *plistInfo, uint32 uFromIP, uint16 uFromPort); + static void ProcessResult(const CUInt128 &uTarget, const CUInt128 &uAnswer, TagList &rlistInfo, uint32 uFromIP, uint16 uFromPort); static void ProcessPublishResult(const CUInt128 &uTarget, const uint8 uLoad, const bool bLoadResponse); - static void GetWords(LPCWSTR sz, WordList *plistWords); + static void GetWords(LPCWSTR sz, WordList &rlistWords); static void UpdateStats(); static bool AlreadySearchingFor(const CUInt128 &uTarget); @@ -71,7 +71,7 @@ namespace Kademlia private: static void FindNode(const CUInt128 &uID, bool bComplete); static bool FindNodeSpecial(const CUInt128 &uID, CKadClientSearcher *pRequester); - static void CancelNodeSpecial(CKadClientSearcher *pRequester); + static void CancelNodeSpecial(const CKadClientSearcher *pRequester); static void JumpStart(); static uint32 m_uNextID; static SearchMap m_mapSearches; diff --git a/srchybrid/kademlia/kademlia/Tag.h b/srchybrid/kademlia/kademlia/Tag.h index ff8e152e..79f77903 100644 --- a/srchybrid/kademlia/kademlia/Tag.h +++ b/srchybrid/kademlia/kademlia/Tag.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -34,16 +34,15 @@ their client on the eMule forum. #include "otherfunctions.h" #include "kademlia/routing/Maps.h" -// forward declarations namespace Kademlia { + // forward declarations class CKadTagValueString; -} -void KadTagStrMakeLower(Kademlia::CKadTagValueString &rwstr); -int KadTagStrCompareNoCase(LPCWSTR dst, LPCWSTR src) noexcept; -namespace Kademlia -{ + void deleteTagListEntries(TagList &rTaglist); + void KadTagStrMakeLower(Kademlia::CKadTagValueString &rwstr); + bool EqualKadTagStr(LPCWSTR dst, LPCWSTR src) noexcept; + class CKadTagNameString : protected CStringA { public: @@ -59,10 +58,8 @@ namespace Kademlia { } - ~CKadTagNameString() = default; - // A tag name may include character values >= 0xD0 and also >= 0xF0. to prevent those - // characters to be interpreted as multibyte character sequences we have to ensure that a binary + // characters to be interpreted as multi-byte character sequences we have to ensure that a binary // string compare is performed. int Compare(LPCSTR psz) const noexcept { @@ -84,6 +81,11 @@ namespace Kademlia return __ascii_stricmp(GetString(), psz); } + friend bool operator==(const CKadTagNameString& str1, LPCSTR const psz2) noexcept + { + return (str1.Compare(psz2) == 0); + } + CKadTagNameString& operator=(LPCSTR pszSrc) { CStringA::operator=(pszSrc); @@ -97,7 +99,7 @@ namespace Kademlia XCHAR operator[](int iChar) const noexcept { - return CStringA::operator [](iChar); + return CStringA::operator[](iChar); } PXSTR GetBuffer() @@ -135,13 +137,11 @@ namespace Kademlia : CStringW(psz, iLen) { } - - ~CKadTagValueString() = default; - int CompareNoCase(LPCWSTR src) const noexcept + /*bool EqualNoCase(LPCWSTR src) const noexcept //unused { - return KadTagStrCompareNoCase(GetString(), src); - } + return EqualKadTagStr(GetString(), src); + }*/ int Collate(PCXSTR psz) const noexcept { @@ -185,7 +185,7 @@ namespace Kademlia } virtual ~CKadTag() = default; - virtual CKadTag* Copy() = 0; + virtual CKadTag* Copy() const = 0; bool IsStr() const { @@ -236,37 +236,37 @@ namespace Kademlia virtual CKadTagValueString GetStr() const { - ASSERT(0); + ASSERT(0); //requires implementation return CKadTagValueString(); } virtual uint64 GetInt() const { - ASSERT(0); + ASSERT(0); //requires implementation return 0; } virtual float GetFloat() const { - ASSERT(0); + ASSERT(0); //requires implementation return 0.0F; } virtual const BYTE* GetBsob() const { - ASSERT(0); + ASSERT(0); //requires implementation return NULL; } virtual uint8 GetBsobSize() const { - ASSERT(0); + ASSERT(0); //requires implementation return 0; } virtual bool GetBool() const { - ASSERT(0); + ASSERT(0); //requires implementation return false; } virtual const BYTE* GetHash() const { - ASSERT(0); + ASSERT(0); //requires implementation return NULL; } @@ -292,7 +292,7 @@ namespace Kademlia { } - virtual CKadTagStr* Copy() + virtual CKadTagStr* Copy() const { return new CKadTagStr(m_name, m_value); } @@ -314,7 +314,7 @@ namespace Kademlia { } - virtual CKadTagUInt* Copy() + virtual CKadTagUInt* Copy() const { return new CKadTagUInt(m_name, m_value); } @@ -336,7 +336,7 @@ namespace Kademlia { } - virtual CKadTagUInt64* Copy() + virtual CKadTagUInt64* Copy() const { return new CKadTagUInt64(m_name, m_value); } @@ -359,7 +359,7 @@ namespace Kademlia { } - virtual CKadTagUInt32* Copy() + virtual CKadTagUInt32* Copy() const { return new CKadTagUInt32(m_name, m_value); } @@ -382,7 +382,7 @@ namespace Kademlia { } - virtual CKadTagFloat* Copy() + virtual CKadTagFloat* Copy() const { return new CKadTagFloat(m_name, m_value); } @@ -405,7 +405,7 @@ namespace Kademlia { } - virtual CKadTagBool* Copy() + virtual CKadTagBool* Copy() const { return new CKadTagBool(m_name, m_value); } @@ -429,7 +429,7 @@ namespace Kademlia { } - virtual CKadTagUInt16* Copy() + virtual CKadTagUInt16* Copy() const { return new CKadTagUInt16(m_name, m_value); } @@ -453,7 +453,7 @@ namespace Kademlia { } - virtual CKadTagUInt8* Copy() + virtual CKadTagUInt8* Copy() const { return new CKadTagUInt8(m_name, m_value); } @@ -487,7 +487,7 @@ namespace Kademlia CKadTagBsob(const CKadTagBsob&) = delete; CKadTagBsob& operator=(const CKadTagBsob&) = delete; - virtual CKadTagBsob* Copy() + virtual CKadTagBsob* Copy() const { return new CKadTagBsob(m_name, m_value, m_size); } @@ -525,7 +525,7 @@ namespace Kademlia CKadTagHash(const CKadTagHash&) = delete; CKadTagHash& operator=(const CKadTagHash&) = delete; - virtual CKadTagHash* Copy() + virtual CKadTagHash* Copy() const { return new CKadTagHash(m_name, m_value); } diff --git a/srchybrid/kademlia/kademlia/UDPFirewallTester.cpp b/srchybrid/kademlia/kademlia/UDPFirewallTester.cpp index 264bdc62..c9a9d99f 100644 --- a/srchybrid/kademlia/kademlia/UDPFirewallTester.cpp +++ b/srchybrid/kademlia/kademlia/UDPFirewallTester.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -44,8 +44,8 @@ bool CUDPFirewallTester::m_bNodeSearchStarted = false; bool CUDPFirewallTester::m_bTimedOut = false; uint8 CUDPFirewallTester::m_byFWChecksRunningUDP = 0; uint8 CUDPFirewallTester::m_byFWChecksFinishedUDP = 0; -uint32 CUDPFirewallTester::m_dwTestStart = 0; -uint32 CUDPFirewallTester::m_dwLastSucceededTime = 0; +DWORD CUDPFirewallTester::m_dwTestStart = 0; +DWORD CUDPFirewallTester::m_dwLastSucceededTime = 0; CList CUDPFirewallTester::m_liPossibleTestClients; CList CUDPFirewallTester::m_liUsedTestClients; @@ -71,8 +71,9 @@ bool CUDPFirewallTester::IsFirewalledUDP(bool bLastStateIfTesting) return (bLastStateIfTesting && bCheckingFW) ? m_bFirewalledLastStateUDP : m_bFirewalledUDP; } +// are we in search for test clients bool CUDPFirewallTester::GetUDPCheckClientsNeeded() -{ // are we in search for testclients +{ return (m_byFWChecksRunningUDP + m_byFWChecksFinishedUDP) < UDP_FIREWALLTEST_CLIENTSTOASK; } @@ -82,16 +83,17 @@ void CUDPFirewallTester::SetUDPFWCheckResult(bool bSucceeded, bool bTestCancelle return; // see if we actually requested a firewall check from this client bool bRequested = false; + const DWORD curTick = ::GetTickCount(); for (POSITION pos = m_liUsedTestClients.GetHeadPosition(); pos != NULL;) { UsedClient_Struct &ucs = m_liUsedTestClients.GetNext(pos); if (ucs.contact.GetIPAddress() == uFromIP) { - if (!IsFWCheckUDPRunning() && !m_bFirewalledUDP && m_bIsFWVerifiedUDP && ::GetTickCount() < m_dwLastSucceededTime + SEC2MS(10) + if (!IsFWCheckUDPRunning() && !m_bFirewalledUDP && m_bIsFWVerifiedUDP && curTick < m_dwLastSucceededTime + SEC2MS(10) && nIncomingPort == CKademlia::GetPrefs()->GetInternKadPort() && CKademlia::GetPrefs()->GetUseExternKadPort()) { // our test finished already in the last 10 seconds with being open because we received a proper result packet before // however we now receive another answer packet on our incoming port (which is not unusual as both result packets are sent - // nearly at the same time and UDP doesn't cares if the order stays), while the one before was received on our extern port + // nearly at the same time and UDP doesn't care if the order stays), while the one before was received on our extern port // Because a proper forwarded intern port is more reliable to stay open, than an extern port set by the NAT, we prefer // intern ports and change the setting. CKademlia::GetPrefs()->SetUseExternKadPort(false); @@ -132,7 +134,7 @@ void CUDPFirewallTester::SetUDPFWCheckResult(bool bSucceeded, bool bTestCancelle m_byFWChecksFinishedUDP = UDP_FIREWALLTEST_CLIENTSTOASK; // don't do any more tests m_byFWChecksRunningUDP = 0; // all other tests are cancelled m_liPossibleTestClients.RemoveAll(); // clear list, keep used clients list through - m_dwLastSucceededTime = ::GetTickCount(); // for delayed results, see above + m_dwLastSucceededTime = curTick; // for delayed results, see above CSearchManager::CancelNodeFWCheckUDPSearch(); // cancel firewall node searches if any are still active // if this packet came to our internal port, explicitly set the internal port as used port from now on if (nIncomingPort == CKademlia::GetPrefs()->GetInternKadPort()) { diff --git a/srchybrid/kademlia/kademlia/UDPFirewallTester.h b/srchybrid/kademlia/kademlia/UDPFirewallTester.h index 32c31ab3..bd5cd38f 100644 --- a/srchybrid/kademlia/kademlia/UDPFirewallTester.h +++ b/srchybrid/kademlia/kademlia/UDPFirewallTester.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -50,8 +50,8 @@ namespace Kademlia static bool m_bTimedOut; static uint8 m_byFWChecksRunningUDP; static uint8 m_byFWChecksFinishedUDP; - static uint32 m_dwTestStart; - static uint32 m_dwLastSucceededTime; + static DWORD m_dwTestStart; + static DWORD m_dwLastSucceededTime; static CList m_liPossibleTestClients; static CList m_liUsedTestClients; }; diff --git a/srchybrid/kademlia/net/KademliaUDPListener.cpp b/srchybrid/kademlia/net/KademliaUDPListener.cpp index 3b0cefe1..0e4a892b 100644 --- a/srchybrid/kademlia/net/KademliaUDPListener.cpp +++ b/srchybrid/kademlia/net/KademliaUDPListener.cpp @@ -1,6 +1,6 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) -Copyright (C)2007-2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) +Copyright (C)2007-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) This program is free software; you can redistribute it and/or @@ -25,7 +25,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -99,7 +99,7 @@ void CKademliaUDPListener::Bootstrap(uint32 uIP, uint16 uUDPPort, uint8 byKadVer if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_BOOTSTRAP_REQ", uIP, uUDPPort); CSafeMemFile fileIO(0); - SendPacket(&fileIO, KADEMLIA2_BOOTSTRAP_REQ, uIP, uUDPPort, CKadUDPKey() + SendPacket(fileIO, KADEMLIA2_BOOTSTRAP_REQ, uIP, uUDPPort, CKadUDPKey() , (byKadVersion >= KADEMLIA_VERSION6_49aBETA) ? uCryptTargetID : NULL); } @@ -124,11 +124,12 @@ void CKademliaUDPListener::SendMyDetails(byte byOpcode, uint32 uIP, uint16 uUDPP } byteIOResponse.WriteUInt8(byTagCount); if (!CKademlia::GetPrefs()->GetUseExternKadPort()) - byteIOResponse.WriteTag(&CKadTagUInt16(TAG_SOURCEUPORT, CKademlia::GetPrefs()->GetInternKadPort())); + byteIOResponse.WriteTag(CKadTagUInt16(TAG_SOURCEUPORT, CKademlia::GetPrefs()->GetInternKadPort())); + if (byKadVersion >= KADEMLIA_VERSION8_49b && (bRequestAckPackage || CKademlia::GetPrefs()->GetFirewalled() || CUDPFirewallTester::IsFirewalledUDP(true))) { - // if we are firewalled we sent this tag, so the other client doesn't adds us to his routing table (if UDP firewalled) and for statistics reasons (TCP firewalled) + // if we are firewalled we sent this tag, so the other client doesn't add us to his routing table (if UDP firewalled) and for statistics reasons (TCP firewalled) // 5 - reserved (!) // 1 - Requesting HELLO_RES_ACK // 1 - TCP firewalled @@ -137,12 +138,12 @@ void CKademliaUDPListener::SendMyDetails(byte byOpcode, uint32 uIP, uint16 uUDPP const uint8 uTCPFirewalled = static_cast(CKademlia::GetPrefs()->GetFirewalled()); const uint8 uRequestACK = static_cast(bRequestAckPackage); const uint8 byMiscOptions = (uRequestACK << 2) | (uTCPFirewalled << 1) | (uUDPFirewalled << 0); - byteIOResponse.WriteTag(&CKadTagUInt8(TAG_KADMISCOPTIONS, byMiscOptions)); + byteIOResponse.WriteTag(CKadTagUInt8(TAG_KADMISCOPTIONS, byMiscOptions)); } //byteIOResponse.WriteTag(&CKadTagUInt(TAG_USER_COUNT, CKademlia::GetPrefs()->GetKademliaUsers())); //byteIOResponse.WriteTag(&CKadTagUInt(TAG_FILE_COUNT, CKademlia::GetPrefs()->GetKademliaFiles())); - uint32 uLen = (sizeof byPacket) - byteIOResponse.GetAvailable(); + uint32 uLen = (uint32)(sizeof byPacket - byteIOResponse.GetAvailable()); if (byKadVersion >= KADEMLIA_VERSION6_49aBETA) { if (uCryptTargetID && isnulmd4(uCryptTargetID->GetDataPtr())) { DebugLogWarning(_T("Sending hello response to crypt enabled Kad Node which provided an empty NodeID: %s (%u)"), (LPCTSTR)ipstr(htonl(uIP)), byKadVersion); @@ -155,7 +156,7 @@ void CKademliaUDPListener::SendMyDetails(byte byOpcode, uint32 uIP, uint16 uUDPP } } //else - // ASSERT( false ); + // ASSERT(0); } // Kad1.0 & Kad2.0 currently. @@ -165,17 +166,17 @@ void CKademliaUDPListener::FirewalledCheck(uint32 uIP, uint16 uUDPPort, const CK // new Opcode since 0.49a with extended informations to support obfuscated connections properly CSafeMemFile fileIO(19); fileIO.WriteUInt16(thePrefs.GetPort()); - fileIO.WriteUInt128(&CKademlia::GetPrefs()->GetClientHash()); + fileIO.WriteUInt128(CKademlia::GetPrefs()->GetClientHash()); fileIO.WriteUInt8(CKademlia::GetPrefs()->GetMyConnectOptions(true, false)); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA_FIREWALLED2_REQ", uIP, uUDPPort); - SendPacket(&fileIO, KADEMLIA_FIREWALLED2_REQ, uIP, uUDPPort, senderUDPKey, NULL); + SendPacket(fileIO, KADEMLIA_FIREWALLED2_REQ, uIP, uUDPPort, senderUDPKey, NULL); } else { CSafeMemFile fileIO(2); fileIO.WriteUInt16(thePrefs.GetPort()); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA_FIREWALLED_REQ", uIP, uUDPPort); - SendPacket(&fileIO, KADEMLIA_FIREWALLED_REQ, uIP, uUDPPort, senderUDPKey, NULL); + SendPacket(fileIO, KADEMLIA_FIREWALLED_REQ, uIP, uUDPPort, senderUDPKey, NULL); } theApp.clientlist->AddKadFirewallRequest(ntohl(uIP)); } @@ -183,33 +184,32 @@ void CKademliaUDPListener::FirewalledCheck(uint32 uIP, uint16 uUDPPort, const CK void CKademliaUDPListener::SendNullPacket(byte byOpcode, uint32 uIP, uint16 uUDPPort, const CKadUDPKey &targetUDPKey, const CUInt128 *uCryptTargetID) { CSafeMemFile fileIO(0); - SendPacket(&fileIO, byOpcode, uIP, uUDPPort, targetUDPKey, uCryptTargetID); + SendPacket(fileIO, byOpcode, uIP, uUDPPort, targetUDPKey, uCryptTargetID); } void CKademliaUDPListener::SendPublishSourcePacket(CContact *pContact, const CUInt128 &uTargetID, const CUInt128 &uContactID, const TagList &tags) { //We need to get the tag lists working with CSafeMemFiles. + LPCSTR pszOper; byte byPacket[1024]; CByteIO byteIO(byPacket, sizeof byPacket); byteIO.WriteByte(OP_KADEMLIAHEADER); if (pContact->GetVersion() >= KADEMLIA_VERSION4_47c) { + pszOper = "KADEMLIA2_PUBLISH_SOURCE_REQ"; byteIO.WriteByte(KADEMLIA2_PUBLISH_SOURCE_REQ); byteIO.WriteUInt128(uTargetID); - byteIO.WriteUInt128(uContactID); - byteIO.WriteTagList(tags); - if (thePrefs.GetDebugClientKadUDPLevel() > 0) - DebugSend("KADEMLIA2_PUBLISH_SOURCE_REQ", pContact->GetIPAddress(), pContact->GetUDPPort()); } else { + pszOper = "KADEMLIA_PUBLISH_REQ"; byteIO.WriteByte(KADEMLIA_PUBLISH_REQ); byteIO.WriteUInt128(uTargetID); //We only use this for publishing sources now. So we always send one here. byteIO.WriteUInt16(1); - byteIO.WriteUInt128(uContactID); - byteIO.WriteTagList(tags); - if (thePrefs.GetDebugClientKadUDPLevel() > 0) - DebugSend("KADEMLIA_PUBLISH_REQ", pContact->GetIPAddress(), pContact->GetUDPPort()); } - uint32 uLen = (sizeof byPacket) - byteIO.GetAvailable(); + byteIO.WriteUInt128(uContactID); + byteIO.WriteTagList(tags); + if (thePrefs.GetDebugClientKadUDPLevel() > 0) + DebugSend(pszOper, pContact->GetIPAddress(), pContact->GetUDPPort()); + uint32 uLen = (uint32)(sizeof byPacket - byteIO.GetAvailable()); if (pContact->GetVersion() >= KADEMLIA_VERSION6_49aBETA) { // obfuscated? CUInt128 uClientID = pContact->GetClientID(); SendPacket(byPacket, uLen, pContact->GetIPAddress(), pContact->GetUDPPort(), pContact->GetUDPKey(), &uClientID); @@ -423,7 +423,7 @@ bool CKademliaUDPListener::AddContact_KADEMLIA2(const byte *pbyData, uint32 uLen CByteIO byteIO(pbyData, uLenData); CUInt128 uID; - byteIO.ReadUInt128(&uID); + byteIO.ReadUInt128(uID); if (puOutContactID != NULL) *puOutContactID = uID; uint16 uTCPPort = byteIO.ReadUInt16(); @@ -463,7 +463,7 @@ bool CKademliaUDPListener::AddContact_KADEMLIA2(const byte *pbyData, uint32 uLen const FetchNodeID_Struct &fnode = listFetchNodeIDRequests.GetNext(pos); if (fnode.dwIP == uIP && fnode.dwTCPPort == uTCPPort) { CString strID; - uID.ToHexString(&strID); + uID.ToHexString(strID); DebugLog(_T("Result Addcontact: %s"), (LPCTSTR)strID); uchar uchID[16]; uID.ToByteArray(uchID); @@ -476,7 +476,7 @@ bool CKademliaUDPListener::AddContact_KADEMLIA2(const byte *pbyData, uint32 uLen if (bFromHelloReq && uVersion >= KADEMLIA_VERSION8_49b) { // This is just for statistic calculations. We try to determine the ratio of (UDP) firewalled users, // by counting how many of all nodes, which have us in their routing table (our own routing table is supposed - // to have no UDP firewalled nodes at all) and support the firewalled tag, are firewalled themself. + // to have no UDP firewalled nodes at all) and support the firewalled tag, are firewalled themselves. // Obviously this only works if we are not firewalled ourselves CKademlia::GetPrefs()->StatsIncUDPFirewalledNodes(bUDPFirewalled); CKademlia::GetPrefs()->StatsIncTCPFirewalledNodes(bTCPFirewalled); @@ -493,34 +493,34 @@ bool CKademliaUDPListener::AddContact_KADEMLIA2(const byte *pbyData, uint32 uLen void CKademliaUDPListener::Process_KADEMLIA2_BOOTSTRAP_REQ(uint32 uIP, uint16 uUDPPort, const CKadUDPKey &senderUDPKey) { // Get some contacts to return - ContactList contacts; - uint16 uNumContacts = (uint16)CKademlia::GetRoutingZone()->GetBootstrapContacts(&contacts, 20); + ContactArray contacts; + uint16 uNumContacts = (uint16)CKademlia::GetRoutingZone()->GetBootstrapContacts(contacts, 20); // Create response packet //We only collect a max of 20 contacts here. Max size is 521. //2 + 25*20 + 19 CSafeMemFile fileIO(521); - fileIO.WriteUInt128(&CKademlia::GetPrefs()->GetKadID()); + fileIO.WriteUInt128(CKademlia::GetPrefs()->GetKadID()); fileIO.WriteUInt16(thePrefs.GetPort()); fileIO.WriteUInt8(KADEMLIA_VERSION); // Write packet info fileIO.WriteUInt16(uNumContacts); - for (ContactList::const_iterator iContactList = contacts.begin(); iContactList != contacts.end(); ++iContactList) { - CContact *pContact = *iContactList; - fileIO.WriteUInt128(&pContact->GetClientID()); - fileIO.WriteUInt32(pContact->GetIPAddress()); - fileIO.WriteUInt16(pContact->GetUDPPort()); - fileIO.WriteUInt16(pContact->GetTCPPort()); - fileIO.WriteUInt8(pContact->GetVersion()); + for (ContactArray::const_iterator itContact = contacts.begin(); itContact != contacts.end(); ++itContact) { + const CContact &rContact(**itContact); + fileIO.WriteUInt128(rContact.GetClientID()); + fileIO.WriteUInt32(rContact.GetIPAddress()); + fileIO.WriteUInt16(rContact.GetUDPPort()); + fileIO.WriteUInt16(rContact.GetTCPPort()); + fileIO.WriteUInt8(rContact.GetVersion()); } // Send response if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_BOOTSTRAP_RES", uIP, uUDPPort); - SendPacket(&fileIO, KADEMLIA2_BOOTSTRAP_RES, uIP, uUDPPort, senderUDPKey, NULL); + SendPacket(fileIO, KADEMLIA2_BOOTSTRAP_RES, uIP, uUDPPort, senderUDPKey, NULL); } // Used only for Kad2.0 @@ -536,7 +536,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_BOOTSTRAP_RES(const byte *pbyPacket // How many contacts were given CSafeMemFile fileIO(pbyPacketData, uLenPacket); CUInt128 uContactID; - fileIO.ReadUInt128(&uContactID); + fileIO.ReadUInt128(uContactID); uint16 uTCPPort = fileIO.ReadUInt16(); uint8 uVersion = fileIO.ReadUInt8(); // If we don't know any Contacts yet and try to Bootstrap, we assume that all contacts are verified, @@ -550,7 +550,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_BOOTSTRAP_RES(const byte *pbyPacket DEBUG_ONLY(AddDebugLogLine(DLP_LOW, false, _T("Inc Kad2 Bootstrap Packet from %s"), (LPCTSTR)ipstr(htonl(uIP)))); for (unsigned uNumContacts = fileIO.ReadUInt16(); uNumContacts > 0; --uNumContacts) { - fileIO.ReadUInt128(&uContactID); + fileIO.ReadUInt128(uContactID); uIP = fileIO.ReadUInt32(); uUDPPort = fileIO.ReadUInt16(); uTCPPort = fileIO.ReadUInt16(); @@ -576,7 +576,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_HELLO_REQ(const byte *pbyPacketData SendMyDetails(KADEMLIA2_HELLO_RES, uIP, uUDPPort, byContactVersion, senderUDPKey, &uContactID, bAddedOrUpdated && !bValidReceiverKey); if (bAddedOrUpdated && !bValidReceiverKey && byContactVersion == KADEMLIA_VERSION7_49a && !HasActiveLegacyChallenge(uIP)) { - // Kad Version 7 doesn't supports HELLO_RES_ACK, but sender/receiver keys, so send a ping to validate + // Kad Version 7 doesn't support HELLO_RES_ACK, but sender/receiver keys, so send a ping to validate AddLegacyChallenge(uContactID, CUInt128(0ul), uIP, KADEMLIA2_PING); SendNullPacket(KADEMLIA2_PING, uIP, uUDPPort, senderUDPKey, NULL); #ifdef _DEBUG @@ -620,7 +620,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_HELLO_RES_ACK(const byte *pbyPacket // additional packet to complete a three-way-handshake, making sure the remote contact is not using a spoofed IP CSafeMemFile fileIO(pbyPacketData, uLenPacket); CUInt128 uRemoteID; - fileIO.ReadUInt128(&uRemoteID); + fileIO.ReadUInt128(uRemoteID); if (!CKademlia::GetRoutingZone()->VerifyContact(uRemoteID, uIP)) DebugLogWarning(_T("Kad: Process_KADEMLIA2_HELLO_RES_ACK: Unable to find valid sender in routing table (sender: %s)"), (LPCTSTR)ipstr(htonl(uIP))); //else @@ -652,11 +652,11 @@ void CKademliaUDPListener::Process_KADEMLIA2_HELLO_RES(const byte *pbyPacketData } else { CSafeMemFile fileIO(17); CUInt128 uID(CKademlia::GetPrefs()->GetKadID()); - fileIO.WriteUInt128(&uID); + fileIO.WriteUInt128(uID); fileIO.WriteUInt8(0); // no tags at this time if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_HELLO_RES_ACK", uIP, uUDPPort); - SendPacket(&fileIO, KADEMLIA2_HELLO_RES_ACK, uIP, uUDPPort, senderUDPKey, NULL); + SendPacket(fileIO, KADEMLIA2_HELLO_RES_ACK, uIP, uUDPPort, senderUDPKey, NULL); //DEBUG_ONLY( AddDebugLogLine(DLP_LOW, false, _T("Sent HELLO_RES_ACK to %s"), (LPCTSTR)ipstr(htonl(uIP))) ); } } else if (bAddedOrUpdated && !bValidReceiverKey && byContactVersion < KADEMLIA_VERSION7_49a) { @@ -691,31 +691,31 @@ void CKademliaUDPListener::Process_KADEMLIA2_REQ(const byte *pbyPacketData, uint //This is the target node trying to be found. CUInt128 uTarget; - fileIO.ReadUInt128(&uTarget); + fileIO.ReadUInt128(uTarget); //Convert Target to Distance as this is how we store contacts. CUInt128 uDistance(CKademlia::GetPrefs()->GetKadID()); uDistance.Xor(uTarget); //This makes sure we are not mistaken identify. Some client may have fresh installed and have a new KadID. CUInt128 uCheck; - fileIO.ReadUInt128(&uCheck); + fileIO.ReadUInt128(uCheck); if (CKademlia::GetPrefs()->GetKadID() == uCheck) { // Get required number closest to target ContactMap results; - CKademlia::GetRoutingZone()->GetClosestTo(2, uTarget, uDistance, (uint32)byType, &results); + CKademlia::GetRoutingZone()->GetClosestTo(2, uTarget, uDistance, (uint32)byType, results); uint8 uCount = static_cast(results.size()); // Write response // Max count is 32, size 817. // 16 + 1 + 25*32 CSafeMemFile fileIO2(817); - fileIO2.WriteUInt128(&uTarget); + fileIO2.WriteUInt128(uTarget); fileIO2.WriteUInt8(uCount); for (ContactMap::const_iterator itContactMap = results.begin(); itContactMap != results.end(); ++itContactMap) { CUInt128 uID; CContact *pContact = itContactMap->second; - pContact->GetClientID(&uID); - fileIO2.WriteUInt128(&uID); + pContact->GetClientID(uID); + fileIO2.WriteUInt128(uID); fileIO2.WriteUInt32(pContact->GetIPAddress()); fileIO2.WriteUInt16(pContact->GetUDPPort()); fileIO2.WriteUInt16(pContact->GetTCPPort()); @@ -725,7 +725,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_REQ(const byte *pbyPacketData, uint if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSendF("KADEMLIA2_RES", uIP, uUDPPort, _T("Count=%u"), uCount); - SendPacket(&fileIO2, KADEMLIA2_RES, uIP, uUDPPort, senderUDPKey, NULL); + SendPacket(fileIO2, KADEMLIA2_RES, uIP, uUDPPort, senderUDPKey, NULL); } } @@ -753,7 +753,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_RES(const byte *pbyPacketData, uint // What search does this relate to CSafeMemFile fileIO(pbyPacketData, uLenPacket); CUInt128 uTarget; - fileIO.ReadUInt128(&uTarget); + fileIO.ReadUInt128(uTarget); uint8 uNumContacts = fileIO.ReadUInt8(); // is this one of our legacy challenge packets? @@ -790,12 +790,12 @@ void CKademliaUDPListener::Process_KADEMLIA2_RES(const byte *pbyPacketData, uint if (CUDPFirewallTester::IsFWCheckUDPRunning() && CSearchManager::IsFWCheckUDPSearch(uTarget)) bIsFirewallUDPCheckSearch = true; - uint32 nIgnoredCount = 0; - ContactList *pResults = new ContactList; + ContactArray cResults; CUInt128 uIDResult; + uint32 nIgnoredCount = 0; try { for (uint8 iIndex = 0; iIndex < uNumContacts; ++iIndex) { - fileIO.ReadUInt128(&uIDResult); + fileIO.ReadUInt128(uIDResult); uint32 uIPResult = fileIO.ReadUInt32(); uint16 uUDPPortResult = fileIO.ReadUInt16(); uint16 uTCPPortResult = fileIO.ReadUInt16(); @@ -807,7 +807,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_RES(const byte *pbyPacketData, uint if (bIsFirewallUDPCheckSearch) { // UDP FirewallCheck searches are special. The point is we need an IP which we didn't send a UDP message yet // (or in the near future), so we do not try to add those contacts to our routing zone, and we also don't - // deliver them back to the search manager (because he would UDP-ask them for further results), but only report + // deliver them back to the search manager (because it would UDP-ask them for further results), but only report // them to FirewallCheck - this will of course cripple the search but that's not the point, since we only // care for IPs and not the randomly set target CUDPFirewallTester::AddPossibleTestContact(uIDResult, uIPResult, uUDPPortResult, uTCPPortResult, uTarget, uVersion, CKadUDPKey(), false); @@ -816,7 +816,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_RES(const byte *pbyPacketData, uint bool bWasAdded = pRoutingZone->AddUnfiltered(uIDResult, uIPResult, uUDPPortResult, uTCPPortResult, uVersion, CKadUDPKey(), bVerified, false, false, false); CContact *pTemp = new CContact(uIDResult, uIPResult, uUDPPortResult, uTCPPortResult, uTarget, uVersion, CKadUDPKey(), false); if (bWasAdded || pRoutingZone->IsAcceptableContact(pTemp)) - pResults->push_back(pTemp); + cResults.push_back(pTemp); else { ++nIgnoredCount; delete pTemp; @@ -831,14 +831,13 @@ void CKademliaUDPListener::Process_KADEMLIA2_RES(const byte *pbyPacketData, uint } } } catch (...) { - for (ContactList::const_iterator it = pResults->begin(); it != pResults->end(); ++it) - delete *it; - delete pResults; + for (ContactArray::const_iterator itContact = cResults.begin(); itContact != cResults.end(); ++itContact) + delete *itContact; throw; } if (nIgnoredCount > 0) DebugLogWarning(_T("Ignored %u bad contacts in routing answer from %s"), nIgnoredCount, (LPCTSTR)ipstr(htonl(uIP))); - CSearchManager::ProcessResponse(uTarget, uIP, uUDPPort, pResults); + CSearchManager::ProcessResponse(uTarget, uIP, uUDPPort, cResults); } void CKademliaUDPListener::Free(SSearchTerm *pSearchTerms) @@ -855,13 +854,13 @@ void CKademliaUDPListener::Free(SSearchTerm *pSearchTerms) static void TokenizeOptQuotedSearchTerm(LPCTSTR pszString, CStringWArray *lst) { for (LPCTSTR pch = pszString; *pch != _T('\0');) { - if (*pch == _T('\"')) { + if (*pch == _T('"')) { // Start of quoted string found. If there is no terminating quote character found, // the start quote character is just skipped. If the quoted string is empty, no // new entry is added to 'list'. // ++pch; - LPCTSTR pchNextQuote = _tcschr(pch, _T('\"')); + LPCTSTR pchNextQuote = _tcschr(pch, _T('"')); if (pchNextQuote) { size_t nLenQuoted = pchNextQuote - pch; if (nLenQuoted) @@ -877,7 +876,7 @@ static void TokenizeOptQuotedSearchTerm(LPCTSTR pszString, CStringWArray *lst) pch += nNextDelimiter; if (*pch == _T('\0')) break; - if (*pch == _T('\"')) + if (*pch == _T('"')) continue; } ++pch; @@ -1061,7 +1060,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_SEARCH_KEY_REQ(const byte *pbyPacke { CSafeMemFile fileIO(pbyPacketData, uLenPacket); CUInt128 uTarget; - fileIO.ReadUInt128(&uTarget); + fileIO.ReadUInt128(uTarget); uint16 uStartPosition = fileIO.ReadUInt16(); bool uRestrictive = ((uStartPosition & 0x8000) != 0); uStartPosition &= 0x7FFF; @@ -1084,7 +1083,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_SEARCH_KEY_REQ(const byte *pbyPacke throw; } if (pSearchTerms == NULL) - throw CString(_T("Invalid search expression")); + throwCStr(_T("Invalid search expression")); } CKademlia::GetIndexed()->SendValidKeywordResult(uTarget, pSearchTerms, uIP, uUDPPort, false, uStartPosition, senderUDPKey); Free(pSearchTerms); @@ -1095,7 +1094,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_SEARCH_SOURCE_REQ(const byte *pbyPa { CSafeMemFile fileIO(pbyPacketData, uLenPacket); CUInt128 uTarget; - fileIO.ReadUInt128(&uTarget); + fileIO.ReadUInt128(uTarget); uint16 uStartPosition = (fileIO.ReadUInt16() & 0x7FFF); uint64 uFileSize = fileIO.ReadUInt64(); CKademlia::GetIndexed()->SendValidSourceResult(uTarget, uIP, uUDPPort, uStartPosition, uFileSize, senderUDPKey); @@ -1114,13 +1113,13 @@ void CKademliaUDPListener::Process_KADEMLIA_SEARCH_RES(const byte *pbyPacketData // What search does this relate to CByteIO byteIO(pbyPacketData, uLenPacket); CUInt128 uTarget; - byteIO.ReadUInt128(&uTarget); + byteIO.ReadUInt128(uTarget); // How many results. Not supported yet. CUInt128 uAnswer; for (unsigned uCount = byteIO.ReadUInt16(); uCount > 0; --uCount) { // What is the answer - byteIO.ReadUInt128(&uAnswer); + byteIO.ReadUInt128(uAnswer); // Get info about answer // NOTE: this is the one and only place in Kad where we allow string conversion to local code page in @@ -1128,18 +1127,15 @@ void CKademliaUDPListener::Process_KADEMLIA_SEARCH_RES(const byte *pbyPacketData // supposed to be 'viewed' by user only and not fed into the Kad engine again! // If that tag list is once used for something else than for viewing, special care has to be taken for any // string conversion! - TagList *pTags = NULL; + TagList lTags; try { - pTags = new TagList; - byteIO.ReadTagList(pTags, true); + byteIO.ReadTagList(lTags, true); } catch (...) { - if (pTags) { - deleteTagListEntries(pTags); - delete pTags; - } + deleteTagListEntries(lTags); throw; } - CSearchManager::ProcessResult(uTarget, uAnswer, pTags, uIP, uUDPPort); + CSearchManager::ProcessResult(uTarget, uAnswer, lTags, uIP, uUDPPort); + deleteTagListEntries(lTags); } } @@ -1150,17 +1146,17 @@ void CKademliaUDPListener::Process_KADEMLIA2_SEARCH_RES(const byte *pbyPacketDat // Who sent this packet. CUInt128 uSource; - byteIO.ReadUInt128(&uSource); + byteIO.ReadUInt128(uSource); // What search does this relate to CUInt128 uTarget; - byteIO.ReadUInt128(&uTarget); + byteIO.ReadUInt128(uTarget); // Total results. CUInt128 uAnswer; for (unsigned uCount = byteIO.ReadUInt16(); uCount > 0; --uCount) { // What is the answer - byteIO.ReadUInt128(&uAnswer); + byteIO.ReadUInt128(uAnswer); // Get info about answer // NOTE: this is the one and only place in Kad where we allow string conversion to local code page in @@ -1168,18 +1164,15 @@ void CKademliaUDPListener::Process_KADEMLIA2_SEARCH_RES(const byte *pbyPacketDat // supposed to be 'viewed' by user only and not feed into the Kad engine again! // If that tag list is once used for something else than for viewing, special care has to be taken for any // string conversion! - TagList *pTags = NULL; + TagList lTags; try { - pTags = new TagList; - byteIO.ReadTagList(pTags, true); + byteIO.ReadTagList(lTags, true); } catch (...) { - if (pTags) { - deleteTagListEntries(pTags); - delete pTags; - } + deleteTagListEntries(lTags); throw; } - CSearchManager::ProcessResult(uTarget, uAnswer, pTags, uIP, uUDPPort); + CSearchManager::ProcessResult(uTarget, uAnswer, lTags, uIP, uUDPPort); + deleteTagListEntries(lTags); } } @@ -1193,7 +1186,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_PUBLISH_KEY_REQ(const byte *pbyPack CByteIO byteIO(pbyPacketData, uLenPacket); CUInt128 uFile; - byteIO.ReadUInt128(&uFile); + byteIO.ReadUInt128(uFile); CUInt128 uDistance(CKademlia::GetPrefs()->GetKadID()); uDistance.Xor(uFile); @@ -1210,7 +1203,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_PUBLISH_KEY_REQ(const byte *pbyPack CKeyEntry *pEntry = NULL; try { CString sInfo; - byteIO.ReadUInt128(&uTarget); + byteIO.ReadUInt128(uTarget); pEntry = new Kademlia::CKeyEntry(); pEntry->m_uIP = uIP; pEntry->m_uUDPPort = uUDPPort; @@ -1275,11 +1268,11 @@ void CKademliaUDPListener::Process_KADEMLIA2_PUBLISH_KEY_REQ(const byte *pbyPack } } CSafeMemFile fileIO2(17); - fileIO2.WriteUInt128(&uFile); + fileIO2.WriteUInt128(uFile); fileIO2.WriteUInt8(uLoad); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_PUBLISH_RES", uIP, uUDPPort); - SendPacket(&fileIO2, KADEMLIA2_PUBLISH_RES, uIP, uUDPPort, senderUDPKey, NULL); + SendPacket(fileIO2, KADEMLIA2_PUBLISH_RES, uIP, uUDPPort, senderUDPKey, NULL); } // Used in Kad2.0 only @@ -1292,7 +1285,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_PUBLISH_SOURCE_REQ(const byte *pbyP CByteIO byteIO(pbyPacketData, uLenPacket); CUInt128 uFile; - byteIO.ReadUInt128(&uFile); + byteIO.ReadUInt128(uFile); CUInt128 uDistance(CKademlia::GetPrefs()->GetKadID()); uDistance.Xor(uFile); @@ -1303,7 +1296,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_PUBLISH_SOURCE_REQ(const byte *pbyP bool bDbgInfo = (thePrefs.GetDebugClientKadUDPLevel() > 0); uint8 uLoad = 0; CUInt128 uTarget; - byteIO.ReadUInt128(&uTarget); + byteIO.ReadUInt128(uTarget); CKadTag *pTag = NULL; CEntry *pEntry = NULL; try { @@ -1396,11 +1389,11 @@ void CKademliaUDPListener::Process_KADEMLIA2_PUBLISH_SOURCE_REQ(const byte *pbyP if (pEntry->m_bSource && CKademlia::GetIndexed()->AddSources(uFile, uTarget, pEntry, uLoad)) { CSafeMemFile fileIO2(17); - fileIO2.WriteUInt128(&uFile); + fileIO2.WriteUInt128(uFile); fileIO2.WriteUInt8(uLoad); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_PUBLISH_RES", uIP, uUDPPort); - SendPacket(&fileIO2, KADEMLIA2_PUBLISH_RES, uIP, uUDPPort, senderUDPKey, NULL); + SendPacket(fileIO2, KADEMLIA2_PUBLISH_RES, uIP, uUDPPort, senderUDPKey, NULL); } else delete pEntry; } @@ -1422,7 +1415,7 @@ void CKademliaUDPListener::Process_KADEMLIA_PUBLISH_RES(const byte *pbyPacketDat CSafeMemFile fileIO(pbyPacketData, uLenPacket); CUInt128 uFile; - fileIO.ReadUInt128(&uFile); + fileIO.ReadUInt128(uFile); bool bLoadResponse = false; uint8 uLoad = 0; @@ -1444,7 +1437,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_PUBLISH_RES(const byte *pbyPacketDa } CSafeMemFile fileIO(pbyPacketData, uLenPacket); CUInt128 uFile; - fileIO.ReadUInt128(&uFile); + fileIO.ReadUInt128(uFile); uint8 uLoad = fileIO.ReadUInt8(); CSearchManager::ProcessPublishResult(uFile, uLoad, true); if (fileIO.GetLength() > fileIO.GetPosition()) { @@ -1465,7 +1458,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_SEARCH_NOTES_REQ(const byte *pbyPac { CSafeMemFile fileIO(pbyPacketData, uLenPacket); CUInt128 uTarget; - fileIO.ReadUInt128(&uTarget); + fileIO.ReadUInt128(uTarget); uint64 uFileSize = fileIO.ReadUInt64(); CKademlia::GetIndexed()->SendValidNoteResult(uTarget, uIP, uUDPPort, uFileSize, senderUDPKey); } @@ -1488,31 +1481,28 @@ void CKademliaUDPListener::Process_KADEMLIA_SEARCH_NOTES_RES(const byte *pbyPack // What search does this relate to CByteIO byteIO(pbyPacketData, uLenPacket); CUInt128 uTarget; - byteIO.ReadUInt128(&uTarget); + byteIO.ReadUInt128(uTarget); CUInt128 uAnswer; for (unsigned uCount = byteIO.ReadUInt16(); uCount > 0; --uCount) { // What is the answer - byteIO.ReadUInt128(&uAnswer); + byteIO.ReadUInt128(uAnswer); // Get info about answer // NOTE: this is the one and only place in Kad where we allow string conversion to local code page in - // case we did not receive a UTF-8 string. This is for backward compatibility for search results which are - // supposed to be 'viewed' by user only and not feed into the Kad engine again! - // If that tag list is once used for something else than for viewing, special care has to be taken for any - // string conversion! - TagList *pTags = NULL; + // case we did not receive a UTF-8 string. This is for backward compatibility for search results + // which are supposed to be 'viewed' by user only and not feed into the Kad engine again! + // If that tag list is once used for something else than for viewing, special care has to be taken + // for any string conversion! + TagList lTags; try { - pTags = new TagList; - byteIO.ReadTagList(pTags, true); + byteIO.ReadTagList(lTags, true); } catch (...) { - if (pTags) { - deleteTagListEntries(pTags); - delete pTags; - } + deleteTagListEntries(lTags); throw; } - CSearchManager::ProcessResult(uTarget, uAnswer, pTags, uIP, uUDPPort); + CSearchManager::ProcessResult(uTarget, uAnswer, lTags, uIP, uUDPPort); + deleteTagListEntries(lTags); } } @@ -1527,7 +1517,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_PUBLISH_NOTES_REQ(const byte *pbyPa CByteIO byteIO(pbyPacketData, uLenPacket); CUInt128 uTarget; - byteIO.ReadUInt128(&uTarget); + byteIO.ReadUInt128(uTarget); CUInt128 uDistance(CKademlia::GetPrefs()->GetKadID()); uDistance.Xor(uTarget); @@ -1537,7 +1527,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_PUBLISH_NOTES_REQ(const byte *pbyPa return; CUInt128 uSource; - byteIO.ReadUInt128(&uSource); + byteIO.ReadUInt128(uSource); CKadTag *pTag = NULL; Kademlia::CEntry *pEntry = new Kademlia::CEntry(); @@ -1574,12 +1564,12 @@ void CKademliaUDPListener::Process_KADEMLIA2_PUBLISH_NOTES_REQ(const byte *pbyPa uint8 uLoad = 0; if (CKademlia::GetIndexed()->AddNotes(uTarget, uSource, pEntry, uLoad)) { CSafeMemFile fileIO2(17); - fileIO2.WriteUInt128(&uTarget); + fileIO2.WriteUInt128(uTarget); fileIO2.WriteUInt8(uLoad); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_PUBLISH_RES", uIP, uUDPPort); - SendPacket(&fileIO2, KADEMLIA2_PUBLISH_RES, uIP, uUDPPort, senderUDPKey, NULL); + SendPacket(fileIO2, KADEMLIA2_PUBLISH_RES, uIP, uUDPPort, senderUDPKey, NULL); } else delete pEntry; } @@ -1610,7 +1600,7 @@ void CKademliaUDPListener::Process_KADEMLIA_FIREWALLED_REQ(const byte *pbyPacket if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA_FIREWALLED_RES", uIP, uUDPPort); - SendPacket(&fileIO2, KADEMLIA_FIREWALLED_RES, uIP, uUDPPort, senderUDPKey, NULL); + SendPacket(fileIO2, KADEMLIA_FIREWALLED_RES, uIP, uUDPPort, senderUDPKey, NULL); } // Used by Kad2.0 Prot.Version 7+ @@ -1626,7 +1616,7 @@ void CKademliaUDPListener::Process_KADEMLIA_FIREWALLED2_REQ(const byte *pbyPacke CSafeMemFile fileIO(pbyPacketData, uLenPacket); uint16 uTCPPort = fileIO.ReadUInt16(); CUInt128 userID; - fileIO.ReadUInt128(&userID); + fileIO.ReadUInt128(userID); uint8 byConnectOptions = fileIO.ReadUInt8(); CContact contact; @@ -1643,7 +1633,7 @@ void CKademliaUDPListener::Process_KADEMLIA_FIREWALLED2_REQ(const byte *pbyPacke if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA_FIREWALLED_RES", uIP, uUDPPort); - SendPacket(&fileIO2, KADEMLIA_FIREWALLED_RES, uIP, uUDPPort, senderUDPKey, NULL); + SendPacket(fileIO2, KADEMLIA_FIREWALLED_RES, uIP, uUDPPort, senderUDPKey, NULL); } // Used by Kad1.0 and Kad2.0 @@ -1706,9 +1696,9 @@ void CKademliaUDPListener::Process_KADEMLIA_FINDBUDDY_REQ(const byte *pbyPacketD CSafeMemFile fileIO(pbyPacketData, uLenPacket); CUInt128 BuddyID; - fileIO.ReadUInt128(&BuddyID); + fileIO.ReadUInt128(BuddyID); CUInt128 userID; - fileIO.ReadUInt128(&userID); + fileIO.ReadUInt128(userID); uint16 uTCPPort = fileIO.ReadUInt16(); CContact contact; @@ -1720,15 +1710,15 @@ void CKademliaUDPListener::Process_KADEMLIA_FINDBUDDY_REQ(const byte *pbyPacketD return; // cancelled for some reason, don't send a response CSafeMemFile fileIO2(34); - fileIO2.WriteUInt128(&BuddyID); - fileIO2.WriteUInt128(&CKademlia::GetPrefs()->GetClientHash()); + fileIO2.WriteUInt128(BuddyID); + fileIO2.WriteUInt128(CKademlia::GetPrefs()->GetClientHash()); fileIO2.WriteUInt16(thePrefs.GetPort()); if (!senderUDPKey.IsEmpty()) // remove check for later versions fileIO2.WriteUInt8(CKademlia::GetPrefs()->GetMyConnectOptions(true, false)); // new since 0.49a, old mules will ignore it (hopefully ;) ) if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA_FINDBUDDY_RES", uIP, uUDPPort); - SendPacket(&fileIO2, KADEMLIA_FINDBUDDY_RES, uIP, uUDPPort, senderUDPKey, NULL); + SendPacket(fileIO2, KADEMLIA_FINDBUDDY_RES, uIP, uUDPPort, senderUDPKey, NULL); } // Used by Kad1.0 and Kad2.0 @@ -1749,11 +1739,11 @@ void CKademliaUDPListener::Process_KADEMLIA_FINDBUDDY_RES(const byte *pbyPacketD CSafeMemFile fileIO(pbyPacketData, uLenPacket); CUInt128 uCheck; - fileIO.ReadUInt128(&uCheck); + fileIO.ReadUInt128(uCheck); uCheck.Xor(CUInt128(true)); if (CKademlia::GetPrefs()->GetKadID() == uCheck) { CUInt128 userID; - fileIO.ReadUInt128(&userID); + fileIO.ReadUInt128(userID); uint16 uTCPPort = fileIO.ReadUInt16(); uint8 byConnectOptions = 0; if (uLenPacket > 34) @@ -1784,21 +1774,21 @@ void CKademliaUDPListener::Process_KADEMLIA_CALLBACK_REQ(const byte *pbyPacketDa if (pBuddy != NULL) { CSafeMemFile fileIO(pbyPacketData, uLenPacket); CUInt128 uCheck; - fileIO.ReadUInt128(&uCheck); + fileIO.ReadUInt128(uCheck); //JOHNTODO: Begin filtering bad buddy ID's. //CUInt128 bud(pBuddy->GetBuddyID()); CUInt128 uFile; - fileIO.ReadUInt128(&uFile); + fileIO.ReadUInt128(uFile); uint16 uTCP = fileIO.ReadUInt16(); if (pBuddy->socket == NULL) throw CString(__FUNCTION__ ": Buddy has no valid socket."); CSafeMemFile fileIO2(uLenPacket + 6); - fileIO2.WriteUInt128(&uCheck); - fileIO2.WriteUInt128(&uFile); + fileIO2.WriteUInt128(uCheck); + fileIO2.WriteUInt128(uFile); fileIO2.WriteUInt32(uIP); fileIO2.WriteUInt16(uTCP); - Packet *pPacket = new Packet(&fileIO2, OP_EMULEPROT, OP_CALLBACK); + Packet *pPacket = new Packet(fileIO2, OP_EMULEPROT, OP_CALLBACK); if (thePrefs.GetDebugClientKadUDPLevel() > 0 || thePrefs.GetDebugClientTCPLevel() > 0) DebugSend("OP_CALLBACK", pBuddy); theStats.AddUpDataOverheadFileRequest(pPacket->size); @@ -1813,7 +1803,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_PING(uint32 uIP, uint16 uUDPPort, c fileIO2.WriteUInt16(uUDPPort); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_PONG", uIP, uUDPPort); - SendPacket(&fileIO2, KADEMLIA2_PONG, uIP, uUDPPort, senderUDPKey, NULL); + SendPacket(fileIO2, KADEMLIA2_PONG, uIP, uUDPPort, senderUDPKey, NULL); } void CKademliaUDPListener::Process_KADEMLIA2_PONG(const byte *pbyPacketData, uint32 uLenPacket, uint32 uIP, uint16 /*uUDPPort*/, const CKadUDPKey& /*senderUDPKey*/) @@ -1841,9 +1831,9 @@ void CKademliaUDPListener::Process_KADEMLIA2_PONG(const byte *pbyPacketData, uin } if (CKademlia::GetPrefs()->FindExternKadPort(false)) { - // the reported port doesn't always has to be our true external port, esp. if we used our intern port - // and communicated recently with the client some routers might remember this and assign the intern port as source - // but this shouldn't be a problem because we prefer intern ports anyway. + // the reported port doesn't always have to be our true external port, esp. if we used our intern + // port and communicated recently with the client some routers might remember this and assign + // the intern port as source but this shouldn't be a problem because we prefer intern ports anyway. // might have to be reviewed in later versions when more data is available CKademlia::GetPrefs()->SetExternKadPort(PeekUInt16(pbyPacketData), uIP); if (CUDPFirewallTester::IsFWCheckUDPRunning()) @@ -1872,7 +1862,7 @@ void CKademliaUDPListener::Process_KADEMLIA2_FIREWALLUDP(const byte *pbyPacketDa DebugLog(_T("Received UDP FirewallCheck packet from %s with incoming port %u"), (LPCTSTR)ipstr(htonl(uIP)), nIncomingPort); CUDPFirewallTester::SetUDPFWCheckResult(true, false, uIP, nIncomingPort); } else { - DebugLog(_T("Received UDP FirewallCheck packet from %s with incoming port %u with remote errorcode %u - ignoring result"), (LPCTSTR)ipstr(htonl(uIP)), nIncomingPort, byErrorCode); + DebugLog(_T("Received UDP FirewallCheck packet from %s with incoming port %u with remote error code %u - ignoring result"), (LPCTSTR)ipstr(htonl(uIP)), nIncomingPort, byErrorCode); CUDPFirewallTester::SetUDPFWCheckResult(false, true, uIP, 0); } } @@ -1913,7 +1903,7 @@ void CKademliaUDPListener::SendPacket(const byte *pbyData, uint32 uLenData, byte , true, targetUDPKey.GetKeyValue(theApp.GetPublicIP(false))); } -void CKademliaUDPListener::SendPacket(CSafeMemFile *pbyData, byte byOpcode, uint32 uDestinationHost, uint16 uDestinationPort, const CKadUDPKey &targetUDPKey, const CUInt128 *uCryptTargetID) +void CKademliaUDPListener::SendPacket(CSafeMemFile &pbyData, byte byOpcode, uint32 uDestinationHost, uint16 uDestinationPort, const CKadUDPKey &targetUDPKey, const CUInt128 *uCryptTargetID) { Packet *pPacket = new Packet(pbyData, OP_KADEMLIAHEADER); pPacket->opcode = byOpcode; @@ -1941,7 +1931,7 @@ bool CKademliaUDPListener::FindNodeIDByIP(CKadClientSearcher *pRequester, uint32 return true; } -void CKademliaUDPListener::ExpireClientSearch(CKadClientSearcher *pExpireImmediately) +void CKademliaUDPListener::ExpireClientSearch(const CKadClientSearcher *pExpireImmediately) { for (POSITION pos = listFetchNodeIDRequests.GetHeadPosition(); pos != NULL;) { POSITION pos2 = pos; @@ -1981,11 +1971,11 @@ void CKademliaUDPListener::SendLegacyChallenge(uint32 uIP, uint16 uUDPPort, cons uChallenge = 1; } // Put the target we want into the packet. This is our challenge - fileIO.WriteUInt128(&uChallenge); + fileIO.WriteUInt128(uChallenge); // Add the ID of the contact we are contacting for sanity checks on the other end. - fileIO.WriteUInt128(&uContactID); + fileIO.WriteUInt128(uContactID); // those versions we send those requests to don't support encryption / obfuscation - CKademlia::GetUDPListener()->SendPacket(&fileIO, KADEMLIA2_REQ, uIP, uUDPPort, CKadUDPKey(), NULL); + CKademlia::GetUDPListener()->SendPacket(fileIO, KADEMLIA2_REQ, uIP, uUDPPort, CKadUDPKey(), NULL); if (thePrefs.GetDebugClientKadUDPLevel() > 0) DebugSend("KADEMLIA2_REQ(SendLegacyChallenge)", uIP, uUDPPort); AddLegacyChallenge(uContactID, uChallenge, uIP, KADEMLIA2_REQ); diff --git a/srchybrid/kademlia/net/KademliaUDPListener.h b/srchybrid/kademlia/net/KademliaUDPListener.h index aeb52ae8..ff405f32 100644 --- a/srchybrid/kademlia/net/KademliaUDPListener.h +++ b/srchybrid/kademlia/net/KademliaUDPListener.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -62,10 +62,10 @@ namespace Kademlia virtual void ProcessPacket(const byte *pbyData, uint32 uLenData, uint32 uIP, uint16 uUDPPort, bool bValidReceiverKey, const CKadUDPKey &senderUDPKey); void SendPacket(const byte *pbyData, uint32 uLenData, uint32 uDestinationHost, uint16 uDestinationPort, const CKadUDPKey &targetUDPKey, const CUInt128 *uCryptTargetID); void SendPacket(const byte *pbyData, uint32 uLenData, byte byOpcode, uint32 uDestinationHost, uint16 uDestinationPort, const CKadUDPKey &targetUDPKey, const CUInt128 *uCryptTargetID); - void SendPacket(CSafeMemFile *pbyData, byte byOpcode, uint32 uDestinationHost, uint16 uDestinationPort, const CKadUDPKey &targetUDPKey, const CUInt128 *uCryptTargetID); + void SendPacket(CSafeMemFile &pbyData, byte byOpcode, uint32 uDestinationHost, uint16 uDestinationPort, const CKadUDPKey &targetUDPKey, const CUInt128 *uCryptTargetID); bool FindNodeIDByIP(CKadClientSearcher *pRequester, uint32 dwIP, uint16 nTCPPort, uint16 nUDPPort); - void ExpireClientSearch(CKadClientSearcher *pExpireImmediately = NULL); + void ExpireClientSearch(const CKadClientSearcher *pExpireImmediately = NULL); private: bool AddContact_KADEMLIA2(const byte *pbyData, uint32 uLenData, uint32 uIP, uint16 &uUDPPort, uint8 *pnOutVersion, const CKadUDPKey &cUDPKey, bool &rbIPVerified, bool bUpdate, bool bFromHelloReq, bool *pbOutRequestsACK, CUInt128 *puOutContactID); void SendLegacyChallenge(uint32 uIP, uint16 uUDPPort, const CUInt128 &uContactID); diff --git a/srchybrid/kademlia/net/PacketTracking.cpp b/srchybrid/kademlia/net/PacketTracking.cpp index 88a1b631..300d3418 100644 --- a/srchybrid/kademlia/net/PacketTracking.cpp +++ b/srchybrid/kademlia/net/PacketTracking.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -45,14 +45,14 @@ CPacketTracking::~CPacketTracking() void CPacketTracking::AddTrackedOutPacket(uint32 dwIP, uint8 byOpcode) { - // this tracklist tacks _outgoing_ request packets, to make sure incoming answer packets were requested - // only track packets which we actually check for later - if (!IsTrackedOutListRequestPacket(byOpcode)) - return; - const uint32 tick = ::GetTickCount(); - listTrackedRequests.AddHead(TrackPackets_Struct{tick, dwIP, byOpcode}); - while (!listTrackedRequests.IsEmpty() && tick >= listTrackedRequests.GetTail().dwInserted + SEC2MS(180)) - listTrackedRequests.RemoveTail(); + // this tracklist monitors _outgoing_ request packets, to make sure incoming answer packets were requested + // later we will check only tracked packets + if (IsTrackedOutListRequestPacket(byOpcode)) { + const DWORD curTick = ::GetTickCount(); + listTrackedRequests.AddHead(TrackPackets_Struct{ curTick, dwIP, byOpcode }); + while (!listTrackedRequests.IsEmpty() && curTick >= listTrackedRequests.GetTail().dwInserted + SEC2MS(180)) + listTrackedRequests.RemoveTail(); + } } bool CPacketTracking::IsTrackedOutListRequestPacket(uint8 byOpcode) @@ -82,11 +82,11 @@ bool CPacketTracking::IsOnOutTrackList(uint32 dwIP, uint8 byOpcode, bool bDontRe if (!IsTrackedOutListRequestPacket(byOpcode)) ASSERT(0); // code error / bug #endif - const uint32 tick = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); for (POSITION pos = listTrackedRequests.GetHeadPosition(); pos != NULL;) { POSITION pos2 = pos; const TrackPackets_Struct &req = listTrackedRequests.GetNext(pos); - if (tick >= req.dwInserted + SEC2MS(180)) + if (curTick >= req.dwInserted + SEC2MS(180)) break; if (req.dwIP == dwIP && req.byOpcode == byOpcode) { if (!bDontRemove) @@ -102,64 +102,59 @@ int CPacketTracking::InTrackListIsAllowedPacket(uint32 uIP, uint8 byOpcode, bool { // this tracklist monitors _incoming_ request packets and acts as a general flood protection // by dropping too frequent requests from a single IP, thus avoiding response floods, saving CPU time, - // preventing DOS attacks and slowing down other possible attacks/behavior + // preventing DoS attacks and slowing down other possible attacks/behaviour // (scanning indexed files, fake publish floods, etc) - // first figure out if this is a request packet to be tracked and its time limits + // first figure out if this is a request packet to be tracked // time limits are chosen by estimating the max. frequency of such packets in normal operation (+ buffer) // (those limits are not meant be fine for normal usage, but only supposed to be a flood detection) - uint32 iAllowedPacketsPerMinute; + // + // Tokens are calculated as the number of milliseconds corresponding to the allowed quantity of packets per minute. + int token; const byte byDbgOrgOpcode = byOpcode; switch (byOpcode) { case KADEMLIA2_BOOTSTRAP_REQ: - iAllowedPacketsPerMinute = 2; + token = MIN2MS(1) / 2; break; case KADEMLIA2_HELLO_REQ: - iAllowedPacketsPerMinute = 3; + token = MIN2MS(1) / 3; break; case KADEMLIA2_REQ: - iAllowedPacketsPerMinute = 10; + token = MIN2MS(1) / 10; break; case KADEMLIA2_SEARCH_NOTES_REQ: - iAllowedPacketsPerMinute = 3; - break; case KADEMLIA2_SEARCH_KEY_REQ: - iAllowedPacketsPerMinute = 3; - break; case KADEMLIA2_SEARCH_SOURCE_REQ: - iAllowedPacketsPerMinute = 3; + token = MIN2MS(1) / 3; break; case KADEMLIA2_PUBLISH_KEY_REQ: - iAllowedPacketsPerMinute = 4; + token = MIN2MS(1) / 4; break; case KADEMLIA2_PUBLISH_SOURCE_REQ: - iAllowedPacketsPerMinute = 3; + token = MIN2MS(1) / 3; break; case KADEMLIA2_PUBLISH_NOTES_REQ: - iAllowedPacketsPerMinute = 2; + token = MIN2MS(1) / 2; break; case KADEMLIA_FIREWALLED2_REQ: byOpcode = KADEMLIA_FIREWALLED_REQ; case KADEMLIA_FIREWALLED_REQ: - iAllowedPacketsPerMinute = 2; - break; case KADEMLIA_FINDBUDDY_REQ: - iAllowedPacketsPerMinute = 2; + token = MIN2MS(1) / 2; break; case KADEMLIA_CALLBACK_REQ: - iAllowedPacketsPerMinute = 1; + token = MIN2MS(1) / 1; break; case KADEMLIA2_PING: - iAllowedPacketsPerMinute = 2; + token = MIN2MS(1) / 2; break; default: - // not a request packets, so it's a response - no further checks at this point + // not a request packets, but a response - no further checks at this point return 0; } - const uint32 milliSecsPerPacket = MIN2MS(1) / iAllowedPacketsPerMinute; - const uint32 dwCurrentTick = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); // time for cleaning up? - if (dwCurrentTick >= dwLastTrackInCleanup + MIN2MS(12)) + if (curTick >= dwLastTrackInCleanup + MIN2MS(12)) InTrackListCleanup(); // check for existing entries @@ -167,77 +162,62 @@ int CPacketTracking::InTrackListIsAllowedPacket(uint32 uIP, uint8 byOpcode, bool if (!m_mapTrackPacketsIn.Lookup(uIP, pTrackEntry)) { pTrackEntry = new TrackPacketsIn_Struct(); pTrackEntry->m_uIP = uIP; - m_mapTrackPacketsIn.SetAt(uIP, pTrackEntry); + m_mapTrackPacketsIn[uIP] = pTrackEntry; m_liTrackPacketsIn.AddHead(pTrackEntry); } - // search specific request tracks - for (int i = 0; i < pTrackEntry->m_aTrackedRequests.GetCount(); ++i) { - if (pTrackEntry->m_aTrackedRequests[i].m_byOpcode == byOpcode) { - // already tracked requests with this opcode, remove expired request counts - TrackPacketsIn_Struct::TrackedRequestIn_Struct &rCurTrackedRequest = pTrackEntry->m_aTrackedRequests[i]; - if (rCurTrackedRequest.m_nCount > 0 - && dwCurrentTick >= rCurTrackedRequest.m_dwFirstAdded + milliSecsPerPacket + 500) //allow small extra time - { - uint32 nRemoveCount = (dwCurrentTick - rCurTrackedRequest.m_dwFirstAdded - 500) / milliSecsPerPacket; - if (nRemoveCount >= rCurTrackedRequest.m_nCount) { - rCurTrackedRequest.m_nCount = 0; - rCurTrackedRequest.m_dwFirstAdded = dwCurrentTick; // for the packet we just process - } else { - rCurTrackedRequest.m_nCount -= nRemoveCount; - rCurTrackedRequest.m_dwFirstAdded += milliSecsPerPacket * nRemoveCount; - } - } - // we increase the counter in any case, even if we drop the packet later - ++rCurTrackedRequest.m_nCount; - // remember only for easier cleanup - pTrackEntry->m_dwLastExpire = max(pTrackEntry->m_dwLastExpire, rCurTrackedRequest.m_dwFirstAdded + milliSecsPerPacket * rCurTrackedRequest.m_nCount); + INT_PTR i = pTrackEntry->m_aTrackedRequests.GetCount(); + // search for the specific request track + while (--i >= 0 && pTrackEntry->m_aTrackedRequests[i].m_byOpcode == byOpcode); + + if (i >= 0) { + // already tracking requests with this opcode + TrackPacketsIn_Struct::TrackedRequestIn_Struct &TrackedRequest = pTrackEntry->m_aTrackedRequests[i]; + TrackedRequest.m_tokens += curTick - TrackedRequest.m_dwLatest; + if (TrackedRequest.m_tokens > MIN2MS(1)) + TrackedRequest.m_tokens = MIN2MS(1); + TrackedRequest.m_tokens -= token; + TrackedRequest.m_dwLatest = curTick; + // remember only for easier cleanup + pTrackEntry->m_dwLastExpire = max(pTrackEntry->m_dwLastExpire, curTick + abs(TrackedRequest.m_tokens) + token); - if (CKademlia::IsRunningInLANMode() && IsLANIP(ntohl(uIP))) // no flood detection in LanMode - return 0; + if (CKademlia::IsRunningInLANMode() && IsLANIP(ntohl(uIP))) // no flood detection in LanMode + return 0; - // now the actual check if this request is allowed - if (rCurTrackedRequest.m_nCount > iAllowedPacketsPerMinute * 4) { - // this is so far above the limit that it has to be an intentional flood / misuse in any case - // so we take the next higher punishment and ban the IP + // now the actual check if this request is allowed + if (TrackedRequest.m_tokens < 0) { + if (TrackedRequest.m_tokens < MIN2MS(-3)) { + // this is so far above the limit that has to be an intentional flood / misuse + // so we take higher level of punishment and ban the IP DebugLogWarning(_T("Kad: Massive request flood detected for opcode 0x%X (0x%X) from IP %s - Banning IP"), byOpcode, byDbgOrgOpcode, (LPCTSTR)ipstr(htonl(uIP))); theApp.clientlist->AddBannedClient(ntohl(uIP)); return 2; // drop the packet, remove the contact from routing } - if (rCurTrackedRequest.m_nCount > iAllowedPacketsPerMinute) { - // over the limit, drop the packet but do nothing else - if (!rCurTrackedRequest.m_bDbgLogged) { - rCurTrackedRequest.m_bDbgLogged = true; - DebugLog(_T("Kad: Request flood detected for opcode 0x%X (0x%X) from IP %s - Dropping packets with this opcode"), byOpcode, byDbgOrgOpcode, (LPCTSTR)ipstr(htonl(uIP))); - } - return 1; // drop the packet + // over the limit, drop the packet but do nothing else + if (!TrackedRequest.m_bDbgLogged) { + TrackedRequest.m_bDbgLogged = true; + DebugLog(_T("Kad: Request flood detected for opcode 0x%X (0x%X) from IP %s - Dropping packets with this opcode"), byOpcode, byDbgOrgOpcode, (LPCTSTR)ipstr(htonl(uIP))); } - rCurTrackedRequest.m_bDbgLogged = false; - return 0; + return 1; // drop the packet } + TrackedRequest.m_bDbgLogged = false; + } else { + // add a new entry for this request + TrackPacketsIn_Struct::TrackedRequestIn_Struct TrackedRequest = { curTick, MIN2MS(1) - token, byOpcode, false }; + pTrackEntry->m_aTrackedRequests.Add(TrackedRequest); } - - // add a new entry for this request, no checks needed since 1 is always OK - TrackPacketsIn_Struct::TrackedRequestIn_Struct curTrackedRequest; - curTrackedRequest.m_byOpcode = byOpcode; - curTrackedRequest.m_bDbgLogged = false; - curTrackedRequest.m_dwFirstAdded = dwCurrentTick; - curTrackedRequest.m_nCount = 1; - // remember only for easier cleanup - pTrackEntry->m_dwLastExpire = max(pTrackEntry->m_dwLastExpire, dwCurrentTick + milliSecsPerPacket); - pTrackEntry->m_aTrackedRequests.Add(curTrackedRequest); return 0; } void CPacketTracking::InTrackListCleanup() { - const uint32 dwCurrentTick = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); const INT_PTR dbgOldSize = m_liTrackPacketsIn.GetCount(); - dwLastTrackInCleanup = dwCurrentTick; + dwLastTrackInCleanup = curTick; for (POSITION pos = m_liTrackPacketsIn.GetHeadPosition(); pos != NULL;) { POSITION pos2 = pos; const TrackPacketsIn_Struct *curEntry = m_liTrackPacketsIn.GetNext(pos); - if (dwCurrentTick >= curEntry->m_dwLastExpire) { + if (curTick >= curEntry->m_dwLastExpire) { VERIFY(m_mapTrackPacketsIn.RemoveKey(curEntry->m_uIP)); m_liTrackPacketsIn.RemoveAt(pos2); delete curEntry; @@ -248,9 +228,9 @@ void CPacketTracking::InTrackListCleanup() void CPacketTracking::AddLegacyChallenge(const CUInt128 &uContactID, const CUInt128 &uChallengeID, uint32 uIP, uint8 byOpcode) { - const uint32 tick = ::GetTickCount(); - listChallengeRequests.AddHead(TrackChallenge_Struct{tick, uContactID, uChallengeID, uIP, byOpcode}); - while (!listChallengeRequests.IsEmpty() && tick >= listChallengeRequests.GetTail().dwInserted + SEC2MS(180)) { + const DWORD curTick = ::GetTickCount(); + listChallengeRequests.AddHead(TrackChallenge_Struct{ curTick, uIP, uContactID, uChallengeID, byOpcode }); + while (!listChallengeRequests.IsEmpty() && curTick >= listChallengeRequests.GetTail().dwInserted + SEC2MS(180)) { DEBUG_ONLY(DebugLog(_T("Challenge timed out, client not verified - %s"), (LPCTSTR)ipstr(htonl(listChallengeRequests.GetTail().uIP)))); listChallengeRequests.RemoveTail(); } @@ -259,11 +239,11 @@ void CPacketTracking::AddLegacyChallenge(const CUInt128 &uContactID, const CUInt bool CPacketTracking::IsLegacyChallenge(const CUInt128 &uChallengeID, uint32 uIP, uint8 byOpcode, CUInt128 &ruContactID) { bool bDbgWarning = false; - const uint32 tick = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); for (POSITION pos = listChallengeRequests.GetHeadPosition(); pos != NULL;) { POSITION pos2 = pos; const TrackChallenge_Struct &tc = listChallengeRequests.GetNext(pos); - if (tick >= tc.dwInserted + SEC2MS(180)) + if (curTick >= tc.dwInserted + SEC2MS(180)) break; if (tc.uIP == uIP && tc.byOpcode == byOpcode) { ASSERT(tc.uChallenge != 0 || byOpcode == KADEMLIA2_PING); @@ -282,10 +262,10 @@ bool CPacketTracking::IsLegacyChallenge(const CUInt128 &uChallengeID, uint32 uIP bool CPacketTracking::HasActiveLegacyChallenge(uint32 uIP) const { - const uint32 tick = ::GetTickCount(); + const DWORD curTick = ::GetTickCount(); for (POSITION pos = listChallengeRequests.GetHeadPosition(); pos != NULL;) { const TrackChallenge_Struct &tcstruct = listChallengeRequests.GetNext(pos); - if (tick >= tcstruct.dwInserted + SEC2MS(180)) + if (curTick >= tcstruct.dwInserted + SEC2MS(180)) break; if (tcstruct.uIP == uIP) return true; diff --git a/srchybrid/kademlia/net/PacketTracking.h b/srchybrid/kademlia/net/PacketTracking.h index e5a242d0..81179f90 100644 --- a/srchybrid/kademlia/net/PacketTracking.h +++ b/srchybrid/kademlia/net/PacketTracking.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -22,26 +22,26 @@ namespace Kademlia { struct TrackPackets_Struct { - uint32 dwInserted; - uint32 dwIP; - uint8 byOpcode; + DWORD dwInserted; + uint32 dwIP; + uint8 byOpcode; }; struct TrackChallenge_Struct { - uint32 dwInserted; + DWORD dwInserted; + uint32 uIP; CUInt128 uContactID; CUInt128 uChallenge; - uint32 uIP; - uint8 byOpcode; + uint8 byOpcode; }; struct TrackPacketsIn_Struct { struct TrackedRequestIn_Struct { - uint32 m_dwFirstAdded; - uint32 m_nCount; + DWORD m_dwLatest; + int m_tokens; //tokens are equal to milliseconds in this Token Bucket algorithm implementation uint8 m_byOpcode; bool m_bDbgLogged; }; @@ -52,7 +52,7 @@ namespace Kademlia { } - uint32 m_dwLastExpire; + DWORD m_dwLastExpire; uint32 m_uIP; CArray m_aTrackedRequests; }; @@ -78,6 +78,6 @@ namespace Kademlia CList listChallengeRequests; CTypedPtrList m_liTrackPacketsIn; CMap m_mapTrackPacketsIn; - uint32 dwLastTrackInCleanup; + DWORD dwLastTrackInCleanup; }; } \ No newline at end of file diff --git a/srchybrid/kademlia/routing/Contact.cpp b/srchybrid/kademlia/routing/Contact.cpp index a8c429cb..e7128103 100644 --- a/srchybrid/kademlia/routing/Contact.cpp +++ b/srchybrid/kademlia/routing/Contact.cpp @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -29,7 +29,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -79,7 +79,7 @@ CContact::CContact(const CUInt128 &uClientID, uint32 uIp, uint16 uUdpPort, uint1 , m_uVersion(uVersion) , m_bIPVerified(bIPVerified) { - CKademlia::GetPrefs()->GetKadID(&m_uDistance); + CKademlia::GetPrefs()->GetKadID(m_uDistance); m_uDistance.Xor(uClientID); InitContact(); } @@ -132,31 +132,31 @@ void CContact::InitContact() m_bBootstrapContact = false; } -void CContact::GetClientID(CUInt128 *puId) const +void CContact::GetClientID(CUInt128 &uId) const { - puId->SetValue(m_uClientID); + uId.SetValue(m_uClientID); } -void CContact::GetClientID(CString *psId) const +void CContact::GetClientID(CString &sId) const { - m_uClientID.ToHexString(psId); + m_uClientID.ToHexString(sId); } void CContact::SetClientID(const CUInt128 &uClientID) { m_uClientID = uClientID; - CKademlia::GetPrefs()->GetKadID(&m_uDistance); + CKademlia::GetPrefs()->GetKadID(m_uDistance); m_uDistance.Xor(uClientID); } -void CContact::GetDistance(CUInt128 *puDistance) const +void CContact::GetDistance(CUInt128 &uDistance) const { - puDistance->SetValue(m_uDistance); + uDistance.SetValue(m_uDistance); } -void CContact::GetDistance(CString *psDistance) const +void CContact::GetDistance(CString &sDistance) const { - m_uDistance.ToBinaryString(psDistance); + m_uDistance.ToBinaryString(sDistance); } CUInt128 CContact::GetDistance() const @@ -174,9 +174,9 @@ uint32 CContact::GetNetIP() const return m_uNetIp; } -void CContact::GetIPAddress(CString *psIp) const +void CContact::GetIPAddress(CString &sIp) const { - CMiscUtils::IPAddressToString(m_uIp, psIp); + CMiscUtils::IPAddressToString(m_uIp, sIp); } void CContact::SetIPAddress(uint32 uIp) @@ -193,9 +193,9 @@ uint16 CContact::GetTCPPort() const return m_uTcpPort; } -void CContact::GetTCPPort(CString *psPort) const +void CContact::GetTCPPort(CString &sPort) const { - psPort->Format(_T("%hu"), m_uTcpPort); + sPort.Format(_T("%hu"), m_uTcpPort); } void CContact::SetTCPPort(uint16 uPort) @@ -208,9 +208,9 @@ uint16 CContact::GetUDPPort() const return m_uUdpPort; } -void CContact::GetUDPPort(CString *psPort) const +void CContact::GetUDPPort(CString &sPort) const { - psPort->Format(_T("%hu"), m_uUdpPort); + sPort.Format(_T("%hu"), m_uUdpPort); } void CContact::SetUDPPort(uint16 uPort) diff --git a/srchybrid/kademlia/routing/Contact.h b/srchybrid/kademlia/routing/Contact.h index e81e2239..2ecaa6f9 100644 --- a/srchybrid/kademlia/routing/Contact.h +++ b/srchybrid/kademlia/routing/Contact.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -29,7 +29,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -52,22 +52,22 @@ namespace Kademlia CContact(const CContact &k1) { Copy(k1); } CContact& operator=(const CContact &k1) { Copy(k1); return *this; } - void GetClientID(CUInt128 *puId) const; + void GetClientID(CUInt128 &uId) const; CUInt128 GetClientID() const; - void GetClientID(CString *psId) const; + void GetClientID(CString &sId) const; void SetClientID(const CUInt128 &uClientID); - void GetDistance(CUInt128 *puDistance) const; - void GetDistance(CString *psDistance) const; + void GetDistance(CUInt128 &uDistance) const; + void GetDistance(CString &sDistance) const; CUInt128 GetDistance() const; uint32 GetIPAddress() const; uint32 GetNetIP() const; - void GetIPAddress(CString *psIp) const; + void GetIPAddress(CString &sIp) const; void SetIPAddress(uint32 uIp); uint16 GetTCPPort() const; - void GetTCPPort(CString *psPort) const; + void GetTCPPort(CString &sPort) const; void SetTCPPort(uint16 uPort); uint16 GetUDPPort() const; - void GetUDPPort(CString *psPort) const; + void GetUDPPort(CString &sPort) const; void SetUDPPort(uint16 uPort); byte GetType() const; void UpdateType(); diff --git a/srchybrid/kademlia/routing/Maps.h b/srchybrid/kademlia/routing/Maps.h index 0bfb747e..61936d6a 100644 --- a/srchybrid/kademlia/routing/Maps.h +++ b/srchybrid/kademlia/routing/Maps.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,14 +23,15 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ #pragma once -#include #include +#include #include +#include #include "MapKey.h" #include "kademlia/utils/UInt128.h" @@ -44,9 +45,10 @@ namespace Kademlia class CKadTagValueString; typedef std::map ContactMap; typedef std::list ContactList; + typedef std::vector ContactArray; typedef CTypedPtrList _ContactList; - typedef std::list UIntList; - typedef std::list TagList; + typedef CArray UIntList; + typedef std::vector TagList; typedef std::list WordList; typedef std::map SearchMap; typedef std::map EventMap; diff --git a/srchybrid/kademlia/routing/RoutingBin.cpp b/srchybrid/kademlia/routing/RoutingBin.cpp index 46b5c1c4..7ca2e84c 100644 --- a/srchybrid/kademlia/routing/RoutingBin.cpp +++ b/srchybrid/kademlia/routing/RoutingBin.cpp @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -29,7 +29,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -64,12 +64,11 @@ CRoutingBin::CRoutingBin() CRoutingBin::~CRoutingBin() { try { - // Delete all contacts - for (ContactList::const_iterator itContactList = m_listEntries.begin(); itContactList != m_listEntries.end(); ++itContactList) { - AdjustGlobalTracking((*itContactList)->GetIPAddress(), false); + for (ContactList::const_iterator itContact = m_listEntries.begin(); itContact != m_listEntries.end(); ++itContact) { + AdjustGlobalTracking((*itContact)->GetIPAddress(), false); if (!m_bDontDeleteContacts) - delete *itContactList; + delete *itContact; } // Remove all contact entries. m_listEntries.clear(); @@ -81,13 +80,13 @@ CRoutingBin::~CRoutingBin() bool CRoutingBin::AddContact(CContact *pContact) { ASSERT(pContact != NULL); - const uint32 cIP = pContact->GetIPAddress(); - uint32 cSameSubnets = 0; + const uint32 uIP = pContact->GetIPAddress(); + uint32 uSameSubnets = 0; // Check if we already have a contact with this ID in the list. - for (ContactList::const_iterator itContactList = m_listEntries.begin(); itContactList != m_listEntries.end(); ++itContactList) { - if (pContact->GetClientID() == (*itContactList)->m_uClientID) + for (ContactList::const_iterator itContact = m_listEntries.begin(); itContact != m_listEntries.end(); ++itContact) { + if (pContact->GetClientID() == (*itContact)->m_uClientID) return false; - cSameSubnets += static_cast(((cIP ^ (*itContactList)->GetIPAddress()) & ~0xFF) == 0); + uSameSubnets += static_cast(((uIP ^ (*itContact)->GetIPAddress()) & ~0xFF) == 0); } // Several checks to make sure that we don't store multiple contacts from the same IP or too many @@ -95,12 +94,12 @@ bool CRoutingBin::AddContact(CContact *pContact) // several attacks and raise the resource needs (IPs) for a successful contact on the attacker side. // Such IPs are not banned from Kad, they still can index, search, etc., // so multiple KAD clients behind one IP still work - if (!CheckGlobalIPLimits(cIP, pContact->GetUDPPort(), true)) + if (!CheckGlobalIPLimits(uIP, pContact->GetUDPPort(), true)) return false; // no more than 2 IPs from the same /24 block in one bin, except if it's a LAN IP // (if we don't accept LAN IPs, they already have been filtered before) - if (cSameSubnets >= 2 && !IsLANIP(pContact->GetNetIP())) { + if (uSameSubnets >= 2 && !IsLANIP(pContact->GetNetIP())) { if (thePrefs.GetLogFilteredIPs()) AddDebugLogLine(false, _T("Ignored kad contact (IP=%s:%u) - too many contacts with the same subnet in RoutingBin"), (LPCTSTR)ipstr(pContact->GetNetIP()), pContact->GetUDPPort()); return false; @@ -109,7 +108,7 @@ bool CRoutingBin::AddContact(CContact *pContact) // If not full, add to the end of list if (m_listEntries.size() < K) { m_listEntries.push_back(pContact); - AdjustGlobalTracking(cIP, true); + AdjustGlobalTracking(uIP, true); return true; } return false; @@ -132,9 +131,9 @@ void CRoutingBin::SetAlive(CContact *pContact) void CRoutingBin::SetTCPPort(uint32 uIP, uint16 uUDPPort, uint16 uTCPPort) { // Find contact with IP/Port - for (ContactList::const_iterator itContactList = m_listEntries.begin(); itContactList != m_listEntries.end(); ++itContactList) { - CContact *pContact = *itContactList; - if ((uIP == pContact->GetIPAddress()) && (uUDPPort == pContact->GetUDPPort())) { + for (ContactList::const_iterator itContact = m_listEntries.begin(); itContact != m_listEntries.end(); ++itContact) { + CContact *pContact = *itContact; + if (uIP == pContact->GetIPAddress() && uUDPPort == pContact->GetUDPPort()) { // Set TCPPort and mark as alive. pContact->SetTCPPort(uTCPPort); pContact->UpdateType(); @@ -148,8 +147,8 @@ void CRoutingBin::SetTCPPort(uint32 uIP, uint16 uUDPPort, uint16 uTCPPort) CContact* CRoutingBin::GetContact(uint32 uIP, uint16 nPort, bool bTCPPort) { // Find contact with IP/Port - for (ContactList::const_iterator itContactList = m_listEntries.begin(); itContactList != m_listEntries.end(); ++itContactList) { - CContact *pContact = *itContactList; + for (ContactList::const_iterator itContact = m_listEntries.begin(); itContact != m_listEntries.end(); ++itContact) { + CContact *pContact = *itContact; if ((uIP == pContact->GetIPAddress()) && ((!bTCPPort && nPort == pContact->GetUDPPort()) || (bTCPPort && nPort == pContact->GetTCPPort()) || nPort == 0)) { @@ -169,10 +168,10 @@ void CRoutingBin::RemoveContact(CContact *pContact, bool bNoTrackingAdjust) CContact* CRoutingBin::GetContact(const CUInt128 &uID) { // Find contact by ID. - for (ContactList::const_iterator itContactList = m_listEntries.begin(); itContactList != m_listEntries.end(); ++itContactList) { - if (uID == (*itContactList)->m_uClientID) - return *itContactList; - } + for (ContactList::const_iterator itContact = m_listEntries.begin(); itContact != m_listEntries.end(); ++itContact) + if (uID == (*itContact)->m_uClientID) + return *itContact; + return NULL; } @@ -184,8 +183,8 @@ UINT CRoutingBin::GetSize() const void CRoutingBin::GetNumContacts(uint32 &nInOutContacts, uint32 &nInOutFilteredContacts, uint8 byMinVersion) const { // Count all Nodes which meet the search criteria and also report those who don't - for (ContactList::const_iterator itContactList = m_listEntries.begin(); itContactList != m_listEntries.end(); ++itContactList) - if ((*itContactList)->GetVersion() >= byMinVersion) + for (ContactList::const_iterator itContact = m_listEntries.begin(); itContact != m_listEntries.end(); ++itContact) + if ((*itContact)->GetVersion() >= byMinVersion) ++nInOutContacts; else ++nInOutFilteredContacts; @@ -196,29 +195,25 @@ UINT CRoutingBin::GetRemaining() const return (UINT)(K - m_listEntries.size()); } -void CRoutingBin::GetEntries(ContactList *plistResult, bool bEmptyFirst) +void CRoutingBin::GetEntries(ContactArray &listResult, bool bEmptyFirst) { - // Clear results if requested first. - if (bEmptyFirst) - plistResult->clear(); - // Append all entries to the results. - if (!m_listEntries.empty()) - plistResult->insert(plistResult->end(), m_listEntries.begin(), m_listEntries.end()); + if (bEmptyFirst) // Clear results if requested + listResult.assign(m_listEntries.begin(), m_listEntries.end()); + else // Append all entries to the results + listResult.insert(listResult.end(), m_listEntries.begin(), m_listEntries.end()); } CContact* CRoutingBin::GetOldest() { // All new/updated entries are appended to the back. - if (!m_listEntries.empty()) - return m_listEntries.front(); - return NULL; + return m_listEntries.empty() ? NULL : m_listEntries.front(); } -void CRoutingBin::GetClosestTo(uint32 uMaxType, const CUInt128 &uTarget, uint32 uMaxRequired, ContactMap *pmapResult, bool bEmptyFirst, bool bInUse) +void CRoutingBin::GetClosestTo(uint32 uMaxType, const CUInt128 &uTarget, uint32 uMaxRequired, ContactMap &rmapResult, bool bEmptyFirst, bool bInUse) { // Empty list if requested. if (bEmptyFirst) - pmapResult->clear(); + rmapResult.clear(); // Return 0 since we have no entries. if (m_listEntries.empty()) @@ -226,23 +221,23 @@ void CRoutingBin::GetClosestTo(uint32 uMaxType, const CUInt128 &uTarget, uint32 // First put results in sort order for uTarget so we can insert them correctly. // We don't care about max results at this time. - for (ContactList::const_iterator itContactList = m_listEntries.begin(); itContactList != m_listEntries.end(); ++itContactList) - if ((*itContactList)->GetType() <= uMaxType && (*itContactList)->IsIpVerified()) { - CUInt128 uTargetDistance((*itContactList)->m_uClientID); + for (ContactList::const_iterator itContact = m_listEntries.begin(); itContact != m_listEntries.end(); ++itContact) + if ((*itContact)->GetType() <= uMaxType && (*itContact)->IsIpVerified()) { + CUInt128 uTargetDistance((*itContact)->m_uClientID); uTargetDistance.Xor(uTarget); - (*pmapResult)[uTargetDistance] = *itContactList; + rmapResult[uTargetDistance] = *itContact; // This list will be used for an unknown time, Inc in use so it's not deleted. if (bInUse) - (*itContactList)->IncUse(); + (*itContact)->IncUse(); } // Remove any extra results by least wanted first. - while (pmapResult->size() > uMaxRequired) { + while (rmapResult.size() > uMaxRequired) { // Dec in use count. if (bInUse) - (--pmapResult->end())->second->DecUse(); + (--rmapResult.end())->second->DecUse(); // remove from results - pmapResult->erase(--pmapResult->end()); + rmapResult.erase(--rmapResult.end()); } // Return result count to the caller. } @@ -266,7 +261,7 @@ void CRoutingBin::AdjustGlobalTracking(uint32 uIP, bool bIncrease) --nSameIPCount; if (nSameIPCount != 0) - s_mapGlobalContactIPs.SetAt(uIP, nSameIPCount); + s_mapGlobalContactIPs[uIP] = nSameIPCount; else s_mapGlobalContactIPs.RemoveKey(uIP); @@ -287,17 +282,17 @@ void CRoutingBin::AdjustGlobalTracking(uint32 uIP, bool bIncrease) --nSameSubnetCount; if (nSameSubnetCount != 0) - s_mapGlobalContactSubnets.SetAt(uIP & ~0xFF, nSameSubnetCount); + s_mapGlobalContactSubnets[uIP & ~0xFF] = nSameSubnetCount; else s_mapGlobalContactSubnets.RemoveKey(uIP & ~0xFF); } bool CRoutingBin::ChangeContactIPAddress(CContact *pContact, uint32 uNewIP) { - // Called if we want to update an indexed contact with a new IP. We have to check if we actually allow such a change - // and if adjust our tracking. Rejecting a change will in the worst case lead a node contact to become invalid and purged later, - // but it also protects against a flood of malicous update requests from on IP which would be able to "reroute" all - // contacts to itself and by that making them useless + // Called if we want to update an indexed contact with a new IP. We have to check if we actually allow + // such a change and if adjust our tracking. Rejecting a change will in the worst case lead a node contact + // to become invalid and purged later, but it also protects against a flood of malicious update requests + // from an IP which would be able to "reroute" all contacts to itself and by that making them useless if (pContact->GetIPAddress() == uNewIP) return true; @@ -325,14 +320,14 @@ bool CRoutingBin::ChangeContactIPAddress(CContact *pContact, uint32 uNewIP) return false; } - uint32 cSameSubnets = 0; + uint32 uSameSubnet = 0; // Check if we already have a contact with this ID in the list. - for (ContactList::const_iterator itContactList = m_listEntries.begin(); itContactList != m_listEntries.end(); ++itContactList) - cSameSubnets += static_cast(((uNewIP ^ (*itContactList)->GetIPAddress()) & ~0xFF) == 0); + for (ContactList::const_iterator itContact = m_listEntries.begin(); itContact != m_listEntries.end(); ++itContact) + uSameSubnet += static_cast(((uNewIP ^ (*itContact)->GetIPAddress()) & ~0xFF) == 0); // no more than 2 IPs from the same /24 block in one bin, except if it's a LAN IP // (if we don't accept LAN IPs, they already have been filtered before) - if (cSameSubnets >= 2 && !IsLANIP(ntohl(uNewIP))) { + if (uSameSubnet >= 2 && !IsLANIP(ntohl(uNewIP))) { if (thePrefs.GetLogFilteredIPs()) AddDebugLogLine(false, _T("Rejected kad contact ip change on update (old IP=%s, requested IP=%s) - too many contacts with the same Subnet (local)"), (LPCTSTR)ipstr(pContact->GetNetIP()), (LPCTSTR)ipstr(htonl(uNewIP))); return false; @@ -359,18 +354,17 @@ CContact* CRoutingBin::GetRandomContact(uint32 nMaxType, uint32 nMinKadVersion) { if (m_listEntries.empty()) return NULL; - // Find contact with IP/Port + // Find contact with a suitable version CContact *pLastFit = NULL; - uint32 nRandomStartPos = GetRandomUInt16() % m_listEntries.size(); - uint32 nIndex = 0; - for (ContactList::const_iterator itContactList = m_listEntries.begin(); itContactList != m_listEntries.end(); ++itContactList) { - CContact *pContact = *itContactList; + int iRandomStartPos = rand() % m_listEntries.size(); + for (ContactList::const_iterator itContact = m_listEntries.begin(); itContact != m_listEntries.end(); ++itContact) { + CContact *pContact = *itContact; if (pContact->GetType() <= nMaxType && pContact->GetVersion() >= nMinKadVersion) { - if (nIndex >= nRandomStartPos) + if (iRandomStartPos <= 0) return pContact; pLastFit = pContact; } - ++nIndex; + --iRandomStartPos; } return pLastFit; } @@ -378,8 +372,8 @@ CContact* CRoutingBin::GetRandomContact(uint32 nMaxType, uint32 nMinKadVersion) void CRoutingBin::SetAllContactsVerified() { // Find contact by ID. - for (ContactList::const_iterator itContactList = m_listEntries.begin(); itContactList != m_listEntries.end(); ++itContactList) - (*itContactList)->SetIpVerified(true); + for (ContactList::const_iterator itContact = m_listEntries.begin(); itContact != m_listEntries.end(); ++itContact) + (*itContact)->SetIpVerified(true); } bool CRoutingBin::CheckGlobalIPLimits(uint32 uIP, uint16 uPort, bool bLog) @@ -408,8 +402,8 @@ bool CRoutingBin::CheckGlobalIPLimits(uint32 uIP, uint16 uPort, bool bLog) bool CRoutingBin::HasOnlyLANNodes() const { - for (ContactList::const_iterator itContactList = m_listEntries.begin(); itContactList != m_listEntries.end(); ++itContactList) - if (!IsLANIP((*itContactList)->GetNetIP())) + for (ContactList::const_iterator itContact = m_listEntries.begin(); itContact != m_listEntries.end(); ++itContact) + if (!IsLANIP((*itContact)->GetNetIP())) return false; return true; diff --git a/srchybrid/kademlia/routing/RoutingBin.h b/srchybrid/kademlia/routing/RoutingBin.h index 3e3f7f08..116712fb 100644 --- a/srchybrid/kademlia/routing/RoutingBin.h +++ b/srchybrid/kademlia/routing/RoutingBin.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -29,7 +29,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -54,8 +54,8 @@ namespace Kademlia UINT GetSize() const; void GetNumContacts(uint32 &nInOutContacts, uint32 &nInOutFilteredContacts, uint8 byMinVersion) const; UINT GetRemaining() const; - void GetEntries(ContactList *plistResult, bool bEmptyFirst = true); - void GetClosestTo(uint32 uMaxType, const CUInt128 &uTarget, uint32 uMaxRequired, ContactMap *pmapResult, bool bEmptyFirst = true, bool bSetInUse = false); + void GetEntries(ContactArray &listResult, bool bEmptyFirst = true); + void GetClosestTo(uint32 uMaxType, const CUInt128 &uTarget, uint32 uMaxRequired, ContactMap &rmapResult, bool bEmptyFirst = true, bool bSetInUse = false); bool ChangeContactIPAddress(CContact *pContact, uint32 uNewIP); void PushToBottom(CContact *pContact); // puts an existing contact from X to the end of the list CContact* GetRandomContact(uint32 nMaxType, uint32 nMinKadVersion); diff --git a/srchybrid/kademlia/routing/RoutingZone.cpp b/srchybrid/kademlia/routing/RoutingZone.cpp index 1adae788..475bf38e 100644 --- a/srchybrid/kademlia/routing/RoutingZone.cpp +++ b/srchybrid/kademlia/routing/RoutingZone.cpp @@ -1,6 +1,6 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) -Copyright (C)2007-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) +Copyright (C)2007-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -30,7 +30,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -82,9 +82,9 @@ CRoutingZone::CRoutingZone() { // Can only create routing zone after prefs // Set our KadID for creating the contact tree - CKademlia::GetPrefs()->GetKadID(&uMe); - // Set the preference file name. - m_sFilename = thePrefs.GetMuleDirectory(EMULE_CONFIGDIR) + _T("nodes.dat"); + CKademlia::GetPrefs()->GetKadID(uMe); + // Set the nodes file name. + m_sFilename.Format(_T("%s") _T("nodes.dat"), (LPCTSTR)thePrefs.GetMuleDirectory(EMULE_CONFIGDIR)); // Init our root node. Init(NULL, 0, CUInt128(0ul)); } @@ -93,7 +93,7 @@ CRoutingZone::CRoutingZone(LPCSTR szFilename) { // Can only create routing zone after prefs // Set our KadID for creating the contact tree - CKademlia::GetPrefs()->GetKadID(&uMe); + CKademlia::GetPrefs()->GetKadID(uMe); m_sFilename = szFilename; // Init our root node. Init(NULL, 0, CUInt128(0ul)); @@ -172,7 +172,7 @@ void CRoutingZone::ReadFile(const CString &strSpecialNodesdate) CSafeBufferedFile file; CFileException fexp; if (file.Open(strSpecialNodesdate.IsEmpty() ? m_sFilename : strSpecialNodesdate, CFile::modeRead | CFile::osSequentialScan | CFile::typeBinary | CFile::shareDenyWrite, &fexp)) { - setvbuf(file.m_pStream, NULL, _IOFBF, 32768); + ::setvbuf(file.m_pStream, NULL, _IOFBF, 32768); // Get how many contacts in the saved list. // NOTE: Older clients put the number of contacts here. @@ -204,7 +204,7 @@ void CRoutingZone::ReadFile(const CString &strSpecialNodesdate) uint32 uValidContacts = 0; CUInt128 uID; while (uNumContacts--) { - file.ReadUInt128(&uID); + file.ReadUInt128(uID); uint32 uIP = file.ReadUInt32(); uint16 uUDPPort = file.ReadUInt16(); uint16 uTCPPort = file.ReadUInt16(); @@ -277,7 +277,7 @@ void CRoutingZone::ReadBootstrapNodesDat(CFileDataIO &file) uint32 uValidContacts = 0; CUInt128 uID; while (uNumContacts--) { - file.ReadUInt128(&uID); + file.ReadUInt128(uID); uint32 uIP = file.ReadUInt32(); uint16 uUDPPort = file.ReadUInt16(); uint16 uTCPPort = file.ReadUInt16(); @@ -292,13 +292,14 @@ void CRoutingZone::ReadBootstrapNodesDat(CFileDataIO &file) if (thePrefs.GetLogFilteredIPs()) AddDebugLogLine(false, _T("Ignored kad contact (IP=%s:%u)--read known.dat"), (LPCTSTR)ipstr(uhostIP), uUDPPort); } else if (uContactVersion > 1) { // only kad2 nodes - // we want the 50 nodes closest to our own ID (provides randomness between different users and gets has good chances to get a bootstrap with close Nodes which is a nice start for our routing table) + // we want 50 nodes closest to our own ID (provides randomness between different users and + // gives good chances to bootstrap with close Nodes as a nice start for our routing table) CUInt128 uDistance = uMe; uDistance.Xor(uID); ++uValidContacts; // don't bother if we already have 50 and the farthest distance is smaller than this contact if (CKademlia::s_liBootstrapList.GetCount() < 50 || CKademlia::s_liBootstrapList.GetTail()->GetDistance() > uDistance) { - // look were to put this contact into the proper position + // look for the proper position where to insert this contact bool bInserted = false; CContact *pContact = new CContact(uID, uIP, uUDPPort, uTCPPort, uMe, uContactVersion, CKadUDPKey(), false); pContact->SetBootstrapContact(); @@ -346,28 +347,28 @@ void CRoutingZone::WriteFile() CSafeBufferedFile file; CFileException fexp; if (file.Open(m_sFilename, CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyWrite, &fexp)) { - setvbuf(file.m_pStream, NULL, _IOFBF, 32768); + ::setvbuf(file.m_pStream, NULL, _IOFBF, 32768); // The bootstrap method gets a very nice sample of contacts to save. - ContactList listContacts; - GetBootstrapContacts(&listContacts, 200); + ContactArray listContacts; + GetBootstrapContacts(listContacts, 200); // Start file with 0 to prevent older clients from reading it. file.WriteUInt32(0); // Now tag it with a version which happens to be 2 (1 till 0.48a). file.WriteUInt32(2); // file.WriteUInt32(0) // if we would use version >=3, this would mean that this is a normal nodes.dat file.WriteUInt32((uint32)listContacts.size()); - for (ContactList::const_iterator itContactList = listContacts.begin(); itContactList != listContacts.end(); ++itContactList) { + for (ContactArray::const_iterator itContact = listContacts.begin(); itContact != listContacts.end(); ++itContact) { CUInt128 uID; - const CContact *pContact = *itContactList; - pContact->GetClientID(&uID); - file.WriteUInt128(&uID); - file.WriteUInt32(pContact->GetIPAddress()); - file.WriteUInt16(pContact->GetUDPPort()); - file.WriteUInt16(pContact->GetTCPPort()); - file.WriteUInt8(pContact->GetVersion()); - pContact->GetUDPKey().StoreToFile(file); - file.WriteUInt8(static_cast(pContact->IsIpVerified())); + const CContact &rContact(**itContact); + rContact.GetClientID(uID); + file.WriteUInt128(uID); + file.WriteUInt32(rContact.GetIPAddress()); + file.WriteUInt16(rContact.GetUDPPort()); + file.WriteUInt16(rContact.GetTCPPort()); + file.WriteUInt8(rContact.GetVersion()); + rContact.GetUDPKey().StoreToFile(file); + file.WriteUInt8(static_cast(rContact.IsIpVerified())); } file.Close(); AddDebugLogLine(false, _T("Wrote %ld contact%s to file."), listContacts.size(), ((listContacts.size() == 1) ? _T("") : _T("s"))); @@ -389,16 +390,16 @@ void CRoutingZone::DbgWriteBootstrapFile() CSafeBufferedFile file; CFileException fexp; if (file.Open(m_sFilename, CFile::modeWrite | CFile::modeCreate | CFile::typeBinary | CFile::shareDenyWrite, &fexp)) { - setvbuf(file.m_pStream, NULL, _IOFBF, 32768); + ::setvbuf(file.m_pStream, NULL, _IOFBF, 32768); // The bootstrap method gets a very nice sample of contacts to save. ContactMap mapContacts; CUInt128 uRandom(CUInt128(0ul), 0); CUInt128 uDistance = uRandom; uDistance.Xor(uMe); - GetClosestTo(2, uRandom, uDistance, 1200, &mapContacts, false, false); + GetClosestTo(2, uRandom, uDistance, 1200, mapContacts, false, false); // filter out Kad1 nodes - for (ContactMap::const_iterator itContactMap = mapContacts.begin(); itContactMap != mapContacts.end(); ) { + for (ContactMap::const_iterator itContactMap = mapContacts.begin(); itContactMap != mapContacts.end();) { ContactMap::const_iterator itCurContactMap = itContactMap++; const CContact *pContact = itCurContactMap->second; if (pContact->GetVersion() <= 1) @@ -412,8 +413,8 @@ void CRoutingZone::DbgWriteBootstrapFile() file.WriteUInt32((uint32)mapContacts.size()); for (ContactMap::const_iterator itContactMap = mapContacts.begin(); itContactMap != mapContacts.end(); ++itContactMap) { const CContact *pContact = itContactMap->second; - pContact->GetClientID(&uID); - file.WriteUInt128(&uID); + pContact->GetClientID(uID); + file.WriteUInt128(uID); file.WriteUInt32(pContact->GetIPAddress()); file.WriteUInt16(pContact->GetUDPPort()); file.WriteUInt16(pContact->GetTCPPort()); @@ -567,7 +568,7 @@ bool CRoutingZone::Add(CContact *pContact, bool &bUpdate, bool &bOutIPVerified) bUpdate = false; // This bin is not full, so add the new contact. if (m_pBin->AddContact(pContact)) { - // Add was successful, add to the GUI and let contact know it's listed in the gui. + // Add was successful, add to the GUI and let the contact know it's listed in the GUI. if (theApp.emuledlg->kademliawnd->ContactAdd(pContact)) pContact->SetGuiRefs(true); return true; @@ -590,7 +591,7 @@ CContact* CRoutingZone::GetContact(const CUInt128 &uID) const return m_pBin->GetContact(uID); CUInt128 uDistance; - CKademlia::GetPrefs()->GetKadID(&uDistance); + CKademlia::GetPrefs()->GetKadID(uDistance); uDistance.Xor(uID); return m_pSubZones[uDistance.GetBitNumber(m_uLevel)]->GetContact(uID); } @@ -609,63 +610,61 @@ CContact* CRoutingZone::GetRandomContact(uint32 nMaxType, uint32 nMinKadVersion) if (IsLeaf()) return m_pBin->GetRandomContact(nMaxType, nMinKadVersion); - uint32 nZone = GetRandomUInt16() % 2; + uint32 nZone = rand() & 1; CContact *pContact = m_pSubZones[nZone]->GetRandomContact(nMaxType, nMinKadVersion); return (pContact != NULL) ? pContact : m_pSubZones[static_cast(nZone != 1)]->GetRandomContact(nMaxType, nMinKadVersion); } -void CRoutingZone::GetClosestTo(uint32 uMaxType, const CUInt128 &uTarget, const CUInt128 &uDistance, uint32 uMaxRequired, ContactMap *pmapResult, bool bEmptyFirst, bool bInUse) const +void CRoutingZone::GetClosestTo(uint32 uMaxType, const CUInt128 &uTarget, const CUInt128 &uDistance, uint32 uMaxRequired, ContactMap &rmapResult, bool bEmptyFirst, bool bInUse) const { // If leaf zone, do it here if (IsLeaf()) { - m_pBin->GetClosestTo(uMaxType, uTarget, uMaxRequired, pmapResult, bEmptyFirst, bInUse); + m_pBin->GetClosestTo(uMaxType, uTarget, uMaxRequired, rmapResult, bEmptyFirst, bInUse); return; } // otherwise, recurse in the closer-to-the-target subzone first int iCloser = uDistance.GetBitNumber(m_uLevel); - m_pSubZones[iCloser]->GetClosestTo(uMaxType, uTarget, uDistance, uMaxRequired, pmapResult, bEmptyFirst, bInUse); + m_pSubZones[iCloser]->GetClosestTo(uMaxType, uTarget, uDistance, uMaxRequired, rmapResult, bEmptyFirst, bInUse); // if still not enough tokens found, recurse in the other subzone too - if (pmapResult->size() < uMaxRequired) - m_pSubZones[1 - iCloser]->GetClosestTo(uMaxType, uTarget, uDistance, uMaxRequired, pmapResult, false, bInUse); + if (rmapResult.size() < uMaxRequired) + m_pSubZones[1 - iCloser]->GetClosestTo(uMaxType, uTarget, uDistance, uMaxRequired, rmapResult, false, bInUse); } -void CRoutingZone::GetAllEntries(ContactList *plistResult, bool bEmptyFirst) +void CRoutingZone::GetAllEntries(ContactArray &listResult, bool bEmptyFirst) { if (IsLeaf()) - m_pBin->GetEntries(plistResult, bEmptyFirst); + m_pBin->GetEntries(listResult, bEmptyFirst); else { - m_pSubZones[0]->GetAllEntries(plistResult, bEmptyFirst); - m_pSubZones[1]->GetAllEntries(plistResult, false); + m_pSubZones[0]->GetAllEntries(listResult, bEmptyFirst); + m_pSubZones[1]->GetAllEntries(listResult, false); } } -void CRoutingZone::TopDepth(int iDepth, ContactList *plistResult, bool bEmptyFirst) +void CRoutingZone::TopDepth(int iDepth, ContactArray &listResult, bool bEmptyFirst) { if (IsLeaf()) - m_pBin->GetEntries(plistResult, bEmptyFirst); + m_pBin->GetEntries(listResult, bEmptyFirst); else if (iDepth <= 0) - RandomBin(plistResult, bEmptyFirst); + RandomBin(listResult, bEmptyFirst); else { - m_pSubZones[0]->TopDepth(iDepth - 1, plistResult, bEmptyFirst); - m_pSubZones[1]->TopDepth(iDepth - 1, plistResult, false); + m_pSubZones[0]->TopDepth(iDepth - 1, listResult, bEmptyFirst); + m_pSubZones[1]->TopDepth(iDepth - 1, listResult, false); } } -void CRoutingZone::RandomBin(ContactList *plistResult, bool bEmptyFirst) +void CRoutingZone::RandomBin(ContactArray &listResult, bool bEmptyFirst) { if (IsLeaf()) - m_pBin->GetEntries(plistResult, bEmptyFirst); + m_pBin->GetEntries(listResult, bEmptyFirst); else - m_pSubZones[rand() & 1]->RandomBin(plistResult, bEmptyFirst); + m_pSubZones[rand() & 1]->RandomBin(listResult, bEmptyFirst); } uint32 CRoutingZone::GetMaxDepth() const { - if (IsLeaf()) - return 0; - return 1 + max(m_pSubZones[0]->GetMaxDepth(), m_pSubZones[1]->GetMaxDepth()); + return IsLeaf() ? 0 : 1 + max(m_pSubZones[0]->GetMaxDepth(), m_pSubZones[1]->GetMaxDepth()); } void CRoutingZone::Split() @@ -675,16 +674,16 @@ void CRoutingZone::Split() m_pSubZones[0] = GenSubZone(0); m_pSubZones[1] = GenSubZone(1); - ContactList listEntries; - m_pBin->GetEntries(&listEntries); + ContactArray listEntries; + m_pBin->GetEntries(listEntries); m_pBin->m_bDontDeleteContacts = true; delete m_pBin; m_pBin = NULL; - for (ContactList::const_iterator itContactList = listEntries.begin(); itContactList != listEntries.end(); ++itContactList) { - int iSuperZone = (*itContactList)->m_uDistance.GetBitNumber(m_uLevel); - if (!m_pSubZones[iSuperZone]->m_pBin->AddContact(*itContactList)) - delete *itContactList; + for (ContactArray::const_iterator itContact = listEntries.begin(); itContact != listEntries.end(); ++itContact) { + int iSuperZone = (*itContact)->m_uDistance.GetBitNumber(m_uLevel); + if (!m_pSubZones[iSuperZone]->m_pBin->AddContact(*itContact)) + delete *itContact; } } @@ -703,10 +702,10 @@ uint32 CRoutingZone::Consolidate() m_pSubZones[0]->StopTimer(); m_pSubZones[1]->StopTimer(); - ContactList list0; - ContactList list1; - m_pSubZones[0]->m_pBin->GetEntries(&list0); - m_pSubZones[1]->m_pBin->GetEntries(&list1); + ContactArray list0; + ContactArray list1; + m_pSubZones[0]->m_pBin->GetEntries(list0); + m_pSubZones[1]->m_pBin->GetEntries(list1); m_pSubZones[0]->m_pBin->m_bDontDeleteContacts = true; m_pSubZones[1]->m_pBin->m_bDontDeleteContacts = true; @@ -715,13 +714,13 @@ uint32 CRoutingZone::Consolidate() m_pSubZones[0] = NULL; m_pSubZones[1] = NULL; - for (ContactList::const_iterator itContactList = list0.begin(); itContactList != list0.end(); ++itContactList) - if (!m_pBin->AddContact(*itContactList)) - delete *itContactList; + for (ContactArray::const_iterator itContact = list0.begin(); itContact != list0.end(); ++itContact) + if (!m_pBin->AddContact(*itContact)) + delete *itContact; - for (ContactList::const_iterator itContactList = list1.begin(); itContactList != list1.end(); ++itContactList) - if (!m_pBin->AddContact(*itContactList)) - delete *itContactList; + for (ContactArray::const_iterator itContact = list1.begin(); itContact != list1.end(); ++itContact) + if (!m_pBin->AddContact(*itContact)) + delete *itContact; StartTimer(); ++uMergeCount; @@ -776,7 +775,7 @@ uint32 CRoutingZone::EstimateCount() return (uint32)(pow(2.0F, (int)m_uLevel)*K); CRoutingZone *pCurZone = m_pSuperZone->m_pSuperZone->m_pSuperZone; // Find out how full this part of the tree is. - float fModify = pCurZone->GetNumContacts() / (K*2.0f); + float fModify = pCurZone->GetNumContacts() / (K * 2.0f); // First calculate users assuming the tree is full. // Modify count by bin size. // Modify count by how full the tree is. @@ -802,7 +801,7 @@ uint32 CRoutingZone::EstimateCount() fFirewalledModifyTotal = fFirewalledModifyOld; ASSERT(fFirewalledModifyTotal > 1.0F && fFirewalledModifyTotal < 1.90F); - return (uint32)(pow(2.0F, (int)m_uLevel - 2)*K*fModify*fFirewalledModifyTotal); + return (uint32)(pow(2.0F, (int)m_uLevel - 2) * K * fModify * fFirewalledModifyTotal); } void CRoutingZone::OnSmallTimer() @@ -812,11 +811,11 @@ void CRoutingZone::OnSmallTimer() CContact *pContact = NULL; time_t tNow = time(NULL); - ContactList listEntries; + ContactArray listEntries; // Remove dead entries - m_pBin->GetEntries(&listEntries); - for (ContactList::const_iterator itContactList = listEntries.begin(); itContactList != listEntries.end(); ++itContactList) { - pContact = *itContactList; + m_pBin->GetEntries(listEntries); + for (ContactArray::const_iterator itContact = listEntries.begin(); itContact != listEntries.end(); ++itContact) { + pContact = *itContact; if (pContact->GetType() == 4) { if (((pContact->m_tExpires > 0) && (pContact->m_tExpires <= tNow))) { if (!pContact->InUse()) { @@ -845,11 +844,12 @@ void CRoutingZone::OnSmallTimer() CKademlia::GetUDPListener()->SendMyDetails(KADEMLIA2_HELLO_REQ, pContact->GetIPAddress(), pContact->GetUDPPort(), pContact->GetVersion(), pContact->GetUDPKey(), &uClientID, false); if (pContact->GetVersion() >= KADEMLIA_VERSION8_49b) { // FIXME: - // This is a bit of a work around for statistic values. Normally we only count values from incoming HELLO_REQs for - // the firewalled statistics in order to get numbers from nodes which have us on their routing table, - // however if we send a HELLO due to the timer, the remote node won't send a HELLO_REQ itself any more (but - // a HELLO_RES which we don't count), so count those statistics here. This isn't really accurate, but it should - // do fair enough. Maybe improve it later for example by putting a flag into the contact and make the answer count + // This is a bit of a work around for statistic values. Normally we only count values from + // incoming HELLO_REQs for the firewalled statistics in order to get numbers from nodes + // which have us on their routing table, however if we send a HELLO due to the timer, + // the remote node won't send a HELLO_REQ itself any more (but a HELLO_RES which we don't count), + // so count those statistics here. This isn't really accurate, but it should do fair enough. + // Maybe improve it later for example by putting a flag into the contact and make the answer count CKademlia::GetPrefs()->StatsIncUDPFirewalledNodes(false); CKademlia::GetPrefs()->StatsIncTCPFirewalledNodes(false); } @@ -890,17 +890,17 @@ void CRoutingZone::GetNumContacts(uint32 &nInOutContacts, uint32 &nInOutFiltered } } -uint32 CRoutingZone::GetBootstrapContacts(ContactList *plistResult, uint32 uMaxRequired) +uint32 CRoutingZone::GetBootstrapContacts(ContactArray &rlistResult, uint32 uMaxRequired) { ASSERT(m_pSuperZone == NULL); - plistResult->clear(); + rlistResult.clear(); uint32 uRetVal = 0; try { - ContactList top; - TopDepth(LOG_BASE_EXPONENT, &top); + ContactArray top; + TopDepth(LOG_BASE_EXPONENT, top); if (!top.empty()) { - for (ContactList::const_iterator itContactList = top.begin(); itContactList != top.end(); ++itContactList) { - plistResult->push_back(*itContactList); + for (ContactArray::const_iterator itContact = top.begin(); itContact != top.end(); ++itContact) { + rlistResult.push_back(*itContact); if (++uRetVal >= uMaxRequired) break; } diff --git a/srchybrid/kademlia/routing/RoutingZone.h b/srchybrid/kademlia/routing/RoutingZone.h index bb457197..34ad00e7 100644 --- a/srchybrid/kademlia/routing/RoutingZone.h +++ b/srchybrid/kademlia/routing/RoutingZone.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -29,7 +29,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -74,12 +74,12 @@ namespace Kademlia // Check if we know a contact with the same ID or IP but non-matching IP/ID and other limitations, similar checks like when adding a node to the table except allowing duplicates bool IsAcceptableContact(const CContact *pToCheck) const; // Returns a list of all contacts in all leafs of this zone. - void GetAllEntries(ContactList *plistResult, bool bEmptyFirst = true); + void GetAllEntries(ContactArray &listResult, bool bEmptyFirst = true); // Returns the *maxRequired* tokens that are closest to the target within this zone's subtree. - void GetClosestTo(uint32 uMaxType, const CUInt128 &uTarget, const CUInt128 &uDistance, uint32 uMaxRequired, ContactMap *plistResult, bool bEmptyFirst = true, bool bSetInUse = false) const; + void GetClosestTo(uint32 uMaxType, const CUInt128 &uTarget, const CUInt128 &uDistance, uint32 uMaxRequired, ContactMap &rlistResult, bool bEmptyFirst = true, bool bSetInUse = false) const; // Ideally: Returns all contacts that are in buckets of common range between us and the asker. // In practice: returns the contacts from the top (2^{logBase+1}) buckets. - uint32 GetBootstrapContacts(ContactList *plistResult, uint32 uMaxRequired); + uint32 GetBootstrapContacts(ContactArray &rlistResult, uint32 uMaxRequired); uint32 EstimateCount(); bool HasOnlyLANNodes() const; time_t m_tNextBigTimer; @@ -94,10 +94,10 @@ namespace Kademlia bool IsLeaf() const; bool CanSplit() const; // Returns all contacts from this zone tree that are no deeper than *depth* from the current zone. - void TopDepth(int iDepth, ContactList *plistResult, bool bEmptyFirst = true); + void TopDepth(int iDepth, ContactArray &listResult, bool bEmptyFirst = true); // Returns the maximum depth of the tree as the number of edges of the longest path to a leaf. UINT GetMaxDepth() const; - void RandomBin(ContactList *plistResult, bool bEmptyFirst = true); + void RandomBin(ContactArray &listResult, bool bEmptyFirst = true); void Split(); void StartTimer(); void StopTimer(); diff --git a/srchybrid/kademlia/utils/KadClientSearcher.h b/srchybrid/kademlia/utils/KadClientSearcher.h index 94d7ec80..637af63f 100644 --- a/srchybrid/kademlia/utils/KadClientSearcher.h +++ b/srchybrid/kademlia/utils/KadClientSearcher.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -16,7 +16,7 @@ //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #pragma once -// Interface class for non-kad classes which want to do clientsearches +// Interface class for non-kad classes which want to do client searches namespace Kademlia { enum EKadClientSearchRes @@ -29,8 +29,9 @@ namespace Kademlia class CKadClientSearcher { public: - virtual ~CKadClientSearcher() = default; //just in case... virtual void KadSearchNodeIDByIPResult(EKadClientSearchRes eStatus, const uchar *pachNodeID) = 0; virtual void KadSearchIPByNodeIDResult(EKadClientSearchRes eStatus, uint32 dwIP, uint16 nPort) = 0; + protected: + virtual ~CKadClientSearcher() = default; }; } \ No newline at end of file diff --git a/srchybrid/kademlia/utils/KadUDPKey.h b/srchybrid/kademlia/utils/KadUDPKey.h index 2132ced1..30aedd48 100644 --- a/srchybrid/kademlia/utils/KadUDPKey.h +++ b/srchybrid/kademlia/utils/KadUDPKey.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2008 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License diff --git a/srchybrid/kademlia/utils/LookupHistory.cpp b/srchybrid/kademlia/utils/LookupHistory.cpp index 2f02a161..18ed8466 100644 --- a/srchybrid/kademlia/utils/LookupHistory.cpp +++ b/srchybrid/kademlia/utils/LookupHistory.cpp @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2010-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -60,14 +60,14 @@ void CLookupHistory::SetGUIDeleted() void CLookupHistory::ContactReceived(CContact *pRecContact, CContact *pFromContact, const CUInt128 &uDistance, bool bCloser, bool bForceInteresting) { // Do we know this contact already? If pRecContact is NULL we only set the responded flag to the pFromContact - for (int i = (int)m_aHistoryEntries.GetCount(); --i >= 0;) + for (INT_PTR i = m_aHistoryEntries.GetCount(); --i >= 0;) if (uDistance == m_aHistoryEntries[i]->m_uDistance || pRecContact == NULL) { if (pFromContact != NULL) { int iIdx = GetInterestingContactIdxByID(pFromContact->GetClientID()); if (iIdx >= 0) { if (pRecContact != NULL) m_aHistoryEntries[i]->m_liReceivedFromIdx.Add(iIdx); - m_aIntrestingHistoryEntries[iIdx]->m_uRespondedContact++; + ++m_aIntrestingHistoryEntries[iIdx]->m_uRespondedContact; if (bCloser) m_aIntrestingHistoryEntries[iIdx]->m_bProvidedCloser = true; } @@ -85,7 +85,7 @@ void CLookupHistory::ContactReceived(CContact *pRecContact, CContact *pFromConta int iIdx = GetInterestingContactIdxByID(pFromContact->GetClientID()); if (iIdx >= 0) { pstructNewEntry->m_liReceivedFromIdx.Add(iIdx); - m_aIntrestingHistoryEntries[iIdx]->m_uRespondedContact++; + ++m_aIntrestingHistoryEntries[iIdx]->m_uRespondedContact; if (bCloser) m_aIntrestingHistoryEntries[iIdx]->m_bProvidedCloser = true; } @@ -104,7 +104,7 @@ void CLookupHistory::ContactReceived(CContact *pRecContact, CContact *pFromConta void CLookupHistory::ContactAskedKad(const CContact *pContact) { // Find contact - for (int i = (int)m_aHistoryEntries.GetCount(); --i >= 0;) + for (INT_PTR i = m_aHistoryEntries.GetCount(); --i >= 0;) if (pContact->GetClientID() == m_aHistoryEntries[i]->m_uContactID) { if (!m_aHistoryEntries[i]->IsInteresting()) m_aIntrestingHistoryEntries.Add(m_aHistoryEntries[i]); @@ -117,9 +117,9 @@ void CLookupHistory::ContactAskedKad(const CContact *pContact) int CLookupHistory::GetInterestingContactIdxByID(const CUInt128 &uContact) const { - for (int i = (int)m_aIntrestingHistoryEntries.GetCount(); --i >= 0;) + for (INT_PTR i = m_aIntrestingHistoryEntries.GetCount(); --i >= 0;) if (uContact == m_aIntrestingHistoryEntries[i]->m_uContactID) - return i; + return (int)i; ASSERT(0); return -1; @@ -128,7 +128,7 @@ int CLookupHistory::GetInterestingContactIdxByID(const CUInt128 &uContact) const void CLookupHistory::ContactAskedKeyword(const CContact *pContact) { // Find contact - for (int i = (int)m_aHistoryEntries.GetCount(); --i >= 0;) + for (INT_PTR i = m_aHistoryEntries.GetCount(); --i >= 0;) if (pContact->GetClientID() == m_aHistoryEntries[i]->m_uContactID) { if (!m_aHistoryEntries[i]->IsInteresting()) m_aIntrestingHistoryEntries.Add(m_aHistoryEntries[i]); @@ -142,7 +142,7 @@ void CLookupHistory::ContactAskedKeyword(const CContact *pContact) void CLookupHistory::ContactRespondedKeyword(uint32 uContactIP, uint16 uContactUDPPort, uint32 uResultCount) { - for (int i = (int)m_aIntrestingHistoryEntries.GetCount(); --i >= 0;) + for (INT_PTR i = m_aIntrestingHistoryEntries.GetCount(); --i >= 0;) if ((m_aIntrestingHistoryEntries[i]->m_uIP == uContactIP) && (m_aIntrestingHistoryEntries[i]->m_uPort == uContactUDPPort)) { ASSERT(m_aIntrestingHistoryEntries[i]->m_dwAskedSearchItemTime > 0 || m_uType == CSearch::NODE || m_uType == CSearch::NODEFWCHECKUDP); m_aIntrestingHistoryEntries[i]->m_uRespondedSearchItem += uResultCount; diff --git a/srchybrid/kademlia/utils/LookupHistory.h b/srchybrid/kademlia/utils/LookupHistory.h index aaa3b1ab..1c5e9ff8 100644 --- a/srchybrid/kademlia/utils/LookupHistory.h +++ b/srchybrid/kademlia/utils/LookupHistory.h @@ -1,5 +1,5 @@ //this file is part of eMule -//Copyright (C)2002-2010 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net ) +//Copyright (C)2002-2023 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / https://www.emule-project.net ) // //This program is free software; you can redistribute it and/or //modify it under the terms of the GNU General Public License @@ -28,10 +28,10 @@ namespace Kademlia { CUInt128 m_uContactID; CUInt128 m_uDistance; - CArray m_liReceivedFromIdx; - uint32 m_dwAskedContactsTime; + CArray m_liReceivedFromIdx; + DWORD m_dwAskedContactsTime; uint32 m_uRespondedContact; - uint32 m_dwAskedSearchItemTime; + DWORD m_dwAskedSearchItemTime; uint32 m_uRespondedSearchItem; uint32 m_uIP; uint16 m_uPort; diff --git a/srchybrid/kademlia/utils/MiscUtils.cpp b/srchybrid/kademlia/utils/MiscUtils.cpp index 3a9c0fe2..8cf26e78 100644 --- a/srchybrid/kademlia/utils/MiscUtils.cpp +++ b/srchybrid/kademlia/utils/MiscUtils.cpp @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -40,12 +40,10 @@ static char THIS_FILE[] = __FILE__; using namespace Kademlia; -//CString CMiscUtils::m_sAppDirectory; - -void CMiscUtils::IPAddressToString(uint32 uIP, CString *pString) +void CMiscUtils::IPAddressToString(uint32 uIP, CString &sAddr) { const BYTE *pucIP = (BYTE*)&uIP; - pString->Format(_T("%u.%u.%u.%u"), pucIP[3], pucIP[2], pucIP[1], pucIP[0]); + sAddr.Format(_T("%u.%u.%u.%u"), pucIP[3], pucIP[2], pucIP[1], pucIP[0]); } diff --git a/srchybrid/kademlia/utils/MiscUtils.h b/srchybrid/kademlia/utils/MiscUtils.h index c40c4084..ada030dd 100644 --- a/srchybrid/kademlia/utils/MiscUtils.h +++ b/srchybrid/kademlia/utils/MiscUtils.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -35,11 +35,9 @@ namespace Kademlia class CMiscUtils { public: - static void IPAddressToString(uint32 uIP, CString *pString); + static void IPAddressToString(uint32 uIP, CString &sAddr); #ifdef DEBUG static void DebugHexDump(const byte *pbyData, uint32 uLenData); #endif - //private: - // static CString m_sAppDirectory; }; } \ No newline at end of file diff --git a/srchybrid/kademlia/utils/ThreadName.cpp b/srchybrid/kademlia/utils/ThreadName.cpp index 916e6dfc..238ed982 100644 --- a/srchybrid/kademlia/utils/ThreadName.cpp +++ b/srchybrid/kademlia/utils/ThreadName.cpp @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ diff --git a/srchybrid/kademlia/utils/ThreadName.h b/srchybrid/kademlia/utils/ThreadName.h index d714eb1b..340dffa1 100644 --- a/srchybrid/kademlia/utils/ThreadName.h +++ b/srchybrid/kademlia/utils/ThreadName.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ diff --git a/srchybrid/kademlia/utils/UInt128.cpp b/srchybrid/kademlia/utils/UInt128.cpp index f7d66499..ddd09d94 100644 --- a/srchybrid/kademlia/utils/UInt128.cpp +++ b/srchybrid/kademlia/utils/UInt128.cpp @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,13 +23,13 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ #include "stdafx.h" -#include +#include "cryptopp/osrng.h" #include "kademlia/utils/UInt128.h" #ifdef _DEBUG @@ -158,32 +158,32 @@ CUInt128& CUInt128::XorBE(const byte *pbyValueBE) return Xor(CUInt128(pbyValueBE)); } -void CUInt128::ToHexString(CString *pstr) const +void CUInt128::ToHexString(CString &str) const { - pstr->Empty(); + str.Empty(); for (int iIndex = 0; iIndex < 4; ++iIndex) - pstr->AppendFormat(_T("%08lX"), m_uData[iIndex]); + str.AppendFormat(_T("%08lX"), m_uData[iIndex]); } CString CUInt128::ToHexString() const { CString str; - ToHexString(&str); + ToHexString(str); return str; } -void CUInt128::ToBinaryString(CString *pstr, bool bTrim) const +void CUInt128::ToBinaryString(CString &str, bool bTrim) const { - pstr->Empty(); + str.Empty(); for (int iIndex = 0; iIndex < 128; ++iIndex) { int iBit = GetBitNumber(iIndex); - if (!bTrim || (iBit != 0)) { - *pstr += iBit ? _T('1') : _T('0'); + if (!bTrim || iBit) { + str += TCHAR(_T('0') + iBit); bTrim = false; } } - if (pstr->IsEmpty()) - *pstr += _T('0'); + if (str.IsEmpty()) + str += _T('0'); } void CUInt128::ToByteArray(byte *pby) const @@ -222,7 +222,7 @@ CUInt128& CUInt128::Add(const CUInt128 &uValue) if (uValue == 0) return *this; __int64 iSum = 0; - for (int iIndex = 4; --iIndex >= 0; ) { + for (int iIndex = 4; --iIndex >= 0;) { iSum += m_uData[iIndex]; iSum += uValue.m_uData[iIndex]; m_uData[iIndex] = (ULONG)iSum; @@ -295,8 +295,7 @@ CUInt128& CUInt128::ShiftLeft(UINT uBits) uResult[iIndex - iIndexShift] = (ULONG)iShifted; iShifted = iShifted >> 32; } - for (int iIndex = 4; --iIndex >= 0;) - m_uData[iIndex] = uResult[iIndex]; + memcpy(m_uData, uResult, sizeof uResult); return *this; } diff --git a/srchybrid/kademlia/utils/UInt128.h b/srchybrid/kademlia/utils/UInt128.h index df15d61b..d8e918bb 100644 --- a/srchybrid/kademlia/utils/UInt128.h +++ b/srchybrid/kademlia/utils/UInt128.h @@ -1,5 +1,5 @@ /* -Copyright (C)2003 Barry Dunne (http://www.emule-project.net) +Copyright (C)2003 Barry Dunne (https://www.emule-project.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -23,7 +23,7 @@ There is going to be a new forum created just for the Kademlia side of the clien If you feel there is an error or a way to improve something, please post it in the forum first and let us look at it. If it is a real improvement, it will be added to the official client. Changing something without knowing -what all it does can cause great harm to the network if released in mass form. +what all it does, can cause great harm to the network if released in mass form. Any mod that changes anything within the Kademlia side will not be allowed to advertise their client on the eMule forum. */ @@ -49,9 +49,9 @@ namespace Kademlia UINT GetBitNumber(UINT uBit) const; int CompareTo(const CUInt128 &uOther) const; int CompareTo(ULONG uValue) const; - void ToHexString(CString *pstr) const; + void ToHexString(CString &str) const; CString ToHexString() const; - void ToBinaryString(CString *pstr, bool bTrim = false) const; + void ToBinaryString(CString &str, bool bTrim = false) const; void ToByteArray(byte *pby) const; ULONG Get32BitChunk(int iVal) const; CUInt128& SetValue(const CUInt128 &uValue); diff --git a/srchybrid/lang/ar_AE.rc b/srchybrid/lang/ar_AE.rc index be771d51..8b688fce 100644 --- a/srchybrid/lang/ar_AE.rc +++ b/srchybrid/lang/ar_AE.rc @@ -471,7 +471,7 @@ BEGIN IDS_GLOBALSEARCH "عالمي (Server)" IDS_METHOD "طريقة" IDS_UNDO "تراجع" - IDS_DAYLY "يومي" + IDS_DAILY "يومي" END STRINGTABLE @@ -1488,7 +1488,7 @@ BEGIN IDS_EM_HELP "&مساعدة" IDS_WRN_FRIENDDUPLIPPORT "صديق لم يضف.\r\n\r\nهناك صديق متوفر بنفس الاي بي و البورت." - IDS_DYNUP "رفع بحاسة السرعة" + IDS_DYNUP "رفع بحاسة السرعة (غير منصوح به)" IDS_KADOVERHEAD "Kad راس (Packets): %s (%s)" IDS_FIND "جد..." IDS_LOG_BANNED_CLIENTS "عملاء مطرودين" @@ -1602,7 +1602,7 @@ BEGIN IDS_CHAT_DOWNLOADED "حمل:" IDS_CHAT_UPLOADED "رفع:" IDS_CHAT_IDENT "كشف الهوية:" - IDS_MAXHALFOPENCONS "الحد الاقصى: نصف الاتصالات المفتوحة" + IDS_MAXHALFOPENCONS "الحد الأقصى للاتصالات نصف المفتوحة" IDS_WIZ_STARTWITHWINDOWS "فعل هذا الاختيار لبدأ ايمول عند بدأ الويندوز. [معطل تلقائياً]" IDS_KAD_WAITCBK "انتظر الرد من Kad " diff --git a/srchybrid/lang/ar_AE.vcxproj b/srchybrid/lang/ar_AE.vcxproj index 8abd6e0a..44e9e626 100644 --- a/srchybrid/lang/ar_AE.vcxproj +++ b/srchybrid/lang/ar_AE.vcxproj @@ -14,82 +14,45 @@ languages - Arabic (UAE) {A710033C-F75A-4431-96AA-876A9867A2F8} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)ar_AE.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)ar_AE.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/ba_BA.rc b/srchybrid/lang/ba_BA.rc index c8e35954..1716840b 100644 --- a/srchybrid/lang/ba_BA.rc +++ b/srchybrid/lang/ba_BA.rc @@ -428,7 +428,7 @@ BEGIN IDS_GLOBALSEARCH "Globala (Zerbitzaria)" IDS_METHOD "Metodoa" IDS_UNDO "Desegin" - IDS_DAYLY "egunero" + IDS_DAILY "egunero" END STRINGTABLE @@ -1451,7 +1451,7 @@ BEGIN IDS_EM_HELP "Laguntza" IDS_WRN_FRIENDDUPLIPPORT "Laguna ez da gehitu.\r\n\r\nBadago dagoeneko IP eta portu berdina dituen lagun bat." - IDS_DYNUP "Igoera abiadura sentsorea" + IDS_DYNUP "Igoera abiadura sentsorea (ez da gomendagarria)" IDS_KADOVERHEAD "Kad trafiko gainkarga (paketeak): %s (%s)" IDS_FIND "Aurkitu..." IDS_LOG_BANNED_CLIENTS "Blokeatutako bezeroak log fitxategian gorde" diff --git a/srchybrid/lang/ba_BA.vcxproj b/srchybrid/lang/ba_BA.vcxproj index 2ce73f33..cd44b4c8 100644 --- a/srchybrid/lang/ba_BA.vcxproj +++ b/srchybrid/lang/ba_BA.vcxproj @@ -14,82 +14,45 @@ languages - Basque {EAEEB94B-AA03-4E8D-8135-D02D22FBD422} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)ba_BA.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)ba_BA.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/bg_BG.rc b/srchybrid/lang/bg_BG.rc index 00c3baf9..0adf8dfa 100644 --- a/srchybrid/lang/bg_BG.rc +++ b/srchybrid/lang/bg_BG.rc @@ -471,7 +471,7 @@ BEGIN IDS_GLOBALSEARCH "Глобално" IDS_METHOD "Метод" IDS_UNDO "Отмени" - IDS_DAYLY "Ежедневно" + IDS_DAILY "Ежедневно" END STRINGTABLE @@ -1492,7 +1492,7 @@ BEGIN IDS_EM_HELP "Помощ" IDS_WRN_FRIENDDUPLIPPORT "Приятелят не е добавен.\r\n\r\nВече съществува приятел със същият IP адрес и порт." - IDS_DYNUP "'Умно' качване" + IDS_DYNUP "'Умно' качване (не се препоръчва)" IDS_KADOVERHEAD "Превишение за Kad (пакета): %s (%s)" IDS_FIND "Търси..." IDS_LOG_BANNED_CLIENTS "Отчет за забранените клиенти" diff --git a/srchybrid/lang/bg_BG.vcxproj b/srchybrid/lang/bg_BG.vcxproj index 86bf0cb1..5f671524 100644 --- a/srchybrid/lang/bg_BG.vcxproj +++ b/srchybrid/lang/bg_BG.vcxproj @@ -14,82 +14,45 @@ languages - Bulgarian {44716561-6BA7-40DA-AE7F-F3FFB422E86D} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)bg_BG.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)bg_BG.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/ca_ES.rc b/srchybrid/lang/ca_ES.rc index 1f74400f..05950284 100644 --- a/srchybrid/lang/ca_ES.rc +++ b/srchybrid/lang/ca_ES.rc @@ -422,7 +422,7 @@ BEGIN IDS_GLOBALSEARCH "Global (Servidor)" IDS_METHOD "Mètode" IDS_UNDO "Desfer" - IDS_DAYLY "diari" + IDS_DAILY "diari" END STRINGTABLE @@ -1427,7 +1427,7 @@ BEGIN IDS_EM_HELP "A&juda" IDS_WRN_FRIENDDUPLIPPORT "Amic no afegit.\r\n\r\Ja existeix un amic amb la mateixa adreça IP i port disponible." - IDS_DYNUP "Sensor de Velocitat de Pujada" + IDS_DYNUP "Sensor de Velocitat de Pujada (no es recomana)" IDS_KADOVERHEAD "Tràfic excedent Kad (Paquets): %s (%s)" IDS_FIND "Trobar..." IDS_LOG_BANNED_CLIENTS "Registrar clients exclosos" diff --git a/srchybrid/lang/ca_ES.vcxproj b/srchybrid/lang/ca_ES.vcxproj index 2b7310b5..35df62c4 100644 --- a/srchybrid/lang/ca_ES.vcxproj +++ b/srchybrid/lang/ca_ES.vcxproj @@ -14,82 +14,45 @@ languages - Catalan {0C96EF73-186D-4888-BB53-EECE60B55647} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)ca_ES.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)ca_ES.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/cz_CZ.rc b/srchybrid/lang/cz_CZ.rc index 0e107fa7..5b0c5539 100644 --- a/srchybrid/lang/cz_CZ.rc +++ b/srchybrid/lang/cz_CZ.rc @@ -461,7 +461,7 @@ BEGIN IDS_GLOBALSEARCH "Globální (Server)" IDS_METHOD "Metoda" IDS_UNDO "Zpět" - IDS_DAYLY "denně" + IDS_DAILY "denně" END STRINGTABLE @@ -1427,7 +1427,7 @@ BEGIN IDS_EM_HELP "&Nápověda" IDS_WRN_FRIENDDUPLIPPORT "Přítel nepřidán.\r\n\r\nJiž je zde přítel se stejnou IP adresou i portem." - IDS_DYNUP "Citlivost na rychlost uploadu" + IDS_DYNUP "Citlivost na rychlost uploadu (není doporučeno)" IDS_KADOVERHEAD "Kad Overhead (Pakety): %s (%s)" IDS_FIND "Najít..." IDS_LOG_BANNED_CLIENTS "Logovat zakázané klienty" diff --git a/srchybrid/lang/cz_CZ.vcxproj b/srchybrid/lang/cz_CZ.vcxproj index 1e29b392..bfd28799 100644 --- a/srchybrid/lang/cz_CZ.vcxproj +++ b/srchybrid/lang/cz_CZ.vcxproj @@ -14,82 +14,45 @@ languages - Czech {E5EF62C7-377D-4B61-8244-CC4F8555F733} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)cz_CZ.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)cz_CZ.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/da_DK.rc b/srchybrid/lang/da_DK.rc index 7f4cd368..664ec5b0 100644 --- a/srchybrid/lang/da_DK.rc +++ b/srchybrid/lang/da_DK.rc @@ -426,7 +426,7 @@ BEGIN IDS_GLOBALSEARCH "Global (Server)" IDS_METHOD "Metode" IDS_UNDO "Fortryd ændring" - IDS_DAYLY "dagligt" + IDS_DAILY "dagligt" END STRINGTABLE @@ -1442,7 +1442,7 @@ BEGIN IDS_EM_HELP "&Hjælp" IDS_WRN_FRIENDDUPLIPPORT "Ven ikke tilføjet.\r\n\r\nDer er allerede en ven med samme IP og port tilrådig." - IDS_DYNUP "Upload SpeedSense" + IDS_DYNUP "Upload SpeedSense (ikke anbefalet)" IDS_KADOVERHEAD "Kad Overhead (Pakker): %s (%s)" IDS_FIND "Find..." IDS_LOG_BANNED_CLIENTS "Log bandlyste klienter" diff --git a/srchybrid/lang/da_DK.vcxproj b/srchybrid/lang/da_DK.vcxproj index b329d13a..b5ba441f 100644 --- a/srchybrid/lang/da_DK.vcxproj +++ b/srchybrid/lang/da_DK.vcxproj @@ -14,82 +14,45 @@ languages - Danish {0C42D310-84EB-462F-944B-7166C0D071E9} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)da_DK.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)da_DK.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/de_DE.rc b/srchybrid/lang/de_DE.rc index d7114033..b3fec8bb 100644 --- a/srchybrid/lang/de_DE.rc +++ b/srchybrid/lang/de_DE.rc @@ -436,7 +436,7 @@ BEGIN IDS_GLOBALSEARCH "Global (Server)" IDS_METHOD "Methode" IDS_UNDO "Rückgängig" - IDS_DAYLY "Täglich" + IDS_DAILY "Täglich" IDS_DAY_MO_FR "Mo-Fr" END @@ -1442,7 +1442,7 @@ BEGIN IDS_EM_HELP "&Hilfe" IDS_WRN_FRIENDDUPLIPPORT "Freund wurde nicht hinzugefügt.\r\n\r\nEs gibt bereits einen Freund mit gleicher IP und Port." - IDS_DYNUP "Upload SpeedSense" //! + IDS_DYNUP "Upload SpeedSense (nicht empfohlen)" IDS_KADOVERHEAD "Kad Overhead (Pakete): %s (%s)" IDS_FIND "Suche..." IDS_LOG_BANNED_CLIENTS "Logge gebannte Clients" diff --git a/srchybrid/lang/de_DE.vcxproj b/srchybrid/lang/de_DE.vcxproj index a6d624d8..7f35c56f 100644 --- a/srchybrid/lang/de_DE.vcxproj +++ b/srchybrid/lang/de_DE.vcxproj @@ -14,82 +14,45 @@ languages - German (Germany) {8104E8D8-7343-4BE7-8955-80A1F2D26EC1} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)de_DE.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)de_DE.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/el_GR.rc b/srchybrid/lang/el_GR.rc index b6e3c143..092919ae 100644 --- a/srchybrid/lang/el_GR.rc +++ b/srchybrid/lang/el_GR.rc @@ -406,7 +406,7 @@ BEGIN IDS_GLOBALSEARCH "Ευρύτερη" IDS_METHOD "Μέθοδος" IDS_UNDO "Αναίρεση" - IDS_DAYLY "Καθημερινά" + IDS_DAILY "Καθημερινά" END STRINGTABLE @@ -1394,7 +1394,7 @@ BEGIN IDS_MINLENGTH "Ελάχ. μήκος [ωω:λλ:δδ]" IDS_EM_HELP "&Βοήθεια" IDS_WRN_FRIENDDUPLIPPORT "Ο φίλος δεν προστέθηκε.\r\n\r\nΥπάρχει ήδη ένας φίλος διαθέσιμος με την ίδια διεύθυνση IP και port." - IDS_DYNUP "Διαίσθηση ταχύτητας ανεβάσματος" + IDS_DYNUP "Διαίσθηση ταχύτητας ανεβάσματος (δεν προτείνεται)" IDS_KADOVERHEAD "Kademlia (Πακέτα): %s (%s)" IDS_FIND "Αναζήτηση..." IDS_LOG_BANNED_CLIENTS "Καταγραφή εμποδισμένων χρηστών" diff --git a/srchybrid/lang/el_GR.vcxproj b/srchybrid/lang/el_GR.vcxproj index 8e5327e3..48fddb10 100644 --- a/srchybrid/lang/el_GR.vcxproj +++ b/srchybrid/lang/el_GR.vcxproj @@ -14,82 +14,45 @@ languages - Greek {8DA8A9E2-9987-4B68-9825-45C445C52730} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)el_GR.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)el_GR.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/es_AS.rc b/srchybrid/lang/es_AS.rc index eb1eb332..80cf82ff 100644 --- a/srchybrid/lang/es_AS.rc +++ b/srchybrid/lang/es_AS.rc @@ -470,7 +470,7 @@ BEGIN IDS_GLOBALSEARCH "Global (Servidores)" IDS_METHOD "Métodu" IDS_UNDO "Desfacer" - IDS_DAYLY "Tolos díes" + IDS_DAILY "Tolos díes" END STRINGTABLE @@ -1506,7 +1506,7 @@ BEGIN IDS_EM_HELP "&Ayuda" IDS_WRN_FRIENDDUPLIPPORT "Collaciu ensin amestar.\r\n\r\nYá esiste un collaciu cola mesma dirección IP y puertu disponible." - IDS_DYNUP "Sensor de Velocidá de Subida" + IDS_DYNUP "Sensor de Velocidá de Subida (not recommended)" IDS_KADOVERHEAD "Tráficu escedente Kad (Paquetes): %s (%s)" IDS_FIND "Alcontrar..." IDS_LOG_BANNED_CLIENTS "Rexistrar veceros bloqueaos" diff --git a/srchybrid/lang/es_AS.vcxproj b/srchybrid/lang/es_AS.vcxproj index 8d3d5a39..d3fd667c 100644 --- a/srchybrid/lang/es_AS.vcxproj +++ b/srchybrid/lang/es_AS.vcxproj @@ -14,82 +14,45 @@ languages - Asturian {E32658C1-CD24-40DC-8912-C7D3FE803FC1} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)es_AS.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)es_AS.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/es_ES_T.rc b/srchybrid/lang/es_ES_T.rc index bc5c66b8..c5db28a9 100644 --- a/srchybrid/lang/es_ES_T.rc +++ b/srchybrid/lang/es_ES_T.rc @@ -428,7 +428,7 @@ BEGIN IDS_GLOBALSEARCH "Global (Servidores)" IDS_METHOD "Método" IDS_UNDO "Deshacer" - IDS_DAYLY "Diariamente" + IDS_DAILY "Diariamente" END STRINGTABLE @@ -1451,7 +1451,7 @@ BEGIN IDS_EM_HELP "A&yuda" IDS_WRN_FRIENDDUPLIPPORT "Amigo no añadido.\r\n\r\nYa existe un amigo con la misma dirección IP y puerto disponible." - IDS_DYNUP "Sensor de Velocidad de Subida" + IDS_DYNUP "Sensor de Velocidad de Subida (no recomendado)" IDS_KADOVERHEAD "Tráfico excedente Kad (Paquetes): %s (%s)" IDS_FIND "Encontrar..." IDS_LOG_BANNED_CLIENTS "Registrar clientes excluidos" diff --git a/srchybrid/lang/es_ES_T.vcxproj b/srchybrid/lang/es_ES_T.vcxproj index 9e638404..649c9d28 100644 --- a/srchybrid/lang/es_ES_T.vcxproj +++ b/srchybrid/lang/es_ES_T.vcxproj @@ -14,82 +14,45 @@ languages - Spanish (Castilian) {B0DAEE35-FD0F-4FAF-A7C1-3D52103B3E81} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)es_ES_T.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)es_ES_T.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/et_EE.rc b/srchybrid/lang/et_EE.rc index 4af6c0dd..cc8aac51 100644 --- a/srchybrid/lang/et_EE.rc +++ b/srchybrid/lang/et_EE.rc @@ -414,7 +414,7 @@ BEGIN IDS_WEB_ERR_CANTLOAD "Viga makettide laadimisel: ei saa avada faili %s" IDS_GLOBALSEARCH "Globaalne (server)" IDS_METHOD "Meetod" - IDS_DAYLY "Päev" + IDS_DAILY "Päev" END STRINGTABLE @@ -1411,7 +1411,7 @@ BEGIN IDS_EM_HELP "&Appi" IDS_WRN_FRIENDDUPLIPPORT "Sõber jäi lisamata.\r\n\r\nMeil juba on üks sama IP aadressi ja pordiga sõber." - IDS_DYNUP "Saatmiskiiruse regulaator (USS)" + IDS_DYNUP "Saatmiskiiruse regulaator - USS (not recommended)" IDS_KADOVERHEAD "Kad Overhead (pakette): %s (%s)" IDS_FIND "Leia..." IDS_LOG_BANNED_CLIENTS "Logi bännitud kasutajad" diff --git a/srchybrid/lang/et_EE.vcxproj b/srchybrid/lang/et_EE.vcxproj index 5dd27ef8..83b31afa 100644 --- a/srchybrid/lang/et_EE.vcxproj +++ b/srchybrid/lang/et_EE.vcxproj @@ -14,82 +14,45 @@ languages - Estonian {14AB1B79-6F57-43EB-A5EA-B9B117B659B4} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)et_EE.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)et_EE.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/fa_IR.rc b/srchybrid/lang/fa_IR.rc index 6988342d..cb00c7f4 100644 --- a/srchybrid/lang/fa_IR.rc +++ b/srchybrid/lang/fa_IR.rc @@ -498,7 +498,7 @@ BEGIN IDS_GLOBALSEARCH "همه سرويس دهنده ها" IDS_METHOD "روش" IDS_UNDO "برگشت به قبل" - IDS_DAYLY "روزانه" + IDS_DAILY "روزانه" IDS_DAY_MO_FR "دوشنبه.جمعه" END @@ -1561,7 +1561,7 @@ BEGIN IDS_EM_HELP "&راهنما" IDS_WRN_FRIENDDUPLIPPORT "دوست اضافه نشد.\r\n\r\nيک دوست از قبل با آدرس آي پي و پورت مشابه در دسترس است.َ" - IDS_DYNUP "تعيين سرعت آپلود" + IDS_DYNUP "تعيين سرعت آپلود (توصيه نمي شود)َ" IDS_KADOVERHEAD "Kad سربار (بسته هاي اطلاعاتي)َ: %s (%s)" IDS_FIND "يافتن...َ" IDS_LOG_BANNED_CLIENTS "مشتري هايي با ممنوعيت ورود" diff --git a/srchybrid/lang/fa_IR.vcxproj b/srchybrid/lang/fa_IR.vcxproj index 295c1fe4..9b3ead8d 100644 --- a/srchybrid/lang/fa_IR.vcxproj +++ b/srchybrid/lang/fa_IR.vcxproj @@ -14,82 +14,45 @@ languages - Farsi {F2ED1274-6DA7-4F08-B9C8-1915409EAEC1} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)fa_IR.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)fa_IR.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/fi_FI.rc b/srchybrid/lang/fi_FI.rc index 5c8f0ebb..73d386cc 100644 --- a/srchybrid/lang/fi_FI.rc +++ b/srchybrid/lang/fi_FI.rc @@ -498,7 +498,7 @@ BEGIN IDS_GLOBALSEARCH "Palvelimilta" IDS_METHOD "Tapa" IDS_UNDO "Kumoa" - IDS_DAYLY "päivittäin" + IDS_DAILY "päivittäin" IDS_DAY_MO_FR "Ma - pe" END @@ -1562,7 +1562,7 @@ BEGIN IDS_EM_HELP "&Ohje" IDS_WRN_FRIENDDUPLIPPORT "En lisännyt kaveria.\r\n\r\nToinen kaveri on olemassa samalla IP-osoitteella ja portilla." - IDS_DYNUP "Lähetysnopeuden tunnustelu" + IDS_DYNUP "Lähetysnopeuden tunnustelu (ei suositella)" IDS_KADOVERHEAD "Kademlian kokonaisliikenne %s (paketteja: %s)" IDS_FIND "Etsi..." IDS_LOG_BANNED_CLIENTS "Kirjaa lokiin estetyt käyttäjät" diff --git a/srchybrid/lang/fi_FI.vcxproj b/srchybrid/lang/fi_FI.vcxproj index ac8531a0..ebb0d6fb 100644 --- a/srchybrid/lang/fi_FI.vcxproj +++ b/srchybrid/lang/fi_FI.vcxproj @@ -14,82 +14,45 @@ languages - Finnish {745D6455-7389-4C76-8275-D91F7451E0FA} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)fi_FI.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)fi_FI.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/fr_BR.rc b/srchybrid/lang/fr_BR.rc index f8c50d7a..79b9159a 100644 --- a/srchybrid/lang/fr_BR.rc +++ b/srchybrid/lang/fr_BR.rc @@ -711,7 +711,7 @@ BEGIN IDS_IRC_ADDTOFRIENDLIST "Ouzhpennañ d'ar roll mignoned" IDS_IRC_LOADCHANNELLISTONCON "Kargañ ar rollad saloñsoù pa vez kennasket" IDS_IRC_ADDASFRIEND "en deus ouzhpennet ac'hanoc'h evel mignon !" - IDS_PW_WARNING "Re vras eo ar werzhiad ho peus dibabet ""%s"" evit bezañ skoret gant ho reizhiad korvoiñ : %u\nGallout a ra lakaat ho \nreizhiad da vezañ distabil.\n\nHa fellout a ra deoc'h ober an dra-mañ evelkent ?" + IDS_PW_WARNING "Re vras eo ar werzhiad ho peus dibabet ""%s"" evit bezañ skoret gant ho reizhiad korvoiñ : %u\nGallout a ra lakaat ho \nreizhiad da vezañ distabil.\n\nHa fellout a ra deoc'h ober an dra-mañ evelkent ?" IDS_TAKEOVER "Adgolloiñ" IDS_CLEANUP "Naetaat" IDS_RENAME "Adenvel" @@ -1044,7 +1044,7 @@ BEGIN IDS_GLOBALSEARCH "Hollek (Servijer)" IDS_METHOD "Hentenn" IDS_UNDO "Nullañ" - IDS_DAYLY "Bemdeziek" + IDS_DAILY "Bemdeziek" END STRINGTABLE FIXED IMPURE @@ -1448,7 +1448,7 @@ BEGIN IDS_MINLENGTH "Padelezh izel. [hh:mm:ss]" IDS_EM_HELP "&Skoazell" IDS_WRN_FRIENDDUPLIPPORT "Mignon ket ouzhpennet.\r\n\r\nUr mignon all a zo dija enrollet gant ar memes chomlec'h IP ha porzh." - IDS_DYNUP "Dizoloiñ an tizh kas" + IDS_DYNUP "Dizoloiñ an tizh kas (not recommended)" IDS_KADOVERHEAD "Bann tremen dreistniverel Kad (Pakadoù): %s (%s)" IDS_FIND "Kavout..." IDS_LOG_BANNED_CLIENTS "Enskrivañ an ostizien forbannet" diff --git a/srchybrid/lang/fr_BR.vcxproj b/srchybrid/lang/fr_BR.vcxproj index 34c1ca6e..fa422501 100644 --- a/srchybrid/lang/fr_BR.vcxproj +++ b/srchybrid/lang/fr_BR.vcxproj @@ -14,82 +14,45 @@ languages - French (Breton) {5E420537-E1A9-4004-BBDC-F2853AAD5485} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)fr_BR.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\Debug\lang md ..\Debug\lang -copy "$(TargetPath)" ..\Debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)fr_BR.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\Debug\lang md ..\Debug\lang -copy "$(TargetPath)" ..\Debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\Debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/fr_FR.rc b/srchybrid/lang/fr_FR.rc index 3d2e0d15..3559a0d0 100644 --- a/srchybrid/lang/fr_FR.rc +++ b/srchybrid/lang/fr_FR.rc @@ -419,7 +419,7 @@ BEGIN IDS_GLOBALSEARCH "Globale (Serveur)" IDS_METHOD "Méthode" IDS_UNDO "Supprimer" - IDS_DAYLY "Quotidien" + IDS_DAILY "Quotidien" END STRINGTABLE @@ -1424,7 +1424,7 @@ BEGIN IDS_EM_HELP "Ai&de" IDS_WRN_FRIENDDUPLIPPORT "Ami non ajouté.\r\n\r\nIl y a déjà un ami enregistré avec les mêmes adresse IP et port." - IDS_DYNUP "Contrôle de la vitesse d'émission (USS)" + IDS_DYNUP "Contrôle de la vitesse d'émission - USS (déconseillé)" IDS_KADOVERHEAD "Surplus de Bande passante Kad (Paquets): %s (%s)" IDS_FIND "Trouver..." IDS_LOG_BANNED_CLIENTS "Consigner les clients bannis" diff --git a/srchybrid/lang/fr_FR.vcxproj b/srchybrid/lang/fr_FR.vcxproj index 459fdda6..81134f88 100644 --- a/srchybrid/lang/fr_FR.vcxproj +++ b/srchybrid/lang/fr_FR.vcxproj @@ -14,82 +14,45 @@ languages - French (France) {A7E4E792-AA76-4977-A725-1C428AADE381} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)fr_FR.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)fr_FR.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/gl_ES.rc b/srchybrid/lang/gl_ES.rc index 81e24fb5..e84bcbc4 100644 --- a/srchybrid/lang/gl_ES.rc +++ b/srchybrid/lang/gl_ES.rc @@ -461,7 +461,7 @@ BEGIN IDS_GLOBALSEARCH "Global (Servidor)" IDS_METHOD "Método" IDS_UNDO "Desfacer" - IDS_DAYLY "diariamente" + IDS_DAILY "diariamente" END STRINGTABLE @@ -1450,7 +1450,7 @@ BEGIN IDS_EM_HELP "A&xuda" IDS_WRN_FRIENDDUPLIPPORT "Amigo non engadido.\r\n\r\nXa hai un amigo coa mesma IP e porto dispoñible." - IDS_DYNUP "Sensor de velocidade de subida" + IDS_DYNUP "Sensor de velocidade de subida (non recomendado)" IDS_KADOVERHEAD "Tráfico excedente de Kademlia (Packets): %s (%s)" IDS_FIND "Buscar..." IDS_LOG_BANNED_CLIENTS "Rexistrar clientes bloqueados" diff --git a/srchybrid/lang/gl_ES.vcxproj b/srchybrid/lang/gl_ES.vcxproj index df69e593..23aed974 100644 --- a/srchybrid/lang/gl_ES.vcxproj +++ b/srchybrid/lang/gl_ES.vcxproj @@ -14,82 +14,45 @@ languages - Galician {583840C9-525A-4417-866C-6197EBC12214} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)gl_ES.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)gl_ES.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/he_IL.rc b/srchybrid/lang/he_IL.rc index 2ca32ced..1e21c179 100644 --- a/srchybrid/lang/he_IL.rc +++ b/srchybrid/lang/he_IL.rc @@ -217,7 +217,7 @@ BEGIN IDS_GLOBALSEARCH "גלובלי בשרת" IDS_METHOD "שיטת חיפוש" IDS_UNDO "בטל" - IDS_DAYLY "יומי" + IDS_DAILY "יומי" END STRINGTABLE @@ -1421,7 +1421,7 @@ BEGIN IDS_EM_HELP "עזרה" IDS_WRN_FRIENDDUPLIPPORT "חבר לא נוסף.\r\n\r\nכבר קיים חבר עם כתובת איי פי ופורט דומים." - IDS_DYNUP "Upload SpeedSense"//! + IDS_DYNUP "Upload SpeedSense (לא מומלץ)" IDS_KADOVERHEAD "תקורת רשת קדמליה (מנות): %s (%s)" IDS_FIND "חפש..." IDS_LOG_BANNED_CLIENTS "שמור יומן קליינטים מוחרמים" diff --git a/srchybrid/lang/he_IL.vcxproj b/srchybrid/lang/he_IL.vcxproj index 4b8fe75c..232f264f 100644 --- a/srchybrid/lang/he_IL.vcxproj +++ b/srchybrid/lang/he_IL.vcxproj @@ -14,82 +14,45 @@ languages - Hebrew (Israel) {6191AA5F-75C1-4448-9CE1-E5DED284501B} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)he_IL.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)he_IL.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/hu_HU.rc b/srchybrid/lang/hu_HU.rc index 83a934aa..4e82e3f6 100644 --- a/srchybrid/lang/hu_HU.rc +++ b/srchybrid/lang/hu_HU.rc @@ -421,7 +421,7 @@ BEGIN IDS_GLOBALSEARCH "Globális" IDS_METHOD "Metódus" IDS_UNDO "Visszacsinál" - IDS_DAYLY "naponta" + IDS_DAILY "naponta" END STRINGTABLE @@ -1448,7 +1448,7 @@ BEGIN IDS_EM_HELP "Súgó" IDS_WRN_FRIENDDUPLIPPORT "Friend not added.\r\n\r\nThere is already a friend with same IP address and port available." - IDS_DYNUP "Feltöltési érzékenység" + IDS_DYNUP "Feltöltési érzékenység (not recommended)" IDS_KADOVERHEAD "Kad előny (Csomag): %s (%s)" IDS_FIND "Keresés..." IDS_LOG_BANNED_CLIENTS "Kitiltott kliensek naplózása" diff --git a/srchybrid/lang/hu_HU.vcxproj b/srchybrid/lang/hu_HU.vcxproj index 8756a3d4..9c803273 100644 --- a/srchybrid/lang/hu_HU.vcxproj +++ b/srchybrid/lang/hu_HU.vcxproj @@ -14,82 +14,45 @@ languages - Hungarian {3C9B64A2-6676-4A60-A805-15301A18C550} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)hu_HU.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)hu_HU.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/it_IT.rc b/srchybrid/lang/it_IT.rc index f95a8331..87375586 100644 --- a/srchybrid/lang/it_IT.rc +++ b/srchybrid/lang/it_IT.rc @@ -498,7 +498,7 @@ BEGIN IDS_GLOBALSEARCH "Globale (server)" IDS_METHOD "Metodo di ricerca" IDS_UNDO "Annulla" - IDS_DAYLY "- Quotidiano -" + IDS_DAILY "- Quotidiano -" IDS_DAY_MO_FR "Lun-ven" END @@ -1561,7 +1561,7 @@ BEGIN IDS_EM_HELP "Ai&uto" IDS_WRN_FRIENDDUPLIPPORT "Amico non aggiunto.\r\n\r\nEsiste già un amico con lo stesso IP e la stessa porta." - IDS_DYNUP "Limite dinamico della banda d'invio" + IDS_DYNUP "Limite dinamico della banda d'invio (sconsigliato)" IDS_KADOVERHEAD "Overhead Kad (pacchetti): %s (%s)" IDS_FIND "Trova..." IDS_LOG_BANNED_CLIENTS "Registra gli utenti bloccati" diff --git a/srchybrid/lang/it_IT.vcxproj b/srchybrid/lang/it_IT.vcxproj index dce43e0b..db99213a 100644 --- a/srchybrid/lang/it_IT.vcxproj +++ b/srchybrid/lang/it_IT.vcxproj @@ -14,82 +14,45 @@ languages - Italian (Italy) {FEF2FD72-388B-42F6-B5DA-B9A663ACF557} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)it_IT.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)it_IT.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/jp_JP.rc b/srchybrid/lang/jp_JP.rc index 54bca013..60860057 100644 --- a/srchybrid/lang/jp_JP.rc +++ b/srchybrid/lang/jp_JP.rc @@ -473,7 +473,7 @@ BEGIN IDS_GLOBALSEARCH "グローバル(サーバー)" IDS_METHOD "検索方法" IDS_UNDO "元に戻す" - IDS_DAYLY "毎日" + IDS_DAILY "毎日" END STRINGTABLE @@ -1485,7 +1485,7 @@ BEGIN IDS_EM_HELP "ヘルプ" IDS_WRN_FRIENDDUPLIPPORT "友達は追加されませんでした\r\n\r\n既に同じIPアドレスとポートを持った友達が存在します" - IDS_DYNUP "アップロード速度感知" + IDS_DYNUP "アップロード速度感知 (非推奨)" IDS_KADOVERHEAD "Kadオーバーヘッド(パケット): %s (%s)" IDS_FIND "検索..." IDS_LOG_BANNED_CLIENTS "BANしたクライアントのログを採る" diff --git a/srchybrid/lang/jp_JP.vcxproj b/srchybrid/lang/jp_JP.vcxproj index 108a77a2..93e9d8b8 100644 --- a/srchybrid/lang/jp_JP.vcxproj +++ b/srchybrid/lang/jp_JP.vcxproj @@ -14,82 +14,45 @@ languages - Japanese {76FA1CA3-FC3D-45D2-86A8-B068F551652F} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)jp_JP.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)jp_JP.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/ko_KR.rc b/srchybrid/lang/ko_KR.rc index 7142f482..9719f81e 100644 --- a/srchybrid/lang/ko_KR.rc +++ b/srchybrid/lang/ko_KR.rc @@ -496,7 +496,7 @@ BEGIN IDS_GLOBALSEARCH "전역 (서버)" IDS_METHOD "방식" IDS_UNDO "실행 취소" - IDS_DAYLY "매일" + IDS_DAILY "매일" IDS_DAY_MO_FR "월-금" END @@ -1559,7 +1559,7 @@ BEGIN IDS_EM_HELP "도움말(&H)" IDS_WRN_FRIENDDUPLIPPORT "친구로 추가되지 않음.\r\n\r\n이미 같은 IP와 포트에 친구가 있습니다." - IDS_DYNUP "업로드 속도 감지" + IDS_DYNUP "업로드 속도 감지 (권장하지 않음)" IDS_KADOVERHEAD "Kad 오버헤드 (패킷): %s (%s)" IDS_FIND "찾기..." IDS_LOG_BANNED_CLIENTS "추방당한 클라이언트 기록" diff --git a/srchybrid/lang/ko_KR.vcxproj b/srchybrid/lang/ko_KR.vcxproj index 7e24764c..439a5278 100644 --- a/srchybrid/lang/ko_KR.vcxproj +++ b/srchybrid/lang/ko_KR.vcxproj @@ -14,82 +14,45 @@ languages - Korean {AA2EA361-4793-4FF7-A042-40E271030CC4} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)ko_KR.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)ko_KR.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/lang.rc2 b/srchybrid/lang/lang.rc2 index 1fb09a90..cc240360 100644 --- a/srchybrid/lang/lang.rc2 +++ b/srchybrid/lang/lang.rc2 @@ -38,7 +38,7 @@ BEGIN VALUE "CompanyName", "http://www.emule-project.net" VALUE "FileDescription", "eMule Language DLL" VALUE "FileVersion", SZ_VERSION_NAME - VALUE "LegalCopyright", "Copyright © 2002-2006 Merkur - read license.txt for more infos" + VALUE "LegalCopyright", "Copyright © 2002-2023 Merkur - read license.txt for more infos" VALUE "ProductName", "eMule" VALUE "ProductVersion", SZ_VERSION_NAME END diff --git a/srchybrid/lang/lang.sln b/srchybrid/lang/lang.sln index 34c4f733..d38bfa0a 100644 --- a/srchybrid/lang/lang.sln +++ b/srchybrid/lang/lang.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30626.31 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "languages - Arabic (UAE)", "ar_AE.vcxproj", "{A710033C-F75A-4431-96AA-876A9867A2F8}" EndProject @@ -90,193 +90,188 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "languages - Valencian (RACV EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Dynamic|Win32 = Dynamic|Win32 Dynamic|x64 = Dynamic|x64 - Dynamic|x86 = Dynamic|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A710033C-F75A-4431-96AA-876A9867A2F8}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {A710033C-F75A-4431-96AA-876A9867A2F8}.Dynamic|Win32.Build.0 = Dynamic|Win32 {A710033C-F75A-4431-96AA-876A9867A2F8}.Dynamic|x64.ActiveCfg = Dynamic|x64 {A710033C-F75A-4431-96AA-876A9867A2F8}.Dynamic|x64.Build.0 = Dynamic|x64 - {A710033C-F75A-4431-96AA-876A9867A2F8}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {A710033C-F75A-4431-96AA-876A9867A2F8}.Dynamic|x86.Build.0 = Dynamic|Win32 + {44716561-6BA7-40DA-AE7F-F3FFB422E86D}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {44716561-6BA7-40DA-AE7F-F3FFB422E86D}.Dynamic|Win32.Build.0 = Dynamic|Win32 {44716561-6BA7-40DA-AE7F-F3FFB422E86D}.Dynamic|x64.ActiveCfg = Dynamic|x64 {44716561-6BA7-40DA-AE7F-F3FFB422E86D}.Dynamic|x64.Build.0 = Dynamic|x64 - {44716561-6BA7-40DA-AE7F-F3FFB422E86D}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {44716561-6BA7-40DA-AE7F-F3FFB422E86D}.Dynamic|x86.Build.0 = Dynamic|Win32 + {0C96EF73-186D-4888-BB53-EECE60B55647}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {0C96EF73-186D-4888-BB53-EECE60B55647}.Dynamic|Win32.Build.0 = Dynamic|Win32 {0C96EF73-186D-4888-BB53-EECE60B55647}.Dynamic|x64.ActiveCfg = Dynamic|x64 {0C96EF73-186D-4888-BB53-EECE60B55647}.Dynamic|x64.Build.0 = Dynamic|x64 - {0C96EF73-186D-4888-BB53-EECE60B55647}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {0C96EF73-186D-4888-BB53-EECE60B55647}.Dynamic|x86.Build.0 = Dynamic|Win32 + {0C42D310-84EB-462F-944B-7166C0D071E9}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {0C42D310-84EB-462F-944B-7166C0D071E9}.Dynamic|Win32.Build.0 = Dynamic|Win32 {0C42D310-84EB-462F-944B-7166C0D071E9}.Dynamic|x64.ActiveCfg = Dynamic|x64 {0C42D310-84EB-462F-944B-7166C0D071E9}.Dynamic|x64.Build.0 = Dynamic|x64 - {0C42D310-84EB-462F-944B-7166C0D071E9}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {0C42D310-84EB-462F-944B-7166C0D071E9}.Dynamic|x86.Build.0 = Dynamic|Win32 + {8104E8D8-7343-4BE7-8955-80A1F2D26EC1}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {8104E8D8-7343-4BE7-8955-80A1F2D26EC1}.Dynamic|Win32.Build.0 = Dynamic|Win32 {8104E8D8-7343-4BE7-8955-80A1F2D26EC1}.Dynamic|x64.ActiveCfg = Dynamic|x64 {8104E8D8-7343-4BE7-8955-80A1F2D26EC1}.Dynamic|x64.Build.0 = Dynamic|x64 - {8104E8D8-7343-4BE7-8955-80A1F2D26EC1}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {8104E8D8-7343-4BE7-8955-80A1F2D26EC1}.Dynamic|x86.Build.0 = Dynamic|Win32 + {8DA8A9E2-9987-4B68-9825-45C445C52730}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {8DA8A9E2-9987-4B68-9825-45C445C52730}.Dynamic|Win32.Build.0 = Dynamic|Win32 {8DA8A9E2-9987-4B68-9825-45C445C52730}.Dynamic|x64.ActiveCfg = Dynamic|x64 {8DA8A9E2-9987-4B68-9825-45C445C52730}.Dynamic|x64.Build.0 = Dynamic|x64 - {8DA8A9E2-9987-4B68-9825-45C445C52730}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {8DA8A9E2-9987-4B68-9825-45C445C52730}.Dynamic|x86.Build.0 = Dynamic|Win32 + {B0DAEE35-FD0F-4FAF-A7C1-3D52103B3E81}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {B0DAEE35-FD0F-4FAF-A7C1-3D52103B3E81}.Dynamic|Win32.Build.0 = Dynamic|Win32 {B0DAEE35-FD0F-4FAF-A7C1-3D52103B3E81}.Dynamic|x64.ActiveCfg = Dynamic|x64 {B0DAEE35-FD0F-4FAF-A7C1-3D52103B3E81}.Dynamic|x64.Build.0 = Dynamic|x64 - {B0DAEE35-FD0F-4FAF-A7C1-3D52103B3E81}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {B0DAEE35-FD0F-4FAF-A7C1-3D52103B3E81}.Dynamic|x86.Build.0 = Dynamic|Win32 + {14AB1B79-6F57-43EB-A5EA-B9B117B659B4}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {14AB1B79-6F57-43EB-A5EA-B9B117B659B4}.Dynamic|Win32.Build.0 = Dynamic|Win32 {14AB1B79-6F57-43EB-A5EA-B9B117B659B4}.Dynamic|x64.ActiveCfg = Dynamic|x64 {14AB1B79-6F57-43EB-A5EA-B9B117B659B4}.Dynamic|x64.Build.0 = Dynamic|x64 - {14AB1B79-6F57-43EB-A5EA-B9B117B659B4}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {14AB1B79-6F57-43EB-A5EA-B9B117B659B4}.Dynamic|x86.Build.0 = Dynamic|Win32 + {745D6455-7389-4C76-8275-D91F7451E0FA}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {745D6455-7389-4C76-8275-D91F7451E0FA}.Dynamic|Win32.Build.0 = Dynamic|Win32 {745D6455-7389-4C76-8275-D91F7451E0FA}.Dynamic|x64.ActiveCfg = Dynamic|x64 {745D6455-7389-4C76-8275-D91F7451E0FA}.Dynamic|x64.Build.0 = Dynamic|x64 - {745D6455-7389-4C76-8275-D91F7451E0FA}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {745D6455-7389-4C76-8275-D91F7451E0FA}.Dynamic|x86.Build.0 = Dynamic|Win32 + {A7E4E792-AA76-4977-A725-1C428AADE381}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {A7E4E792-AA76-4977-A725-1C428AADE381}.Dynamic|Win32.Build.0 = Dynamic|Win32 {A7E4E792-AA76-4977-A725-1C428AADE381}.Dynamic|x64.ActiveCfg = Dynamic|x64 {A7E4E792-AA76-4977-A725-1C428AADE381}.Dynamic|x64.Build.0 = Dynamic|x64 - {A7E4E792-AA76-4977-A725-1C428AADE381}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {A7E4E792-AA76-4977-A725-1C428AADE381}.Dynamic|x86.Build.0 = Dynamic|Win32 + {3C9B64A2-6676-4A60-A805-15301A18C550}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {3C9B64A2-6676-4A60-A805-15301A18C550}.Dynamic|Win32.Build.0 = Dynamic|Win32 {3C9B64A2-6676-4A60-A805-15301A18C550}.Dynamic|x64.ActiveCfg = Dynamic|x64 {3C9B64A2-6676-4A60-A805-15301A18C550}.Dynamic|x64.Build.0 = Dynamic|x64 - {3C9B64A2-6676-4A60-A805-15301A18C550}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {3C9B64A2-6676-4A60-A805-15301A18C550}.Dynamic|x86.Build.0 = Dynamic|Win32 + {FEF2FD72-388B-42F6-B5DA-B9A663ACF557}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {FEF2FD72-388B-42F6-B5DA-B9A663ACF557}.Dynamic|Win32.Build.0 = Dynamic|Win32 {FEF2FD72-388B-42F6-B5DA-B9A663ACF557}.Dynamic|x64.ActiveCfg = Dynamic|x64 {FEF2FD72-388B-42F6-B5DA-B9A663ACF557}.Dynamic|x64.Build.0 = Dynamic|x64 - {FEF2FD72-388B-42F6-B5DA-B9A663ACF557}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {FEF2FD72-388B-42F6-B5DA-B9A663ACF557}.Dynamic|x86.Build.0 = Dynamic|Win32 + {AA2EA361-4793-4FF7-A042-40E271030CC4}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {AA2EA361-4793-4FF7-A042-40E271030CC4}.Dynamic|Win32.Build.0 = Dynamic|Win32 {AA2EA361-4793-4FF7-A042-40E271030CC4}.Dynamic|x64.ActiveCfg = Dynamic|x64 {AA2EA361-4793-4FF7-A042-40E271030CC4}.Dynamic|x64.Build.0 = Dynamic|x64 - {AA2EA361-4793-4FF7-A042-40E271030CC4}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {AA2EA361-4793-4FF7-A042-40E271030CC4}.Dynamic|x86.Build.0 = Dynamic|Win32 + {9B6F843F-A792-466D-98E3-A3921525AFF5}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {9B6F843F-A792-466D-98E3-A3921525AFF5}.Dynamic|Win32.Build.0 = Dynamic|Win32 {9B6F843F-A792-466D-98E3-A3921525AFF5}.Dynamic|x64.ActiveCfg = Dynamic|x64 {9B6F843F-A792-466D-98E3-A3921525AFF5}.Dynamic|x64.Build.0 = Dynamic|x64 - {9B6F843F-A792-466D-98E3-A3921525AFF5}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {9B6F843F-A792-466D-98E3-A3921525AFF5}.Dynamic|x86.Build.0 = Dynamic|Win32 + {2885B86D-9DDA-460C-9FB8-41B005F15349}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {2885B86D-9DDA-460C-9FB8-41B005F15349}.Dynamic|Win32.Build.0 = Dynamic|Win32 {2885B86D-9DDA-460C-9FB8-41B005F15349}.Dynamic|x64.ActiveCfg = Dynamic|x64 {2885B86D-9DDA-460C-9FB8-41B005F15349}.Dynamic|x64.Build.0 = Dynamic|x64 - {2885B86D-9DDA-460C-9FB8-41B005F15349}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {2885B86D-9DDA-460C-9FB8-41B005F15349}.Dynamic|x86.Build.0 = Dynamic|Win32 + {DE470764-A818-4780-B590-78EB8D560E89}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {DE470764-A818-4780-B590-78EB8D560E89}.Dynamic|Win32.Build.0 = Dynamic|Win32 {DE470764-A818-4780-B590-78EB8D560E89}.Dynamic|x64.ActiveCfg = Dynamic|x64 {DE470764-A818-4780-B590-78EB8D560E89}.Dynamic|x64.Build.0 = Dynamic|x64 - {DE470764-A818-4780-B590-78EB8D560E89}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {DE470764-A818-4780-B590-78EB8D560E89}.Dynamic|x86.Build.0 = Dynamic|Win32 + {A989B752-28A2-44E7-8C19-F49C7ECD61DC}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {A989B752-28A2-44E7-8C19-F49C7ECD61DC}.Dynamic|Win32.Build.0 = Dynamic|Win32 {A989B752-28A2-44E7-8C19-F49C7ECD61DC}.Dynamic|x64.ActiveCfg = Dynamic|x64 {A989B752-28A2-44E7-8C19-F49C7ECD61DC}.Dynamic|x64.Build.0 = Dynamic|x64 - {A989B752-28A2-44E7-8C19-F49C7ECD61DC}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {A989B752-28A2-44E7-8C19-F49C7ECD61DC}.Dynamic|x86.Build.0 = Dynamic|Win32 + {57E9C9FF-E57F-46E0-823A-38DD76FEEBC6}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {57E9C9FF-E57F-46E0-823A-38DD76FEEBC6}.Dynamic|Win32.Build.0 = Dynamic|Win32 {57E9C9FF-E57F-46E0-823A-38DD76FEEBC6}.Dynamic|x64.ActiveCfg = Dynamic|x64 {57E9C9FF-E57F-46E0-823A-38DD76FEEBC6}.Dynamic|x64.Build.0 = Dynamic|x64 - {57E9C9FF-E57F-46E0-823A-38DD76FEEBC6}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {57E9C9FF-E57F-46E0-823A-38DD76FEEBC6}.Dynamic|x86.Build.0 = Dynamic|Win32 + {C7F4CB73-7D57-4077-9C04-931A6CB0677D}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {C7F4CB73-7D57-4077-9C04-931A6CB0677D}.Dynamic|Win32.Build.0 = Dynamic|Win32 {C7F4CB73-7D57-4077-9C04-931A6CB0677D}.Dynamic|x64.ActiveCfg = Dynamic|x64 {C7F4CB73-7D57-4077-9C04-931A6CB0677D}.Dynamic|x64.Build.0 = Dynamic|x64 - {C7F4CB73-7D57-4077-9C04-931A6CB0677D}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {C7F4CB73-7D57-4077-9C04-931A6CB0677D}.Dynamic|x86.Build.0 = Dynamic|Win32 + {64DFFE85-14E0-41D7-ADFA-7D53EE81D1B2}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {64DFFE85-14E0-41D7-ADFA-7D53EE81D1B2}.Dynamic|Win32.Build.0 = Dynamic|Win32 {64DFFE85-14E0-41D7-ADFA-7D53EE81D1B2}.Dynamic|x64.ActiveCfg = Dynamic|x64 {64DFFE85-14E0-41D7-ADFA-7D53EE81D1B2}.Dynamic|x64.Build.0 = Dynamic|x64 - {64DFFE85-14E0-41D7-ADFA-7D53EE81D1B2}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {64DFFE85-14E0-41D7-ADFA-7D53EE81D1B2}.Dynamic|x86.Build.0 = Dynamic|Win32 + {4AE4AB3A-FD80-4DFE-BF9B-AC845DCF2449}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {4AE4AB3A-FD80-4DFE-BF9B-AC845DCF2449}.Dynamic|Win32.Build.0 = Dynamic|Win32 {4AE4AB3A-FD80-4DFE-BF9B-AC845DCF2449}.Dynamic|x64.ActiveCfg = Dynamic|x64 {4AE4AB3A-FD80-4DFE-BF9B-AC845DCF2449}.Dynamic|x64.Build.0 = Dynamic|x64 - {4AE4AB3A-FD80-4DFE-BF9B-AC845DCF2449}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {4AE4AB3A-FD80-4DFE-BF9B-AC845DCF2449}.Dynamic|x86.Build.0 = Dynamic|Win32 + {F8A9B7BC-3CBB-4DEC-A04E-5224A65A6632}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {F8A9B7BC-3CBB-4DEC-A04E-5224A65A6632}.Dynamic|Win32.Build.0 = Dynamic|Win32 {F8A9B7BC-3CBB-4DEC-A04E-5224A65A6632}.Dynamic|x64.ActiveCfg = Dynamic|x64 {F8A9B7BC-3CBB-4DEC-A04E-5224A65A6632}.Dynamic|x64.Build.0 = Dynamic|x64 - {F8A9B7BC-3CBB-4DEC-A04E-5224A65A6632}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {F8A9B7BC-3CBB-4DEC-A04E-5224A65A6632}.Dynamic|x86.Build.0 = Dynamic|Win32 + {2AECAA37-18C5-4C04-8E34-3E6EDCD926AE}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {2AECAA37-18C5-4C04-8E34-3E6EDCD926AE}.Dynamic|Win32.Build.0 = Dynamic|Win32 {2AECAA37-18C5-4C04-8E34-3E6EDCD926AE}.Dynamic|x64.ActiveCfg = Dynamic|x64 {2AECAA37-18C5-4C04-8E34-3E6EDCD926AE}.Dynamic|x64.Build.0 = Dynamic|x64 - {2AECAA37-18C5-4C04-8E34-3E6EDCD926AE}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {2AECAA37-18C5-4C04-8E34-3E6EDCD926AE}.Dynamic|x86.Build.0 = Dynamic|Win32 + {EFE9605D-BF5C-4339-9A5A-32184D4BD03C}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {EFE9605D-BF5C-4339-9A5A-32184D4BD03C}.Dynamic|Win32.Build.0 = Dynamic|Win32 {EFE9605D-BF5C-4339-9A5A-32184D4BD03C}.Dynamic|x64.ActiveCfg = Dynamic|x64 {EFE9605D-BF5C-4339-9A5A-32184D4BD03C}.Dynamic|x64.Build.0 = Dynamic|x64 - {EFE9605D-BF5C-4339-9A5A-32184D4BD03C}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {EFE9605D-BF5C-4339-9A5A-32184D4BD03C}.Dynamic|x86.Build.0 = Dynamic|Win32 + {BFCEE1BE-5DC9-4CDF-B55E-6DEDFC4FF782}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {BFCEE1BE-5DC9-4CDF-B55E-6DEDFC4FF782}.Dynamic|Win32.Build.0 = Dynamic|Win32 {BFCEE1BE-5DC9-4CDF-B55E-6DEDFC4FF782}.Dynamic|x64.ActiveCfg = Dynamic|x64 {BFCEE1BE-5DC9-4CDF-B55E-6DEDFC4FF782}.Dynamic|x64.Build.0 = Dynamic|x64 - {BFCEE1BE-5DC9-4CDF-B55E-6DEDFC4FF782}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {BFCEE1BE-5DC9-4CDF-B55E-6DEDFC4FF782}.Dynamic|x86.Build.0 = Dynamic|Win32 + {DB748474-ADA6-4AEB-8694-F02088D88AD7}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {DB748474-ADA6-4AEB-8694-F02088D88AD7}.Dynamic|Win32.Build.0 = Dynamic|Win32 {DB748474-ADA6-4AEB-8694-F02088D88AD7}.Dynamic|x64.ActiveCfg = Dynamic|x64 {DB748474-ADA6-4AEB-8694-F02088D88AD7}.Dynamic|x64.Build.0 = Dynamic|x64 - {DB748474-ADA6-4AEB-8694-F02088D88AD7}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {DB748474-ADA6-4AEB-8694-F02088D88AD7}.Dynamic|x86.Build.0 = Dynamic|Win32 + {583840C9-525A-4417-866C-6197EBC12214}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {583840C9-525A-4417-866C-6197EBC12214}.Dynamic|Win32.Build.0 = Dynamic|Win32 {583840C9-525A-4417-866C-6197EBC12214}.Dynamic|x64.ActiveCfg = Dynamic|x64 {583840C9-525A-4417-866C-6197EBC12214}.Dynamic|x64.Build.0 = Dynamic|x64 - {583840C9-525A-4417-866C-6197EBC12214}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {583840C9-525A-4417-866C-6197EBC12214}.Dynamic|x86.Build.0 = Dynamic|Win32 + {6191AA5F-75C1-4448-9CE1-E5DED284501B}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {6191AA5F-75C1-4448-9CE1-E5DED284501B}.Dynamic|Win32.Build.0 = Dynamic|Win32 {6191AA5F-75C1-4448-9CE1-E5DED284501B}.Dynamic|x64.ActiveCfg = Dynamic|x64 {6191AA5F-75C1-4448-9CE1-E5DED284501B}.Dynamic|x64.Build.0 = Dynamic|x64 - {6191AA5F-75C1-4448-9CE1-E5DED284501B}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {6191AA5F-75C1-4448-9CE1-E5DED284501B}.Dynamic|x86.Build.0 = Dynamic|Win32 + {76FA1CA3-FC3D-45D2-86A8-B068F551652F}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {76FA1CA3-FC3D-45D2-86A8-B068F551652F}.Dynamic|Win32.Build.0 = Dynamic|Win32 {76FA1CA3-FC3D-45D2-86A8-B068F551652F}.Dynamic|x64.ActiveCfg = Dynamic|x64 {76FA1CA3-FC3D-45D2-86A8-B068F551652F}.Dynamic|x64.Build.0 = Dynamic|x64 - {76FA1CA3-FC3D-45D2-86A8-B068F551652F}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {76FA1CA3-FC3D-45D2-86A8-B068F551652F}.Dynamic|x86.Build.0 = Dynamic|Win32 + {E5EF62C7-377D-4B61-8244-CC4F8555F733}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {E5EF62C7-377D-4B61-8244-CC4F8555F733}.Dynamic|Win32.Build.0 = Dynamic|Win32 {E5EF62C7-377D-4B61-8244-CC4F8555F733}.Dynamic|x64.ActiveCfg = Dynamic|x64 {E5EF62C7-377D-4B61-8244-CC4F8555F733}.Dynamic|x64.Build.0 = Dynamic|x64 - {E5EF62C7-377D-4B61-8244-CC4F8555F733}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {E5EF62C7-377D-4B61-8244-CC4F8555F733}.Dynamic|x86.Build.0 = Dynamic|Win32 + {3DCA40EE-0C42-4D51-996F-EF2D3E599738}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {3DCA40EE-0C42-4D51-996F-EF2D3E599738}.Dynamic|Win32.Build.0 = Dynamic|Win32 {3DCA40EE-0C42-4D51-996F-EF2D3E599738}.Dynamic|x64.ActiveCfg = Dynamic|x64 {3DCA40EE-0C42-4D51-996F-EF2D3E599738}.Dynamic|x64.Build.0 = Dynamic|x64 - {3DCA40EE-0C42-4D51-996F-EF2D3E599738}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {3DCA40EE-0C42-4D51-996F-EF2D3E599738}.Dynamic|x86.Build.0 = Dynamic|Win32 + {5E420537-E1A9-4004-BBDC-F2853AAD5485}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {5E420537-E1A9-4004-BBDC-F2853AAD5485}.Dynamic|Win32.Build.0 = Dynamic|Win32 {5E420537-E1A9-4004-BBDC-F2853AAD5485}.Dynamic|x64.ActiveCfg = Dynamic|x64 {5E420537-E1A9-4004-BBDC-F2853AAD5485}.Dynamic|x64.Build.0 = Dynamic|x64 - {5E420537-E1A9-4004-BBDC-F2853AAD5485}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {5E420537-E1A9-4004-BBDC-F2853AAD5485}.Dynamic|x86.Build.0 = Dynamic|Win32 + {EAEEB94B-AA03-4E8D-8135-D02D22FBD422}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {EAEEB94B-AA03-4E8D-8135-D02D22FBD422}.Dynamic|Win32.Build.0 = Dynamic|Win32 {EAEEB94B-AA03-4E8D-8135-D02D22FBD422}.Dynamic|x64.ActiveCfg = Dynamic|x64 {EAEEB94B-AA03-4E8D-8135-D02D22FBD422}.Dynamic|x64.Build.0 = Dynamic|x64 - {EAEEB94B-AA03-4E8D-8135-D02D22FBD422}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {EAEEB94B-AA03-4E8D-8135-D02D22FBD422}.Dynamic|x86.Build.0 = Dynamic|Win32 + {67E3DA3B-6DA6-4948-BA97-3C2519F4DCC6}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {67E3DA3B-6DA6-4948-BA97-3C2519F4DCC6}.Dynamic|Win32.Build.0 = Dynamic|Win32 {67E3DA3B-6DA6-4948-BA97-3C2519F4DCC6}.Dynamic|x64.ActiveCfg = Dynamic|x64 {67E3DA3B-6DA6-4948-BA97-3C2519F4DCC6}.Dynamic|x64.Build.0 = Dynamic|x64 - {67E3DA3B-6DA6-4948-BA97-3C2519F4DCC6}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {67E3DA3B-6DA6-4948-BA97-3C2519F4DCC6}.Dynamic|x86.Build.0 = Dynamic|Win32 + {8104E8D8-7343-4BE7-8955-80A1F2D26EC2}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {8104E8D8-7343-4BE7-8955-80A1F2D26EC2}.Dynamic|Win32.Build.0 = Dynamic|Win32 {8104E8D8-7343-4BE7-8955-80A1F2D26EC2}.Dynamic|x64.ActiveCfg = Dynamic|x64 {8104E8D8-7343-4BE7-8955-80A1F2D26EC2}.Dynamic|x64.Build.0 = Dynamic|x64 - {8104E8D8-7343-4BE7-8955-80A1F2D26EC2}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {8104E8D8-7343-4BE7-8955-80A1F2D26EC2}.Dynamic|x86.Build.0 = Dynamic|Win32 + {7DB64944-4784-4F40-9F87-98B8BC623854}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {7DB64944-4784-4F40-9F87-98B8BC623854}.Dynamic|Win32.Build.0 = Dynamic|Win32 {7DB64944-4784-4F40-9F87-98B8BC623854}.Dynamic|x64.ActiveCfg = Dynamic|x64 {7DB64944-4784-4F40-9F87-98B8BC623854}.Dynamic|x64.Build.0 = Dynamic|x64 - {7DB64944-4784-4F40-9F87-98B8BC623854}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {7DB64944-4784-4F40-9F87-98B8BC623854}.Dynamic|x86.Build.0 = Dynamic|Win32 + {D0CFB304-1B97-4C5E-AF66-35A223DDB14B}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {D0CFB304-1B97-4C5E-AF66-35A223DDB14B}.Dynamic|Win32.Build.0 = Dynamic|Win32 {D0CFB304-1B97-4C5E-AF66-35A223DDB14B}.Dynamic|x64.ActiveCfg = Dynamic|x64 {D0CFB304-1B97-4C5E-AF66-35A223DDB14B}.Dynamic|x64.Build.0 = Dynamic|x64 - {D0CFB304-1B97-4C5E-AF66-35A223DDB14B}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {D0CFB304-1B97-4C5E-AF66-35A223DDB14B}.Dynamic|x86.Build.0 = Dynamic|Win32 + {E32658C1-CD24-40DC-8912-C7D3FE803FC1}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {E32658C1-CD24-40DC-8912-C7D3FE803FC1}.Dynamic|Win32.Build.0 = Dynamic|Win32 {E32658C1-CD24-40DC-8912-C7D3FE803FC1}.Dynamic|x64.ActiveCfg = Dynamic|x64 {E32658C1-CD24-40DC-8912-C7D3FE803FC1}.Dynamic|x64.Build.0 = Dynamic|x64 - {E32658C1-CD24-40DC-8912-C7D3FE803FC1}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {E32658C1-CD24-40DC-8912-C7D3FE803FC1}.Dynamic|x86.Build.0 = Dynamic|Win32 + {2A1AEDDB-5ED3-4CA7-8E2D-B0178131397F}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {2A1AEDDB-5ED3-4CA7-8E2D-B0178131397F}.Dynamic|Win32.Build.0 = Dynamic|Win32 {2A1AEDDB-5ED3-4CA7-8E2D-B0178131397F}.Dynamic|x64.ActiveCfg = Dynamic|x64 {2A1AEDDB-5ED3-4CA7-8E2D-B0178131397F}.Dynamic|x64.Build.0 = Dynamic|x64 - {2A1AEDDB-5ED3-4CA7-8E2D-B0178131397F}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {2A1AEDDB-5ED3-4CA7-8E2D-B0178131397F}.Dynamic|x86.Build.0 = Dynamic|Win32 + {631B7B35-DF4B-480A-A61E-F6693403FE5E}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {631B7B35-DF4B-480A-A61E-F6693403FE5E}.Dynamic|Win32.Build.0 = Dynamic|Win32 {631B7B35-DF4B-480A-A61E-F6693403FE5E}.Dynamic|x64.ActiveCfg = Dynamic|x64 {631B7B35-DF4B-480A-A61E-F6693403FE5E}.Dynamic|x64.Build.0 = Dynamic|x64 - {631B7B35-DF4B-480A-A61E-F6693403FE5E}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {631B7B35-DF4B-480A-A61E-F6693403FE5E}.Dynamic|x86.Build.0 = Dynamic|Win32 + {F2ED1274-6DA7-4F08-B9C8-1915409EAEC1}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {F2ED1274-6DA7-4F08-B9C8-1915409EAEC1}.Dynamic|Win32.Build.0 = Dynamic|Win32 {F2ED1274-6DA7-4F08-B9C8-1915409EAEC1}.Dynamic|x64.ActiveCfg = Dynamic|x64 {F2ED1274-6DA7-4F08-B9C8-1915409EAEC1}.Dynamic|x64.Build.0 = Dynamic|x64 - {F2ED1274-6DA7-4F08-B9C8-1915409EAEC1}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {F2ED1274-6DA7-4F08-B9C8-1915409EAEC1}.Dynamic|x86.Build.0 = Dynamic|Win32 + {246A71D1-8AD2-46A1-B04D-8EEF78036F27}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {246A71D1-8AD2-46A1-B04D-8EEF78036F27}.Dynamic|Win32.Build.0 = Dynamic|Win32 {246A71D1-8AD2-46A1-B04D-8EEF78036F27}.Dynamic|x64.ActiveCfg = Dynamic|x64 {246A71D1-8AD2-46A1-B04D-8EEF78036F27}.Dynamic|x64.Build.0 = Dynamic|x64 - {246A71D1-8AD2-46A1-B04D-8EEF78036F27}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {246A71D1-8AD2-46A1-B04D-8EEF78036F27}.Dynamic|x86.Build.0 = Dynamic|Win32 + {506A62DC-BB66-4686-BCBE-E1BBB0B1E27A}.Dynamic|Win32.ActiveCfg = Dynamic|Win32 + {506A62DC-BB66-4686-BCBE-E1BBB0B1E27A}.Dynamic|Win32.Build.0 = Dynamic|Win32 {506A62DC-BB66-4686-BCBE-E1BBB0B1E27A}.Dynamic|x64.ActiveCfg = Dynamic|x64 {506A62DC-BB66-4686-BCBE-E1BBB0B1E27A}.Dynamic|x64.Build.0 = Dynamic|x64 - {506A62DC-BB66-4686-BCBE-E1BBB0B1E27A}.Dynamic|x86.ActiveCfg = Dynamic|Win32 - {506A62DC-BB66-4686-BCBE-E1BBB0B1E27A}.Dynamic|x86.Build.0 = Dynamic|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(DevPartner) = postSolution - EndGlobalSection - GlobalSection(DevPartner) = postSolution - EndGlobalSection - GlobalSection(DevPartner) = postSolution - EndGlobalSection - GlobalSection(DevPartner) = postSolution + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {17AA2359-FA6F-4A1A-B126-6C530112C78F} EndGlobalSection GlobalSection(DevPartner) = postSolution EndGlobalSection diff --git a/srchybrid/lang/lt_LT.rc b/srchybrid/lang/lt_LT.rc index 4abc8e4e..48e867c7 100644 --- a/srchybrid/lang/lt_LT.rc +++ b/srchybrid/lang/lt_LT.rc @@ -420,7 +420,7 @@ BEGIN IDS_GLOBALSEARCH "Globaliai (serveris)" IDS_METHOD "Metodas" IDS_UNDO "Atšaukti" - IDS_DAYLY "kasdien" + IDS_DAILY "kasdien" END STRINGTABLE @@ -1426,7 +1426,7 @@ BEGIN IDS_EM_HELP "Pa&galba" IDS_WRN_FRIENDDUPLIPPORT "Draugas nepridėtas.\r\n\r\nSąraše jau yra draugas su tokiu pačiu IP ir portu." - IDS_DYNUP "Išsiuntimo greičio automatika (IGA)" + IDS_DYNUP "Išsiuntimo greičio automatika (nerekomenduojama)" IDS_KADOVERHEAD "Kad perkrova (paketai): %s (%s)" IDS_FIND "Rasti..." IDS_LOG_BANNED_CLIENTS "Loginti užbanintus klientus" diff --git a/srchybrid/lang/lt_LT.vcxproj b/srchybrid/lang/lt_LT.vcxproj index ac445142..f95f3b31 100644 --- a/srchybrid/lang/lt_LT.vcxproj +++ b/srchybrid/lang/lt_LT.vcxproj @@ -14,82 +14,45 @@ languages - Lithuanian {9B6F843F-A792-466D-98E3-A3921525AFF5} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)lt_LT.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)lt_LT.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/lv_LV.rc b/srchybrid/lang/lv_LV.rc index 51c81b24..1c402c4b 100644 --- a/srchybrid/lang/lv_LV.rc +++ b/srchybrid/lang/lv_LV.rc @@ -472,7 +472,7 @@ BEGIN IDS_GLOBALSEARCH "Globālie (Serveri)" IDS_METHOD "Metode" IDS_UNDO "Atsaukt" - IDS_DAYLY "Ikdiena" + IDS_DAILY "Ikdiena" END STRINGTABLE @@ -1200,10 +1200,10 @@ BEGIN IDS_SHAREDREQ1 "User %s (%u) requested your list of shared directories -> %s" IDS_SHAREDREQ2 "User %s (%u) requested your list of shared files for directory '%s' -> %s" IDS_SHAREDANSW "User %s (%u) shares directory '%s'" - IDS_SHAREDANSW2 "User %s (%u) sent not requested list of shared directories - ignored" + IDS_SHAREDANSW2 "User %s (%u) sent unrequested list of shared directories - ignored" IDS_SHAREDINFO1 "User %s (%u) sent list of shared files for directory '%s'" IDS_SHAREDINFO2 "User %s (%u) finished sending lists of shared files" - IDS_SHAREDANSW3 "User %s (%u) sent not requested list of shared files for directory '%s' - ignored" + IDS_SHAREDANSW3 "User %s (%u) sent unrequested list of shared files for directory '%s' - ignored" END STRINGTABLE @@ -1502,7 +1502,7 @@ BEGIN IDS_EM_HELP "&Help" IDS_WRN_FRIENDDUPLIPPORT "Friend not added.\r\n\r\nThere is already a friend with same IP address and port available." - IDS_DYNUP "Upload SpeedSense" + IDS_DYNUP "Upload SpeedSense (not recommended)" IDS_KADOVERHEAD "Kad Overhead (Packets): %s (%s)" IDS_FIND "Find..." IDS_LOG_BANNED_CLIENTS "Log banned clients" diff --git a/srchybrid/lang/lv_LV.vcxproj b/srchybrid/lang/lv_LV.vcxproj index bb194b00..a87613ae 100644 --- a/srchybrid/lang/lv_LV.vcxproj +++ b/srchybrid/lang/lv_LV.vcxproj @@ -14,82 +14,45 @@ languages - Latvian {2885B86D-9DDA-460C-9FB8-41B005F15349} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)lv_LV.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)lv_LV.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/mt_MT.rc b/srchybrid/lang/mt_MT.rc index ec7c839f..059e24d0 100644 --- a/srchybrid/lang/mt_MT.rc +++ b/srchybrid/lang/mt_MT.rc @@ -471,7 +471,7 @@ BEGIN IDS_GLOBALSEARCH "Globali (Fis-Servers)" IDS_METHOD "Metodu" IDS_UNDO "Erġa Lura" - IDS_DAYLY "Kuljum" + IDS_DAILY "Kuljum" END STRINGTABLE @@ -1507,7 +1507,7 @@ BEGIN IDS_EM_HELP "Għajnuna" IDS_WRN_FRIENDDUPLIPPORT "Ħabib mhux miżjud. \r\n\r\nDiġa hemm ħabib bl-istess indirizz tal-IP u port." - IDS_DYNUP "SpeedSense fl-Upload" + IDS_DYNUP "SpeedSense fl-Upload (mhux rikomandat)" IDS_KADOVERHEAD "Il-ħela mill-Kad (Pakketti): %s (%s)" IDS_FIND "Sib..." IDS_LOG_BANNED_CLIENTS "Żomm nota tal-klijenti ibbenjati" diff --git a/srchybrid/lang/mt_MT.vcxproj b/srchybrid/lang/mt_MT.vcxproj index d4f00447..73e16e31 100644 --- a/srchybrid/lang/mt_MT.vcxproj +++ b/srchybrid/lang/mt_MT.vcxproj @@ -14,82 +14,45 @@ languages - Maltese {D0CFB304-1B97-4C5E-AF66-35A223DDB14B} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)mt_MT.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)mt_MT.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/nb_NO.rc b/srchybrid/lang/nb_NO.rc index 046450c1..25ddbcce 100644 --- a/srchybrid/lang/nb_NO.rc +++ b/srchybrid/lang/nb_NO.rc @@ -420,7 +420,7 @@ BEGIN IDS_GLOBALSEARCH "Global (Server)" IDS_METHOD "Metode" IDS_UNDO "Angre" - IDS_DAYLY "daglig" + IDS_DAILY "daglig" END STRINGTABLE @@ -1436,7 +1436,7 @@ BEGIN IDS_EM_HELP "&Hjelp" IDS_WRN_FRIENDDUPLIPPORT "Venn ikke lagt til.\r\n\r\nDet er allerede en venn med samme IP og port tilgjengelig." - IDS_DYNUP "Opplasnings hastighetmåler" + IDS_DYNUP "Opplasnings hastighetmåler (ikke anbefalt)" IDS_KADOVERHEAD "Kad Dataoverskudd (Pakker): %s (%s)" IDS_FIND "Finn..." IDS_LOG_BANNED_CLIENTS "Logg svartelistede klienter" diff --git a/srchybrid/lang/nb_NO.vcxproj b/srchybrid/lang/nb_NO.vcxproj index b4f52e70..5f11fef8 100644 --- a/srchybrid/lang/nb_NO.vcxproj +++ b/srchybrid/lang/nb_NO.vcxproj @@ -14,82 +14,45 @@ languages - Norwegian (Bokmal) {DE470764-A818-4780-B590-78EB8D560E89} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)nb_NO.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)nb_NO.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/nl_NL.rc b/srchybrid/lang/nl_NL.rc index e8498a04..d8deaebb 100644 --- a/srchybrid/lang/nl_NL.rc +++ b/srchybrid/lang/nl_NL.rc @@ -422,7 +422,7 @@ BEGIN IDS_GLOBALSEARCH "Globaal (server)" IDS_METHOD "Methode" IDS_UNDO "Ongedaan maken" - IDS_DAYLY "dagelijks" + IDS_DAILY "dagelijks" END STRINGTABLE @@ -1445,7 +1445,7 @@ BEGIN IDS_EM_HELP "Help" IDS_WRN_FRIENDDUPLIPPORT "Vriend niet toegevoegd.\r\n\r\nEr is al een vriend met hetzelfde IP-adres en poort beschikbaar." - IDS_DYNUP "Uploadsnelheidssensor" + IDS_DYNUP "Uploadsnelheidssensor (niet aangeraden)" IDS_KADOVERHEAD "Kad-overhead (pakketten): %s (%s)" IDS_FIND "Zoeken..." IDS_LOG_BANNED_CLIENTS "Verbannen cliënten loggen" diff --git a/srchybrid/lang/nl_NL.vcxproj b/srchybrid/lang/nl_NL.vcxproj index a9d44cfd..79c758e5 100644 --- a/srchybrid/lang/nl_NL.vcxproj +++ b/srchybrid/lang/nl_NL.vcxproj @@ -14,82 +14,45 @@ languages - Dutch (Netherlands) {A989B752-28A2-44E7-8C19-F49C7ECD61DC} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)nl_NL.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)nl_NL.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/nn_NO.rc b/srchybrid/lang/nn_NO.rc index 49df5f6f..704b7030 100644 --- a/srchybrid/lang/nn_NO.rc +++ b/srchybrid/lang/nn_NO.rc @@ -404,7 +404,7 @@ BEGIN IDS_GLOBALSEARCH "Global (tenar)" IDS_METHOD "Metode" IDS_UNDO "Angre" - IDS_DAYLY "dagleg" + IDS_DAILY "dagleg" END STRINGTABLE @@ -1404,7 +1404,7 @@ BEGIN IDS_MINLENGTH "Min. lengde [tt:mm:ss]" IDS_EM_HELP "Hjelp" IDS_WRN_FRIENDDUPLIPPORT "Ven ikke lagd til.\r\n\r\nDet finst allereie ein ven med same IP og port tilgjengeleg." - IDS_DYNUP "Opplastingsfartsmålar" + IDS_DYNUP "Opplastingsfartsmålar (ikkje tilrådd)" IDS_KADOVERHEAD "Kad-dataoverskot (pakkar): %s (%s)" IDS_FIND "Finn..." IDS_LOG_BANNED_CLIENTS "Logg nekta klientar" diff --git a/srchybrid/lang/nn_NO.vcxproj b/srchybrid/lang/nn_NO.vcxproj index 55d77ba5..cb97692c 100644 --- a/srchybrid/lang/nn_NO.vcxproj +++ b/srchybrid/lang/nn_NO.vcxproj @@ -14,82 +14,45 @@ languages - Norwegian (Nynorsk) {67E3DA3B-6DA6-4948-BA97-3C2519F4DCC6} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)nn_NO.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)nn_NO.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/pl_PL.rc b/srchybrid/lang/pl_PL.rc index 76c96315..ad2cc035 100644 --- a/srchybrid/lang/pl_PL.rc +++ b/srchybrid/lang/pl_PL.rc @@ -500,7 +500,7 @@ BEGIN IDS_GLOBALSEARCH "Globalny (Serwer)" IDS_METHOD "Metoda" IDS_UNDO "Cofnij" - IDS_DAYLY "Codziennie" + IDS_DAILY "Codziennie" IDS_DAY_MO_FR "Pon-Pia" END @@ -1565,7 +1565,7 @@ BEGIN IDS_EM_HELP "&Pomoc" IDS_WRN_FRIENDDUPLIPPORT "Znajomy nie dodany.\r\n\r\nJest już znajomy z tym samym adresem IP i portem." - IDS_DYNUP "Wysyłanie SpeedSense" + IDS_DYNUP "Wysyłanie SpeedSense (niezalecane)" IDS_KADOVERHEAD "Narzut Kad (pakietów): %s (%s)" IDS_FIND "Szukaj..." IDS_LOG_BANNED_CLIENTS "Loguj banowanych klientów" diff --git a/srchybrid/lang/pl_PL.vcxproj b/srchybrid/lang/pl_PL.vcxproj index 7e8958ae..3aec7a7e 100644 --- a/srchybrid/lang/pl_PL.vcxproj +++ b/srchybrid/lang/pl_PL.vcxproj @@ -14,82 +14,45 @@ languages - Polish {57E9C9FF-E57F-46E0-823A-38DD76FEEBC6} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)pl_PL.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)pl_PL.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/pt_BR.rc b/srchybrid/lang/pt_BR.rc index ad627e52..0fd50bf8 100644 --- a/srchybrid/lang/pt_BR.rc +++ b/srchybrid/lang/pt_BR.rc @@ -439,7 +439,7 @@ BEGIN IDS_GLOBALSEARCH "Global (Servidores)" IDS_METHOD "Método" IDS_UNDO "Desfazer" - IDS_DAYLY "Diário" + IDS_DAILY "Diário" IDS_DAY_MO_FR "Seg-Sex" END @@ -1467,7 +1467,7 @@ BEGIN IDS_EM_HELP "Aj&uda" IDS_WRN_FRIENDDUPLIPPORT "Amigo não adicionado.\r\n\r\nJá existe um amigo com o mesmo endereço IP e porta na lista." - IDS_DYNUP "Sensor de velocidade de upload (SpeedSense)" + IDS_DYNUP "Sensor de velocidade de upload (não recomendado)" IDS_KADOVERHEAD "Overhead na rede Kad (pacotes): %s (%s)" IDS_FIND "Localizar..." IDS_LOG_BANNED_CLIENTS "Registrar usuários banidos" diff --git a/srchybrid/lang/pt_BR.vcxproj b/srchybrid/lang/pt_BR.vcxproj index 6c96dcdb..b243edbe 100644 --- a/srchybrid/lang/pt_BR.vcxproj +++ b/srchybrid/lang/pt_BR.vcxproj @@ -14,82 +14,45 @@ languages - Portuguese (Brazil) {C7F4CB73-7D57-4077-9C04-931A6CB0677D} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)pt_BR.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)pt_BR.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/pt_PT.rc b/srchybrid/lang/pt_PT.rc index 39baa23c..b71d3f5b 100644 --- a/srchybrid/lang/pt_PT.rc +++ b/srchybrid/lang/pt_PT.rc @@ -425,7 +425,7 @@ BEGIN IDS_GLOBALSEARCH "Global (Servidores)" IDS_METHOD "Método" IDS_UNDO "Desfazer" - IDS_DAYLY "diariamente" + IDS_DAILY "diariamente" END STRINGTABLE @@ -1429,7 +1429,7 @@ BEGIN IDS_EM_HELP "&Ajuda" IDS_WRN_FRIENDDUPLIPPORT "Amigo não adicionado.\r\n\r\nJá existe um amigo registado com o mesmo endereço de IP e Porta." - IDS_DYNUP "Detecção da Velocidade de Upload" + IDS_DYNUP "Detecção da Velocidade de Upload (não recomendado)" IDS_KADOVERHEAD "Largura de Banda Kad Adicional (Pacotes): %s (%s)" IDS_FIND "Pesquisar..." IDS_LOG_BANNED_CLIENTS "Registar clientes banidos" diff --git a/srchybrid/lang/pt_PT.vcxproj b/srchybrid/lang/pt_PT.vcxproj index 5943aefe..af446c57 100644 --- a/srchybrid/lang/pt_PT.vcxproj +++ b/srchybrid/lang/pt_PT.vcxproj @@ -14,82 +14,45 @@ languages - Portuguese (Portugal) {64DFFE85-14E0-41D7-ADFA-7D53EE81D1B2} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)pt_PT.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)pt_PT.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/ro_RO.rc b/srchybrid/lang/ro_RO.rc index 515a2e2e..46d365bb 100644 --- a/srchybrid/lang/ro_RO.rc +++ b/srchybrid/lang/ro_RO.rc @@ -464,7 +464,7 @@ BEGIN IDS_GLOBALSEARCH "Global (Server)" IDS_METHOD "Tipul căutării" IDS_UNDO "Anulează" - IDS_DAYLY "zilnic" + IDS_DAILY "zilnic" END STRINGTABLE @@ -1453,7 +1453,7 @@ BEGIN IDS_EM_HELP "&Ajutor" IDS_WRN_FRIENDDUPLIPPORT "Slot prieten neadăugat.\r\n\r\nExistă deja un prieten cu acelaşi IP şi port." - IDS_DYNUP "Upload dinamic" + IDS_DYNUP "Upload dinamic (nerecomandat)" IDS_KADOVERHEAD "Adiţional Kad (Pachete): %s (%s)" IDS_FIND "Caută..." IDS_LOG_BANNED_CLIENTS "Loghează clienţii alungaţi" diff --git a/srchybrid/lang/ro_RO.vcxproj b/srchybrid/lang/ro_RO.vcxproj index 9af0a299..d1c5f545 100644 --- a/srchybrid/lang/ro_RO.vcxproj +++ b/srchybrid/lang/ro_RO.vcxproj @@ -14,82 +14,45 @@ languages - Romania {3DCA40EE-0C42-4D51-996F-EF2D3E599738} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)ro_RO.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\Debug\lang md ..\Debug\lang -copy "$(TargetPath)" ..\Debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)ro_RO.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\Debug\lang md ..\Debug\lang -copy "$(TargetPath)" ..\Debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\Debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/ru_RU.rc b/srchybrid/lang/ru_RU.rc index b6d8cb9d..cc72c897 100644 --- a/srchybrid/lang/ru_RU.rc +++ b/srchybrid/lang/ru_RU.rc @@ -472,7 +472,7 @@ BEGIN IDS_GLOBALSEARCH "Глобальный (серверы) " IDS_METHOD "Метод" IDS_UNDO "Вернуть" - IDS_DAYLY "Ежедневно" + IDS_DAILY "Ежедневно" END STRINGTABLE @@ -1499,7 +1499,7 @@ BEGIN IDS_EM_HELP "&Помощь" IDS_WRN_FRIENDDUPLIPPORT "Не добавлен в список друзей.\r\n\r\nУже есть друг с таким же IP и портом." - IDS_DYNUP "'Умная' отдача" + IDS_DYNUP "'Умная' отдача (не рекомендовано)" IDS_KADOVERHEAD "Сеть Kad (пакеты): %s (%s)" IDS_FIND "Поиск..." IDS_LOG_BANNED_CLIENTS "Лог забаненных клиентов" diff --git a/srchybrid/lang/ru_RU.vcxproj b/srchybrid/lang/ru_RU.vcxproj index 8a3cfde4..2b69dcd9 100644 --- a/srchybrid/lang/ru_RU.vcxproj +++ b/srchybrid/lang/ru_RU.vcxproj @@ -14,82 +14,45 @@ languages - Russian {4AE4AB3A-FD80-4DFE-BF9B-AC845DCF2449} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)ru_RU.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)ru_RU.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/sl_SI.rc b/srchybrid/lang/sl_SI.rc index ae314874..8941b311 100644 --- a/srchybrid/lang/sl_SI.rc +++ b/srchybrid/lang/sl_SI.rc @@ -421,7 +421,7 @@ BEGIN IDS_GLOBALSEARCH "Globalno (Strežnik)" IDS_METHOD "Način" IDS_UNDO "Razveljavi" - IDS_DAYLY "dnevno" + IDS_DAILY "dnevno" END STRINGTABLE @@ -1418,7 +1418,7 @@ BEGIN IDS_EM_HELP "&Pomoč" IDS_WRN_FRIENDDUPLIPPORT "Prijatelj ni bil dodan.\r\n\r\nPrijatelj z istim IP naslovom in vrati že obstaja." - IDS_DYNUP "Zaznavanje hitrosti prenosa gor (SpeedSense)" + IDS_DYNUP "Zaznavanje hitrosti prenosa gor (ni priporočljivo)" IDS_KADOVERHEAD "Presežek Kad (Paketov): %s (%s)" IDS_FIND "Najdi..." IDS_LOG_BANNED_CLIENTS "Beleži izločene odjemalce" diff --git a/srchybrid/lang/sl_SI.vcxproj b/srchybrid/lang/sl_SI.vcxproj index 5ce09be2..e00a05c7 100644 --- a/srchybrid/lang/sl_SI.vcxproj +++ b/srchybrid/lang/sl_SI.vcxproj @@ -14,81 +14,45 @@ languages - Slovenian {F8A9B7BC-3CBB-4DEC-A04E-5224A65A6632} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - Level3 - - - $(OutDir)sl_SI.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)sl_SI.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -99,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/sq_AL.rc b/srchybrid/lang/sq_AL.rc index 685df933..947adfb3 100644 --- a/srchybrid/lang/sq_AL.rc +++ b/srchybrid/lang/sq_AL.rc @@ -470,7 +470,7 @@ BEGIN IDS_GLOBALSEARCH "Globale (Server)" IDS_METHOD "Metodë" IDS_UNDO "Zhbëje" - IDS_DAYLY "Përditë" + IDS_DAILY "Përditë" END STRINGTABLE @@ -1503,7 +1503,7 @@ BEGIN IDS_EM_HELP "&Ndihmë" IDS_WRN_FRIENDDUPLIPPORT "Shoku nuk u shtua.\r\n\r\nNjë tjetër me të njëjtën adresë dhe port IP të vlefshëm ekziston që më parë." - IDS_DYNUP "Ana e Shpejtësisë Ngarkuese" + IDS_DYNUP "Ana e Shpejtësisë Ngarkuese (nuk rekomandohet)" IDS_KADOVERHEAD "Sipëria e Kad-it (Paketa): %s (%s)" IDS_FIND "Kërko..." IDS_LOG_BANNED_CLIENTS "Shëno klientët e dëbuar" diff --git a/srchybrid/lang/sq_AL.vcxproj b/srchybrid/lang/sq_AL.vcxproj index be449af9..3ff814a1 100644 --- a/srchybrid/lang/sq_AL.vcxproj +++ b/srchybrid/lang/sq_AL.vcxproj @@ -14,81 +14,45 @@ languages - Albanian (Albania) {8104E8D8-7343-4BE7-8955-80A1F2D26EC2} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - Level3 - - - $(OutDir)sq_AL.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)sq_AL.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -99,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/sv_SE.rc b/srchybrid/lang/sv_SE.rc index adc7da99..7551f10d 100644 --- a/srchybrid/lang/sv_SE.rc +++ b/srchybrid/lang/sv_SE.rc @@ -418,7 +418,7 @@ BEGIN IDS_GLOBALSEARCH "Globalt (server)" IDS_METHOD "Metod" IDS_UNDO "Ångra" - IDS_DAYLY "Dagligen" + IDS_DAILY "Dagligen" END STRINGTABLE @@ -1442,7 +1442,7 @@ BEGIN IDS_EM_HELP "&Hjälp" IDS_WRN_FRIENDDUPLIPPORT "Kompisen blev inte tillagd.\r\n\r\nDet finns redan en kompis med samma IP-adress och port." - IDS_DYNUP "Uppladdning SpeedSense" + IDS_DYNUP "Uppladdning SpeedSense (inte rekommenderat)" IDS_KADOVERHEAD "Kad overhead (paket): %s (%s)" IDS_FIND "Hitta..." IDS_LOG_BANNED_CLIENTS "Logga bannade klienter" diff --git a/srchybrid/lang/sv_SE.vcxproj b/srchybrid/lang/sv_SE.vcxproj index f900de12..7e6a44ac 100644 --- a/srchybrid/lang/sv_SE.vcxproj +++ b/srchybrid/lang/sv_SE.vcxproj @@ -14,81 +14,45 @@ languages - Swedish {2AECAA37-18C5-4C04-8E34-3E6EDCD926AE} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - Level3 - - - $(OutDir)sv_SE.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)sv_SE.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -99,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/tr_TR.rc b/srchybrid/lang/tr_TR.rc index d7aef9ac..55b62530 100644 --- a/srchybrid/lang/tr_TR.rc +++ b/srchybrid/lang/tr_TR.rc @@ -434,7 +434,7 @@ BEGIN IDS_GLOBALSEARCH "Genel (Sunucular)" IDS_METHOD "Yöntem" IDS_UNDO "Geri Al" - IDS_DAYLY "Günlük" + IDS_DAILY "Günlük" END STRINGTABLE @@ -1450,7 +1450,7 @@ BEGIN IDS_EM_HELP "&Yardım" IDS_WRN_FRIENDDUPLIPPORT "Arkadaş eklenmedi.\r\n\r\nZaten aynı IP adresi ve bağlantı noktası olan arkadaş var." - IDS_DYNUP "Gönderme Hızı Algılama" + IDS_DYNUP "Gönderme Hızı Algılama (önerilmez)" IDS_KADOVERHEAD "Kad Ek Yükü (Paket): %s (%s)" IDS_FIND "Bul..." IDS_LOG_BANNED_CLIENTS "Yasaklı istemcileri günlükle" diff --git a/srchybrid/lang/tr_TR.vcxproj b/srchybrid/lang/tr_TR.vcxproj index 3265bb62..e2ce53da 100644 --- a/srchybrid/lang/tr_TR.vcxproj +++ b/srchybrid/lang/tr_TR.vcxproj @@ -14,82 +14,45 @@ languages - Turkish {EFE9605D-BF5C-4339-9A5A-32184D4BD03C} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)tr_TR.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)tr_TR.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/ua_UA.rc b/srchybrid/lang/ua_UA.rc index 7386da7f..9fb43d41 100644 --- a/srchybrid/lang/ua_UA.rc +++ b/srchybrid/lang/ua_UA.rc @@ -471,7 +471,7 @@ BEGIN IDS_GLOBALSEARCH "Глобальний" IDS_METHOD "Метод" IDS_UNDO "Повернути" - IDS_DAYLY "Щоденно" + IDS_DAILY "Щоденно" END STRINGTABLE @@ -1507,7 +1507,7 @@ BEGIN IDS_EM_HELP "&Довідка" IDS_WRN_FRIENDDUPLIPPORT "Не додано до списку друзів.\r\n\r\nВ списках друзів даний IP вже присутній" - IDS_DYNUP "'Розумне' відвантаження" + IDS_DYNUP "'Розумне' відвантаження (не рекомендується)" IDS_KADOVERHEAD "Kad перевищення (Пакети): %s (%s)" IDS_FIND "Знайти..." IDS_LOG_BANNED_CLIENTS "Лоґ заблокованих клієнтів" diff --git a/srchybrid/lang/ua_UA.vcxproj b/srchybrid/lang/ua_UA.vcxproj index 64b82671..a3ac75a4 100644 --- a/srchybrid/lang/ua_UA.vcxproj +++ b/srchybrid/lang/ua_UA.vcxproj @@ -14,82 +14,45 @@ languages - Ukrainian {7DB64944-4784-4F40-9F87-98B8BC623854} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - - Level3 - - - $(OutDir)ua_UA.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)ua_UA.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -100,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/ug_CN.rc b/srchybrid/lang/ug_CN.rc index 2769c1fc..04169007 100644 --- a/srchybrid/lang/ug_CN.rc +++ b/srchybrid/lang/ug_CN.rc @@ -497,7 +497,7 @@ BEGIN IDS_GLOBALSEARCH "ئومۇمىيەت (مۇلازىمېتىر)‏" IDS_METHOD "ئۇسۇل" IDS_UNDO "يېنىۋال" - IDS_DAYLY "كۈندىلىك" + IDS_DAILY "كۈندىلىك" IDS_DAY_MO_FR "دۈشەنبىدىن - جۈمەگىچە" END @@ -1217,10 +1217,10 @@ BEGIN IDS_SHAREDREQ1 "User %s (%u) requested your list of shared directories -> %s" IDS_SHAREDREQ2 "User %s (%u) requested your list of shared files for directory '%s' -> %s" IDS_SHAREDANSW "User %s (%u) shares directory '%s'" - IDS_SHAREDANSW2 "User %s (%u) sent not requested list of shared directories - ignored" + IDS_SHAREDANSW2 "User %s (%u) sent unrequested list of shared directories - ignored" IDS_SHAREDINFO1 "User %s (%u) sent list of shared files for directory '%s'" IDS_SHAREDINFO2 "User %s (%u) finished sending lists of shared files" - IDS_SHAREDANSW3 "User %s (%u) sent not requested list of shared files for directory '%s' - ignored" + IDS_SHAREDANSW3 "User %s (%u) sent unrequested list of shared files for directory '%s' - ignored" IDS_SHAREDREQDENIED "User %s (%u) denied access to list of shared directories/files" IDS_AUTOCLEANUPFN "ھۆججەت ئاتىنى ئۆزلۈكىدىن تازىلا" IDS_ONNEWDOWNLOAD "دەسلەپلەشتۈرۈش قىممەت تەڭشىكى" @@ -1560,7 +1560,7 @@ BEGIN IDS_EM_HELP "ياردەم" IDS_WRN_FRIENDDUPLIPPORT "دوست قوشمىدى.\r\n\r\nئوخشاش‫ IP ئادرېسى بار دوستتىن بىرسى مەۋجۇد.‬" - IDS_DYNUP "يوللاش سۈرئىتىنى تەكشۈر" + IDS_DYNUP "يوللاش سۈرئىتىنى تەكشۈر (ئىشلىتىش تەۋسىيە قىلىنمايدۇ)‏" IDS_KADOVERHEAD "Kad سەرپىياتى (: %s (%s(بوغچا)" IDS_FIND "ئىزدە…‏" IDS_LOG_BANNED_CLIENTS "خاتىرە چەكلەنگەن خېرىدار" diff --git a/srchybrid/lang/ug_CN.vcxproj b/srchybrid/lang/ug_CN.vcxproj index 7f1b18d9..3a6fe84f 100644 --- a/srchybrid/lang/ug_CN.vcxproj +++ b/srchybrid/lang/ug_CN.vcxproj @@ -14,81 +14,45 @@ languages - Uighur (PRC) {246A71D1-8AD2-46A1-B04D-8EEF78036F27} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - Level3 - - - $(OutDir)ug_CN.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)ug_CN.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -99,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/va_ES.rc b/srchybrid/lang/va_ES.rc index 10125988..39f6ba8e 100644 --- a/srchybrid/lang/va_ES.rc +++ b/srchybrid/lang/va_ES.rc @@ -422,7 +422,7 @@ BEGIN IDS_GLOBALSEARCH "Global (servidor)" IDS_METHOD "Mètode" IDS_UNDO "Desfés" - IDS_DAYLY "a diari" + IDS_DAILY "a diari" END STRINGTABLE @@ -1427,7 +1427,7 @@ BEGIN IDS_EM_HELP "A&juda" IDS_WRN_FRIENDDUPLIPPORT "No s'ha afegit l'amic.\r\n\r\Ja existeix un amic amb la mateixa adreça IP i port disponible." - IDS_DYNUP "Sensor de velocitat de pujada" + IDS_DYNUP "Sensor de velocitat de pujada (no es recomana)" IDS_KADOVERHEAD "Tràfic excedent Kad (paquets): %s (%s)" IDS_FIND "Troba..." IDS_LOG_BANNED_CLIENTS "Registra els clients exclosos" diff --git a/srchybrid/lang/va_ES.vcxproj b/srchybrid/lang/va_ES.vcxproj index 710bef90..148c54b9 100644 --- a/srchybrid/lang/va_ES.vcxproj +++ b/srchybrid/lang/va_ES.vcxproj @@ -14,81 +14,45 @@ languages - Valencian {631B7B35-DF4B-480A-A61E-F6693403FE5E} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - Level3 - - - $(OutDir)va_ES.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)va_ES.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -99,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/va_ES_RACV.rc b/srchybrid/lang/va_ES_RACV.rc index 57a48612..80c2506b 100644 --- a/srchybrid/lang/va_ES_RACV.rc +++ b/srchybrid/lang/va_ES_RACV.rc @@ -428,7 +428,7 @@ BEGIN IDS_GLOBALSEARCH "Global (Servidor)" IDS_METHOD "Mètodo" IDS_UNDO "Desfer" - IDS_DAYLY "Diari" + IDS_DAILY "Diari" END STRINGTABLE @@ -1434,7 +1434,7 @@ BEGIN IDS_EM_HELP "A&juda" IDS_WRN_FRIENDDUPLIPPORT "Amic no afegit.\r\n\r\nYa existix un amic en la mateixa IP i port disponible." - IDS_DYNUP "Sensor de velocitat de pujada" + IDS_DYNUP "Sensor de velocitat de pujada (no recomanat)" IDS_KADOVERHEAD "Tràfic excedent Kad (Paquets): %s (%s)" IDS_FIND "Trobar..." IDS_LOG_BANNED_CLIENTS "Registrar clients prohibits" diff --git a/srchybrid/lang/va_ES_RACV.vcxproj b/srchybrid/lang/va_ES_RACV.vcxproj index d331bbc5..c53996ac 100644 --- a/srchybrid/lang/va_ES_RACV.vcxproj +++ b/srchybrid/lang/va_ES_RACV.vcxproj @@ -14,81 +14,45 @@ languages - Valencian (RACV) {506A62DC-BB66-4686-BCBE-E1BBB0B1E27A} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - Level3 - - - $(OutDir)va_ES_RACV.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)va_ES_RACV.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -99,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/vi_VN.rc b/srchybrid/lang/vi_VN.rc index 3db2a757..f6737e09 100644 --- a/srchybrid/lang/vi_VN.rc +++ b/srchybrid/lang/vi_VN.rc @@ -472,7 +472,7 @@ BEGIN IDS_GLOBALSEARCH "Toàn cục (Các máy chủ)" IDS_METHOD "Phương pháp" IDS_UNDO "Làm lại" - IDS_DAYLY "Hàng ngày" + IDS_DAILY "Hàng ngày" END STRINGTABLE @@ -1508,7 +1508,7 @@ BEGIN IDS_EM_HELP "&Trợ Giúp" IDS_WRN_FRIENDDUPLIPPORT "Bạn bè không được thêm vào.\r\n\r\nĐã có bạn với cùng địa chỉ IP và cổng này rồi." - IDS_DYNUP "ĐoánTốcĐộ-TảiLên" + IDS_DYNUP "ĐoánTốcĐộ-TảiLên (không khuyến khích)" IDS_KADOVERHEAD "Phần dư Kad (Gói): %s (%s)" IDS_FIND "Tìm..." IDS_LOG_BANNED_CLIENTS "Ghi lại các máy khách bị cấm" diff --git a/srchybrid/lang/vi_VN.vcxproj b/srchybrid/lang/vi_VN.vcxproj index 1a3cc873..c15de2bb 100644 --- a/srchybrid/lang/vi_VN.vcxproj +++ b/srchybrid/lang/vi_VN.vcxproj @@ -14,81 +14,45 @@ languages - Vietnamese {2A1AEDDB-5ED3-4CA7-8E2D-B0178131397F} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - Level3 - - - $(OutDir)vi_VN.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)vi_VN.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -99,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/zh_CN.rc b/srchybrid/lang/zh_CN.rc index 61ed2c74..3d4d0b39 100644 --- a/srchybrid/lang/zh_CN.rc +++ b/srchybrid/lang/zh_CN.rc @@ -500,7 +500,7 @@ BEGIN IDS_GLOBALSEARCH "全局(服务器)" IDS_METHOD "方法" IDS_UNDO "撤销" - IDS_DAYLY "每日" + IDS_DAILY "每日" IDS_DAY_MO_FR "周一-周五" END @@ -1563,7 +1563,7 @@ BEGIN IDS_EM_HELP "帮助(&H)" IDS_WRN_FRIENDDUPLIPPORT "朋友没有添加.\r\n\r\n已存在一个有着相同的IP和端口的朋友." - IDS_DYNUP "上传速度侦测(USS)" + IDS_DYNUP "上传速度侦测 - USS (不推荐)" IDS_KADOVERHEAD "Kad开销(包):%s (%s)" IDS_FIND "查找 ..." IDS_LOG_BANNED_CLIENTS "记录被禁止的客户" diff --git a/srchybrid/lang/zh_CN.vcxproj b/srchybrid/lang/zh_CN.vcxproj index 8bfbf49d..8673d158 100644 --- a/srchybrid/lang/zh_CN.vcxproj +++ b/srchybrid/lang/zh_CN.vcxproj @@ -14,81 +14,45 @@ languages - Chinese (P.R.C.) {BFCEE1BE-5DC9-4CDF-B55E-6DEDFC4FF782} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - Level3 - - - $(OutDir)zh_CN.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)zh_CN.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -99,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/lang/zh_TW.rc b/srchybrid/lang/zh_TW.rc index 283402bc..478ae6bd 100644 --- a/srchybrid/lang/zh_TW.rc +++ b/srchybrid/lang/zh_TW.rc @@ -1053,7 +1053,7 @@ BEGIN IDS_GLOBALSEARCH "全球搜尋 (伺服器)" IDS_METHOD "方式" IDS_UNDO "復原" - IDS_DAYLY "每天" + IDS_DAILY "每天" END STRINGTABLE @@ -1460,7 +1460,7 @@ BEGIN IDS_EM_HELP "說明" IDS_WRN_FRIENDDUPLIPPORT "好友沒有被加入.\r\n\r\n在那裡已經有一個以相同 IP 位址及連接埠的好友可使用." - IDS_DYNUP "上載速度感應器" + IDS_DYNUP "上載速度感應器 - USS (不建議使用)" IDS_KADOVERHEAD "Kad 額外支出的傳輸量 (封包): %s (%s)" IDS_FIND "尋找..." IDS_LOG_BANNED_CLIENTS "記錄已被禁止客戶端" diff --git a/srchybrid/lang/zh_TW.vcxproj b/srchybrid/lang/zh_TW.vcxproj index ed2cc260..ee196d77 100644 --- a/srchybrid/lang/zh_TW.vcxproj +++ b/srchybrid/lang/zh_TW.vcxproj @@ -14,81 +14,45 @@ languages - Chinese (Taiwan) {DB748474-ADA6-4AEB-8694-F02088D88AD7} Win32Proj - 10.0 - + DynamicLibrary - v141_xp - Unicode - - - DynamicLibrary - v141_xp Unicode + v143 - - - - + <_ProjectFileVersion>14.0.25420.1 - - dynamic\ - obj\ - false - $(MSBuildProjectName) - - - false + + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ $(MSBuildProjectName) + None - - - WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - Level3 - - - $(OutDir)zh_TW.dll - Windows - true - true - true - - - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - - - + WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) MultiThreaded - - Level3 - $(OutDir)zh_TW.dll Windows true true true - Copying language DLL into debug directory - if not exist ..\debug\lang md ..\debug\lang -copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) + Copying language DLL to intermediate directory + if not exist ..\$(Platform)\lang md ..\$(Platform)\lang +copy "$(TargetPath)" ..\$(Platform)\lang\ @@ -99,6 +63,5 @@ copy "$(TargetPath)" ..\debug\lang\$(TargetFileName) - - + \ No newline at end of file diff --git a/srchybrid/res/MiniMule.htm b/srchybrid/res/MiniMule.htm index 1dba202e..0747316e 100644 --- a/srchybrid/res/MiniMule.htm +++ b/srchybrid/res/MiniMule.htm @@ -36,14 +36,14 @@
Upload
- 50.0 kB/s + 50.0 KB/s
Download
- 123.4 kB/s + 123.4 KB/s diff --git a/srchybrid/res/Mule_Vista.ico b/srchybrid/res/Mule_Vista.ico index 77c46503b865e180ea3a485a037ca4fa0c94fd18..3bb4c7b203abba884e0d711dadee2ef109da4485 100644 GIT binary patch delta 15630 zcmbt*1z45o+V1k7y+^TI#|}!mTNDHZu@f*z2|*CCgN3M=i~-nU3)t9&q8J#MU?8Dm zPp2{a|K~pU^DY=C_BrR;=XlLC-&!9l-sgTg*3HaMZr-b<)o5yIYHJ!dZp`aHG{&_w znyDHMpUeF^ny7zjG+Df-d)`SC^$(5a)7lzMr%t-pzy2?cCa#`5*S$Wcjz%-0Va@YS znjC)4Z!I;No;~I7oixUt8qF>vjmB8MgVZVSz|v0-w^=diABVkar`9{1l9AI`%hzg> zN%98uk8k?xzdFWYhxAOwmDV$lE^TC=SlXiJ+|t&)7nio_n^xLk@aj^7(c4Q+BJxTt z6V8>oBwa7{U3RZ@P{za3L8~8@4qo#}(ZKWvrG9C5OFie^D7BqhSZW%3vebCoL2apV z@a|IMvDu{tf!j(u4qeX=UQ*h~VX}PLmbzw9HuWuIG(vy;*WJ-p<7#hP$IZdEqnm@x z2-5EEjy9$L3GqG0+#DL)gzl5wjbsbPQziwWq8cLiQY@^qW7}9=(FseBJahw;gNC;E;BE} zGX4~dBl2Jvyc-6ic0fO1D>@I~fOZ2`p{3`1G_Xy8o@wO8Iwld$bFE8h1w< zjkBFy?d}dX9Y{Uh>@5SFZOte2aBPzb9+ZzM?`Y0O6tB!p5+z0*r ze9^D3FZy_UeeL1qyvxPbVv>`M=_ujX)!w=*`LF9@XIYD2l7Cy?rJfRjhaVA0Ky$a* zXw_?eH3AvvGBOK>K{+sqJPeEYeArIC2)h|qNS9$h{gNWvDHmWBcM4`vhhP+(i>{-# zqw|O?bR4=)q1dk9=lINf0h+l^2PKR;#^LAd7=^j$X}gWnG%+0`2-N23I+FVlq}^@~ z)}^lYR%Kou?k|Up40t~#G#aBrqYxY(g~;e=#Kw;Q6UD^DASyZrP$n2DQIY)h=$bghD5P} zbsS|Ki+UD9F=%KRjb=6xXk`&UW zC-()71~xisY@dJ@P7~3_B^DiABGJ_)L<>WgK$y7r*Ka`Pnl)Ixb}cq+%0lM4^_aJCF(yr!im>nqj2blx zV@3raB4Qk-&PvAor7MxPG93#Rregf~C=44s;A^iQuG!8uS{)2Di+c0{2WSaT^vt5( z)wPIL+%$2Xro5q8g2-9?LMzV{G^2%xeCwJFZ-j-5pA{sUN-wOKy%*Wp73zSg?gTb)(rU~g;4;J2D6T&HjTk^TVG1uzKGZ>OM@ z*L*bVJ_k*mr=yAEWZq9uG8Yu&HG;@z-t*ADUm6%F(UDdn*3wC?)g+I9e=e3ZbiGz* zO8v!YEJFvMx#;RW1twn6a2ps4|L8fGG-ojuF8Lf8nHgA5jy7-KiS4<2u{C=)pJyR` z^;)E*uff9QnMhf(5=&OB!Iqu5IC$&?PMn|D!o^*T-#T*T&W zyAU@)8;kxvUf(#|==6XH2nrKPkEsg^fyQ(F)NMn=6XboJMfe!ylv-%?HTSVvv`H=~nw#74rifv!^m1yK^�sZ%Q zG@y4AJ6DhC<(j(9Quf?=-PH4Nntl?cj>B<`<{bGsV7^oW!rX~DJUfOk0|phJRycqt&2O}sbD4PhZr3Kt1y_L*}{y=iJYPr+LGrEZ{Xyf-egnJ|A z1g2!fJoY3rq%*LdbRM=-3Sq-c$(~t~^PH=2pI3}t3z;XT-hylL4c@;3tHcXhLUfjJ z5sIiI=oYpQhGVm-4_lR0v}1_vGBg9Wp_|cfY7S!4@~~*jDQwCs#DV-GoGL8B`J!vM zbgfuvy4d&yB9gmzAF^}zsK+9E;kx|ki$77t7cWrxO#2cgG>tQaGLyk%OyI~G1dPdj zBB_$Zd@T$${y<`TQ*z&y+;?S$+l|?f>G%`m{48uHUtpGe3C^>x!ZnE*ane^*DizxkAaz)nOK3Vo^jX&QZ6mwHt9#v1?C87>^PM7DR-~boA6z78~s1OhXE@~;YS2KdCw*3nih7` zFT*mi5EcmqFrRo1W)sd3PNG0_lC;}k^bT}o5z&P%)M{J~`X`@2%<4ic$+?6rM=s&O z>5Di?6bi0f*LgcC^xX$#ctHCufBGCxp1;Pk*I(h~m*3#^*WcpRSKq3~&tHGd``WMY z{LR;>c=iG}OCKP6?_Pw51w*PUBCwa-=ja)SMv!~)h*hEof`Dj$XJ))6kw=u=ttJ=3 zcG^X_P}9B0weR9P=vz&`i*Cbj$sG(xBlkqWkCl^;R7^z3MN1{I6$JPJibNNvNTx9- zm0}r%?1d52Zb3mxF^h4z@SbxTLCeo$&W6*-$UcP~N6sVf>=oo+x{k{?Zljn8+ArB{7Z_UF?MI_oTG9N$=hf&TtD&dv1iqA=dSCpV1 zEuqiCTSTB(tIR~4gf*Ro)s#yRC@n+}=sry%jDZ=SXH-1N;q^z7`eW_$E-2d|SE#AL>kM|!w;4L5j@Y7F3M*AIK zP=mlLBJdD7`}QIHBLXHwAcAy~2s|MI@9JB}t4g-xu#Gg;!_<6wJDRa@??t;FNICmw z-pAPW4-vfKAwoAkQWV6;qt-pd@QnLP4}7Q>9$K1*tM(ckXB8RTNGVh$B_61NyGcON(?#X^l0IFtK0(!ttBA@_;E&yDOSGf`Oy zeJZ9Xs?8K?{_G-n&M!uP%3in+%X)<9ZI2PN<1u1)lp|*QV?=BzL-3|Y@L&A^gO-=T zchMa!-*gjhbdll?B`DZT`-p%v9mFG=L@+`!HW;y~z@&i)?1ppPLG+(<1kq{7kh=L4 zb%0ioe+j296ye+z#)KO;l_fkVe}XSwzQNbuevhB2{qNts{{sTrU+@+G@Z!x^e9@OQ znHRYI;4$_bJcNkw&>94C$$d7hV0>+Zpj0AI)x>EkIt^J%(Hx|*o`vJgEAXNy`={N- zh>TK%ko$?*<(Rgo64UlpV)E_^#PfMHQ3&PV0@pmiU_n5;=+1wHfFUhGe1dtzemKYH z!Eg3agf2aSCU8kQN=S#Eg9vn6R@P;hW14xb^{tEHBZD68s4Pi3j2fELBuIqf#kx zvl0)Cm?a4rhaP}=WFDL*9)Zv76BxDVG-hr%i>-pdnS2~z?!V{oG3+~X3`bArqmVhm zZDzb>%z{K0-Y^b)_x%s}@h9!i_<`>5&DY;C7<`FJCIuyB6)KQy&(2{q99yFUmPBAY z>11ug5akE{9Rj{YARx0;Y5jsDmDq8q5=U-S;SgzCVI@*|Z(>e4!e|Npq61o;8T<_a zD<%>W4NaLyO5@2moNX701tNbzAp9WAqmROI(n)yD&d2c7vq)Tf4jT`gWvzD#Is2I> z=Iq5bR!TVs@^JXn8JxXTq$(hZj*<^PeesI+|IK&!hEPZhcuHu*Vcez{JjoO~odxIU zfRQx_NNpg#UqYnJ?cLa(k&f5s2{m1QkjL%P2;&5>lE|gT^42U{PGZXu-Mu47BrP}1)ip@sX>1WY9xd1~_ z3lN*0k5xO4VAq~~*viUx!&fJAnlm>{@Kb?oI;{o$j4k#Ir_yLLa!Hj$}_LgJa*$QM8RAAZha&j;6;IWF1^nhCQ=8J`U zDH80-y^UnV%m+pLE!a}EoWKAx@eJ$|&%r*i0JaJFs?};4cbbXEdAi<9@JzmheyNu+ zEUgHUs|t{^b|2E$OK)I}Ds18>CSYuE82f@D7~&s{0V6^X89#%41nqu0hElr5*Gz}L zW})x}Zc+QM+`5On6Q{9w=@Lf5;P-xgJYTF@wMw#LLBNAnu)oF+GY$55w=G%*=QUc=nuBcUpQHr zt@;B3O^AR65tv2PJ-iG6VKy zP0&lrgi#7b$5}egrEv6M8Z|oe4i+9L#l9;~aJ}L?oWAxL^D}p0bZioO4;u%^zTq$* zFazd+nXr#13e*F!1_%0%KK#=0Sr4%BEDPJ4Ww>zdCN8i>EGWFFt~ZK{@$lh8JbV5e z+Apc~Z&(P3?=O8+N$&5dV)Ep<0_;ARhh=Oy2aFgB4iUZ(3-|*9&53{=5r`!nV@IsK ziDTkh(E|xiQWJ}$$BXXO3obliUO)wv> zM00e;U8J9Qj1xE6=P9Ycoif>OZ{%)PMKWFL=vL_}zQ$2NnXq(Eh(tZIY|EN>FgQ zh|!PS@88cB>q;ah#D5sv-?xe*6lDQ_K){m->?HU5Nhx|J;p^EWdfv(_6-F#tEE6xN zWL6Sea!QN1r8pOb7mqqKq@uqyU{Dp~nfJbi`|+Wl3^zJRIovHY{l{|;hRMmnM+!!f|u z`?ZIw<3=J7Al!3&R+pTMALvQiMhn=->WGk^zy3w;b^l7(&6=6K1P}uGAu)R7an**vtaGrh+qtb6;>dq1@+bBeR+qG#i+NEoG)Cw5R)kTLH&H5(EblOTA7XEoS>7t zlU;2YAXX#Lj8`in5JNg$$0+m*&i39lb)C&7)^^p%Fk^Sbn(3S<`R_%J6uU&mQp^8Y zCDtHtk+I+^Le`gJO+Gu7uYOeA|MuH&H2~nr(=U*^6pb+pKp8<=} z>(GhAM?t}Ad>(qu%Ez$97cnmVGNx?2h=n^YU{!7bGIR5xUAN~9w(LKH&AErz0o#O> zl(~o;7pAhFp^W?eeZAlG>h8Re10#P23ljq(P=}*a&hAyOSWplItQiqwNv9YUpVAuM zNpHB*@J&h?C5^LWd&icdmY$#_H|C6#<`d3nb!}1x4RdO&=s=%^#YosyhMa3}@bdc) zzjI#m;LESR!kM$@Fq=Ny(%KGn>o-EZy7kbms~Oz=r=eF2zcgSi`^c+#fQ>L7yAw9! z55hI!FuW)4!{Dhq5HfosVv;g3Fk5UmoaT0<@2Yz70dqR$joovi6 zy4YFm*`XcG~5AziW#oD&+c11|kwi}-U2 z1*sQRVat2$|FY91<5X6*+!0XF^jmt1g=0DP-(*<+;qM4Y=i=UjhuE-nC;AT?3j-5d z80Z_r!l@5jLs!5hZa)nCH=s?w6&zfyQt6p-&@Pyc*#hGMsW9t35zfA0=;apxZQuSw zF>v5O3?dC2(2w%&jXs|4uX}Rz?r3cmVsFvSha*!vBG6W3PXv_gb>s8j5fD$v3OVc` z5tvuoFnB!?c;3i<66b|!%nN7Ze@oqYze z8?Rv#BiNm%-{IR|e#O83`=b>|_u>@;mvp^T7H1$Zd?E&n41?FGDR7P10juad%6>hE z6HD2mU&7=hjU$?LwDVc~b94I%CCyF!3)`FbE3~xIx)eIv*c7_jS?I{#vXEnUlJ!n{ zJAZQAf#cGD3b#Tc`))6uH;B987Ba4@Nbr0NZ=;~v#B2}`VRJl4ID@hEo- zGjj)bdrJ#?R3ap1OgwKR^i1_?CRvqEAuKZiP z`SDl$^5MVnfl=Ts`Tgq0w=sD5{Cga|{TlNRRUu&IO*q6I;#_e9TCpeDtVa^3a-2)s zCw^codRE&YIGeSKJ-011LN<2p8W#r#jk}XgHQDm2lkVRotX5>I`TZ}db`yrUQ1Z%! z5e^4sBtoiZ9z`L~Rqaq|g-c6J@GDXZOwIv_T3X;HY62; zXXGMve<_aM`&Rk=SKs`A$1lIe<+3-UkbCVF=H*pjAk&3%}&gP^)JYTu09+w2Pim$UrJ>I_a4VJA|*g90QAN zn=zp2k7ehL{FzBtZafv4a+OZKJhx!IA_X;IS<9D zTu7*%QIH7_Twl*PSVKw=+2Jh=v>^ljq&&W^iuATF8E9Z0f%>MLUm1sTRyjk>D`Zk5 z2NnfXk9n2RgQOr>%U52gUnn0==jMi7{0g<3PcuK`v&cHZ;3>c7s`gM(iKlu{_hCwW< z!~98mi1s5A83;#xGcrM{XBMH9S|-I({Y&_e9=T+B=5g$i2?%NM%>}OnHNMm{<9Y+z*v-1j(0+j{+VxwmJhiw9dhNIM%p&Q(LW+rG z5w&Owk@c%*5ZH`JenPaB3)C|Xp#;*K9OoP)*XKzn(2AVm z@i4?WEPd|IG1_WZhHRc&z*d`Xtt^j*$3-Eo&Qxf1-f>>p_jfym-*P1b+v8%NQm`Gx@%98KBBCjasVVN?;2Q zSuaUd(sr759-a$sbBsiiD@h6_$5~fdDR45xZjh`P$V!@wpXH#kbkoo#j@mX31Ohyt z{tX^T9JLXtnV!MuI&}?3eM-}#_67->e@4_etThkn&V%-#b~x~$34Grp>1(v^vlMNa zL`fRa%sol%G_~Vnhs1n%FS^I-o)f(#tmsL)R+h9gSluz(x0}o{R?IONa&#e+;`R*4 zE%+G?XnOp7P($^lg;RkxZxx&2*}u z(5*(ezfNZb^^a*oZ616i4}P!a;37^TS$k;FOSfqxNOc{ynujl7ucSmbKUMvc>e(up zklu=P7J5lbjLidEHVDne6LB_)yNuc?8%A~%T^g4)=DcHWQvRvI*c+c31YIHO7kJ>) z)Zt8`@AY36QyTF=e?UB-#@I9z(*XYMc0*gLgU?cxYN&~{|7LD4WkR7%=hK4W*fe;T zLfeOE59F9zMxP_u?(*kQNCpFP9lG)!2f%mGgDnt2T}okF7Kj$HC)C_u)~C2$=Y&QM zQ)qeIwW4?>&J+D|D*1v>^~d%j6E4-LH`M?%z&{?|_um|zGuz&aRZS+lxkfaiu7O*q zlSJHOp4w*7A-+a2Fkrb%FdrdmYZ>C$uZ?Fve*&-LwmiZ}cCP!8xjr1-NT1I$t`<&ELXlMVeYAIBfgjf>)LIz5C@N*RZ2_l~%$k)^N{|oXT5C5rQ&_FVF zM?6MruGPs(tyD>pF&lB&NEi^bbc@AYT&2pG1ZTrDsSu-9m$2@~WUE%{owl z#N5YhzduCKy89Thip@!mjrf#!U z?r!YA4t?ic=J2orlX5E+H%pFJAv3=cTh3QtU48}T9?*?hrMWzC<$cv`6g^X%&Fz0f zbs(%I31#ctm?2E|c_pO~*TFA(%gv?|9`G#1bG+IxyczX%;`!fkq+9?^Srk;ljw}S3 z&;-@=N+uYbT*!8ljw@P=$6PwV324pbQt4I+SEDm;BYyh>Bp-N;Om?gG7FA*I)hB#h zg`|U3i0066^oBiJ{2n>GLuWhurs}bN?5W7u4jai9 zxp3#VWVo);FS``oxho~X&t}?X_R{Fxs%0ly*>Nakr*m$UU5v;spLCQN!Ezql@~@oD z-DIkzmmr_iR}UKB0jBuRxWW5Q{H|&2aox8NLrE$nI~G4GM%SMC;b*;)xfPtil3<)J z3NpDdVY%uu=>!HYyo_iz>SuG>v*1uU79OcU%Hb+Z-&cw8oO#PG#7Mfn5o1@~qh*R8 zlt{z|ID6e9K$&}3lSS1HoFqa#$rhqch$`&LQZ;>S1FH#-Sd+w&JrQ1mzp~h5YZt9} zLh?xQwI`1w__FnM{m&$?F(;39v#!CCnZ7yuF^Wg-?sZ^t)`qUVmFHaYIGNjS5vXSw zt30D@vbXh~k8UH^z-!hSj9hgWVVvm*Uvax+u3w?%y|Ud9!iiT<^p=O1xu*=X_HqSc z>q9OCl&HlJY53Z6x+#5L+4GRrsATQ3PTz&iLdg&%!)@)g;AbXt*BGOi#0LFMjKbr` zMBtxH1X?q!MeyYhnlZ_jElfL(1)XMdq`=m)1!XDSSV>A-d8evvUYT1;sb0@4`p3o& zQyy`j;ci`%h_a?mQ(qefZ2BOB758bU(P!=j3|@K-ff;wW%kn^}Y3QahL{8XVrmS`D zL4v?(OW>OOYV_M(E0a9w=ohIUNZ3x7{x+w21l)q1c~eep#T&>^LR!$K>QkPS5)arJ&2e<**3Z0oTbV;gfm;gXuy?WIjaX z82Z!jOIzA3aY$qI6JLJuoa1=DAXCPqDAG~hDrjn4ZsuTLHY2FC(be zT#jrQ%3aur7jorVk6R6~EOx6VNpIzcFj9ebll=sl&XYPbp0#jK7QoBMfY>SJ8dhVc z>07tA)BWT?rMBXUj6%gq{rRGe+&6#IlKmUApl$G-TY!j7C0uMcgD!rlDi>wUa21(qp~q>brF|4kE3&ME$Xp8XwHUG zbDmo&T1xLKKRS%>?Mz~`CYZHMaBE$;5ad7!hl{rG2qmP4RItZSKc#0f z;8_CMFx$kI!dXX0zvA#K98y|nHn z)e{#sD>O@%ZS0S#mRO^PR zuY43+K_OBM2b0?AIw&FXiRvG}f+|B@`6yo_)~h1lFuwOdwR}a!LL+M){6AmG&nbRs z0-3NEaOD&=I?L|PAODe8jnvS@T%XvF;y$>NXML-9Zbr*~ID2iBrSL7!dA@&=xrZxoFpLB?amTvanhzcev!9p8J79=t1^je$E`YG$KzVZM2IDPPE zoqB)ro2Hh`_C9&9exj)P$asQTKm`tQ(PYeC(w4c)a7v^5WO z*N#B4hX1tHSI#=*4WCqB8}VA8`}6PD_k7-w_vOmZRaaKS_-{U!&rw&tQC;~0b>$0m z*HEqQ4Vp&PH)>a3Kf!PE0hEF6%6Di!N#+eLuLZpJKyoeJcNf%>mvrPw`5&*}YveQK JgLw?#e*xlB)}sIb delta 36819 zcmc$_1yoc|{5L$iG)SYAGzy~9NVALdk5oVqq@*RKk+@4qNQz3ABB?Zz(h|}lAsr$D zQqr~ito}Ow&-|HJbS zo)sW%02tx=-9Ia^xqu76x!B(wvVuIUAO9!6JHYZ60J!+F)a@C5xeG}w2@}>YF#YKa zYxtvJ1O8qp;$uiS2%4Ij01AbQYi5e4zQ70(0@UyFA2f^*+vA@lER0SJ1pr~#k4j4y zhNV9WVOUr^9W|kVfVV(EfPiblAGnvRfDj!WEj6_(bx?q~P?*IBN$ z_r0O8us>}=U0t!AqNb+zzAxnUCr%g|ATA(^brC>Iosi)9hdyDbXgr;l7gm4`FZ5gY zf5Z-Rjra8YfqMo~C;S!1BB9t$g@%S=d-OvSVDGP=h46>ImshCgZ~Py`6N`Fg!Vo6{~Z?)Vjxcl^RND3 zaRSjW4CMh zjtUUCFF^Y*oDe2PP3`%+{$Jvw0s?{p{=_Q!+uw?c>#!;Vb+zXG7>s8P;a zqQ3|D!zMrg3*k^F{sH`KXahnzI_z&xK>JSvLTVINgOHl??*;%C`V$a${l|!T{i+ur z;2fWYa~6kC0QHj+Q2*f1!GE&n;4uE59KjDE8-)3-pjj}OO#}vm2L3YOC&fDZ4|?(= z238mSgZ@R1X~N#g7;M2(oZl#R+<)>vDGEEi{osG6SUoHc{b_*p_(P7t{7)41n;iAi z57yJqIDer8zuKdIr{ur!|DfPE{s)DyD(K&UlRqfSPs4-X_)VH$4K`(drL+FO(mC|6 zbOG~g!2aJT1{3oI5@a~l7)o%e+ zEq$P&Z2)fS8UkH?BXH}s3D7e%1-Fgv0z+eSaL3dVnB27iCKh(U*wO(QS~vrJa~E*) zt~*dQ^@f0w$pavN#~UDTdjKh2Hz0b`4G3$x0Dg5Ba8=a>@ciNmF8$&LcvL+AkA@Gp ztObF~Hv_;Gogi@aRtVs`9SZmjBY>cB3=lSb41~>|0O7mOfRK3t5HwE&f)>d@$TAfO zTBQRa>r5bQlLdrrvw_IH9B|DZ$_HYOg+TKDYk+Vo0Z8{UAnREHke+V<(yJOEylR28 zcRi5uZUB-Gnt-HdGm!Ra0SMm~AnVr(u0w6u+79GUoj^YDJx~nl0ZJjgKsjs>{1Pz) zR38lkwMU~s{m~fE2p$7keq-RK_ZZOj{RDKNai9l06qwy`6?Hf|7GyMSFxGq8`U0d|infn9hRunQ{zcA>Aqy^um+9rOyA`saf?J~`mF zcQ(-Vcn)s5Wr3S6nc(LAba2Bt8E85s0Bxry;FePywnl?nj*;M&LpXr+>_dRQT@Wy| z4*V0d&Ke43mAlQZ*ResLLmU0nz3o8Q6C?mjp;JOYPD$Kd$*7?AuQ7U&;( z%=C2UIsbwE!Cq#iXJ9=42m7PJc!7hB3CYh-&+rrGP8lpS|j5Z{;Cf>&YWnMGtg60kQSp6lT*_%HnX(1x3|1&tSKd{rf+Vk-8|9t z@~;*-y{`j|bX4V}#AqZH)Nh+w+B-Np*jt+FNXw|+GPCsT?D>0#xKdM6LJ-pY0)jM> ziW&x3eMe`_651;MuUF z5Ehz7`^N>?*f`mQM8|M(u(AE2^q0o7%;W@f3w`BlGLVX#L{ zr~F0n_h$EKm$#*vo~nd|oPvUinx>wOv$M0BzJ*soS9k93N`KPS`1v=6mZo~DzVBMH zvof-Cg8Xfq)l{(qT>H8IZ~lL~|8lwq{mm?mwMRaF{E(fVnVy;TqSr%O1v|oS)32WW z>G+RUK~IOhx&GIgvC+ZY+??!}**SxsDwNcXE#13%vi{KevyqjYkXDks`FU=-@JA^q z==%8alWzzL@+-{y`*{6nLqgK^edBY^`pgvn@#E0Y(1#BR+3TDCj|RQ-=lehYS_+t_cEKi2n}# zh#!K+oI2Y(qcNCoe;57_9HRcP-rU}PAA_#>A2j|BODm`wnA|mY_*UojcLA3Buj`K! zlu^;RZD?d@p#9)q2LAz2Qe2Z!R@c07LqoOgKg9opQYff|g{7`5Y1aAu()(ZW|6x!} zNhOR#@QR2@$f~Ko`-kv9Sb8d9iMpy{nrMWpsltEA{{~^>M^n*=qH0?Qi~D6=?G&5- zCjJkmn1<#WGN6rQn&gYDy}e5Lf2jNo;-wLmL^l6~WDQ+a{QoBWkKeykSXeyxw_b#( zIjD#H-QZu`Wnqaw`cR>0XDItGjlTg+!dDvq1Z1Hb_VOct^8e8q`P)rjsc5fK^&eXQ zBcyQq=Kt;{`uF%ZsF?m6{2$$81t`OS|DE{XGBvF~vHzn`HJX1K{J(DfmKb4vq*TAA zp}x!j0sTAA{5|jdznq8uEe*wn#TIND`bXn;;BWN*W*&-l{2yuPukrs+^U&7+4|ymy zez=x~5-BkQcB>MQswm6f#3rLZwnnfS>5mP>J1%)v0N4azGSI$HYLr*{Dg z4xJK*B|Iz`H#ieY(8Yo3W(kaYAzh^3mg%Eb{?OoiY8#y#_DW!E5`s4~G}6r8VF2b`v3VD~#@nVBaXvEQ%E&dPm*@>Iwm`q7&Wlk#2k3HhEff^PRrW`h;ENWEF znMgR5IiU)matcdNPnY1Z`|424H#J!2eIfN*^!-xGSFZwx)~bvX{mKll)% zvnyBB$fXt47p?K(g!41!w_SVT(!n15x2Q0ba=;|4jOz2LXnQR7Qcj=0e*Id+&Z6=u zIfhL6oj7b@6Yu&aKD;ygX4r+HI|r`Bl*kKv>r<*15kwG^+8j$i)Gn5Yt3@(&mi2PL zB(Q}=3UI=dBO|7#rwi01)>c2&%3_9wMyUhg}zk5o7-tlo+=L3~g<5VHTu%fbP} zGxDibK2RA@nN`^g*~>LQ%k2S^zlFRT$x4L0t8<2wRHM)0W}%+U!DZfq>&HHRFdZGe zpf5lk|EPMCQT!Jebc?;i!{gi7vNfL*D*sevvx}5K(aG0G$R-S#_yZ1!zCmoJ3F|Vxu{r0QGuw> z=VHHb&C$|>{L^lLeKaDFc!(`8sYH$TgxAoDBkxJ=T{5Vug9OTh7Zk8d@uMtw%&ou} zp@`c2xu$e!AB9a#8$Y%K3E}{Rk8Erk-E}IIJZ0_vdRkhqRf2=@ch=aj#mdGt+ln4^FSW%F*lPj zpejgb{=-pF1!8Dj^EKoF6V6$z*(_fmyO_h9kztErbw8C2w#8WRH1|S6czOKrJRFV~ zR>qc@nT*Zu8eoa50-PxGWZU&kTIWnPAw4~kp>IXbo{W2rcixA{6rUQAdDZ(@OFKHE zJ3={>EzSr58%vOxr~L9J&0_ABVhi65#aLYDMAmZe#rJ1voj#Qv2A;kA%%t97V#K`t zD47gzYHCU-(V5Q}^D(2>CT#%y8RJvGiF-2O#*}YC+~t*O2i<^wD|VbmV>&naA%z2# zgXNbu$7b*bI*#DeYhw+56XI&l>oKGrt*t$?*c}E8Saxk zbNMgpQ>FN=MuvxKh^*5oGE&E4a^uE~3`QnqMG4BKWP~*y@DsT@DM)vofj#6pC#$ya z29+{g>`ZX0T*L0_=xS;6Tm6F+$VqNUC)IiGDM|8DYIspm-(?eTOWoDB@c8uNq9Wea zbGOwF43hw&;_$FB@e)Gyc=g$yrvThp?0lzHxpLccDMIDs3^;1o&x2Z{?9+I;sdwWUl*!!-0i#PxH5mCT(KJKo{8w?Bn5{ENOPq%N(~ZWK zNx}y8{rD;iem3e~Cj+6NaS1PGa~la%$!nYoyt@K$5^% zT5;3r$2hAhPoDVJXJ`A(me(*Lo9RrRT-061qeZuUy4pz@HIPtJcC&}T3?ja(`gr0R z>&R$&%n3E+K!phx9%d{v95Hzk(-EiflI|0B3cC4iNB6pGbslAyz!+3S0^d35hSu}9CGSAjN zIOR5cOaF{?8WY{hnk=USYkQk$pQ7mp0kM_S(OEl_~0Tpk8Y!rrD`&}YhyD|^Gf*6yJfesvSOSr>A8-dXz+M5nzDI)%Heh0ghvL=r@DppQOqI9`f>d1(1;SQ z){Ss2^{WMTcCzRCv@ig_wvJzzKaBF?fq=)m`xk2$G#cm@Vx(#HOiuGH4XYg0pZK03 z5+(9xVPxWlC_o%6?)sU>pq)k#-#IZaFE5hU=;-F>>TN^>R9}k=OX%x0Z)^>Sb7P>t zKoBx$FRa1a!apK?;3~}IDU%%IH?turG2VFet-N1NeDzg1OOP!U^)w~b*Kc1_?daO4 z915BHl}?yOvRM*_h`5H1K5lAP_Fyd7`>etDBZvmF_d#%!r#RNyE?~bI+XP_)#FlAa+cYCCA)a1r}WmRVkYOyJ=P<$ukR_Y z9v8`SKC7Kx*pkNynANsU_x{3Lk0U=YJuMTyLVNer2=Y2*K?qFv-X5P(U2Bk&#Vx$2 zWn=>N4?z~_efJH8;3UkPJn?kwu)IWpWK~ot?ZwU4ZmFZykCBL-c1qC z5q|zet$pE?Nq@hIe86Qz$$vdx;+&t~TN4QSl9W4|;kPHQIqz^Wpsz2wrsmE%`C2jW z7ZsnWYm1}HACva>`5R|&j7Giv5%ij@DQbeMtnt`sfVYVm;g&#~WbXkbPcolsW|_jm zuAs0>A_MFMZ|t}Gl;nYr4~yYuP;qAS(rkyztsKb?w173r5Y8ZklL%`vhgTGTg&0m2 zqTAbsWFj`5cP5OBs}RhZQf`Nf3GpMo-QlKQUiv0AF7K=b^V>FV%^W*ak116cu$OYZFMX)0N>ap*&P6r<;k z6Li*rZ_@WDJ>qgv zCQoYBs~`=r^S12eGWFJs{reEL=2i=fAjXLI+N87h!wl0L#8b4Dpn{sbBdV%^ z$aC_3#|Uw(kQ)wIZI3wB^jJ-la4(&hlhNaNkqFp+|GcF4`p(u`Ja6rH0>gAK z)Zqx8_oA+=IG*A!a*AEwy^vDx2$2G__XQdF&*a@B3raCTX1j7+O!J0zF*gs_EECX% zy=V1&chHY`k0|g4m7Tw;lizl3naettTur^|u+Y+PxT}wcB)fP*rU=(Tt8Sx()V}6# zh909IE|)QmcxJs0r37_~miy~dU5{fZTlff(Z9rZi_6nSbTA6nCYWw30e8%+547K}w zqQ)`!8ADXQc1={w(xgysIR*KqfL_zf%W8>ZL~5I76fCKpo1NtAu?jn$J6xM7%zO3V zsD8We#UbvCXM>JYwU&-{s};IV9)6lKr3Z*4{+SA^=Bn8q%UMgFrq=bq*p6m33$IKA(2OqLzT&CD}M z(VjCP3FE-O0CT%z1>S=XaIZ&$lanW2PMZDudLp{U;g7q@2 zX}XD$ru>3hpIGGPL=FnhvTo?R@ZA;aM@|hc`BwRCFpn<8Aa40J4KY|6!RoSH=m{#Asx4EyaB?u{+M(AZ;tM#+R=KM#klq`=}1ad18UyE}J~2IGVP(d=J7LbP#Ci zn+hQ|8lIQASYtE3)#TAz8C8vTjP&#)NqeJ1D&=tTnUqI&U{lz|rNKr_4@9-DCea#_ z(TPlqcus(-a%4v^lZBGEVffTxzx0}1jOA^bKp`-P{c6#7Fsp9jnB&0=zel3OtY!ic zcLL6*rbA~k_%aO@uFE8}EWl)pta$_CZEZ+7^6BEw@A+nu#rL7F9N|B7+D<(#6a-z`Sp$wC5VV`_i(g_#?;T~ zYQZW4Wgg*u64s|`>{4QF>KLyp5eJ?8?2*~rq;!_hT`6>=CjY+0MfB=X@zt3UGr9WD zFXV~%U*dO3m-NHFR;9% z@ig4h+*2q)6ep^RpkAnNhS_VjG3nYV+63}HnaOh&fArC)kB8!ek!{XyFOl4H8I*F< z#=wo+HwYkI9H@M*+0l)B7iq@HkM7ZYVdvEEpf-?kG*8=jAk~91SlJylLEJmub0{7- zUadvHKHOfKIZv!B|IT{-Q+clKyNJcK!E~dqUhA6PBq+u0;BXt8d-D#BT@ossRCEwg zDCMIPf%DDES00+NgKK3C_tfe(3lENGFr}x_k{kAXhwI0eVdr4T8}KWaVckHG@L&&B zx2-!oO#Y^-YV_^?!l>`^%VWpTczEERJyJvVn#$P#@pPE!IYbP>fVp~a%UROaWl~ms zBXY=+R7#qy!qZWyLv`P5(pJwe`YlxDzg9WAce+>AIMp*P_{L`N`5P5#F0}qo1>=YO z9rA>RiYK^RwDZp&cV%BM+~>YG*Uvi-YS(AW(ck&cT=t3UuH&mON_YT9s=im4LJ*X{ z%*Q%ORfpk&qsl0i>1DAmW0vYW(kBCQnDk#RK*ya9ji`2C+p)mF92z?3T1aq`m^+F< zD>Q2bd4XqzE3>R2yareI>vZK=$v5@*4lP@GX@1Nem6cQX7otSb1;xcNYO8Ss>y4Pg zNYId`(T?5SaC()OH|D-4zBH*Zy1i0Zoc`gB-6%=^oc|a2WQ#~+KSO+OFVfvFjUHIQ zSz;6g&R?s9p4^7DZgD;=hjQ?=pmE(z(TaHj#K9bz2PhEnC!N%p)&h%5u?ondfGaRw zYGsnyHJq4W4EoK)`eEl{LjO^db@A~BKLncPAg#}rVnD6%2CtUoIaKp&@a}#0jax|b zj)z^uVLPphTU!jL%iDdZ4wkluqsH=L`k_QuU1i))cSk!MtLN|`Dwn53kmy^_j`oBB zDZgpa5k5~vyms5~Lc#@pNrG=!0#ZfE4~@9f-3iYD_vI`rB2JQehaB-my1 zdn8bdBG3_zdf6%Jrznx;D zSx{V9*XTLQV1N7cj7Gy(gjYmNtU8zXF)v3-b95-wwu;H82)h#S;!8b2a|E$Jb1}_% zdRYtZ$b(Ia=RH((zgT)x@Gs`KXKyzID>3`Ibuf8Omij!|fTRqlDTqPDMb;ag7g;TF zu*o@JwTyMEH|7*Ny}}VdeT&a`wjgd@2L0r%NRf7b%bKtltU4T5cw1Ah2sxl$ggjf& zp{~%{mQN>o%3YMECxa%pUz-g7QeM>De$_C;Sv<`_CPUNK#^zw(!i^&4WUf(Qp<3wv z&N9n8WCy+*v@soaJJnH(1> z!mr6vF?Gz)!2*kkNrlY~sB6E{8gx!_m1p!|jQFQuE+iKCnb@tL*)@VH_}J$3{f>-= zRgb#H+F5H1Nx}+uHr`byv03$PomrbL)GtP|q-)ef9U~I5I?b?U-=cYMolSUjerzUeiRJLyFLKHg;YMbg*+^@;= z$PaEz^t?h{5*iS6B{QioKTg*5S`KeybNjCAtSihaF%aOc%A74iGEiqtOI3P3qc8a( zk=W^X#sl;^7lbD*(t?AsfSrft!w(t23IyY)x<-V$g36lXrbQ=~!>=y+Q))_|x=n0A z&_v&jhRa0Ph{RrkANy-va8|vn35oPzPE=XIwGmopPP5jBq|2`TlEr-I9vyM@CknWB ztlDjBA0M2D$<3AHC|rx~C((M1WXn4*YPYvGG*xdG(^x?4n87kNA)1+MPJMC}>S$Re zYFXI5J5?6anf-`s`P~c33TDr1G>T+{eWY4+FtJz0DD{PoEixoZMNx-Pz7Slv%Mtdn zyq+9Y>@LHRbkRV~BCqWEb$U_9)WSDKeK#nHZNCYL>^%sIQ+iAq0gEk(FP19;Noco7 zUS)h(Hz9UWWzG6wjmCd}3f+N#{IN;#*PdS0b4C@`)?DPLOZK+S- z^^R8Z=;(;!(YdSR*cFV*#3QQNv=JFi?d#7#!dXsOy(`7)mzqz6C+j1IjceP7MW?Ik zqU;H}W}jWWRhw3YwdT6-V;Y5-k?IPJaT*6{_pU4PF`^vPi_#-r;3 z#!y$+eK`Z#!?B6rZ&csaU+#8}LKsM~&fcPQ6L?)D8K=fY(N8x9F}h|UQakP3A25-w z2q9yPMpkv-aRSRHjrF(FY;K+E;@2nYQ=@{oF7-ZopRG-3Ekeg-)Y_kmhuuV5!`yDT zzo2+yTvb+f5C?UFVH$ZuP)2~f{j)ce6r7Udn9~giqZ2dX9;MyYun{M@VR1cwYq=#S z%0BbLlLZl&2IRMM1iqiy#baSn)376WJB1`#$oZfrIY8mjIVYo|@7;bARZh7lGDKoY zN6+E0gh(Cm_>k{1=*I4HOnZk_u!c+qRZY5dbG_i;fUM~Un_bT#4m1@3F|B-{VSm<3 z_=|R&&WahK=iBcjYDx^dW4+UabsX1MlZ`gduI~>O;z+zakK;^WH@m0TL|qVATz0OZ zfFXPSMnz-8nL1C0cglkA!cFhUU0q33KwfH&<8~#z7ZYN>a&kgzP~)*-F%jC9qA}uX4zoXLo-Y|F)=}fza zDYL4cqRVazvCfgSnCOOT4dLRhc5Iy<<(E^Mwhcg|4fNt3>(0XM;j9T^Y!VyYT7?D& zwEC6zhMB+YlV8-%*O7`-K0Nj3pdjSLZm)OYv8tka{Hc5gt5~g%(KipDz&^8>*|Wj} zpPbz+zp)Ep_Pa3=3NMtRzBx!9e#%W(l0evUhZ^wl%VfJ`OgEpbZz|(!h_qHp+xm|m z(NRLNvnd89S3evTJl79E3Vqk3!O1+r33(<_eBGhjO(!ZN0_lLGc;vIS^4y2gDhF}Z zPb0s%Hj~`!HU7#s^6h=}+Uu%@GW$=0#7Cbpx~qTR^D?xdW{dJiYFcSi}E{CgNHOA$pE6%fHTxm3~3zr5~1b%I^^sEIF7wE z{vS@*V&1EUyybnJxvMf^SD~4mxix3e!NefKG8_>qw{(b+XAhi8(Yw1l?^F7HqsnYm zHHIxseS1{GZTs}dRsfZ6okX3KsN(V=oa{Rpe!p zTAVQLiQ334`Y7KuhnR=2R*Tc3tYZl>~wG(<$*v!kFqFdae0x^F(a;sUYX zKfrF_zUk~w+dr%~xi68%Qh)jkBgdW+q-2)U@Ys?U6_A6^$<^wee9zb=z>mEH0w2s9U6dC{^%$logBDtkYEE@u`C(b~BKk z_<#~dID{}IWy5}mQl0zpIfl+>6Y@f}&P8gYPs>OBa7+%5NC}Tp!?InZj%1uhaK-58 zwHkpVO#g;I+sSoPch%K82ZL!dTc`AMI#nYYW#jNP)okCLpS8u{KrWifT& z^^if(n+>)Th{`R&VZfZ}yYXe!PQ))srhPus+e$gQEYD9HC-*M9k+sd;fL!yo`Lk5X z3*z0wgzbxuYol&!A zU~yOOke!9fzv#7y&^tY7-~WqYam$}i`QjHf9 z$$BG>3a`yoC2benqxI09J>)?q-@cRcwcf5Iepd=l441kv#V%J!DMud4dU??EP^ zeFROe{@JnVv-(BEcd#Fsv=nU|9Hur8`R@314QCvEq-~F3!H8*ASyI*KWb{CxMV~7l z7&{LKe&XXf{cd;zW^f$`O~jSWTkP_AaN*{w%!Q}W)jaTEDc z;lWF2VJcMI)XH#fO~^vTXqysdL46~Af7F5cK`_7Fy=LNp@9vnKSYp{l1|!{9^nsj{ z$s&1<$jfI|#d9Y@bK?1wRxix7eI)lIjp8zjoUNu;*ihM6>QVG&EqVUD<%Y}J_3E{> zfHgVncwoP_EfVmaPcC?=(xfBOaTVN{FXYB!=Rb9MbcW^~&lYs`96B(ZFW9)3VCR?6 z?$wUZF((vJ)_0=b({JDK+YwK6UKdF`T{fBf8iTqdeDzmAt&m)eBZ)WTQ8ox-{GaV1?tCzfrN>s#|0_gCYT!`CRfQem*1e$ zrAd`z>@*HUy%?aJs0XrHDjoBAF{gyJLk^F%9t0Z#nT)EBa8|-KlUhNo<&~z#xb1Y0 z!F!roInBqYWev^2JO0BTnuPuKtGgQm_R;-vVrxe}_g6?U$RQ%yFI-17lXxPUxQ7y8 zeZj6GLfK#JWSH>nQj2K)MUz&ViqtKE_^`*68o;p%yT`QlREwZ=Qka3i zvNg*rHv>A!TF$+CW~Y`x^MvBKhdA#OE)551%!G6@o))ps9VD?oy(|?nsbyn-f9ndW zV5t|Pg1+5XN{bwl*~R(FyOCGS=y{}@C;7#f_iKT{c{&}N-5UmUPbTrA9&#W~hWf-Z zS3e{w+>|`N;(s+-jYcDPsE^^rFnkQp)A~M3`sP%h zy%4TWvRTqS(RT^pLqvzM5)E0iAR1R2TCNrvD7sJEq& zHa=D}<0L_xL{BI=VNWiNk9+LXJuDSY)AlAu92HxgxP8<}Kg}t=uqJ~JG6~J~C|kV7 z{cO|D`!edpKZKkqean?>W&A{aD6{T#bMcwHx0GJwLUq(N_6#D!!>|eMmYph1;>XXBN!O{6^sNiK zd)p#7Q#m1PM7LOWd~lcQS(1x)+;a>ycu`+o&pHA#XJMjrOL3F)U98xUU`wQ5V+kZ%Xxl!(&(6z$`Y&7ycQq&MZ-`nLa|jay^JVsTzbH)CLdjWZ;48F_&18B8H;JYiEToM{VueqK(DQ$D6yruZ48z-m!>FdtyI-<4 zt9<-8g0CSp7krW5uk(ZY~E|qIp1}KBd~#4 z{%D_Ff2yRvrdi7-!<=oRbc!jBF0z^u=PK`G({(QO}Lg-v`Muy+f}lAP82+~aB3n#667r$>}eLp1Z+5c*(Q*h zPQfzeV5kU5?|$C3JKiI{yH!6QZKtxWM98I5V5_!K|Lq0DDmW9eFX78D9y1)2TFIuVjglldedqU~C zT!|abd+gzt_jEFi8COuR#Y4$?ohTel@E%BdL_XlX4S^V5U--;P#>VU;6SU^Z!kp3; zngr3Lj!`d64+^!l)69f7L@?;Yq(pp4aux7i_Yqi)RCVsb(_0uLks*~HL-qBM1-F_B zX&vAzb3TrYh3DBgDr|o{%(Igw8?x%le9j7Kn=e$G@^c#mlE61J$Iixb<0#W+M&7t_ zgYtA5@@(vu=MIkblp^nOuX0*w$uBr|@yvS;&p1A*ROs+1G70H4KT+GJ zy@fwTs{`bhkvzoTy`*Tuvc)mJr^qAUBYXBR=W2@BY$63RC&Jxy)_eCp?Jh>n>ax_i z9633iGM%NOfQ^k3R`8KOlRhy~nRjL-%ACxCv>2J5+HS<&?(Qes@m#yUR^8=v^dZ_| zl_H9Z|FnX6h+`E!+SI^KZAWGkf{#~%EKG9@W|iX7>L3>jv{1@S9xLW#PuPW7M(l~ zHNdi)%Rjvm7yR-pTHtkWl?R-4Z2zp?z0%gX+16#Z?^$D4h>4|`MUHJ=d9R7g*yg4m zF)M-!d9h)^M=x7C-B{t7j?FFbSWf;QE2b}|45P1Cc&-n-*L!3LdtXbrUJda{zHz$7 z%KRv+syHFd{AiQ&4lD$_PJJX|pod`` z)pvLg>Sb_)*mQJtU)0v(i-@@Ay?!lcWW+R4Y}qlkRlwt+fwDu#&6%Om^sA?N_-1R# zB459LZF==0dj6K|S)bnZsk*dC){`yy=RO&*u=jLt-@esV zTV3I;Vw_$f+SG{-lKj}DoQW^q8wF|PxKE6G2*}#W`5Zf9&#RRQwCzna<3^J}k+*S) zF1`wv542r7PrKLNZdIX?5@0)IefPuXd>iJOz}h4HU>=@1a$MVU?5UA-=QU_2YCoB? z_ZUiHV|17XHzlAb>6Y3Hy_0w2EsT`Y=}lOBA7QMA&h0s=Z^i|T{9c!*o}!^ zPq?jj#Aj_Cg#L|Y5$U8g_@3)w!}G+a65^})rOdH!xK!Dns+pc1?fOE;du#ef^CTyg zWQxSS3+;2}dPeUEU#54^F?&M?W^NuH?GM@GMjabZ_pCqJuGv?V4t6Q>F@9!_6)|<9 z<=rB~E}G~UuxE;j9()^A+Hg#}MrxfZ{$Qvt0PXK4po$6}T5lxzTHAU@vT11n7de7! z>m-OFeKC+8gD&O?sgYnWQYt=c>9a#`W@YB)>A7@_ce33KnT{o2Q(JQEr$>4+aJs+F?*Ym;7GcQs zwl&fq2J%;*WXC<1qSJaBS>|G9@=%(U=ZJM*JqqL?^|hML2sUaX z|D|+x9pPFSguJDI{jLU)?WBUcHJ0AkGsrjhchkP$!eN( z_wf5-hFOm9a9cR_c8lhCwZkZ{{lpuGo{)?Zv(wt=9Z%R;A7M9ZowI1&@#W#U0+-v@ zJiJ%#6=>Sq*kpcrs5_FG$vRBbiJGNDV*5Kktar;u-Tg$!s;`s9u+rrM+GWO1e|vmI zpuP-#&FP9TC7T_D3X33Y+90PPjuy1iD$6RRyh?qM|FQEC!ej9%%>e6M@tZeK*h&(J zRJ(VW05%rt#GGd*gQ|JCsk%`U+uJ}-+RNS#zcJ_ z>dxt{A5(IJRxZ3AZ>S?3vhFz_Z^yaTXqHBg<1EHRh#T0`;c323#5GX+P+=+g6M?HN zm4r3+OH+k$7PQ>W=M-}3>)l;bNuo~ESxK-Ae?s4RVr^BPlI)|kZcMW~V8O(z{07ck zaP&xiZ>IKmt!+i`R+8l8{{DCNOroBS;@5?j6ETW!pw6?b!ot_I_+u|#sp*&6Rx^kT z?t$)c+;Ui>_8EwjT_&!_!OrVe`gI}W6 zl|bY<;v}@iG>f#)wZ>aAby~PEdZMsM;Kx!1zgV`BBYFNPl78q?lPs+1mqc8ooE0AS zmivUVgdVChil!<3;xwPFlJliMIq>7aKxas()dVRy`SvHTU>(8mzUXM*lFc>bjrI>*?G?kwB|zOYvq=L2S1K=k_6Eu#Wls3#D9q~K^7s><|KSlLJxn0 z=zH%GBH_0OrAo|M&n%_pq3`**=PWshU%s=#M=7Ij20O}>4+MSfBt-j;8oAv&N)Vk= zqYhT?y!5t|HfNKXNQ;B=#znQEu$N~yuOXpYY+v@K);i)#hDTEh!O)J;oaRv8>q0zT z{10cOk{b~gXV@H)=DQObBZ=aqC8`?rf~Kt5izH9sc*i8M=?Lr)ZGrZYHs13StX|Oc z99S(AopB-Qy>M~vVq?ZDlw;z#CSE9U1W4!TguV?)Y%|2Qg*_pvt(7qJKfs_fG~f!9 z*u#L^YN)3gFZ>D$GoT}SU!o0W)lF`u#9j;ThbW?+>tZ_1(=5MSC0-F1t90j)Qp+Tr zNDY2oRTXSf|4HDnvLm-;)pRTHqQ3S)nn%B_p4C@Z2j*q3!?|M_8E zWWHTVaUsR#p@8d`SE5FeO^%eYo04t>5FfGW2Ppz|U3m(*R~M9vP^>T>(j1ncd+@f1 z>r_tI1NKjdo)6kE<=Y6x6G5Mgx9`-(_2%Lz>>C$Ji$sY|d94lW(a;kMOLsAUM$&eUjthc%VY=v@c z^2!RF41urp3wyH`UW?kJP@c=G8s`^bBJ`yaL_?L-_Z=o`pEmYSOZzC=^OY2HUr|QB z;xIMQ*Xg75B4GsW=^Ej-Tl#d61m4uP*+@{umVFQKW_0EV8@YU#~vhJFyE6 zF?GNAz99M8u#U)!)d#-}?dEkaGni$I&AZgK*dtclB$N_Ko_usy`Zza0{Y?Tpc8Fz< zI>l&-qpt*ZcB>D_)<+R8Y(%q6ZJV1VeJ5@v67e1{ZBsPrY`dZ8nrjZ@Zp|$nEXNlQ zH}s6%&vF5Sq|i5ewv`IFS|3j0_wpB~AN3<*g!&{>NS2!k-?+QYaJ)!WdfABm51AJT z#QQ_x&;TpqhLe+_u~I+AW16S=E_mXLvxR=D<)j|`fy(}iwX0U;Gxt|z8@DL2|1c67 z@Q#EQJ&JuD%5+vhPGLl4m$fPGvCT@n+}b00_O_YyJR$ZlDIb(Xf-d>m=(M}FglifH zvTP{HT|=E{`3!K4ZV0#^xlKs2B$_sU5-8OyjTj#vKTR#)*nhs=F?>+E61_U-!R>7O zrFUuYQ-fTHMu>bt(CJcOfe<-z*sNrO!d--QUL+{l&Ho|x0c&S(6W$QBDCxkT*&yxU ze=N*RUAD41Q#}_v2$>N{Vvm%wGe6jD-oPGVK{ReFw%j?2Ec)DZ#jNC*iD4qQgD2|F zvvDT_iNU7DQGdqd)~KvaijCENB2yX?B%y!)z~k=C$@2cY<2$y8<^()rFOQ$I<=LoO zd0xU^e@6ljBuSx`CUJHZjh4%P;OPSAhj8M7)VI=j=}fYA9f7aTV%tNZtq+)tUDKWv zUz%+!eEng-Un)U;;i+!%CTp`Ndf%s)l$6wn!0o;gKen&%&L@rQh(1RkOcFEqk{yf2 z<(HYPoSbAm&IbB|fM%Rf%#5FL# z4hF~7K|0FZf`n163~*r1Yec}eYR6NW;mx8ZBwr3G*7i!x_JCH|CQQd~ne$Px_j)<4 zdAl@|lBn1qEl)=kkB7$eXfKZpCI?ls3_@%e&-{b*1zp5M?{!cu{VI@dm*k?D?4nCx z&{FYPMCHP)IG`--RTFk3ttWdeY&mP|buZX$4dTu3@?3I2JLSox^EJbX?;|yH;<`T< zXNH5Gf~IofWO(jRRj@X@$nqd!`%1!KF|VzH+@t0$i{KGD_o?f1bUJ}p?Cf1d%C5^8 zq2$Zp>c_v?kTIT4h6ZWsHzJGM;BBE>{?T{Z6m~sc2xG+#-}KKC&zVmpJ_oE4xUjf9 zf~ey{H->auTxjR*CS{c4Pum3FrxAPI+E7TCyWP8@$5r-i!bY6SdwsZ$Ss=O^kvu~uci_UUBKJ53% z++3YJkzJqI;;Pq}F(E>9E4b;gF4U1x0k>FG1$>5R=R=Lnx%fD5SE zSER~NCP6vzUG%r2!|(~3)1P^M6&bH72~mV%o|Zmg%PBz3ND&B}&T0v{pB^9sDO9v8 zj1C0}Ua4QWltkf|8--1(Q4TR?;hgi%PGK+Ayk>lY>r3)6dt<)M`bFlZhjJRqNJ+j- zhi0mX9I|{tAA6;*OiJn@F}HuwgP}9%Pk@-M?T$>X$)fFNdsBa9UjN$(3LHC6e#`dN zWN?~BTSXU@y7^fR$hO&%b>K%=5bbpJeHAK_sd)3 z*mpg0vubaO=zC(;iEqJ4tpqR6i4Pvh=o>yGy+2Dl8f+%PJQqvxWdj!uAd);dIvS?b z&lTrMtT6rp5@ z9{%OTU(*E>DX+gxeM6pXKP7b!dZb;zk0BkmvQMO)y1+{yI?5NNCV0i;#COT4O|$B% zx*sKcXa0)LkML3Y+!-TC{SdeCxX##~r&B zZ_Um>9lqCYeXu{ujqNBeK+tzQ*;+6s_^TLI?u5^O4MMNm7rdob72R$!KUb%|yC!J3 zAAI}w*7nQD64)vL9qAP20>~X@WQy3-nshcBieSbK?>|#Tg)%(>`kx7o0pAAq=8+kb$dBEvM z(vcnC?!zk*Kc%Wk<<5;Kn{K0QeLoztu8^box7{Wtrzr8^BQA6lRVRnO6MeC6{Pdu1 zs>+o@AUB03LAWEJCy_x}XUTCcghs}fj5s>*^mdUYuf^cjt{(5jB5xdR~7=H9iX(Ye_=QHPW(>_W9hjmTP@Z$hZF;`+@^|8#*7NO{EpMdfstx zyl(oaJ;eVZJApf*cPQ?m{qx(8VGH>nBi-fdrvz79{n?~ibPh7bpGD{^L($&jmRG_( zxEtT1jPi-(8djsTR$#it8SmaEwNZiP3&!{r{a6luvK+&<#UX3@LD!tx!f<_r2RIH?x1=sDa|t? zBL?<58Glg-v)C!vKP9&vai!dWZx?=apW&p8sTX4t#jXc_7=);na_@SdNLQ9=)&;U3 zpi;Di77e^A`lHk-_raA5ZJOCgutvawY-wZz318=aN3W0{f#h>0G>^(0Ni>@xWERrd z6UyMZ?obzNwsFT|M#0hY=eO4t+-x#YGJ|a}+dea53DfhkjBt#8DJSx&8JN@pI_x6nxkR34No7kR)@KI8RVkC7UVNwZJj_=RQ;d@{e=64%a9 z*RtJx%%{db_2M!EBA&26NvlB7Al(8kUg}r9pW?D+s~39c^lRkCEMx{* z<6QAwGPJ|a>%6O9I~XPE3u*3W{OT{MX2iNP$lU0y@Pss*!_{DF)ugP)1x$3FTxHbU zui{rmddyP;#f(J^h!|*b+Z6I-WMoKvlu*DCMs`|E*nMFa$RbROxr96RZTxwHlAj8{ zM1(V;xldkWiY~C%d+;UyAx)<$P={@} z33K9aNV`z%gI2|G^9>;ahmnM(vc-YQFo9n}Oum839qAa3Odr(a#^3{jm=6rH-i@kD z$414Y*EwctKEsEDbGa38a1I*wJR{RSvA=0h`7NGa)ugvrr!>SCxtPMt~#ppkiG#Ms*gDcQ<$mD~AWN8#F5J&|?i0b~BmZg1pz z5(aJ^U2#RKP$x^)G{|aIC<*`Gni48Tjn&H%{t5AMvnptIs_^FII2nvxTiy^v%D0D~ z(~?Y9dA%Q}wFEVB?v{nvgZIZ zJ71an6|qDaP>@Diyq9ZLzs>n1iVdk&?ibX@Z;aeuFZujMkOo%xr=wXm8y(zu zOsLcn&y%77n|vfFF`bukD{F+o&AKB%g}E9QjE&{TLwT|OsT{MDlS#zC|&5gXkvMU8$Tr*4k*_c#`E0-|p{N?qN0@M?dR#0V+Y zjtHfRasm~OIr34(IB4stG%tMlS#9%I7W7mFW3|$O_M4XQD*rh%1Fac#iKGvgwK7TD zsBTJVb)O8HA)XDxdmYr`#4PV36ff=7qn)c`+K0s9w8y1~5{^h12cF8#G?Uy`GmUII zd!{r%f!Zo-(MwIa30O-+k&COAd`ad|_9SNh5?U&eEFpL_(WRWW&=6=sDL<<%D zIOH!pqINysq1M8stmKwSttf6v=$yvWIKprNhdE)jy)=(qDsvimAtqzrA1j zfJ<4A^{H=oJUw%VY%LK_oPrh&e9wRqN* zs302T&|0=wh14u-XxhI?cBJ#D=i$sldp&uTmGk99EXeJ}g`DzHeBO>jHx7mNb;f+SiN}Y;3nDe~iC#m<( za@>N({ZTV!p};0XC&mXct}%P2_b(BW8xd)KM+}`3Mlx_vGF5g>$&-t;Qo%4d9ADr( zGTm^S=C`d7g8k?v0XzCg1`jlB)B7->qk;<68V~i240oh9-U}hwJ6imxvR7Fj8genR z9-eC=B_Gkv7-G3(LF~&!)hId+rP~<~l~-#FEBoRiO!uqz$uM(Xy+-o1l|bVu`YagZ z6QDAUd$tz+voePxwW~yj4yu$&C=yE;2()E6zil3bcreubTUL4ZT?cMQw$kpkR zv0UNS+41UhqJ00_ZfyG;n}oUU-e!6`?K`7T27<}v5|tS;qyPXkG}T1#OUQy`=5lN5j{OWl*P%fZXOLgo8wK-SR{$*iwdFe z2}G%t_Zn_--$!;d8LhYzBVs(LgJ`4JS*aJOjVPLRmS^+wjV zEJ2OW^&GE0;T2zE!X^&yKAr5`NrslsVGkU@?Xe)~l-khwL)xRyaF|SXS4v2QG+|)N z(n$67YX>Si{VX0!LQSors5xhevb}&r_gZC1g%P5i&5Rcf=t$05rdfQ#>TT_AttEsy zeIuY{*Rtg^ITUUZC$#)xmj}g(Np*9E?y|pJn!17ZcAg-%VJd@$8uBb9%}3?bPsa-K zw}MQci)AOUhT(OTw(`QSX~RizXW*du8vO^XDVTIzL-t1+rm9?=9Iu}SD^AYN7XM}S z<9Jb(lY=KOaCq>HI)UqS{1>ao!wx(tWO!`1uD5OwL2We_s_93&3^4b3o zqx~)Mm%v$SiBuwuoBhF5rPfd_mWM~6={J1TQ){Y5({Bydeg@@QukMBS_jL~*V>@P@ z?;lXD8j%(}x+BCa^I749vaNr_1xaH4gAVcYzt3CP=k!D>jZ($+QWM;V%S3WM=X^2k zC?{#TrDzFRmU?bXmFJ0XMF=@xLakRmnpp0Y+?=l4+E)kW|B{e^=ZR$`dzKbh~?UsnKtWhvmYYW zD2eG&dS(P`&O;@mNoZ;U5@+jqXl~?gm63GxV2aP?CZUjgC7y6e}7=J zECsD)tr#BunJoM?l3Ko@k}+^s%R_Dxdr#5&kxGw5y?4$fDg#EsB3b(5i*)!?;_Jzg za)Sz2y#`#d4uz+$#<#8>{ML^eVoc=So-urS=g{_p#bimGClTXskCWw)yJ9Dp1xP~c z$dQMri4aZO*)NuY_T5>C<%09*MI*`}{iq@$A`YDb{Vbi!-z0zEr^Orz-*VzYz)BN- zFzs#fvX}d!HdJ(mKeR^l+Bco(?1GOc{kE7u>yy{?g|AR8+3q4aL7Qwqmb?mtC6T1+rLlwA3>6Yy$2@^yYHSJB@b;UkZaDcn=3k`^Bt$3X|qZ zquku^&c24C6CV3>OKq`&%#!eQPls^{JtL)F4MYL!z^Asyp`4ei_NB(IKB?4?X}_nH z9ztYo)g~-WBME`tZ!!9gjXydBzRlM%E>G4j-*$zT;NJi3`6jUejZ08S@jze zh+EHz+52h~Oly|JGw|m88c#pUL(X$$Cciu<{k^lk8elh6Y2)!nu!^FuVn8$zLI{P|4V?r(wHqWD#?qktXe=jJ7YOdk+p z|EGy)xu=%7$KF)C<4DlgGFr`k>n|4YcEQTZBqVy%v-cUo`23K| zzcxLXt=)%s--3oahu43ll-f;RoVYeXpKR-4m*O_nuoI4c3E?M{z`k7~wh^p*KG3V` zFH=9myGO~<4{$_0$b^|bH>^r#cf|=MJ@3>Gd_>AH(WGp)n?Gh2MQe*T;&W@|f~Oue zoy0p5o8GE4J1i>s30)z3AZreDKM{>}$zD!e)EO3wg($fSI^X-O<{U-X1VAE-Em%a*0$WpWhZ#; zE6cDTvia@n#;JG4Gv>FL+?=ekiJ7WNeGOesJTfZ0gQ7V7?7(#7H0aH_x_vh^w1#Yf>2io)5fA!BSd#5dd6W94D4DnQ^<)U}qZ zBmLJ&2W%N+4FEf+l#_#e8y>i)@3XVI;ozD=XYC~pR` zXkv#baMvF2jmnz~1aVRNuJ1?CQ(hrz&+!<!CNrhN@a!@i^3{Ze=m^W8JdT4@rs@ z%JGa%Zb;m$MGwLyLQXrd^{}|@DU9X4Js?hyhKl{Uo;UAMU?eJPrrMGynMLc!-Q}d> z@;miae40N^J%tAYbK6NbMBxGNVPwfMu8QG3GplXS?1uNnnvL+y-Pv9U^kZV7X*)#C zhMpg2W8KkwkQpN)%deY6XZka!<4N*Ulw+&D@E{@=_a8imZEka!hDB+Td^RF2N9TS(djiNuX39ZMFykQ-M(-)10}W&iY9H@p!Z(vDrrSk z8hn5ne{b~er>~)pzPb~2w3s-?C(tZT^lWPP;5^;`sF+rJcuX&YtP~-cE--|*<@;dk z<;3}RipC;*9E?bSX^+h$k48LCXqXx`~F%m?+w?Iq@hM7gKoW0^w2`)hmY zi%z#?I@d|^LW^qMi6jUXq5DLPhVN%3O( z?0-n@Z@a?*z3Y8>v+B9F*{#kq?f8$7)VYsRk1q`Rj<%8#ie!w_B}AQNIqtH@jeUFZ z^Xtf3Wr=9E4>d&n;W_~hxfeX12!#eoAt%;Vl_<^y}1+&3-bo=YiyPRkoM` zcIbO^3m)%W3Gbum6`cNVBsr-iK*OZqr}+Ie_3YGJdVgHxkxC-Xu=mHKQO!F3!fL&H zD46Db3N7z5HBx~;!YKk__7?f=$6J~U$n-XtI%5D|Efgw}I;oY+ukrd4KX^LbK~T0_ z$yLtFBsje37tXnQ)whC)bLWm8ST|jAZNIuSa4~29ICM7wg^U$5+v(nykL0jmd!6J) zFwZyYcQ-Z%zs!%95}3{kY&8GQJ$_G*i#)2c^`ZLy&&%JM=g3^D&X&C8c1UDX-#v7O zyVcf4w(di>`ZF%-SH$fR()B%TE*S=)=Ir~mGWXL2hHzpDv=RDWEnDL6irXL*ev=B} zzV_wzBRW(Usa%yl^;O!+QuBQ&yq|&vF{_P%t{tMjb$hPoS6iT+5}}WT>;Bgn>-Wbw zPjXFUD_dj(iVwc@aS_DkFVPlOHSEww9uK`2(`tkqexi-dG#g_xoqnz?sB9pDUuNHj zS}ut{9M214XAXDcK_Af~9>iQ$VFRygbUVhhk_rCJ>)5FQ~aTEN@Cpwix<>Q5a z>(+jwZLiOS$xw$IHImY7ZNxsD>HPQ`4%$&U$;5CY+l{q*rY}W%U$S6aJ79cdATgfj zBz_rMt!6)*98Qm^y|9n|iPgkjw@?@)_L~Fi2&X7k6=wmR^0%VGvOZym@`x6Nf2f;K zJSHX)d7CZTEpd6oI6v$0;UzojtgQs)orJVNTU&J!bU73a8idh{x{q31za3^s{)~YA>E6C+EL?PS!8#t$SH)+fZxQhEJJfsEYRVzli$M zQhgcVXH6l<14!mAL$$YH*|3^xT%M5k{!#My!;cYoPaG>NYexzwG;WeQF)!IMo4J7c zS>m>B4N;baP-&3nJo*Xrj#2T1o+UjCdW(sw{38=5US!FUmLZ=>xTsI1?Va)3uV*|0 z^e#duxYEDIQY5>EFgjLHO1vl9zTpV*GIka*(IG|P4}b1#P7)<*J-pjWN14NY8ETNV zcn_2rpGA}*78?TFpOW=$ch2Y&BDSOAh z5np)(+@(_(J3qgD!HtO_Ch@Wn8#nq>mU@%JV>t8<@m5GV-gEZ1kzqsKW06qx(e_d% zq;+KVlS5mdaWEk7buk1#svK_4e?)hb=faX00Ey7+T878ZHVTy@(^wzsnCdaebx|_o7d~P1{c#~~p zM=kuDeO9V5L6JdCx<*Ga)EB7ZS!rvLzv_>0vO92-oZ?pPUd4XZ$rPu9y=3;y6i(bDPF_8@}VN zh!25y;#cB?zB570X(o5$#c>f3yJ zF(YyQN!3jEi1ot5|09CL^2-R$-OyHkRAHaO5gLX7Eo{tZ)^C%c@~WKGJ?LCx;Z^3; z<#?)d+(;ifPM(oc+$$4|{gd+Tg>Y3XBhFoV4WbVJ(EFiI?{F`EAoPS!ZkLMl#&xZ> zcGG^D-ID7)`Z&|@Du>$c;Mu|tWXfjbIO}Y@omnhfuhgQeP2~b}EoJ3^{n~;!y z{%T@U&a$;p*|!3QcL@d8@pU1BLa(uym+1mVxABO{{ECIdMZdT{euOkLR_{1n>?Fz+ zMH(adsH^nT9<~n#Q$Mzj14dLvaL40mDuJ=EpV29CQJX(}Y-ue|`>N{7IB^7+Uf0df zT%grIydTrsR&cPt7O|Yu%TlYc&G{%*FlRrTm}8NZ@o5Lnp#6}qKnlG7GY&oyi!n8FW<8mpgLqd~?f3MN`R?H;hM$+HVz;|U zlMvrHeEvSg?tjpPj5&T55l8-ksRc8~Pyj`KKHvNGJ?g+GPj}&GPGYTkt5xMjT{n9v ziS>d`9K_c$s_K#|il88IaVReKkuQXLaB%eD>+Oxd9=K8BiXXnK>C~p3pC&;c5Q)WW z)E`}$BK_3L4^oPQ_6i#h!K(qG0sEPl9XejoBb0K^OqpknYC~*UJbiVpIvZMZ87O{G z+vA?Z`$fj>lJx7KApya1MpYUls78qlGU-ujg!yW)+fHX@=>Ew2Ks@Ha>r0I6P)639 zmSm)dTzR0Mg~}xB7OUogZld&l2ThaIPn?d2oknFw<24ebOora! zVrm8A`eXY0iHPH=Kp#GQXKGLqv!8Y-^%ub%!_N>(N)}YXRYH1|`=~!Y=n1y8D1Gh7 zBdYU*GXCfD{H<MlzT}OF#m(xe;XkF-M zHmM-0lQ&_6NR#8Em4R4jJIXo%4l9m4D5`~DsC@bFbTULA_K#lB%?Du4xwF5TY9Y_l zyQ15+qWk{Gu_Dn?IX%IQFjyS_e%Gs$V8uqoBjch<_kzXC9LqyfN&JdrUpI=2ogJZCx zPxGWZ(!sNPQKYVT-iyqo_|k=(l7o$&TOQJqiXj*$CMIw1J!Ib5*(g$HEJSN} zBX&QEOYQq3DDg~R^XFY7&$HRfUF((4^Nmp)BXJaXg@+0MM9}pa`vvZWFvj_9P11H+`P~UMa1=4CfoyI*LJ(s4<$&BfeL zu^ST!H7oEZ2JF$@fBWnyRv1G4eR=Vgo~Sx}1haHlV|sD(*aOJ0{L(eGyJv8$Dgh@` zlAQ7>*6Y^jnmAVpHY-lq*6#1kd*|vU3JHJm21}l-{e9iH&}tP+Vv?@I6Pq8N9rI`K zQbidJ?L9MDcJLmY(B}|GSuWLAomgZk5Yg<;1u+TYpvaR^i!$(%%PLOmg-44g4C6oC zlvjGflJn7!D{wtG0u86kL6~Q4|aIduQ5mLcW!i-IEsVa)s*7Fe+2{v zJ7k+$rtYy<%64(3$#}}j+eA`~UjF4C+rGtGOo4<aYg8Z71>* zW=t1X_*9|oxw?C&oC}4G!u*@QHdpjCBxl6$-quz-=d!oacpp(M0Oo!`lLFoU) z#F|9Wa7Ln_nXoy?jv7OHWD?v2RY zhRO%x@QSqTh|ag(wleUJMNB=H4LMVm+t^kO7&|03#GP3(?EWj3pI2MEHfzcy7MUZD zpTexG)8w??RJUyBZY{5-M%+q9Wk-Cj(_i&H>xF1`H^Ic%jF9Z}j0C?QKY-+;ulp0@ zqhy`_54RT$JEKqcS5+sbrUFGf;|JT`EkIZ}&Fecmq^c`+70>RF{2B6Q=Z{2Hz9efq zdCyQ5te(N#K`*L{x+iP2Yi(!Y0atU)&fk1h`Mw(w zd)+OrM!c0d!0-8y_nSPDM2iX~;WdgFLc7srBqx#!aN}Jx-6g_#`CE z`+0jWX94feX1F7EW;RGAygk&Rz)-D(n~a4W^vbiDI&Rzgo6h>&-?NSGq8}buIgO1o z4Mqd;HFn(EDw+?l0!64GR$>S8yH(uz&CS$*MMLg9KH6ENptv%-FDfl9ZFjmSUC1Gu zrP!^bAZsci@dbFF*GT)BE(f@FiD*J3*~#X;6R%10XPt#DN->q*=hNFF6f)lwoHwK> z>Qb`~8m3BOj7?8Vyr{nl5n*g(u~|53Deb2xM!W2Qx~Ov>=A$4U1`oR-0$~YPMs;1V zKc5QOZr}MqZR5<`vYX2`FOS;lFxpQU)q_@Ss}~zBcE<2PI{J)Bv(|l|NCDo+=gAi* zlcSNKYw(CZ`;}SpD^6_#U-gG(;@1(BJ2%0 zi4UGem~9>XVPhJ5>bgW0gQ|Bo!rN9pkok>0$^6HowzW5cb*Km$q+_KvM2D8-JOB2j zNMV$YAj7_B&ax(hNyXti&s&S3w7GBJY8E>WV`?|ZC>~_b>{9kcv!2jDjxSd1W57f+ z@AMCvn42PxpnKU|zccft&V0OZVcdl(f$Wo3Do0*1XM)_+=3L$L-A{hEj7$vc*;)%D zACz>--IasvL+`cWYW+G{XTm}8@a}V=tF&JbA374a=+8TU^RW@N!wrFf1W_W0@3KBY zNteMz+U>X>Bj|Eo-tgV)sg7a1!Z0Q)e$*c$MIWtz!O-YO*o4fvQ%6TLV+xxmP=oD` z$8s;x=tMaA?7QYf&q!k;-g6=Uz4OJEEk#YuKf1LhveuqjmaT#b6+!frfmKBhxqkSb zl9Y5A%dxco&?6xT8tm6qiHGLzw$HX&65YOi2e;7A(`){0jbAS83O7u+k%ks!MwSQ3 z7o8HBmB9Y^O}mHrR_k$@-KhDfJuj1hDI4i|=5o&Ras_;@@A2Oet@?v3KWdXQ>p4Tq zQSF4SWT7TZ<_P-f?h*d=Utts2=P@;->q$%;YYwj7ZsThlxnomvN<`4E;@0Q4S5F-x z{DrID_cuY08D|s;57ez@+?B?7O@XC6-|0{LnC`sIZ88K3f(mg&gp@isQ{%qBSDvBU z#*`$NWaI^=bv)L8t-#+=0+wY=r(*vQ`S1c!*HWAMPaW0)4KK=4r%j;5Ng3y;RorO< zdC2;#-t(}zy7KwT9F#t-gZz^a$?&3nmzb)CKjA(h+9U4Drqw@lJhi6N=g&xv@LR-@ zc+#+w-+Vt^5^djLw4+}^a>Mj>Lzp7zk*T-TMDs-Ogz#kW1SBH#LVp)$s`Sp6+^WYb z;4?dxBdxCIl+DFD{zmK_>yS4$+|Ri}F!NH~>{8OzO+P|ukQb_KMQPwE(Zq#rQ`{iD*w~ zgMFu-Wk`|;awjCx>+SZ3MPoeu*+nYKGEw45;?XrX$Nup3aNd)|abk$!*US1KdMJBH z{Uw*qZ~c^^mU>jE!}e{_i~-)SlukknE&T64?7r&v5DT5^|1^13)tZibE3^wY3?XBl z?VpoWN&D-lA>p2{i3xu(iNTmh^i>&agY(A$onV`W?4zlnv6aN<2aOvaMaX?g7VkX3 zV_op&|2o2ivie|CV9#dx)mJmB8j6HeMd#kceF2>LtXXPBF(|LMb4aU7ZI5R*6K&9D z6-DgF-ED}j*bWiash|E+*&p*0+LJqx`F>4-?zi_#hhL;ZdhjVzZ=2$pq#W~B9nU`A z9&TsLnmQL8@X9=;qb1Bf;osL^y*0e}3>s;9dy2gpleTE=qnvfTKP>;OI`I%aEwy3u z)#}I8p)?}4lxNVW{%5+!ugmkhQqnvkjvdn?($?5mOe&1pGMa+jnfAShH&Umc+v@qG zp5l4ySlLcw=~fEh+94`&6rWXF7Vui|wpegW7#w;ipg}*s-SoIXhuZf*GHdUwV() z#cY2y?sR@9UBbrw=9Hq71jU9`lUfEJDbEkiGN?$Uh@{{1{*k(*LBK*AiJ?TVfAv-7 zDUDLnLxL^o;ZasWxxul8(Ux>~)L%FoUaK!sv7KilbMhRzUI<4clVdp$V;Bx6zIMAC zgGPnpK*9v&2O|3;Df*7REseQr81$ZTe2rbZP_XZKZT(U)+0n^;HEu6?iGgE%UuOCn z?WKDL^RbBc=lw(bDAtyc#P>o*HU>W7r{b&Asfz|aS*Q0`S)?%c_=oF;(bs>9>*oRT z;~hNjXqMP}Qi()VRD85}zO@KDF1(FARPo2+Pj?9*r6lBFoNk}U#2mvH$<=wN0o9^H zk=2IcbMnsxUzXJ5ea+j;Qw?ErtNX*MNqnF0zRF8tb{x`|HrgI5oF7+=?yI36f<{gZ zRFph9igC^$K3j=6e)WR=q!=NPstFY;R`67y73-k^Pb``GtO zhq{8|7lU$2)zdb)!PGB%9i(nTwvZ@~VaPX&$cN{oh7u8Ih9Mts6P-9HC1EE$O!8@Y zJx`qc!p60)ZRJf069z5dloB>9J2FZQ{x#+Lsc|0Of6DT=I*T!Ne@@wYxsjC_1EU8c zfX(F36;fA&ZzApkTcl$Hg5ojMuE;SIopDpCAY88TnOxtghq(yR5W8<8K!TPKA+>0gT|y!QZ4$T)zi`@Lc(^Ory^tYiF&9|Oc6vsqhOP_^(k zAFYXrcRnKh8+c0uC|;5;=KPZQ{pEd(^=mA`OyeqX#4_TCy>h1}15qW>tIuK8?auU% zAS@GRh((b#Ml^~(wJ!nJVgKabDOw=O?K5JNV%8>GQ-;lVRxX6C{(BS+1g}10%2Cih z!NRrpu)X>>pK0}kj0$bLn7Ex1+x1tCXFiP5n@y+Y3!&q=RK#010t^&o9O~c5enOPE z7%2aH0R5jX{=d1_IU9a;DjI3z@g}6yLHvB^|Mj?X`WHHld0&TYx7HLBt zbs24&SVaxP4pB+Dm6uX-$1<{t=kkgwqi~i=47dX$WM}X6SW-%MTTkBzywTAI8d^F) z_O(9XGEBT=Q*u3gpxkuIb7uVGw|(WEpW^(b!v7NXg7oLE9=! z-N-TNwV`7epQ4!$oOJe$lvxCif?0r=l%|!lg0^`&zl=@~pQ`O2PVJCWLHlAL88iSi z%{>W#fuS)lHZcblmexQ?MGd&PdT`uOW@KWnXl!D337<0nT;1G(qoXs>b_fUjz60R7 zV>4j0ECMY0iGWeX4=@Ou0VW>hOJ?p@hior(PgqpE0GDYd;CHG8Lhc`duxBd}cC7<1 z%rXF%hA&`}u?39s&VWhXA27d(25c6EfZeqNh=stLOk?JNUO*`U@b-a#pMM|-2@L~| zPA&jumEjF#<`&ipkgwlmR#rAhNlORbA#vcPTRC{)-4CAG*8?`QJiwwC513Sg!BZ(O zm^w@FL?r;Q8Knarn-U=C+5|+rJHSi-PcR<_fn@OT4ZN;jQ_5kI2~!pbn6$zGt7$fP z?gWn@a1=;K&jPu~F#=#4ng??73qe_V1qcoayQWg%hB7yIFD(;Oi_412Dp38Q0mwL{ z13q~C+#WsPnQaY>EekN~L<2^pK=4G|3D8P8!1Z{*X^{u`o$GF>k_hYvufoTGZ1fb6 zi=6?oQByz~u3xu{c(;S+MyY^FGZ?TMXTYPagXd!iNJUP=zn>-mvOcvSyQKbxGD9O% z;OXV#dPA9wtwVwj`aQU}M&f0E`O$fL72LFepNR z%`gq{*p>nzk5(WK^X6697*L3t1Fw@8fM)8#4ZN;Phkt>2*$V`mKL93;V8CLK1fJPc z03NSCAQ^Ezia7!pNi&FgTMo)$0^$=Afqy{oha1Ygef-RVf85_&E&n50aQo{5acX0Fh?d;~Y<^mU6d#A5aG4c2?WvozeSk&Xd@EA`2usD9$P)$in$pBbi zK~zi}sIIO70|SEqPL>Q{r3 z!*VtNL|kiuu~SHxpc zkDUdoN%KHGWdSIueFJLZ3&6r;1t{8%ftOaPm-^P;`9_X`c?M>7U*M$YJL;NmfQF{d zp>Ig6z>O_OAQIl+5{7*J15KQrUBR`SySaM;dlxUD5IG7YVeR1c>IKiuasi#RGpuoO zfW!Ph8uv1w52j=EUmE8*1C;sZfw9gH;OV&vpy2O-&oUPXyHo?|&=Fu{=?pBbY+z&L z2<#o4fV-zp^#7y*mKn2@)HG0BQVJ3?a)5qFHIRiZ+RM;!!0FZn*sMyyQ&oS!0NbN$ zP3AO71MH?5fZaS7aKg5U&$$-xOZNjU=|x~;^$UaquL3t{0xwSD~ZeRn!a+@EZm~p3UHGNh5&s z1cUeQivgSl9QgYO+!%Zx$oJn6w(-E%&kwc?MZg(q1dMMY0GoNijb#vp$08Fm3*N*H zf%58l5E~Z{oSoek6O&SI!E_|#!}0(Ngi~Zx41m**gP4?TpcVHSNWu1q8@5Zy75$*P zrUsOhmH{}X6yz5afY7k;o5dzLBoqV$1cJc8AlOU=f?(J>6%@eczN`#*#1+9=Ua|oj zyv|&YMH(KHQCt^DOwR^s@O>cPfY1Mv58;t9gxSTccxQK}>8Mh=ofG{Qq_RdY&U9qi*K9xESUaTuRHzfk{9v5VcCZ zkaj6Nd*fSt91s?F5ELG>8xS0^6&@Aq^dA~D^b*su!iR>2L1$;z&Hb*8+_n6sr)PjP zc#cwG8A?e>1xd*%ASo#sE-9e0sv1;OR^C{X@`{QJC@j&#AvBBAJ|vsfIXw4?Z(Kf2 zWNHCfOwwBv*Z}BBM#rbv_4W7Pm>xfPG8L6nZ-g@^Hy31Q=YZ?Q`ntS(mvvKI-8|rd ze}Dz35qxZE0o^@4@KKHN_AoLx$%4Z7+%Q*;o0>n~AaZbYxsjA>X(=jt|L;-=OU`w1 zc5%OP724X{!KY7spr^O@G9~@3{tYsCDCn7Q-%Wm~s|N~-Dlio}|3-F=@V`q$L=;d_ zRli}umoHyId3nVyY*guBWL`q4X&D~Z!z_fU`0tL_^K-5DH}eD|&VUyb*x`funhHk8 z#$Y|kPKJ^A3Kf@DGQ#N z2fKg&-XLG!*aW>pW3Z~eFM&IUa+lV&Fe%x`pPijwfTg8nz|6)0svA3jN%|x(P3#AL z!I7{|6~X7u05CPb3Opj;ZPwH`GhcURPsytk(1WrsZmz(<2RJ^v{9iah zX~)cE*@srGn~n)@i!Jz!<3MmhADCa;13~4pKssU^C?$M{7s7ea|9$_aoIbNMkN}WTiR|vld%F!+OhD0lMDD@cUai74TwSAK-{kvi23&1I0}MpO~59+crGHZ z_4ajVuAtBuJ9aL?OFC9TKriib<0G=0Wdk0&@*6)#jP7eK@q94!jgJ>^v{(5t(XP; z#1IGq@`izHe9c)C>W^U@FuydSM}TI`D0pUC3|yn~CaofCuAleZBtznIctlj(PM-=|0Xhl08|ReI zH1RSjv#c75e}6wbqY^u}tby{{9LHo;8FL#YgIB&?HK?(!oMcR0 z<4}FWGs~WcIs%554uD<>0*X#42k}`If%c)fcmJ{J{{|^VO_DFIQ!aRHs)2s;BzR%} z0lc(MJq^!p7QRME78IAq`by9L@ERG5iVtv$E*Ol?DCO61O1$>k@X6d0Yw$c`i$>(AdrH(;HgXj$wkc;*BJ0qb1K~FCG3HOQSg3JZgqk~(A#V4LrMI$tksaqDEU&* zsR8EBXTYonuO-DzS=YUAb4%+2JtDID;gL((1!P_?5Rb@Q6C3Wh#uQJm8s!14*fH?T zq!0w8Rt=j*)L+l89fnVIE?QthAsSp^CC;zy(Gh|V;+F7g1EOw?z&4_I#VN7*n(Ob0 zJW^Y5Lf_Tbvl-_D#gI=x(>wnlAiMJ)@wdW{De7iZbj{t6@#_MTj(JCE75&%RT!wEJ z)rj=2`ja8QP4T6)Tg8!QdMhh@p$gX~wh;x&_!uJLT=v%^t%V70{D1@B@0MF~v!ZQW z6DHgs2?4>Ys|!H{;sOcIE=>W$>#6v^fd9&Y4dOFJ_Yffd)qVpZ7{SFq2u}VB?jqpC-|+RNe>yCo{HtRJ o-#^gnU$7JW3wDEl5i)x94?+Ki0skWC>VLuRf9fmnFA#|T4+J!O0ssI2 diff --git a/srchybrid/res/emule.rc2 b/srchybrid/res/emule.rc2 index cb4a492d..fd29ef34 100644 --- a/srchybrid/res/emule.rc2 +++ b/srchybrid/res/emule.rc2 @@ -38,7 +38,7 @@ BEGIN VALUE "FileDescription", "eMule" VALUE "FileVersion", SZ_VERSION_NAME " Unicode" VALUE "InternalName", "emule.exe" - VALUE "LegalCopyright", "Copyright © 2002-2021 Merkur - Read license.txt for more infos." + VALUE "LegalCopyright", "Copyright © 2002-2023 Merkur - Read license.txt for more infos." VALUE "OriginalFilename", "emule.exe" VALUE "ProductName", "eMule" VALUE "ProductVersion", SZ_VERSION_NAME " Unicode" diff --git a/srchybrid/res/emuleWin32.manifest b/srchybrid/res/emuleWin32.manifest index 9be86d8f..c9e4087a 100644 --- a/srchybrid/res/emuleWin32.manifest +++ b/srchybrid/res/emuleWin32.manifest @@ -4,7 +4,7 @@ name="eMule" processorArchitecture="x86" publicKeyToken="0000000000000000" - version="0.60.3.1" + version="0.70.0.9" /> eMule by https://www.emule-project.net @@ -16,7 +16,7 @@ - + @@ -25,7 +25,7 @@ - + \ No newline at end of file diff --git a/srchybrid/res/emulex64.manifest b/srchybrid/res/emulex64.manifest index 2509b455..d7d35dad 100644 --- a/srchybrid/res/emulex64.manifest +++ b/srchybrid/res/emulex64.manifest @@ -2,9 +2,9 @@ eMule by https://www.emule-project.net @@ -16,7 +16,7 @@ - + @@ -25,7 +25,7 @@ - + \ No newline at end of file