Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2011-04-11 04:00:00 +0400
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:16:05 +0300
commit35596517f203f1c4970413b3b5b2e216b849e462 (patch)
tree93240df3eb4ddbd8eebbe6a5fc65e93f2ccb6495
parentde4f8c22fe4b9e59b60495b84db2e81de50999a9 (diff)
9.219.21
-rwxr-xr-xC/7zCrc.c65
-rwxr-xr-xC/7zCrcOpt.c38
-rwxr-xr-xC/7zVersion.h8
-rwxr-xr-xC/CpuArch.h4
-rwxr-xr-xC/Lzma2Dec.c26
-rwxr-xr-xC/LzmaDec.c22
-rwxr-xr-xC/LzmaEnc.c14
-rwxr-xr-xC/LzmaEnc.h12
-rwxr-xr-xC/Ppmd.h7
-rwxr-xr-xC/Ppmd8.h6
-rwxr-xr-xC/Util/SfxSetup/SfxSetup.c37
-rwxr-xr-xC/Util/SfxSetup/makefile2
-rwxr-xr-xC/Xz.h10
-rwxr-xr-xC/XzDec.c48
-rwxr-xr-xC/XzEnc.c297
-rwxr-xr-xC/XzEnc.h32
-rwxr-xr-xC/XzIn.c41
-rwxr-xr-xCPP/7zip/Archive/7z/7zCompressionMode.h9
-rwxr-xr-xCPP/7zip/Archive/7z/7zEncode.cpp12
-rwxr-xr-xCPP/7zip/Archive/7z/7zHandler.cpp52
-rwxr-xr-xCPP/7zip/Archive/7z/7zHandler.h63
-rwxr-xr-xCPP/7zip/Archive/7z/7zHandlerOut.cpp393
-rwxr-xr-xCPP/7zip/Archive/7z/7zIn.cpp33
-rwxr-xr-xCPP/7zip/Archive/7z/7zIn.h1
-rwxr-xr-xCPP/7zip/Archive/7z/7zUpdate.cpp192
-rwxr-xr-xCPP/7zip/Archive/Bz2Handler.cpp143
-rwxr-xr-xCPP/7zip/Archive/Cab/CabHandler.cpp33
-rwxr-xr-xCPP/7zip/Archive/Chm/ChmIn.h2
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixer2MT.cpp2
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixer2MT.h1
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixer2ST.cpp14
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixer2ST.h8
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixerMT.cpp2
-rwxr-xr-xCPP/7zip/Archive/Common/CoderMixerMT.h1
-rwxr-xr-xCPP/7zip/Archive/Common/HandlerOut.cpp606
-rwxr-xr-xCPP/7zip/Archive/Common/HandlerOut.h80
-rwxr-xr-xCPP/7zip/Archive/Common/ItemNameUtils.cpp4
-rwxr-xr-xCPP/7zip/Archive/Common/ParseProperties.cpp174
-rwxr-xr-xCPP/7zip/Archive/Common/ParseProperties.h16
-rwxr-xr-xCPP/7zip/Archive/DeflateProps.cpp115
-rwxr-xr-xCPP/7zip/Archive/DeflateProps.h29
-rwxr-xr-xCPP/7zip/Archive/GzHandler.cpp21
-rwxr-xr-xCPP/7zip/Archive/Icons/bz2.icobin3638 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Icons/cab.icobin3638 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Icons/fat.icobin3638 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Icons/gz.icobin3638 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Icons/hfs.icobin3638 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Icons/iso.icobin3638 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Icons/split.icobin3638 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Icons/squashfs.icobin3638 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Icons/xz.icobin3638 -> 3638 bytes
-rwxr-xr-xCPP/7zip/Archive/Iso/IsoHandler.cpp13
-rwxr-xr-xCPP/7zip/Archive/LzhHandler.cpp144
-rwxr-xr-xCPP/7zip/Archive/LzmaHandler.cpp3
-rwxr-xr-xCPP/7zip/Archive/MubHandler.cpp24
-rwxr-xr-xCPP/7zip/Archive/Nsis/NsisIn.h2
-rwxr-xr-xCPP/7zip/Archive/PeHandler.cpp337
-rwxr-xr-xCPP/7zip/Archive/Rar/RarIn.cpp2
-rwxr-xr-xCPP/7zip/Archive/SquashfsHandler.cpp104
-rwxr-xr-xCPP/7zip/Archive/SwfHandler.cpp13
-rwxr-xr-xCPP/7zip/Archive/Tar/TarHandler.cpp47
-rwxr-xr-xCPP/7zip/Archive/Tar/TarHandler.h1
-rwxr-xr-xCPP/7zip/Archive/Tar/TarHandlerOut.cpp8
-rwxr-xr-xCPP/7zip/Archive/Tar/TarHeader.h1
-rwxr-xr-xCPP/7zip/Archive/Tar/TarIn.cpp102
-rwxr-xr-xCPP/7zip/Archive/Tar/TarItem.h17
-rwxr-xr-xCPP/7zip/Archive/Tar/TarOut.cpp26
-rwxr-xr-xCPP/7zip/Archive/Tar/TarUpdate.cpp24
-rwxr-xr-xCPP/7zip/Archive/Tar/TarUpdate.h10
-rwxr-xr-xCPP/7zip/Archive/Udf/UdfIn.cpp35
-rwxr-xr-xCPP/7zip/Archive/UefiHandler.cpp1935
-rwxr-xr-xCPP/7zip/Archive/Wim/WimHandlerOut.cpp3
-rwxr-xr-xCPP/7zip/Archive/XzHandler.cpp115
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipAddCommon.cpp101
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipCompressionMode.h56
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipHandler.cpp44
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipHandler.h41
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipHandlerOut.cpp298
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipIn.cpp4
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipItem.cpp62
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipItem.h13
-rwxr-xr-xCPP/7zip/Archive/Zip/ZipUpdate.cpp69
-rwxr-xr-xCPP/7zip/Bundles/Alone/Alone.dsp8
-rwxr-xr-xCPP/7zip/Bundles/Alone/makefile1
-rwxr-xr-xCPP/7zip/Bundles/Alone7z/makefile1
-rwxr-xr-xCPP/7zip/Bundles/Fm/FM.dsp8
-rwxr-xr-xCPP/7zip/Bundles/Fm/makefile1
-rwxr-xr-xCPP/7zip/Bundles/Fm/resource.rc2
-rwxr-xr-xCPP/7zip/Bundles/Format7z/makefile1
-rwxr-xr-xCPP/7zip/Bundles/Format7zExtract/makefile1
-rwxr-xr-xCPP/7zip/Bundles/Format7zF/Format7z.dsp4
-rwxr-xr-xCPP/7zip/Bundles/Format7zF/makefile1
-rwxr-xr-xCPP/7zip/Bundles/Format7zF/resource.rc4
-rwxr-xr-xCPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp67
-rwxr-xr-xCPP/7zip/Bundles/LzmaCon/LzmaCon.dsp16
-rwxr-xr-xCPP/7zip/Bundles/LzmaCon/makefile2
-rwxr-xr-xCPP/7zip/Bundles/LzmaCon/makefile.gcc21
-rwxr-xr-xCPP/7zip/Bundles/SFXCon/Main.cpp27
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp15
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/ExtractCallback.h6
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp15
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/ExtractEngine.h8
-rwxr-xr-xCPP/7zip/Bundles/SFXSetup/Main.cpp27
-rwxr-xr-xCPP/7zip/Bundles/SFXWin/Main.cpp29
-rwxr-xr-xCPP/7zip/Common/CWrappers.cpp2
-rwxr-xr-xCPP/7zip/Common/FilePathAutoRename.cpp18
-rwxr-xr-xCPP/7zip/Common/FilePathAutoRename.h8
-rwxr-xr-xCPP/7zip/Common/FileStreams.cpp32
-rwxr-xr-xCPP/7zip/Common/FileStreams.h48
-rwxr-xr-xCPP/7zip/Common/InOutTempBuffer.cpp11
-rwxr-xr-xCPP/7zip/Common/InOutTempBuffer.h2
-rwxr-xr-xCPP/7zip/Common/MethodId.cpp24
-rwxr-xr-xCPP/7zip/Common/MethodProps.cpp491
-rwxr-xr-xCPP/7zip/Common/MethodProps.h177
-rwxr-xr-xCPP/7zip/Common/StreamBinder.cpp148
-rwxr-xr-xCPP/7zip/Common/StreamBinder.h36
-rwxr-xr-xCPP/7zip/Common/StreamObjects.cpp4
-rwxr-xr-xCPP/7zip/Common/VirtThread.cpp14
-rwxr-xr-xCPP/7zip/Common/VirtThread.h11
-rwxr-xr-xCPP/7zip/Compress/BZip2Encoder.cpp89
-rwxr-xr-xCPP/7zip/Compress/BZip2Encoder.h21
-rwxr-xr-xCPP/7zip/Compress/DeflateEncoder.cpp134
-rwxr-xr-xCPP/7zip/Compress/DeflateEncoder.h21
-rwxr-xr-xCPP/7zip/Compress/DeltaFilter.cpp17
-rwxr-xr-xCPP/7zip/Compress/DllExports2.cpp9
-rwxr-xr-xCPP/7zip/Compress/LzmaEncoder.cpp29
-rwxr-xr-xCPP/7zip/Compress/LzxDecoder.cpp3
-rwxr-xr-xCPP/7zip/Compress/PpmdEncoder.cpp67
-rwxr-xr-xCPP/7zip/Compress/PpmdEncoder.h23
-rwxr-xr-xCPP/7zip/Compress/PpmdZip.cpp92
-rwxr-xr-xCPP/7zip/Compress/PpmdZip.h27
-rwxr-xr-xCPP/7zip/Compress/QuantumDecoder.cpp22
-rwxr-xr-xCPP/7zip/Compress/QuantumDecoder.h2
-rwxr-xr-xCPP/7zip/Crypto/RandGen.cpp60
-rwxr-xr-xCPP/7zip/Crypto/RandGen.h4
-rwxr-xr-xCPP/7zip/Guid.txt8
-rwxr-xr-xCPP/7zip/ICoder.h4
-rwxr-xr-xCPP/7zip/MyVersion.h12
-rwxr-xr-xCPP/7zip/UI/Agent/Agent.cpp130
-rwxr-xr-xCPP/7zip/UI/Agent/Agent.h60
-rwxr-xr-xCPP/7zip/UI/Agent/AgentOut.cpp226
-rwxr-xr-xCPP/7zip/UI/Agent/AgentProxy.cpp12
-rwxr-xr-xCPP/7zip/UI/Agent/AgentProxy.h10
-rwxr-xr-xCPP/7zip/UI/Agent/ArchiveFolder.cpp33
-rwxr-xr-xCPP/7zip/UI/Agent/ArchiveFolderOpen.cpp29
-rwxr-xr-xCPP/7zip/UI/Agent/ArchiveFolderOut.cpp115
-rwxr-xr-xCPP/7zip/UI/Agent/IFolderArchive.h10
-rwxr-xr-xCPP/7zip/UI/Agent/UpdateCallbackAgent.cpp2
-rwxr-xr-xCPP/7zip/UI/Client7z/Client7z.cpp108
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveCommandLine.cpp70
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveCommandLine.h8
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveExtractCallback.cpp54
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveExtractCallback.h10
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveName.cpp20
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveOpenCallback.cpp4
-rwxr-xr-xCPP/7zip/UI/Common/ArchiveOpenCallback.h6
-rwxr-xr-xCPP/7zip/UI/Common/Bench.cpp845
-rwxr-xr-xCPP/7zip/UI/Common/Bench.h29
-rwxr-xr-xCPP/7zip/UI/Common/CompressCall.cpp16
-rwxr-xr-xCPP/7zip/UI/Common/CompressCall.h5
-rwxr-xr-xCPP/7zip/UI/Common/CompressCall2.cpp16
-rwxr-xr-xCPP/7zip/UI/Common/DirItem.h10
-rwxr-xr-xCPP/7zip/UI/Common/EnumDirItems.cpp84
-rwxr-xr-xCPP/7zip/UI/Common/EnumDirItems.h4
-rwxr-xr-xCPP/7zip/UI/Common/Extract.cpp14
-rwxr-xr-xCPP/7zip/UI/Common/Extract.h2
-rwxr-xr-xCPP/7zip/UI/Common/ExtractingFilePath.cpp8
-rwxr-xr-xCPP/7zip/UI/Common/LoadCodecs.cpp83
-rwxr-xr-xCPP/7zip/UI/Common/LoadCodecs.h23
-rwxr-xr-xCPP/7zip/UI/Common/OpenArchive.cpp48
-rwxr-xr-xCPP/7zip/UI/Common/OpenArchive.h1
-rwxr-xr-xCPP/7zip/UI/Common/Property.h6
-rwxr-xr-xCPP/7zip/UI/Common/SetProperties.cpp4
-rwxr-xr-xCPP/7zip/UI/Common/TempFiles.cpp5
-rwxr-xr-xCPP/7zip/UI/Common/TempFiles.h6
-rwxr-xr-xCPP/7zip/UI/Common/Update.cpp121
-rwxr-xr-xCPP/7zip/UI/Common/Update.h20
-rwxr-xr-xCPP/7zip/UI/Common/UpdateCallback.cpp30
-rwxr-xr-xCPP/7zip/UI/Common/UpdateCallback.h5
-rwxr-xr-xCPP/7zip/UI/Common/WorkDir.cpp50
-rwxr-xr-xCPP/7zip/UI/Common/WorkDir.h22
-rwxr-xr-xCPP/7zip/UI/Common/ZipRegistry.cpp26
-rwxr-xr-xCPP/7zip/UI/Common/ZipRegistry.h4
-rwxr-xr-xCPP/7zip/UI/Console/BenchCon.cpp291
-rwxr-xr-xCPP/7zip/UI/Console/BenchCon.h8
-rwxr-xr-xCPP/7zip/UI/Console/Console.dsp16
-rwxr-xr-xCPP/7zip/UI/Console/ExtractCallbackConsole.cpp8
-rwxr-xr-xCPP/7zip/UI/Console/List.cpp6
-rwxr-xr-xCPP/7zip/UI/Console/Main.cpp30
-rwxr-xr-xCPP/7zip/UI/Console/MainAr.cpp5
-rwxr-xr-xCPP/7zip/UI/Console/PercentPrinter.cpp36
-rwxr-xr-xCPP/7zip/UI/Console/PercentPrinter.h9
-rwxr-xr-xCPP/7zip/UI/Console/makefile2
-rwxr-xr-xCPP/7zip/UI/Explorer/ContextMenu.cpp53
-rwxr-xr-xCPP/7zip/UI/Explorer/DllExports.cpp17
-rwxr-xr-xCPP/7zip/UI/Far/FarUtils.cpp3
-rwxr-xr-xCPP/7zip/UI/Far/Main.cpp29
-rwxr-xr-xCPP/7zip/UI/Far/Plugin.cpp17
-rwxr-xr-xCPP/7zip/UI/Far/Plugin.h9
-rwxr-xr-xCPP/7zip/UI/Far/PluginDelete.cpp67
-rwxr-xr-xCPP/7zip/UI/Far/PluginRead.cpp8
-rwxr-xr-xCPP/7zip/UI/Far/PluginWrite.cpp209
-rwxr-xr-xCPP/7zip/UI/FileManager/App.cpp27
-rwxr-xr-xCPP/7zip/UI/FileManager/App.h2
-rwxr-xr-xCPP/7zip/UI/FileManager/BrowseDialog.cpp38
-rwxr-xr-xCPP/7zip/UI/FileManager/BrowseDialog.h6
-rwxr-xr-xCPP/7zip/UI/FileManager/ExtractCallback.cpp45
-rwxr-xr-xCPP/7zip/UI/FileManager/ExtractCallback.h1
-rwxr-xr-xCPP/7zip/UI/FileManager/FM.cpp35
-rwxr-xr-xCPP/7zip/UI/FileManager/FSDrives.cpp48
-rwxr-xr-xCPP/7zip/UI/FileManager/FSDrives.h8
-rwxr-xr-xCPP/7zip/UI/FileManager/FSFolder.cpp88
-rwxr-xr-xCPP/7zip/UI/FileManager/FSFolder.h26
-rwxr-xr-xCPP/7zip/UI/FileManager/FSFolderCopy.cpp157
-rwxr-xr-xCPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp39
-rwxr-xr-xCPP/7zip/UI/FileManager/FileFolderPluginOpen.h2
-rwxr-xr-xCPP/7zip/UI/FileManager/FilePlugins.cpp104
-rwxr-xr-xCPP/7zip/UI/FileManager/FilePlugins.h47
-rwxr-xr-xCPP/7zip/UI/FileManager/FoldersPage.cpp8
-rwxr-xr-xCPP/7zip/UI/FileManager/HelpUtils.cpp10
-rwxr-xr-xCPP/7zip/UI/FileManager/IFolder.h3
-rwxr-xr-xCPP/7zip/UI/FileManager/LangUtils.cpp51
-rwxr-xr-xCPP/7zip/UI/FileManager/LangUtils.h6
-rwxr-xr-xCPP/7zip/UI/FileManager/ListViewDialog.cpp7
-rwxr-xr-xCPP/7zip/UI/FileManager/MenuPage.cpp2
-rwxr-xr-xCPP/7zip/UI/FileManager/MessagesDialog.cpp5
-rwxr-xr-xCPP/7zip/UI/FileManager/MyLoadMenu.cpp31
-rwxr-xr-xCPP/7zip/UI/FileManager/NetFolder.cpp10
-rwxr-xr-xCPP/7zip/UI/FileManager/OpenCallback.cpp13
-rwxr-xr-xCPP/7zip/UI/FileManager/OpenCallback.h6
-rwxr-xr-xCPP/7zip/UI/FileManager/OptionsDialog.cpp10
-rwxr-xr-xCPP/7zip/UI/FileManager/Panel.cpp67
-rwxr-xr-xCPP/7zip/UI/FileManager/Panel.h47
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelCrc.cpp44
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelDrag.cpp28
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelFolderChange.cpp68
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelItemOpen.cpp323
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelItems.cpp11
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelListNotify.cpp18
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelMenu.cpp3
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelOperations.cpp28
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelSelect.cpp14
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelSort.cpp4
-rwxr-xr-xCPP/7zip/UI/FileManager/PanelSplitFile.cpp68
-rwxr-xr-xCPP/7zip/UI/FileManager/PasswordDialog.cpp23
-rwxr-xr-xCPP/7zip/UI/FileManager/PasswordDialog.h8
-rwxr-xr-xCPP/7zip/UI/FileManager/PluginLoader.h4
-rwxr-xr-xCPP/7zip/UI/FileManager/ProgramLocation.cpp21
-rwxr-xr-xCPP/7zip/UI/FileManager/ProgramLocation.h4
-rwxr-xr-xCPP/7zip/UI/FileManager/ProgressDialog2.cpp17
-rwxr-xr-xCPP/7zip/UI/FileManager/ProgressDialog2.h7
-rwxr-xr-xCPP/7zip/UI/FileManager/ProgressDialog2Res.h4
-rwxr-xr-xCPP/7zip/UI/FileManager/RegistryAssociations.cpp295
-rwxr-xr-xCPP/7zip/UI/FileManager/RegistryAssociations.h47
-rwxr-xr-xCPP/7zip/UI/FileManager/RegistryPlugins.cpp18
-rwxr-xr-xCPP/7zip/UI/FileManager/RegistryPlugins.h6
-rwxr-xr-xCPP/7zip/UI/FileManager/RootFolder.cpp8
-rwxr-xr-xCPP/7zip/UI/FileManager/SettingsPage.cpp1
-rwxr-xr-xCPP/7zip/UI/FileManager/SysIconUtils.cpp38
-rwxr-xr-xCPP/7zip/UI/FileManager/SysIconUtils.h5
-rwxr-xr-xCPP/7zip/UI/FileManager/SystemPage.cpp591
-rwxr-xr-xCPP/7zip/UI/FileManager/SystemPage.h108
-rwxr-xr-xCPP/7zip/UI/FileManager/SystemPage.rc17
-rwxr-xr-xCPP/7zip/UI/FileManager/SystemPageRes.h6
-rwxr-xr-xCPP/7zip/UI/FileManager/resource.h1
-rwxr-xr-xCPP/7zip/UI/FileManager/resource.rc3
-rwxr-xr-xCPP/7zip/UI/GUI/BenchmarkDialog.cpp188
-rwxr-xr-xCPP/7zip/UI/GUI/BenchmarkDialog.h34
-rwxr-xr-xCPP/7zip/UI/GUI/BenchmarkDialog.rc27
-rwxr-xr-xCPP/7zip/UI/GUI/BenchmarkDialogRes.h4
-rwxr-xr-xCPP/7zip/UI/GUI/CompressDialog.cpp6
-rwxr-xr-xCPP/7zip/UI/GUI/CompressDialog.h2
-rwxr-xr-xCPP/7zip/UI/GUI/CompressDialog.rc14
-rwxr-xr-xCPP/7zip/UI/GUI/ExtractDialog.cpp1
-rwxr-xr-xCPP/7zip/UI/GUI/ExtractDialog.rc13
-rwxr-xr-xCPP/7zip/UI/GUI/ExtractGUI.cpp11
-rwxr-xr-xCPP/7zip/UI/GUI/GUI.cpp5
-rwxr-xr-xCPP/7zip/UI/GUI/GUI.dsp8
-rwxr-xr-xCPP/7zip/UI/GUI/UpdateGUI.cpp27
-rwxr-xr-xCPP/7zip/UI/GUI/makefile3
-rwxr-xr-xCPP/Build.mak4
-rwxr-xr-xCPP/Common/C_FileIO.cpp6
-rwxr-xr-xCPP/Common/C_FileIO.h4
-rwxr-xr-xCPP/Common/Lang.cpp2
-rwxr-xr-xCPP/Common/Lang.h3
-rwxr-xr-xCPP/Common/ListFileUtils.cpp7
-rwxr-xr-xCPP/Common/ListFileUtils.h6
-rwxr-xr-xCPP/Common/MyString.cpp174
-rwxr-xr-xCPP/Common/MyString.h138
-rwxr-xr-xCPP/Common/MyWindows.cpp11
-rwxr-xr-xCPP/Common/MyWindows.h17
-rwxr-xr-xCPP/Common/StringToInt.cpp7
-rwxr-xr-xCPP/Common/StringToInt.h8
-rwxr-xr-xCPP/Common/Wildcard.cpp4
-rwxr-xr-xCPP/Windows/Control/Dialog.cpp15
-rwxr-xr-xCPP/Windows/Control/ListView.cpp59
-rwxr-xr-xCPP/Windows/Control/ListView.h29
-rwxr-xr-xCPP/Windows/Control/PropertyPage.cpp50
-rwxr-xr-xCPP/Windows/DLL.cpp129
-rwxr-xr-xCPP/Windows/DLL.h21
-rwxr-xr-xCPP/Windows/Error.cpp54
-rwxr-xr-xCPP/Windows/Error.h20
-rwxr-xr-xCPP/Windows/FileDir.cpp944
-rwxr-xr-xCPP/Windows/FileDir.h171
-rwxr-xr-xCPP/Windows/FileFind.cpp354
-rwxr-xr-xCPP/Windows/FileFind.h73
-rwxr-xr-xCPP/Windows/FileIO.cpp181
-rwxr-xr-xCPP/Windows/FileIO.h45
-rwxr-xr-xCPP/Windows/FileName.cpp35
-rwxr-xr-xCPP/Windows/FileName.h18
-rwxr-xr-xCPP/Windows/FileSystem.cpp145
-rwxr-xr-xCPP/Windows/FileSystem.h34
-rwxr-xr-xCPP/Windows/PropVariantUtils.cpp20
-rwxr-xr-xCPP/Windows/PropVariantUtils.h1
-rwxr-xr-xCPP/Windows/Time.cpp43
-rwxr-xr-xCPP/Windows/Time.h2
-rwxr-xr-xDOC/7zip.inf4
-rwxr-xr-xDOC/7zip.nsi25
-rwxr-xr-xDOC/7zip.wxs39
-rwxr-xr-xDOC/history.txt6
-rwxr-xr-xDOC/lzma.txt8
-rwxr-xr-xDOC/readme.txt2
322 files changed, 9881 insertions, 7651 deletions
diff --git a/C/7zCrc.c b/C/7zCrc.c
index a9208496..cd94201b 100755
--- a/C/7zCrc.c
+++ b/C/7zCrc.c
@@ -1,15 +1,24 @@
-/* 7zCrc.c -- CRC32 calculation
-2009-11-23 : Igor Pavlov : Public domain */
+/* 7zCrc.c -- CRC32 init
+2010-12-01 : Igor Pavlov : Public domain */
#include "7zCrc.h"
#include "CpuArch.h"
#define kCrcPoly 0xEDB88320
-#ifdef MY_CPU_LE
-#define CRC_NUM_TABLES 8
+#ifdef MY_CPU_X86_OR_AMD64
+ #define CRC_NUM_TABLES 8
+ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
+#elif defined(MY_CPU_LE)
+ #define CRC_NUM_TABLES 4
#else
-#define CRC_NUM_TABLES 1
+ #define CRC_NUM_TABLES 5
+ #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
+ UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
+#endif
+
+#ifndef MY_CPU_BE
+ UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
#endif
typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
@@ -17,25 +26,6 @@ typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size,
static CRC_FUNC g_CrcUpdate;
UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
-#if CRC_NUM_TABLES == 1
-
-#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
-
-static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
-{
- const Byte *p = (const Byte *)data;
- for (; size > 0; size--, p++)
- v = CRC_UPDATE_BYTE_2(v, *p);
- return v;
-}
-
-#else
-
-UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
-UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
-
-#endif
-
UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)
{
return g_CrcUpdate(v, data, size, g_CrcTable);
@@ -57,18 +47,37 @@ void MY_FAST_CALL CrcGenerateTable()
r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
g_CrcTable[i] = r;
}
- #if CRC_NUM_TABLES == 1
- g_CrcUpdate = CrcUpdateT1;
- #else
for (; i < 256 * CRC_NUM_TABLES; i++)
{
UInt32 r = g_CrcTable[i - 256];
g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
}
+
+ #ifdef MY_CPU_LE
+
g_CrcUpdate = CrcUpdateT4;
- #ifdef MY_CPU_X86_OR_AMD64
+
+ #if CRC_NUM_TABLES == 8
if (!CPU_Is_InOrder())
g_CrcUpdate = CrcUpdateT8;
#endif
+
+ #else
+ {
+ #ifndef MY_CPU_BE
+ UInt32 k = 1;
+ if (*(const Byte *)&k == 1)
+ g_CrcUpdate = CrcUpdateT4;
+ else
+ #endif
+ {
+ for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
+ {
+ UInt32 x = g_CrcTable[i - 256];
+ g_CrcTable[i] = CRC_UINT32_SWAP(x);
+ }
+ g_CrcUpdate = CrcUpdateT1_BeT4;
+ }
+ }
#endif
}
diff --git a/C/7zCrcOpt.c b/C/7zCrcOpt.c
index 6c766a20..a8d42a80 100755
--- a/C/7zCrcOpt.c
+++ b/C/7zCrcOpt.c
@@ -1,12 +1,12 @@
-/* 7zCrcOpt.c -- CRC32 calculation : optimized version
-2009-11-23 : Igor Pavlov : Public domain */
+/* 7zCrcOpt.c -- CRC32 calculation
+2010-12-01 : Igor Pavlov : Public domain */
#include "CpuArch.h"
-#ifdef MY_CPU_LE
-
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
+#ifndef MY_CPU_BE
+
UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
{
const Byte *p = (const Byte *)data;
@@ -32,3 +32,33 @@ UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const U
}
#endif
+
+
+#ifndef MY_CPU_LE
+
+#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
+
+UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
+{
+ const Byte *p = (const Byte *)data;
+ for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2(v, *p);
+ v = CRC_UINT32_SWAP(v);
+ table += 0x100;
+ for (; size >= 4; size -= 4, p += 4)
+ {
+ v ^= *(const UInt32 *)p;
+ v =
+ table[0x000 + (v & 0xFF)] ^
+ table[0x100 + ((v >> 8) & 0xFF)] ^
+ table[0x200 + ((v >> 16) & 0xFF)] ^
+ table[0x300 + ((v >> 24))];
+ }
+ table -= 0x100;
+ v = CRC_UINT32_SWAP(v);
+ for (; size > 0; size--, p++)
+ v = CRC_UPDATE_BYTE_2(v, *p);
+ return v;
+}
+
+#endif
diff --git a/C/7zVersion.h b/C/7zVersion.h
index 9d99c5df..9691d29f 100755
--- a/C/7zVersion.h
+++ b/C/7zVersion.h
@@ -1,7 +1,7 @@
#define MY_VER_MAJOR 9
-#define MY_VER_MINOR 20
-#define MY_VER_BUILD 0
-#define MY_VERSION "9.20"
-#define MY_DATE "2010-11-18"
+#define MY_VER_MINOR 21
+#define MY_VER_BUILD 00
+#define MY_VERSION "9.21 beta"
+#define MY_DATE "2011-04-11"
#define MY_COPYRIGHT ": Igor Pavlov : Public domain"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE
diff --git a/C/CpuArch.h b/C/CpuArch.h
index 01930c7e..e3d7af2e 100755
--- a/C/CpuArch.h
+++ b/C/CpuArch.h
@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code
-2010-10-26: Igor Pavlov : Public domain */
+2010-12-01: Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H
#define __CPU_ARCH_H
@@ -52,7 +52,7 @@ If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of pla
#define MY_CPU_LE
#endif
-#if defined(__BIG_ENDIAN__)
+#if defined(__BIG_ENDIAN__) || defined(__m68k__) || defined(__ARMEB__) || defined(__MIPSEB__)
#define MY_CPU_BE
#endif
diff --git a/C/Lzma2Dec.c b/C/Lzma2Dec.c
index 7ea1cc95..f3a6b821 100755
--- a/C/Lzma2Dec.c
+++ b/C/Lzma2Dec.c
@@ -1,5 +1,5 @@
/* Lzma2Dec.c -- LZMA2 Decoder
-2009-05-03 : Igor Pavlov : Public domain */
+2010-12-15 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */
@@ -330,27 +330,21 @@ SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc)
{
- CLzma2Dec decoder;
+ CLzma2Dec p;
SRes res;
SizeT outSize = *destLen, inSize = *srcLen;
- Byte props[LZMA_PROPS_SIZE];
-
- Lzma2Dec_Construct(&decoder);
-
*destLen = *srcLen = 0;
*status = LZMA_STATUS_NOT_SPECIFIED;
- decoder.decoder.dic = dest;
- decoder.decoder.dicBufSize = outSize;
-
- RINOK(Lzma2Dec_GetOldProps(prop, props));
- RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc));
-
+ Lzma2Dec_Construct(&p);
+ RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
+ p.decoder.dic = dest;
+ p.decoder.dicBufSize = outSize;
+ Lzma2Dec_Init(&p);
*srcLen = inSize;
- res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status);
- *destLen = decoder.decoder.dicPos;
+ res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
+ *destLen = p.decoder.dicPos;
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
res = SZ_ERROR_INPUT_EOF;
-
- LzmaDec_FreeProbs(&decoder.decoder, alloc);
+ Lzma2Dec_FreeProbs(&p, alloc);
return res;
}
diff --git a/C/LzmaDec.c b/C/LzmaDec.c
index 2036761b..8c1a1486 100755
--- a/C/LzmaDec.c
+++ b/C/LzmaDec.c
@@ -1,5 +1,5 @@
/* LzmaDec.c -- LZMA Decoder
-2009-09-20 : Igor Pavlov : Public domain */
+2010-12-15 : Igor Pavlov : Public domain */
#include "LzmaDec.h"
@@ -442,8 +442,9 @@ static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
p->processedPos += len;
p->remainLen -= len;
- while (len-- != 0)
+ while (len != 0)
{
+ len--;
dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
dicPos++;
}
@@ -972,28 +973,21 @@ SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
{
CLzmaDec p;
SRes res;
- SizeT inSize = *srcLen;
- SizeT outSize = *destLen;
- *srcLen = *destLen = 0;
+ SizeT outSize = *destLen, inSize = *srcLen;
+ *destLen = *srcLen = 0;
+ *status = LZMA_STATUS_NOT_SPECIFIED;
if (inSize < RC_INIT_SIZE)
return SZ_ERROR_INPUT_EOF;
-
LzmaDec_Construct(&p);
- res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
- if (res != 0)
- return res;
+ RINOK(LzmaDec_AllocateProbs(&p, propData, propSize, alloc));
p.dic = dest;
p.dicBufSize = outSize;
-
LzmaDec_Init(&p);
-
*srcLen = inSize;
res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
-
+ *destLen = p.dicPos;
if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
res = SZ_ERROR_INPUT_EOF;
-
- (*destLen) = p.dicPos;
LzmaDec_FreeProbs(&p, alloc);
return res;
}
diff --git a/C/LzmaEnc.c b/C/LzmaEnc.c
index cf131388..ef26e0cf 100755
--- a/C/LzmaEnc.c
+++ b/C/LzmaEnc.c
@@ -1,5 +1,5 @@
/* LzmaEnc.c -- LZMA Encoder
-2010-04-16 : Igor Pavlov : Public domain */
+2011-01-27 : Igor Pavlov : Public domain */
#include <string.h>
@@ -46,6 +46,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p)
{
p->level = 5;
p->dictSize = p->mc = 0;
+ p->reduceSize = (UInt32)(Int32)-1;
p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
p->writeEndMark = 0;
}
@@ -56,6 +57,15 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p)
if (level < 0) level = 5;
p->level = level;
if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
+ if (p->dictSize > p->reduceSize)
+ {
+ unsigned i;
+ for (i = 15; i <= 30; i++)
+ {
+ if (p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; }
+ if (p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; }
+ }
+ }
if (p->lc < 0) p->lc = 3;
if (p->lp < 0) p->lp = 0;
if (p->pb < 0) p->pb = 2;
@@ -329,7 +339,6 @@ typedef struct
SRes result;
UInt32 dictSize;
- UInt32 matchFinderCycles;
int needInit;
@@ -398,7 +407,6 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30))
return SZ_ERROR_PARAM;
p->dictSize = props.dictSize;
- p->matchFinderCycles = props.mc;
{
unsigned fb = props.fb;
if (fb < 5)
diff --git a/C/LzmaEnc.h b/C/LzmaEnc.h
index 200d60eb..b8d9ce77 100755
--- a/C/LzmaEnc.h
+++ b/C/LzmaEnc.h
@@ -1,14 +1,12 @@
/* LzmaEnc.h -- LZMA Encoder
-2009-02-07 : Igor Pavlov : Public domain */
+2011-01-27 : Igor Pavlov : Public domain */
#ifndef __LZMA_ENC_H
#define __LZMA_ENC_H
#include "Types.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
#define LZMA_PROPS_SIZE 5
@@ -18,6 +16,8 @@ typedef struct _CLzmaEncProps
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
(1 << 12) <= dictSize <= (1 << 30) for 64-bit version
default = (1 << 24) */
+ UInt32 reduceSize; /* estimated size of data that will be compressed. default = 0xFFFFFFFF.
+ Encoder uses this value to reduce dictionary size */
int lc; /* 0 <= lc <= 8, default = 3 */
int lp; /* 0 <= lp <= 4, default = 0 */
int pb; /* 0 <= pb <= 4, default = 2 */
@@ -73,8 +73,6 @@ SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/C/Ppmd.h b/C/Ppmd.h
index 72a1cc52..9cbc4664 100755
--- a/C/Ppmd.h
+++ b/C/Ppmd.h
@@ -1,5 +1,5 @@
/* Ppmd.h -- PPMD codec common code
-2010-03-12 : Igor Pavlov : Public domain
+2011-01-27 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef __PPMD_H
@@ -29,6 +29,9 @@ EXTERN_C_BEGIN
#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
+#pragma pack(push, 1)
+/* Most compilers works OK here even without #pragma pack(push, 1), but some GCC compilers need it. */
+
/* SEE-contexts for PPM-contexts with masked symbols */
typedef struct
{
@@ -48,6 +51,8 @@ typedef struct
UInt16 SuccessorHigh;
} CPpmd_State;
+#pragma pack(pop)
+
typedef
#ifdef PPMD_32BIT
CPpmd_State *
diff --git a/C/Ppmd8.h b/C/Ppmd8.h
index 870dc9dd..7dcfc916 100755
--- a/C/Ppmd8.h
+++ b/C/Ppmd8.h
@@ -1,5 +1,5 @@
/* Ppmd8.h -- PPMdI codec
-2010-03-24 : Igor Pavlov : Public domain
+2011-01-27 : Igor Pavlov : Public domain
This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
@@ -24,6 +24,8 @@ typedef
#endif
CPpmd8_Context_Ref;
+#pragma pack(push, 1)
+
typedef struct CPpmd8_Context_
{
Byte NumStats;
@@ -33,6 +35,8 @@ typedef struct CPpmd8_Context_
CPpmd8_Context_Ref Suffix;
} CPpmd8_Context;
+#pragma pack(pop)
+
#define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->SummFreq)
/* The BUG in Shkarin's code for FREEZE mode was fixed, but that fixed
diff --git a/C/Util/SfxSetup/SfxSetup.c b/C/Util/SfxSetup/SfxSetup.c
index a15d7729..a8e3f587 100755
--- a/C/Util/SfxSetup/SfxSetup.c
+++ b/C/Util/SfxSetup/SfxSetup.c
@@ -1,5 +1,5 @@
/* SfxSetup.c - 7z SFX Setup
-2010-11-11 : Igor Pavlov : Public domain */
+2010-12-13 : Igor Pavlov : Public domain */
#ifndef UNICODE
#define UNICODE
@@ -128,26 +128,21 @@ static Bool FindSignature(CSzFile *stream, UInt64 *resPos)
*resPos = 0;
for (;;)
{
- size_t numTests, pos;
+ size_t processed, pos;
if (*resPos > kSignatureSearchLimit)
return False;
-
- do
- {
- size_t processed = kBufferSize - numPrevBytes;
- if (File_Read(stream, buf + numPrevBytes, &processed) != 0)
- return False;
- if (processed == 0)
- return False;
- numPrevBytes += processed;
- }
- while (numPrevBytes <= k7zStartHeaderSize);
-
- numTests = numPrevBytes - k7zStartHeaderSize;
- for (pos = 0; pos < numTests; pos++)
+ processed = kBufferSize - numPrevBytes;
+ if (File_Read(stream, buf + numPrevBytes, &processed) != 0)
+ return False;
+ processed += numPrevBytes;
+ if (processed < k7zStartHeaderSize ||
+ (processed == k7zStartHeaderSize && numPrevBytes != 0))
+ return False;
+ processed -= k7zStartHeaderSize;
+ for (pos = 0; pos <= processed; pos++)
{
- for (; buf[pos] != '7' && pos < numTests; pos++);
- if (pos == numTests)
+ for (; buf[pos] != '7' && pos <= processed; pos++);
+ if (pos > processed)
break;
if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0)
if (CrcCalc(buf + pos + 12, 20) == GetUi32(buf + pos + 8))
@@ -156,9 +151,9 @@ static Bool FindSignature(CSzFile *stream, UInt64 *resPos)
return True;
}
}
- *resPos += numTests;
- numPrevBytes -= numTests;
- memmove(buf, buf + numTests, numPrevBytes);
+ *resPos += processed;
+ numPrevBytes = k7zStartHeaderSize;
+ memmove(buf, buf + processed, k7zStartHeaderSize);
}
}
diff --git a/C/Util/SfxSetup/makefile b/C/Util/SfxSetup/makefile
index f3f78c81..ce1fbc9d 100755
--- a/C/Util/SfxSetup/makefile
+++ b/C/Util/SfxSetup/makefile
@@ -1,6 +1,6 @@
PROG = 7zS2.sfx
LIBS = $(LIBS)
-CFLAGS = $(CFLAGS) -DUNICODE -D_UNICODE
+CFLAGS = $(CFLAGS) -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_WARNINGS
C_OBJS = \
$O\7zAlloc.obj \
diff --git a/C/Xz.h b/C/Xz.h
index 2cfa1b78..0f7a822c 100755
--- a/C/Xz.h
+++ b/C/Xz.h
@@ -1,5 +1,5 @@
/* Xz.h - Xz interface
-2010-09-17 : Igor Pavlov : Public domain */
+2011-01-09 : Igor Pavlov : Public domain */
#ifndef __XZ_H
#define __XZ_H
@@ -220,7 +220,8 @@ typedef struct
Byte buf[XZ_BLOCK_HEADER_SIZE_MAX];
} CXzUnpacker;
-SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc);
+void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc);
+void XzUnpacker_Init(CXzUnpacker *p);
void XzUnpacker_Free(CXzUnpacker *p);
/*
@@ -232,8 +233,9 @@ finishMode:
Returns:
SZ_OK
status:
- LZMA_STATUS_FINISHED_WITH_MARK
- LZMA_STATUS_NOT_FINISHED
+ CODER_STATUS_NOT_FINISHED,
+ CODER_STATUS_NEEDS_MORE_INPUT - maybe there are more xz streams,
+ call XzUnpacker_IsStreamWasFinished to check that current stream was finished
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
diff --git a/C/XzDec.c b/C/XzDec.c
index 40f1a2a4..113e2cdf 100755
--- a/C/XzDec.c
+++ b/C/XzDec.c
@@ -1,5 +1,5 @@
/* XzDec.c -- Xz Decode
-2010-04-16 : Igor Pavlov : Public domain */
+2011-02-07 : Igor Pavlov : Public domain */
/* #define XZ_DUMP */
@@ -18,7 +18,8 @@
#include "Lzma2Dec.h"
#ifdef USE_SUBBLOCK
-#include "SbDec.h"
+#include "Bcj3Dec.c"
+#include "SbDec.c"
#endif
#include "Xz.h"
@@ -72,7 +73,6 @@ SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *a
{
CBraState *p = ((CBraState *)pp);
alloc = alloc;
- p->encodeMode = 0;
p->ip = 0;
if (p->methodId == XZ_ID_Delta)
{
@@ -195,7 +195,7 @@ static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
return SZ_OK;
}
-SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc)
+SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc)
{
CBraState *decoder;
if (id != XZ_ID_Delta &&
@@ -211,6 +211,7 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc)
if (decoder == 0)
return SZ_ERROR_MEM;
decoder->methodId = (UInt32)id;
+ decoder->encodeMode = encodeMode;
p->p = decoder;
p->Free = BraState_Free;
p->SetProps = BraState_SetProps;
@@ -225,8 +226,8 @@ SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc)
static void SbState_Free(void *pp, ISzAlloc *alloc)
{
- CSubblockDec *p = (CSubblockDec *)pp;
- SubblockDec_Free(p, alloc);
+ CSbDec *p = (CSbDec *)pp;
+ SbDec_Free(p);
alloc->Free(alloc, pp);
}
@@ -240,24 +241,32 @@ static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAl
static void SbState_Init(void *pp)
{
- SubblockDec_Init((CSubblockDec *)pp);
+ SbDec_Init((CSbDec *)pp);
}
static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
{
- ECoderStatus status;
- SRes res = SubblockDec_Decode((CSubblockDec *)pp, dest, destLen, src, srcLen, finishMode, &status);
+ CSbDec *p = (CSbDec *)pp;
+ SRes res;
srcWasFinished = srcWasFinished;
- *wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
+ p->dest = dest;
+ p->destLen = *destLen;
+ p->src = src;
+ p->srcLen = *srcLen;
+ p->finish = finishMode; /* change it */
+ res = SbDec_Decode((CSbDec *)pp);
+ *destLen -= p->destLen;
+ *srcLen -= p->srcLen;
+ *wasFinished = (*destLen == 0 && *srcLen == 0); /* change it */
return res;
}
SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
{
- CSubblockDec *decoder;
+ CSbDec *decoder;
p->p = 0;
- decoder = alloc->Alloc(alloc, sizeof(CSubblockDec));
+ decoder = alloc->Alloc(alloc, sizeof(CSbDec));
if (decoder == 0)
return SZ_ERROR_MEM;
p->p = decoder;
@@ -265,7 +274,8 @@ SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
p->SetProps = SbState_SetProps;
p->Init = SbState_Init;
p->Code = SbState_Code;
- SubblockDec_Construct(decoder);
+ SbDec_Construct(decoder);
+ SbDec_SetAlloc(decoder, alloc);
return SZ_OK;
}
#endif
@@ -369,7 +379,7 @@ SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId)
}
if (coderIndex == 0)
return SZ_ERROR_UNSUPPORTED;
- return BraState_SetFromMethod(sc, methodId, p->alloc);
+ return BraState_SetFromMethod(sc, methodId, 0, p->alloc);
}
SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
@@ -587,13 +597,17 @@ SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
return SZ_OK;
}
-SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc)
+void XzUnpacker_Init(CXzUnpacker *p)
{
- MixCoder_Construct(&p->decoder, alloc);
p->state = XZ_STATE_STREAM_HEADER;
p->pos = 0;
p->numStreams = 0;
- return SZ_OK;
+}
+
+void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc)
+{
+ MixCoder_Construct(&p->decoder, alloc);
+ XzUnpacker_Init(p);
}
void XzUnpacker_Free(CXzUnpacker *p)
diff --git a/C/XzEnc.c b/C/XzEnc.c
index 721b4e76..56cfd579 100755
--- a/C/XzEnc.c
+++ b/C/XzEnc.c
@@ -1,5 +1,5 @@
/* XzEnc.c -- Xz Encode
-2009-06-04 : Igor Pavlov : Public domain */
+2011-02-07 : Igor Pavlov : Public domain */
#include <stdlib.h>
#include <string.h>
@@ -9,7 +9,9 @@
#include "Bra.h"
#include "CpuArch.h"
#ifdef USE_SUBBLOCK
-#include "SbEnc.h"
+#include "Bcj3Enc.c"
+#include "SbFind.c"
+#include "SbEnc.c"
#endif
#include "XzEnc.h"
@@ -198,158 +200,147 @@ static size_t MyWrite(void *pp, const void *data, size_t size)
/* ---------- CSeqInFilter ---------- */
-/*
-typedef struct _IFilter
-{
- void *p;
- void (*Free)(void *p, ISzAlloc *alloc);
- SRes (*SetProps)(void *p, const Byte *props, size_t propSize, ISzAlloc *alloc);
- void (*Init)(void *p);
- size_t (*Filter)(void *p, Byte *data, SizeT destLen);
-} IFilter;
-
-#define FILT_BUF_SIZE (1 << 19)
+#define FILTER_BUF_SIZE (1 << 20)
typedef struct
{
ISeqInStream p;
ISeqInStream *realStream;
- UInt32 x86State;
- UInt32 ip;
- UInt64 processed;
- CXzCheck check;
- Byte buf[FILT_BUF_SIZE];
- UInt32 bufferPos;
- UInt32 convertedPosBegin;
- UInt32 convertedPosEnd;
- IFilter *filter;
+ IStateCoder StateCoder;
+ Byte *buf;
+ size_t curPos;
+ size_t endPos;
+ int srcWasFinished;
} CSeqInFilter;
static SRes SeqInFilter_Read(void *pp, void *data, size_t *size)
{
CSeqInFilter *p = (CSeqInFilter *)pp;
- size_t remSize = *size;
+ size_t sizeOriginal = *size;
+ if (sizeOriginal == 0)
+ return S_OK;
*size = 0;
-
- while (remSize > 0)
+ for (;;)
{
- int i;
- if (p->convertedPosBegin != p->convertedPosEnd)
- {
- UInt32 sizeTemp = p->convertedPosEnd - p->convertedPosBegin;
- if (remSize < sizeTemp)
- sizeTemp = (UInt32)remSize;
- memmove(data, p->buf + p->convertedPosBegin, sizeTemp);
- p->convertedPosBegin += sizeTemp;
- data = (void *)((Byte *)data + sizeTemp);
- remSize -= sizeTemp;
- *size += sizeTemp;
- break;
- }
- for (i = 0; p->convertedPosEnd + i < p->bufferPos; i++)
- p->buf[i] = p->buf[i + p->convertedPosEnd];
- p->bufferPos = i;
- p->convertedPosBegin = p->convertedPosEnd = 0;
- {
- size_t processedSizeTemp = FILT_BUF_SIZE - p->bufferPos;
- RINOK(p->realStream->Read(p->realStream, p->buf + p->bufferPos, &processedSizeTemp));
- p->bufferPos = p->bufferPos + (UInt32)processedSizeTemp;
- }
- p->convertedPosEnd = (UInt32)p->filter->Filter(p->filter->p, p->buf, p->bufferPos);
- if (p->convertedPosEnd == 0)
+ if (!p->srcWasFinished && p->curPos == p->endPos)
{
- if (p->bufferPos == 0)
- break;
- else
- {
- p->convertedPosEnd = p->bufferPos;
- continue;
- }
+ p->curPos = 0;
+ p->endPos = FILTER_BUF_SIZE;
+ RINOK(p->realStream->Read(p->realStream, p->buf, &p->endPos));
+ if (p->endPos == 0)
+ p->srcWasFinished = 1;
}
- if (p->convertedPosEnd > p->bufferPos)
{
- for (; p->bufferPos < p->convertedPosEnd; p->bufferPos++)
- p->buf[p->bufferPos] = 0;
- p->convertedPosEnd = (UInt32)p->filter->Filter(p->filter->p, p->buf, p->bufferPos);
+ SizeT srcLen = p->endPos - p->curPos;
+ int wasFinished;
+ SRes res;
+ *size = sizeOriginal;
+ res = p->StateCoder.Code(p->StateCoder.p, data, size, p->buf + p->curPos, &srcLen,
+ p->srcWasFinished, CODER_FINISH_ANY, &wasFinished);
+ p->curPos += srcLen;
+ if (*size != 0 || srcLen == 0 || res != 0)
+ return res;
}
}
- return SZ_OK;
}
-*/
-/*
-typedef struct
+static void SeqInFilter_Construct(CSeqInFilter *p)
{
- ISeqInStream p;
- ISeqInStream *realStream;
- CMixCoder mixCoder;
- Byte buf[FILT_BUF_SIZE];
- UInt32 bufPos;
- UInt32 bufSize;
-} CMixCoderSeqInStream;
+ p->buf = NULL;
+ p->p.Read = SeqInFilter_Read;
+}
-static SRes CMixCoderSeqInStream_Read(void *pp, void *data, size_t *size)
+static void SeqInFilter_Free(CSeqInFilter *p)
{
- CMixCoderSeqInStream *p = (CMixCoderSeqInStream *)pp;
- SRes res = SZ_OK;
- size_t remSize = *size;
- *size = 0;
- while (remSize > 0)
+ if (p->buf)
{
- if (p->bufPos == p->bufSize)
- {
- size_t curSize;
- p->bufPos = p->bufSize = 0;
- if (*size != 0)
- break;
- curSize = FILT_BUF_SIZE;
- RINOK(p->realStream->Read(p->realStream, p->buf, &curSize));
- p->bufSize = (UInt32)curSize;
- }
- {
- SizeT destLen = remSize;
- SizeT srcLen = p->bufSize - p->bufPos;
- res = MixCoder_Code(&p->mixCoder, data, &destLen, p->buf + p->bufPos, &srcLen, 0);
- data = (void *)((Byte *)data + destLen);
- remSize -= destLen;
- *size += destLen;
- p->bufPos += srcLen;
- }
+ g_Alloc.Free(&g_Alloc, p->buf);
+ p->buf = NULL;
}
- return res;
}
-*/
+
+SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc);
+
+static SRes SeqInFilter_Init(CSeqInFilter *p, const CXzFilter *props)
+{
+ if (!p->buf)
+ {
+ p->buf = g_Alloc.Alloc(&g_Alloc, FILTER_BUF_SIZE);
+ if (!p->buf)
+ return SZ_ERROR_MEM;
+ }
+ p->curPos = p->endPos = 0;
+ p->srcWasFinished = 0;
+ RINOK(BraState_SetFromMethod(&p->StateCoder, props->id, 1, &g_Alloc));
+ RINOK(p->StateCoder.SetProps(p->StateCoder.p, props->props, props->propsSize, &g_Alloc));
+ p->StateCoder.Init(p->StateCoder.p);
+ return S_OK;
+}
+
+/* ---------- CSbEncInStream ---------- */
#ifdef USE_SUBBLOCK
+
typedef struct
{
ISeqInStream p;
- CSubblockEnc sb;
- UInt64 processed;
+ ISeqInStream *inStream;
+ CSbEnc enc;
} CSbEncInStream;
-void SbEncInStream_Init(CSbEncInStream *p)
+static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
{
- p->processed = 0;
- SubblockEnc_Init(&p->sb);
+ CSbEncInStream *p = (CSbEncInStream *)pp;
+ size_t sizeOriginal = *size;
+ if (sizeOriginal == 0)
+ return S_OK;
+ for (;;)
+ {
+ if (p->enc.needRead && !p->enc.readWasFinished)
+ {
+ size_t processed = p->enc.needReadSizeMax;
+ RINOK(p->inStream->Read(p->inStream, p->enc.buf + p->enc.readPos, &processed));
+ p->enc.readPos += processed;
+ if (processed == 0)
+ {
+ p->enc.readWasFinished = True;
+ p->enc.isFinalFinished = True;
+ }
+ p->enc.needRead = False;
+ }
+ *size = sizeOriginal;
+ RINOK(SbEnc_Read(&p->enc, data, size));
+ if (*size != 0 || !p->enc.needRead)
+ return S_OK;
+ }
}
-static SRes SbEncInStream_Read(void *pp, void *data, size_t *size)
+void SbEncInStream_Construct(CSbEncInStream *p, ISzAlloc *alloc)
{
- CSbEncInStream *p = (CSbEncInStream *)pp;
- SRes res = SubblockEnc_Read(&p->sb, data, size);
- p->processed += *size;
- return res;
+ SbEnc_Construct(&p->enc, alloc);
+ p->p.Read = SbEncInStream_Read;
}
+
+SRes SbEncInStream_Init(CSbEncInStream *p)
+{
+ return SbEnc_Init(&p->enc);
+}
+
+void SbEncInStream_Free(CSbEncInStream *p)
+{
+ SbEnc_Free(&p->enc);
+}
+
#endif
+
typedef struct
{
- /* CMixCoderSeqInStream inStream; */
CLzma2EncHandle lzma2;
#ifdef USE_SUBBLOCK
CSbEncInStream sb;
#endif
+ CSeqInFilter filter;
ISzAlloc *alloc;
ISzAlloc *bigAlloc;
} CLzma2WithFilters;
@@ -361,9 +352,9 @@ static void Lzma2WithFilters_Construct(CLzma2WithFilters *p, ISzAlloc *alloc, IS
p->bigAlloc = bigAlloc;
p->lzma2 = NULL;
#ifdef USE_SUBBLOCK
- p->sb.p.Read = SbEncInStream_Read;
- SubblockEnc_Construct(&p->sb.sb, p->alloc);
+ SbEncInStream_Construct(&p->sb, alloc);
#endif
+ SeqInFilter_Construct(&p->filter);
}
static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p)
@@ -376,8 +367,9 @@ static SRes Lzma2WithFilters_Create(CLzma2WithFilters *p)
static void Lzma2WithFilters_Free(CLzma2WithFilters *p)
{
+ SeqInFilter_Free(&p->filter);
#ifdef USE_SUBBLOCK
- SubblockEnc_Free(&p->sb.sb);
+ SbEncInStream_Free(&p->sb);
#endif
if (p->lzma2)
{
@@ -386,17 +378,28 @@ static void Lzma2WithFilters_Free(CLzma2WithFilters *p)
}
}
-static SRes Xz_Compress(CXzStream *xz,
- CLzma2WithFilters *lzmaf,
- ISeqOutStream *outStream,
- ISeqInStream *inStream,
- const CLzma2EncProps *lzma2Props,
- Bool useSubblock,
- ICompressProgress *progress)
+void XzProps_Init(CXzProps *p)
{
- xz->flags = XZ_CHECK_CRC32;
+ p->lzma2Props = 0;
+ p->filterProps = 0;
+ p->checkId = XZ_CHECK_CRC32;
+}
- RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, lzma2Props));
+void XzFilterProps_Init(CXzFilterProps *p)
+{
+ p->id = 0;
+ p->delta = 0;
+ p->ip= 0;
+ p->ipDefined = False;
+}
+
+static SRes Xz_Compress(CXzStream *xz, CLzma2WithFilters *lzmaf,
+ ISeqOutStream *outStream, ISeqInStream *inStream,
+ const CXzProps *props, ICompressProgress *progress)
+{
+ xz->flags = (Byte)props->checkId;
+
+ RINOK(Lzma2Enc_SetProps(lzmaf->lzma2, props->lzma2Props));
RINOK(Xz_WriteHeader(xz->flags, outStream));
{
@@ -404,15 +407,27 @@ static SRes Xz_Compress(CXzStream *xz,
CSeqSizeOutStream seqSizeOutStream;
CXzBlock block;
int filterIndex = 0;
+ CXzFilter *filter = NULL;
+ const CXzFilterProps *fp = props->filterProps;
XzBlock_ClearFlags(&block);
- XzBlock_SetNumFilters(&block, 1 + (useSubblock ? 1 : 0));
+ XzBlock_SetNumFilters(&block, 1 + (fp ? 1 : 0));
- if (useSubblock)
+ if (fp)
{
- CXzFilter *f = &block.filters[filterIndex++];
- f->id = XZ_ID_Subblock;
- f->propsSize = 0;
+ filter = &block.filters[filterIndex++];
+ filter->id = fp->id;
+ filter->propsSize = 0;
+ if (fp->id == XZ_ID_Delta)
+ {
+ filter->props[0] = (Byte)(fp->delta - 1);
+ filter->propsSize = 1;
+ }
+ else if (fp->ipDefined)
+ {
+ SetUi32(filter->props, fp->ip);
+ filter->propsSize = 4;
+ }
}
{
@@ -432,20 +447,30 @@ static SRes Xz_Compress(CXzStream *xz,
checkInStream.realStream = inStream;
SeqCheckInStream_Init(&checkInStream, XzFlags_GetCheckType(xz->flags));
- #ifdef USE_SUBBLOCK
- if (useSubblock)
+ if (fp)
{
- lzmaf->sb.sb.inStream = &checkInStream.p;
- SubblockEnc_Init(&lzmaf->sb.sb);
+ #ifdef USE_SUBBLOCK
+ if (fp->id == XZ_ID_Subblock)
+ {
+ lzmaf->sb.inStream = &checkInStream.p;
+ RINOK(SbEncInStream_Init(&lzmaf->sb));
+ }
+ else
+ #endif
+ {
+ lzmaf->filter.realStream = &checkInStream.p;
+ RINOK(SeqInFilter_Init(&lzmaf->filter, filter));
+ }
}
- #endif
-
+
{
UInt64 packPos = seqSizeOutStream.processed;
SRes res = Lzma2Enc_Encode(lzmaf->lzma2, &seqSizeOutStream.p,
+ fp ?
#ifdef USE_SUBBLOCK
- useSubblock ? &lzmaf->sb.p:
+ (fp->id == XZ_ID_Subblock) ? &lzmaf->sb.p:
#endif
+ &lzmaf->filter.p:
&checkInStream.p,
progress);
RINOK(res);
@@ -467,8 +492,7 @@ static SRes Xz_Compress(CXzStream *xz,
}
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
- const CLzma2EncProps *lzma2Props, Bool useSubblock,
- ICompressProgress *progress)
+ const CXzProps *props, ICompressProgress *progress)
{
SRes res;
CXzStream xz;
@@ -477,8 +501,7 @@ SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
Lzma2WithFilters_Construct(&lzmaf, &g_Alloc, &g_BigAlloc);
res = Lzma2WithFilters_Create(&lzmaf);
if (res == SZ_OK)
- res = Xz_Compress(&xz, &lzmaf, outStream, inStream,
- lzma2Props, useSubblock, progress);
+ res = Xz_Compress(&xz, &lzmaf, outStream, inStream, props, progress);
Lzma2WithFilters_Free(&lzmaf);
Xz_Free(&xz, &g_Alloc);
return res;
diff --git a/C/XzEnc.h b/C/XzEnc.h
index 13390df8..c3c19eca 100755
--- a/C/XzEnc.h
+++ b/C/XzEnc.h
@@ -1,5 +1,5 @@
/* XzEnc.h -- Xz Encode
-2009-04-15 : Igor Pavlov : Public domain */
+2011-02-07 : Igor Pavlov : Public domain */
#ifndef __XZ_ENC_H
#define __XZ_ENC_H
@@ -8,18 +8,32 @@
#include "Xz.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+EXTERN_C_BEGIN
+
+typedef struct
+{
+ UInt32 id;
+ UInt32 delta;
+ UInt32 ip;
+ int ipDefined;
+} CXzFilterProps;
+
+void XzFilterProps_Init(CXzFilterProps *p);
+
+typedef struct
+{
+ const CLzma2EncProps *lzma2Props;
+ const CXzFilterProps *filterProps;
+ unsigned checkId;
+} CXzProps;
+
+void XzProps_Init(CXzProps *p);
SRes Xz_Encode(ISeqOutStream *outStream, ISeqInStream *inStream,
- const CLzma2EncProps *lzma2Props, Bool useSubblock,
- ICompressProgress *progress);
+ const CXzProps *props, ICompressProgress *progress);
SRes Xz_EncodeEmpty(ISeqOutStream *outStream);
-#ifdef __cplusplus
-}
-#endif
+EXTERN_C_END
#endif
diff --git a/C/XzIn.c b/C/XzIn.c
index 7f0f6af8..4ba87a2c 100755
--- a/C/XzIn.c
+++ b/C/XzIn.c
@@ -1,5 +1,5 @@
/* XzIn.c - Xz input
-2009-06-19 : Igor Pavlov : Public domain */
+2011-02-01 : Igor Pavlov : Public domain */
#include <string.h>
@@ -152,39 +152,38 @@ static SRes Xz_ReadBackward(CXzStream *p, ILookInStream *stream, Int64 *startOff
if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
{
- Int64 i = 0;
+ UInt32 total = 0;
*startOffset += XZ_STREAM_FOOTER_SIZE;
for (;;)
{
- int j;
- size_t processedSize;
+ size_t i;
#define TEMP_BUF_SIZE (1 << 10)
Byte tempBuf[TEMP_BUF_SIZE];
- if (*startOffset < XZ_STREAM_FOOTER_SIZE || i > (1 << 16))
+ if (*startOffset < XZ_STREAM_FOOTER_SIZE || total > (1 << 16))
return SZ_ERROR_NO_ARCHIVE;
- processedSize = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset;
- i += processedSize;
- *startOffset = -(Int64)processedSize;
+ i = (*startOffset > TEMP_BUF_SIZE) ? TEMP_BUF_SIZE : (size_t)*startOffset;
+ total += (UInt32)i;
+ *startOffset = -(Int64)i;
RINOK(SeekFromCur(stream, startOffset));
- RINOK(LookInStream_Read2(stream, tempBuf, processedSize, SZ_ERROR_NO_ARCHIVE));
- for (j = (int)processedSize; j >= 0; j--)
- if (tempBuf[j -1] != 0)
+ RINOK(LookInStream_Read2(stream, tempBuf, i, SZ_ERROR_NO_ARCHIVE));
+ for (; i != 0; i--)
+ if (tempBuf[i - 1] != 0)
break;
- if (j != 0)
+ if (i != 0)
{
- if ((j & 3) != 0)
- return SZ_ERROR_NO_ARCHIVE;
- *startOffset += j;
- if (*startOffset < XZ_STREAM_FOOTER_SIZE)
- return SZ_ERROR_NO_ARCHIVE;
- *startOffset -= XZ_STREAM_FOOTER_SIZE;
- RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));
- RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
- if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
+ if ((i & 3) != 0)
return SZ_ERROR_NO_ARCHIVE;
+ *startOffset += i;
break;
}
}
+ if (*startOffset < XZ_STREAM_FOOTER_SIZE)
+ return SZ_ERROR_NO_ARCHIVE;
+ *startOffset -= XZ_STREAM_FOOTER_SIZE;
+ RINOK(stream->Seek(stream, startOffset, SZ_SEEK_SET));
+ RINOK(LookInStream_Read2(stream, buf, XZ_STREAM_FOOTER_SIZE, SZ_ERROR_NO_ARCHIVE));
+ if (memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) != 0)
+ return SZ_ERROR_NO_ARCHIVE;
}
p->flags = (CXzStreamFlags)GetBe16(buf + 8);
diff --git a/CPP/7zip/Archive/7z/7zCompressionMode.h b/CPP/7zip/Archive/7z/7zCompressionMode.h
index 55bbc68e..5cde97c3 100755
--- a/CPP/7zip/Archive/7z/7zCompressionMode.h
+++ b/CPP/7zip/Archive/7z/7zCompressionMode.h
@@ -3,19 +3,18 @@
#ifndef __7Z_COMPRESSION_MODE_H
#define __7Z_COMPRESSION_MODE_H
-#include "../../../Common/MyString.h"
-
-#include "../../../Windows/PropVariant.h"
-
+#include "../../Common/MethodId.h"
#include "../../Common/MethodProps.h"
namespace NArchive {
namespace N7z {
-struct CMethodFull: public CMethod
+struct CMethodFull: public CProps
{
+ CMethodId Id;
UInt32 NumInStreams;
UInt32 NumOutStreams;
+
bool IsSimpleCoder() const { return (NumInStreams == 1) && (NumOutStreams == 1); }
};
diff --git a/CPP/7zip/Archive/7z/7zEncode.cpp b/CPP/7zip/Archive/7z/7zEncode.cpp
index 87996bc0..614f9913 100755
--- a/CPP/7zip/Archive/7z/7zEncode.cpp
+++ b/CPP/7zip/Archive/7z/7zEncode.cpp
@@ -49,6 +49,15 @@ static void ConvertBindInfoToFolderItemInfo(const NCoderMixer::CBindInfo &bindIn
folder.PackStreams.Add(bindInfo.InStreams[i]);
}
+static HRESULT SetCoderProps2(const CProps &props, const UInt64 *dataSizeReduce, IUnknown *coder)
+{
+ CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
+ coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
+ if (setCoderProperties)
+ return props.SetCoderProps(setCoderProperties, dataSizeReduce);
+ return props.AreThereNonOptionalProps() ? E_INVALIDARG : S_OK;
+}
+
HRESULT CEncoder::CreateMixerCoder(
DECL_EXTERNAL_CODECS_LOC_VARS
const UInt64 *inSizeForReduce)
@@ -86,8 +95,7 @@ HRESULT CEncoder::CreateMixerCoder(
}
#endif
-
- RINOK(SetMethodProperties(methodFull, inSizeForReduce, encoderCommon));
+ RINOK(SetCoderProps2(methodFull, inSizeForReduce, encoderCommon));
/*
CMyComPtr<ICryptoResetSalt> resetSalt;
diff --git a/CPP/7zip/Archive/7z/7zHandler.cpp b/CPP/7zip/Archive/7z/7zHandler.cpp
index 4ab7afa8..93d4f51e 100755
--- a/CPP/7zip/Archive/7z/7zHandler.cpp
+++ b/CPP/7zip/Archive/7z/7zHandler.cpp
@@ -24,25 +24,20 @@
using namespace NWindows;
-extern UString ConvertMethodIdToString(UInt64 id);
-
namespace NArchive {
namespace N7z {
CHandler::CHandler()
{
- _crcSize = 4;
-
#ifndef _NO_CRYPTO
_passwordIsDefined = false;
#endif
#ifdef EXTRACT_ONLY
+ _crcSize = 4;
#ifdef __7Z_SET_PROPERTIES
_numThreads = NSystem::GetNumberOfProcessors();
#endif
- #else
- Init();
#endif
}
@@ -70,7 +65,7 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
#else
-STATPROPSTG kArcProps[] =
+static const STATPROPSTG kArcProps[] =
{
{ NULL, kpidMethod, VT_BSTR},
{ NULL, kpidSolid, VT_BOOL},
@@ -80,6 +75,25 @@ STATPROPSTG kArcProps[] =
{ NULL, kpidOffset, VT_UI8}
};
+static inline wchar_t GetHex(Byte value)
+{
+ return (wchar_t)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
+}
+
+static UString ConvertMethodIdToString(UInt64 id)
+{
+ wchar_t s[32];
+ int len = 32;
+ s[--len] = 0;
+ do
+ {
+ s[--len] = GetHex((Byte)id & 0xF); id >>= 4;
+ s[--len] = GetHex((Byte)id & 0xF); id >>= 4;
+ }
+ while (id != 0);
+ return s + len;
+}
+
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
@@ -172,22 +186,18 @@ static UString GetStringForSizeValue(UInt32 value)
return result;
}
-static const UInt64 k_Copy = 0x0;
-static const UInt64 k_Delta = 3;
-static const UInt64 k_LZMA2 = 0x21;
-static const UInt64 k_LZMA = 0x030101;
-static const UInt64 k_PPMD = 0x030401;
-
-static wchar_t GetHex(Byte value)
-{
- return (wchar_t)((value < 10) ? (L'0' + value) : (L'A' + (value - 10)));
-}
static inline void AddHexToString(UString &res, Byte value)
{
res += GetHex((Byte)(value >> 4));
res += GetHex((Byte)(value & 0xF));
}
+static void AddProp32(UString &s, const wchar_t *name, UInt32 v)
+{
+ s += name;
+ s += ConvertUInt32ToString(v);
+}
+
#endif
bool CHandler::IsEncrypted(UInt32 index2) const
@@ -283,6 +293,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
{
UInt32 dicSize = GetUi32((const Byte *)coder.Props + 1);
propsString = GetStringForSizeValue(dicSize);
+ UInt32 d = coder.Props[0];
+ UInt32 lc = d % 9;
+ d /= 9;
+ UInt32 pb = d / 5;
+ UInt32 lp = d % 5;
+ if (lc != 3) AddProp32(propsString, L":lc", lc);
+ if (lp != 0) AddProp32(propsString, L":lp", lp);
+ if (pb != 2) AddProp32(propsString, L":pb", pb);
}
else if (coder.MethodID == k_LZMA2 && coder.Props.GetCapacity() == 1)
{
diff --git a/CPP/7zip/Archive/7z/7zHandler.h b/CPP/7zip/Archive/7z/7zHandler.h
index 56062d46..247b55f7 100755
--- a/CPP/7zip/Archive/7z/7zHandler.h
+++ b/CPP/7zip/Archive/7z/7zHandler.h
@@ -18,6 +18,16 @@
namespace NArchive {
namespace N7z {
+const UInt32 k_Copy = 0x0;
+const UInt32 k_Delta = 3;
+const UInt32 k_LZMA2 = 0x21;
+const UInt32 k_LZMA = 0x030101;
+const UInt32 k_PPMD = 0x030401;
+const UInt32 k_BCJ = 0x03030103;
+const UInt32 k_BCJ2 = 0x0303011B;
+const UInt32 k_Deflate = 0x040108;
+const UInt32 k_BZip2 = 0x040202;
+
#ifndef __7Z_SET_PROPERTIES
#ifdef EXTRACT_ONLY
@@ -31,9 +41,52 @@ namespace N7z {
#endif
+#ifndef EXTRACT_ONLY
+
+class COutHandler: public CMultiMethodProps
+{
+ HRESULT SetSolidFromString(const UString &s);
+ HRESULT SetSolidFromPROPVARIANT(const PROPVARIANT &value);
+public:
+ bool _removeSfxBlock;
+
+ UInt64 _numSolidFiles;
+ UInt64 _numSolidBytes;
+ bool _numSolidBytesDefined;
+ bool _solidExtension;
+
+ bool _compressHeaders;
+ bool _encryptHeadersSpecified;
+ bool _encryptHeaders;
+
+ bool WriteCTime;
+ bool WriteATime;
+ bool WriteMTime;
+
+ bool _volumeMode;
+
+ void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
+ void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); }
+ void InitSolid()
+ {
+ InitSolidFiles();
+ InitSolidSize();
+ _solidExtension = false;
+ _numSolidBytesDefined = false;
+ }
+
+ void InitProps();
+
+ COutHandler() { InitProps(); }
+
+ HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
+};
+
+#endif
+
class CHandler:
#ifndef EXTRACT_ONLY
- public NArchive::COutHandler,
+ public COutHandler,
#endif
public IInArchive,
#ifdef __7Z_SET_PROPERTIES
@@ -90,16 +143,16 @@ private:
CRecordVector<CBind> _binds;
- HRESULT SetCompressionMethod(CCompressionMethodMode &method,
+ HRESULT PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m);
+ HRESULT SetHeaderMethod(CCompressionMethodMode &headerMethod);
+ void AddDefaultMethod();
+ HRESULT SetMainMethod(CCompressionMethodMode &method,
CObjectVector<COneMethodInfo> &methodsInfo
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
);
- HRESULT SetCompressionMethod(
- CCompressionMethodMode &method,
- CCompressionMethodMode &headerMethod);
#endif
diff --git a/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/CPP/7zip/Archive/7z/7zHandlerOut.cpp
index a8ccab6d..dd73ee84 100755
--- a/CPP/7zip/Archive/7z/7zHandlerOut.cpp
+++ b/CPP/7zip/Archive/7z/7zHandlerOut.cpp
@@ -2,13 +2,9 @@
#include "StdAfx.h"
-#include "../../../Windows/PropVariant.h"
-
#include "../../../Common/ComTry.h"
#include "../../../Common/StringToInt.h"
-#include "../../ICoder.h"
-
#include "../Common/ItemNameUtils.h"
#include "../Common/ParseProperties.h"
@@ -21,24 +17,19 @@ using namespace NWindows;
namespace NArchive {
namespace N7z {
-static const wchar_t *kLZMAMethodName = L"LZMA";
-static const wchar_t *kCopyMethod = L"Copy";
-static const wchar_t *kDefaultMethodName = kLZMAMethodName;
+static const wchar_t *k_LZMA_Name = L"LZMA";
+static const wchar_t *kDefaultMethodName = k_LZMA_Name;
+static const wchar_t *k_Copy_Name = L"Copy";
-static const UInt32 kLzmaAlgorithmX5 = 1;
-static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
-static const UInt32 kDictionaryForHeaders =
+static const wchar_t *k_MatchFinder_ForHeaders = L"BT2";
+static const UInt32 k_NumFastBytes_ForHeaders = 273;
+static const UInt32 k_Level_ForHeaders = 5;
+static const UInt32 k_Dictionary_ForHeaders =
#ifdef UNDER_CE
- 1 << 18
+ 1 << 18;
#else
- 1 << 20
+ 1 << 20;
#endif
-;
-static const UInt32 kNumFastBytesForHeaders = 273;
-static const UInt32 kAlgorithmForHeaders = kLzmaAlgorithmX5;
-
-static inline bool IsCopyMethod(const UString &methodName)
- { return (methodName.CompareNoCase(kCopyMethod) == 0); }
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
{
@@ -46,123 +37,105 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
return S_OK;
}
-HRESULT CHandler::SetCompressionMethod(
- CCompressionMethodMode &methodMode,
- CCompressionMethodMode &headerMethod)
+HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m)
{
- HRESULT res = SetCompressionMethod(methodMode, _methods
- #ifndef _7ZIP_ST
- , _numThreads
- #endif
- );
- RINOK(res);
- methodMode.Binds = _binds;
+ if (!FindMethod(
+ EXTERNAL_CODECS_VARS
+ m.MethodName, dest.Id, dest.NumInStreams, dest.NumOutStreams))
+ return E_INVALIDARG;
+ (CProps &)dest = (CProps &)m;
+ return S_OK;
+}
- if (_compressHeaders)
- {
- // headerMethod.Methods.Add(methodMode.Methods.Back());
+HRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod)
+{
+ if (!_compressHeaders)
+ return S_OK;
+ COneMethodInfo m;
+ m.MethodName = k_LZMA_Name;
+ m.AddPropString(NCoderPropID::kMatchFinder, k_MatchFinder_ForHeaders);
+ m.AddProp32(NCoderPropID::kLevel, k_Level_ForHeaders);
+ m.AddProp32(NCoderPropID::kNumFastBytes, k_NumFastBytes_ForHeaders);
+ m.AddProp32(NCoderPropID::kDictionarySize, k_Dictionary_ForHeaders);
+ m.AddNumThreadsProp(1);
+
+ CMethodFull methodFull;
+ RINOK(PropsMethod_To_FullMethod(methodFull, m));
+ headerMethod.Methods.Add(methodFull);
+ return S_OK;
+}
- CObjectVector<COneMethodInfo> headerMethodInfoVector;
- COneMethodInfo oneMethodInfo;
- oneMethodInfo.MethodName = kLZMAMethodName;
- {
- CProp prop;
- prop.Id = NCoderPropID::kMatchFinder;
- prop.Value = kLzmaMatchFinderForHeaders;
- oneMethodInfo.Props.Add(prop);
- }
- {
- CProp prop;
- prop.Id = NCoderPropID::kAlgorithm;
- prop.Value = kAlgorithmForHeaders;
- oneMethodInfo.Props.Add(prop);
- }
- {
- CProp prop;
- prop.Id = NCoderPropID::kNumFastBytes;
- prop.Value = (UInt32)kNumFastBytesForHeaders;
- oneMethodInfo.Props.Add(prop);
- }
- {
- CProp prop;
- prop.Id = NCoderPropID::kDictionarySize;
- prop.Value = (UInt32)kDictionaryForHeaders;
- oneMethodInfo.Props.Add(prop);
- }
- headerMethodInfoVector.Add(oneMethodInfo);
- HRESULT res = SetCompressionMethod(headerMethod, headerMethodInfoVector
- #ifndef _7ZIP_ST
- , 1
- #endif
- );
- RINOK(res);
+void CHandler::AddDefaultMethod()
+{
+ for (int i = 0; i < _methods.Size(); i++)
+ {
+ UString &methodName = _methods[0].MethodName;
+ if (methodName.IsEmpty())
+ methodName = kDefaultMethodName;
+ }
+ if (_methods.IsEmpty())
+ {
+ COneMethodInfo m;
+ m.MethodName = (GetLevel() == 0 ? k_Copy_Name : kDefaultMethodName);
+ _methods.Add(m);
}
- return S_OK;
}
-HRESULT CHandler::SetCompressionMethod(
+HRESULT CHandler::SetMainMethod(
CCompressionMethodMode &methodMode,
- CObjectVector<COneMethodInfo> &methodsInfo
+ CObjectVector<COneMethodInfo> &methods
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
)
{
- UInt32 level = _level;
-
- if (methodsInfo.IsEmpty())
- {
- COneMethodInfo oneMethodInfo;
- oneMethodInfo.MethodName = ((level == 0) ? kCopyMethod : kDefaultMethodName);
- methodsInfo.Add(oneMethodInfo);
- }
+ AddDefaultMethod();
+
+ const UInt64 kSolidBytes_Min = (1 << 24);
+ const UInt64 kSolidBytes_Max = ((UInt64)1 << 32) - 1;
bool needSolid = false;
- for(int i = 0; i < methodsInfo.Size(); i++)
+ for (int i = 0; i < methods.Size(); i++)
{
- COneMethodInfo &oneMethodInfo = methodsInfo[i];
- SetCompressionMethod2(oneMethodInfo
+ COneMethodInfo &oneMethodInfo = methods[i];
+ SetGlobalLevelAndThreads(oneMethodInfo
#ifndef _7ZIP_ST
, numThreads
#endif
);
- if (!IsCopyMethod(oneMethodInfo.MethodName))
- needSolid = true;
-
CMethodFull methodFull;
-
- if (!FindMethod(
- EXTERNAL_CODECS_VARS
- oneMethodInfo.MethodName, methodFull.Id, methodFull.NumInStreams, methodFull.NumOutStreams))
- return E_INVALIDARG;
- methodFull.Props = oneMethodInfo.Props;
+ RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
methodMode.Methods.Add(methodFull);
- if (!_numSolidBytesDefined)
+ if (methodFull.Id != k_Copy)
+ needSolid = true;
+
+ if (_numSolidBytesDefined)
+ continue;
+
+ UInt32 dicSize;
+ switch (methodFull.Id)
{
- for (int j = 0; j < methodFull.Props.Size(); j++)
- {
- const CProp &prop = methodFull.Props[j];
- if ((prop.Id == NCoderPropID::kDictionarySize ||
- prop.Id == NCoderPropID::kUsedMemorySize) && prop.Value.vt == VT_UI4)
- {
- _numSolidBytes = ((UInt64)prop.Value.ulVal) << 7;
- const UInt64 kMinSize = (1 << 24);
- if (_numSolidBytes < kMinSize)
- _numSolidBytes = kMinSize;
- _numSolidBytesDefined = true;
- break;
- }
- }
+ case k_LZMA:
+ case k_LZMA2: dicSize = oneMethodInfo.Get_Lzma_DicSize(); break;
+ case k_PPMD: dicSize = oneMethodInfo.Get_Ppmd_MemSize(); break;
+ case k_Deflate: dicSize = (UInt32)1 << 15; break;
+ case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break;
+ default: continue;
}
- }
-
- if (!needSolid && !_numSolidBytesDefined)
- {
+ _numSolidBytes = (UInt64)dicSize << 7;
+ if (_numSolidBytes < kSolidBytes_Min) _numSolidBytes = kSolidBytes_Min;
+ if (_numSolidBytes > kSolidBytes_Max) _numSolidBytes = kSolidBytes_Max;
_numSolidBytesDefined = true;
- _numSolidBytes = 0;
}
+
+ if (!_numSolidBytesDefined)
+ if (needSolid)
+ _numSolidBytes = kSolidBytes_Max;
+ else
+ _numSolidBytes = 0;
+ _numSolidBytesDefined = true;
return S_OK;
}
@@ -326,7 +299,16 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
}
CCompressionMethodMode methodMode, headerMethod;
- RINOK(SetCompressionMethod(methodMode, headerMethod));
+
+ HRESULT res = SetMainMethod(methodMode, _methods
+ #ifndef _7ZIP_ST
+ , _numThreads
+ #endif
+ );
+ RINOK(res);
+ methodMode.Binds = _binds;
+
+ RINOK(SetHeaderMethod(headerMethod));
#ifndef _7ZIP_ST
methodMode.NumThreads = _numThreads;
headerMethod.NumThreads = 1;
@@ -373,8 +355,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CUpdateOptions options;
options.Method = &methodMode;
options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0;
- options.UseFilters = _level != 0 && _autoFilter;
- options.MaxFilter = _level >= 8;
+ int level = GetLevel();
+ options.UseFilters = level != 0 && _autoFilter;
+ options.MaxFilter = level >= 8;
options.HeaderOptions.CompressMainHeader = compressMainHeader;
options.HeaderOptions.WriteCTime = WriteCTime;
@@ -393,7 +376,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CMyComPtr<ICryptoGetTextPassword> getPassword;
updateCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getPassword);
- HRESULT res = Update(
+ res = Update(
EXTERNAL_CODECS_VARS
#ifdef _7Z_VOL
volume ? volume->Stream: 0,
@@ -437,25 +420,138 @@ static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream
return S_OK;
}
-static HRESULT GetBindInfo(UString &srcString, CBind &bind)
+void COutHandler::InitProps()
{
- RINOK(GetBindInfoPart(srcString, bind.OutCoder, bind.OutStream));
- if (srcString[0] != ':')
- return E_INVALIDARG;
- srcString.Delete(0);
- RINOK(GetBindInfoPart(srcString, bind.InCoder, bind.InStream));
- if (!srcString.IsEmpty())
- return E_INVALIDARG;
+ CMultiMethodProps::Init();
+
+ _removeSfxBlock = false;
+ _compressHeaders = true;
+ _encryptHeadersSpecified = false;
+ _encryptHeaders = false;
+
+ WriteCTime = false;
+ WriteATime = false;
+ WriteMTime = true;
+
+ _volumeMode = false;
+ InitSolid();
+}
+
+HRESULT COutHandler::SetSolidFromString(const UString &s)
+{
+ UString s2 = s;
+ s2.MakeUpper();
+ for (int i = 0; i < s2.Length();)
+ {
+ const wchar_t *start = ((const wchar_t *)s2) + i;
+ const wchar_t *end;
+ UInt64 v = ConvertStringToUInt64(start, &end);
+ if (start == end)
+ {
+ if (s2[i++] != 'E')
+ return E_INVALIDARG;
+ _solidExtension = true;
+ continue;
+ }
+ i += (int)(end - start);
+ if (i == s2.Length())
+ return E_INVALIDARG;
+ wchar_t c = s2[i++];
+ if (c == 'F')
+ {
+ if (v < 1)
+ v = 1;
+ _numSolidFiles = v;
+ }
+ else
+ {
+ unsigned numBits;
+ switch (c)
+ {
+ case 'B': numBits = 0; break;
+ case 'K': numBits = 10; break;
+ case 'M': numBits = 20; break;
+ case 'G': numBits = 30; break;
+ default: return E_INVALIDARG;
+ }
+ _numSolidBytes = (v << numBits);
+ _numSolidBytesDefined = true;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT COutHandler::SetSolidFromPROPVARIANT(const PROPVARIANT &value)
+{
+ bool isSolid;
+ switch (value.vt)
+ {
+ case VT_EMPTY: isSolid = true; break;
+ case VT_BOOL: isSolid = (value.boolVal != VARIANT_FALSE); break;
+ case VT_BSTR:
+ if (StringToBool(value.bstrVal, isSolid))
+ break;
+ return SetSolidFromString(value.bstrVal);
+ default: return E_INVALIDARG;
+ }
+ if (isSolid)
+ InitSolid();
+ else
+ _numSolidFiles = 1;
return S_OK;
}
-STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
+{
+ UString name = nameSpec;
+ name.MakeUpper();
+ if (name.IsEmpty())
+ return E_INVALIDARG;
+
+ if (name[0] == L'S')
+ {
+ name.Delete(0);
+ if (name.IsEmpty())
+ return SetSolidFromPROPVARIANT(value);
+ if (value.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ return SetSolidFromString(name);
+ }
+
+ UInt32 number;
+ int index = ParseStringToUInt32(name, number);
+ UString realName = name.Mid(index);
+ if (index == 0)
+ {
+ if (name.CompareNoCase(L"RSFX") == 0) return PROPVARIANT_to_bool(value, _removeSfxBlock);
+ if (name.CompareNoCase(L"HC") == 0) return PROPVARIANT_to_bool(value, _compressHeaders);
+ if (name.CompareNoCase(L"HCF") == 0)
+ {
+ bool compressHeadersFull = true;
+ RINOK(PROPVARIANT_to_bool(value, compressHeadersFull));
+ return compressHeadersFull ? S_OK: E_INVALIDARG;
+ }
+ if (name.CompareNoCase(L"HE") == 0)
+ {
+ RINOK(PROPVARIANT_to_bool(value, _encryptHeaders));
+ _encryptHeadersSpecified = true;
+ return S_OK;
+ }
+ if (name.CompareNoCase(L"TC") == 0) return PROPVARIANT_to_bool(value, WriteCTime);
+ if (name.CompareNoCase(L"TA") == 0) return PROPVARIANT_to_bool(value, WriteATime);
+ if (name.CompareNoCase(L"TM") == 0) return PROPVARIANT_to_bool(value, WriteMTime);
+ if (name.CompareNoCase(L"V") == 0) return PROPVARIANT_to_bool(value, _volumeMode);
+ }
+ return CMultiMethodProps::SetProperty(name, value);
+}
+
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
{
COM_TRY_BEGIN
_binds.Clear();
- BeforeSetProperty();
+ InitProps();
- for (int i = 0; i < numProperties; i++)
+ for (int i = 0; i < numProps; i++)
{
UString name = names[i];
name.MakeUpper();
@@ -466,9 +562,17 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
if (name[0] == 'B')
{
+ if (value.vt != VT_EMPTY)
+ return E_INVALIDARG;
name.Delete(0);
CBind bind;
- RINOK(GetBindInfo(name, bind));
+ RINOK(GetBindInfoPart(name, bind.OutCoder, bind.OutStream));
+ if (name[0] != ':')
+ return E_INVALIDARG;
+ name.Delete(0);
+ RINOK(GetBindInfoPart(name, bind.InCoder, bind.InStream));
+ if (!name.IsEmpty())
+ return E_INVALIDARG;
_binds.Add(bind);
continue;
}
@@ -476,6 +580,47 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
RINOK(SetProperty(name, value));
}
+ int numEmptyMethods = GetNumEmptyMethods();
+ if (numEmptyMethods > 0)
+ {
+ int k;
+ for (k = 0; k < _binds.Size(); k++)
+ {
+ const CBind &bind = _binds[k];
+ if (bind.InCoder < (UInt32)numEmptyMethods ||
+ bind.OutCoder < (UInt32)numEmptyMethods)
+ return E_INVALIDARG;
+ }
+ for (k = 0; k < _binds.Size(); k++)
+ {
+ CBind &bind = _binds[k];
+ bind.InCoder -= (UInt32)numEmptyMethods;
+ bind.OutCoder -= (UInt32)numEmptyMethods;
+ }
+ _methods.Delete(0, numEmptyMethods);
+ }
+
+ AddDefaultMethod();
+
+ if (!_filterMethod.MethodName.IsEmpty())
+ {
+ for (int k = 0; k < _binds.Size(); k++)
+ {
+ CBind &bind = _binds[k];
+ bind.InCoder++;
+ bind.OutCoder++;
+ }
+ _methods.Insert(0, _filterMethod);
+ }
+
+ for (int k = 0; k < _binds.Size(); k++)
+ {
+ const CBind &bind = _binds[k];
+ if (bind.InCoder >= (UInt32)_methods.Size() ||
+ bind.OutCoder >= (UInt32)_methods.Size())
+ return E_INVALIDARG;
+ }
+
return S_OK;
COM_TRY_END
}
diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp
index 0feb81d2..fd751a74 100755
--- a/CPP/7zip/Archive/7z/7zIn.cpp
+++ b/CPP/7zip/Archive/7z/7zIn.cpp
@@ -317,7 +317,6 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
const UInt32 kBufferSize = (1 << 16);
byteBuffer.SetCapacity(kBufferSize);
Byte *buffer = byteBuffer;
- UInt32 numPrevBytes = kHeaderSize;
memcpy(buffer, _header, kHeaderSize);
UInt64 curTestPos = _arhiveBeginStreamPosition;
for (;;)
@@ -325,21 +324,14 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
if (searchHeaderSizeLimit != NULL)
if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
break;
- do
- {
- UInt32 numReadBytes = kBufferSize - numPrevBytes;
- UInt32 processedSize;
- RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
- numPrevBytes += processedSize;
- if (processedSize == 0)
- return S_FALSE;
- }
- while (numPrevBytes <= kHeaderSize);
- UInt32 numTests = numPrevBytes - kHeaderSize;
- for (UInt32 pos = 0; pos < numTests; pos++)
+ UInt32 processedSize;
+ RINOK(stream->Read(buffer + kHeaderSize, kBufferSize - kHeaderSize, &processedSize));
+ if (processedSize == 0)
+ return S_FALSE;
+ for (UInt32 pos = 1; pos <= processedSize; pos++)
{
- for (; buffer[pos] != '7' && pos < numTests; pos++);
- if (pos == numTests)
+ for (; buffer[pos] != '7' && pos <= processedSize; pos++);
+ if (pos > processedSize)
break;
if (TestSignature(buffer + pos))
{
@@ -349,9 +341,8 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL);
}
}
- curTestPos += numTests;
- numPrevBytes -= numTests;
- memmove(buffer, buffer + numTests, numPrevBytes);
+ curTestPos += processedSize;
+ memmove(buffer, buffer + processedSize, kHeaderSize);
}
return S_FALSE;
}
@@ -362,6 +353,8 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
HeadersSize = 0;
Close();
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
+ RINOK(stream->Seek(0, STREAM_SEEK_END, &_fileEndPosition))
+ RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL))
RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
_stream = stream;
return S_OK;
@@ -1194,12 +1187,14 @@ HRESULT CInArchive::ReadDatabase2(
if (nextHeaderSize == 0)
return S_OK;
- if (nextHeaderSize > (UInt64)0xFFFFFFFF)
+ if (nextHeaderSize > (UInt64)(UInt32)0xFFFFFFFF)
return S_FALSE;
if ((Int64)nextHeaderOffset < 0)
return S_FALSE;
+ if (db.ArchiveInfo.StartPositionAfterHeader + nextHeaderOffset > _fileEndPosition)
+ return S_FALSE;
RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL));
CByteBuffer buffer2;
diff --git a/CPP/7zip/Archive/7z/7zIn.h b/CPP/7zip/Archive/7z/7zIn.h
index 971f27b2..4305a8c5 100755
--- a/CPP/7zip/Archive/7z/7zIn.h
+++ b/CPP/7zip/Archive/7z/7zIn.h
@@ -133,6 +133,7 @@ class CInArchive
CInByte2 *_inByteBack;
UInt64 _arhiveBeginStreamPosition;
+ UInt64 _fileEndPosition;
Byte _header[kHeaderSize];
diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp
index ee7f55c0..e63b09d2 100755
--- a/CPP/7zip/Archive/7z/7zUpdate.cpp
+++ b/CPP/7zip/Archive/7z/7zUpdate.cpp
@@ -24,15 +24,6 @@
namespace NArchive {
namespace N7z {
-static const UInt64 k_LZMA = 0x030101;
-static const UInt64 k_BCJ = 0x03030103;
-static const UInt64 k_BCJ2 = 0x0303011B;
-
-static const wchar_t *kMatchFinderForBCJ2_LZMA = L"BT2";
-static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20;
-static const UInt32 kAlgorithmForBCJ2_LZMA = 1;
-static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;
-
#ifdef MY_CPU_X86_OR_AMD64
#define USE_86_FILTER
#endif
@@ -339,90 +330,74 @@ static bool IsExeExt(const UString &ext)
return false;
}
-#ifdef USE_86_FILTER
-static inline void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &methodResult)
+static inline void GetMethodFull(UInt64 methodID, UInt32 numInStreams, CMethodFull &m)
{
- methodResult.Id = methodID;
- methodResult.NumInStreams = numInStreams;
- methodResult.NumOutStreams = 1;
+ m.Id = methodID;
+ m.NumInStreams = numInStreams;
+ m.NumOutStreams = 1;
+}
+
+static void AddBcj2Methods(CCompressionMethodMode &mode)
+{
+ CMethodFull m;
+ GetMethodFull(k_LZMA, 1, m);
+
+ m.AddProp32(NCoderPropID::kDictionarySize, 1 << 20);
+ m.AddProp32(NCoderPropID::kNumFastBytes, 128);
+ m.AddProp32(NCoderPropID::kNumThreads, 1);
+ m.AddProp32(NCoderPropID::kLitPosBits, 2);
+ m.AddProp32(NCoderPropID::kLitContextBits, 0);
+ // m.AddPropString(NCoderPropID::kMatchFinder, L"BT2");
+
+ mode.Methods.Add(m);
+ mode.Methods.Add(m);
+
+ CBind bind;
+ bind.OutCoder = 0;
+ bind.InStream = 0;
+ bind.InCoder = 1; bind.OutStream = 0; mode.Binds.Add(bind);
+ bind.InCoder = 2; bind.OutStream = 1; mode.Binds.Add(bind);
+ bind.InCoder = 3; bind.OutStream = 2; mode.Binds.Add(bind);
}
-static void MakeExeMethod(const CCompressionMethodMode &method,
- bool bcj2Filter, CCompressionMethodMode &exeMethod)
+static void MakeExeMethod(CCompressionMethodMode &mode,
+ bool useFilters, bool addFilter, bool bcj2Filter)
{
- exeMethod = method;
+ if (!mode.Binds.IsEmpty() || !useFilters || mode.Methods.Size() > 2)
+ return;
+ if (mode.Methods.Size() == 2)
+ {
+ if (mode.Methods[0].Id == k_BCJ2)
+ AddBcj2Methods(mode);
+ return;
+ }
+ if (!addFilter)
+ return;
+ bcj2Filter = bcj2Filter;
+ #ifdef USE_86_FILTER
if (bcj2Filter)
{
- CMethodFull methodFull;
- GetMethodFull(k_BCJ2, 4, methodFull);
- exeMethod.Methods.Insert(0, methodFull);
- GetMethodFull(k_LZMA, 1, methodFull);
- {
- CProp prop;
- prop.Id = NCoderPropID::kAlgorithm;
- prop.Value = kAlgorithmForBCJ2_LZMA;
- methodFull.Props.Add(prop);
- }
- {
- CProp prop;
- prop.Id = NCoderPropID::kMatchFinder;
- prop.Value = kMatchFinderForBCJ2_LZMA;
- methodFull.Props.Add(prop);
- }
- {
- CProp prop;
- prop.Id = NCoderPropID::kDictionarySize;
- prop.Value = kDictionaryForBCJ2_LZMA;
- methodFull.Props.Add(prop);
- }
- {
- CProp prop;
- prop.Id = NCoderPropID::kNumFastBytes;
- prop.Value = kNumFastBytesForBCJ2_LZMA;
- methodFull.Props.Add(prop);
- }
- {
- CProp prop;
- prop.Id = NCoderPropID::kNumThreads;
- prop.Value = (UInt32)1;
- methodFull.Props.Add(prop);
- }
-
- exeMethod.Methods.Add(methodFull);
- exeMethod.Methods.Add(methodFull);
- CBind bind;
-
- bind.OutCoder = 0;
- bind.InStream = 0;
-
- bind.InCoder = 1;
- bind.OutStream = 0;
- exeMethod.Binds.Add(bind);
-
- bind.InCoder = 2;
- bind.OutStream = 1;
- exeMethod.Binds.Add(bind);
-
- bind.InCoder = 3;
- bind.OutStream = 2;
- exeMethod.Binds.Add(bind);
+ CMethodFull m;
+ GetMethodFull(k_BCJ2, 4, m);
+ mode.Methods.Insert(0, m);
+ AddBcj2Methods(mode);
}
else
{
- CMethodFull methodFull;
- GetMethodFull(k_BCJ, 1, methodFull);
- exeMethod.Methods.Insert(0, methodFull);
+ CMethodFull m;
+ GetMethodFull(k_BCJ, 1, m);
+ mode.Methods.Insert(0, m);
CBind bind;
bind.OutCoder = 0;
bind.InStream = 0;
bind.InCoder = 1;
bind.OutStream = 0;
- exeMethod.Binds.Add(bind);
+ mode.Binds.Add(bind);
}
+ #endif
}
-#endif
static void FromUpdateItemToFileItem(const CUpdateItem &ui,
CFileItem &file, CFileItem2 &file2)
@@ -601,6 +576,7 @@ public:
Fos = FosSpec;
Result = E_FAIL;
}
+ ~CThreadDecoder() { CVirtThread::WaitThreadFinish(); }
virtual void Execute();
};
@@ -669,9 +645,7 @@ STDMETHODIMP CCryptoGetTextPassword::CryptoGetTextPassword(BSTR *password)
static const int kNumGroupsMax = 4;
-#ifdef USE_86_FILTER
static bool Is86Group(int group) { return (group & 1) != 0; }
-#endif
static bool IsEncryptedGroup(int group) { return (group & 2) != 0; }
static int GetGroupIndex(bool encrypted, int bcjFiltered)
{ return (encrypted ? 2 : 0) + (bcjFiltered ? 1 : 0); }
@@ -789,16 +763,15 @@ HRESULT Update(
if (inSizeForReduce2 > inSizeForReduce)
inSizeForReduce = inSizeForReduce2;
- const UInt32 kMinReduceSize = (1 << 16);
- if (inSizeForReduce < kMinReduceSize)
- inSizeForReduce = kMinReduceSize;
-
RINOK(updateCallback->SetTotal(complexity));
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(updateCallback, true);
+ CStreamBinder sb;
+ RINOK(sb.CreateEvents());
+
CThreadDecoder threadDecoder;
if (!folderRefs.IsEmpty())
{
@@ -870,13 +843,8 @@ HRESULT Update(
{
const CSolidGroup &group = groups[groupIndex];
- CCompressionMethodMode method;
- #ifdef USE_86_FILTER
- if (Is86Group(groupIndex))
- MakeExeMethod(*options.Method, options.MaxFilter, method);
- else
- #endif
- method = *options.Method;
+ CCompressionMethodMode method = *options.Method;
+ MakeExeMethod(method, options.UseFilters, Is86Group(groupIndex), options.MaxFilter);
if (IsEncryptedGroup(groupIndex))
{
@@ -923,11 +891,6 @@ HRESULT Update(
}
else
{
- CStreamBinder sb;
- RINOK(sb.CreateEvents());
- CMyComPtr<ISequentialOutStream> sbOutStream;
- CMyComPtr<ISequentialInStream> sbInStream;
- sb.CreateStreams(&sbInStream, &sbOutStream);
CBoolVector extractStatuses;
CNum numUnpackStreams = db->NumUnpackStreamsVector[folderIndex];
@@ -946,24 +909,31 @@ HRESULT Update(
extractStatuses.Add(needExtract);
}
- RINOK(threadDecoder.FosSpec->Init(db, db->FolderStartFileIndex[folderIndex], &extractStatuses, sbOutStream));
- sbOutStream.Release();
-
- threadDecoder.InStream = inStream;
- threadDecoder.Folder = &db->Folders[folderIndex];
- threadDecoder.StartPos = db->GetFolderStreamPos(folderIndex, 0);
- threadDecoder.PackSizes = &db->PackSizes[db->FolderStartPackStreamIndex[folderIndex]];
-
- threadDecoder.Start();
-
int startPackIndex = newDatabase.PackSizes.Size();
CFolder newFolder;
- RINOK(encoder.Encode(
- EXTERNAL_CODECS_LOC_VARS
- sbInStream, NULL, &inSizeForReduce, newFolder,
- archive.SeqStream, newDatabase.PackSizes, progress));
-
- threadDecoder.WaitFinish();
+ {
+ CMyComPtr<ISequentialInStream> sbInStream;
+ {
+ CMyComPtr<ISequentialOutStream> sbOutStream;
+ sb.CreateStreams(&sbInStream, &sbOutStream);
+ sb.ReInit();
+ RINOK(threadDecoder.FosSpec->Init(db, db->FolderStartFileIndex[folderIndex], &extractStatuses, sbOutStream));
+ }
+
+ threadDecoder.InStream = inStream;
+ threadDecoder.Folder = &db->Folders[folderIndex];
+ threadDecoder.StartPos = db->GetFolderStreamPos(folderIndex, 0);
+ threadDecoder.PackSizes = &db->PackSizes[db->FolderStartPackStreamIndex[folderIndex]];
+
+ threadDecoder.Start();
+
+ RINOK(encoder.Encode(
+ EXTERNAL_CODECS_LOC_VARS
+ sbInStream, NULL, &inSizeForReduce, newFolder,
+ archive.SeqStream, newDatabase.PackSizes, progress));
+
+ threadDecoder.WaitExecuteFinish();
+ }
RINOK(threadDecoder.Result);
@@ -1134,6 +1104,8 @@ HRESULT Update(
if (folderRefIndex != folderRefs.Size())
return E_FAIL;
+ RINOK(lps->SetCur());
+
/*
folderRefs.ClearAndFree();
fileIndexToUpdateIndexMap.ClearAndFree();
@@ -1169,7 +1141,7 @@ HRESULT Update(
newDatabase.AddFile(file, file2);
}
}
-
+
newDatabase.ReserveDown();
return S_OK;
}
diff --git a/CPP/7zip/Archive/Bz2Handler.cpp b/CPP/7zip/Archive/Bz2Handler.cpp
index 98cbcc18..49ae8c79 100755
--- a/CPP/7zip/Archive/Bz2Handler.cpp
+++ b/CPP/7zip/Archive/Bz2Handler.cpp
@@ -4,13 +4,6 @@
#include "Common/ComTry.h"
-#include "Windows/PropVariant.h"
-
-#ifndef _7ZIP_ST
-#include "../../Windows/System.h"
-#endif
-
-#include "../Common/CreateCoder.h"
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
#include "../Common/StreamUtils.h"
@@ -20,21 +13,13 @@
#include "../Compress/CopyCoder.h"
#include "Common/DummyOutStream.h"
-#include "Common/ParseProperties.h"
+#include "Common/HandlerOut.h"
using namespace NWindows;
namespace NArchive {
namespace NBz2 {
-static const UInt32 kNumPassesX1 = 1;
-static const UInt32 kNumPassesX7 = 2;
-static const UInt32 kNumPassesX9 = 7;
-
-static const UInt32 kDicSizeX1 = 100000;
-static const UInt32 kDicSizeX3 = 500000;
-static const UInt32 kDicSizeX5 = 900000;
-
class CHandler:
public IInArchive,
public IArchiveOpenSeq,
@@ -48,22 +33,7 @@ class CHandler:
UInt64 _startPosition;
bool _packSizeDefined;
- UInt32 _level;
- UInt32 _dicSize;
- UInt32 _numPasses;
- #ifndef _7ZIP_ST
- UInt32 _numThreads;
- #endif
-
- void InitMethodProperties()
- {
- _level = 5;
- _dicSize =
- _numPasses = 0xFFFFFFFF;
- #ifndef _7ZIP_ST
- _numThreads = NWindows::NSystem::GetNumberOfProcessors();;
- #endif
- }
+ CSingleMethodProps _props;
public:
MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties)
@@ -73,10 +43,10 @@ public:
STDMETHOD(OpenSeq)(ISequentialInStream *stream);
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);
- CHandler() { InitMethodProperties(); }
+ CHandler() { }
};
-STATPROPSTG kProps[] =
+static const STATPROPSTG kProps[] =
{
{ NULL, kpidPackSize, VT_UI8}
};
@@ -87,7 +57,7 @@ IMP_IInArchive_ArcProps_NO_Table
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
- switch(propID)
+ switch (propID)
{
case kpidPhySize: if (_packSizeDefined) prop = _packSize; break;
}
@@ -104,7 +74,7 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
{
NWindows::NCOM::CPropVariant prop;
- switch(propID)
+ switch (propID)
{
case kpidPackSize: if (_packSizeDefined) prop = _packSize; break;
}
@@ -188,7 +158,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
decoderSpec->SetInStream(_seqStream);
#ifndef _7ZIP_ST
- RINOK(decoderSpec->SetNumberOfThreads(_numThreads));
+ RINOK(decoderSpec->SetNumberOfThreads(_props._numThreads));
#endif
CDummyOutStream *outStreamSpec = new CDummyOutStream;
@@ -246,50 +216,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
static HRESULT UpdateArchive(
UInt64 unpackSize,
ISequentialOutStream *outStream,
- int indexInClient,
- UInt32 dictionary,
- UInt32 numPasses,
- #ifndef _7ZIP_ST
- UInt32 numThreads,
- #endif
+ const CProps &props,
IArchiveUpdateCallback *updateCallback)
{
RINOK(updateCallback->SetTotal(unpackSize));
- UInt64 complexity = 0;
- RINOK(updateCallback->SetCompleted(&complexity));
-
CMyComPtr<ISequentialInStream> fileInStream;
-
- RINOK(updateCallback->GetStream(indexInClient, &fileInStream));
-
+ RINOK(updateCallback->GetStream(0, &fileInStream));
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
localProgressSpec->Init(updateCallback, true);
-
NCompress::NBZip2::CEncoder *encoderSpec = new NCompress::NBZip2::CEncoder;
CMyComPtr<ICompressCoder> encoder = encoderSpec;
- {
- NWindows::NCOM::CPropVariant properties[] =
- {
- dictionary,
- numPasses
- #ifndef _7ZIP_ST
- , numThreads
- #endif
- };
- PROPID propIDs[] =
- {
- NCoderPropID::kDictionarySize,
- NCoderPropID::kNumPasses
- #ifndef _7ZIP_ST
- , NCoderPropID::kNumThreads
- #endif
- };
- RINOK(encoderSpec->SetCoderProperties(propIDs, properties, sizeof(propIDs) / sizeof(propIDs[0])));
- }
-
+ RINOK(props.SetCoderProps(encoderSpec, NULL));
RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, localProgress));
-
return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
}
@@ -336,25 +275,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
}
-
- UInt32 dicSize = _dicSize;
- if (dicSize == 0xFFFFFFFF)
- dicSize = (_level >= 5 ? kDicSizeX5 :
- (_level >= 3 ? kDicSizeX3 :
- kDicSizeX1));
-
- UInt32 numPasses = _numPasses;
- if (numPasses == 0xFFFFFFFF)
- numPasses = (_level >= 9 ? kNumPassesX9 :
- (_level >= 7 ? kNumPassesX7 :
- kNumPassesX1));
-
- return UpdateArchive(
- size, outStream, 0, dicSize, numPasses,
- #ifndef _7ZIP_ST
- _numThreads,
- #endif
- updateCallback);
+ return UpdateArchive(size, outStream, _props, updateCallback);
}
if (indexInArchive != 0)
return E_INVALIDARG;
@@ -365,47 +286,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
{
- InitMethodProperties();
- #ifndef _7ZIP_ST
- const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
- _numThreads = numProcessors;
- #endif
-
- for (int i = 0; i < numProps; i++)
- {
- UString name = names[i];
- name.MakeUpper();
- if (name.IsEmpty())
- return E_INVALIDARG;
- const PROPVARIANT &prop = values[i];
- if (name[0] == L'X')
- {
- UInt32 level = 9;
- RINOK(ParsePropValue(name.Mid(1), prop, level));
- _level = level;
- }
- else if (name[0] == L'D')
- {
- UInt32 dicSize = kDicSizeX5;
- RINOK(ParsePropDictionaryValue(name.Mid(1), prop, dicSize));
- _dicSize = dicSize;
- }
- else if (name.Left(4) == L"PASS")
- {
- UInt32 num = kNumPassesX9;
- RINOK(ParsePropValue(name.Mid(4), prop, num));
- _numPasses = num;
- }
- else if (name.Left(2) == L"MT")
- {
- #ifndef _7ZIP_ST
- RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _numThreads));
- #endif
- }
- else
- return E_INVALIDARG;
- }
- return S_OK;
+ return _props.SetProperties(names, values, numProps);
}
static IInArchive *CreateArc() { return new CHandler; }
diff --git a/CPP/7zip/Archive/Cab/CabHandler.cpp b/CPP/7zip/Archive/Cab/CabHandler.cpp
index 20f670d3..fd707fe5 100755
--- a/CPP/7zip/Archive/Cab/CabHandler.cpp
+++ b/CPP/7zip/Archive/Cab/CabHandler.cpp
@@ -4,9 +4,7 @@
#include "../../../../C/Alloc.h"
-#include "Common/Buffer.h"
#include "Common/ComTry.h"
-#include "Common/Defs.h"
#include "Common/IntToString.h"
#include "Common/StringConvert.h"
#include "Common/UTFConvert.h"
@@ -654,7 +652,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
bool allFilesMode = (numItems == (UInt32)-1);
if (allFilesMode)
numItems = m_Database.Items.Size();
- if(numItems == 0)
+ if (numItems == 0)
return S_OK;
bool testMode = (testModeSpec != 0);
UInt64 totalUnPacked = 0;
@@ -780,12 +778,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
curUnpack, extractCallback, testMode);
cabBlockInStreamSpec->MsZip = false;
+ HRESULT res = S_OK;
switch(folder.GetCompressionMethod())
{
case NHeader::NCompressionMethodMajor::kNone:
break;
case NHeader::NCompressionMethodMajor::kMSZip:
- if(deflateDecoderSpec == NULL)
+ if (!deflateDecoder)
{
deflateDecoderSpec = new NCompress::NDeflate::NDecoder::CCOMCoder;
deflateDecoder = deflateDecoderSpec;
@@ -793,33 +792,35 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
cabBlockInStreamSpec->MsZip = true;
break;
case NHeader::NCompressionMethodMajor::kLZX:
- if(lzxDecoderSpec == NULL)
+ if (!lzxDecoder)
{
lzxDecoderSpec = new NCompress::NLzx::CDecoder;
lzxDecoder = lzxDecoderSpec;
}
- RINOK(lzxDecoderSpec->SetParams(folder.CompressionTypeMinor));
+ res = lzxDecoderSpec->SetParams(folder.CompressionTypeMinor);
break;
case NHeader::NCompressionMethodMajor::kQuantum:
- if(quantumDecoderSpec == NULL)
+ if (!quantumDecoder)
{
quantumDecoderSpec = new NCompress::NQuantum::CDecoder;
quantumDecoder = quantumDecoderSpec;
}
- quantumDecoderSpec->SetParams(folder.CompressionTypeMinor);
+ res = quantumDecoderSpec->SetParams(folder.CompressionTypeMinor);
break;
default:
- {
- RINOK(cabFolderOutStream->Unsupported());
- totalUnPacked += curUnpack;
- continue;
- }
+ res = E_INVALIDARG;
+ break;
}
- cabBlockInStreamSpec->InitForNewFolder();
-
- HRESULT res = S_OK;
+ if (res == E_INVALIDARG)
+ {
+ RINOK(cabFolderOutStream->Unsupported());
+ totalUnPacked += curUnpack;
+ continue;
+ }
+ RINOK(res);
+ cabBlockInStreamSpec->InitForNewFolder();
{
int volIndex = mvItem.VolumeIndex;
int locFolderIndex = item.GetFolderIndex(db.Folders.Size());
diff --git a/CPP/7zip/Archive/Chm/ChmIn.h b/CPP/7zip/Archive/Chm/ChmIn.h
index 4719a484..4b1ac7a6 100755
--- a/CPP/7zip/Archive/Chm/ChmIn.h
+++ b/CPP/7zip/Archive/Chm/ChmIn.h
@@ -39,7 +39,7 @@ struct CItem
{
if (Name.Length() == 0)
return false;
- return (Name[Name.Length() - 1] == '/');
+ return (Name.Back() == '/');
}
};
diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
index d76450bd..87686e85 100755
--- a/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
+++ b/CPP/7zip/Archive/Common/CoderMixer2MT.cpp
@@ -214,7 +214,7 @@ STDMETHODIMP CCoderMixer2MT::Code(ISequentialInStream **inStreams,
for (i = 0; i < _coders.Size(); i++)
if (i != _progressCoderIndex)
- _coders[i].WaitFinish();
+ _coders[i].WaitExecuteFinish();
RINOK(ReturnIfError(E_ABORT));
RINOK(ReturnIfError(E_OUTOFMEMORY));
diff --git a/CPP/7zip/Archive/Common/CoderMixer2MT.h b/CPP/7zip/Archive/Common/CoderMixer2MT.h
index d1c7f4d0..81bb3f0b 100755
--- a/CPP/7zip/Archive/Common/CoderMixer2MT.h
+++ b/CPP/7zip/Archive/Common/CoderMixer2MT.h
@@ -19,6 +19,7 @@ struct CCoder2: public CCoderInfo2, public CVirtThread
CRecordVector<ISequentialOutStream*> OutStreamPointers;
CCoder2(UInt32 numInStreams, UInt32 numOutStreams);
+ ~CCoder2() { CVirtThread::WaitThreadFinish(); }
void SetCoderInfo(const UInt64 **inSizes, const UInt64 **outSizes);
virtual void Execute();
void Code(ICompressProgressInfo *progress);
diff --git a/CPP/7zip/Archive/Common/CoderMixer2ST.cpp b/CPP/7zip/Archive/Common/CoderMixer2ST.cpp
index a59ce5fc..a21ca0c0 100755
--- a/CPP/7zip/Archive/Common/CoderMixer2ST.cpp
+++ b/CPP/7zip/Archive/Common/CoderMixer2ST.cpp
@@ -4,7 +4,7 @@
#include "CoderMixer2ST.h"
-namespace NCoderMixer2 {
+namespace NCoderMixer {
CCoderMixer2ST::CCoderMixer2ST() {}
@@ -42,7 +42,7 @@ HRESULT CCoderMixer2ST::GetInStream(
{
CMyComPtr<ISequentialInStream> seqInStream;
int i;
- for(i = 0; i < _bindInfo.InStreams.Size(); i++)
+ for (i = 0; i < _bindInfo.InStreams.Size(); i++)
if (_bindInfo.InStreams[i] == streamIndex)
{
seqInStream = inStreams[i];
@@ -57,7 +57,7 @@ HRESULT CCoderMixer2ST::GetInStream(
_bindInfo.FindOutStream(_bindInfo.BindPairs[binderIndex].OutIndex,
coderIndex, coderStreamIndex);
- CCoderInfo &coder = _coders[coderIndex];
+ CCoderInfo2 &coder = _coders[coderIndex];
if (!coder.Coder)
return E_NOTIMPL;
coder.Coder.QueryInterface(IID_ISequentialInStream, &seqInStream);
@@ -91,7 +91,7 @@ HRESULT CCoderMixer2ST::GetOutStream(
{
CMyComPtr<ISequentialOutStream> seqOutStream;
int i;
- for(i = 0; i < _bindInfo.OutStreams.Size(); i++)
+ for (i = 0; i < _bindInfo.OutStreams.Size(); i++)
if (_bindInfo.OutStreams[i] == streamIndex)
{
seqOutStream = outStreams[i];
@@ -106,7 +106,7 @@ HRESULT CCoderMixer2ST::GetOutStream(
_bindInfo.FindInStream(_bindInfo.BindPairs[binderIndex].InIndex,
coderIndex, coderStreamIndex);
- CCoderInfo &coder = _coders[coderIndex];
+ CCoderInfo2 &coder = _coders[coderIndex];
if (!coder.Coder)
return E_NOTIMPL;
coder.Coder.QueryInterface(IID_ISequentialOutStream, &seqOutStream);
@@ -169,7 +169,7 @@ STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams,
// _mainCoderIndex = 0;
// _mainCoderIndex = _coders.Size() - 1;
- CCoderInfo &mainCoder = _coders[_mainCoderIndex];
+ CCoderInfo2 &mainCoder = _coders[_mainCoderIndex];
CObjectVector< CMyComPtr<ISequentialInStream> > seqInStreams;
CObjectVector< CMyComPtr<ISequentialOutStream> > seqOutStreams;
@@ -198,7 +198,7 @@ STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams,
{
if (i == _mainCoderIndex)
continue;
- CCoderInfo &coder = _coders[i];
+ CCoderInfo2 &coder = _coders[i];
CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize;
coder.Coder.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize);
if (setOutStreamSize)
diff --git a/CPP/7zip/Archive/Common/CoderMixer2ST.h b/CPP/7zip/Archive/Common/CoderMixer2ST.h
index a4ea7e80..d35655ba 100755
--- a/CPP/7zip/Archive/Common/CoderMixer2ST.h
+++ b/CPP/7zip/Archive/Common/CoderMixer2ST.h
@@ -7,7 +7,7 @@
#include "../../../Common/MyCom.h"
#include "../../ICoder.h"
-namespace NCoderMixer2 {
+namespace NCoderMixer {
// SetBindInfo()
// for each coder
@@ -26,11 +26,11 @@ namespace NCoderMixer2 {
// Code
// }
-struct CSTCoderInfo: public CCoderInfo
+struct CSTCoderInfo: public CCoderInfo2
{
bool IsMain;
CSTCoderInfo(UInt32 numInStreams, UInt32 numOutStreams, bool isMain):
- CCoderInfo(numInStreams, numOutStreams),IsMain(isMain) {}
+ CCoderInfo2(numInStreams, numOutStreams), IsMain(isMain) {}
};
class CCoderMixer2ST:
@@ -84,5 +84,5 @@ public:
};
}
-#endif
+#endif
diff --git a/CPP/7zip/Archive/Common/CoderMixerMT.cpp b/CPP/7zip/Archive/Common/CoderMixerMT.cpp
index f43d1612..96ea76a3 100755
--- a/CPP/7zip/Archive/Common/CoderMixerMT.cpp
+++ b/CPP/7zip/Archive/Common/CoderMixerMT.cpp
@@ -73,7 +73,7 @@ STDMETHODIMP CCoderMixerMT::Code(ISequentialInStream *inStream,
for (i = 0; i < _coders.Size(); i++)
if (i != _progressCoderIndex)
- _coders[i].WaitFinish();
+ _coders[i].WaitExecuteFinish();
RINOK(ReturnIfError(E_ABORT));
RINOK(ReturnIfError(E_OUTOFMEMORY));
diff --git a/CPP/7zip/Archive/Common/CoderMixerMT.h b/CPP/7zip/Archive/Common/CoderMixerMT.h
index c70e1829..9491a965 100755
--- a/CPP/7zip/Archive/Common/CoderMixerMT.h
+++ b/CPP/7zip/Archive/Common/CoderMixerMT.h
@@ -18,6 +18,7 @@ struct CCoder: public CCoderInfo, public CVirtThread
virtual void Execute();
void Code(ICompressProgressInfo *progress);
+ ~CCoder() { CVirtThread::WaitThreadFinish(); }
};
/*
diff --git a/CPP/7zip/Archive/Common/HandlerOut.cpp b/CPP/7zip/Archive/Common/HandlerOut.cpp
index 70ad47aa..7e6f4602 100755
--- a/CPP/7zip/Archive/Common/HandlerOut.cpp
+++ b/CPP/7zip/Archive/Common/HandlerOut.cpp
@@ -2,16 +2,10 @@
#include "StdAfx.h"
-#include "../../../Common/StringToInt.h"
-
-#include "../../../Windows/PropVariant.h"
-
#ifndef _7ZIP_ST
#include "../../../Windows/System.h"
#endif
-#include "../../ICoder.h"
-
#include "../Common/ParseProperties.h"
#include "HandlerOut.h"
@@ -20,487 +14,40 @@ using namespace NWindows;
namespace NArchive {
-static const wchar_t *kCopyMethod = L"Copy";
-static const wchar_t *kLZMAMethodName = L"LZMA";
-static const wchar_t *kLZMA2MethodName = L"LZMA2";
-static const wchar_t *kBZip2MethodName = L"BZip2";
-static const wchar_t *kPpmdMethodName = L"PPMd";
-static const wchar_t *kDeflateMethodName = L"Deflate";
-static const wchar_t *kDeflate64MethodName = L"Deflate64";
-
-static const wchar_t *kLzmaMatchFinderX1 = L"HC4";
-static const wchar_t *kLzmaMatchFinderX5 = L"BT4";
-
-static const UInt32 kLzmaAlgoX1 = 0;
-static const UInt32 kLzmaAlgoX5 = 1;
-
-static const UInt32 kLzmaDicSizeX1 = 1 << 16;
-static const UInt32 kLzmaDicSizeX3 = 1 << 20;
-static const UInt32 kLzmaDicSizeX5 = 1 << 24;
-static const UInt32 kLzmaDicSizeX7 = 1 << 25;
-static const UInt32 kLzmaDicSizeX9 = 1 << 26;
-
-static const UInt32 kLzmaFastBytesX1 = 32;
-static const UInt32 kLzmaFastBytesX7 = 64;
-
-static const UInt32 kPpmdMemSizeX1 = (1 << 22);
-static const UInt32 kPpmdMemSizeX5 = (1 << 24);
-static const UInt32 kPpmdMemSizeX7 = (1 << 26);
-static const UInt32 kPpmdMemSizeX9 = (192 << 20);
-
-static const UInt32 kPpmdOrderX1 = 4;
-static const UInt32 kPpmdOrderX5 = 6;
-static const UInt32 kPpmdOrderX7 = 16;
-static const UInt32 kPpmdOrderX9 = 32;
-
-static const UInt32 kDeflateAlgoX1 = 0;
-static const UInt32 kDeflateAlgoX5 = 1;
-
-static const UInt32 kDeflateFastBytesX1 = 32;
-static const UInt32 kDeflateFastBytesX7 = 64;
-static const UInt32 kDeflateFastBytesX9 = 128;
-
-static const UInt32 kDeflatePassesX1 = 1;
-static const UInt32 kDeflatePassesX7 = 3;
-static const UInt32 kDeflatePassesX9 = 10;
-
-static const UInt32 kBZip2NumPassesX1 = 1;
-static const UInt32 kBZip2NumPassesX7 = 2;
-static const UInt32 kBZip2NumPassesX9 = 7;
-
-static const UInt32 kBZip2DicSizeX1 = 100000;
-static const UInt32 kBZip2DicSizeX3 = 500000;
-static const UInt32 kBZip2DicSizeX5 = 900000;
-
-static const wchar_t *kDefaultMethodName = kLZMAMethodName;
-
-static const wchar_t *kLzmaMatchFinderForHeaders = L"BT2";
-static const UInt32 kDictionaryForHeaders = 1 << 20;
-static const UInt32 kNumFastBytesForHeaders = 273;
-static const UInt32 kAlgorithmForHeaders = kLzmaAlgoX5;
-
-static bool AreEqual(const UString &methodName, const wchar_t *s)
- { return (methodName.CompareNoCase(s) == 0); }
-
-bool COneMethodInfo::IsLzma() const
-{
- return
- AreEqual(MethodName, kLZMAMethodName) ||
- AreEqual(MethodName, kLZMA2MethodName);
-}
-
-static inline bool IsBZip2Method(const UString &methodName)
- { return AreEqual(methodName, kBZip2MethodName); }
-
-static inline bool IsPpmdMethod(const UString &methodName)
- { return AreEqual(methodName, kPpmdMethodName); }
-
-static inline bool IsDeflateMethod(const UString &methodName)
-{
- return
- AreEqual(methodName, kDeflateMethodName) ||
- AreEqual(methodName, kDeflate64MethodName);
-}
-
-struct CNameToPropID
-{
- PROPID PropID;
- VARTYPE VarType;
- const wchar_t *Name;
-};
-
-static CNameToPropID g_NameToPropID[] =
-{
- { NCoderPropID::kBlockSize, VT_UI4, L"C" },
- { NCoderPropID::kDictionarySize, VT_UI4, L"D" },
- { NCoderPropID::kUsedMemorySize, VT_UI4, L"MEM" },
-
- { NCoderPropID::kOrder, VT_UI4, L"O" },
- { NCoderPropID::kPosStateBits, VT_UI4, L"PB" },
- { NCoderPropID::kLitContextBits, VT_UI4, L"LC" },
- { NCoderPropID::kLitPosBits, VT_UI4, L"LP" },
- { NCoderPropID::kEndMarker, VT_BOOL, L"eos" },
-
- { NCoderPropID::kNumPasses, VT_UI4, L"Pass" },
- { NCoderPropID::kNumFastBytes, VT_UI4, L"fb" },
- { NCoderPropID::kMatchFinderCycles, VT_UI4, L"mc" },
- { NCoderPropID::kAlgorithm, VT_UI4, L"a" },
- { NCoderPropID::kMatchFinder, VT_BSTR, L"mf" },
- { NCoderPropID::kNumThreads, VT_UI4, L"mt" },
- { NCoderPropID::kDefaultProp, VT_UI4, L"" }
-};
-
-static bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType, NCOM::CPropVariant &destProp)
-{
- if (varType == srcProp.vt)
- {
- destProp = srcProp;
- return true;
- }
- if (varType == VT_UI1)
- {
- if (srcProp.vt == VT_UI4)
- {
- UInt32 value = srcProp.ulVal;
- if (value > 0xFF)
- return false;
- destProp = (Byte)value;
- return true;
- }
- }
- else if (varType == VT_BOOL)
- {
- bool res;
- if (SetBoolProperty(res, srcProp) != S_OK)
- return false;
- destProp = res;
- return true;
- }
- return false;
-}
-
-static int FindPropIdExact(const UString &name)
-{
- for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++)
- if (name.CompareNoCase(g_NameToPropID[i].Name) == 0)
- return i;
- return -1;
-}
-
-static int FindPropIdStart(const UString &name)
+static void SetMethodProp32(COneMethodInfo &m, PROPID propID, UInt32 value)
{
- for (int i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++)
- {
- UString t = g_NameToPropID[i].Name;
- if (t.CompareNoCase(name.Left(t.Length())) == 0)
- return i;
- }
- return -1;
+ if (m.FindProp(propID) < 0)
+ m.AddProp32(propID, value);
}
-static void SetMethodProp(COneMethodInfo &m, PROPID propID, const NCOM::CPropVariant &value)
-{
- for (int j = 0; j < m.Props.Size(); j++)
- if (m.Props[j].Id == propID)
- return;
- CProp prop;
- prop.Id = propID;
- prop.Value = value;
- m.Props.Add(prop);
-}
-
-void COutHandler::SetCompressionMethod2(COneMethodInfo &oneMethodInfo
+void CMultiMethodProps::SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
)
{
UInt32 level = _level;
- if (oneMethodInfo.MethodName.IsEmpty())
- oneMethodInfo.MethodName = kDefaultMethodName;
-
- if (oneMethodInfo.IsLzma())
- {
- UInt32 dicSize =
- (level >= 9 ? kLzmaDicSizeX9 :
- (level >= 7 ? kLzmaDicSizeX7 :
- (level >= 5 ? kLzmaDicSizeX5 :
- (level >= 3 ? kLzmaDicSizeX3 :
- kLzmaDicSizeX1))));
-
- UInt32 algo =
- (level >= 5 ? kLzmaAlgoX5 :
- kLzmaAlgoX1);
-
- UInt32 fastBytes =
- (level >= 7 ? kLzmaFastBytesX7 :
- kLzmaFastBytesX1);
-
- const wchar_t *matchFinder =
- (level >= 5 ? kLzmaMatchFinderX5 :
- kLzmaMatchFinderX1);
-
- SetMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
- SetMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
- SetMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
- SetMethodProp(oneMethodInfo, NCoderPropID::kMatchFinder, matchFinder);
- #ifndef _7ZIP_ST
- SetMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
- #endif
- }
- else if (IsDeflateMethod(oneMethodInfo.MethodName))
- {
- UInt32 fastBytes =
- (level >= 9 ? kDeflateFastBytesX9 :
- (level >= 7 ? kDeflateFastBytesX7 :
- kDeflateFastBytesX1));
-
- UInt32 numPasses =
- (level >= 9 ? kDeflatePassesX9 :
- (level >= 7 ? kDeflatePassesX7 :
- kDeflatePassesX1));
-
- UInt32 algo =
- (level >= 5 ? kDeflateAlgoX5 :
- kDeflateAlgoX1);
-
- SetMethodProp(oneMethodInfo, NCoderPropID::kAlgorithm, algo);
- SetMethodProp(oneMethodInfo, NCoderPropID::kNumFastBytes, fastBytes);
- SetMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
- }
- else if (IsBZip2Method(oneMethodInfo.MethodName))
- {
- UInt32 numPasses =
- (level >= 9 ? kBZip2NumPassesX9 :
- (level >= 7 ? kBZip2NumPassesX7 :
- kBZip2NumPassesX1));
-
- UInt32 dicSize =
- (level >= 5 ? kBZip2DicSizeX5 :
- (level >= 3 ? kBZip2DicSizeX3 :
- kBZip2DicSizeX1));
-
- SetMethodProp(oneMethodInfo, NCoderPropID::kNumPasses, numPasses);
- SetMethodProp(oneMethodInfo, NCoderPropID::kDictionarySize, dicSize);
- #ifndef _7ZIP_ST
- SetMethodProp(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
- #endif
- }
- else if (IsPpmdMethod(oneMethodInfo.MethodName))
- {
- UInt32 useMemSize =
- (level >= 9 ? kPpmdMemSizeX9 :
- (level >= 7 ? kPpmdMemSizeX7 :
- (level >= 5 ? kPpmdMemSizeX5 :
- kPpmdMemSizeX1)));
-
- UInt32 order =
- (level >= 9 ? kPpmdOrderX9 :
- (level >= 7 ? kPpmdOrderX7 :
- (level >= 5 ? kPpmdOrderX5 :
- kPpmdOrderX1)));
-
- SetMethodProp(oneMethodInfo, NCoderPropID::kUsedMemorySize, useMemSize);
- SetMethodProp(oneMethodInfo, NCoderPropID::kOrder, order);
- }
-}
-
-static void SplitParams(const UString &srcString, UStringVector &subStrings)
-{
- subStrings.Clear();
- UString name;
- int len = srcString.Length();
- if (len == 0)
- return;
- for (int i = 0; i < len; i++)
- {
- wchar_t c = srcString[i];
- if (c == L':')
- {
- subStrings.Add(name);
- name.Empty();
- }
- else
- name += c;
- }
- subStrings.Add(name);
-}
-
-static void SplitParam(const UString &param, UString &name, UString &value)
-{
- int eqPos = param.Find(L'=');
- if (eqPos >= 0)
- {
- name = param.Left(eqPos);
- value = param.Mid(eqPos + 1);
- return;
- }
- for(int i = 0; i < param.Length(); i++)
- {
- wchar_t c = param[i];
- if (c >= L'0' && c <= L'9')
- {
- name = param.Left(i);
- value = param.Mid(i);
- return;
- }
- }
- name = param;
-}
-
-HRESULT COutHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value)
-{
- CProp prop;
- int index = FindPropIdExact(name);
- if (index < 0)
- return E_INVALIDARG;
- const CNameToPropID &nameToPropID = g_NameToPropID[index];
- prop.Id = nameToPropID.PropID;
-
- if (prop.Id == NCoderPropID::kBlockSize ||
- prop.Id == NCoderPropID::kDictionarySize ||
- prop.Id == NCoderPropID::kUsedMemorySize)
- {
- UInt32 dicSize;
- RINOK(ParsePropDictionaryValue(value, dicSize));
- prop.Value = dicSize;
- }
- else
- {
- NCOM::CPropVariant propValue;
-
- if (nameToPropID.VarType == VT_BSTR)
- propValue = value;
- else if (nameToPropID.VarType == VT_BOOL)
- {
- bool res;
- if (!StringToBool(value, res))
- return E_INVALIDARG;
- propValue = res;
- }
- else
- {
- UInt32 number;
- if (ParseStringToUInt32(value, number) == value.Length())
- propValue = number;
- else
- propValue = value;
- }
-
- if (!ConvertProperty(propValue, nameToPropID.VarType, prop.Value))
- return E_INVALIDARG;
- }
- oneMethodInfo.Props.Add(prop);
- return S_OK;
-}
-
-HRESULT COutHandler::SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString)
-{
- UStringVector params;
- SplitParams(srcString, params);
- if (params.Size() > 0)
- oneMethodInfo.MethodName = params[0];
- for (int i = 1; i < params.Size(); i++)
- {
- const UString &param = params[i];
- UString name, value;
- SplitParam(param, name, value);
- RINOK(SetParam(oneMethodInfo, name, value));
- }
- return S_OK;
-}
-
-HRESULT COutHandler::SetSolidSettings(const UString &s)
-{
- UString s2 = s;
- s2.MakeUpper();
- for (int i = 0; i < s2.Length();)
- {
- const wchar_t *start = ((const wchar_t *)s2) + i;
- const wchar_t *end;
- UInt64 v = ConvertStringToUInt64(start, &end);
- if (start == end)
- {
- if (s2[i++] != 'E')
- return E_INVALIDARG;
- _solidExtension = true;
- continue;
- }
- i += (int)(end - start);
- if (i == s2.Length())
- return E_INVALIDARG;
- wchar_t c = s2[i++];
- switch(c)
- {
- case 'F':
- if (v < 1)
- v = 1;
- _numSolidFiles = v;
- break;
- case 'B':
- _numSolidBytes = v;
- _numSolidBytesDefined = true;
- break;
- case 'K':
- _numSolidBytes = (v << 10);
- _numSolidBytesDefined = true;
- break;
- case 'M':
- _numSolidBytes = (v << 20);
- _numSolidBytesDefined = true;
- break;
- case 'G':
- _numSolidBytes = (v << 30);
- _numSolidBytesDefined = true;
- break;
- default:
- return E_INVALIDARG;
- }
- }
- return S_OK;
-}
-
-HRESULT COutHandler::SetSolidSettings(const PROPVARIANT &value)
-{
- bool isSolid;
- switch(value.vt)
- {
- case VT_EMPTY:
- isSolid = true;
- break;
- case VT_BOOL:
- isSolid = (value.boolVal != VARIANT_FALSE);
- break;
- case VT_BSTR:
- if (StringToBool(value.bstrVal, isSolid))
- break;
- return SetSolidSettings(value.bstrVal);
- default:
- return E_INVALIDARG;
- }
- if (isSolid)
- InitSolid();
- else
- _numSolidFiles = 1;
- return S_OK;
-}
-
-void COutHandler::Init()
-{
- _removeSfxBlock = false;
- _compressHeaders = true;
- _encryptHeadersSpecified = false;
- _encryptHeaders = false;
-
- WriteCTime = false;
- WriteATime = false;
- WriteMTime = true;
-
+ if (level != (UInt32)(UInt32)-1)
+ SetMethodProp32(oneMethodInfo, NCoderPropID::kLevel, (UInt32)level);
#ifndef _7ZIP_ST
- _numThreads = NSystem::GetNumberOfProcessors();
+ SetMethodProp32(oneMethodInfo, NCoderPropID::kNumThreads, numThreads);
#endif
-
- _level = 5;
- _autoFilter = true;
- _volumeMode = false;
- _crcSize = 4;
- InitSolid();
}
-void COutHandler::BeforeSetProperty()
+void CMultiMethodProps::Init()
{
- Init();
#ifndef _7ZIP_ST
- numProcessors = NSystem::GetNumberOfProcessors();
+ _numProcessors = _numThreads = NSystem::GetNumberOfProcessors();
#endif
-
- mainDicSize = 0xFFFFFFFF;
- mainDicMethodIndex = 0xFFFFFFFF;
- minNumber = 0;
+
+ _level = (UInt32)(UInt32)-1;
+ _autoFilter = true;
_crcSize = 4;
+ _filterMethod.Clear();
+ _methods.Clear();
}
-HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
+HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
{
UString name = nameSpec;
name.MakeUpper();
@@ -511,24 +58,14 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
{
name.Delete(0);
_level = 9;
- return ParsePropValue(name, value, _level);
- }
-
- if (name[0] == L'S')
- {
- name.Delete(0);
- if (name.IsEmpty())
- return SetSolidSettings(value);
- if (value.vt != VT_EMPTY)
- return E_INVALIDARG;
- return SetSolidSettings(name);
+ return ParsePropToUInt32(name, value, _level);
}
if (name == L"CRC")
{
- _crcSize = 4;
name.Delete(0, 3);
- return ParsePropValue(name, value, _crcSize);
+ _crcSize = 4;
+ return ParsePropToUInt32(name, value, _crcSize);
}
UInt32 number;
@@ -536,86 +73,67 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
UString realName = name.Mid(index);
if (index == 0)
{
- if(name.Left(2).CompareNoCase(L"MT") == 0)
+ if (name.Left(2).CompareNoCase(L"MT") == 0)
{
#ifndef _7ZIP_ST
- RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
+ RINOK(ParseMtProp(name.Mid(2), value, _numProcessors, _numThreads));
#endif
return S_OK;
}
- if (name.CompareNoCase(L"RSFX") == 0) return SetBoolProperty(_removeSfxBlock, value);
- if (name.CompareNoCase(L"F") == 0) return SetBoolProperty(_autoFilter, value);
- if (name.CompareNoCase(L"HC") == 0) return SetBoolProperty(_compressHeaders, value);
- if (name.CompareNoCase(L"HCF") == 0)
+ if (name.CompareNoCase(L"F") == 0)
{
- bool compressHeadersFull = true;
- RINOK(SetBoolProperty(compressHeadersFull, value));
- if (!compressHeadersFull)
+ HRESULT res = PROPVARIANT_to_bool(value, _autoFilter);
+ if (res == S_OK)
+ return res;
+ if (value.vt != VT_BSTR)
return E_INVALIDARG;
- return S_OK;
+ return _filterMethod.ParseMethodFromPROPVARIANT(L"", value);
}
- if (name.CompareNoCase(L"HE") == 0)
- {
- RINOK(SetBoolProperty(_encryptHeaders, value));
- _encryptHeadersSpecified = true;
- return S_OK;
- }
- if (name.CompareNoCase(L"TC") == 0) return SetBoolProperty(WriteCTime, value);
- if (name.CompareNoCase(L"TA") == 0) return SetBoolProperty(WriteATime, value);
- if (name.CompareNoCase(L"TM") == 0) return SetBoolProperty(WriteMTime, value);
- if (name.CompareNoCase(L"V") == 0) return SetBoolProperty(_volumeMode, value);
number = 0;
}
- if (number > 10000)
+ if (number > 64)
return E_FAIL;
- if (number < minNumber)
- return E_INVALIDARG;
- number -= minNumber;
- for(int j = _methods.Size(); j <= (int)number; j++)
- {
- COneMethodInfo oneMethodInfo;
- _methods.Add(oneMethodInfo);
- }
-
- COneMethodInfo &oneMethodInfo = _methods[number];
-
- if (realName.Length() == 0)
- {
- if (value.vt != VT_BSTR)
- return E_INVALIDARG;
-
- RINOK(SetParams(oneMethodInfo, value.bstrVal));
- }
- else
+ for (int j = _methods.Size(); j <= (int)number; j++)
+ _methods.Add(COneMethodInfo());
+ return _methods[number].ParseMethodFromPROPVARIANT(realName, value);
+}
+
+void CSingleMethodProps::Init()
+{
+ Clear();
+ #ifndef _7ZIP_ST
+ _numProcessors = _numThreads = NWindows::NSystem::GetNumberOfProcessors();
+ AddNumThreadsProp(_numThreads);
+ #endif
+ _level = (UInt32)(UInt32)-1;
+}
+
+HRESULT CSingleMethodProps::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
+{
+ Init();
+ for (int i = 0; i < numProps; i++)
{
- int index = FindPropIdStart(realName);
- if (index < 0)
+ UString name = names[i];
+ name.MakeUpper();
+ if (name.IsEmpty())
return E_INVALIDARG;
- const CNameToPropID &nameToPropID = g_NameToPropID[index];
- CProp prop;
- prop.Id = nameToPropID.PropID;
-
- if (prop.Id == NCoderPropID::kBlockSize ||
- prop.Id == NCoderPropID::kDictionarySize ||
- prop.Id == NCoderPropID::kUsedMemorySize)
+ const PROPVARIANT &value = values[i];
+ if (name[0] == L'X')
{
- UInt32 dicSize;
- RINOK(ParsePropDictionaryValue(realName.Mid(MyStringLen(nameToPropID.Name)), value, dicSize));
- prop.Value = dicSize;
- if (number <= mainDicMethodIndex)
- mainDicSize = dicSize;
+ UInt32 a = 9;
+ RINOK(ParsePropToUInt32(name.Mid(1), value, a));
+ _level = a;
+ AddLevelProp(a);
}
- else
+ else if (name.Left(2).CompareNoCase(L"MT") == 0)
{
- int index = FindPropIdExact(realName);
- if (index < 0)
- return E_INVALIDARG;
- const CNameToPropID &nameToPropID = g_NameToPropID[index];
- prop.Id = nameToPropID.PropID;
- if (!ConvertProperty(value, nameToPropID.VarType, prop.Value))
- return E_INVALIDARG;
+ #ifndef _7ZIP_ST
+ RINOK(ParseMtProp(name.Mid(2), value, _numProcessors, _numThreads));
+ AddNumThreadsProp(_numThreads);
+ #endif
}
- oneMethodInfo.Props.Add(prop);
+ else
+ return ParseParamsFromPROPVARIANT(name, value);
}
return S_OK;
}
diff --git a/CPP/7zip/Archive/Common/HandlerOut.h b/CPP/7zip/Archive/Common/HandlerOut.h
index 72ea4032..d3c9a237 100755
--- a/CPP/7zip/Archive/Common/HandlerOut.h
+++ b/CPP/7zip/Archive/Common/HandlerOut.h
@@ -3,83 +3,61 @@
#ifndef __HANDLER_OUT_H
#define __HANDLER_OUT_H
-#include "../../../Common/MyString.h"
#include "../../Common/MethodProps.h"
namespace NArchive {
-struct COneMethodInfo
-{
- CObjectVector<CProp> Props;
- UString MethodName;
-
- bool IsLzma() const;
-};
-
-class COutHandler
+class CMultiMethodProps
{
+ UInt32 _level;
public:
- HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
-
- HRESULT SetSolidSettings(const UString &s);
- HRESULT SetSolidSettings(const PROPVARIANT &value);
-
#ifndef _7ZIP_ST
UInt32 _numThreads;
+ UInt32 _numProcessors;
#endif
UInt32 _crcSize;
-
CObjectVector<COneMethodInfo> _methods;
- bool _removeSfxBlock;
-
- UInt64 _numSolidFiles;
- UInt64 _numSolidBytes;
- bool _numSolidBytesDefined;
- bool _solidExtension;
-
- bool _compressHeaders;
- bool _encryptHeadersSpecified;
- bool _encryptHeaders;
-
- bool WriteCTime;
- bool WriteATime;
- bool WriteMTime;
-
+ COneMethodInfo _filterMethod;
bool _autoFilter;
- UInt32 _level;
- bool _volumeMode;
-
- HRESULT SetParam(COneMethodInfo &oneMethodInfo, const UString &name, const UString &value);
- HRESULT SetParams(COneMethodInfo &oneMethodInfo, const UString &srcString);
-
- void SetCompressionMethod2(COneMethodInfo &oneMethodInfo
+ void SetGlobalLevelAndThreads(COneMethodInfo &oneMethodInfo
#ifndef _7ZIP_ST
, UInt32 numThreads
#endif
);
- void InitSolidFiles() { _numSolidFiles = (UInt64)(Int64)(-1); }
- void InitSolidSize() { _numSolidBytes = (UInt64)(Int64)(-1); }
- void InitSolid()
+ int GetNumEmptyMethods() const
{
- InitSolidFiles();
- InitSolidSize();
- _solidExtension = false;
- _numSolidBytesDefined = false;
+ int i;
+ for (i = 0; i < _methods.Size(); i++)
+ if (!_methods[i].IsEmpty())
+ break;
+ return i;
}
+ int GetLevel() const { return _level == (UInt32)(UInt32)-1 ? 5 : (int)_level; }
+
void Init();
- COutHandler() { Init(); }
+ CMultiMethodProps() { Init(); }
+ HRESULT SetProperty(const wchar_t *name, const PROPVARIANT &value);
+};
- void BeforeSetProperty();
+class CSingleMethodProps: public CMethodProps
+{
+ UInt32 _level;
+
+ void Init();
+public:
+ #ifndef _7ZIP_ST
+ UInt32 _numThreads;
+ UInt32 _numProcessors;
+ #endif
- UInt32 minNumber;
- UInt32 numProcessors;
- UInt32 mainDicSize;
- UInt32 mainDicMethodIndex;
+ CSingleMethodProps() { Init(); }
+ int GetLevel() const { return _level == (UInt32)(UInt32)-1 ? 5 : (int)_level; }
+ HRESULT SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);
};
}
diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/CPP/7zip/Archive/Common/ItemNameUtils.cpp
index a5e0dc0b..cc476fad 100755
--- a/CPP/7zip/Archive/Common/ItemNameUtils.cpp
+++ b/CPP/7zip/Archive/Common/ItemNameUtils.cpp
@@ -31,8 +31,8 @@ UString GetOSName2(const UString &name)
if (name.IsEmpty())
return UString();
UString newName = GetOSName(name);
- if (newName[newName.Length() - 1] == kOSDirDelimiter)
- newName.Delete(newName.Length() - 1);
+ if (newName.Back() == kOSDirDelimiter)
+ newName.DeleteBack();
return newName;
}
diff --git a/CPP/7zip/Archive/Common/ParseProperties.cpp b/CPP/7zip/Archive/Common/ParseProperties.cpp
index 5cd849e2..63e4f3ef 100755
--- a/CPP/7zip/Archive/Common/ParseProperties.cpp
+++ b/CPP/7zip/Archive/Common/ParseProperties.cpp
@@ -1,177 +1,3 @@
// ParseProperties.cpp
#include "StdAfx.h"
-
-#include "ParseProperties.h"
-
-#include "Common/StringToInt.h"
-#include "Common/MyCom.h"
-
-HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
-{
- if (prop.vt == VT_UI4)
- {
- if (!name.IsEmpty())
- return E_INVALIDARG;
- resValue = prop.ulVal;
- }
- else if (prop.vt == VT_EMPTY)
- {
- if(!name.IsEmpty())
- {
- const wchar_t *start = name;
- const wchar_t *end;
- UInt64 v = ConvertStringToUInt64(start, &end);
- if (end - start != name.Length())
- return E_INVALIDARG;
- resValue = (UInt32)v;
- }
- }
- else
- return E_INVALIDARG;
- return S_OK;
-}
-
-static const int kLogarithmicSizeLimit = 32;
-static const wchar_t kByteSymbol = L'B';
-static const wchar_t kKiloByteSymbol = L'K';
-static const wchar_t kMegaByteSymbol = L'M';
-
-HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize)
-{
- UString srcString = srcStringSpec;
- srcString.MakeUpper();
-
- const wchar_t *start = srcString;
- const wchar_t *end;
- UInt64 number = ConvertStringToUInt64(start, &end);
- int numDigits = (int)(end - start);
- if (numDigits == 0 || srcString.Length() > numDigits + 1)
- return E_INVALIDARG;
- if (srcString.Length() == numDigits)
- {
- if (number >= kLogarithmicSizeLimit)
- return E_INVALIDARG;
- dicSize = (UInt32)1 << (int)number;
- return S_OK;
- }
- switch (srcString[numDigits])
- {
- case kByteSymbol:
- if (number >= ((UInt64)1 << kLogarithmicSizeLimit))
- return E_INVALIDARG;
- dicSize = (UInt32)number;
- break;
- case kKiloByteSymbol:
- if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10)))
- return E_INVALIDARG;
- dicSize = (UInt32)(number << 10);
- break;
- case kMegaByteSymbol:
- if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20)))
- return E_INVALIDARG;
- dicSize = (UInt32)(number << 20);
- break;
- default:
- return E_INVALIDARG;
- }
- return S_OK;
-}
-
-HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
-{
- if (name.IsEmpty())
- {
- if (prop.vt == VT_UI4)
- {
- UInt32 logDicSize = prop.ulVal;
- if (logDicSize >= 32)
- return E_INVALIDARG;
- resValue = (UInt32)1 << logDicSize;
- return S_OK;
- }
- if (prop.vt == VT_BSTR)
- return ParsePropDictionaryValue(prop.bstrVal, resValue);
- return E_INVALIDARG;
- }
- return ParsePropDictionaryValue(name, resValue);
-}
-
-bool StringToBool(const UString &s, bool &res)
-{
- if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0 || s.Compare(L"+") == 0)
- {
- res = true;
- return true;
- }
- if (s.CompareNoCase(L"OFF") == 0 || s.Compare(L"-") == 0)
- {
- res = false;
- return true;
- }
- return false;
-}
-
-HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
-{
- switch(value.vt)
- {
- case VT_EMPTY:
- dest = true;
- return S_OK;
- case VT_BOOL:
- dest = (value.boolVal != VARIANT_FALSE);
- return S_OK;
- /*
- case VT_UI4:
- dest = (value.ulVal != 0);
- break;
- */
- case VT_BSTR:
- return StringToBool(value.bstrVal, dest) ? S_OK : E_INVALIDARG;
- }
- return E_INVALIDARG;
-}
-
-int ParseStringToUInt32(const UString &srcString, UInt32 &number)
-{
- const wchar_t *start = srcString;
- const wchar_t *end;
- UInt64 number64 = ConvertStringToUInt64(start, &end);
- if (number64 > 0xFFFFFFFF)
- {
- number = 0;
- return 0;
- }
- number = (UInt32)number64;
- return (int)(end - start);
-}
-
-HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
-{
- if (name.IsEmpty())
- {
- switch(prop.vt)
- {
- case VT_UI4:
- numThreads = prop.ulVal;
- break;
- default:
- {
- bool val;
- RINOK(SetBoolProperty(val, prop));
- numThreads = (val ? defaultNumThreads : 1);
- break;
- }
- }
- }
- else
- {
- UInt32 number;
- int index = ParseStringToUInt32(name, number);
- if (index != name.Length())
- return E_INVALIDARG;
- numThreads = number;
- }
- return S_OK;
-}
diff --git a/CPP/7zip/Archive/Common/ParseProperties.h b/CPP/7zip/Archive/Common/ParseProperties.h
index 6f80f634..1038a8c0 100755
--- a/CPP/7zip/Archive/Common/ParseProperties.h
+++ b/CPP/7zip/Archive/Common/ParseProperties.h
@@ -1,18 +1,6 @@
// ParseProperties.h
-#ifndef __PARSEPROPERTIES_H
-#define __PARSEPROPERTIES_H
-
-#include "Common/MyString.h"
-#include "Common/Types.h"
-
-HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
-HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize);
-HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
-
-bool StringToBool(const UString &s, bool &res);
-HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value);
-int ParseStringToUInt32(const UString &srcString, UInt32 &number);
-HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);
+#ifndef __PARSE_PROPERTIES_H
+#define __PARSE_PROPERTIES_H
#endif
diff --git a/CPP/7zip/Archive/DeflateProps.cpp b/CPP/7zip/Archive/DeflateProps.cpp
index 8498e056..ca3dc6f5 100755
--- a/CPP/7zip/Archive/DeflateProps.cpp
+++ b/CPP/7zip/Archive/DeflateProps.cpp
@@ -1,118 +1,3 @@
// DeflateProps.cpp
#include "StdAfx.h"
-
-#include "Windows/PropVariant.h"
-
-#include "Common/ParseProperties.h"
-
-#include "DeflateProps.h"
-
-namespace NArchive {
-
-static const UInt32 kAlgo1 = 0;
-static const UInt32 kAlgo5 = 1;
-
-static const UInt32 kPasses1 = 1;
-static const UInt32 kPasses7 = 3;
-static const UInt32 kPasses9 = 10;
-
-static const UInt32 kFb1 = 32;
-static const UInt32 kFb7 = 64;
-static const UInt32 kFb9 = 128;
-
-void CDeflateProps::Normalize()
-{
- UInt32 level = Level;
- if (level == 0xFFFFFFFF)
- level = 5;
-
- if (Algo == 0xFFFFFFFF)
- Algo = (level >= 5 ?
- kAlgo5 :
- kAlgo1);
-
- if (NumPasses == 0xFFFFFFFF)
- NumPasses =
- (level >= 9 ? kPasses9 :
- (level >= 7 ? kPasses7 :
- kPasses1));
- if (Fb == 0xFFFFFFFF)
- Fb =
- (level >= 9 ? kFb9 :
- (level >= 7 ? kFb7 :
- kFb1));
-}
-
-HRESULT CDeflateProps::SetCoderProperties(ICompressSetCoderProperties *setCoderProperties)
-{
- Normalize();
-
- NWindows::NCOM::CPropVariant props[] =
- {
- Algo,
- NumPasses,
- Fb,
- Mc
- };
- PROPID propIDs[] =
- {
- NCoderPropID::kAlgorithm,
- NCoderPropID::kNumPasses,
- NCoderPropID::kNumFastBytes,
- NCoderPropID::kMatchFinderCycles
- };
- int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
- if (!McDefined)
- numProps--;
- return setCoderProperties->SetCoderProperties(propIDs, props, numProps);
-}
-
-HRESULT CDeflateProps::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
-{
- Init();
- for (int i = 0; i < numProps; i++)
- {
- UString name = names[i];
- name.MakeUpper();
- if (name.IsEmpty())
- return E_INVALIDARG;
- const PROPVARIANT &prop = values[i];
- if (name[0] == L'X')
- {
- UInt32 a = 9;
- RINOK(ParsePropValue(name.Mid(1), prop, a));
- Level = a;
- }
- else if (name.Left(1) == L"A")
- {
- UInt32 a = kAlgo5;
- RINOK(ParsePropValue(name.Mid(1), prop, a));
- Algo = a;
- }
- else if (name.Left(4) == L"PASS")
- {
- UInt32 a = kPasses9;
- RINOK(ParsePropValue(name.Mid(4), prop, a));
- NumPasses = a;
- }
- else if (name.Left(2) == L"FB")
- {
- UInt32 a = kFb9;
- RINOK(ParsePropValue(name.Mid(2), prop, a));
- Fb = a;
- }
- else if (name.Left(2) == L"MC")
- {
- UInt32 a = 0xFFFFFFFF;
- RINOK(ParsePropValue(name.Mid(2), prop, a));
- Mc = a;
- McDefined = true;
- }
- else
- return E_INVALIDARG;
- }
- return S_OK;
-}
-
-}
diff --git a/CPP/7zip/Archive/DeflateProps.h b/CPP/7zip/Archive/DeflateProps.h
index e05a9d4a..9fd2c2e9 100755
--- a/CPP/7zip/Archive/DeflateProps.h
+++ b/CPP/7zip/Archive/DeflateProps.h
@@ -3,33 +3,4 @@
#ifndef __DEFLATE_PROPS_H
#define __DEFLATE_PROPS_H
-#include "../ICoder.h"
-
-namespace NArchive {
-
-class CDeflateProps
-{
- UInt32 Level;
- UInt32 NumPasses;
- UInt32 Fb;
- UInt32 Algo;
- UInt32 Mc;
- bool McDefined;
-
- void Init()
- {
- Level = NumPasses = Fb = Algo = Mc = 0xFFFFFFFF;
- McDefined = false;
- }
- void Normalize();
-public:
- CDeflateProps() { Init(); }
- bool IsMaximum() const { return Algo > 0; }
-
- HRESULT SetCoderProperties(ICompressSetCoderProperties *setCoderProperties);
- HRESULT SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps);
-};
-
-}
-
#endif
diff --git a/CPP/7zip/Archive/GzHandler.cpp b/CPP/7zip/Archive/GzHandler.cpp
index 7b73bddc..ede6b01b 100755
--- a/CPP/7zip/Archive/GzHandler.cpp
+++ b/CPP/7zip/Archive/GzHandler.cpp
@@ -18,11 +18,10 @@
#include "../Compress/DeflateDecoder.h"
#include "../Compress/DeflateEncoder.h"
+#include "Common/HandlerOut.h"
#include "Common/InStreamWithCRC.h"
#include "Common/OutStreamWithCRC.h"
-#include "DeflateProps.h"
-
#define Get32(p) GetUi32(p)
using namespace NWindows;
@@ -305,7 +304,7 @@ class CHandler:
CMyComPtr<ICompressCoder> _decoder;
NCompress::NDeflate::NDecoder::CCOMCoder *_decoderSpec;
- CDeflateProps _method;
+ CSingleMethodProps _props;
public:
MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties)
@@ -321,7 +320,7 @@ public:
}
};
-STATPROPSTG kProps[] =
+static STATPROPSTG const kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidSize, VT_UI8},
@@ -545,7 +544,7 @@ static HRESULT UpdateArchive(
ISequentialOutStream *outStream,
UInt64 unpackSize,
const CItem &newItem,
- CDeflateProps &deflateProps,
+ const CSingleMethodProps &props,
IArchiveUpdateCallback *updateCallback)
{
UInt64 complexity = 0;
@@ -567,7 +566,7 @@ static HRESULT UpdateArchive(
CItem item = newItem;
item.Method = NHeader::NCompressionMethod::kDeflate;
- item.ExtraFlags = deflateProps.IsMaximum() ?
+ item.ExtraFlags = props.GetLevel() >= 7 ?
NHeader::NExtraFlags::kMaximum :
NHeader::NExtraFlags::kFastest;
@@ -577,7 +576,7 @@ static HRESULT UpdateArchive(
NCompress::NDeflate::NEncoder::CCOMCoder *deflateEncoderSpec = new NCompress::NDeflate::NEncoder::CCOMCoder;
CMyComPtr<ICompressCoder> deflateEncoder = deflateEncoderSpec;
- RINOK(deflateProps.SetCoderProperties(deflateEncoderSpec));
+ RINOK(props.SetCoderProps(deflateEncoderSpec, NULL));
RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, progress));
item.Crc = inStreamSpec->GetCRC();
@@ -616,8 +615,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (prop.vt != VT_FILETIME)
return E_INVALIDARG;
utcTime = prop.filetime;
- if (!NTime::FileTimeToUnixTime(utcTime, newItem.Time))
- return E_INVALIDARG;
+ NTime::FileTimeToUnixTime(utcTime, newItem.Time);
}
{
NCOM::CPropVariant prop;
@@ -658,8 +656,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
}
-
- return UpdateArchive(outStream, size, newItem, _method, updateCallback);
+ return UpdateArchive(outStream, size, newItem, _props, updateCallback);
}
if (indexInArchive != 0)
@@ -680,7 +677,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
{
- return _method.SetProperties(names, values, numProps);
+ return _props.SetProperties(names, values, numProps);
}
static IInArchive *CreateArc() { return new CHandler; }
diff --git a/CPP/7zip/Archive/Icons/bz2.ico b/CPP/7zip/Archive/Icons/bz2.ico
index 614e3540..f22abebc 100755
--- a/CPP/7zip/Archive/Icons/bz2.ico
+++ b/CPP/7zip/Archive/Icons/bz2.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/cab.ico b/CPP/7zip/Archive/Icons/cab.ico
index cc2007fc..c96c0f01 100755
--- a/CPP/7zip/Archive/Icons/cab.ico
+++ b/CPP/7zip/Archive/Icons/cab.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/fat.ico b/CPP/7zip/Archive/Icons/fat.ico
index 882753ac..7503d933 100755
--- a/CPP/7zip/Archive/Icons/fat.ico
+++ b/CPP/7zip/Archive/Icons/fat.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/gz.ico b/CPP/7zip/Archive/Icons/gz.ico
index f50d8c08..d402a698 100755
--- a/CPP/7zip/Archive/Icons/gz.ico
+++ b/CPP/7zip/Archive/Icons/gz.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/hfs.ico b/CPP/7zip/Archive/Icons/hfs.ico
index 92a46b81..bf2c1986 100755
--- a/CPP/7zip/Archive/Icons/hfs.ico
+++ b/CPP/7zip/Archive/Icons/hfs.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/iso.ico b/CPP/7zip/Archive/Icons/iso.ico
index 2538e408..b3e3ac2f 100755
--- a/CPP/7zip/Archive/Icons/iso.ico
+++ b/CPP/7zip/Archive/Icons/iso.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/split.ico b/CPP/7zip/Archive/Icons/split.ico
index 79cb089b..65723ff3 100755
--- a/CPP/7zip/Archive/Icons/split.ico
+++ b/CPP/7zip/Archive/Icons/split.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/squashfs.ico b/CPP/7zip/Archive/Icons/squashfs.ico
index 551a7439..b802d942 100755
--- a/CPP/7zip/Archive/Icons/squashfs.ico
+++ b/CPP/7zip/Archive/Icons/squashfs.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Icons/xz.ico b/CPP/7zip/Archive/Icons/xz.ico
index 02707351..bc07a7eb 100755
--- a/CPP/7zip/Archive/Icons/xz.ico
+++ b/CPP/7zip/Archive/Icons/xz.ico
Binary files differ
diff --git a/CPP/7zip/Archive/Iso/IsoHandler.cpp b/CPP/7zip/Archive/Iso/IsoHandler.cpp
index 4bfb7dc6..f040b033 100755
--- a/CPP/7zip/Archive/Iso/IsoHandler.cpp
+++ b/CPP/7zip/Archive/Iso/IsoHandler.cpp
@@ -172,11 +172,11 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
int pos = s.ReverseFind(L';');
if (pos >= 0 && pos == s.Length() - 2)
- if (s[s.Length() - 1] == L'1')
+ if (s.Back() == L'1')
s = s.Left(pos);
if (!s.IsEmpty())
- if (s[s.Length() - 1] == L'.')
- s = s.Left(s.Length() - 1);
+ if (s.Back() == L'.')
+ s.DeleteBack();
prop = (const wchar_t *)NItemName::GetOSName2(s);
}
break;
@@ -211,19 +211,18 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
return S_OK;
UInt64 totalSize = 0;
UInt32 i;
- for(i = 0; i < numItems; i++)
+ for (i = 0; i < numItems; i++)
{
UInt32 index = (allFilesMode ? i : indices[i]);
if (index < (UInt32)_archive.Refs.Size())
{
const CRef &ref = _archive.Refs[index];
const CDir &item = ref.Dir->_subItems[ref.Index];
- totalSize += item.DataLength;
+ if (!item.IsDir())
+ totalSize += item.DataLength;
}
else
- {
totalSize += _archive.GetBootItemSize(index - _archive.Refs.Size());
- }
}
extractCallback->SetTotal(totalSize);
diff --git a/CPP/7zip/Archive/LzhHandler.cpp b/CPP/7zip/Archive/LzhHandler.cpp
index 95efc501..194de47e 100755
--- a/CPP/7zip/Archive/LzhHandler.cpp
+++ b/CPP/7zip/Archive/LzhHandler.cpp
@@ -177,47 +177,6 @@ struct CItem
}
};
-struct CItemEx: public CItem
-{
- UInt64 DataPosition;
-};
-
-class CInArchive
-{
- CMyComPtr<IInStream> m_Stream;
- UInt64 m_Position;
-
- HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize);
- HRESULT CheckReadBytes(void *data, UInt32 size);
-public:
- HRESULT Open(IInStream *inStream);
- HRESULT GetNextItem(bool &filled, CItemEx &itemInfo);
- HRESULT Skip(UInt64 numBytes);
-};
-
-HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
-{
- size_t realProcessedSize = size;
- RINOK(ReadStream(m_Stream, data, &realProcessedSize));
- processedSize = (UInt32)realProcessedSize;
- m_Position += processedSize;
- return S_OK;
-}
-
-HRESULT CInArchive::CheckReadBytes(void *data, UInt32 size)
-{
- UInt32 processedSize;
- RINOK(ReadBytes(data, size, processedSize));
- return (processedSize == size) ? S_OK: S_FALSE;
-}
-
-HRESULT CInArchive::Open(IInStream *inStream)
-{
- RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &m_Position));
- m_Stream = inStream;
- return S_OK;
-}
-
static const Byte *ReadUInt16(const Byte *p, UInt16 &v)
{
v = Get16(p);
@@ -245,13 +204,13 @@ static Byte CalcSum(const Byte *data, size_t size)
return sum;
}
-HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
+static HRESULT GetNextItem(ISequentialInStream *stream, bool &filled, CItem &item)
{
filled = false;
- UInt32 processedSize;
+ size_t processedSize = 2;
Byte startHeader[2];
- RINOK(ReadBytes(startHeader, 2, processedSize))
+ RINOK(ReadStream(stream, startHeader, &processedSize))
if (processedSize == 0)
return S_OK;
if (processedSize == 1)
@@ -261,7 +220,8 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
Byte header[256];
const UInt32 kBasicPartSize = 22;
- RINOK(ReadBytes(header, kBasicPartSize, processedSize));
+ processedSize = kBasicPartSize;
+ RINOK(ReadStream(stream, header, &processedSize));
if (processedSize != kBasicPartSize)
return (startHeader[0] == 0) ? S_OK: S_FALSE;
@@ -284,8 +244,7 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
headerSize = startHeader[0];
if (headerSize < kBasicPartSize)
return S_FALSE;
- UInt32 remain = headerSize - kBasicPartSize;
- RINOK(CheckReadBytes(header + kBasicPartSize, remain));
+ RINOK(ReadStream_FALSE(stream, header + kBasicPartSize, headerSize - kBasicPartSize));
if (startHeader[1] != CalcSum(header, headerSize))
return S_FALSE;
size_t nameLength = *p++;
@@ -294,13 +253,13 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
p = ReadString(p, nameLength, item.Name);
}
else
- headerSize = startHeader[0] | ((UInt32)startHeader[1] << 8);
+ headerSize = startHeader[0] | ((UInt32)startHeader[1] << 8);
p = ReadUInt16(p, item.CRC);
if (item.Level != 0)
{
if (item.Level == 2)
{
- RINOK(CheckReadBytes(header + kBasicPartSize, 2));
+ RINOK(ReadStream_FALSE(stream, header + kBasicPartSize, 2));
}
if ((size_t)(p - header) + 3 > headerSize)
return S_FALSE;
@@ -317,39 +276,30 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
return S_FALSE;
item.PackSize -= nextSize;
}
+ if (item.Extensions.Size() >= (1 << 8))
+ return S_FALSE;
CExtension ext;
- RINOK(CheckReadBytes(&ext.Type, 1))
+ RINOK(ReadStream_FALSE(stream, &ext.Type, 1))
nextSize -= 3;
ext.Data.SetCapacity(nextSize);
- RINOK(CheckReadBytes((Byte *)ext.Data, nextSize))
+ RINOK(ReadStream_FALSE(stream, (Byte *)ext.Data, nextSize))
item.Extensions.Add(ext);
Byte hdr2[2];
- RINOK(CheckReadBytes(hdr2, 2));
+ RINOK(ReadStream_FALSE(stream, hdr2, 2));
ReadUInt16(hdr2, nextSize);
}
}
- item.DataPosition = m_Position;
filled = true;
return S_OK;
}
-HRESULT CInArchive::Skip(UInt64 numBytes)
-{
- UInt64 newPostion;
- RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion));
- m_Position += numBytes;
- if (m_Position != newPostion)
- return E_FAIL;
- return S_OK;
-}
-
struct COsPair
{
Byte Id;
const char *Name;
};
-static COsPair g_OsPairs[] =
+static const COsPair g_OsPairs[] =
{
{ 0, "MS-DOS" },
{ 'M', "MS-DOS" },
@@ -380,7 +330,7 @@ static const char *GetOS(Byte osId)
return kUnknownOS;
}
-static STATPROPSTG kProps[] =
+static const STATPROPSTG kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsDir, VT_BOOL},
@@ -393,6 +343,11 @@ static STATPROPSTG kProps[] =
{ NULL, kpidHostOS, VT_BSTR}
};
+static const STATPROPSTG kArcProps[] =
+{
+ { NULL, kpidPhySize, VT_UI8}
+};
+
class CCRC
{
UInt16 _value;
@@ -479,12 +434,19 @@ STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *pro
return result;
}
+struct CItemEx: public CItem
+{
+ UInt64 DataPosition;
+};
+
class CHandler:
public IInArchive,
public CMyUnknownImp
{
CObjectVector<CItemEx> _items;
CMyComPtr<IInStream> _stream;
+ UInt64 _phySize;
+ AString _errorMessage;
public:
MY_UNKNOWN_IMP1(IInArchive)
INTERFACE_IInArchive(;)
@@ -492,7 +454,7 @@ public:
};
IMP_IInArchive_Props
-IMP_IInArchive_ArcProps_NO
+IMP_IInArchive_ArcProps
CHandler::CHandler() {}
@@ -502,6 +464,18 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+ NCOM::CPropVariant prop;
+ switch(propID)
+ {
+ case kpidPhySize: prop = _phySize; break;
+ case kpidError: if (!_errorMessage.IsEmpty()) prop = _errorMessage; break;
+ }
+ prop.Detach(value);
+ return S_OK;
+}
+
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
@@ -514,8 +488,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
UString s = NItemName::WinNameToOSName(MultiByteToUnicodeString(item.GetName(), CP_OEMCP));
if (!s.IsEmpty())
{
- if (s[s.Length() - 1] == WCHAR_PATH_SEPARATOR)
- s.Delete(s.Length() - 1);
+ if (s.Back() == WCHAR_PATH_SEPARATOR)
+ s.DeleteBack();
prop = s;
}
break;
@@ -567,32 +541,43 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
try
{
_items.Clear();
- CInArchive archive;
UInt64 endPos = 0;
bool needSetTotal = true;
- if (callback != NULL)
- {
- RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos));
- RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
- }
+ RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos));
+ RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
- RINOK(archive.Open(stream));
+ _phySize = 0;
for (;;)
{
CItemEx item;
bool filled;
- HRESULT result = archive.GetNextItem(filled, item);
+ HRESULT result = GetNextItem(stream, filled, item);
+ RINOK(stream->Seek(0, STREAM_SEEK_CUR, &item.DataPosition));
if (result == S_FALSE)
- return S_FALSE;
+ {
+ _errorMessage = "Incorrect header";
+ break;
+ }
+
if (result != S_OK)
return S_FALSE;
+ _phySize = item.DataPosition;
if (!filled)
break;
_items.Add(item);
- archive.Skip(item.PackSize);
- if (callback != NULL)
+
+ UInt64 newPostion;
+ RINOK(stream->Seek(item.PackSize, STREAM_SEEK_CUR, &newPostion));
+ if (newPostion > endPos)
+ {
+ _phySize = endPos;
+ _errorMessage = "Unexpected end of archive";
+ break;
+ }
+ _phySize = newPostion;
+ if (callback)
{
if (needSetTotal)
{
@@ -622,6 +607,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
STDMETHODIMP CHandler::Close()
{
+ _errorMessage.Empty();
_items.Clear();
_stream.Release();
return S_OK;
diff --git a/CPP/7zip/Archive/LzmaHandler.cpp b/CPP/7zip/Archive/LzmaHandler.cpp
index a83e6a1a..778c2fd8 100755
--- a/CPP/7zip/Archive/LzmaHandler.cpp
+++ b/CPP/7zip/Archive/LzmaHandler.cpp
@@ -296,7 +296,8 @@ STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCal
RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos));
_packSize = endPos - _startPosition;
_packSizeDefined = true;
-
+ if (_packSize >= 24 && _header.Size == 0 && _header.FilterID == 0 && _header.LzmaProps[0] == 0)
+ return S_FALSE;
_stream = inStream;
_seqStream = inStream;
return S_OK;
diff --git a/CPP/7zip/Archive/MubHandler.cpp b/CPP/7zip/Archive/MubHandler.cpp
index da4df24c..5ebda099 100755
--- a/CPP/7zip/Archive/MubHandler.cpp
+++ b/CPP/7zip/Archive/MubHandler.cpp
@@ -15,7 +15,7 @@
#include "../Compress/CopyCoder.h"
-#define Get32(p) GetBe32(p)
+static UInt32 Get32(const Byte *p, int be) { if (be) return GetBe32(p); return GetUi32(p); }
namespace NArchive {
namespace NMub {
@@ -116,8 +116,16 @@ HRESULT CHandler::Open2(IInStream *stream)
RINOK(ReadStream(stream, buf, &processed));
if (processed < kHeaderSize)
return S_FALSE;
- UInt32 num = Get32(buf + 4);
- if (Get32(buf) != 0xCAFEBABE || num > kNumFilesMax || processed < kHeaderSize + num * kRecordSize)
+
+ bool be;
+ switch (GetBe32(buf))
+ {
+ case 0xCAFEBABE: be = true; break;
+ case 0xB9FAF10E: be = false; break;
+ default: return S_FALSE;
+ }
+ UInt32 num = Get32(buf + 4, be);
+ if (num > kNumFilesMax || processed < kHeaderSize + num * kRecordSize)
return S_FALSE;
UInt64 endPosMax = kHeaderSize;
for (UInt32 i = 0; i < num; i++)
@@ -125,11 +133,11 @@ HRESULT CHandler::Open2(IInStream *stream)
const Byte *p = buf + kHeaderSize + i * kRecordSize;
CItem &sb = _items[i];
sb.IsTail = false;
- sb.Type = Get32(p);
- sb.SubType = Get32(p + 4);
- sb.Offset = Get32(p + 8);
- sb.Size = Get32(p + 12);
- sb.Align = Get32(p + 16);
+ sb.Type = Get32(p, be);
+ sb.SubType = Get32(p + 4, be);
+ sb.Offset = Get32(p + 8, be);
+ sb.Size = Get32(p + 12, be);
+ sb.Align = Get32(p + 16, be);
if ((sb.Type & ~MACH_TYPE_ABI64) >= 0x100 ||
(sb.SubType & ~MACH_SUBTYPE_ABI64) >= 0x100 ||
diff --git a/CPP/7zip/Archive/Nsis/NsisIn.h b/CPP/7zip/Archive/Nsis/NsisIn.h
index 87ae3f1c..7ca719e4 100755
--- a/CPP/7zip/Archive/Nsis/NsisIn.h
+++ b/CPP/7zip/Archive/Nsis/NsisIn.h
@@ -87,7 +87,7 @@ struct CItem
else
s = MultiByteToUnicodeString(PrefixA);
if (s.Length() > 0)
- if (s[s.Length() - 1] != L'\\')
+ if (s.Back() != L'\\')
s += L'\\';
if (unicode)
s += NameU;
diff --git a/CPP/7zip/Archive/PeHandler.cpp b/CPP/7zip/Archive/PeHandler.cpp
index c64067aa..e5946969 100755
--- a/CPP/7zip/Archive/PeHandler.cpp
+++ b/CPP/7zip/Archive/PeHandler.cpp
@@ -631,7 +631,7 @@ enum
// kpidBaseOfData32,
};
-STATPROPSTG kArcProps[] =
+static const STATPROPSTG kArcProps[] =
{
{ NULL, kpidCpu, VT_BSTR},
{ NULL, kpidBit64, VT_BOOL},
@@ -662,7 +662,7 @@ STATPROPSTG kArcProps[] =
// { L"Base Of Data", kpidBaseOfData32, VT_UI8},
};
-STATPROPSTG kProps[] =
+static const STATPROPSTG kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidSize, VT_UI8},
@@ -1749,4 +1749,335 @@ static CArcInfo g_ArcInfo =
REGISTER_ARC(Pe)
-}}
+}
+
+
+
+
+namespace NTe {
+
+// Terse Executable (TE) image
+
+/*
+struct CDataDir
+{
+ UInt32 Va;
+ UInt32 Size;
+};
+*/
+
+static const UInt32 kHeaderSize = 40;
+
+static bool FindValue(const CUInt32PCharPair *pairs, unsigned num, UInt32 value)
+{
+ for (unsigned i = 0; i < num; i++)
+ if (pairs[i].Value == value)
+ return true;
+ return false;
+}
+
+#define MY_FIND_VALUE(pairs, value) FindValue(pairs, sizeof(pairs) / sizeof(pairs[0]), value)
+
+struct CHeader
+{
+ UInt16 Machine;
+ Byte NumSections;
+ Byte SubSystem;
+ UInt16 StrippedSize;
+ /*
+ UInt32 AddressOfEntryPoint;
+ UInt32 BaseOfCode;
+ UInt64 ImageBase;
+ CDataDir DataDir[2]; // base relocation and debug directory
+ */
+
+ UInt32 ConvertPa(UInt32 pa) const { return pa - StrippedSize + kHeaderSize; }
+
+ bool Parse(const Byte *p)
+ {
+ if (p[0] != 'V' || p[1] != 'Z')
+ return false;
+ Machine = Get16(p + 2);
+ NumSections = p[4];
+ SubSystem = p[5];
+ StrippedSize = Get16(p + 6);
+ /*
+ AddressOfEntryPoint = Get32(p + 8);
+ BaseOfCode = Get32(p + 12);
+ ImageBase = Get64(p + 16);
+ for (int i = 0; i < 2; i++)
+ {
+ const Byte *p2 = p + 24 + i * 8;
+ DataDir[i].Va = Get32(p2);
+ DataDir[i].Size = Get32(p2 + 4);
+ }
+ */
+ return NumSections <= 64 &&
+ MY_FIND_VALUE(NPe::g_MachinePairs, Machine) &&
+ MY_FIND_VALUE(NPe::g_SubSystems, SubSystem);
+ }
+};
+
+struct CSection
+{
+ Byte Name[8];
+
+ // UInt32 VSize;
+ UInt32 Va;
+ UInt32 PSize;
+ UInt32 Pa;
+ UInt32 Flags;
+ // UInt16 NumRelocs;
+
+ void Parse(const Byte *p)
+ {
+ memcpy(Name, p, 8);
+ // VSize = Get32(p + 8);
+ Va = Get32(p + 12);
+ PSize = Get32(p + 16);
+ Pa = Get32(p + 20);
+ // NumRelocs = Get16(p + 32);
+ Flags = Get32(p + 36);
+ }
+
+ bool Check() const { return (PSize + Pa > Pa); }
+
+ void UpdateTotalSize(UInt32 &totalSize)
+ {
+ UInt32 t = Pa + PSize;
+ if (t > totalSize)
+ totalSize = t;
+ }
+};
+
+class CHandler:
+ public IInArchive,
+ public IInArchiveGetStream,
+ public CMyUnknownImp
+{
+ UInt32 _totalSize;
+ CMyComPtr<IInStream> _stream;
+ CObjectVector<CSection> _items;
+ CHeader _h;
+ UInt64 _fileSize;
+
+ HRESULT Open2(IInStream *stream);
+public:
+ MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
+ INTERFACE_IInArchive(;)
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
+};
+
+static const STATPROPSTG kProps[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidSize, VT_UI4},
+ { NULL, kpidPackSize, VT_UI4},
+ { NULL, kpidCharacts, VT_BSTR},
+ { NULL, kpidOffset, VT_UI4},
+ { NULL, kpidVa, VT_UI8}
+};
+
+enum
+{
+ kpidSubSystem
+ // , kpidImageBase
+};
+
+static const STATPROPSTG kArcProps[] =
+{
+ { NULL, kpidPhySize, VT_UI4},
+ // { NULL, kpidHeadersSize, VT_UI4},
+ { NULL, kpidCpu, VT_BSTR},
+ { L"Subsystem", kpidSubSystem, VT_BSTR},
+ // { L"Image Base", kpidImageBase, VT_UI8}
+};
+
+IMP_IInArchive_Props
+IMP_IInArchive_ArcProps_WITH_NAME
+
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NCOM::CPropVariant prop;
+ switch(propID)
+ {
+ case kpidPhySize: prop = _totalSize; break;
+ case kpidCpu: PAIR_TO_PROP(NPe::g_MachinePairs, _h.Machine, prop); break;
+ case kpidSubSystem: PAIR_TO_PROP(NPe::g_SubSystems, _h.SubSystem, prop); break;
+ /*
+ case kpidImageBase: prop = _h.ImageBase; break;
+ case kpidAddressOfEntryPoint: prop = _h.AddressOfEntryPoint; break;
+ case kpidBaseOfCode: prop = _h.BaseOfCode; break;
+ */
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NCOM::CPropVariant prop;
+ {
+ const CSection &item = _items[index];
+ switch(propID)
+ {
+ case kpidPath: StringToProp(NPe::GetName(item.Name), prop); break;
+ case kpidSize:
+ case kpidPackSize: prop = (UInt64)item.PSize; break;
+ case kpidOffset: prop = item.Pa; break;
+ case kpidVa: prop = item.Va; break;
+ case kpidCharacts: FLAGS_TO_PROP(NPe::g_SectFlags, item.Flags, prop); break;
+ }
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+HRESULT CHandler::Open2(IInStream *stream)
+{
+ Byte h[kHeaderSize];
+ RINOK(ReadStream_FALSE(stream, h, kHeaderSize));
+ if (!_h.Parse(h))
+ return S_FALSE;
+
+ CByteBuffer buf;
+ UInt32 headerSize = NPe::kSectionSize * _h.NumSections;
+ buf.SetCapacity(headerSize);
+ RINOK(ReadStream_FALSE(stream, buf, headerSize));
+
+ _totalSize = kHeaderSize + headerSize;
+
+ for (UInt32 i = 0; i < headerSize; i += NPe::kSectionSize)
+ {
+ CSection sect;
+ sect.Parse(buf + i);
+ sect.Pa = _h.ConvertPa(sect.Pa);
+ _items.Add(sect);
+ sect.UpdateTotalSize(_totalSize);
+ if (!sect.Check())
+ return S_FALSE;
+ }
+
+ return stream->Seek(0, STREAM_SEEK_END, &_fileSize);
+}
+
+STDMETHODIMP CHandler::Open(IInStream *inStream,
+ const UInt64 * /* maxCheckStartPosition */,
+ IArchiveOpenCallback * /* openArchiveCallback */)
+{
+ COM_TRY_BEGIN
+ Close();
+ try
+ {
+ if (Open2(inStream) != S_OK)
+ return S_FALSE;
+ _stream = inStream;
+ }
+ catch(...) { return S_FALSE; }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _stream.Release();
+ _items.Clear();
+ _totalSize = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _items.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool allFilesMode = (numItems == (UInt32)-1);
+ if (allFilesMode)
+ numItems = _items.Size();
+ if (numItems == 0)
+ return S_OK;
+ UInt64 totalSize = 0;
+ UInt32 i;
+ for (i = 0; i < numItems; i++)
+ totalSize += _items[allFilesMode ? i : indices[i]].PSize;
+ extractCallback->SetTotal(totalSize);
+
+ UInt64 currentTotalSize = 0;
+
+ NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
+ CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
+
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(extractCallback, false);
+
+ CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
+ CMyComPtr<ISequentialInStream> inStream(streamSpec);
+ streamSpec->SetStream(_stream);
+
+ for (i = 0; i < numItems; i++)
+ {
+ lps->InSize = lps->OutSize = currentTotalSize;
+ RINOK(lps->SetCur());
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode = testMode ?
+ NExtract::NAskMode::kTest :
+ NExtract::NAskMode::kExtract;
+ UInt32 index = allFilesMode ? i : indices[i];
+ const CSection &item = _items[index];
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+ currentTotalSize += item.PSize;
+
+ if (!testMode && !realOutStream)
+ continue;
+ RINOK(extractCallback->PrepareOperation(askMode));
+ int res = NExtract::NOperationResult::kDataError;
+ if (item.Pa <= _fileSize)
+ {
+ if (testMode)
+ {
+ if (item.Pa + item.PSize <= _fileSize)
+ res = NExtract::NOperationResult::kOK;
+ }
+ else
+ {
+ RINOK(_stream->Seek(item.Pa, STREAM_SEEK_SET, NULL));
+ streamSpec->Init(item.PSize);
+ RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
+ if (copyCoderSpec->TotalSize == item.PSize)
+ res = NExtract::NOperationResult::kOK;
+ }
+ }
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(res));
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
+{
+ COM_TRY_BEGIN
+ const CSection &item = _items[index];
+ return CreateLimitedInStream(_stream, item.Pa, item.PSize, stream);
+ COM_TRY_END
+}
+
+static IInArchive *CreateArc() { return new CHandler; }
+
+static CArcInfo g_ArcInfo =
+ { L"TE", L"te", 0, 0xCF, { 'V', 'Z' }, 2, false, CreateArc, 0 };
+
+REGISTER_ARC(TE)
+
+}
+}
diff --git a/CPP/7zip/Archive/Rar/RarIn.cpp b/CPP/7zip/Archive/Rar/RarIn.cpp
index e4c23752..a7d018ff 100755
--- a/CPP/7zip/Archive/Rar/RarIn.cpp
+++ b/CPP/7zip/Archive/Rar/RarIn.cpp
@@ -112,7 +112,7 @@ HRESULT CInArchive::Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit
(UInt32)Get16(buf) != (CrcCalc(buf + 2, headerSize - 2) & 0xFFFF))
return S_FALSE;
- size_t commentSize = blockSize - headerSize;
+ size_t commentSize = blockSize - headerSize;
_comment.SetCapacity(commentSize);
RINOK(ReadStream_FALSE(stream, _comment, commentSize));
AddToSeekValue(commentSize);
diff --git a/CPP/7zip/Archive/SquashfsHandler.cpp b/CPP/7zip/Archive/SquashfsHandler.cpp
index 2cc1219a..efaffed1 100755
--- a/CPP/7zip/Archive/SquashfsHandler.cpp
+++ b/CPP/7zip/Archive/SquashfsHandler.cpp
@@ -5,6 +5,7 @@
#include "../../../C/7zCrc.h"
#include "../../../C/Alloc.h"
#include "../../../C/CpuArch.h"
+#include "../../../C/Xz.h"
#include "Common/ComTry.h"
#include "Common/IntToString.h"
@@ -13,6 +14,7 @@
#include "Windows/PropVariantUtils.h"
#include "Windows/Time.h"
+#include "../Common/CWrappers.h"
#include "../Common/LimitedStreams.h"
#include "../Common/ProgressUtils.h"
#include "../Common/RegisterArc.h"
@@ -26,6 +28,10 @@
namespace NArchive {
namespace NSquashfs {
+static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
+static void SzFree(void *p, void *address) { p = p; MyFree(address); }
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
static const UInt32 kNumFilesMax = (1 << 28);
static const unsigned kNumDirLevelsMax = (1 << 10);
@@ -62,13 +68,15 @@ static const UInt32 kSignature32_LZ = 0x71736873;
#define kMethod_ZLIB 1
#define kMethod_LZMA 2
#define kMethod_LZO 3
+#define kMethod_XZ 4
static const char *k_Methods[] =
{
"Unknown",
"ZLIB",
"LZMA",
- "LZO"
+ "LZO",
+ "XZ"
};
static const UInt32 kMetadataBlockSizeLog = 13;
@@ -860,6 +868,8 @@ class CHandler:
NCompress::NZlib::CDecoder *_zlibDecoderSpec;
CMyComPtr<ICompressCoder> _zlibDecoder;
+ CXzUnpacker _xz;
+
CByteBuffer _inputBuffer;
CDynBufSeqOutStream *_dynOutStreamSpec;
@@ -886,6 +896,11 @@ class CHandler:
public:
CHandler();
+ ~CHandler()
+ {
+ XzUnpacker_Free(&_xz);
+ }
+
MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
INTERFACE_IInArchive(;)
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
@@ -895,6 +910,8 @@ public:
CHandler::CHandler()
{
+ XzUnpacker_Construct(&_xz, &g_Alloc);
+
_limitedInStreamSpec = new CLimitedSequentialInStream;
_limitedInStream = _limitedInStreamSpec;
@@ -1104,33 +1121,16 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool
RINOK(_stream->Seek(-1, STREAM_SEEK_CUR, NULL));
}
- if (method == kMethod_LZO)
+ if (method == kMethod_ZLIB)
{
- if (_inputBuffer.GetCapacity() < inSize)
- {
- _inputBuffer.Free();
- _inputBuffer.SetCapacity(inSize);
- }
- RINOK(ReadStream_FALSE(_stream, _inputBuffer, inSize));
-
- Byte *dest = outBuf;
- if (!outBuf)
+ if (!_zlibDecoder)
{
- dest = _dynOutStreamSpec->GetBufPtrForWriting(outSizeMax);
- if (!dest)
- return E_OUTOFMEMORY;
+ _zlibDecoderSpec = new NCompress::NZlib::CDecoder();
+ _zlibDecoder = _zlibDecoderSpec;
}
- SizeT destLen = outSizeMax, srcLen = inSize;
- RINOK(LzoDecode(dest, &destLen, _inputBuffer, &srcLen));
- if (inSize != srcLen)
+ RINOK(_zlibDecoder->Code(_limitedInStream, outStream, NULL, NULL, NULL));
+ if (inSize != _zlibDecoderSpec->GetInputProcessedSize())
return S_FALSE;
- if (outBuf)
- {
- *outBufWasWritten = true;
- *outBufWasWrittenSize = (UInt32)destLen;
- }
- else
- _dynOutStreamSpec->UpdateSize(destLen);
}
else if (method == kMethod_LZMA)
{
@@ -1153,14 +1153,44 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool
}
else
{
- if (!_zlibDecoder)
+ if (_inputBuffer.GetCapacity() < inSize)
{
- _zlibDecoderSpec = new NCompress::NZlib::CDecoder();
- _zlibDecoder = _zlibDecoderSpec;
+ _inputBuffer.Free();
+ _inputBuffer.SetCapacity(inSize);
}
- RINOK(_zlibDecoder->Code(_limitedInStream, outStream, NULL, NULL, NULL));
- if (inSize != _zlibDecoderSpec->GetInputProcessedSize())
+ RINOK(ReadStream_FALSE(_stream, _inputBuffer, inSize));
+
+ Byte *dest = outBuf;
+ if (!outBuf)
+ {
+ dest = _dynOutStreamSpec->GetBufPtrForWriting(outSizeMax);
+ if (!dest)
+ return E_OUTOFMEMORY;
+ }
+ SizeT destLen = outSizeMax, srcLen = inSize;
+ if (method == kMethod_LZO)
+ {
+ RINOK(LzoDecode(dest, &destLen, _inputBuffer, &srcLen));
+ }
+ else
+ {
+ ECoderStatus status;
+ XzUnpacker_Init(&_xz);
+ SRes res = XzUnpacker_Code(&_xz, dest, &destLen, _inputBuffer, &srcLen, LZMA_FINISH_END, &status);
+ if (res != 0)
+ return SResToHRESULT(res);
+ if (status != CODER_STATUS_NEEDS_MORE_INPUT || !XzUnpacker_IsStreamWasFinished(&_xz))
+ return S_FALSE;
+ }
+ if (inSize != srcLen)
return S_FALSE;
+ if (outBuf)
+ {
+ *outBufWasWritten = true;
+ *outBufWasWrittenSize = (UInt32)destLen;
+ }
+ else
+ _dynOutStreamSpec->UpdateSize(destLen);
}
return S_OK;
}
@@ -1418,6 +1448,7 @@ HRESULT CHandler::Open2(IInStream *inStream)
case kMethod_ZLIB:
case kMethod_LZMA:
case kMethod_LZO:
+ case kMethod_XZ:
break;
default:
return E_NOTIMPL;
@@ -2072,15 +2103,18 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
if (inStream)
{
HRESULT hres = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
- if (hres != S_OK && hres != S_FALSE)
+ if (hres == S_OK)
{
- RINOK(hres);
+ if (copyCoderSpec->TotalSize == unpackSize)
+ res = NExtract::NOperationResult::kOK;
+ }
+ else if (hres == E_NOTIMPL)
+ {
+ res = NExtract::NOperationResult::kUnSupportedMethod;
}
- if (copyCoderSpec->TotalSize == unpackSize && hres == S_OK)
- res = NExtract::NOperationResult::kOK;
- else
+ else if(hres != S_FALSE)
{
- res = res;
+ RINOK(hres);
}
}
}
diff --git a/CPP/7zip/Archive/SwfHandler.cpp b/CPP/7zip/Archive/SwfHandler.cpp
index dfc0326d..d7d9537e 100755
--- a/CPP/7zip/Archive/SwfHandler.cpp
+++ b/CPP/7zip/Archive/SwfHandler.cpp
@@ -21,8 +21,7 @@
#include "../Compress/ZlibEncoder.h"
#include "Common/DummyOutStream.h"
-
-#include "DeflateProps.h"
+#include "Common/HandlerOut.h"
using namespace NWindows;
@@ -69,7 +68,7 @@ class CHandler:
CMyComPtr<ISequentialInStream> _seqStream;
CMyComPtr<IInStream> _stream;
- CDeflateProps _method;
+ CSingleMethodProps _props;
public:
MY_UNKNOWN_IMP4(IInArchive, IArchiveOpenSeq, IOutArchive, ISetProperties)
@@ -206,7 +205,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
static HRESULT UpdateArchive(ISequentialOutStream *outStream,
- UInt64 size, CDeflateProps &deflateProps,
+ UInt64 size, const CSingleMethodProps &props,
IArchiveUpdateCallback *updateCallback)
{
UInt64 complexity = 0;
@@ -234,7 +233,7 @@ static HRESULT UpdateArchive(ISequentialOutStream *outStream,
NCompress::NZlib::CEncoder *encoderSpec = new NCompress::NZlib::CEncoder;
CMyComPtr<ICompressCoder> encoder = encoderSpec;
encoderSpec->Create();
- RINOK(deflateProps.SetCoderProperties(encoderSpec->DeflateEncoderSpec));
+ RINOK(props.SetCoderProps(encoderSpec->DeflateEncoderSpec, NULL));
RINOK(encoder->Code(fileInStream, outStream, NULL, NULL, progress));
if (encoderSpec->GetInputProcessedSize() + kHeaderSize != size)
return E_INVALIDARG;
@@ -284,7 +283,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
}
- return UpdateArchive(outStream, size, _method, updateCallback);
+ return UpdateArchive(outStream, size, _props, updateCallback);
}
if (indexInArchive != 0)
@@ -304,7 +303,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
{
- return _method.SetProperties(names, values, numProps);
+ return _props.SetProperties(names, values, numProps);
}
static IInArchive *CreateArc() { return new CHandler; }
diff --git a/CPP/7zip/Archive/Tar/TarHandler.cpp b/CPP/7zip/Archive/Tar/TarHandler.cpp
index 4db0cae8..251afdb7 100755
--- a/CPP/7zip/Archive/Tar/TarHandler.cpp
+++ b/CPP/7zip/Archive/Tar/TarHandler.cpp
@@ -64,6 +64,8 @@ HRESULT CHandler::ReadItem2(ISequentialInStream *stream, bool &filled, CItemEx &
{
item.HeaderPos = _phySize;
RINOK(ReadItem(stream, filled, item, _errorMessage));
+ if (filled && item.IsSparse())
+ _isSparse = true;
_phySize += item.HeaderSize;
_headersSize += item.HeaderSize;
return S_OK;
@@ -87,7 +89,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
break;
_items.Add(item);
- RINOK(stream->Seek(item.GetPackSize(), STREAM_SEEK_CUR, &_phySize));
+ RINOK(stream->Seek(item.GetPackSizeAligned(), STREAM_SEEK_CUR, &_phySize));
if (_phySize > endPos)
{
_errorMessage = kUnexpectedEnd;
@@ -162,6 +164,7 @@ STDMETHODIMP CHandler::Close()
_headersSize = 0;
_curIndex = 0;
_latestIsRead = false;
+ _isSparse = false;
_items.Clear();
_seqStream.Release();
_stream.Release();
@@ -186,7 +189,7 @@ HRESULT CHandler::SkipTo(UInt32 index)
{
if (_latestIsRead)
{
- UInt64 packSize = _latestItem.GetPackSize();
+ UInt64 packSize = _latestItem.GetPackSizeAligned();
RINOK(copyCoderSpec->Code(_seqStream, NULL, &packSize, &packSize, NULL));
_phySize += copyCoderSpec->TotalSize;
if (copyCoderSpec->TotalSize != packSize)
@@ -241,13 +244,13 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPath: prop = NItemName::GetOSName2(TarStringToUnicode(item->Name)); break;
case kpidIsDir: prop = item->IsDir(); break;
case kpidSize: prop = item->GetUnpackSize(); break;
- case kpidPackSize: prop = item->GetPackSize(); break;
+ case kpidPackSize: prop = item->GetPackSizeAligned(); break;
case kpidMTime:
if (item->MTime != 0)
{
FILETIME ft;
- NTime::UnixTimeToFileTime(item->MTime, ft);
- prop = ft;
+ if (NTime::UnixTime64ToFileTime(item->MTime, ft))
+ prop = ft;
}
break;
case kpidPosixAttrib: prop = item->Mode; break;
@@ -319,7 +322,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
UInt64 unpackSize = item->GetUnpackSize();
totalSize += unpackSize;
- totalPackSize += item->GetPackSize();
+ totalPackSize += item->GetPackSizeAligned();
if (item->IsDir())
{
RINOK(extractCallback->PrepareOperation(askMode));
@@ -340,18 +343,26 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
realOutStream.Release();
outStreamSpec->Init(skipMode ? 0 : unpackSize, true);
- if (item->IsLink())
- {
- RINOK(WriteStream(outStreamSpec, (const char *)item->LinkName, item->LinkName.Length()));
- }
+ Int32 opRes = NExtract::NOperationResult::kOK;
+ if (item->IsSparse())
+ opRes = NExtract::NOperationResult::kUnSupportedMethod;
else
{
- if (!seqMode)
+ if (item->IsLink())
+ {
+ RINOK(WriteStream(outStreamSpec, (const char *)item->LinkName, item->LinkName.Length()));
+ }
+ else
{
- RINOK(_stream->Seek(item->GetDataPosition(), STREAM_SEEK_SET, NULL));
+ if (!seqMode)
+ {
+ RINOK(_stream->Seek(item->GetDataPosition(), STREAM_SEEK_SET, NULL));
+ }
+ streamSpec->Init(item->GetPackSizeAligned());
+ RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
}
- streamSpec->Init(item->GetPackSize());
- RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
+ if (outStreamSpec->GetRem() != 0)
+ opRes = NExtract::NOperationResult::kDataError;
}
if (seqMode)
{
@@ -359,9 +370,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
_curIndex++;
}
outStreamSpec->ReleaseStream();
- RINOK(extractCallback->SetOperationResult(outStreamSpec->GetRem() == 0 ?
- NExtract::NOperationResult::kOK:
- NExtract::NOperationResult::kDataError));
+ RINOK(extractCallback->SetOperationResult(opRes));
}
return S_OK;
COM_TRY_END
@@ -371,6 +380,8 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
{
COM_TRY_BEGIN
const CItemEx &item = _items[index];
+ if (item.IsSparse())
+ return E_NOTIMPL;
if (item.IsLink())
{
CBufInStream *streamSpec = new CBufInStream;
@@ -379,7 +390,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
*stream = streamTemp.Detach();
return S_OK;
}
- return CreateLimitedInStream(_stream, item.GetDataPosition(), item.Size, stream);
+ return CreateLimitedInStream(_stream, item.GetDataPosition(), item.PackSize, stream);
COM_TRY_END
}
diff --git a/CPP/7zip/Archive/Tar/TarHandler.h b/CPP/7zip/Archive/Tar/TarHandler.h
index b1967061..9251edf6 100755
--- a/CPP/7zip/Archive/Tar/TarHandler.h
+++ b/CPP/7zip/Archive/Tar/TarHandler.h
@@ -32,6 +32,7 @@ class CHandler:
UInt64 _headersSize;
bool _phySizeDefined;
AString _errorMessage;
+ bool _isSparse;
NCompress::CCopyCoder *copyCoderSpec;
CMyComPtr<ICompressCoder> copyCoder;
diff --git a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
index ffdf2b13..b0ec63d1 100755
--- a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
+++ b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
@@ -37,7 +37,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
IArchiveUpdateCallback *callback)
{
COM_TRY_BEGIN
- if ((_stream && !_errorMessage.IsEmpty()) || _seqStream)
+ if ((_stream && (!_errorMessage.IsEmpty() || _isSparse)) || _seqStream)
return E_NOTIMPL;
CObjectVector<CUpdateItem> updateItems;
for (UInt32 i = 0; i < numItems; i++)
@@ -81,11 +81,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
NCOM::CPropVariant prop;
RINOK(callback->GetProperty(i, kpidMTime, &prop));
if (prop.vt == VT_EMPTY)
- ui.Time = 0;
+ ui.MTime = 0;
else if (prop.vt != VT_FILETIME)
return E_INVALIDARG;
- else if (!NTime::FileTimeToUnixTime(prop.filetime, ui.Time))
- ui.Time = 0;
+ else
+ ui.MTime = NTime::FileTimeToUnixTime64(prop.filetime);
}
{
NCOM::CPropVariant prop;
diff --git a/CPP/7zip/Archive/Tar/TarHeader.h b/CPP/7zip/Archive/Tar/TarHeader.h
index 0b78bdc2..a212ae03 100755
--- a/CPP/7zip/Archive/Tar/TarHeader.h
+++ b/CPP/7zip/Archive/Tar/TarHeader.h
@@ -84,6 +84,7 @@ namespace NFileHeader
Each file name is terminated by a null + an additional null after
the last file name. */
+ const char kSparse = 'S';
}
// Further link types may be defined later.
diff --git a/CPP/7zip/Archive/Tar/TarIn.cpp b/CPP/7zip/Archive/Tar/TarIn.cpp
index 5ceaa509..b6e5e0f5 100755
--- a/CPP/7zip/Archive/Tar/TarIn.cpp
+++ b/CPP/7zip/Archive/Tar/TarIn.cpp
@@ -63,6 +63,31 @@ static void ReadString(const char *s, int size, AString &result)
result = temp;
}
+static bool ParseInt64(const char *p, Int64 &val)
+{
+ UInt32 h = GetBe32(p);
+ val = GetBe64(p + 4);
+ if (h == (UInt32)1 << 31)
+ return ((val >> 63) & 1) == 0;
+ if (h == (UInt32)(Int32)-1)
+ return ((val >> 63) & 1) != 0;
+ UInt64 uv;
+ bool res = OctalToNumber(p, 12, uv);
+ val = uv;
+ return res;
+}
+
+static bool ParseSize(const char *p, UInt64 &val)
+{
+ if (GetBe32(p) == (UInt32)1 << 31)
+ {
+ // GNU extension
+ val = GetBe64(p + 4);
+ return ((val >> 63) & 1) == 0;
+ }
+ return OctalToNumber(p, 12, val);
+}
+
static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemEx &item, AString &error)
{
char buf[NFileHeader::kRecordSize];
@@ -105,17 +130,10 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
if (!OctalToNumber32(p, 8, item.UID)) item.UID = 0; p += 8;
if (!OctalToNumber32(p, 8, item.GID)) item.GID = 0; p += 8;
- if (GetBe32(p) == (UInt32)1 << 31)
- {
- // GNU extension
- item.Size = GetBe64(p + 4);
- }
- else
- {
- RIF(OctalToNumber(p, 12, item.Size));
- }
+ RIF(ParseSize(p, item.PackSize));
+ item.Size = item.PackSize;
p += 12;
- RIF(OctalToNumber32(p, 12, item.MTime)); p += 12;
+ RIF(ParseInt64(p, item.MTime)); p += 12;
UInt32 checkSum;
RIF(OctalToNumber32(p, 8, checkSum));
@@ -141,7 +159,36 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
item.Name = prefix + AString('/') + item.Name;
if (item.LinkFlag == NFileHeader::NLinkFlag::kLink)
+ {
+ item.PackSize = 0;
item.Size = 0;
+ }
+ else if (item.LinkFlag == NFileHeader::NLinkFlag::kSparse)
+ {
+ if (buf[482] != 0)
+ return S_FALSE;
+ RIF(ParseSize(buf + 483, item.Size));
+ p = buf + 386;
+ UInt64 min = 0;
+ for (int i = 0; i < 4; i++, p += 24)
+ {
+ if (GetBe32(p) == 0)
+ break;
+ CSparseBlock sb;
+ RIF(ParseSize(p, sb.Offset));
+ RIF(ParseSize(p + 12, sb.Size));
+ item.SparseBlocks.Add(sb);
+ if (sb.Offset < min || sb.Offset > item.Size)
+ return S_FALSE;
+ if ((sb.Offset & 0x1FF) != 0 || (sb.Size & 0x1FF) != 0)
+ return S_FALSE;
+ min = sb.Offset + sb.Size;
+ if (min < sb.Offset)
+ return S_FALSE;
+ }
+ if (min > item.Size)
+ return S_FALSE;
+ }
UInt32 checkSumReal = 0;
for (int i = 0; i < NFileHeader::kRecordSize; i++)
@@ -178,26 +225,39 @@ HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, AStri
if (item.Name.Compare(NFileHeader::kLongLink) != 0 &&
item.Name.Compare(NFileHeader::kLongLink2) != 0)
return S_FALSE;
- if (item.Size > (1 << 14))
+ if (item.PackSize > (1 << 14))
return S_FALSE;
- int packSize = (int)item.GetPackSize();
+ int packSize = (int)item.GetPackSizeAligned();
char *buf = name->GetBuffer(packSize);
RINOK(ReadStream_FALSE(stream, buf, packSize));
item.HeaderSize += packSize;
- buf[(size_t)item.Size] = '\0';
+ buf[(size_t)item.PackSize] = '\0';
name->ReleaseBuffer();
continue;
}
- if (item.LinkFlag == 'g' || item.LinkFlag == 'x' || item.LinkFlag == 'X')
+ switch (item.LinkFlag)
{
- // pax Extended Header
+ case 'g':
+ case 'x':
+ case 'X':
+ {
+ // pax Extended Header
+ break;
+ }
+ case NFileHeader::NLinkFlag::kDumpDir:
+ {
+ break;
+ // GNU Extensions to the Archive Format
+ }
+ case NFileHeader::NLinkFlag::kSparse:
+ {
+ break;
+ // GNU Extensions to the Archive Format
+ }
+ default:
+ if (item.LinkFlag > '7' || (item.LinkFlag < '0' && item.LinkFlag != 0))
+ return S_FALSE;
}
- else if (item.LinkFlag == NFileHeader::NLinkFlag::kDumpDir)
- {
- // GNU Extensions to the Archive Format
- }
- else if (item.LinkFlag > '7' || (item.LinkFlag < '0' && item.LinkFlag != 0))
- return S_FALSE;
if (flagL) item.Name = nameL;
if (flagK) item.LinkName = nameK;
return S_OK;
diff --git a/CPP/7zip/Archive/Tar/TarItem.h b/CPP/7zip/Archive/Tar/TarItem.h
index 859e66dd..3584a7ce 100755
--- a/CPP/7zip/Archive/Tar/TarItem.h
+++ b/CPP/7zip/Archive/Tar/TarItem.h
@@ -10,15 +10,22 @@
namespace NArchive {
namespace NTar {
+struct CSparseBlock
+{
+ UInt64 Offset;
+ UInt64 Size;
+};
+
struct CItem
{
AString Name;
+ UInt64 PackSize;
UInt64 Size;
+ Int64 MTime;
UInt32 Mode;
UInt32 UID;
UInt32 GID;
- UInt32 MTime;
UInt32 DeviceMajor;
UInt32 DeviceMinor;
@@ -31,7 +38,10 @@ struct CItem
bool DeviceMajorDefined;
bool DeviceMinorDefined;
+ CRecordVector<CSparseBlock> SparseBlocks;
+
bool IsLink() const { return LinkFlag == NFileHeader::NLinkFlag::kSymbolicLink && (Size == 0); }
+ bool IsSparse() const { return LinkFlag == NFileHeader::NLinkFlag::kSparse; }
UInt64 GetUnpackSize() const { return IsLink() ? LinkName.Length() : Size; }
bool IsDir() const
@@ -56,15 +66,16 @@ struct CItem
return true;
}
- UInt64 GetPackSize() const { return (Size + 0x1FF) & (~((UInt64)0x1FF)); }
+ UInt64 GetPackSizeAligned() const { return (PackSize + 0x1FF) & (~((UInt64)0x1FF)); }
};
struct CItemEx: public CItem
{
UInt64 HeaderPos;
unsigned HeaderSize;
+
UInt64 GetDataPosition() const { return HeaderPos + HeaderSize; }
- UInt64 GetFullSize() const { return HeaderSize + Size; }
+ UInt64 GetFullSize() const { return HeaderSize + PackSize; }
};
}}
diff --git a/CPP/7zip/Archive/Tar/TarOut.cpp b/CPP/7zip/Archive/Tar/TarOut.cpp
index e542a3b2..6e699e28 100755
--- a/CPP/7zip/Archive/Tar/TarOut.cpp
+++ b/CPP/7zip/Archive/Tar/TarOut.cpp
@@ -47,7 +47,7 @@ static bool MakeOctalString8(char *s, UInt32 value)
if (tempString.Length() >= kMaxSize)
return false;
int numSpaces = kMaxSize - (tempString.Length() + 1);
- for(int i = 0; i < numSpaces; i++)
+ for (int i = 0; i < numSpaces; i++)
s[i] = ' ';
MyStringCopy(s + numSpaces, (const char *)tempString);
return true;
@@ -55,7 +55,7 @@ static bool MakeOctalString8(char *s, UInt32 value)
static void MakeOctalString12(char *s, UInt64 value)
{
- AString tempString = MakeOctalString(value);
+ AString tempString = MakeOctalString(value);
const int kMaxSize = 12;
if (tempString.Length() > kMaxSize)
{
@@ -67,11 +67,23 @@ static void MakeOctalString12(char *s, UInt64 value)
return;
}
int numSpaces = kMaxSize - tempString.Length();
- for(int i = 0; i < numSpaces; i++)
+ for (int i = 0; i < numSpaces; i++)
s[i] = ' ';
memmove(s + numSpaces, (const char *)tempString, tempString.Length());
}
+static void MakeOctalString12_From_Int64(char *s, Int64 value)
+{
+ if (value >= 0)
+ {
+ MakeOctalString12(s, value);
+ return;
+ }
+ s[0] = s[1] = s[2] = s[3] = (char)(Byte)0xFF;
+ for (int i = 0; i < 8; i++, value <<= 8)
+ s[4 + i] = (char)(value >> 56);
+}
+
static bool CopyString(char *dest, const AString &src, int maxSize)
{
if (src.Length() >= maxSize)
@@ -100,8 +112,8 @@ HRESULT COutArchive::WriteHeaderReal(const CItem &item)
RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.UID)); cur += 8;
RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.GID)); cur += 8;
- MakeOctalString12(cur, item.Size); cur += 12;
- MakeOctalString12(cur, item.MTime); cur += 12;
+ MakeOctalString12(cur, item.PackSize); cur += 12;
+ MakeOctalString12_From_Int64(cur, item.MTime); cur += 12;
memmove(cur, NFileHeader::kCheckSumBlanks, 8);
cur += 8;
@@ -130,7 +142,7 @@ HRESULT COutArchive::WriteHeaderReal(const CItem &item)
UInt32 checkSumReal = 0;
- for(i = 0; i < NFileHeader::kRecordSize; i++)
+ for (i = 0; i < NFileHeader::kRecordSize; i++)
checkSumReal += Byte(record[i]);
RETURN_IF_NOT_TRUE(MakeOctalString8(record + 148, checkSumReal));
@@ -146,7 +158,7 @@ HRESULT COutArchive::WriteHeader(const CItem &item)
CItem modifiedItem = item;
int nameStreamSize = nameSize + 1;
- modifiedItem.Size = nameStreamSize;
+ modifiedItem.PackSize = nameStreamSize;
modifiedItem.LinkFlag = 'L';
modifiedItem.Name = NFileHeader::kLongLink;
modifiedItem.LinkName.Empty();
diff --git a/CPP/7zip/Archive/Tar/TarUpdate.cpp b/CPP/7zip/Archive/Tar/TarUpdate.cpp
index c1633218..fb123169 100755
--- a/CPP/7zip/Archive/Tar/TarUpdate.cpp
+++ b/CPP/7zip/Archive/Tar/TarUpdate.cpp
@@ -48,7 +48,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
complexity = 0;
- for(i = 0; i < updateItems.Size(); i++)
+ for (i = 0; i < updateItems.Size(); i++)
{
lps->InSize = lps->OutSize = complexity;
RINOK(lps->SetCur());
@@ -64,14 +64,14 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
if (ui.IsDir)
{
item.LinkFlag = NFileHeader::NLinkFlag::kDirectory;
- item.Size = 0;
+ item.PackSize = 0;
}
else
{
item.LinkFlag = NFileHeader::NLinkFlag::kNormal;
- item.Size = ui.Size;
+ item.PackSize = ui.Size;
}
- item.MTime = ui.Time;
+ item.MTime = ui.MTime;
item.DeviceMajorDefined = false;
item.DeviceMinorDefined = false;
item.UID = 0;
@@ -83,12 +83,12 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
if (ui.NewData)
{
- item.Size = ui.Size;
- if (item.Size == (UInt64)(Int64)-1)
+ item.PackSize = ui.Size;
+ if (ui.Size == (UInt64)(Int64)-1)
return E_INVALIDARG;
}
else
- item.Size = inputItems[ui.IndexInArchive].Size;
+ item.PackSize = inputItems[ui.IndexInArchive].PackSize;
if (ui.NewData)
{
@@ -101,9 +101,9 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
if (!ui.IsDir)
{
RINOK(copyCoder->Code(fileInStream, outStream, NULL, NULL, progress));
- if (copyCoderSpec->TotalSize != item.Size)
+ if (copyCoderSpec->TotalSize != item.PackSize)
return E_FAIL;
- RINOK(outArchive.FillDataResidual(item.Size));
+ RINOK(outArchive.FillDataResidual(item.PackSize));
}
}
complexity += ui.Size;
@@ -117,7 +117,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
{
RINOK(outArchive.WriteHeader(item));
RINOK(inStream->Seek(existItem.GetDataPosition(), STREAM_SEEK_SET, NULL));
- size = existItem.Size;
+ size = existItem.PackSize;
}
else
{
@@ -129,10 +129,12 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress));
if (copyCoderSpec->TotalSize != size)
return E_FAIL;
- RINOK(outArchive.FillDataResidual(existItem.Size));
+ RINOK(outArchive.FillDataResidual(existItem.PackSize));
complexity += size;
}
}
+ lps->InSize = lps->OutSize = complexity;
+ RINOK(lps->SetCur());
return outArchive.WriteFinishHeader();
}
diff --git a/CPP/7zip/Archive/Tar/TarUpdate.h b/CPP/7zip/Archive/Tar/TarUpdate.h
index fb217d19..3f889739 100755
--- a/CPP/7zip/Archive/Tar/TarUpdate.h
+++ b/CPP/7zip/Archive/Tar/TarUpdate.h
@@ -13,15 +13,15 @@ struct CUpdateItem
{
int IndexInArchive;
int IndexInClient;
- UInt32 Time;
- UInt32 Mode;
+ Int64 MTime;
UInt64 Size;
- AString Name;
- AString User;
- AString Group;
+ UInt32 Mode;
bool NewData;
bool NewProps;
bool IsDir;
+ AString Name;
+ AString User;
+ AString Group;
};
HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
diff --git a/CPP/7zip/Archive/Udf/UdfIn.cpp b/CPP/7zip/Archive/Udf/UdfIn.cpp
index 60d5fc2a..d2a2884f 100755
--- a/CPP/7zip/Archive/Udf/UdfIn.cpp
+++ b/CPP/7zip/Archive/Udf/UdfIn.cpp
@@ -574,34 +574,33 @@ HRESULT CInArchive::Open2()
{
Clear();
+ // Some UDFs contain additional pad zeros (2 KB).
+ // Seek to STREAM_SEEK_END for direct DVD reading can return 8 KB more, so we check last 16 KB.
+ // And when we read last block, result read size can be smaller than required size.
+
UInt64 fileSize;
RINOK(_stream->Seek(0, STREAM_SEEK_END, &fileSize));
-
- // Some UDFs contain additional 2 KB of zeros, so we also check 12, corrected to 11.
- const int kSecLogSizeMax = 12;
- Byte buf[1 << kSecLogSizeMax];
- Byte kSizesLog[] = { 11, 8, 12 };
-
- for (int i = 0;; i++)
+ const size_t kBufSize = 1 << 14;
+ Byte buf[kBufSize];
+ size_t readSize = (fileSize < kBufSize) ? (size_t)fileSize : kBufSize;
+ RINOK(_stream->Seek(fileSize - readSize, STREAM_SEEK_SET, NULL));
+ RINOK(ReadStream(_stream, buf, &readSize));
+ size_t i = readSize;
+ for (;;)
{
- if (i == sizeof(kSizesLog) / sizeof(kSizesLog[0]))
- return S_FALSE;
- SecLogSize = kSizesLog[i];
- Int32 bufSize = 1 << SecLogSize;
- if (bufSize > fileSize)
+ const size_t kSecSizeMin = 1 << 8;
+ if (i < kSecSizeMin)
return S_FALSE;
- RINOK(_stream->Seek(-bufSize, STREAM_SEEK_END, NULL));
- RINOK(ReadStream_FALSE(_stream, buf, bufSize));
+ i -= kSecSizeMin;
+ SecLogSize = (readSize - i < ((size_t)1 << 11)) ? 8 : 11;
CTag tag;
- if (tag.Parse(buf, bufSize) == S_OK)
+ if (tag.Parse(buf + i, (1 << SecLogSize)) == S_OK)
if (tag.Id == DESC_TYPE_AnchorVolPtr)
break;
}
- if (SecLogSize == 12)
- SecLogSize = 11;
CExtent extentVDS;
- extentVDS.Parse(buf + 16);
+ extentVDS.Parse(buf + i + 16);
for (UInt32 location = extentVDS.Pos; ; location++)
{
diff --git a/CPP/7zip/Archive/UefiHandler.cpp b/CPP/7zip/Archive/UefiHandler.cpp
new file mode 100755
index 00000000..88739d8f
--- /dev/null
+++ b/CPP/7zip/Archive/UefiHandler.cpp
@@ -0,0 +1,1935 @@
+// UefiHandler.cpp
+
+#include "StdAfx.h"
+
+// #define SHOW_DEBUG_INFO
+
+// #include <stdio.h>
+
+#ifdef SHOW_DEBUG_INFO
+#include <stdio.h>
+#endif
+
+#include "../../../C/7zCrc.h"
+#include "../../../C/Alloc.h"
+#include "../../../C/CpuArch.h"
+#include "../../../C/LzmaDec.h"
+
+#include "Common/Buffer.h"
+#include "Common/ComTry.h"
+#include "Common/IntToString.h"
+#include "Common/StringConvert.h"
+
+#include "Windows/PropVariant.h"
+#include "Windows/PropVariantUtils.h"
+
+#include "../Common/ProgressUtils.h"
+#include "../Common/RegisterArc.h"
+#include "../Common/StreamObjects.h"
+#include "../Common/StreamUtils.h"
+
+#include "../Compress/CopyCoder.h"
+
+#include "./Common/FindSignature.h"
+
+#ifdef SHOW_DEBUG_INFO
+#define PRF(x) x
+#else
+#define PRF(x)
+#endif
+
+#define Get16(p) GetUi16(p)
+#define Get32(p) GetUi32(p)
+#define Get64(p) GetUi64(p)
+#define Get24(p) (Get32(p) & 0xFFFFFF)
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+namespace NArchive {
+namespace NUefi {
+
+static const UInt32 kBufTotalSizeMax = (1 << 29);
+static const UInt32 kNumFilesMax = (1 << 18);
+static const int kLevelMax = 64;
+
+static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
+static void SzFree(void *p, void *address) { p = p; MyFree(address); }
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+static const UInt32 kFvHeaderSize = 0x38;
+static const UInt32 kGuidSize = 16;
+static const UInt32 kCapsuleSigSize = kGuidSize;
+#define CAPSULE_SIGNATURE \
+ { 0xBD,0x86,0x66,0x3B,0x76,0x0D,0x30,0x40,0xB7,0x0E,0xB5,0x51,0x9E,0x2F,0xC5,0xA0 }
+static const Byte kCapsuleSig[kCapsuleSigSize] = CAPSULE_SIGNATURE;
+
+static const UInt32 kFfsGuidOffset = 16;
+#define FFS_SIGNATURE \
+ { 0xD9,0x54,0x93,0x7A,0x68,0x04,0x4A,0x44,0x81,0xCE,0x0B,0xF6,0x17,0xD8,0x90,0xDF }
+static const Byte k_FFS_Guid[kGuidSize] = FFS_SIGNATURE;
+
+static const Byte k_MacFS_Guid[kGuidSize] =
+ { 0xAD,0xEE,0xAD,0x04,0xFF,0x61,0x31,0x4D,0xB6,0xBA,0x64,0xF8,0xBF,0x90,0x1F,0x5A };
+
+static const UInt32 kFvSignature = 0x4856465F;
+
+static const Byte kGuids[][kGuidSize] =
+{
+ { 0xB0,0xCD,0x1B,0xFC,0x31,0x7D,0xAA,0x49,0x93,0x6A,0xA4,0x60,0x0D,0x9D,0xD0,0x83 },
+ { 0x2E,0x06,0xA0,0x1B,0x79,0xC7,0x82,0x45,0x85,0x66,0x33,0x6A,0xE8,0xF7,0x8F,0x09 },
+ { 0x25,0x4E,0x37,0x7E,0x01,0x8E,0xEE,0x4F,0x87,0xf2,0x39,0x0C,0x23,0xC6,0x06,0xCD },
+ { 0x97,0xE5,0x1B,0x16,0xC5,0xE9,0xDB,0x49,0xAE,0x50,0xC4,0x62,0xAB,0x54,0xEE,0xDA },
+ { 0xDB,0x7F,0xAD,0x77,0x2A,0xDF,0x02,0x43,0x88,0x98,0xC7,0x2E,0x4C,0xDB,0xD0,0xF4 },
+ { 0xAB,0x71,0xCF,0xF5,0x4B,0xB0,0x7E,0x4B,0x98,0x8A,0xD8,0xA0,0xD4,0x98,0xE6,0x92 },
+ { 0x91,0x45,0x53,0x7A,0xCE,0x37,0x81,0x48,0xB3,0xC9,0x71,0x38,0x14,0xF4,0x5D,0x6B },
+ { 0x84,0xE6,0x7A,0x36,0x5D,0x33,0x71,0x46,0xA1,0x6D,0x89,0x9D,0xBF,0xEA,0x6B,0x88 },
+ { 0x98,0x07,0x40,0x24,0x07,0x38,0x42,0x4A,0xB4,0x13,0xA1,0xEC,0xEE,0x20,0x5D,0xD8 },
+ { 0xEE,0xA2,0x3F,0x28,0x2C,0x53,0x4D,0x48,0x93,0x83,0x9F,0x93,0xB3,0x6F,0x0B,0x7E },
+ { 0x9B,0xD5,0xB8,0x98,0xBA,0xE8,0xEE,0x48,0x98,0xDD,0xC2,0x95,0x39,0x2F,0x1E,0xDB },
+ { 0x09,0x6D,0xE3,0xC3,0x94,0x82,0x97,0x4B,0xA8,0x57,0xD5,0x28,0x8F,0xE3,0x3E,0x28 },
+ { 0x18,0x88,0x53,0x4A,0xE0,0x5A,0xB2,0x4E,0xB2,0xEB,0x48,0x8B,0x23,0x65,0x70,0x22 }
+};
+
+
+static const char *kGuidNames[] =
+{
+ "CRC",
+ "VolumeTopFile",
+ "ACPI",
+ "ACPI2",
+ "Main",
+ "Intel32",
+ "Intel64",
+ "Intel32c",
+ "Intel64c",
+ "MacVolume",
+ "MacUpdate.txt",
+ "MacName",
+ "Insyde"
+};
+
+enum
+{
+ kGuidIndex_CRC = 0
+};
+
+struct CSigExtPair
+{
+ const char *ext;
+ unsigned sigSize;
+ Byte sig[16];
+};
+
+static const CSigExtPair g_Sigs[] =
+{
+ { "bmp", 2, { 'B','M' } },
+ { "riff", 4, { 'R','I','F','F' } },
+ { "pe", 2, { 'M','Z'} },
+ { "gif", 6, { 'G','I','F','8','9', 'a' } },
+ { "png", 8, { 0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A } },
+ { "jpg", 10, { 0xFF,0xD8,0xFF,0xE0,0x00,0x10,0x4A,0x46,0x49,0x46 } },
+ { "rom", 2, { 0x55,0xAA } }
+};
+
+enum
+{
+ kSig_BMP,
+ kSig_RIFF,
+ kSig_PE
+};
+
+static const char *FindExt(const Byte *p, size_t size)
+{
+ unsigned i;
+ for (i = 0; i < ARRAY_SIZE(g_Sigs); i++)
+ {
+ const CSigExtPair &pair = g_Sigs[i];
+ if (size >= pair.sigSize)
+ if (memcmp(p, pair.sig, pair.sigSize) == 0)
+ break;
+ }
+ if (i == ARRAY_SIZE(g_Sigs))
+ return NULL;
+ switch (i)
+ {
+ case kSig_BMP:
+ if (GetUi32(p + 2) > size || GetUi32(p + 0xA) > size)
+ return NULL;
+ break;
+ case kSig_RIFF:
+ if (GetUi32(p + 8) == 0x45564157 || GetUi32(p + 0xC) == 0x20746D66 )
+ return "wav";
+ break;
+ case kSig_PE:
+ {
+ if (size < 512)
+ return NULL;
+ UInt32 peOffset = GetUi32(p + 0x3C);
+ if (peOffset >= 0x1000 || peOffset + 512 > size || (peOffset & 7) != 0)
+ return NULL;
+ if (GetUi32(p + peOffset) != 0x00004550)
+ return NULL;
+ break;
+ }
+ }
+ return g_Sigs[i].ext;
+}
+
+static bool AreGuidsEq(const Byte *p1, const Byte *p2)
+{
+ return memcmp(p1, p2, kGuidSize) == 0;
+}
+
+static int FindGuid(const Byte *p)
+{
+ for (int i = 0; i < ARRAY_SIZE(kGuids); i++)
+ if (AreGuidsEq(p, kGuids[i]))
+ return i;
+ return -1;
+}
+
+static bool IsFfs(const Byte *p)
+{
+ return (Get32(p + 0x28) == kFvSignature && AreGuidsEq(p + kFfsGuidOffset, k_FFS_Guid));
+}
+
+#define FVB_ERASE_POLARITY (1 << 11)
+
+/*
+static const CUInt32PCharPair g_FV_Attribs[] =
+{
+ { 0, "ReadDisabledCap" },
+ { 1, "ReadEnabledCap" },
+ { 2, "ReadEnabled" },
+ { 3, "WriteDisabledCap" },
+ { 4, "WriteEnabledCap" },
+ { 5, "WriteEnabled" },
+ { 6, "LockCap" },
+ { 7, "Locked" },
+
+ { 9, "StickyWrite" },
+ { 10, "MemoryMapped" },
+ { 11, "ErasePolarity" },
+
+ { 12, "ReadLockCap" },
+ { 13, "WriteLockCap" },
+ { 14, "WriteLockCap" }
+};
+*/
+
+enum
+{
+ FV_FILETYPE_ALL,
+ FV_FILETYPE_RAW,
+ FV_FILETYPE_FREEFORM,
+ FV_FILETYPE_SECURITY_CORE,
+ FV_FILETYPE_PEI_CORE,
+ FV_FILETYPE_DXE_CORE,
+ FV_FILETYPE_PEIM,
+ FV_FILETYPE_DRIVER,
+ FV_FILETYPE_COMBINED_PEIM_DRIVER,
+ FV_FILETYPE_APPLICATION,
+ // The value 0x0A is reserved and should not be used
+ FV_FILETYPE_FIRMWARE_VOLUME_IMAGE = 0x0B,
+ // types 0xF0 - 0xFF are FFS file types
+ FV_FILETYPE_FFS_PAD = 0xF0
+};
+
+static const char *g_FileTypes[] =
+{
+ "ALL",
+ "RAW",
+ "FREEFORM",
+ "SECURITY_CORE",
+ "PEI_CORE",
+ "DXE_CORE",
+ "PEIM",
+ "DRIVER",
+ "COMBINED_PEIM_DRIVER",
+ "APPLICATION",
+ "0xA",
+ "VOLUME"
+};
+
+// typedef Byte FFS_FILE_ATTRIBUTES;
+// FFS File Attributes
+#define FFS_ATTRIB_TAIL_PRESENT 0x01
+// #define FFS_ATTRIB_RECOVERY 0x02
+// #define FFS_ATTRIB_HEADER_EXTENSION 0x04
+// #define FFS_ATTRIB_DATA_ALIGNMENT 0x38
+#define FFS_ATTRIB_CHECKSUM 0x40
+
+static const CUInt32PCharPair g_FFS_FILE_ATTRIBUTES[] =
+{
+ { 0, "" /* "TAIL" */ },
+ { 1, "RECOVERY" },
+ // { 2, "HEADER_EXTENSION" }, // reserved for future
+ { 6, "" /* "CHECKSUM" */ }
+};
+
+// static const Byte g_Allignment[8] = { 3, 4, 7, 9, 10, 12, 15, 16 };
+
+// typedef Byte FFS_FILE_STATE;
+
+// Look also FVB_ERASE_POLARITY.
+// Lower-order State bits are superceded by higher-order State bits.
+
+// #define FILE_HEADER_CONSTRUCTION 0x01
+// #define FILE_HEADER_VALID 0x02
+#define FILE_DATA_VALID 0x04
+// #define FILE_MARKED_FOR_UPDATE 0x08
+// #define FILE_DELETED 0x10
+// #define FILE_HEADER_INVALID 0x20
+
+// SECTION_TYPE
+
+#define SECTION_ALL 0x00
+
+#define SECTION_COMPRESSION 0x01
+#define SECTION_GUID_DEFINED 0x02
+
+// Leaf section Type values
+#define SECTION_PE32 0x10
+#define SECTION_PIC 0x11
+#define SECTION_TE 0x12
+#define SECTION_DXE_DEPEX 0x13
+#define SECTION_VERSION 0x14
+#define SECTION_USER_INTERFACE 0x15
+#define SECTION_COMPATIBILITY16 0x16
+#define SECTION_FIRMWARE_VOLUME_IMAGE 0x17
+#define SECTION_FREEFORM_SUBTYPE_GUID 0x18
+#define SECTION_RAW 0x19
+#define SECTION_PEI_DEPEX 0x1B
+
+
+// #define GUIDED_SECTION_PROCESSING_REQUIRED 0x01
+// #define GUIDED_SECTION_AUTH_STATUS_VALID 0x02
+
+static const CUInt32PCharPair g_GUIDED_SECTION_ATTRIBUTES[] =
+{
+ { 0, "PROCESSING_REQUIRED" },
+ { 1, "AUTH" }
+};
+
+static const CUInt32PCharPair g_SECTION_TYPE[] =
+{
+ { 0x01, "COMPRESSION" },
+ { 0x02, "GUID" },
+ { 0x10, "efi" },
+ { 0x11, "PIC" },
+ { 0x12, "te" },
+ { 0x13, "DXE_DEPEX" },
+ { 0x14, "VERSION" },
+ { 0x15, "USER_INTERFACE" },
+ { 0x16, "COMPATIBILITY16" },
+ { 0x17, "VOLUME" },
+ { 0x18, "FREEFORM_SUBTYPE_GUID" },
+ { 0x19, "raw" },
+ { 0x1B, "PEI_DEPEX" }
+};
+
+#define COMPRESSION_TYPE_NONE 0
+#define COMPRESSION_TYPE_LZH 1
+#define COMPRESSION_TYPE_LZMA 2
+
+static const char *g_Methods[] =
+{
+ "COPY",
+ "LZH",
+ "LZMA"
+};
+
+static AString UInt32ToString(UInt32 val)
+{
+ char sz[16];
+ ConvertUInt32ToString(val, sz);
+ return sz;
+}
+
+static void ConvertByteToHex(unsigned value, char *s)
+{
+ for (int i = 0; i < 2; i++)
+ {
+ unsigned t = value & 0xF;
+ value >>= 4;
+ s[1 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ }
+}
+
+static AString GuidToString(const Byte *p, bool full)
+{
+ char s[16 * 2 + 8];
+ int i;
+ for (i = 0; i < 4; i++)
+ ConvertByteToHex(p[3 - i], s + i * 2);
+ s[8] = 0;
+
+ if (full)
+ {
+ s[8] = '-';
+ for (i = 4; i < kGuidSize; i++)
+ ConvertByteToHex(p[i], s + 1 + i * 2);
+ s[32 + 1] = 0;
+ }
+ return s;
+}
+
+static const char *kExpressionCommands[] =
+{
+ "BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "TRUE", "FALSE", "END", "SOR"
+};
+
+static bool ParseDepedencyExpression(const Byte *p, UInt32 size, AString &res)
+{
+ res.Empty();
+ for (UInt32 i = 0; i < size;)
+ {
+ unsigned command = p[i++];
+ if (command > ARRAY_SIZE(kExpressionCommands))
+ return false;
+ res += kExpressionCommands[command];
+ if (command < 3)
+ {
+ if (i + kGuidSize > size)
+ return false;
+ res += " ";
+ res += GuidToString(p + i, false);
+ i += kGuidSize;
+ }
+ res += "; ";
+ }
+ return true;
+}
+
+static bool ParseUtf16zString(const Byte *p, UInt32 size, UString &res)
+{
+ if ((size & 1) != 0)
+ return false;
+ res.Empty();
+ UInt32 i;
+ for (i = 0; i < size; i += 2)
+ {
+ wchar_t c = Get16(p + i);
+ if (c == 0)
+ break;
+ res += c;
+ }
+ return (i == size - 2);
+}
+
+static bool ParseUtf16zString2(const Byte *p, UInt32 size, AString &res)
+{
+ UString s;
+ if (!ParseUtf16zString(p, size, s))
+ return false;
+ res = UnicodeStringToMultiByte(s);
+ return true;
+}
+
+#define FLAGS_TO_STRING(pairs, value) FlagsToString(pairs, ARRAY_SIZE(pairs), value)
+#define TYPE_TO_STRING(table, value) TypeToString(table, ARRAY_SIZE(table), value)
+#define TYPE_PAIR_TO_STRING(table, value) TypePairToString(table, ARRAY_SIZE(table), value)
+
+static const UInt32 kFileHeaderSize = 24;
+
+static void AddSpaceAndString(AString &res, const AString &newString)
+{
+ if (!res.IsEmpty() && !newString.IsEmpty())
+ res += ' ';
+ res += newString;
+}
+
+class CFfsFileHeader
+{
+ Byte CheckHeader;
+ Byte CheckFile;
+ Byte Attrib;
+ Byte State;
+
+ UInt16 GetTailReference() const { return CheckHeader | ((UInt16)CheckFile << 8); }
+ UInt32 GetTailSize() const { return IsThereTail() ? 2 : 0; }
+ bool IsThereFileChecksum() const { return (Attrib & FFS_ATTRIB_CHECKSUM) != 0; }
+ bool IsThereTail() const { return (Attrib & FFS_ATTRIB_TAIL_PRESENT) != 0; }
+public:
+ Byte GuidName[kGuidSize];
+ Byte Type;
+ UInt32 Size;
+
+ bool Parse(const Byte *p)
+ {
+ int i;
+ for (i = 0; i < kFileHeaderSize; i++)
+ if (p[i] != 0xFF)
+ break;
+ if (i == kFileHeaderSize)
+ return false;
+ memcpy(GuidName, p, kGuidSize);
+ CheckHeader = p[0x10];
+ CheckFile = p[0x11];
+ Type = p[0x12];
+ Attrib = p[0x13];
+ Size = Get24(p + 0x14);
+ State = p[0x17];
+ return true;
+ }
+
+ UInt32 GetDataSize() const { return Size - kFileHeaderSize - GetTailSize(); }
+
+ bool Check(const Byte *p, UInt32 size)
+ {
+ if (Size > size)
+ return false;
+ UInt32 tailSize = GetTailSize();
+ if (Size < kFileHeaderSize + tailSize)
+ return false;
+
+ {
+ unsigned checkSum = 0;
+ for (UInt32 i = 0; i < kFileHeaderSize; i++)
+ checkSum += p[i];
+ checkSum -= p[0x17];
+ checkSum -= p[0x11];
+ if ((Byte)checkSum != 0)
+ return false;
+ }
+
+ if (IsThereFileChecksum())
+ {
+ unsigned checkSum = 0;
+ UInt32 checkSize = Size - tailSize;
+ for (UInt32 i = 0; i < checkSize; i++)
+ checkSum += p[i];
+ checkSum -= p[0x17];
+ if ((Byte)checkSum != 0)
+ return false;
+ }
+
+ if (IsThereTail())
+ if (GetTailReference() != (UInt16)~Get16(p + Size - 2))
+ return false;
+
+ int polarity = 0;
+ int i;
+ for (i = 5; i >= 0; i--)
+ if (((State >> i) & 1) == polarity)
+ {
+ // AddSpaceAndString(s, g_FFS_FILE_STATE_Flags[i]);
+ if ((1 << i) != FILE_DATA_VALID)
+ return false;
+ break;
+ }
+ if (i < 0)
+ return false;
+
+ return true;
+ }
+
+ AString GetCharacts() const
+ {
+ AString s;
+ if (Type == FV_FILETYPE_FFS_PAD)
+ s += "PAD";
+ else
+ s += TYPE_TO_STRING(g_FileTypes, Type);
+ AddSpaceAndString(s, FLAGS_TO_STRING(g_FFS_FILE_ATTRIBUTES, Attrib & 0xC7));
+ /*
+ int align = (Attrib >> 3) & 7;
+ if (align != 0)
+ {
+ s += " Align:";
+ s += UInt32ToString((UInt32)1 << g_Allignment[align]);
+ }
+ */
+ return s;
+ }
+};
+
+#define GET_32(offs, dest) dest = Get32(p + (offs));
+#define GET_64(offs, dest) dest = Get64(p + (offs));
+
+struct CCapsuleHeader
+{
+ UInt32 HeaderSize;
+ UInt32 Flags;
+ UInt32 CapsuleImageSize;
+ UInt32 SequenceNumber;
+ // Guid InstanceId;
+ UInt32 OffsetToSplitInformation;
+ UInt32 OffsetToCapsuleBody;
+ UInt32 OffsetToOemDefinedHeader;
+ UInt32 OffsetToAuthorInformation;
+ UInt32 OffsetToRevisionInformation;
+ UInt32 OffsetToShortDescription;
+ UInt32 OffsetToLongDescription;
+ UInt32 OffsetToApplicableDevices;
+
+ void Clear() { memset(this, 0, sizeof(this)); }
+
+ void Parse(const Byte *p)
+ {
+ GET_32(0x10, HeaderSize);
+ GET_32(0x14, Flags);
+ GET_32(0x18, CapsuleImageSize);
+ GET_32(0x1C, SequenceNumber);
+ GET_32(0x30, OffsetToSplitInformation);
+ GET_32(0x34, OffsetToCapsuleBody);
+ GET_32(0x38, OffsetToOemDefinedHeader);
+ GET_32(0x3C, OffsetToAuthorInformation);
+ GET_32(0x40, OffsetToRevisionInformation);
+ GET_32(0x44, OffsetToShortDescription);
+ GET_32(0x48, OffsetToLongDescription);
+ GET_32(0x4C, OffsetToApplicableDevices);
+ }
+};
+
+struct CItem
+{
+ AString Name;
+ AString Characts;
+ int Parent;
+ int Method;
+ int NameIndex;
+ int NumChilds;
+ bool IsDir;
+ bool Skip;
+ bool ThereAreSubDirs;
+ bool ThereIsUniqueName;
+ bool KeepName;
+
+ int BufIndex;
+ UInt32 Offset;
+ UInt32 Size;
+
+ CItem(): Parent(-1), Method(-1), NameIndex(-1), NumChilds(0),
+ IsDir(false), Skip(false), ThereAreSubDirs(false), ThereIsUniqueName(false), KeepName(true) {}
+ void SetGuid(const Byte *guidName, bool full = false);
+ AString GetName(int numChildsInParent) const;
+};
+
+void CItem::SetGuid(const Byte *guidName, bool full)
+{
+ ThereIsUniqueName = true;
+ int index = FindGuid(guidName);
+ if (index >= 0)
+ Name = kGuidNames[index];
+ else
+ Name = GuidToString(guidName, full);
+}
+
+AString CItem::GetName(int numChildsInParent) const
+{
+ if (numChildsInParent <= 1 || NameIndex < 0)
+ return Name;
+ char sz[32];
+ char sz2[32];
+ ConvertUInt32ToString(NameIndex, sz);
+ ConvertUInt32ToString(numChildsInParent - 1, sz2);
+ int numZeros = (int)strlen(sz2) - (int)strlen(sz);
+ AString res;
+ for (int i = 0; i < numZeros; i++)
+ res += '0';
+ return res + (AString)sz + '.' + Name;
+}
+
+struct CItem2
+{
+ AString Name;
+ AString Characts;
+ int MainIndex;
+ int Parent;
+
+ CItem2(): Parent(-1) {}
+};
+
+class CHandler:
+ public IInArchive,
+ public IInArchiveGetStream,
+ public CMyUnknownImp
+{
+ CObjectVector<CItem> _items;
+ CObjectVector<CItem2> _items2;
+ CObjectVector<CByteBuffer> _bufs;
+ UString _comment;
+ UInt32 _methodsMask;
+ bool _capsuleMode;
+
+ UInt32 _totalBufsSize;
+ CCapsuleHeader _h;
+
+ void AddCommentString(const wchar_t *name, UInt32 pos);
+ int AddItem(const CItem &item);
+ int AddFileItemWithIndex(CItem &item);
+ int AddDirItem(CItem &item);
+ int AddBuf(UInt32 size);
+
+ HRESULT ParseSections(int bufIndex, UInt32 pos, UInt32 size, int parent, int method, int level);
+ HRESULT ParseVolume(int bufIndex, UInt32 posBase, UInt32 size, int parent, int method, int level);
+ HRESULT OpenCapsule(IInStream *stream);
+ HRESULT OpenFv(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback);
+ HRESULT Open2(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback);
+public:
+ CHandler(bool capsuleMode): _capsuleMode(capsuleMode) {}
+ MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
+ INTERFACE_IInArchive(;)
+ STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
+};
+
+static const STATPROPSTG kProps[] =
+{
+ { NULL, kpidPath, VT_BSTR},
+ { NULL, kpidIsDir, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidMethod, VT_BSTR},
+ { NULL, kpidCharacts, VT_BSTR}
+};
+
+static const STATPROPSTG kArcProps[] =
+{
+ { NULL, kpidComment, VT_BSTR},
+ { NULL, kpidMethod, VT_BSTR},
+ { NULL, kpidPhySize, VT_UI8},
+ { NULL, kpidCharacts, VT_BSTR}
+};
+
+IMP_IInArchive_Props
+IMP_IInArchive_ArcProps
+
+STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant prop;
+ const CItem2 &item2 = _items2[index];
+ const CItem &item = _items[item2.MainIndex];
+ switch(propID)
+ {
+ case kpidPath:
+ {
+ AString path = item2.Name;
+ int cur = item2.Parent;
+ while (cur >= 0)
+ {
+ const CItem2 &item2 = _items2[cur];
+ path = item2.Name + CHAR_PATH_SEPARATOR + path;
+ cur = item2.Parent;
+ }
+ prop = path;
+ break;
+ }
+ case kpidIsDir: prop = item.IsDir; break;
+ case kpidMethod: if (item.Method >= 0) prop = g_Methods[item.Method]; break;
+ case kpidCharacts: if (!item2.Characts.IsEmpty()) prop = item2.Characts; break;
+ case kpidSize: if (!item.IsDir) prop = (UInt64)item.Size; break;
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+void CHandler::AddCommentString(const wchar_t *name, UInt32 pos)
+{
+ UString s;
+ const Byte *buf = _bufs[0];
+ if (pos < _h.HeaderSize)
+ return;
+ for (UInt32 i = pos;; i += 2)
+ {
+ if (s.Length() > (1 << 16) || i >= _h.OffsetToCapsuleBody)
+ return;
+ wchar_t c = Get16(buf + i);
+ if (c == 0)
+ {
+ i += 2;
+ if (i >= _h.OffsetToCapsuleBody)
+ return;
+ c = Get16(buf + i);
+ if (c == 0)
+ break;
+ s += L'\n';
+ }
+ s += c;
+ }
+ if (s.IsEmpty())
+ return;
+ _comment += L'\n';
+ _comment += name;
+ _comment += L": ";
+ _comment += s;
+}
+
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant prop;
+ switch(propID)
+ {
+ case kpidMethod:
+ {
+ AString s;
+ for (int i = 0; i < 32; i++)
+ if ((_methodsMask & ((UInt32)1 << i)) != 0)
+ AddSpaceAndString(s, g_Methods[i]);
+ if (!s.IsEmpty())
+ prop = s;
+ break;
+ }
+ case kpidComment: if (!_comment.IsEmpty()) prop = _comment; break;
+ case kpidPhySize: prop = (UInt64)_h.CapsuleImageSize; break;
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+#ifdef SHOW_DEBUG_INFO
+static void PrintLevel(int level)
+{
+ PRF(printf("\n"));
+ for (int i = 0; i < level; i++)
+ PRF(printf(" "));
+}
+static void MyPrint(UInt32 posBase, UInt32 size, int level, const char *name)
+{
+ PrintLevel(level);
+ PRF(printf("%s, pos = %6x, size = %6d", name, posBase, size));
+}
+#else
+#define PrintLevel(level)
+#define MyPrint(posBase, size, level, name)
+#endif
+
+static const unsigned kNumBigValueBits = 8 * 4;
+static const unsigned kNumValueBytes = 3;
+static const unsigned kNumValueBits = 8 * kNumValueBytes;
+static const UInt32 kMask = (1 << kNumValueBits) - 1;
+
+class CBitmMemDecoder
+{
+ unsigned _bitPos;
+ UInt32 _value;
+ const Byte *_buf;
+ size_t _pos;
+ size_t _size;
+ size_t _extra;
+public:
+ void Init(const Byte *buf, size_t size)
+ {
+ _buf = buf;
+ _size = size;
+ _pos = 0;
+ _extra = 0;
+ _bitPos = kNumBigValueBits;
+ Normalize();
+ }
+
+ bool IsFullFinished() const { return (_extra * 8) == (kNumBigValueBits - _bitPos); }
+
+ void Normalize()
+ {
+ for (; _bitPos >= 8; _bitPos -= 8)
+ {
+ Byte b;
+ if (_pos < _size)
+ b = _buf[_pos++];
+ else
+ {
+ b = 0;
+ _extra++;
+ }
+ _value = (_value << 8) | b;
+ }
+ }
+
+ UInt32 GetValue(unsigned numBits) const
+ {
+ return ((_value >> (8 - _bitPos)) & kMask) >> (kNumValueBits - numBits);
+ }
+
+ void MovePos(unsigned numBits)
+ {
+ _bitPos += numBits;
+ Normalize();
+ }
+
+ UInt32 ReadBitsFast(unsigned numBits)
+ {
+ UInt32 res = GetValue(numBits);
+ MovePos(numBits);
+ return res;
+ }
+
+ UInt32 ReadBits(unsigned numBits);
+ UInt32 ReadAlignBits() { return ReadBits((32 - _bitPos) & 7); }
+};
+
+UInt32 CBitmMemDecoder::ReadBits(unsigned numBits)
+{
+ UInt32 res = GetValue(numBits);
+ MovePos(numBits);
+ return res;
+}
+
+namespace NHuffman {
+
+static const int kNumTableBits = 9;
+static const int kNumBitsMax = 16;
+
+class CDecoder
+{
+ UInt32 m_Limits[kNumBitsMax + 1];
+ UInt32 m_Positions[kNumBitsMax + 1];
+ Byte m_Lengths[1 << kNumTableBits];
+ Int32 m_MainSymbol;
+
+public:
+ UInt32 *m_Symbols;
+ UInt32 m_NumSymbols;
+
+ void SetSingleSymbolMode(UInt32 symbol) { m_MainSymbol = symbol; }
+ bool SetCodeLengths(const Byte *codeLengths);
+ UInt32 DecodeSymbol(CBitmMemDecoder *bitStream)
+ {
+ if (m_MainSymbol != -1)
+ return (UInt32)m_MainSymbol;
+ int numBits;
+ UInt32 value = bitStream->GetValue(kNumBitsMax);
+ if (value < m_Limits[kNumTableBits])
+ numBits = m_Lengths[value >> (kNumBitsMax - kNumTableBits)];
+ else
+ for (numBits = kNumTableBits + 1; value >= m_Limits[numBits]; numBits++);
+ bitStream->MovePos(numBits);
+ return m_Symbols[m_Positions[numBits] + ((value - m_Limits[numBits - 1]) >> (kNumBitsMax - numBits))];
+ }
+};
+
+bool CDecoder::SetCodeLengths(const Byte *codeLengths)
+{
+ m_MainSymbol = -1;
+ int lenCounts[kNumBitsMax + 1];
+ UInt32 tmpPositions[kNumBitsMax + 1];
+ int i;
+ for (i = 1; i <= kNumBitsMax; i++)
+ lenCounts[i] = 0;
+ UInt32 symbol;
+ for (symbol = 0; symbol < m_NumSymbols; symbol++)
+ {
+ int len = codeLengths[symbol];
+ if (len > kNumBitsMax)
+ return false;
+ lenCounts[len]++;
+ m_Symbols[symbol] = 0xFFFFFFFF;
+ }
+ lenCounts[0] = 0;
+ m_Positions[0] = m_Limits[0] = 0;
+ UInt32 startPos = 0;
+ UInt32 index = 0;
+ const UInt32 kMaxValue = (1 << kNumBitsMax);
+ for (i = 1; i <= kNumBitsMax; i++)
+ {
+ startPos += lenCounts[i] << (kNumBitsMax - i);
+ if (startPos > kMaxValue)
+ return false;
+ m_Limits[i] = (i == kNumBitsMax) ? kMaxValue : startPos;
+ m_Positions[i] = m_Positions[i - 1] + lenCounts[i - 1];
+ tmpPositions[i] = m_Positions[i];
+ if (i <= kNumTableBits)
+ {
+ UInt32 limit = (m_Limits[i] >> (kNumBitsMax - kNumTableBits));
+ for (; index < limit; index++)
+ m_Lengths[index] = (Byte)i;
+ }
+ }
+ if (startPos != kMaxValue)
+ return false;
+ for (symbol = 0; symbol < m_NumSymbols; symbol++)
+ {
+ int len = codeLengths[symbol];
+ if (len != 0)
+ m_Symbols[tmpPositions[len]++] = symbol;
+ }
+ return true;
+}
+
+}
+
+static const int kMaxHuffmanLen = 16;
+static const int kExtraSize = kMaxHuffmanLen + 3;
+static const int kMinMatchLen = 3;
+static const int kMaxMatchLen = 256;
+static const int kNumAlphaSymsMax = 256 + kMaxMatchLen - kMinMatchLen + 1;
+static const int kNumDistSymsMax = 24 + 2; // it's limited by bit decoder.
+
+#define HUFF_START_CODE(huff, numSymsMax, numSymBits) \
+ UInt32 numSyms = bitDec.ReadBits(numSymBits); \
+ Byte lens[numSymsMax]; memset(lens, 0, sizeof(lens)); \
+ if (numSyms > (numSymsMax)) return S_FALSE; \
+ huff.m_NumSymbols = numSyms; \
+ if (numSyms == 0) { \
+ numSyms = bitDec.ReadBits(numSymBits); \
+ if (numSyms >= (numSymsMax)) return S_FALSE; \
+ huff.SetSingleSymbolMode(numSyms); } \
+
+static HRESULT LzhDecode(Byte *dest, UInt32 destSize, const Byte *src, UInt32 srcSize)
+{
+ if (srcSize < 8)
+ return S_FALSE;
+ {
+ UInt32 packSize = Get32(src);
+ UInt32 unpackSize = Get32(src + 4);
+ src += 8;
+ srcSize -= 8;
+ if (destSize != unpackSize || srcSize != packSize)
+ return S_FALSE;
+ }
+
+ CBitmMemDecoder bitDec;
+ bitDec.Init(src, srcSize);
+
+ UInt32 pos = 0;
+ for (;;)
+ {
+ UInt32 blockSize = bitDec.ReadBits(16);
+ UInt32 symbols[kExtraSize + kNumAlphaSymsMax + kNumDistSymsMax];
+
+ NHuffman::CDecoder extraHuff;
+ extraHuff.m_Symbols = symbols;
+ {
+ HUFF_START_CODE(extraHuff, kExtraSize, 5)
+ else
+ {
+ for (UInt32 i = 0; i < numSyms; i++)
+ {
+ if (i == 3)
+ {
+ UInt32 numZeros = bitDec.ReadBits(2);
+ if (i + numZeros > numSyms)
+ return S_FALSE;
+ for (UInt32 j = 0; j < numZeros; j++, i++)
+ lens[i] = (Byte)0;
+ if (i == numSyms)
+ break;
+ }
+
+ UInt32 len = bitDec.ReadBits(3);
+ if (len == 7)
+ {
+ for(;; len++)
+ {
+ if (len > kMaxHuffmanLen)
+ return S_FALSE;
+ if (bitDec.ReadBits(1) == 0)
+ break;
+ }
+ }
+ lens[i] = (Byte)len;
+ }
+ if (!extraHuff.SetCodeLengths(lens))
+ return S_FALSE;
+ }
+ }
+
+ NHuffman::CDecoder symHuff;
+ symHuff.m_Symbols = symbols + kExtraSize;
+ {
+ HUFF_START_CODE(symHuff, kNumAlphaSymsMax, 9)
+ else
+ {
+ for (UInt32 i = 0; i < numSyms;)
+ {
+ UInt32 c = extraHuff.DecodeSymbol(&bitDec);
+ if (c > 2)
+ lens[i++] = (Byte)c - 2;
+ else
+ {
+ UInt32 numZeros;
+ if (c == 0)
+ numZeros = 1;
+ else if (c == 1)
+ numZeros = bitDec.ReadBits(4) + 3;
+ else
+ numZeros = bitDec.ReadBits(9) + 20;
+ if (i + numZeros > numSyms)
+ return S_FALSE;
+ for (UInt32 j = 0; j < numZeros; j++, i++)
+ lens[i] = (Byte)0;
+ }
+ }
+ if (!symHuff.SetCodeLengths(lens))
+ return S_FALSE;
+ }
+ }
+
+ NHuffman::CDecoder distHuff;
+ distHuff.m_Symbols = symbols + kExtraSize + kNumAlphaSymsMax;
+ {
+ const UInt32 version = 1;
+ const UInt32 numDistBits = version + 4;
+ HUFF_START_CODE(distHuff, kNumDistSymsMax, numDistBits)
+ else
+ {
+ for (UInt32 i = 0; i < numSyms; i++)
+ {
+ UInt32 len = bitDec.ReadBits(3);
+ if (len == 7)
+ {
+ for(;; len++)
+ {
+ if (len > kMaxHuffmanLen)
+ return S_FALSE;
+ if (bitDec.ReadBits(1) == 0)
+ break;
+ }
+ }
+ lens[i] = (Byte)len;
+ }
+ if (!distHuff.SetCodeLengths(lens))
+ return S_FALSE;
+ }
+ }
+
+ while (blockSize)
+ {
+ blockSize--;
+ UInt32 c = symHuff.DecodeSymbol(&bitDec);
+ if (c < 256)
+ {
+ if (destSize == 0)
+ return S_FALSE;
+ *dest++ = (Byte)c;
+ destSize--;
+ pos++;
+ continue;
+ }
+ c = c - 256 + kMinMatchLen;
+ if (destSize < c)
+ return S_FALSE;
+ UInt32 dist = distHuff.DecodeSymbol(&bitDec);
+ if (dist > 1)
+ dist = ((UInt32)1 << (dist - 1)) + bitDec.ReadBits(dist - 1);
+ dist++;
+ if (dist > pos)
+ return S_FALSE;
+ pos += c;
+ destSize -= c;
+ do
+ {
+ *dest = dest[0 - (Int32)dist];
+ dest++;
+ }
+ while (--c);
+ }
+
+ // PRF(printf("\ndestSize = %6d", destSize));
+ if (destSize == 0)
+ {
+ if (bitDec.ReadAlignBits() != 0)
+ return S_FALSE;
+ if (bitDec.ReadBits(8) != 0)
+ return S_FALSE;
+ if (!bitDec.IsFullFinished())
+ return S_FALSE;
+ break;
+ }
+ }
+ return S_OK;
+}
+
+int CHandler::AddItem(const CItem &item)
+{
+ if (_items.Size() >= kNumFilesMax)
+ throw 2;
+ return _items.Add(item);
+}
+
+int CHandler::AddFileItemWithIndex(CItem &item)
+{
+ int nameIndex = _items.Size();
+ if (item.Parent >= 0)
+ nameIndex = _items[item.Parent].NumChilds++;
+ item.NameIndex = nameIndex;
+ return AddItem(item);
+}
+
+int CHandler::AddDirItem(CItem &item)
+{
+ if (item.Parent >= 0)
+ _items[item.Parent].ThereAreSubDirs = true;
+ item.IsDir = true;
+ item.Size = 0;
+ return AddItem(item);
+}
+
+int CHandler::AddBuf(UInt32 size)
+{
+ if (size > kBufTotalSizeMax - _totalBufsSize)
+ throw 1;
+ _totalBufsSize += size;
+ int index = _bufs.Add(CByteBuffer());
+ _bufs[index].SetCapacity(size);
+ return index;
+}
+
+HRESULT CHandler::ParseSections(int bufIndex, UInt32 posBase, UInt32 size, int parent, int method, int level)
+{
+ if (level > kLevelMax)
+ return S_FALSE;
+ MyPrint(posBase, size, level, "Sections");
+ level++;
+ const Byte *bufData = _bufs[bufIndex];
+ UInt32 pos = 0;
+ for (;;)
+ {
+ if (size == pos)
+ return S_OK;
+ PrintLevel(level);
+ PRF(printf("%s, pos = %6x", "Sect", pos));
+ pos = (pos + 3) & ~(UInt32)3;
+ if (pos > size)
+ return S_FALSE;
+ UInt32 rem = size - pos;
+ if (rem == 0)
+ return S_OK;
+ if (rem < 4)
+ return S_FALSE;
+ const Byte *p = bufData + posBase + pos;
+ UInt32 sectSize = Get24(p);
+ if (sectSize > rem || sectSize < 4)
+ return S_FALSE;
+
+ Byte type = p[3];
+ PrintLevel(level);
+ PRF(printf("%s, type = %2x, pos = %6x, size = %6d", "Sect", type, pos, sectSize));
+ CItem item;
+ item.Method = method;
+ item.BufIndex = bufIndex;
+ item.Parent = parent;
+ item.Offset = posBase + pos + 4;
+ UInt32 sectDataSize = sectSize - 4;
+ item.Size = sectDataSize;
+ item.Name = TYPE_PAIR_TO_STRING(g_SECTION_TYPE, type);
+
+ if (type == SECTION_COMPRESSION)
+ {
+ if (sectSize < 4 + 5)
+ return S_FALSE;
+ UInt32 uncompressedSize = Get32(p + 4);
+ Byte compressionType = p[8];
+
+ UInt32 newSectSize = sectSize - 9;
+ UInt32 newOffset = posBase + pos + 9;
+ const Byte *pStart = p + 9;
+
+ item.KeepName = false;
+ if (compressionType > 2)
+ {
+ // AddFileItemWithIndex(item);
+ return S_FALSE;
+ }
+ else
+ {
+ item.Name = g_Methods[compressionType];
+ // int parent = AddDirItem(item);
+ if (compressionType == COMPRESSION_TYPE_NONE)
+ {
+ RINOK(ParseSections(bufIndex, newOffset, newSectSize, parent, method, level));
+ }
+ else if (compressionType == COMPRESSION_TYPE_LZH)
+ {
+ int newBufIndex = AddBuf(uncompressedSize);
+ CByteBuffer &buf = _bufs[newBufIndex];
+ RINOK(LzhDecode(buf, uncompressedSize, pStart, newSectSize));
+ RINOK(ParseSections(newBufIndex, 0, uncompressedSize, parent, compressionType, level));
+ }
+ else
+ {
+ if (newSectSize < 4 + 5 + 8)
+ return S_FALSE;
+ unsigned addSize = 4;
+ if (pStart[0] == 0x5d && pStart[1] == 0 && pStart[2] == 0 && pStart[3] == 0x80 && pStart[4] == 0)
+ {
+ addSize = 0;
+ // some archives have such header
+ }
+ else
+ {
+ // normal BIOS contains uncompressed size here
+ // UInt32 uncompressedSize2 = Get24(pStart);
+ // Byte firstSectType = p[9 + 3];
+ // firstSectType can be 0 in some archives
+ }
+ pStart += addSize;
+ UInt64 lzmaUncompressedSize = Get64(pStart + 5);
+ if (lzmaUncompressedSize > (1 << 30))
+ return S_FALSE;
+ if (lzmaUncompressedSize < uncompressedSize)
+ return S_FALSE;
+ SizeT destLen = (SizeT)lzmaUncompressedSize;
+ int newBufIndex = AddBuf((UInt32)lzmaUncompressedSize);
+ CByteBuffer &buf = _bufs[newBufIndex];
+ ELzmaStatus status;
+ SizeT srcLen = newSectSize - (addSize + 5 + 8);
+ SizeT srcLen2 = srcLen;
+ SRes res = LzmaDecode(buf, &destLen, pStart + 13, &srcLen,
+ pStart, 5, LZMA_FINISH_END, &status, &g_Alloc);
+ if (res != 0)
+ return S_FALSE;
+ if (srcLen != srcLen2 || destLen != lzmaUncompressedSize || status != LZMA_STATUS_FINISHED_WITH_MARK)
+ return S_FALSE;
+ RINOK(ParseSections(newBufIndex, 0, (UInt32)lzmaUncompressedSize, parent, compressionType, level));
+ }
+ _methodsMask |= (1 << compressionType);
+ }
+ }
+ else if (type == SECTION_GUID_DEFINED)
+ {
+ const UInt32 kHeaderSize = 4 + kGuidSize + 4;
+ if (sectSize < kHeaderSize)
+ return S_FALSE;
+ item.SetGuid(p + 4);
+ UInt32 dataOffset = Get16(p + 4 + kGuidSize);
+ UInt32 attrib = Get16(p + 4 + kGuidSize + 2);
+ if (dataOffset > sectSize || dataOffset < kHeaderSize)
+ return S_FALSE;
+ UInt32 newSectSize = sectSize - dataOffset;
+ item.Size = newSectSize;
+ UInt32 newOffset = posBase + pos + dataOffset;
+ item.Offset = newOffset;
+ UInt32 propsSize = dataOffset - kHeaderSize;
+ bool needDir = true;
+ AddSpaceAndString(item.Characts, FLAGS_TO_STRING(g_GUIDED_SECTION_ATTRIBUTES, attrib));
+ if (AreGuidsEq(p + 0x4, kGuids[kGuidIndex_CRC]) && propsSize == 4)
+ {
+ needDir = false;
+ item.KeepName = false;
+ if (CrcCalc(bufData + newOffset, newSectSize) != Get32(p + kHeaderSize))
+ return S_FALSE;
+ }
+ else
+ {
+ if (propsSize != 0)
+ {
+ CItem item2 = item;
+ item2.Name += ".prop";
+ item2.Size = propsSize;
+ item2.Offset = posBase + pos + kHeaderSize;
+ AddItem(item2);
+ }
+ }
+ int newParent = parent;
+ if (needDir)
+ newParent = AddDirItem(item);
+ RINOK(ParseSections(bufIndex, newOffset, newSectSize, newParent, method, level));
+ }
+ else if (type == SECTION_FIRMWARE_VOLUME_IMAGE)
+ {
+ item.KeepName = false;
+ int newParent = AddDirItem(item);
+ RINOK(ParseVolume(bufIndex, posBase + pos + 4, sectSize - 4, newParent, method, level));
+ }
+ else
+ {
+ bool needAdd = true;
+ switch(type)
+ {
+ case SECTION_RAW:
+ {
+ const UInt32 kInsydeOffset = 12;
+ if (sectDataSize >= kFvHeaderSize + kInsydeOffset)
+ {
+ if (IsFfs(p + 4 + kInsydeOffset) &&
+ sectDataSize - kInsydeOffset == Get64(p + 4 + kInsydeOffset + 0x20))
+ {
+ needAdd = false;
+ item.Name = "vol";
+ int newParent = AddDirItem(item);
+ RINOK(ParseVolume(bufIndex, posBase + pos + 4 + kInsydeOffset, sectDataSize - kInsydeOffset, newParent, method, level));
+ }
+
+ if (needAdd)
+ {
+ const char *ext = FindExt(p + 4, sectDataSize);
+ if (ext)
+ item.Name = ext;
+ }
+ }
+ break;
+ }
+ case SECTION_DXE_DEPEX:
+ case SECTION_PEI_DEPEX:
+ {
+ AString s;
+ if (ParseDepedencyExpression(p + 4, sectDataSize, s))
+ {
+ if (s.Length() < (1 << 9))
+ {
+ s = '[' + s + ']';
+ AddSpaceAndString(_items[item.Parent].Characts, s);
+ needAdd = false;
+ }
+ else
+ {
+ item.BufIndex = AddBuf(s.Length());
+ CByteBuffer &buf0 = _bufs[item.BufIndex];
+ memcpy(buf0, s, s.Length());
+ item.Offset = 0;
+ item.Size = s.Length();
+ }
+ }
+ break;
+ }
+ case SECTION_VERSION:
+ {
+ if (sectDataSize > 2)
+ {
+ AString s;
+ if (ParseUtf16zString2(p + 6, sectDataSize - 2, s))
+ {
+ AddSpaceAndString(_items[item.Parent].Characts, (AString)"ver:" + UInt32ToString(Get16(p + 4)) + ' ' + s);
+ needAdd = false;
+ }
+ }
+ break;
+ }
+ case SECTION_USER_INTERFACE:
+ {
+ AString s;
+ if (ParseUtf16zString2(p + 4, sectDataSize, s))
+ {
+ _items[parent].Name = s;
+ needAdd = false;
+ }
+ break;
+ }
+ case SECTION_FREEFORM_SUBTYPE_GUID:
+ {
+ if (sectDataSize >= kGuidSize)
+ {
+ item.SetGuid(p + 4);
+ item.Size = sectDataSize - kGuidSize;
+ item.Offset = posBase + pos + 4 + kGuidSize;
+ }
+ break;
+ }
+ }
+
+ if (needAdd)
+ AddFileItemWithIndex(item);
+ }
+ pos += sectSize;
+ }
+}
+
+static UInt32 Count_FF_Bytes(const Byte *p, UInt32 size)
+{
+ UInt32 i;
+ for (i = 0; i < size && p[i] == 0xFF; i++);
+ return i;
+}
+
+static bool Is_FF_Stream(const Byte *p, UInt32 size)
+{
+ return (Count_FF_Bytes(p, size) == size);
+}
+
+HRESULT CHandler::ParseVolume(int bufIndex, UInt32 posBase, UInt32 size, int parent, int method, int level)
+{
+ if (level > kLevelMax)
+ return S_FALSE;
+ MyPrint(posBase, size, level, "Volume");
+ level++;
+ if (size < kFvHeaderSize)
+ return S_FALSE;
+ const Byte *p = _bufs[bufIndex] + posBase;
+ // first 16 bytes must be zeros, but they are not zeros sometimes.
+ if (!AreGuidsEq(p + kFfsGuidOffset, k_FFS_Guid) &&
+ !AreGuidsEq(p + kFfsGuidOffset, k_MacFS_Guid))
+ {
+ CItem item;
+ item.Method = method;
+ item.BufIndex = bufIndex;
+ item.Parent = parent;
+ item.Offset = posBase;
+ item.Size = size;
+ item.SetGuid(p + kFfsGuidOffset);
+ item.Name += " [VOLUME]";
+ AddItem(item);
+ return S_OK;
+ }
+
+ if (Get32(p + 0x28) != kFvSignature)
+ return S_FALSE;
+ UInt32 attribs = Get32(p + 0x2C);
+ if ((attribs & FVB_ERASE_POLARITY) == 0)
+ return S_FALSE;
+ // if (parent >= 0) AddSpaceAndString(_items[parent].Characts, FLAGS_TO_STRING(g_FV_Attribs, attribs));
+ UInt64 fvLen = Get64(p + 0x20);
+ UInt32 headerLen = Get16(p + 0x30);
+ if (headerLen > size || headerLen < kFvHeaderSize || (headerLen & 0x7) != 0 ||
+ fvLen > size || fvLen < headerLen)
+ return S_FALSE;
+
+ {
+ UInt32 checkCalc = 0;
+ for (UInt32 i = 0; i < headerLen; i += 2)
+ checkCalc += Get16(p + i);
+ if ((checkCalc & 0xFFFF) != 0)
+ return S_FALSE;
+ }
+
+ // 3 reserved bytes are not zeros sometimes.
+ // UInt16 ExtHeaderOffset; // in new SPECIFICATION?
+ // Byte revision = p[0x37];
+
+ UInt32 pos = kFvHeaderSize;
+ for (;;)
+ {
+ if (pos >= headerLen)
+ return S_FALSE;
+ UInt32 numBlocks = Get32(p + pos);
+ UInt32 length = Get32(p + pos + 4);
+ pos += 8;
+ if (numBlocks == 0 && length == 0)
+ break;
+ }
+ if (pos != headerLen)
+ return S_FALSE;
+
+ CRecordVector<UInt32> guidsVector;
+
+ for (;;)
+ {
+ UInt32 rem = (UInt32)fvLen - pos;
+ if (rem < kFileHeaderSize)
+ break;
+ pos = (pos + 7) & ~7;
+ rem = (UInt32)fvLen - pos;
+ if (rem < kFileHeaderSize)
+ break;
+
+ CItem item;
+ item.Method = method;
+ item.BufIndex = bufIndex;
+ item.Parent = parent;
+
+ const Byte *pFile = p + pos;
+ CFfsFileHeader fh;
+ if (!fh.Parse(pFile))
+ {
+ UInt32 num_FF_bytes = Count_FF_Bytes(pFile, rem);
+ if (num_FF_bytes != rem)
+ {
+ item.Name = "[junk]";
+ item.Offset = posBase + pos + num_FF_bytes;
+ item.Size = rem - num_FF_bytes;
+ AddItem(item);
+ }
+ break;
+ }
+ PrintLevel(level); PRF(printf("%s, pos = %6x, size = %6d", "FILE", posBase + pos, fh.Size));
+ if (!fh.Check(pFile, rem))
+ return S_FALSE;
+
+ UInt32 offset = posBase + pos + kFileHeaderSize;
+ UInt32 sectSize = fh.GetDataSize();
+ item.Offset = offset;
+ item.Size = sectSize;
+
+ pos += fh.Size;
+
+ if (fh.Type == FV_FILETYPE_FFS_PAD)
+ if (Is_FF_Stream(pFile + kFileHeaderSize, sectSize))
+ continue;
+
+ UInt32 guid32 = Get32(fh.GuidName);
+ bool full = true;
+ if (guidsVector.FindInSorted(guid32) < 0)
+ {
+ guidsVector.AddToUniqueSorted(guid32);
+ full = false;
+ }
+ item.SetGuid(fh.GuidName, full);
+
+ item.Characts = fh.GetCharacts();
+ PrintLevel(level);
+ PRF(printf("%s", item.Characts));
+
+ if (fh.Type == FV_FILETYPE_FFS_PAD ||
+ fh.Type == FV_FILETYPE_RAW)
+ {
+ bool isVolume = false;
+ if (fh.Type == FV_FILETYPE_RAW)
+ {
+ if (sectSize >= kFvHeaderSize)
+ if (IsFfs(pFile + kFileHeaderSize))
+ isVolume = true;
+ }
+ if (isVolume)
+ {
+ int newParent = AddDirItem(item);
+ RINOK(ParseVolume(bufIndex, offset, sectSize, newParent, method, level));
+ }
+ else
+ AddItem(item);
+ }
+ else
+ {
+ int newParent = AddDirItem(item);
+ RINOK(ParseSections(bufIndex, offset, sectSize, newParent, method, level));
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CHandler::OpenCapsule(IInStream *stream)
+{
+ const UInt32 kHeaderSize = 80;
+ Byte buf[kHeaderSize];
+ RINOK(ReadStream_FALSE(stream, buf, kHeaderSize));
+ _h.Parse(buf);
+ if (_h.HeaderSize != kHeaderSize ||
+ _h.CapsuleImageSize < kHeaderSize ||
+ _h.OffsetToCapsuleBody < kHeaderSize ||
+ _h.OffsetToCapsuleBody > _h.CapsuleImageSize)
+ return S_FALSE;
+
+ if (_h.SequenceNumber != 0 ||
+ _h.OffsetToSplitInformation != 0 )
+ return E_NOTIMPL;
+
+ int bufIndex = AddBuf(_h.CapsuleImageSize);
+ CByteBuffer &buf0 = _bufs[bufIndex];
+ memcpy(buf0, buf, kHeaderSize);
+ ReadStream_FALSE(stream, buf0 + kHeaderSize, _h.CapsuleImageSize - kHeaderSize);
+
+ AddCommentString(L"Author", _h.OffsetToAuthorInformation);
+ AddCommentString(L"Revision", _h.OffsetToRevisionInformation);
+ AddCommentString(L"Short Description", _h.OffsetToShortDescription);
+ AddCommentString(L"Long Description", _h.OffsetToLongDescription);
+
+ return ParseVolume(bufIndex, _h.OffsetToCapsuleBody, _h.CapsuleImageSize - _h.OffsetToCapsuleBody, -1, -1, 0);
+}
+
+HRESULT CHandler::OpenFv(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
+{
+ UInt64 fileSize;
+ RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize));
+ if (fileSize > (1 << 27))
+ return S_FALSE;
+
+ UInt32 volIndex = 0;
+ UInt32 pos = 0, prevEnd = 0;
+ if (callback)
+ {
+ RINOK(callback->SetTotal(NULL, &fileSize));
+ }
+
+ for (;;)
+ {
+ UInt64 limit = 0;
+ UInt64 *limitPtr = NULL;
+ if (maxCheckStartPosition)
+ {
+ UInt32 directSize = pos - prevEnd;
+ if (directSize >= *maxCheckStartPosition)
+ break;
+ limit = *maxCheckStartPosition - directSize;
+ limitPtr = &limit;
+ }
+
+ UInt64 resPos;
+ RINOK(stream->Seek(pos + kFfsGuidOffset, STREAM_SEEK_SET, NULL));
+ if (FindSignatureInStream(stream, k_FFS_Guid, kGuidSize, limitPtr, resPos) == S_FALSE)
+ break;
+
+ pos += (UInt32)resPos;
+ UInt64 fvSize;
+ {
+ UInt32 rem = (UInt32)fileSize - pos;
+ if (rem < kFvHeaderSize)
+ break;
+ RINOK(stream->Seek(pos, STREAM_SEEK_SET, NULL));
+ Byte buf[kFvHeaderSize];
+ RINOK(ReadStream_FALSE(stream, buf, kFvHeaderSize));
+ fvSize = Get64(buf + 0x20);
+ if (!IsFfs(buf) || fvSize > rem)
+ {
+ pos++;
+ continue;
+ }
+ }
+
+ RINOK(stream->Seek(prevEnd, STREAM_SEEK_SET, NULL));
+
+ if (pos != prevEnd)
+ {
+ CItem item;
+ item.Offset = 0;
+ item.Size = pos - prevEnd;
+ item.BufIndex = AddBuf(item.Size);
+ CByteBuffer &buf0 = _bufs[item.BufIndex];
+ RINOK(ReadStream_FALSE(stream, buf0, item.Size));
+ item.Name = UInt32ToString(volIndex++);
+ AddItem(item);
+ }
+
+ prevEnd = pos;
+ RINOK(stream->Seek(pos, STREAM_SEEK_SET, NULL));
+ UInt32 fvSize32 = (UInt32)fvSize;
+ CItem item;
+ item.BufIndex = AddBuf(fvSize32);
+ CByteBuffer &buf0 = _bufs[item.BufIndex];
+ item.Name = UInt32ToString(volIndex++);
+ int parent = AddDirItem(item);
+ ReadStream_FALSE(stream, buf0, fvSize32);
+ RINOK(ParseVolume(item.BufIndex, 0, fvSize32, parent, -1, 0));
+ pos += fvSize32;
+ prevEnd = pos;
+
+ if (callback)
+ {
+ UInt64 pos64 = pos;
+ RINOK(callback->SetCompleted(NULL, &pos64));
+ }
+ }
+ if (_items.Size() == 0)
+ return S_FALSE;
+
+ if (pos <= fileSize)
+ {
+ pos = (UInt32)fileSize;
+ if (prevEnd < pos)
+ {
+ CItem item;
+ item.Offset = 0;
+ item.Size = pos - prevEnd;
+ item.BufIndex = AddBuf(item.Size);
+ CByteBuffer &buf0 = _bufs[item.BufIndex];
+ RINOK(stream->Seek(prevEnd, STREAM_SEEK_SET, NULL));
+ RINOK(ReadStream_FALSE(stream, buf0, item.Size));
+ item.Name = UInt32ToString(volIndex++);
+ AddItem(item);
+ }
+ }
+ _h.CapsuleImageSize = pos;
+ return S_OK;
+}
+
+HRESULT CHandler::Open2(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
+{
+ if (_capsuleMode)
+ {
+ RINOK(OpenCapsule(stream));
+ }
+ else
+ {
+ RINOK(OpenFv(stream, maxCheckStartPosition, callback));
+ }
+
+ CIntVector numChilds;
+ numChilds.Reserve(_items.Size());
+ int i;
+ for (i = 0; i < _items.Size(); i++)
+ {
+ numChilds.Add(0);
+ int parent = _items[i].Parent;
+ if (parent >= 0)
+ numChilds[parent]++;
+ }
+
+ for (i = 0; i < _items.Size(); i++)
+ {
+ CItem &item = _items[i];
+ int parent = item.Parent;
+ if (parent >= 0)
+ {
+ CItem &parentItem = _items[parent];
+ if (numChilds[parent] == 1)
+ if (!item.ThereIsUniqueName || !parentItem.ThereIsUniqueName || !parentItem.ThereAreSubDirs)
+ parentItem.Skip = true;
+ }
+ }
+
+ CIntVector mainToReduced;
+ for (i = 0; i < _items.Size(); i++)
+ {
+ mainToReduced.Add(_items2.Size());
+ const CItem &item = _items[i];
+ if (item.Skip)
+ continue;
+ AString name;
+ int numItems = -1;
+ int parent = item.Parent;
+ if (parent >= 0)
+ numItems = numChilds[parent];
+ AString name2 = item.GetName(numItems);
+ AString characts2 = item.Characts;
+ if (item.KeepName)
+ name = name2;
+ while (parent >= 0)
+ {
+ const CItem &item3 = _items[parent];
+ if (!item3.Skip)
+ break;
+ if (item3.KeepName)
+ {
+ AString name3 = item3.GetName(-1);
+ if (name.IsEmpty())
+ name = name3;
+ else
+ name = name3 + '.' + name;
+ }
+ AddSpaceAndString(characts2, item3.Characts);
+ parent = item3.Parent;
+ }
+ if (name.IsEmpty())
+ name = name2;
+
+ CItem2 item2;
+ item2.MainIndex = i;
+ item2.Name = name;
+ item2.Characts = characts2;
+ if (parent >= 0)
+ item2.Parent = mainToReduced[parent];
+ _items2.Add(item2);
+ /*
+ CItem2 item2;
+ item2.MainIndex = i;
+ item2.Name = item.Name;
+ item2.Parent = item.Parent;
+ _items2.Add(item2);
+ */
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::Open(IInStream *inStream,
+ const UInt64 *maxCheckStartPosition,
+ IArchiveOpenCallback *callback)
+{
+ COM_TRY_BEGIN
+ Close();
+ try
+ {
+ if (Open2(inStream, maxCheckStartPosition, callback) != S_OK)
+ return S_FALSE;
+ }
+ catch(...) { return S_FALSE; }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _totalBufsSize = 0;
+ _methodsMask = 0;
+ _items.Clear();
+ _items2.Clear();
+ _bufs.Clear();
+ _comment.Empty();
+ _h.Clear();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _items2.Size();
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool allFilesMode = (numItems == (UInt32)-1);
+ if (allFilesMode)
+ numItems = _items2.Size();
+ if (numItems == 0)
+ return S_OK;
+ UInt64 totalSize = 0;
+ UInt32 i;
+ for (i = 0; i < numItems; i++)
+ totalSize += _items[_items2[allFilesMode ? i : indices[i]].MainIndex].Size;
+ extractCallback->SetTotal(totalSize);
+
+ UInt64 currentTotalSize = 0;
+
+ NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
+ CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
+
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(extractCallback, false);
+
+ for (i = 0; i < numItems; i++)
+ {
+ lps->InSize = lps->OutSize = currentTotalSize;
+ RINOK(lps->SetCur());
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode = testMode ?
+ NExtract::NAskMode::kTest :
+ NExtract::NAskMode::kExtract;
+ UInt32 index = allFilesMode ? i : indices[i];
+ const CItem &item = _items[_items2[index].MainIndex];
+ RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
+ currentTotalSize += item.Size;
+
+ if (!testMode && !realOutStream)
+ continue;
+ RINOK(extractCallback->PrepareOperation(askMode));
+ if (testMode || item.IsDir)
+ {
+ RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
+ continue;
+ }
+ int res = NExtract::NOperationResult::kDataError;
+ CMyComPtr<ISequentialInStream> inStream;
+ GetStream(index, &inStream);
+ if (inStream)
+ {
+ RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
+ if (copyCoderSpec->TotalSize == item.Size)
+ res = NExtract::NOperationResult::kOK;
+ }
+ realOutStream.Release();
+ RINOK(extractCallback->SetOperationResult(res));
+ }
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
+{
+ COM_TRY_BEGIN
+ const CItem &item = _items[_items2[index].MainIndex];
+ if (item.IsDir)
+ return S_FALSE;
+ CBufInStream *streamSpec = new CBufInStream;
+ CMyComPtr<IInStream> streamTemp = streamSpec;
+ const CByteBuffer &buf = _bufs[item.BufIndex];
+ /*
+ if (item.Offset + item.Size > buf.GetCapacity())
+ return S_FALSE;
+ */
+ streamSpec->Init(buf + item.Offset, item.Size, (IInArchive *)this);
+ *stream = streamTemp.Detach();
+ return S_OK;
+ COM_TRY_END
+}
+
+
+namespace UEFIc
+{
+ static IInArchive *CreateArc() { return new CHandler(true); }
+ static CArcInfo g_ArcInfo =
+ { L"UEFIc", L"scap", 0, 0xD0, CAPSULE_SIGNATURE, kCapsuleSigSize, false, CreateArc, 0 };
+ REGISTER_ARC(UEFIc)
+}
+
+namespace UEFIs
+{
+ static IInArchive *CreateArc() { return new CHandler(false); }
+ static CArcInfo g_ArcInfo =
+ { L"UEFIs", L"", 0, 0xD1, FFS_SIGNATURE, kGuidSize, false, CreateArc, 0 };
+ REGISTER_ARC(UEFIs)
+}
+
+}}
diff --git a/CPP/7zip/Archive/Wim/WimHandlerOut.cpp b/CPP/7zip/Archive/Wim/WimHandlerOut.cpp
index 50b879e7..85f0771c 100755
--- a/CPP/7zip/Archive/Wim/WimHandlerOut.cpp
+++ b/CPP/7zip/Archive/Wim/WimHandlerOut.cpp
@@ -465,7 +465,8 @@ static HRESULT UpdateArchive(ISequentialOutStream *seqOutStream,
RINOK(callback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
}
}
-
+ lps->InSize = lps->OutSize = complexity;
+ RINOK(lps->SetCur());
CUpdateItem ri;
FILETIME ft;
diff --git a/CPP/7zip/Archive/XzHandler.cpp b/CPP/7zip/Archive/XzHandler.cpp
index 64b7a586..8383488b 100755
--- a/CPP/7zip/Archive/XzHandler.cpp
+++ b/CPP/7zip/Archive/XzHandler.cpp
@@ -8,6 +8,7 @@
#include "../../Common/ComTry.h"
#include "../../Common/IntToString.h"
+#include "../../Common/StringConvert.h"
#include "../ICoder.h"
@@ -40,13 +41,15 @@ namespace NXz {
struct CCrc64Gen { CCrc64Gen() { Crc64GenerateTable(); } } g_Crc64TableInit;
+static const wchar_t *k_LZMA2_Name = L"LZMA2";
+
class CHandler:
public IInArchive,
public IArchiveOpenSeq,
#ifndef EXTRACT_ONLY
public IOutArchive,
public ISetProperties,
- public COutHandler,
+ public CMultiMethodProps,
#endif
public CMyUnknownImp
{
@@ -62,12 +65,12 @@ class CHandler:
CMyComPtr<IInStream> _stream;
CMyComPtr<ISequentialInStream> _seqStream;
- UInt32 _crcSize;
+ UInt32 _filterId;
void Init()
{
- _crcSize = 4;
- COutHandler::Init();
+ _filterId = 0;
+ CMultiMethodProps::Init();
}
HRESULT Open2(IInStream *inStream, IArchiveOpenCallback *callback);
@@ -98,14 +101,14 @@ CHandler::CHandler()
Init();
}
-STATPROPSTG kProps[] =
+static STATPROPSTG const kProps[] =
{
{ NULL, kpidSize, VT_UI8},
{ NULL, kpidPackSize, VT_UI8},
{ NULL, kpidMethod, VT_BSTR}
};
-STATPROPSTG kArcProps[] =
+static STATPROPSTG const kArcProps[] =
{
{ NULL, kpidMethod, VT_BSTR},
{ NULL, kpidNumBlocks, VT_UI4}
@@ -160,11 +163,11 @@ struct CMethodNamePair
const char *Name;
};
-static CMethodNamePair g_NamePairs[] =
+static const CMethodNamePair g_NamePairs[] =
{
{ XZ_ID_Subblock, "SB" },
{ XZ_ID_Delta, "Delta" },
- { XZ_ID_X86, "x86" },
+ { XZ_ID_X86, "BCJ" },
{ XZ_ID_PPC, "PPC" },
{ XZ_ID_IA64, "IA64" },
{ XZ_ID_ARM, "ARM" },
@@ -439,7 +442,10 @@ struct CXzUnpackerCPP
Byte *InBuf;
Byte *OutBuf;
CXzUnpacker p;
- CXzUnpackerCPP(): InBuf(0), OutBuf(0) {}
+ CXzUnpackerCPP(): InBuf(0), OutBuf(0)
+ {
+ XzUnpacker_Construct(&p, &g_Alloc);
+ }
~CXzUnpackerCPP()
{
XzUnpacker_Free(&p);
@@ -483,7 +489,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CCompressProgressWrap progressWrap(progress);
- SRes res;
+ SRes res = S_OK;
const UInt32 kInBufSize = 1 << 15;
const UInt32 kOutBufSize = 1 << 21;
@@ -492,8 +498,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
UInt32 inSize = 0;
UInt32 outPos = 0;
CXzUnpackerCPP xzu;
- res = XzUnpacker_Create(&xzu.p, &g_Alloc);
- if (res == SZ_OK)
+ XzUnpacker_Init(&xzu.p);
{
xzu.InBuf = (Byte *)MyAlloc(kInBufSize);
xzu.OutBuf = (Byte *)MyAlloc(kOutBufSize);
@@ -534,6 +539,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
outPos = 0;
}
+ RINOK(lps->SetCur());
if (finished)
{
_packSize = lps->InSize;
@@ -553,7 +559,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
break;
}
- RINOK(lps->SetCur());
}
Int32 opRes;
@@ -573,8 +578,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
return SResToHRESULT(res);
}
realOutStream.Release();
- RINOK(extractCallback->SetOperationResult(opRes));
- return S_OK;
+ return extractCallback->SetOperationResult(opRes);
COM_TRY_END
}
@@ -619,8 +623,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (IntToBool(newData))
{
+ UInt64 size;
{
- UInt64 size;
NCOM::CPropVariant prop;
RINOK(updateCallback->GetProperty(0, kpidSize, &prop));
if (prop.vt != VT_UI8)
@@ -632,22 +636,26 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CLzma2EncProps lzma2Props;
Lzma2EncProps_Init(&lzma2Props);
- lzma2Props.lzmaProps.level = _level;
+ lzma2Props.lzmaProps.level = GetLevel();
CMyComPtr<ISequentialInStream> fileInStream;
RINOK(updateCallback->GetStream(0, &fileInStream));
CSeqInStreamWrap seqInStream(fileInStream);
+ {
+ NCOM::CPropVariant prop = (UInt64)size;
+ RINOK(NCompress::NLzma2::SetLzma2Prop(NCoderPropID::kReduceSize, prop, lzma2Props));
+ }
+
for (int i = 0; i < _methods.Size(); i++)
{
COneMethodInfo &m = _methods[i];
- SetCompressionMethod2(m
+ SetGlobalLevelAndThreads(m
#ifndef _7ZIP_ST
, _numThreads
#endif
);
- if (m.IsLzma())
{
for (int j = 0; j < m.Props.Size(); j++)
{
@@ -666,7 +674,40 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
lps->Init(updateCallback, true);
CCompressProgressWrap progressWrap(progress);
- SRes res = Xz_Encode(&seqOutStream.p, &seqInStream.p, &lzma2Props, False, &progressWrap.p);
+ CXzProps xzProps;
+ CXzFilterProps filter;
+ XzProps_Init(&xzProps);
+ XzFilterProps_Init(&filter);
+ xzProps.lzma2Props = &lzma2Props;
+ xzProps.filterProps = (_filterId != 0 ? &filter : NULL);
+ switch (_crcSize)
+ {
+ case 0: xzProps.checkId = XZ_CHECK_NO; break;
+ case 4: xzProps.checkId = XZ_CHECK_CRC32; break;
+ case 8: xzProps.checkId = XZ_CHECK_CRC64; break;
+ case 32: xzProps.checkId = XZ_CHECK_SHA256; break;
+ default: return E_INVALIDARG;
+ }
+ filter.id = _filterId;
+ if (_filterId == XZ_ID_Delta)
+ {
+ bool deltaDefined = false;
+ for (int j = 0; j < _filterMethod.Props.Size(); j++)
+ {
+ const CProp &prop = _filterMethod.Props[j];
+ if (prop.Id == NCoderPropID::kDefaultProp && prop.Value.vt == VT_UI4)
+ {
+ UInt32 delta = (UInt32)prop.Value.ulVal;
+ if (delta < 1 || delta > 256)
+ return E_INVALIDARG;
+ filter.delta = delta;
+ deltaDefined = true;
+ }
+ }
+ if (!deltaDefined)
+ return E_INVALIDARG;
+ }
+ SRes res = Xz_Encode(&seqOutStream.p, &seqInStream.p, &xzProps, &progressWrap.p);
if (res == SZ_OK)
return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
return SResToHRESULT(res);
@@ -678,14 +719,46 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return NCompress::CopyStream(_stream, outStream, 0);
}
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
{
COM_TRY_BEGIN
- BeforeSetProperty();
+ Init();
for (int i = 0; i < numProps; i++)
{
RINOK(SetProperty(names[i], values[i]));
}
+
+ if (!_filterMethod.MethodName.IsEmpty())
+ {
+ int k;
+ for (k = 0; k < ARRAY_SIZE(g_NamePairs); k++)
+ {
+ const CMethodNamePair &pair = g_NamePairs[k];
+ UString m = GetUnicodeString(pair.Name);
+ if (_filterMethod.MethodName.CompareNoCase(m) == 0)
+ {
+ _filterId = pair.Id;
+ break;
+ }
+ }
+ if (k == ARRAY_SIZE(g_NamePairs))
+ return E_INVALIDARG;
+ }
+
+ int numEmptyMethods = GetNumEmptyMethods();
+ _methods.Delete(0, numEmptyMethods);
+ if (_methods.Size() > 1)
+ return E_INVALIDARG;
+ if (_methods.Size() == 1)
+ {
+ UString &methodName = _methods[0].MethodName;
+ if (methodName.IsEmpty())
+ methodName = k_LZMA2_Name;
+ else if (methodName.CompareNoCase(k_LZMA2_Name) != 0)
+ return E_INVALIDARG;
+ }
return S_OK;
COM_TRY_END
}
diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
index 4c5fd38d..da42f3bd 100755
--- a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
+++ b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
@@ -33,6 +33,7 @@ static const UInt32 kLzmaHeaderSize = 4 + kLzmaPropsSize;
class CLzmaEncoder:
public ICompressCoder,
+ public ICompressSetCoderProperties,
public CMyUnknownImp
{
NCompress::NLzma::CEncoder *EncoderSpec;
@@ -41,12 +42,12 @@ class CLzmaEncoder:
public:
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
- HRESULT SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
};
-HRESULT CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
+STDMETHODIMP CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
{
if (!Encoder)
{
@@ -67,7 +68,7 @@ HRESULT CLzmaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIAN
return S_OK;
}
-HRESULT CLzmaEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+STDMETHODIMP CLzmaEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{
RINOK(WriteStream(outStream, Header, kLzmaHeaderSize));
@@ -210,52 +211,12 @@ HRESULT CAddCommon::Compress(
_compressExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_LZMA;
CLzmaEncoder *_lzmaEncoder = new CLzmaEncoder();
_compressEncoder = _lzmaEncoder;
- NWindows::NCOM::CPropVariant props[] =
- {
- #ifndef _7ZIP_ST
- _options.NumThreads,
- #endif
- _options.Algo,
- _options.DicSize,
- _options.NumFastBytes,
- const_cast<BSTR>((const wchar_t *)_options.MatchFinder),
- _options.NumMatchFinderCycles
- };
- PROPID propIDs[] =
- {
- #ifndef _7ZIP_ST
- NCoderPropID::kNumThreads,
- #endif
- NCoderPropID::kAlgorithm,
- NCoderPropID::kDictionarySize,
- NCoderPropID::kNumFastBytes,
- NCoderPropID::kMatchFinder,
- NCoderPropID::kMatchFinderCycles
- };
- int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
- if (!_options.NumMatchFinderCyclesDefined)
- numProps--;
- RINOK(_lzmaEncoder->SetCoderProperties(propIDs, props, numProps));
}
else if (method == NFileHeader::NCompressionMethod::kPPMd)
{
_compressExtractVersion = NFileHeader::NCompressionMethod::kExtractVersion_PPMd;
NCompress::NPpmdZip::CEncoder *encoder = new NCompress::NPpmdZip::CEncoder();
_compressEncoder = encoder;
- NWindows::NCOM::CPropVariant props[] =
- {
- _options.Algo,
- _options.MemSize,
- _options.Order
-
- };
- PROPID propIDs[] =
- {
- NCoderPropID::kAlgorithm,
- NCoderPropID::kUsedMemorySize,
- NCoderPropID::kOrder
- };
- RINOK(encoder->SetCoderProperties(propIDs, props, sizeof(propIDs) / sizeof(propIDs[0])));
}
else
{
@@ -282,56 +243,20 @@ HRESULT CAddCommon::Compress(
if (method == NFileHeader::NCompressionMethod::kDeflated ||
method == NFileHeader::NCompressionMethod::kDeflated64)
{
- NWindows::NCOM::CPropVariant props[] =
- {
- _options.Algo,
- _options.NumPasses,
- _options.NumFastBytes,
- _options.NumMatchFinderCycles
- };
- PROPID propIDs[] =
- {
- NCoderPropID::kAlgorithm,
- NCoderPropID::kNumPasses,
- NCoderPropID::kNumFastBytes,
- NCoderPropID::kMatchFinderCycles
- };
- int numProps = sizeof(propIDs) / sizeof(propIDs[0]);
- if (!_options.NumMatchFinderCyclesDefined)
- numProps--;
- CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
- _compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
- if (setCoderProperties)
- {
- RINOK(setCoderProperties->SetCoderProperties(propIDs, props, numProps));
- }
}
else if (method == NFileHeader::NCompressionMethod::kBZip2)
{
- NWindows::NCOM::CPropVariant props[] =
- {
- _options.DicSize,
- _options.NumPasses
- #ifndef _7ZIP_ST
- , _options.NumThreads
- #endif
- };
- PROPID propIDs[] =
- {
- NCoderPropID::kDictionarySize,
- NCoderPropID::kNumPasses
- #ifndef _7ZIP_ST
- , NCoderPropID::kNumThreads
- #endif
- };
- CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
- _compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);
- if (setCoderProperties)
+ }
+ }
+ {
+ CMyComPtr<ICompressSetCoderProperties> setCoderProps;
+ _compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProps);
+ if (setCoderProps)
{
- RINOK(setCoderProperties->SetCoderProperties(propIDs, props, sizeof(propIDs) / sizeof(propIDs[0])));
+ RINOK(_options.MethodInfo.SetCoderProps(setCoderProps,
+ _options._dataSizeReduceDefined ? &_options._dataSizeReduce : NULL));
}
}
- }
}
CMyComPtr<ISequentialOutStream> outStreamNew;
if (_options.PasswordIsDefined)
diff --git a/CPP/7zip/Archive/Zip/ZipCompressionMode.h b/CPP/7zip/Archive/Zip/ZipCompressionMode.h
index 7ef7cfb2..5be33166 100755
--- a/CPP/7zip/Archive/Zip/ZipCompressionMode.h
+++ b/CPP/7zip/Archive/Zip/ZipCompressionMode.h
@@ -5,36 +5,54 @@
#include "Common/MyString.h"
+#ifndef _7ZIP_ST
+#include "../../../Windows/System.h"
+#endif
+
+#include "../Common/HandlerOut.h"
+
namespace NArchive {
namespace NZip {
-struct CCompressionMethodMode
+struct CBaseProps
{
- CRecordVector<Byte> MethodSequence;
- UString MatchFinder;
- UInt32 Algo;
- UInt32 NumPasses;
- UInt32 NumFastBytes;
- bool NumMatchFinderCyclesDefined;
- UInt32 NumMatchFinderCycles;
- UInt32 DicSize;
- UInt32 MemSize;
- UInt32 Order;
+ CMethodProps MethodInfo;
+ Int32 Level;
#ifndef _7ZIP_ST
UInt32 NumThreads;
+ bool NumThreadsWasChanged;
#endif
- bool PasswordIsDefined;
- AString Password;
bool IsAesMode;
Byte AesKeyMode;
+
+ void Init()
+ {
+ MethodInfo.Clear();
+ Level = -1;
+ #ifndef _7ZIP_ST
+ NumThreads = NWindows::NSystem::GetNumberOfProcessors();;
+ NumThreadsWasChanged = false;
+ #endif
+ IsAesMode = false;
+ AesKeyMode = 3;
+ }
+};
+
+struct CCompressionMethodMode: public CBaseProps
+{
+ CRecordVector<Byte> MethodSequence;
+ bool PasswordIsDefined;
+ AString Password;
+
+ UInt64 _dataSizeReduce;
+ bool _dataSizeReduceDefined;
- CCompressionMethodMode():
- NumMatchFinderCyclesDefined(false),
- PasswordIsDefined(false),
- IsAesMode(false),
- AesKeyMode(3)
- {}
+ CCompressionMethodMode(): PasswordIsDefined(false)
+ {
+ _dataSizeReduceDefined = false;
+ _dataSizeReduce = 0;
+ }
};
}}
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp
index bd156322..2281ed5b 100755
--- a/CPP/7zip/Archive/Zip/ZipHandler.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp
@@ -107,7 +107,7 @@ static struct CStrongCryptoPair
{ NStrongCryptoFlags::kRC4, "RC4" }
};
-static STATPROPSTG kProps[] =
+static const STATPROPSTG kProps[] =
{
{ NULL, kpidPath, VT_BSTR},
{ NULL, kpidIsDir, VT_BOOL},
@@ -117,6 +117,7 @@ static STATPROPSTG kProps[] =
{ NULL, kpidCTime, VT_FILETIME},
{ NULL, kpidATime, VT_FILETIME},
{ NULL, kpidAttrib, VT_UI4},
+ // { NULL, kpidPosixAttrib, VT_UI4},
{ NULL, kpidEncrypted, VT_BOOL},
{ NULL, kpidComment, VT_BSTR},
{ NULL, kpidCRC, VT_UI4},
@@ -125,7 +126,7 @@ static STATPROPSTG kProps[] =
{ NULL, kpidUnpackVer, VT_UI4}
};
-static STATPROPSTG kArcProps[] =
+static const STATPROPSTG kArcProps[] =
{
{ NULL, kpidBit64, VT_BOOL},
{ NULL, kpidComment, VT_BSTR},
@@ -135,7 +136,7 @@ static STATPROPSTG kArcProps[] =
CHandler::CHandler()
{
- InitMethodProperties();
+ InitMethodProps();
}
static AString BytesToString(const CByteBuffer &data)
@@ -165,6 +166,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidComment: prop = MultiByteToUnicodeString(BytesToString(m_Archive.ArcInfo.Comment), CP_ACP); break;
case kpidPhySize: prop = m_Archive.ArcInfo.GetPhySize(); break;
case kpidOffset: if (m_Archive.ArcInfo.StartPosition != 0) prop = m_Archive.ArcInfo.StartPosition; break;
+ case kpidError: if (!m_Archive.IsOkHeaders) prop = "Incorrect headers"; break;
}
prop.Detach(value);
COM_TRY_END
@@ -194,7 +196,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
UInt32 unixTime;
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, ft))
prop = (UInt32)NFileTimeType::kWindows;
- else if (item.CentralExtra.GetUnixTime(NFileHeader::NUnixTime::kMTime, unixTime))
+ else if (item.CentralExtra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
prop = (UInt32)NFileTimeType::kUnix;
else
prop = (UInt32)NFileTimeType::kDOS;
@@ -220,7 +222,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (!item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utc))
{
UInt32 unixTime;
- if (item.CentralExtra.GetUnixTime(NFileHeader::NUnixTime::kMTime, unixTime))
+ if (item.CentralExtra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
NTime::UnixTimeToFileTime(unixTime, utc);
else
{
@@ -233,7 +235,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
prop = utc;
break;
}
- case kpidAttrib: prop = item.GetWinAttributes(); break;
+ case kpidAttrib: prop = item.GetWinAttrib(); break;
+ case kpidPosixAttrib:
+ {
+ UInt32 attrib;
+ if (item.GetPosixAttrib(attrib))
+ prop = attrib;
+ break;
+ }
case kpidEncrypted: prop = item.IsEncrypted(); break;
case kpidComment: prop = item.GetUnicodeString(BytesToString(item.Comment)); break;
case kpidCRC: if (item.IsThereCrc()) prop = item.FileCRC; break;
@@ -435,7 +444,10 @@ public:
ISequentialOutStream *realOutStream,
IArchiveExtractCallback *extractCallback,
ICompressProgressInfo *compressProgress,
- UInt32 numThreads, Int32 &res);
+ #ifndef _7ZIP_ST
+ UInt32 numThreads,
+ #endif
+ Int32 &res);
};
HRESULT CZipDecoder::Decode(
@@ -444,7 +456,10 @@ HRESULT CZipDecoder::Decode(
ISequentialOutStream *realOutStream,
IArchiveExtractCallback *extractCallback,
ICompressProgressInfo *compressProgress,
- UInt32 numThreads, Int32 &res)
+ #ifndef _7ZIP_ST
+ UInt32 numThreads,
+ #endif
+ Int32 &res)
{
res = NExtract::NOperationResult::kDataError;
CInStreamReleaser inStreamReleaser;
@@ -805,15 +820,22 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
RINOK(extractCallback->PrepareOperation(askMode));
Int32 res;
- RINOK(myDecoder.Decode(
+ HRESULT hres = myDecoder.Decode(
EXTERNAL_CODECS_VARS
m_Archive, item, realOutStream, extractCallback,
- progress, _numThreads, res));
+ progress,
+ #ifndef _7ZIP_ST
+ _props.NumThreads,
+ #endif
+ res);
+ RINOK(hres);
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(res))
}
- return S_OK;
+ lps->InSize = currentTotalPacked;
+ lps->OutSize = currentTotalUnPacked;
+ return lps->SetCur();
COM_TRY_END
}
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.h b/CPP/7zip/Archive/Zip/ZipHandler.h
index fdb60aaf..33cf6fdc 100755
--- a/CPP/7zip/Archive/Zip/ZipHandler.h
+++ b/CPP/7zip/Archive/Zip/ZipHandler.h
@@ -12,10 +12,6 @@
#include "ZipIn.h"
#include "ZipCompressionMode.h"
-#ifndef _7ZIP_ST
-#include "../../../Windows/System.h"
-#endif
-
namespace NArchive {
namespace NZip {
@@ -46,53 +42,24 @@ private:
CObjectVector<CItemEx> m_Items;
CInArchive m_Archive;
- int m_Level;
- int m_MainMethod;
- UInt32 m_DicSize;
- UInt32 m_Algo;
- UInt32 m_NumPasses;
- UInt32 m_NumFastBytes;
- UInt32 m_NumMatchFinderCycles;
- UInt32 m_MemSize;
- UInt32 m_Order;
-
- bool m_NumMatchFinderCyclesDefined;
+ CBaseProps _props;
+ int m_MainMethod;
bool m_ForceAesMode;
- bool m_IsAesMode;
- Byte m_AesKeyMode;
-
bool m_WriteNtfsTimeExtra;
bool m_ForceLocal;
bool m_ForceUtf8;
- #ifndef _7ZIP_ST
- UInt32 _numThreads;
- #endif
-
DECL_EXTERNAL_CODECS_VARS
- void InitMethodProperties()
+ void InitMethodProps()
{
- m_Level = -1;
+ _props.Init();
m_MainMethod = -1;
- m_Algo =
- m_DicSize =
- m_NumPasses =
- m_NumFastBytes =
- m_Order =
- m_MemSize =
- m_NumMatchFinderCycles = 0xFFFFFFFF;
- m_NumMatchFinderCyclesDefined = false;
m_ForceAesMode = false;
- m_IsAesMode = false;
- m_AesKeyMode = 3; // aes-256
m_WriteNtfsTimeExtra = true;
m_ForceLocal = false;
m_ForceUtf8 = false;
- #ifndef _7ZIP_ST
- _numThreads = NWindows::NSystem::GetNumberOfProcessors();;
- #endif
}
};
diff --git a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
index a5e0f59d..427b0c31 100755
--- a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
@@ -28,37 +28,6 @@ using namespace NTime;
namespace NArchive {
namespace NZip {
-static const UInt32 kLzAlgoX1 = 0;
-static const UInt32 kLzAlgoX5 = 1;
-
-static const UInt32 kDeflateNumPassesX1 = 1;
-static const UInt32 kDeflateNumPassesX7 = 3;
-static const UInt32 kDeflateNumPassesX9 = 10;
-
-static const UInt32 kDeflateNumFastBytesX1 = 32;
-static const UInt32 kDeflateNumFastBytesX7 = 64;
-static const UInt32 kDeflateNumFastBytesX9 = 128;
-
-static const wchar_t *kLzmaMatchFinderX1 = L"HC4";
-static const wchar_t *kLzmaMatchFinderX5 = L"BT4";
-
-static const UInt32 kLzmaNumFastBytesX1 = 32;
-static const UInt32 kLzmaNumFastBytesX7 = 64;
-
-static const UInt32 kLzmaDicSizeX1 = 1 << 16;
-static const UInt32 kLzmaDicSizeX3 = 1 << 20;
-static const UInt32 kLzmaDicSizeX5 = 1 << 24;
-static const UInt32 kLzmaDicSizeX7 = 1 << 25;
-static const UInt32 kLzmaDicSizeX9 = 1 << 26;
-
-static const UInt32 kBZip2NumPassesX1 = 1;
-static const UInt32 kBZip2NumPassesX7 = 2;
-static const UInt32 kBZip2NumPassesX9 = 7;
-
-static const UInt32 kBZip2DicSizeX1 = 100000;
-static const UInt32 kBZip2DicSizeX3 = 500000;
-static const UInt32 kBZip2DicSizeX5 = 900000;
-
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *timeType)
{
*timeType = NFileTimeType::kDOS;
@@ -99,6 +68,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
COM_TRY_BEGIN2
CObjectVector<CUpdateItem> updateItems;
bool thereAreAesUpdates = false;
+ UInt64 largestSize = 0;
+ bool largestSizeDefined = false;
for (UInt32 i = 0; i < numItems; i++)
{
CUpdateItem ui;
@@ -178,7 +149,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
const wchar_t kSlash = L'/';
if (!name.IsEmpty())
{
- if (name[name.Length() - 1] == kSlash)
+ if (name.Back() == kSlash)
{
if (!ui.IsDir)
return E_INVALIDARG;
@@ -235,6 +206,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (prop.vt != VT_UI8)
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
+ if (largestSize < size)
+ largestSize = size;
+ largestSizeDefined = true;
}
ui.Size = size;
}
@@ -247,6 +221,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
udateCallBack2.QueryInterface(IID_ICryptoGetTextPassword2, &getTextPassword);
}
CCompressionMethodMode options;
+ (CBaseProps &)options = _props;
+ options._dataSizeReduce = largestSize;
+ options._dataSizeReduceDefined = largestSizeDefined;
if (getTextPassword)
{
@@ -256,8 +233,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
options.PasswordIsDefined = IntToBool(passwordIsDefined);
if (options.PasswordIsDefined)
{
- options.IsAesMode = (m_ForceAesMode ? m_IsAesMode : thereAreAesUpdates);
- options.AesKeyMode = m_AesKeyMode;
+ if (!m_ForceAesMode)
+ options.IsAesMode = thereAreAesUpdates;
if (!IsAsciiString((const wchar_t *)password))
return E_INVALIDARG;
@@ -272,13 +249,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
else
options.PasswordIsDefined = false;
- int level = m_Level;
- if (level < 0)
- level = 5;
-
Byte mainMethod;
if (m_MainMethod < 0)
- mainMethod = (Byte)(((level == 0) ?
+ mainMethod = (Byte)(((_props.Level == 0) ?
NFileHeader::NCompressionMethod::kStored :
NFileHeader::NCompressionMethod::kDeflated));
else
@@ -286,83 +259,6 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
options.MethodSequence.Add(mainMethod);
if (mainMethod != NFileHeader::NCompressionMethod::kStored)
options.MethodSequence.Add(NFileHeader::NCompressionMethod::kStored);
- bool isDeflate = (mainMethod == NFileHeader::NCompressionMethod::kDeflated) ||
- (mainMethod == NFileHeader::NCompressionMethod::kDeflated64);
- bool isLZMA = (mainMethod == NFileHeader::NCompressionMethod::kLZMA);
- bool isLz = (isLZMA || isDeflate);
- options.NumPasses = m_NumPasses;
- options.DicSize = m_DicSize;
- options.NumFastBytes = m_NumFastBytes;
- options.NumMatchFinderCycles = m_NumMatchFinderCycles;
- options.NumMatchFinderCyclesDefined = m_NumMatchFinderCyclesDefined;
- options.Algo = m_Algo;
- options.MemSize = m_MemSize;
- options.Order = m_Order;
- #ifndef _7ZIP_ST
- options.NumThreads = _numThreads;
- #endif
- if (isLz)
- {
- if (isDeflate)
- {
- if (options.NumPasses == 0xFFFFFFFF)
- options.NumPasses = (level >= 9 ? kDeflateNumPassesX9 :
- (level >= 7 ? kDeflateNumPassesX7 :
- kDeflateNumPassesX1));
- if (options.NumFastBytes == 0xFFFFFFFF)
- options.NumFastBytes = (level >= 9 ? kDeflateNumFastBytesX9 :
- (level >= 7 ? kDeflateNumFastBytesX7 :
- kDeflateNumFastBytesX1));
- }
- else if (isLZMA)
- {
- if (options.DicSize == 0xFFFFFFFF)
- options.DicSize =
- (level >= 9 ? kLzmaDicSizeX9 :
- (level >= 7 ? kLzmaDicSizeX7 :
- (level >= 5 ? kLzmaDicSizeX5 :
- (level >= 3 ? kLzmaDicSizeX3 :
- kLzmaDicSizeX1))));
-
- if (options.NumFastBytes == 0xFFFFFFFF)
- options.NumFastBytes = (level >= 7 ? kLzmaNumFastBytesX7 :
- kLzmaNumFastBytesX1);
-
- options.MatchFinder =
- (level >= 5 ? kLzmaMatchFinderX5 :
- kLzmaMatchFinderX1);
- }
-
- if (options.Algo == 0xFFFFFFFF)
- options.Algo = (level >= 5 ? kLzAlgoX5 :
- kLzAlgoX1);
- }
- if (mainMethod == NFileHeader::NCompressionMethod::kBZip2)
- {
- if (options.NumPasses == 0xFFFFFFFF)
- options.NumPasses = (level >= 9 ? kBZip2NumPassesX9 :
- (level >= 7 ? kBZip2NumPassesX7 :
- kBZip2NumPassesX1));
- if (options.DicSize == 0xFFFFFFFF)
- options.DicSize = (level >= 5 ? kBZip2DicSizeX5 :
- (level >= 3 ? kBZip2DicSizeX3 :
- kBZip2DicSizeX1));
- }
- if (mainMethod == NFileHeader::NCompressionMethod::kPPMd)
- {
- int level2 = level;
- if (level2 < 1) level2 = 1;
- if (level2 > 9) level2 = 9;
-
- if (options.MemSize == 0xFFFFFFFF)
- options.MemSize = (1 << (19 + (level2 > 8 ? 8 : level2)));
-
- if (options.Order == 0xFFFFFFFF)
- options.Order = 3 + level2;
-
- if (options.Algo == 0xFFFFFFFF)
- options.Algo = (level2 >= 7 ? 1 : 0);
- }
return Update(
EXTERNAL_CODECS_VARS
@@ -371,16 +267,34 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
COM_TRY_END2
}
-STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
+struct CMethodIndexToName
+{
+ unsigned Method;
+ const wchar_t *Name;
+};
+
+static const CMethodIndexToName k_SupportedMethods[] =
{
+ { NFileHeader::NCompressionMethod::kStored, L"COPY" },
+ { NFileHeader::NCompressionMethod::kDeflated, L"DEFLATE" },
+ { NFileHeader::NCompressionMethod::kDeflated64, L"DEFLATE64" },
+ { NFileHeader::NCompressionMethod::kBZip2, L"BZIP2" },
+ { NFileHeader::NCompressionMethod::kLZMA, L"LZMA" },
+ { NFileHeader::NCompressionMethod::kPPMd, L"PPMD" }
+};
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProps)
+{
+ InitMethodProps();
#ifndef _7ZIP_ST
- const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
- _numThreads = numProcessors;
+ const UInt32 numProcessors = _props.NumThreads;
#endif
- InitMethodProperties();
- for (int i = 0; i < numProperties; i++)
+
+ for (int i = 0; i < numProps; i++)
{
- UString name = UString(names[i]);
+ UString name = names[i];
name.MakeUpper();
if (name.IsEmpty())
return E_INVALIDARG;
@@ -390,140 +304,112 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *v
if (name[0] == L'X')
{
UInt32 level = 9;
- RINOK(ParsePropValue(name.Mid(1), prop, level));
- m_Level = level;
- continue;
+ RINOK(ParsePropToUInt32(name.Mid(1), prop, level));
+ _props.Level = level;
+ _props.MethodInfo.AddLevelProp(level);
}
else if (name == L"M")
{
if (prop.vt == VT_BSTR)
{
- UString m = prop.bstrVal;
+ UString m = prop.bstrVal, m2;
m.MakeUpper();
- if (m == L"COPY") m_MainMethod = NFileHeader::NCompressionMethod::kStored;
- else if (m == L"DEFLATE") m_MainMethod = NFileHeader::NCompressionMethod::kDeflated;
- else if (m == L"DEFLATE64") m_MainMethod = NFileHeader::NCompressionMethod::kDeflated64;
- else if (m == L"BZIP2") m_MainMethod = NFileHeader::NCompressionMethod::kBZip2;
- else if (m == L"LZMA") m_MainMethod = NFileHeader::NCompressionMethod::kLZMA;
- else if (m == L"PPMD") m_MainMethod = NFileHeader::NCompressionMethod::kPPMd;
- else return E_INVALIDARG;
+ int colonPos = m.Find(L':');
+ if (colonPos >= 0)
+ {
+ m2 = m.Mid(colonPos + 1);
+ m = m.Left(colonPos);
+ }
+ int k;
+ for (k = 0; k < ARRAY_SIZE(k_SupportedMethods); k++)
+ {
+ const CMethodIndexToName &pair = k_SupportedMethods[k];
+ if (m == pair.Name)
+ {
+ if (!m2.IsEmpty())
+ {
+ RINOK(_props.MethodInfo.ParseParamsFromString(m2));
+ }
+ m_MainMethod = pair.Method;
+ break;
+ }
+ }
+ if (k == ARRAY_SIZE(k_SupportedMethods))
+ return E_INVALIDARG;
}
else if (prop.vt == VT_UI4)
{
- switch(prop.ulVal)
+ int k;
+ for (k = 0; k < ARRAY_SIZE(k_SupportedMethods); k++)
{
- case NFileHeader::NCompressionMethod::kStored:
- case NFileHeader::NCompressionMethod::kDeflated:
- case NFileHeader::NCompressionMethod::kDeflated64:
- case NFileHeader::NCompressionMethod::kBZip2:
- case NFileHeader::NCompressionMethod::kLZMA:
- m_MainMethod = (Byte)prop.ulVal;
+ unsigned method = k_SupportedMethods[k].Method;
+ if (prop.ulVal == method)
+ {
+ m_MainMethod = method;
break;
- default:
- return E_INVALIDARG;
+ }
}
+ if (k == ARRAY_SIZE(k_SupportedMethods))
+ return E_INVALIDARG;
}
else
return E_INVALIDARG;
}
else if (name.Left(2) == L"EM")
{
- if (prop.vt == VT_BSTR)
+ if (prop.vt != VT_BSTR)
+ return E_INVALIDARG;
{
- UString valueString = prop.bstrVal;
- valueString.MakeUpper();
- if (valueString.Left(3) == L"AES")
+ UString m = prop.bstrVal;
+ m.MakeUpper();
+ if (m.Left(3) == L"AES")
{
- valueString = valueString.Mid(3);
- if (valueString == L"128")
- m_AesKeyMode = 1;
- else if (valueString == L"192")
- m_AesKeyMode = 2;
- else if (valueString == L"256" || valueString.IsEmpty())
- m_AesKeyMode = 3;
+ m = m.Mid(3);
+ if (m == L"128")
+ _props.AesKeyMode = 1;
+ else if (m == L"192")
+ _props.AesKeyMode = 2;
+ else if (m == L"256" || m.IsEmpty())
+ _props.AesKeyMode = 3;
else
return E_INVALIDARG;
- m_IsAesMode = true;
+ _props.IsAesMode = true;
m_ForceAesMode = true;
}
- else if (valueString == L"ZIPCRYPTO")
+ else if (m == L"ZIPCRYPTO")
{
- m_IsAesMode = false;
+ _props.IsAesMode = false;
m_ForceAesMode = true;
}
else
return E_INVALIDARG;
}
- else
- return E_INVALIDARG;
- }
- else if (name[0] == L'D')
- {
- UInt32 dicSize = kBZip2DicSizeX5;
- RINOK(ParsePropDictionaryValue(name.Mid(1), prop, dicSize));
- m_DicSize = dicSize;
- }
- else if (name.Left(3) == L"MEM")
- {
- UInt32 memSize = 1 << 24;
- RINOK(ParsePropDictionaryValue(name.Mid(3), prop, memSize));
- m_MemSize = memSize;
- }
- else if (name[0] == L'O')
- {
- UInt32 order = 8;
- RINOK(ParsePropValue(name.Mid(1), prop, order));
- m_Order = order;
- }
- else if (name.Left(4) == L"PASS")
- {
- UInt32 num = kDeflateNumPassesX9;
- RINOK(ParsePropValue(name.Mid(4), prop, num));
- m_NumPasses = num;
- }
- else if (name.Left(2) == L"FB")
- {
- UInt32 num = kDeflateNumFastBytesX9;
- RINOK(ParsePropValue(name.Mid(2), prop, num));
- m_NumFastBytes = num;
- }
- else if (name.Left(2) == L"MC")
- {
- UInt32 num = 0xFFFFFFFF;
- RINOK(ParsePropValue(name.Mid(2), prop, num));
- m_NumMatchFinderCycles = num;
- m_NumMatchFinderCyclesDefined = true;
}
else if (name.Left(2) == L"MT")
{
#ifndef _7ZIP_ST
- RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _numThreads));
+ RINOK(ParseMtProp(name.Mid(2), prop, numProcessors, _props.NumThreads));
+ _props.NumThreadsWasChanged = true;
#endif
}
- else if (name.Left(1) == L"A")
- {
- UInt32 num = kLzAlgoX5;
- RINOK(ParsePropValue(name.Mid(1), prop, num));
- m_Algo = num;
- }
else if (name.CompareNoCase(L"TC") == 0)
{
- RINOK(SetBoolProperty(m_WriteNtfsTimeExtra, prop));
+ RINOK(PROPVARIANT_to_bool(prop, m_WriteNtfsTimeExtra));
}
else if (name.CompareNoCase(L"CL") == 0)
{
- RINOK(SetBoolProperty(m_ForceLocal, prop));
+ RINOK(PROPVARIANT_to_bool(prop, m_ForceLocal));
if (m_ForceLocal)
m_ForceUtf8 = false;
}
else if (name.CompareNoCase(L"CU") == 0)
{
- RINOK(SetBoolProperty(m_ForceUtf8, prop));
+ RINOK(PROPVARIANT_to_bool(prop, m_ForceUtf8));
if (m_ForceUtf8)
m_ForceLocal = false;
}
else
- return E_INVALIDARG;
+ return _props.MethodInfo.ParseParamsFromPROPVARIANT(name, prop);
}
return S_OK;
}
diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp
index b36b61be..e930488f 100755
--- a/CPP/7zip/Archive/Zip/ZipIn.cpp
+++ b/CPP/7zip/Archive/Zip/ZipIn.cpp
@@ -756,6 +756,7 @@ void CEcd64::Parse(const Byte *p)
HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress)
{
+ IsOkHeaders = true;
// m_Signature must be kLocalFileHeaderSignature or
// kEndOfCentralDirSignature
// m_Position points to next byte after signature
@@ -852,6 +853,8 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr
if (ecd64.thisDiskNumber != 0 || ecd64.startCDDiskNumber != 0)
throw CInArchiveException(CInArchiveException::kMultiVolumeArchiveAreNotSupported);
+ if (numCdItems != items.Size())
+ IsOkHeaders = false;
if ((UInt16)ecd64.numEntriesInCDOnThisDisk != ((UInt16)numCdItems) ||
(UInt16)ecd64.numEntriesInCD != ((UInt16)numCdItems) ||
(UInt32)ecd64.cdSize != (UInt32)cdSize ||
@@ -861,7 +864,6 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *pr
_inBufMode = false;
_inBuffer.Free();
- IsOkHeaders = (numCdItems == items.Size());
ArcInfo.FinishPosition = m_Position;
return S_OK;
}
diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp
index 139b0129..ad89f558 100755
--- a/CPP/7zip/Archive/Zip/ZipItem.cpp
+++ b/CPP/7zip/Archive/Zip/ZipItem.cpp
@@ -51,7 +51,7 @@ bool CExtraSubBlock::ExtractNtfsTime(int index, FILETIME &ft) const
return false;
}
-bool CExtraSubBlock::ExtractUnixTime(int index, UInt32 &res) const
+bool CExtraSubBlock::ExtractUnixTime(bool isCentral, int index, UInt32 &res) const
{
res = 0;
UInt32 size = (UInt32)Data.GetCapacity();
@@ -60,6 +60,15 @@ bool CExtraSubBlock::ExtractUnixTime(int index, UInt32 &res) const
const Byte *p = (const Byte *)Data;
Byte flags = *p++;
size--;
+ if (isCentral)
+ {
+ if (index != NFileHeader::NUnixTime::kMTime ||
+ (flags & (1 << NFileHeader::NUnixTime::kMTime)) == 0 ||
+ size < 4)
+ return false;
+ res = GetUi32(p);
+ return true;
+ }
for (int i = 0; i < 3; i++)
if ((flags & (1 << i)) != 0)
{
@@ -88,7 +97,7 @@ bool CItem::IsDir() const
if (!FromCentral)
return false;
WORD highAttributes = WORD((ExternalAttributes >> 16 ) & 0xFFFF);
- switch(MadeByVersion.HostOS)
+ switch (MadeByVersion.HostOS)
{
case NFileHeader::NHostOS::kAMIGA:
switch (highAttributes & NFileHeader::NAmigaAttribute::kIFMT)
@@ -109,44 +118,41 @@ bool CItem::IsDir() const
case NFileHeader::NHostOS::kAcorn:
case NFileHeader::NHostOS::kMVS:
return false; // change it throw kUnknownAttributes;
+ case NFileHeader::NHostOS::kUnix:
+ return (highAttributes & NFileHeader::NUnixAttribute::kIFDIR) != 0;
default:
- /*
- switch (highAttributes & NFileHeader::NUnixAttribute::kIFMT)
- {
- case NFileHeader::NUnixAttribute::kIFDIR:
- return true;
- default:
- return false;
- }
- */
return false;
}
}
-UInt32 CLocalItem::GetWinAttributes() const
-{
- DWORD winAttributes = 0;
- if (IsDir())
- winAttributes |= FILE_ATTRIBUTE_DIRECTORY;
- return winAttributes;
-}
-
-UInt32 CItem::GetWinAttributes() const
+UInt32 CItem::GetWinAttrib() const
{
- DWORD winAttributes = 0;
- switch(MadeByVersion.HostOS)
+ DWORD winAttrib = 0;
+ switch (MadeByVersion.HostOS)
{
case NFileHeader::NHostOS::kFAT:
case NFileHeader::NHostOS::kNTFS:
if (FromCentral)
- winAttributes = ExternalAttributes;
+ winAttrib = ExternalAttributes;
break;
- default:
- winAttributes = 0; // must be converted from unix value;
}
- if (IsDir()) // test it;
- winAttributes |= FILE_ATTRIBUTE_DIRECTORY;
- return winAttributes;
+ if (IsDir()) // test it;
+ winAttrib |= FILE_ATTRIBUTE_DIRECTORY;
+ return winAttrib;
+}
+
+bool CItem::GetPosixAttrib(UInt32 &attrib) const
+{
+ // some archivers can store PosixAttrib in high 16 bits even with HostOS=FAT.
+ if (FromCentral && MadeByVersion.HostOS == NFileHeader::NHostOS::kUnix)
+ {
+ attrib = ExternalAttributes >> 16;
+ return (attrib != 0);
+ }
+ attrib = 0;
+ if (IsDir())
+ attrib = NFileHeader::NUnixAttribute::kIFDIR;
+ return false;
}
void CLocalItem::SetFlagBits(int startBitNumber, int numBits, int value)
diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h
index 31f2de73..5efd433a 100755
--- a/CPP/7zip/Archive/Zip/ZipItem.h
+++ b/CPP/7zip/Archive/Zip/ZipItem.h
@@ -3,7 +3,6 @@
#ifndef __ARCHIVE_ZIP_ITEM_H
#define __ARCHIVE_ZIP_ITEM_H
-#include "Common/Types.h"
#include "Common/MyString.h"
#include "Common/Buffer.h"
#include "Common/UTFConvert.h"
@@ -28,7 +27,7 @@ struct CExtraSubBlock
UInt16 ID;
CByteBuffer Data;
bool ExtractNtfsTime(int index, FILETIME &ft) const;
- bool ExtractUnixTime(int index, UInt32 &res) const;
+ bool ExtractUnixTime(bool isCentral, int index, UInt32 &res) const;
};
struct CWzAesExtraField
@@ -152,13 +151,13 @@ struct CExtraBlock
return false;
}
- bool GetUnixTime(int index, UInt32 &res) const
+ bool GetUnixTime(bool isCentral, int index, UInt32 &res) const
{
for (int i = 0; i < SubBlocks.Size(); i++)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kUnixTime)
- return sb.ExtractUnixTime(index, res);
+ return sb.ExtractUnixTime(isCentral, index, res);
}
return false;
}
@@ -205,7 +204,6 @@ public:
bool IsDir() const;
bool IgnoreItem() const { return false; }
- UInt32 GetWinAttributes() const;
bool HasDescriptor() const { return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; }
@@ -252,7 +250,8 @@ public:
bool NtfsTimeIsDefined;
bool IsDir() const;
- UInt32 GetWinAttributes() const;
+ UInt32 GetWinAttrib() const;
+ bool GetPosixAttrib(UInt32 &attrib) const;
bool IsThereCrc() const
{
@@ -277,5 +276,3 @@ public:
}}
#endif
-
-
diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
index d4fdee3d..490d9e26 100755
--- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
@@ -473,6 +473,9 @@ static HRESULT Update2St(
items.Add(item);
lps->ProgressOffset += NFileHeader::kLocalBlockSize;
}
+ lps->InSize = unpackSizeTotal;
+ lps->OutSize = packSizeTotal;
+ RINOK(lps->SetCur());
archive.WriteCentralDir(items, comment);
return S_OK;
}
@@ -493,7 +496,7 @@ static HRESULT Update2(
UInt64 numBytesToCompress = 0;
int i;
- for(i = 0; i < updateItems.Size(); i++)
+ for (i = 0; i < updateItems.Size(); i++)
{
const CUpdateItem &ui = updateItems[i];
if (ui.NewData)
@@ -527,6 +530,10 @@ static HRESULT Update2(
complexity = 0;
+ CCompressionMethodMode options2;
+ if (options != 0)
+ options2 = *options;
+
#ifndef _7ZIP_ST
const size_t kNumMaxThreads = (1 << 10);
@@ -537,53 +544,58 @@ static HRESULT Update2(
const size_t kMemPerThread = (1 << 25);
const size_t kBlockSize = 1 << 16;
- CCompressionMethodMode options2;
- if (options != 0)
- options2 = *options;
-
bool mtMode = ((options != 0) && (numThreads > 1));
if (numFilesToCompress <= 1)
mtMode = false;
- if (mtMode)
+ if (!mtMode)
+ {
+ if (numThreads < 2)
+ if (options2.MethodInfo.FindProp(NCoderPropID::kNumThreads) < 0 &&
+ options2.NumThreadsWasChanged)
+ options2.MethodInfo.AddNumThreadsProp(1);
+ }
+ else
{
Byte method = options->MethodSequence.Front();
if (method == NFileHeader::NCompressionMethod::kStored && !options->PasswordIsDefined)
- mtMode = false;
+ numThreads = 1;
if (method == NFileHeader::NCompressionMethod::kBZip2)
{
- UInt64 averageSize = numBytesToCompress / numFilesToCompress;
- UInt32 blockSize = options->DicSize;
- if (blockSize == 0)
- blockSize = 1;
- UInt64 averageNumberOfBlocks = averageSize / blockSize;
- UInt32 numBZip2Threads = 32;
- if (averageNumberOfBlocks < numBZip2Threads)
- numBZip2Threads = (UInt32)averageNumberOfBlocks;
- if (numBZip2Threads < 1)
- numBZip2Threads = 1;
- numThreads = numThreads / numBZip2Threads;
- options2.NumThreads = numBZip2Threads;
- if (numThreads <= 1)
- mtMode = false;
+ bool fixedNumber;
+ UInt32 numBZip2Threads = options2.MethodInfo.Get_BZip2_NumThreads(fixedNumber);
+ if (!fixedNumber)
+ {
+ UInt64 averageSize = numBytesToCompress / numFilesToCompress;
+ UInt32 blockSize = options2.MethodInfo.Get_BZip2_BlockSize();
+ UInt64 averageNumberOfBlocks = averageSize / blockSize + 1;
+ numBZip2Threads = 32;
+ if (averageNumberOfBlocks < numBZip2Threads)
+ numBZip2Threads = (UInt32)averageNumberOfBlocks;
+ options2.MethodInfo.AddNumThreadsProp(numBZip2Threads);
+ }
+ numThreads /= numBZip2Threads;
}
if (method == NFileHeader::NCompressionMethod::kLZMA)
{
- UInt32 numLZMAThreads = (options->Algo > 0 ? 2 : 1);
+ bool fixedNumber;
+ // we suppose that default LZMA is 2 thread. So we don't change it
+ UInt32 numLZMAThreads = options2.MethodInfo.Get_Lzma_NumThreads(fixedNumber);
numThreads /= numLZMAThreads;
- options2.NumThreads = numLZMAThreads;
- if (numThreads <= 1)
- mtMode = false;
}
+ if (numThreads > numFilesToCompress)
+ numThreads = (UInt32)numFilesToCompress;
+ if (numThreads <= 1)
+ mtMode = false;
}
if (!mtMode)
#endif
return Update2St(
EXTERNAL_CODECS_LOC_VARS
- archive, inArchive,inStream,
- inputItems, updateItems, options, comment, updateCallback);
+ archive, inArchive, inStream,
+ inputItems, updateItems, &options2, comment, updateCallback);
#ifndef _7ZIP_ST
@@ -606,7 +618,7 @@ static HRESULT Update2(
{
RINOK(memManager.AllocateSpaceAlways((size_t)numThreads * (kMemPerThread / kBlockSize)));
- for(i = 0; i < updateItems.Size(); i++)
+ for (i = 0; i < updateItems.Size(); i++)
refs.Refs.Add(CMemBlocks2());
UInt32 i;
@@ -796,6 +808,7 @@ static HRESULT Update2(
mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity);
itemIndex++;
}
+ RINOK(mtCompressProgressMixer.SetRatioInfo(0, NULL, NULL));
archive.WriteCentralDir(items, comment);
return S_OK;
#endif
diff --git a/CPP/7zip/Bundles/Alone/Alone.dsp b/CPP/7zip/Bundles/Alone/Alone.dsp
index e6328f7e..5e0e3e51 100755
--- a/CPP/7zip/Bundles/Alone/Alone.dsp
+++ b/CPP/7zip/Bundles/Alone/Alone.dsp
@@ -1771,14 +1771,6 @@ SOURCE=..\..\UI\Common\UpdateProduce.cpp
SOURCE=..\..\UI\Common\UpdateProduce.h
# End Source File
-# Begin Source File
-
-SOURCE=..\..\UI\Common\WorkDir.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\UI\Common\WorkDir.h
-# End Source File
# End Group
# Begin Group "Crypto"
diff --git a/CPP/7zip/Bundles/Alone/makefile b/CPP/7zip/Bundles/Alone/makefile
index 862d695a..a99c61ec 100755
--- a/CPP/7zip/Bundles/Alone/makefile
+++ b/CPP/7zip/Bundles/Alone/makefile
@@ -90,7 +90,6 @@ UI_COMMON_OBJS = \
$O\UpdateCallback.obj \
$O\UpdatePair.obj \
$O\UpdateProduce.obj \
- $O\WorkDir.obj \
AR_OBJS = \
$O\Bz2Handler.obj \
diff --git a/CPP/7zip/Bundles/Alone7z/makefile b/CPP/7zip/Bundles/Alone7z/makefile
index 2aefcbd0..8de884f7 100755
--- a/CPP/7zip/Bundles/Alone7z/makefile
+++ b/CPP/7zip/Bundles/Alone7z/makefile
@@ -88,7 +88,6 @@ UI_COMMON_OBJS = \
$O\UpdateCallback.obj \
$O\UpdatePair.obj \
$O\UpdateProduce.obj \
- $O\WorkDir.obj \
AR_OBJS = \
$O\LzmaHandler.obj \
diff --git a/CPP/7zip/Bundles/Fm/FM.dsp b/CPP/7zip/Bundles/Fm/FM.dsp
index 44cc6398..dded8b1d 100755
--- a/CPP/7zip/Bundles/Fm/FM.dsp
+++ b/CPP/7zip/Bundles/Fm/FM.dsp
@@ -613,6 +613,14 @@ SOURCE=..\..\Common\FileStreams.h
# End Source File
# Begin Source File
+SOURCE=..\..\Common\MethodProps.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MethodProps.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Common\ProgressUtils.cpp
# End Source File
# Begin Source File
diff --git a/CPP/7zip/Bundles/Fm/makefile b/CPP/7zip/Bundles/Fm/makefile
index 02ee7af1..b8f9133f 100755
--- a/CPP/7zip/Bundles/Fm/makefile
+++ b/CPP/7zip/Bundles/Fm/makefile
@@ -181,6 +181,7 @@ AR_OBJS = \
$O\SplitHandler.obj \
$O\SquashfsHandler.obj \
$O\SwfHandler.obj \
+ $O\UefiHandler.obj \
$O\VhdHandler.obj \
$O\XarHandler.obj \
$O\XzHandler.obj \
diff --git a/CPP/7zip/Bundles/Fm/resource.rc b/CPP/7zip/Bundles/Fm/resource.rc
index c2aab047..dd2058a1 100755
--- a/CPP/7zip/Bundles/Fm/resource.rc
+++ b/CPP/7zip/Bundles/Fm/resource.rc
@@ -3,5 +3,5 @@
STRINGTABLE
BEGIN
- 100 "7z zip bz2 bzip2 tbz2 tbz rar arj z taz lzh lha cab iso 001 rpm deb cpio tar gz gzip tgz tpz4 wim swm lzma dmg hfs xar vhd fat ntfs xz"
+ 100 "7z zip rar 001 cab iso xz txz lzma tar cpio bz2 bzip2 tbz2 tbz gz gzip tgz tpz z taz lzh lha rpm deb arj vhd wim swm fat ntfs dmg hfs xar squashfs"
END
diff --git a/CPP/7zip/Bundles/Format7z/makefile b/CPP/7zip/Bundles/Format7z/makefile
index d3609f7b..3b04c5e7 100755
--- a/CPP/7zip/Bundles/Format7z/makefile
+++ b/CPP/7zip/Bundles/Format7z/makefile
@@ -109,7 +109,6 @@ CRYPTO_OBJS = \
$O\7zAesRegister.obj \
$O\MyAes.obj \
$O\RandGen.obj \
- $O\Sha1.obj \
C_OBJS = \
$O\Alloc.obj \
diff --git a/CPP/7zip/Bundles/Format7zExtract/makefile b/CPP/7zip/Bundles/Format7zExtract/makefile
index fb76cbc0..5598adc2 100755
--- a/CPP/7zip/Bundles/Format7zExtract/makefile
+++ b/CPP/7zip/Bundles/Format7zExtract/makefile
@@ -26,6 +26,7 @@ WIN_OBJS = \
$O\LimitedStreams.obj \
$O\LockedStream.obj \
$O\MethodId.obj \
+ $O\MethodProps.obj \
$O\OutBuffer.obj \
$O\ProgressUtils.obj \
$O\StreamBinder.obj \
diff --git a/CPP/7zip/Bundles/Format7zF/Format7z.dsp b/CPP/7zip/Bundles/Format7zF/Format7z.dsp
index b13ea42a..5bf1277d 100755
--- a/CPP/7zip/Bundles/Format7zF/Format7z.dsp
+++ b/CPP/7zip/Bundles/Format7zF/Format7z.dsp
@@ -2436,6 +2436,10 @@ SOURCE=..\..\Archive\SwfHandler.cpp
# End Source File
# Begin Source File
+SOURCE=..\..\Archive\UefiHandler.cpp
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Archive\VhdHandler.cpp
# End Source File
# Begin Source File
diff --git a/CPP/7zip/Bundles/Format7zF/makefile b/CPP/7zip/Bundles/Format7zF/makefile
index 11c74872..2601f1d6 100755
--- a/CPP/7zip/Bundles/Format7zF/makefile
+++ b/CPP/7zip/Bundles/Format7zF/makefile
@@ -79,6 +79,7 @@ AR_OBJS = \
$O\SplitHandler.obj \
$O\SwfHandler.obj \
$O\SquashfsHandler.obj \
+ $O\UefiHandler.obj \
$O\VhdHandler.obj \
$O\XarHandler.obj \
$O\XzHandler.obj \
diff --git a/CPP/7zip/Bundles/Format7zF/resource.rc b/CPP/7zip/Bundles/Format7zF/resource.rc
index df492020..1caf7301 100755
--- a/CPP/7zip/Bundles/Format7zF/resource.rc
+++ b/CPP/7zip/Bundles/Format7zF/resource.rc
@@ -1,6 +1,6 @@
#include "../../MyVersionInfo.rc"
-MY_VERSION_INFO_DLL("7z Standalone Plugin", "7za")
+MY_VERSION_INFO_DLL("7z Plugin", "7z")
0 ICON "../../Archive/Icons/7z.ico"
@@ -33,5 +33,5 @@ MY_VERSION_INFO_DLL("7z Standalone Plugin", "7za")
STRINGTABLE
BEGIN
- 100 "7z:0 zip:1 bz2:2 bzip2:2 tbz2:2 tbz:2 rar:3 arj:4 z:5 taz:5 lzh:6 lha:6 cab:7 iso:8 001:9 rpm:10 deb:11 cpio:12 tar:13 gz:14 gzip:14 tgz:14 tpz:14 wim:15 swm:15 lzma:16 dmg:17 hfs:18 xar:19 vhd:20 fat:21 ntfs:22 xz:23 txz:23 squashfs:24"
+ 100 "7z:0 zip:1 rar:3 001:9 cab:7 iso:8 xz:23 txz:23 lzma:16 tar:13 cpio:12 bz2:2 bzip2:2 tbz2:2 tbz:2 gz:14 gzip:14 tgz:14 tpz:14 z:5 taz:5 lzh:6 lha:6 rpm:10 deb:11 arj:4 vhd:20 wim:15 swm:15 fat:21 ntfs:22 dmg:17 hfs:18 xar:19 squashfs:24"
END
diff --git a/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp b/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp
index efda09d7..e0f4dcba 100755
--- a/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp
+++ b/CPP/7zip/Bundles/LzmaCon/LzmaAlone.cpp
@@ -49,6 +49,8 @@ enum Enum
{
kHelp1 = 0,
kHelp2,
+ kMethod,
+ kLevel,
kAlgo,
kDict,
kFb,
@@ -69,6 +71,8 @@ static const CSwitchForm kSwitchForms[] =
{
{ L"?", NSwitchType::kSimple, false },
{ L"H", NSwitchType::kSimple, false },
+ { L"MM", NSwitchType::kUnLimitedPostString, false, 1 },
+ { L"X", NSwitchType::kUnLimitedPostString, false, 1 },
{ L"A", NSwitchType::kUnLimitedPostString, false, 1 },
{ L"D", NSwitchType::kUnLimitedPostString, false, 1 },
{ L"FB", NSwitchType::kUnLimitedPostString, false, 1 },
@@ -186,7 +190,7 @@ int main2(int numArgs, const char *args[])
IncorrectCommand();
}
- if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
+ if (parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
{
PrintHelp();
return 0;
@@ -198,21 +202,38 @@ int main2(int numArgs, const char *args[])
IncorrectCommand();
const UString &command = nonSwitchStrings[paramIndex++];
+ CObjectVector<CProperty> props;
bool dictDefined = false;
- UInt32 dict = (UInt32)-1;
- if(parser[NKey::kDict].ThereIs)
+ UInt32 dict = (UInt32)(Int32)-1;
+ if (parser[NKey::kDict].ThereIs)
{
UInt32 dicLog;
- if (!GetNumber(parser[NKey::kDict].PostStrings[0], dicLog))
+ const UString &s = parser[NKey::kDict].PostStrings[0];
+ if (!GetNumber(s, dicLog))
IncorrectCommand();
dict = 1 << dicLog;
dictDefined = true;
+ CProperty prop;
+ prop.Name = L"d";
+ prop.Value = s;
+ props.Add(prop);
+ }
+ if (parser[NKey::kLevel].ThereIs)
+ {
+ UInt32 level = 5;
+ const UString &s = parser[NKey::kLevel].PostStrings[0];
+ if (!GetNumber(s, level))
+ IncorrectCommand();
+ CProperty prop;
+ prop.Name = L"x";
+ prop.Value = s;
+ props.Add(prop);
}
UString mf = L"BT4";
if (parser[NKey::kMatchFinder].ThereIs)
mf = parser[NKey::kMatchFinder].PostStrings[0];
- UInt32 numThreads = (UInt32)-1;
+ UInt32 numThreads = (UInt32)(Int32)-1;
#ifndef _7ZIP_ST
if (parser[NKey::kMultiThread].ThereIs)
@@ -224,9 +245,24 @@ int main2(int numArgs, const char *args[])
else
if (!GetNumber(s, numThreads))
IncorrectCommand();
+ CProperty prop;
+ prop.Name = L"mt";
+ prop.Value = s;
+ props.Add(prop);
}
#endif
+ if (parser[NKey::kMethod].ThereIs)
+ {
+ UString s = parser[NKey::kMethod].PostStrings[0];
+ if (s.IsEmpty() || s[0] != '=')
+ IncorrectCommand();
+ CProperty prop;
+ prop.Name = L"m";
+ prop.Value = s.Mid(1);
+ props.Add(prop);
+ }
+
if (command.CompareNoCase(L"b") == 0)
{
const UInt32 kNumDefaultItereations = 1;
@@ -236,10 +272,19 @@ int main2(int numArgs, const char *args[])
if (!GetNumber(nonSwitchStrings[paramIndex++], numIterations))
numIterations = kNumDefaultItereations;
}
- return LzmaBenchCon(stderr, numIterations, numThreads, dict);
+ HRESULT res = BenchCon(props, numIterations, stderr);
+ if (res != S_OK)
+ {
+ if (res != E_ABORT)
+ {
+ PrintMessage("Benchmark Error");
+ return 1;
+ }
+ }
+ return 0;
}
- if (numThreads == (UInt32)-1)
+ if (numThreads == (UInt32)(Int32)-1)
numThreads = 1;
bool encodeMode = false;
@@ -267,7 +312,7 @@ int main2(int numArgs, const char *args[])
const UString &inputName = nonSwitchStrings[paramIndex++];
inStreamSpec = new CInFileStream;
inStream = inStreamSpec;
- if (!inStreamSpec->Open(GetSystemString(inputName)))
+ if (!inStreamSpec->Open(us2fs(inputName)))
{
fprintf(stderr, "\nError: can not open input file %s\n",
(const char *)GetOemString(inputName));
@@ -289,7 +334,7 @@ int main2(int numArgs, const char *args[])
const UString &outputName = nonSwitchStrings[paramIndex++];
outStreamSpec = new COutFileStream;
outStream = outStreamSpec;
- if (!outStreamSpec->Create(GetSystemString(outputName), true))
+ if (!outStreamSpec->Create(us2fs(outputName), true))
{
fprintf(stderr, "\nError: can not open output file %s\n",
(const char *)GetOemString(outputName));
@@ -398,7 +443,7 @@ int main2(int numArgs, const char *args[])
if (!GetNumber(parser[NKey::kMc].PostStrings[0], mc))
IncorrectCommand();
- PROPID propIDs[] =
+ const PROPID propIDs[] =
{
NCoderPropID::kDictionarySize,
NCoderPropID::kPosStateBits,
@@ -512,7 +557,7 @@ int main2(int numArgs, const char *args[])
int MY_CDECL main(int numArgs, const char *args[])
{
try { return main2(numArgs, args); }
- catch(const char *s)
+ catch (const char *s)
{
fprintf(stderr, "\nError: %s\n", s);
return 1;
diff --git a/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp b/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp
index e171539d..6111aa7e 100755
--- a/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp
+++ b/CPP/7zip/Bundles/LzmaCon/LzmaCon.dsp
@@ -132,6 +132,14 @@ SOURCE=..\..\..\Windows\FileIO.h
# End Source File
# Begin Source File
+SOURCE=..\..\..\Windows\PropVariant.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\Windows\PropVariant.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\Windows\Synchronization.cpp
# End Source File
# Begin Source File
@@ -280,6 +288,14 @@ SOURCE=..\..\Common\FilterCoder.h
# End Source File
# Begin Source File
+SOURCE=..\..\Common\MethodProps.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MethodProps.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Common\StreamUtils.cpp
# End Source File
# Begin Source File
diff --git a/CPP/7zip/Bundles/LzmaCon/makefile b/CPP/7zip/Bundles/LzmaCon/makefile
index 4a76bbde..35d031af 100755
--- a/CPP/7zip/Bundles/LzmaCon/makefile
+++ b/CPP/7zip/Bundles/LzmaCon/makefile
@@ -21,6 +21,7 @@ COMMON_OBJS = \
WIN_OBJS = \
$O\FileIO.obj \
+ $O\PropVariant.obj \
$O\System.obj
7ZIP_COMMON_OBJS = \
@@ -28,6 +29,7 @@ WIN_OBJS = \
$O\CreateCoder.obj \
$O\FileStreams.obj \
$O\FilterCoder.obj \
+ $O\MethodProps.obj \
$O\OutBuffer.obj \
$O\StreamUtils.obj \
diff --git a/CPP/7zip/Bundles/LzmaCon/makefile.gcc b/CPP/7zip/Bundles/LzmaCon/makefile.gcc
index 32c85f15..0f9f498c 100755
--- a/CPP/7zip/Bundles/LzmaCon/makefile.gcc
+++ b/CPP/7zip/Bundles/LzmaCon/makefile.gcc
@@ -30,15 +30,18 @@ OBJS = \
CWrappers.o \
FileStreams.o \
FilterCoder.o \
+ MethodProps.o \
StreamUtils.o \
$(FILE_IO).o \
CommandLineParser.o \
CRC.o \
IntToString.o \
MyString.o \
+ MyVector.o \
+ MyWindows.o \
StringConvert.o \
StringToInt.o \
- MyVector.o \
+ PropVariant.o \
7zCrc.o \
7zCrcOpt.o \
Alloc.o \
@@ -89,6 +92,9 @@ FileStreams.o: ../../Common/FileStreams.cpp
FilterCoder.o: ../../Common/FilterCoder.cpp
$(CXX) $(CFLAGS) ../../Common/FilterCoder.cpp
+MethodProps.o: ../../Common/MethodProps.cpp
+ $(CXX) $(CFLAGS) ../../Common/MethodProps.cpp
+
StreamUtils.o: ../../Common/StreamUtils.cpp
$(CXX) $(CFLAGS) ../../Common/StreamUtils.cpp
@@ -102,23 +108,26 @@ CommandLineParser.o: ../../../Common/CommandLineParser.cpp
CRC.o: ../../../Common/CRC.cpp
$(CXX) $(CFLAGS) ../../../Common/CRC.cpp
-MyWindows.o: ../../../Common/MyWindows.cpp
- $(CXX) $(CFLAGS) ../../../Common/MyWindows.cpp
-
IntToString.o: ../../../Common/IntToString.cpp
$(CXX) $(CFLAGS) ../../../Common/IntToString.cpp
MyString.o: ../../../Common/MyString.cpp
$(CXX) $(CFLAGS) ../../../Common/MyString.cpp
+MyVector.o: ../../../Common/MyVector.cpp
+ $(CXX) $(CFLAGS) ../../../Common/MyVector.cpp
+
+MyWindows.o: ../../../Common/MyWindows.cpp
+ $(CXX) $(CFLAGS) ../../../Common/MyWindows.cpp
+
StringConvert.o: ../../../Common/StringConvert.cpp
$(CXX) $(CFLAGS) ../../../Common/StringConvert.cpp
StringToInt.o: ../../../Common/StringToInt.cpp
$(CXX) $(CFLAGS) ../../../Common/StringToInt.cpp
-MyVector.o: ../../../Common/MyVector.cpp
- $(CXX) $(CFLAGS) ../../../Common/MyVector.cpp
+PropVariant.o: ../../../Windows/PropVariant.cpp
+ $(CXX) $(CFLAGS) ../../../Windows/PropVariant.cpp
7zCrc.o: ../../../../C/7zCrc.c
$(CXX_C) $(CFLAGS) ../../../../C/7zCrc.c
diff --git a/CPP/7zip/Bundles/SFXCon/Main.cpp b/CPP/7zip/Bundles/SFXCon/Main.cpp
index b136ae7c..3e9a8162 100755
--- a/CPP/7zip/Bundles/SFXCon/Main.cpp
+++ b/CPP/7zip/Bundles/SFXCon/Main.cpp
@@ -11,6 +11,7 @@
#include "Windows/DLL.h"
#include "Windows/FileDir.h"
#endif
+#include "Windows/FileName.h"
#include "../../UI/Common/ExitCode.h"
#include "../../UI/Common/Extract.h"
@@ -25,6 +26,9 @@ using namespace NWindows;
using namespace NFile;
using namespace NCommandLineParser;
+#ifdef _WIN32
+HINSTANCE g_hInstance = 0;
+#endif
int g_CodePage = -1;
extern CStdOutStream *g_StdStream;
@@ -261,12 +265,11 @@ int Main2(
#ifdef _WIN32
- UString arcPath;
+ FString arcPath;
{
- UString path;
- NDLL::MyGetModuleFileName(NULL, path);
- int fileNamePartStartIndex;
- if (!NDirectory::MyGetFullPathName(path, arcPath, fileNamePartStartIndex))
+ FString path;
+ NDLL::MyGetModuleFileName(path);
+ if (!NDirectory::MyGetFullPathName(path, arcPath))
{
g_StdOut << "GetFullPathName Error";
return NExitCode::kFatalError;
@@ -291,7 +294,7 @@ int Main2(
PrintHelpAndExit();
}
- if(parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
+ if (parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs)
{
PrintHelp();
return 0;
@@ -330,23 +333,23 @@ int Main2(
bool passwordEnabled = parser[NKey::kPassword].ThereIs;
UString password;
- if(passwordEnabled)
+ if (passwordEnabled)
password = parser[NKey::kPassword].PostStrings[0];
if (!NFind::DoesFileExist(arcPath))
throw kCantFindSFX;
- UString outputDir;
+ FString outputDir;
if (parser[NKey::kOutputDir].ThereIs)
{
- outputDir = parser[NKey::kOutputDir].PostStrings[0];
+ outputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]);
NName::NormalizeDirPathPrefix(outputDir);
}
{
UStringVector v1, v2;
- v1.Add(arcPath);
- v2.Add(arcPath);
+ v1.Add(fs2us(arcPath));
+ v2.Add(fs2us(arcPath));
const NWildcard::CCensorNode &wildcardCensorHead =
wildcardCensor.Pairs.Front().Head;
@@ -362,7 +365,7 @@ int Main2(
if (result != S_OK)
throw CSystemException(result);
- if(command.CommandType != NCommandType::kList)
+ if (command.CommandType != NCommandType::kList)
{
CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp b/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp
index a28e82d3..9b733da0 100755
--- a/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp
+++ b/CPP/7zip/Bundles/SFXSetup/ExtractCallback.cpp
@@ -6,6 +6,7 @@
#include "Windows/FileDir.h"
#include "Windows/FileFind.h"
+#include "Windows/FileName.h"
#include "Windows/PropVariant.h"
#include "ExtractCallback.h"
@@ -18,7 +19,7 @@ static LPCWSTR kCantOpenFile = L"Can not open output file";
static LPCWSTR kUnsupportedMethod = L"Unsupported Method";
void CExtractCallbackImp::Init(IInArchive *archiveHandler,
- const UString &directoryPath,
+ const FString &directoryPath,
const UString &itemDefaultName,
const FILETIME &defaultMTime,
UInt32 defaultAttributes)
@@ -76,12 +77,12 @@ STDMETHODIMP CExtractCallbackImp::SetCompleted(const UInt64 *completeValue)
void CExtractCallbackImp::CreateComplexDirectory(const UStringVector &dirPathParts)
{
- UString fullPath = _directoryPath;
- for(int i = 0; i < dirPathParts.Size(); i++)
+ FString fullPath = _directoryPath;
+ for (int i = 0; i < dirPathParts.Size(); i++)
{
- fullPath += dirPathParts[i];
+ fullPath += us2fs(dirPathParts[i]);
NDirectory::MyCreateDirectory(fullPath);
- fullPath += NName::kDirDelimiter;
+ fullPath += FCHAR_PATH_SEPARATOR;
}
}
@@ -153,7 +154,7 @@ STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index,
CreateComplexDirectory(pathParts);
}
- UString fullProcessedPath = _directoryPath + processedPath;
+ FString fullProcessedPath = _directoryPath + us2fs(processedPath);
if (_processedFileInfo.IsDir)
{
@@ -166,7 +167,7 @@ STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index,
return S_OK;
}
- NFind::CFileInfoW fileInfo;
+ NFind::CFileInfo fileInfo;
if (fileInfo.Find(fullProcessedPath))
{
if (!NDirectory::DeleteFileAlways(fullProcessedPath))
diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractCallback.h b/CPP/7zip/Bundles/SFXSetup/ExtractCallback.h
index c78ff22b..128988f9 100755
--- a/CPP/7zip/Bundles/SFXSetup/ExtractCallback.h
+++ b/CPP/7zip/Bundles/SFXSetup/ExtractCallback.h
@@ -31,9 +31,9 @@ public:
private:
CMyComPtr<IInArchive> _archiveHandler;
- UString _directoryPath;
+ FString _directoryPath;
UString _filePath;
- UString _diskFilePath;
+ FString _diskFilePath;
bool _extractMode;
struct CProcessedFileInfo
@@ -60,7 +60,7 @@ public:
UString _message;
void Init(IInArchive *archiveHandler,
- const UString &directoryPath,
+ const FString &directoryPath,
const UString &itemDefaultName,
const FILETIME &defaultMTime,
UInt32 defaultAttributes);
diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp
index cc561090..8f830de5 100755
--- a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp
+++ b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.cpp
@@ -3,6 +3,7 @@
#include "StdAfx.h"
#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
#include "Windows/Thread.h"
#include "../../UI/Common/OpenArchive.h"
@@ -20,8 +21,8 @@ static LPCWSTR kCantOpenArchive = L"Can not open the file as archive";
struct CThreadExtracting
{
CCodecs *Codecs;
- UString FileName;
- UString DestFolder;
+ FString FileName;
+ FString DestFolder;
CExtractCallbackImp *ExtractCallbackSpec;
CMyComPtr<IArchiveExtractCallback> ExtractCallback;
@@ -32,7 +33,7 @@ struct CThreadExtracting
void Process2()
{
- NFile::NFind::CFileInfoW fi;
+ NFile::NFind::CFileInfo fi;
if (!fi.Find(FileName))
{
ErrorMessage = kCantFindArchive;
@@ -40,7 +41,7 @@ struct CThreadExtracting
return;
}
- Result = ArchiveLink.Open2(Codecs, CIntVector(), false, NULL, FileName, ExtractCallbackSpec);
+ Result = ArchiveLink.Open2(Codecs, CIntVector(), false, NULL, fs2us(FileName), ExtractCallbackSpec);
if (Result != S_OK)
{
if (Result != S_OK)
@@ -48,7 +49,7 @@ struct CThreadExtracting
return;
}
- UString dirPath = DestFolder;
+ FString dirPath = DestFolder;
NFile::NName::NormalizeDirPathPrefix(dirPath);
if (!NFile::NDirectory::CreateComplexDirectory(dirPath))
@@ -57,7 +58,7 @@ struct CThreadExtracting
#ifdef LANG
0x02000603,
#endif
- dirPath);
+ fs2us(dirPath));
Result = E_FAIL;
return;
}
@@ -86,7 +87,7 @@ struct CThreadExtracting
}
};
-HRESULT ExtractArchive(CCodecs *codecs,const UString &fileName, const UString &destFolder,
+HRESULT ExtractArchive(CCodecs *codecs, const FString &fileName, const FString &destFolder,
bool showProgress, bool &isCorrupt, UString &errorMessage)
{
isCorrupt = false;
diff --git a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h
index 56d69686..295d77b9 100755
--- a/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h
+++ b/CPP/7zip/Bundles/SFXSetup/ExtractEngine.h
@@ -1,11 +1,11 @@
// ExtractEngine.h
-#ifndef __EXTRACTENGINE_H
-#define __EXTRACTENGINE_H
+#ifndef __EXTRACT_ENGINE_H
+#define __EXTRACT_ENGINE_H
#include "../../UI/Common/LoadCodecs.h"
-HRESULT ExtractArchive(CCodecs *codecs, const UString &fileName, const UString &destFolder,
- bool showProgress, bool &isCorrupt, UString &errorMessage);
+HRESULT ExtractArchive(CCodecs *codecs, const FString &fileName, const FString &destFolder,
+ bool showProgress, bool &isCorrupt, UString &errorMessage);
#endif
diff --git a/CPP/7zip/Bundles/SFXSetup/Main.cpp b/CPP/7zip/Bundles/SFXSetup/Main.cpp
index 80e23c4e..008c0e42 100755
--- a/CPP/7zip/Bundles/SFXSetup/Main.cpp
+++ b/CPP/7zip/Bundles/SFXSetup/Main.cpp
@@ -12,6 +12,7 @@
#include "Windows/FileDir.h"
#include "Windows/FileFind.h"
#include "Windows/FileIO.h"
+#include "Windows/FileName.h"
#include "Windows/NtCheck.h"
#include "Windows/ResourceString.h"
@@ -25,11 +26,11 @@ using namespace NWindows;
HINSTANCE g_hInstance;
-static LPCTSTR kTempDirPrefix = TEXT("7zS");
+static CFSTR kTempDirPrefix = FTEXT("7zS");
#define _SHELL_EXECUTE
-static bool ReadDataString(LPCWSTR fileName, LPCSTR startID,
+static bool ReadDataString(CFSTR fileName, LPCSTR startID,
LPCSTR endID, AString &stringResult)
{
stringResult.Empty();
@@ -107,11 +108,11 @@ public:
#ifndef UNDER_CE
class CCurrentDirRestorer
{
- CSysString m_CurrentDirectory;
+ FString m_CurrentDirectory;
public:
CCurrentDirRestorer() { NFile::NDirectory::MyGetCurrentDirectory(m_CurrentDirectory); }
~CCurrentDirRestorer() { RestoreDirectory();}
- bool RestoreDirectory() { return BOOLToBool(::SetCurrentDirectory(m_CurrentDirectory)); }
+ bool RestoreDirectory() const { return NFile::NDirectory::MySetCurrentDirectory(m_CurrentDirectory); }
};
#endif
@@ -137,8 +138,8 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
#endif
NCommandLineParser::SplitCommandLine(GetCommandLineW(), archiveName, switches);
- UString fullPath;
- NDLL::MyGetModuleFileName(g_hInstance, fullPath);
+ FString fullPath;
+ NDLL::MyGetModuleFileName(fullPath);
switches.Trim();
bool assumeYes = false;
@@ -191,7 +192,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
#endif
}
- NFile::NDirectory::CTempDirectory tempDir;
+ NFile::NDirectory::CTempDir tempDir;
if (!tempDir.Create(kTempDirPrefix))
{
if (!assumeYes)
@@ -208,7 +209,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
return 1;
}
- UString tempDirPath = GetUnicodeString(tempDir.GetPath());
+ FString tempDirPath = tempDir.GetPath();
{
bool isCorrupt = false;
UString errorMessage;
@@ -233,7 +234,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
#ifndef UNDER_CE
CCurrentDirRestorer currentDirRestorer;
- if (!SetCurrentDirectory(tempDir.GetPath()))
+ if (!NFile::NDirectory::MySetCurrentDirectory(tempDir.GetPath()))
return 1;
#endif
@@ -281,7 +282,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
if (appLaunched.IsEmpty())
{
appLaunched = L"setup.exe";
- if (!NFile::NFind::DoesFileExist(GetSystemString(appLaunched)))
+ if (!NFile::NFind::DoesFileExist(us2fs(appLaunched)))
{
if (!assumeYes)
ShowErrorMessage(L"Can not find setup.exe");
@@ -290,12 +291,12 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
}
{
- UString s2 = tempDirPath;
+ FString s2 = tempDirPath;
NFile::NName::NormalizeDirPathPrefix(s2);
- appLaunched.Replace(L"%%T" WSTRING_PATH_SEPARATOR, s2);
+ appLaunched.Replace(L"%%T" WSTRING_PATH_SEPARATOR, fs2us(s2));
}
- appLaunched.Replace(L"%%T", tempDirPath);
+ appLaunched.Replace(L"%%T", fs2us(tempDirPath));
if (!switches.IsEmpty())
{
diff --git a/CPP/7zip/Bundles/SFXWin/Main.cpp b/CPP/7zip/Bundles/SFXWin/Main.cpp
index ec5098dd..bb7318a1 100755
--- a/CPP/7zip/Bundles/SFXWin/Main.cpp
+++ b/CPP/7zip/Bundles/SFXWin/Main.cpp
@@ -41,7 +41,7 @@ int APIENTRY WinMain2()
UString password;
bool assumeYes = false;
bool outputFolderDefined = false;
- UString outputFolder;
+ FString outputFolder;
UStringVector commandStrings;
NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings);
@@ -57,7 +57,7 @@ int APIENTRY WinMain2()
assumeYes = true;
else if (s.Left(2).CompareNoCase(L"-o") == 0)
{
- outputFolder = s.Mid(2);
+ outputFolder = us2fs(s.Mid(2));
NWindows::NFile::NName::NormalizeDirPathPrefix(outputFolder);
outputFolderDefined = !outputFolder.IsEmpty();
}
@@ -67,12 +67,11 @@ int APIENTRY WinMain2()
}
}
- UString path;
- NWindows::NDLL::MyGetModuleFileName(g_hInstance, path);
+ FString path;
+ NWindows::NDLL::MyGetModuleFileName(path);
- UString fullPath;
- int fileNamePartStartIndex;
- if (!NWindows::NFile::NDirectory::MyGetFullPathName(path, fullPath, fileNamePartStartIndex))
+ FString fullPath;
+ if (!NWindows::NFile::NDirectory::MyGetFullPathName(path, fullPath))
{
ShowErrorMessage(L"Error 1329484");
return 1;
@@ -102,8 +101,15 @@ int APIENTRY WinMain2()
#endif
CExtractOptions eo;
- eo.OutputDir = outputFolderDefined ? outputFolder :
- fullPath.Left(fileNamePartStartIndex);
+
+ FString dirPrefix;
+ if (!NWindows::NFile::NDirectory::GetOnlyDirPrefix(path, dirPrefix))
+ {
+ ShowErrorMessage(L"Error 1329485");
+ return 1;
+ }
+
+ eo.OutputDir = outputFolderDefined ? outputFolder : dirPrefix;
eo.YesToAll = assumeYes;
eo.OverwriteMode = assumeYes ?
NExtract::NOverwriteMode::kWithoutPrompt :
@@ -112,8 +118,8 @@ int APIENTRY WinMain2()
eo.TestMode = false;
UStringVector v1, v2;
- v1.Add(fullPath);
- v2.Add(fullPath);
+ v1.Add(fs2us(fullPath));
+ v2.Add(fs2us(fullPath));
NWildcard::CCensorNode wildcardCensor;
wildcardCensor.AddItem(true, L"*", true, true, true);
@@ -170,4 +176,3 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
return NExitCode::kFatalError;
}
}
-
diff --git a/CPP/7zip/Common/CWrappers.cpp b/CPP/7zip/Common/CWrappers.cpp
index 358f0b50..ef21228e 100755
--- a/CPP/7zip/Common/CWrappers.cpp
+++ b/CPP/7zip/Common/CWrappers.cpp
@@ -37,6 +37,7 @@ SRes HRESULT_To_SRes(HRESULT res, SRes defaultRes)
case E_INVALIDARG: return SZ_ERROR_PARAM;
case E_ABORT: return SZ_ERROR_PROGRESS;
case S_FALSE: return SZ_ERROR_DATA;
+ case E_NOTIMPL: return SZ_ERROR_UNSUPPORTED;
}
return defaultRes;
}
@@ -90,6 +91,7 @@ HRESULT SResToHRESULT(SRes res)
case SZ_ERROR_PARAM: return E_INVALIDARG;
case SZ_ERROR_PROGRESS: return E_ABORT;
case SZ_ERROR_DATA: return S_FALSE;
+ case SZ_ERROR_UNSUPPORTED: return E_NOTIMPL;
}
return E_FAIL;
}
diff --git a/CPP/7zip/Common/FilePathAutoRename.cpp b/CPP/7zip/Common/FilePathAutoRename.cpp
index 7d6e36f1..495f886b 100755
--- a/CPP/7zip/Common/FilePathAutoRename.cpp
+++ b/CPP/7zip/Common/FilePathAutoRename.cpp
@@ -11,10 +11,10 @@
using namespace NWindows;
-static bool MakeAutoName(const UString &name,
- const UString &extension, unsigned value, UString &path)
+static bool MakeAutoName(const FString &name,
+ const FString &extension, unsigned value, FString &path)
{
- wchar_t number[16];
+ FChar number[16];
ConvertUInt32ToString(value, number);
path = name;
path += number;
@@ -22,18 +22,18 @@ static bool MakeAutoName(const UString &name,
return NFile::NFind::DoesFileOrDirExist(path);
}
-bool AutoRenamePath(UString &fullProcessedPath)
+bool AutoRenamePath(FString &fullProcessedPath)
{
- UString path;
- int dotPos = fullProcessedPath.ReverseFind(L'.');
+ FString path;
+ int dotPos = fullProcessedPath.ReverseFind(FTEXT('.'));
- int slashPos = fullProcessedPath.ReverseFind(L'/');
+ int slashPos = fullProcessedPath.ReverseFind(FTEXT('/'));
#ifdef _WIN32
- int slash1Pos = fullProcessedPath.ReverseFind(L'\\');
+ int slash1Pos = fullProcessedPath.ReverseFind(FTEXT('\\'));
slashPos = MyMax(slashPos, slash1Pos);
#endif
- UString name, extension;
+ FString name, extension;
if (dotPos > slashPos && dotPos > 0)
{
name = fullProcessedPath.Left(dotPos);
diff --git a/CPP/7zip/Common/FilePathAutoRename.h b/CPP/7zip/Common/FilePathAutoRename.h
index 3ef87f48..eee0aba7 100755
--- a/CPP/7zip/Common/FilePathAutoRename.h
+++ b/CPP/7zip/Common/FilePathAutoRename.h
@@ -1,10 +1,10 @@
-// Util/FilePathAutoRename.h
+// FilePathAutoRename.h
-#ifndef __FILEPATHAUTORENAME_H
-#define __FILEPATHAUTORENAME_H
+#ifndef __FILE_PATH_AUTO_RENAME_H
+#define __FILE_PATH_AUTO_RENAME_H
#include "Common/MyString.h"
-bool AutoRenamePath(UString &fullProcessedPath);
+bool AutoRenamePath(FString &fullProcessedPath);
#endif
diff --git a/CPP/7zip/Common/FileStreams.cpp b/CPP/7zip/Common/FileStreams.cpp
index 426a0d3d..a8be8aa4 100755
--- a/CPP/7zip/Common/FileStreams.cpp
+++ b/CPP/7zip/Common/FileStreams.cpp
@@ -29,34 +29,6 @@ static inline HRESULT ConvertBoolToHRESULT(bool result)
#endif
}
-bool CInFileStream::Open(LPCTSTR fileName)
-{
- return File.Open(fileName);
-}
-
-#ifdef USE_WIN_FILE
-#ifndef _UNICODE
-bool CInFileStream::Open(LPCWSTR fileName)
-{
- return File.Open(fileName);
-}
-#endif
-#endif
-
-bool CInFileStream::OpenShared(LPCTSTR fileName, bool shareForWrite)
-{
- return File.OpenShared(fileName, shareForWrite);
-}
-
-#ifdef USE_WIN_FILE
-#ifndef _UNICODE
-bool CInFileStream::OpenShared(LPCWSTR fileName, bool shareForWrite)
-{
- return File.OpenShared(fileName, shareForWrite);
-}
-#endif
-#endif
-
#ifdef SUPPORT_DEVICE_FILE
static const UInt32 kClusterSize = 1 << 18;
@@ -279,7 +251,7 @@ STDMETHODIMP CInFileStream::Seek(Int64 offset, UInt32 seekOrigin,
#else
- off_t res = File.Seek(offset, seekOrigin);
+ off_t res = File.Seek((off_t)offset, seekOrigin);
if (res == -1)
return E_FAIL;
if (newPosition != NULL)
@@ -343,7 +315,7 @@ STDMETHODIMP COutFileStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPo
#else
- off_t res = File.Seek(offset, seekOrigin);
+ off_t res = File.Seek((off_t)offset, seekOrigin);
if (res == -1)
return E_FAIL;
if (newPosition != NULL)
diff --git a/CPP/7zip/Common/FileStreams.h b/CPP/7zip/Common/FileStreams.h
index 895745d3..bb2b1d41 100755
--- a/CPP/7zip/Common/FileStreams.h
+++ b/CPP/7zip/Common/FileStreams.h
@@ -1,12 +1,14 @@
// FileStreams.h
-#ifndef __FILESTREAMS_H
-#define __FILESTREAMS_H
+#ifndef __FILE_STREAMS_H
+#define __FILE_STREAMS_H
#ifdef _WIN32
#define USE_WIN_FILE
#endif
+#include "../../Common/MyString.h"
+
#ifdef USE_WIN_FILE
#include "../../Windows/FileIO.h"
#else
@@ -41,19 +43,15 @@ public:
CInFileStream();
#endif
- bool Open(LPCTSTR fileName);
- #ifdef USE_WIN_FILE
- #ifndef _UNICODE
- bool Open(LPCWSTR fileName);
- #endif
- #endif
-
- bool OpenShared(LPCTSTR fileName, bool shareForWrite);
- #ifdef USE_WIN_FILE
- #ifndef _UNICODE
- bool OpenShared(LPCWSTR fileName, bool shareForWrite);
- #endif
- #endif
+ bool Open(CFSTR fileName)
+ {
+ return File.Open(fileName);
+ }
+
+ bool OpenShared(CFSTR fileName, bool shareForWrite)
+ {
+ return File.OpenShared(fileName, shareForWrite);
+ }
MY_UNKNOWN_IMP2(IInStream, IStreamGetSize)
@@ -78,37 +76,23 @@ class COutFileStream:
public IOutStream,
public CMyUnknownImp
{
+public:
#ifdef USE_WIN_FILE
NWindows::NFile::NIO::COutFile File;
#else
NC::NFile::NIO::COutFile File;
#endif
-public:
virtual ~COutFileStream() {}
- bool Create(LPCTSTR fileName, bool createAlways)
+ bool Create(CFSTR fileName, bool createAlways)
{
ProcessedSize = 0;
return File.Create(fileName, createAlways);
}
- bool Open(LPCTSTR fileName, DWORD creationDisposition)
+ bool Open(CFSTR fileName, DWORD creationDisposition)
{
ProcessedSize = 0;
return File.Open(fileName, creationDisposition);
}
- #ifdef USE_WIN_FILE
- #ifndef _UNICODE
- bool Create(LPCWSTR fileName, bool createAlways)
- {
- ProcessedSize = 0;
- return File.Create(fileName, createAlways);
- }
- bool Open(LPCWSTR fileName, DWORD creationDisposition)
- {
- ProcessedSize = 0;
- return File.Open(fileName, creationDisposition);
- }
- #endif
- #endif
HRESULT Close();
diff --git a/CPP/7zip/Common/InOutTempBuffer.cpp b/CPP/7zip/Common/InOutTempBuffer.cpp
index dfe8b3d3..442374da 100755
--- a/CPP/7zip/Common/InOutTempBuffer.cpp
+++ b/CPP/7zip/Common/InOutTempBuffer.cpp
@@ -13,7 +13,7 @@ using namespace NDirectory;
static const UInt32 kTempBufSize = (1 << 20);
-static LPCTSTR kTempFilePrefixString = TEXT("7zt");
+static CFSTR kTempFilePrefixString = FTEXT("7zt");
CInOutTempBuffer::CInOutTempBuffer(): _buf(NULL) { }
@@ -42,12 +42,7 @@ bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size)
return true;
if (!_tempFileCreated)
{
- CSysString tempDirPath;
- if (!MyGetTempPath(tempDirPath))
- return false;
- if (_tempFile.Create(tempDirPath, kTempFilePrefixString, _tempFileName) == 0)
- return false;
- if (!_outFile.Create(_tempFileName, true))
+ if (!_tempFile.CreateRandomInTempFolder(kTempFilePrefixString, &_outFile))
return false;
_tempFileCreated = true;
}
@@ -91,7 +86,7 @@ HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
if (_tempFileCreated)
{
NIO::CInFile inFile;
- if (!inFile.Open(_tempFileName))
+ if (!inFile.Open(_tempFile.GetPath()))
return E_FAIL;
while (size < _size)
{
diff --git a/CPP/7zip/Common/InOutTempBuffer.h b/CPP/7zip/Common/InOutTempBuffer.h
index 073f95ac..bdf937de 100755
--- a/CPP/7zip/Common/InOutTempBuffer.h
+++ b/CPP/7zip/Common/InOutTempBuffer.h
@@ -5,7 +5,6 @@
#include "../../Common/MyCom.h"
#include "../../Windows/FileDir.h"
-#include "../../Windows/FileIO.h"
#include "../IStream.h"
@@ -15,7 +14,6 @@ class CInOutTempBuffer
NWindows::NFile::NIO::COutFile _outFile;
Byte *_buf;
UInt32 _bufPos;
- CSysString _tempFileName;
bool _tempFileCreated;
UInt64 _size;
UInt32 _crc;
diff --git a/CPP/7zip/Common/MethodId.cpp b/CPP/7zip/Common/MethodId.cpp
index b797b685..1566c97c 100755
--- a/CPP/7zip/Common/MethodId.cpp
+++ b/CPP/7zip/Common/MethodId.cpp
@@ -1,27 +1,3 @@
// MethodId.cpp
#include "StdAfx.h"
-
-#include "MethodId.h"
-#include "../../Common/MyString.h"
-
-static inline wchar_t GetHex(Byte value)
-{
- return (wchar_t)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
-}
-
-UString ConvertMethodIdToString(UInt64 id)
-{
- wchar_t s[32];
- int len = 32;
- s[--len] = 0;
- do
- {
- s[--len] = GetHex((Byte)id & 0xF);
- id >>= 4;
- s[--len] = GetHex((Byte)id & 0xF);
- id >>= 4;
- }
- while (id != 0);
- return s + len;
-}
diff --git a/CPP/7zip/Common/MethodProps.cpp b/CPP/7zip/Common/MethodProps.cpp
index 5836d0f8..e15a3cc8 100755
--- a/CPP/7zip/Common/MethodProps.cpp
+++ b/CPP/7zip/Common/MethodProps.cpp
@@ -2,98 +2,447 @@
#include "StdAfx.h"
-#include "../../Common/MyCom.h"
-
-#include "../ICoder.h"
+#include "../../Common/StringToInt.h"
#include "MethodProps.h"
-static const UInt64 k_LZMA = 0x030101;
-static const UInt64 k_LZMA2 = 0x21;
+using namespace NWindows;
+
+bool StringToBool(const UString &s, bool &res)
+{
+ if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0 || s.Compare(L"+") == 0)
+ {
+ res = true;
+ return true;
+ }
+ if (s.CompareNoCase(L"OFF") == 0 || s.Compare(L"-") == 0)
+ {
+ res = false;
+ return true;
+ }
+ return false;
+}
+
+HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest)
+{
+ switch (prop.vt)
+ {
+ case VT_EMPTY: dest = true; return S_OK;
+ case VT_BOOL: dest = (prop.boolVal != VARIANT_FALSE); return S_OK;
+ case VT_BSTR: return StringToBool(prop.bstrVal, dest) ? S_OK : E_INVALIDARG;
+ }
+ return E_INVALIDARG;
+}
+
+int ParseStringToUInt32(const UString &srcString, UInt32 &number)
+{
+ const wchar_t *start = srcString;
+ const wchar_t *end;
+ UInt64 number64 = ConvertStringToUInt64(start, &end);
+ if (number64 > (UInt32)0xFFFFFFFF)
+ {
+ number = 0;
+ return 0;
+ }
+ number = (UInt32)number64;
+ return (int)(end - start);
+}
+
+HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue)
+{
+ // =VT_UI4
+ // =VT_EMPTY
+ // {stringUInt32}=VT_EMPTY
-HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder)
+ if (prop.vt == VT_UI4)
+ {
+ if (!name.IsEmpty())
+ return E_INVALIDARG;
+ resValue = prop.ulVal;
+ return S_OK;
+ }
+ if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ if (name.IsEmpty())
+ return S_OK;
+ UInt32 v;
+ if (ParseStringToUInt32(name, v) != name.Length())
+ return E_INVALIDARG;
+ resValue = v;
+ return S_OK;
+}
+
+HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads)
{
- bool tryReduce = false;
- UInt32 reducedDictionarySize = 1 << 10;
- if (inSizeForReduce != 0 && (method.Id == k_LZMA || method.Id == k_LZMA2))
+ if (name.IsEmpty())
{
- for (;;)
+ switch (prop.vt)
{
- const UInt32 step = (reducedDictionarySize >> 1);
- if (reducedDictionarySize >= *inSizeForReduce)
- {
- tryReduce = true;
+ case VT_UI4:
+ numThreads = prop.ulVal;
break;
- }
- reducedDictionarySize += step;
- if (reducedDictionarySize >= *inSizeForReduce)
+ default:
{
- tryReduce = true;
+ bool val;
+ RINOK(PROPVARIANT_to_bool(prop, val));
+ numThreads = (val ? defaultNumThreads : 1);
break;
}
- if (reducedDictionarySize >= ((UInt32)3 << 30))
- break;
- reducedDictionarySize += step;
}
+ return S_OK;
+ }
+ if (prop.vt != VT_EMPTY)
+ return E_INVALIDARG;
+ return ParsePropToUInt32(name, prop, numThreads);
+}
+
+static HRESULT StringToDictSize(const UString &srcStringSpec, UInt32 &dicSize)
+{
+ UString srcString = srcStringSpec;
+ srcString.MakeUpper();
+ const wchar_t *start = srcString;
+ const wchar_t *end;
+ UInt64 number = ConvertStringToUInt64(start, &end);
+ int numDigits = (int)(end - start);
+ if (numDigits == 0 || srcString.Length() > numDigits + 1)
+ return E_INVALIDARG;
+ const unsigned kLogDictSizeLimit = 32;
+ if (srcString.Length() == numDigits)
+ {
+ if (number >= kLogDictSizeLimit)
+ return E_INVALIDARG;
+ dicSize = (UInt32)1 << (int)number;
+ return S_OK;
+ }
+ unsigned numBits;
+ switch (srcString[numDigits])
+ {
+ case 'B': numBits = 0; break;
+ case 'K': numBits = 10; break;
+ case 'M': numBits = 20; break;
+ case 'G': numBits = 30; break;
+ default: return E_INVALIDARG;
+ }
+ if (number >= ((UInt64)1 << (kLogDictSizeLimit - numBits)))
+ return E_INVALIDARG;
+ dicSize = (UInt32)number << numBits;
+ return S_OK;
+}
+
+static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, UInt32 &resValue)
+{
+ if (prop.vt == VT_UI4)
+ {
+ UInt32 v = prop.ulVal;
+ if (v >= 32)
+ return E_INVALIDARG;
+ resValue = (UInt32)1 << v;
+ return S_OK;
+ }
+ if (prop.vt == VT_BSTR)
+ return StringToDictSize(prop.bstrVal, resValue);
+ return E_INVALIDARG;
+}
+
+void CProps::AddProp32(PROPID propid, UInt32 level)
+{
+ CProp prop;
+ prop.IsOptional = true;
+ prop.Id = propid;
+ prop.Value = (UInt32)level;
+ Props.Add(prop);
+}
+
+class CCoderProps
+{
+ PROPID *_propIDs;
+ NCOM::CPropVariant *_props;
+ unsigned _numProps;
+ unsigned _numPropsMax;
+public:
+ CCoderProps(unsigned numPropsMax)
+ {
+ _numPropsMax = numPropsMax;
+ _numProps = 0;
+ _propIDs = new PROPID[numPropsMax];
+ _props = new NCOM::CPropVariant[numPropsMax];
+ }
+ ~CCoderProps()
+ {
+ delete []_propIDs;
+ delete []_props;
+ }
+ void AddProp(const CProp &prop);
+ HRESULT SetProps(ICompressSetCoderProperties *setCoderProperties)
+ {
+ return setCoderProperties->SetCoderProperties(_propIDs, _props, _numProps);
+ }
+};
+
+void CCoderProps::AddProp(const CProp &prop)
+{
+ if (_numProps >= _numPropsMax)
+ throw 1;
+ _propIDs[_numProps] = prop.Id;
+ _props[_numProps] = prop.Value;
+ _numProps++;
+}
+
+HRESULT CProps::SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const
+{
+ CCoderProps coderProps(Props.Size() + (dataSizeReduce ? 1 : 0));
+ for (int i = 0; i < Props.Size(); i++)
+ coderProps.AddProp(Props[i]);
+ if (dataSizeReduce)
+ {
+ CProp prop;
+ prop.Id = NCoderPropID::kReduceSize;
+ prop.Value = *dataSizeReduce;
+ coderProps.AddProp(prop);
+ }
+ return coderProps.SetProps(scp);
+}
+
+
+int CMethodProps::FindProp(PROPID id) const
+{
+ for (int i = Props.Size() - 1; i >= 0; i--)
+ if (Props[i].Id == id)
+ return i;
+ return -1;
+}
+
+int CMethodProps::GetLevel() const
+{
+ int i = FindProp(NCoderPropID::kLevel);
+ if (i < 0)
+ return 5;
+ if (Props[i].Value.vt != VT_UI4)
+ return 9;
+ UInt32 level = Props[i].Value.ulVal;
+ return level > 9 ? 9 : (int)level;
+}
+
+struct CNameToPropID
+{
+ VARTYPE VarType;
+ const wchar_t *Name;
+};
+
+static const CNameToPropID g_NameToPropID[] =
+{
+ { VT_UI4, L"" },
+ { VT_UI4, L"d" },
+ { VT_UI4, L"mem" },
+ { VT_UI4, L"o" },
+ { VT_UI4, L"c" },
+ { VT_UI4, L"pb" },
+ { VT_UI4, L"lc" },
+ { VT_UI4, L"lp" },
+ { VT_UI4, L"fb" },
+ { VT_BSTR, L"mf" },
+ { VT_UI4, L"mc" },
+ { VT_UI4, L"pass" },
+ { VT_UI4, L"a" },
+ { VT_UI4, L"mt" },
+ { VT_BOOL, L"eos" },
+ { VT_UI4, L"x" },
+ { VT_UI4, L"reduceSize" }
+};
+
+static int FindPropIdExact(const UString &name)
+{
+ for (unsigned i = 0; i < sizeof(g_NameToPropID) / sizeof(g_NameToPropID[0]); i++)
+ if (name.CompareNoCase(g_NameToPropID[i].Name) == 0)
+ return i;
+ return -1;
+}
+
+static bool ConvertProperty(const PROPVARIANT &srcProp, VARTYPE varType, NCOM::CPropVariant &destProp)
+{
+ if (varType == srcProp.vt)
+ {
+ destProp = srcProp;
+ return true;
+ }
+ if (varType == VT_BOOL)
+ {
+ bool res;
+ if (PROPVARIANT_to_bool(srcProp, res) != S_OK)
+ return false;
+ destProp = res;
+ return true;
+ }
+ if (srcProp.vt == VT_EMPTY)
+ {
+ destProp = srcProp;
+ return true;
+ }
+ return false;
+}
+
+static void SplitParams(const UString &srcString, UStringVector &subStrings)
+{
+ subStrings.Clear();
+ UString s;
+ int len = srcString.Length();
+ if (len == 0)
+ return;
+ for (int i = 0; i < len; i++)
+ {
+ wchar_t c = srcString[i];
+ if (c == L':')
+ {
+ subStrings.Add(s);
+ s.Empty();
+ }
+ else
+ s += c;
}
+ subStrings.Add(s);
+}
+static void SplitParam(const UString &param, UString &name, UString &value)
+{
+ int eqPos = param.Find(L'=');
+ if (eqPos >= 0)
{
- int numProps = method.Props.Size();
- CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
- coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
- if (setCoderProperties == NULL)
+ name = param.Left(eqPos);
+ value = param.Mid(eqPos + 1);
+ return;
+ }
+ int i;
+ for (i = 0; i < param.Length(); i++)
+ {
+ wchar_t c = param[i];
+ if (c >= L'0' && c <= L'9')
+ break;
+ }
+ name = param.Left(i);
+ value = param.Mid(i);
+}
+
+static bool IsLogSizeProp(PROPID propid)
+{
+ switch (propid)
+ {
+ case NCoderPropID::kDictionarySize:
+ case NCoderPropID::kUsedMemorySize:
+ case NCoderPropID::kBlockSize:
+ case NCoderPropID::kReduceSize:
+ return true;
+ }
+ return false;
+}
+
+HRESULT CMethodProps::SetParam(const UString &name, const UString &value)
+{
+ int index = FindPropIdExact(name);
+ if (index < 0)
+ return E_INVALIDARG;
+ const CNameToPropID &nameToPropID = g_NameToPropID[index];
+ CProp prop;
+ prop.Id = index;
+
+ if (IsLogSizeProp(prop.Id))
+ {
+ UInt32 dicSize;
+ RINOK(StringToDictSize(value, dicSize));
+ prop.Value = dicSize;
+ }
+ else
+ {
+ NCOM::CPropVariant propValue;
+ if (nameToPropID.VarType == VT_BSTR)
+ propValue = value;
+ else if (nameToPropID.VarType == VT_BOOL)
{
- if (numProps != 0)
+ bool res;
+ if (!StringToBool(value, res))
return E_INVALIDARG;
+ propValue = res;
}
- else
+ else if (!value.IsEmpty())
{
- CRecordVector<PROPID> propIDs;
- NWindows::NCOM::CPropVariant *values = new NWindows::NCOM::CPropVariant[numProps];
- HRESULT res = S_OK;
- try
- {
- for (int i = 0; i < numProps; i++)
- {
- const CProp &prop = method.Props[i];
- propIDs.Add(prop.Id);
- NWindows::NCOM::CPropVariant &value = values[i];
- value = prop.Value;
- // if (tryReduce && prop.Id == NCoderPropID::kDictionarySize && value.vt == VT_UI4 && reducedDictionarySize < value.ulVal)
- if (tryReduce)
- if (prop.Id == NCoderPropID::kDictionarySize)
- if (value.vt == VT_UI4)
- if (reducedDictionarySize < value.ulVal)
- value.ulVal = reducedDictionarySize;
- }
- CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
- coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties);
- res = setCoderProperties->SetCoderProperties(&propIDs.Front(), values, numProps);
- }
- catch(...)
- {
- delete []values;
- throw;
- }
- delete []values;
- RINOK(res);
+ UInt32 number;
+ if (ParseStringToUInt32(value, number) == value.Length())
+ propValue = number;
+ else
+ propValue = value;
}
+ if (!ConvertProperty(propValue, nameToPropID.VarType, prop.Value))
+ return E_INVALIDARG;
+ }
+ Props.Add(prop);
+ return S_OK;
+}
+
+HRESULT CMethodProps::ParseParamsFromString(const UString &srcString)
+{
+ UStringVector params;
+ SplitParams(srcString, params);
+ for (int i = 0; i < params.Size(); i++)
+ {
+ const UString &param = params[i];
+ UString name, value;
+ SplitParam(param, name, value);
+ RINOK(SetParam(name, value));
}
-
- /*
- CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
- coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties);
- if (writeCoderProperties != NULL)
- {
- CSequentialOutStreamImp *outStreamSpec = new CSequentialOutStreamImp;
- CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
- outStreamSpec->Init();
- RINOK(writeCoderProperties->WriteCoderProperties(outStream));
- size_t size = outStreamSpec->GetSize();
- filterProps.SetCapacity(size);
- memmove(filterProps, outStreamSpec->GetBuffer(), size);
- }
- */
return S_OK;
}
+HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value)
+{
+ if (realName.Length() == 0)
+ {
+ // [empty]=method
+ return E_INVALIDARG;
+ }
+ if (value.vt == VT_EMPTY)
+ {
+ // {realName}=[empty]
+ UString name, value;
+ SplitParam(realName, name, value);
+ return SetParam(name, value);
+ }
+
+ // {realName}=value
+ int index = FindPropIdExact(realName);
+ if (index < 0)
+ return E_INVALIDARG;
+ const CNameToPropID &nameToPropID = g_NameToPropID[index];
+ CProp prop;
+ prop.Id = index;
+
+ if (IsLogSizeProp(prop.Id))
+ {
+ UInt32 dicSize;
+ RINOK(PROPVARIANT_to_DictSize(value, dicSize));
+ prop.Value = dicSize;
+ }
+ else
+ {
+ if (!ConvertProperty(value, nameToPropID.VarType, prop.Value))
+ return E_INVALIDARG;
+ }
+ Props.Add(prop);
+ return S_OK;
+}
+
+HRESULT COneMethodInfo::ParseMethodFromPROPVARIANT(const UString &realName, const PROPVARIANT &value)
+{
+ if (!realName.IsEmpty() && realName.CompareNoCase(L"m") != 0)
+ return ParseParamsFromPROPVARIANT(realName, value);
+ // -m{N}=method
+ if (value.vt != VT_BSTR)
+ return E_INVALIDARG;
+ const UString s = value.bstrVal;
+ int splitPos = s.Find(':');
+ if (splitPos < 0)
+ {
+ MethodName = s;
+ return S_OK;
+ }
+ MethodName = s.Left(splitPos);
+ return ParseParamsFromString(s.Mid(splitPos + 1));
+}
diff --git a/CPP/7zip/Common/MethodProps.h b/CPP/7zip/Common/MethodProps.h
index 8127e21e..0bdddc6b 100755
--- a/CPP/7zip/Common/MethodProps.h
+++ b/CPP/7zip/Common/MethodProps.h
@@ -3,39 +3,182 @@
#ifndef __7Z_METHOD_PROPS_H
#define __7Z_METHOD_PROPS_H
-#include "../../Common/MyVector.h"
+#include "../../Common/MyString.h"
#include "../../Windows/PropVariant.h"
-#include "MethodId.h"
+#include "../ICoder.h"
+
+bool StringToBool(const UString &s, bool &res);
+HRESULT PROPVARIANT_to_bool(const PROPVARIANT &prop, bool &dest);
+int ParseStringToUInt32(const UString &srcString, UInt32 &number);
+HRESULT ParsePropToUInt32(const UString &name, const PROPVARIANT &prop, UInt32 &resValue);
+
+HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads);
struct CProp
{
PROPID Id;
+ bool IsOptional;
NWindows::NCOM::CPropVariant Value;
+ CProp(): IsOptional(false) {}
};
-struct CMethod
+struct CProps
{
- CMethodId Id;
CObjectVector<CProp> Props;
+
+ void Clear() { Props.Clear(); }
+
+ bool AreThereNonOptionalProps() const
+ {
+ for (int i = 0; i < Props.Size(); i++)
+ if (!Props[i].IsOptional)
+ return true;
+ return false;
+ }
+
+ void AddProp32(PROPID propid, UInt32 level);
+
+ void AddPropString(PROPID propid, const wchar_t *s)
+ {
+ CProp prop;
+ prop.IsOptional = true;
+ prop.Id = propid;
+ prop.Value = s;
+ Props.Add(prop);
+ }
+
+ HRESULT SetCoderProps(ICompressSetCoderProperties *scp, const UInt64 *dataSizeReduce) const;
};
-struct CMethodsMode
+class CMethodProps: public CProps
{
- CObjectVector<CMethod> Methods;
- #ifndef _7ZIP_ST
- UInt32 NumThreads;
- #endif
-
- CMethodsMode()
- #ifndef _7ZIP_ST
- : NumThreads(1)
- #endif
- {}
- bool IsEmpty() const { return Methods.IsEmpty() ; }
+ HRESULT SetParam(const UString &name, const UString &value);
+public:
+ int GetLevel() const;
+ int Get_NumThreads() const
+ {
+ int i = FindProp(NCoderPropID::kNumThreads);
+ if (i >= 0)
+ if (Props[i].Value.vt == VT_UI4)
+ return (int)Props[i].Value.ulVal;
+ return -1;
+ }
+
+ bool Get_DicSize(UInt32 &res) const
+ {
+ res = 0;
+ int i = FindProp(NCoderPropID::kDictionarySize);
+ if (i >= 0)
+ if (Props[i].Value.vt == VT_UI4)
+ {
+ res = Props[i].Value.ulVal;
+ return true;
+ }
+ return false;
+ }
+
+ int FindProp(PROPID id) const;
+
+ UInt32 Get_Lzma_Algo() const
+ {
+ int i = FindProp(NCoderPropID::kAlgorithm);
+ if (i >= 0)
+ if (Props[i].Value.vt == VT_UI4)
+ return Props[i].Value.ulVal;
+ return GetLevel() >= 5 ? 1 : 0;
+ }
+
+ UInt32 Get_Lzma_DicSize() const
+ {
+ int i = FindProp(NCoderPropID::kDictionarySize);
+ if (i >= 0)
+ if (Props[i].Value.vt == VT_UI4)
+ return Props[i].Value.ulVal;
+ int level = GetLevel();
+ return level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26));
+ }
+
+ UInt32 Get_Lzma_NumThreads(bool &fixedNumber) const
+ {
+ fixedNumber = false;
+ int numThreads = Get_NumThreads();
+ if (numThreads >= 0)
+ {
+ fixedNumber = true;
+ return numThreads < 2 ? 1 : 2;
+ }
+ return Get_Lzma_Algo() == 0 ? 1 : 2;
+ }
+
+ UInt32 Get_BZip2_NumThreads(bool &fixedNumber) const
+ {
+ fixedNumber = false;
+ int numThreads = Get_NumThreads();
+ if (numThreads >= 0)
+ {
+ fixedNumber = true;
+ if (numThreads < 1) return 1;
+ if (numThreads > 64) return 64;
+ return numThreads;
+ }
+ return 1;
+ }
+
+ UInt32 Get_BZip2_BlockSize() const
+ {
+ int i = FindProp(NCoderPropID::kDictionarySize);
+ if (i >= 0)
+ if (Props[i].Value.vt == VT_UI4)
+ {
+ UInt32 blockSize = Props[i].Value.ulVal;
+ const UInt32 kDicSizeMin = 100000;
+ const UInt32 kDicSizeMax = 900000;
+ if (blockSize < kDicSizeMin) blockSize = kDicSizeMin;
+ if (blockSize > kDicSizeMax) blockSize = kDicSizeMax;
+ return blockSize;
+ }
+ int level = GetLevel();
+ return 100000 * (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1));
+ }
+
+ UInt32 Get_Ppmd_MemSize() const
+ {
+ int i = FindProp(NCoderPropID::kUsedMemorySize);
+ if (i >= 0)
+ if (Props[i].Value.vt == VT_UI4)
+ return Props[i].Value.ulVal;
+ int level = GetLevel();
+ return level >= 9 ? (192 << 20) : ((UInt32)1 << (level + 19));
+ }
+
+ void AddLevelProp(UInt32 level)
+ {
+ AddProp32(NCoderPropID::kLevel, level);
+ }
+
+ void AddNumThreadsProp(UInt32 numThreads)
+ {
+ AddProp32(NCoderPropID::kNumThreads, numThreads);
+ }
+
+ HRESULT ParseParamsFromString(const UString &srcString);
+ HRESULT ParseParamsFromPROPVARIANT(const UString &realName, const PROPVARIANT &value);
};
-HRESULT SetMethodProperties(const CMethod &method, const UInt64 *inSizeForReduce, IUnknown *coder);
+class COneMethodInfo: public CMethodProps
+{
+public:
+ UString MethodName;
+
+ void Clear()
+ {
+ CMethodProps::Clear();
+ MethodName.Empty();
+ }
+ bool IsEmpty() const { return MethodName.IsEmpty() && Props.IsEmpty(); }
+ HRESULT ParseMethodFromPROPVARIANT(const UString &realName, const PROPVARIANT &value);
+};
#endif
diff --git a/CPP/7zip/Common/StreamBinder.cpp b/CPP/7zip/Common/StreamBinder.cpp
index 03f88625..7a4c0ed2 100755
--- a/CPP/7zip/Common/StreamBinder.cpp
+++ b/CPP/7zip/Common/StreamBinder.cpp
@@ -2,149 +2,125 @@
#include "StdAfx.h"
-#include "StreamBinder.h"
-#include "../../Common/Defs.h"
#include "../../Common/MyCom.h"
-using namespace NWindows;
-using namespace NSynchronization;
+#include "StreamBinder.h"
-class CSequentialInStreamForBinder:
+class CBinderInStream:
public ISequentialInStream,
public CMyUnknownImp
{
+ CStreamBinder *_binder;
public:
MY_UNKNOWN_IMP
-
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
-private:
- CStreamBinder *m_StreamBinder;
-public:
- ~CSequentialInStreamForBinder() { m_StreamBinder->CloseRead(); }
- void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
+ ~CBinderInStream() { _binder->CloseRead(); }
+ CBinderInStream(CStreamBinder *binder): _binder(binder) {}
};
-STDMETHODIMP CSequentialInStreamForBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
- { return m_StreamBinder->Read(data, size, processedSize); }
+STDMETHODIMP CBinderInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
+ { return _binder->Read(data, size, processedSize); }
-class CSequentialOutStreamForBinder:
+class CBinderOutStream:
public ISequentialOutStream,
public CMyUnknownImp
{
+ CStreamBinder *_binder;
public:
MY_UNKNOWN_IMP
-
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
-
-private:
- CStreamBinder *m_StreamBinder;
-public:
- ~CSequentialOutStreamForBinder() { m_StreamBinder->CloseWrite(); }
- void SetBinder(CStreamBinder *streamBinder) { m_StreamBinder = streamBinder; }
+ ~CBinderOutStream() { _binder->CloseWrite(); }
+ CBinderOutStream(CStreamBinder *binder): _binder(binder) {}
};
-STDMETHODIMP CSequentialOutStreamForBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
- { return m_StreamBinder->Write(data, size, processedSize); }
+STDMETHODIMP CBinderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
+ { return _binder->Write(data, size, processedSize); }
-//////////////////////////
-// CStreamBinder
-// (_thereAreBytesToReadEvent && _bufferSize == 0) means that stream is finished.
-HRes CStreamBinder::CreateEvents()
+WRes CStreamBinder::CreateEvents()
{
- RINOK(_allBytesAreWritenEvent.Create(true));
- RINOK(_thereAreBytesToReadEvent.Create());
- return _readStreamIsClosedEvent.Create();
+ RINOK(_canWrite_Event.Create(true));
+ RINOK(_canRead_Event.Create());
+ return _readingWasClosed_Event.Create();
}
void CStreamBinder::ReInit()
{
- _thereAreBytesToReadEvent.Reset();
- _readStreamIsClosedEvent.Reset();
+ _waitWrite = true;
+ _canRead_Event.Reset();
+ _readingWasClosed_Event.Reset();
ProcessedSize = 0;
}
-
-void CStreamBinder::CreateStreams(ISequentialInStream **inStream,
- ISequentialOutStream **outStream)
+void CStreamBinder::CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream)
{
- CSequentialInStreamForBinder *inStreamSpec = new
- CSequentialInStreamForBinder;
+ _waitWrite = true;
+ _bufSize = 0;
+ _buf = NULL;
+ ProcessedSize = 0;
+
+ CBinderInStream *inStreamSpec = new CBinderInStream(this);
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
- inStreamSpec->SetBinder(this);
*inStream = inStreamLoc.Detach();
- CSequentialOutStreamForBinder *outStreamSpec = new
- CSequentialOutStreamForBinder;
+ CBinderOutStream *outStreamSpec = new CBinderOutStream(this);
CMyComPtr<ISequentialOutStream> outStreamLoc(outStreamSpec);
- outStreamSpec->SetBinder(this);
*outStream = outStreamLoc.Detach();
-
- _buffer = NULL;
- _bufferSize= 0;
- ProcessedSize = 0;
}
+// (_canRead_Event && _bufSize == 0) means that stream is finished.
+
HRESULT CStreamBinder::Read(void *data, UInt32 size, UInt32 *processedSize)
{
- UInt32 sizeToRead = size;
- if (size > 0)
+ if (processedSize)
+ *processedSize = 0;
+ if (size != 0)
{
- RINOK(_thereAreBytesToReadEvent.Lock());
- sizeToRead = MyMin(_bufferSize, size);
- if (_bufferSize > 0)
+ if (_waitWrite)
{
- memcpy(data, _buffer, sizeToRead);
- _buffer = ((const Byte *)_buffer) + sizeToRead;
- _bufferSize -= sizeToRead;
- if (_bufferSize == 0)
+ RINOK(_canRead_Event.Lock());
+ _waitWrite = false;
+ }
+ if (size > _bufSize)
+ size = _bufSize;
+ if (size != 0)
+ {
+ memcpy(data, _buf, size);
+ _buf = ((const Byte *)_buf) + size;
+ ProcessedSize += size;
+ if (processedSize)
+ *processedSize = size;
+ _bufSize -= size;
+ if (_bufSize == 0)
{
- _thereAreBytesToReadEvent.Reset();
- _allBytesAreWritenEvent.Set();
+ _waitWrite = true;
+ _canRead_Event.Reset();
+ _canWrite_Event.Set();
}
}
}
- if (processedSize != NULL)
- *processedSize = sizeToRead;
- ProcessedSize += sizeToRead;
return S_OK;
}
-void CStreamBinder::CloseRead()
-{
- _readStreamIsClosedEvent.Set();
-}
-
HRESULT CStreamBinder::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
- if (size > 0)
+ if (processedSize)
+ *processedSize = 0;
+ if (size != 0)
{
- _buffer = data;
- _bufferSize = size;
- _allBytesAreWritenEvent.Reset();
- _thereAreBytesToReadEvent.Set();
-
- HANDLE events[2];
- events[0] = _allBytesAreWritenEvent;
- events[1] = _readStreamIsClosedEvent;
+ _buf = data;
+ _bufSize = size;
+ _canWrite_Event.Reset();
+ _canRead_Event.Set();
+
+ HANDLE events[2] = { _canWrite_Event, _readingWasClosed_Event };
DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
if (waitResult != WAIT_OBJECT_0 + 0)
- {
- // ReadingWasClosed = true;
return S_FALSE;
- }
- // if(!_allBytesAreWritenEvent.Lock())
- // return E_FAIL;
+ if (processedSize)
+ *processedSize = size;
}
- if (processedSize != NULL)
- *processedSize = size;
return S_OK;
}
-
-void CStreamBinder::CloseWrite()
-{
- // _bufferSize must be = 0
- _thereAreBytesToReadEvent.Set();
-}
diff --git a/CPP/7zip/Common/StreamBinder.h b/CPP/7zip/Common/StreamBinder.h
index 48f68e60..f3fb5322 100755
--- a/CPP/7zip/Common/StreamBinder.h
+++ b/CPP/7zip/Common/StreamBinder.h
@@ -1,32 +1,34 @@
// StreamBinder.h
-#ifndef __STREAMBINDER_H
-#define __STREAMBINDER_H
+#ifndef __STREAM_BINDER_H
+#define __STREAM_BINDER_H
-#include "../IStream.h"
#include "../../Windows/Synchronization.h"
+#include "../IStream.h"
+
class CStreamBinder
{
- NWindows::NSynchronization::CManualResetEvent _allBytesAreWritenEvent;
- NWindows::NSynchronization::CManualResetEvent _thereAreBytesToReadEvent;
- NWindows::NSynchronization::CManualResetEvent _readStreamIsClosedEvent;
- UInt32 _bufferSize;
- const void *_buffer;
+ NWindows::NSynchronization::CManualResetEvent _canWrite_Event;
+ NWindows::NSynchronization::CManualResetEvent _canRead_Event;
+ NWindows::NSynchronization::CManualResetEvent _readingWasClosed_Event;
+ bool _waitWrite;
+ UInt32 _bufSize;
+ const void *_buf;
public:
- // bool ReadingWasClosed;
UInt64 ProcessedSize;
- CStreamBinder() {}
- HRes CreateEvents();
- void CreateStreams(ISequentialInStream **inStream,
- ISequentialOutStream **outStream);
+ WRes CreateEvents();
+ void CreateStreams(ISequentialInStream **inStream, ISequentialOutStream **outStream);
+ void ReInit();
HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
- void CloseRead();
-
HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize);
- void CloseWrite();
- void ReInit();
+ void CloseRead() { _readingWasClosed_Event.Set(); }
+ void CloseWrite()
+ {
+ // _bufSize must be = 0
+ _canRead_Event.Set();
+ }
};
#endif
diff --git a/CPP/7zip/Common/StreamObjects.cpp b/CPP/7zip/Common/StreamObjects.cpp
index 3c86c3ae..1b6b0af0 100755
--- a/CPP/7zip/Common/StreamObjects.cpp
+++ b/CPP/7zip/Common/StreamObjects.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include <stdlib.h>
+
#include "../../../C/Alloc.h"
#include "StreamObjects.h"
@@ -78,7 +80,7 @@ Byte *CDynBufSeqOutStream::GetBufPtrForWriting(size_t addSize)
void CDynBufSeqOutStream::CopyToBuffer(CByteBuffer &dest) const
{
dest.SetCapacity(_size);
- memcpy(dest, _buffer, _size);
+ memcpy(dest, (const Byte *)_buffer, _size);
}
STDMETHODIMP CDynBufSeqOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
diff --git a/CPP/7zip/Common/VirtThread.cpp b/CPP/7zip/Common/VirtThread.cpp
index cf39bd02..77e3c1ac 100755
--- a/CPP/7zip/Common/VirtThread.cpp
+++ b/CPP/7zip/Common/VirtThread.cpp
@@ -10,7 +10,7 @@ static THREAD_FUNC_DECL CoderThread(void *p)
{
CVirtThread *t = (CVirtThread *)p;
t->StartEvent.Lock();
- if (t->ExitEvent)
+ if (t->Exit)
return 0;
t->Execute();
t->FinishedEvent.Set();
@@ -23,7 +23,7 @@ WRes CVirtThread::Create()
RINOK(FinishedEvent.CreateIfNotCreated());
StartEvent.Reset();
FinishedEvent.Reset();
- ExitEvent = false;
+ Exit = false;
if (Thread.IsCreated())
return S_OK;
return Thread.Create(CoderThread, this);
@@ -31,16 +31,18 @@ WRes CVirtThread::Create()
void CVirtThread::Start()
{
- ExitEvent = false;
+ Exit = false;
StartEvent.Set();
}
-CVirtThread::~CVirtThread()
+void CVirtThread::WaitThreadFinish()
{
- ExitEvent = true;
+ Exit = true;
if (StartEvent.IsCreated())
StartEvent.Set();
if (Thread.IsCreated())
+ {
Thread.Wait();
+ Thread.Close();
+ }
}
-
diff --git a/CPP/7zip/Common/VirtThread.h b/CPP/7zip/Common/VirtThread.h
index f14a1f22..ebee158c 100755
--- a/CPP/7zip/Common/VirtThread.h
+++ b/CPP/7zip/Common/VirtThread.h
@@ -1,7 +1,7 @@
// VirtThread.h
-#ifndef __VIRTTHREAD_H
-#define __VIRTTHREAD_H
+#ifndef __VIRT_THREAD_H
+#define __VIRT_THREAD_H
#include "../../Windows/Synchronization.h"
#include "../../Windows/Thread.h"
@@ -11,13 +11,14 @@ struct CVirtThread
NWindows::NSynchronization::CAutoResetEvent StartEvent;
NWindows::NSynchronization::CAutoResetEvent FinishedEvent;
NWindows::CThread Thread;
- bool ExitEvent;
+ bool Exit;
- ~CVirtThread();
+ ~CVirtThread() { WaitThreadFinish(); }
+ void WaitThreadFinish(); // call it in destructor of child class !
WRes Create();
void Start();
- void WaitFinish() { FinishedEvent.Lock(); }
virtual void Execute() = 0;
+ void WaitExecuteFinish() { FinishedEvent.Lock(); }
};
#endif
diff --git a/CPP/7zip/Compress/BZip2Encoder.cpp b/CPP/7zip/Compress/BZip2Encoder.cpp
index eaa10855..6dafc45f 100755
--- a/CPP/7zip/Compress/BZip2Encoder.cpp
+++ b/CPP/7zip/Compress/BZip2Encoder.cpp
@@ -122,11 +122,24 @@ DWORD CThreadInfo::ThreadFunc()
#endif
-CEncoder::CEncoder():
- NumPasses(1),
- m_OptimizeNumTables(false),
- m_BlockSizeMult(kBlockSizeMultMax)
+void CEncProps::Normalize(int level)
{
+ if (level < 0) level = 5;
+ if (level > 9) level = 9;
+ if (NumPasses == (UInt32)(Int32)-1)
+ NumPasses = (level >= 9 ? 7 : (level >= 7 ? 2 : 1));
+ if (NumPasses < kBlockSizeMultMin) NumPasses = kBlockSizeMultMin;
+ if (NumPasses > kBlockSizeMultMax) NumPasses = kBlockSizeMultMax;
+ if (BlockSizeMult == (UInt32)(Int32)-1)
+ BlockSizeMult = (level >= 5 ? 9 : (level >= 1 ? level * 2 - 1: 1));
+ if (BlockSizeMult == 0) BlockSizeMult = 1;
+ if (BlockSizeMult > kNumPassesMax) BlockSizeMult = kNumPassesMax;
+}
+
+CEncoder::CEncoder()
+{
+ _props.Normalize(-1);
+
#ifndef _7ZIP_ST
ThreadsInfo = 0;
m_NumThreadsPrev = 0;
@@ -198,7 +211,7 @@ UInt32 CEncoder::ReadRleBlock(Byte *buffer)
Byte prevByte;
if (m_InStream.ReadByte(prevByte))
{
- UInt32 blockSize = m_BlockSizeMult * kBlockSizeStep - 1;
+ UInt32 blockSize = _props.BlockSizeMult * kBlockSizeStep - 1;
int numReps = 1;
buffer[i++] = prevByte;
while (i < blockSize) // "- 1" to support RLE
@@ -678,7 +691,7 @@ HRESULT CThreadInfo::EncodeBlock3(UInt32 blockSize)
m_NumCrcs = 0;
- EncodeBlock2(m_Block, blockSize, Encoder->NumPasses);
+ EncodeBlock2(m_Block, blockSize, Encoder->_props.NumPasses);
#ifndef _7ZIP_ST
if (Encoder->MtMode)
@@ -738,7 +751,7 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
ti.Encoder = this;
#endif
- ti.m_OptimizeNumTables = m_OptimizeNumTables;
+ ti.m_OptimizeNumTables = _props.DoOptimizeNumTables();
if (!ti.Alloc())
return E_OUTOFMEMORY;
@@ -770,7 +783,7 @@ HRESULT CEncoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
WriteByte(kArSig0);
WriteByte(kArSig1);
WriteByte(kArSig2);
- WriteByte((Byte)(kArSig3 + m_BlockSizeMult));
+ WriteByte((Byte)(kArSig3 + _props.BlockSizeMult));
#ifndef _7ZIP_ST
@@ -832,62 +845,46 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream
catch(...) { return S_FALSE; }
}
-HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
+HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)
{
- for(UInt32 i = 0; i < numProps; i++)
+ int level = -1;
+ CEncProps props;
+ for (UInt32 i = 0; i < numProps; i++)
{
- const PROPVARIANT &prop = props[i];
- switch(propIDs[i])
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ if (propID >= NCoderPropID::kReduceSize)
+ continue;
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 v = (UInt32)prop.ulVal;
+ switch (propID)
{
- case NCoderPropID::kNumPasses:
- {
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- UInt32 numPasses = prop.ulVal;
- if (numPasses == 0)
- numPasses = 1;
- if (numPasses > kNumPassesMax)
- numPasses = kNumPassesMax;
- NumPasses = numPasses;
- m_OptimizeNumTables = (NumPasses > 1);
- break;
- }
- case NCoderPropID::kDictionarySize:
- {
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- UInt32 dictionary = prop.ulVal / kBlockSizeStep;
- if (dictionary < kBlockSizeMultMin)
- dictionary = kBlockSizeMultMin;
- else if (dictionary > kBlockSizeMultMax)
- dictionary = kBlockSizeMultMax;
- m_BlockSizeMult = dictionary;
- break;
- }
+ case NCoderPropID::kNumPasses: props.NumPasses = v; break;
+ case NCoderPropID::kDictionarySize: props.BlockSizeMult = v / kBlockSizeStep; break;
+ case NCoderPropID::kLevel: level = v; break;
case NCoderPropID::kNumThreads:
{
#ifndef _7ZIP_ST
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- NumThreads = prop.ulVal;
- if (NumThreads < 1)
- NumThreads = 1;
+ SetNumberOfThreads(v);
#endif
break;
}
- default:
- return E_INVALIDARG;
+ default: return E_INVALIDARG;
}
}
+ props.Normalize(level);
+ _props = props;
return S_OK;
}
#ifndef _7ZIP_ST
STDMETHODIMP CEncoder::SetNumberOfThreads(UInt32 numThreads)
{
+ const UInt32 kNumThreadsMax = 64;
+ if (numThreads < 1) numThreads = 1;
+ if (numThreads > kNumThreadsMax) numThreads = kNumThreadsMax;
NumThreads = numThreads;
- if (NumThreads < 1)
- NumThreads = 1;
return S_OK;
}
#endif
diff --git a/CPP/7zip/Compress/BZip2Encoder.h b/CPP/7zip/Compress/BZip2Encoder.h
index a863172f..5aa8a786 100755
--- a/CPP/7zip/Compress/BZip2Encoder.h
+++ b/CPP/7zip/Compress/BZip2Encoder.h
@@ -145,6 +145,20 @@ public:
HRESULT EncodeBlock3(UInt32 blockSize);
};
+struct CEncProps
+{
+ UInt32 BlockSizeMult;
+ UInt32 NumPasses;
+
+ CEncProps()
+ {
+ BlockSizeMult = (UInt32)(Int32)-1;
+ NumPasses = (UInt32)(Int32)-1;
+ }
+ void Normalize(int level);
+ bool DoOptimizeNumTables() const { return NumPasses > 1; }
+};
+
class CEncoder :
public ICompressCoder,
public ICompressSetCoderProperties,
@@ -153,17 +167,12 @@ class CEncoder :
#endif
public CMyUnknownImp
{
- UInt32 m_BlockSizeMult;
- bool m_OptimizeNumTables;
-
- UInt32 m_NumPassesPrev;
-
UInt32 m_NumThreadsPrev;
public:
CInBuffer m_InStream;
Byte MtPad[1 << 8]; // It's pad for Multi-Threading. Must be >= Cache_Line_Size.
CBitmEncoder<COutBuffer> m_OutStream;
- UInt32 NumPasses;
+ CEncProps _props;
CBZip2CombinedCrc CombinedCrc;
#ifndef _7ZIP_ST
diff --git a/CPP/7zip/Compress/DeflateEncoder.cpp b/CPP/7zip/Compress/DeflateEncoder.cpp
index 35a81cae..813b6de4 100755
--- a/CPP/7zip/Compress/DeflateEncoder.cpp
+++ b/CPP/7zip/Compress/DeflateEncoder.cpp
@@ -21,12 +21,12 @@ namespace NCompress {
namespace NDeflate {
namespace NEncoder {
-const int kNumDivPassesMax = 10; // [0, 16); ratio/speed/ram tradeoff; use big value for better compression ratio.
-const UInt32 kNumTables = (1 << kNumDivPassesMax);
+static const int kNumDivPassesMax = 10; // [0, 16); ratio/speed/ram tradeoff; use big value for better compression ratio.
+static const UInt32 kNumTables = (1 << kNumDivPassesMax);
-static UInt32 kFixedHuffmanCodeBlockSizeMax = (1 << 8); // [0, (1 << 32)); ratio/speed tradeoff; use big value for better compression ratio.
-static UInt32 kDivideCodeBlockSizeMin = (1 << 7); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio.
-static UInt32 kDivideBlockSizeMin = (1 << 6); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio.
+static const UInt32 kFixedHuffmanCodeBlockSizeMax = (1 << 8); // [0, (1 << 32)); ratio/speed tradeoff; use big value for better compression ratio.
+static const UInt32 kDivideCodeBlockSizeMin = (1 << 7); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio.
+static const UInt32 kDivideBlockSizeMin = (1 << 6); // [1, (1 << 32)); ratio/speed tradeoff; use small value for better compression ratio.
static const UInt32 kMaxUncompressedBlockSize = ((1 << 16) - 1) * 1; // [1, (1 << 32))
static const UInt32 kMatchArraySize = kMaxUncompressedBlockSize * 10; // [kMatchMaxLen * 2, (1 << 32))
@@ -37,9 +37,9 @@ static const UInt32 kBlockUncompressedSizeThreshold = kMaxUncompressedBlockSize
static const int kMaxCodeBitLength = 11;
static const int kMaxLevelBitLength = 7;
-static Byte kNoLiteralStatPrice = 11;
-static Byte kNoLenStatPrice = 11;
-static Byte kNoPosStatPrice = 6;
+static const Byte kNoLiteralStatPrice = 11;
+static const Byte kNoLenStatPrice = 11;
+static const Byte kNoPosStatPrice = 6;
static Byte g_LenSlots[kNumLenSymbolsMax];
static Byte g_FastPos[1 << 9];
@@ -83,21 +83,61 @@ static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
static void SzFree(void *p, void *address) { p = p; MyFree(address); }
static ISzAlloc g_Alloc = { SzAlloc, SzFree };
+void CEncProps::Normalize()
+{
+ int level = Level;
+ if (level < 0) level = 5;
+ Level = level;
+ if (algo < 0) algo = (level < 5 ? 0 : 1);
+ if (fb < 0) fb = (level < 7 ? 32 : (level < 9 ? 64 : 128));
+ if (btMode < 0) btMode = (algo == 0 ? 0 : 1);
+ if (mc == 0) mc = (16 + (fb >> 1));
+ if (numPasses == (UInt32)(Int32)-1) numPasses = (level < 7 ? 1 : (level < 9 ? 3 : 10));
+}
+
+void CCoder::SetProps(const CEncProps *props2)
+{
+ CEncProps props = *props2;
+ props.Normalize();
+
+ m_MatchFinderCycles = props.mc;
+ {
+ unsigned fb = props.fb;
+ if (fb < kMatchMinLen)
+ fb = kMatchMinLen;
+ if (fb > m_MatchMaxLen)
+ fb = m_MatchMaxLen;
+ m_NumFastBytes = fb;
+ }
+ _fastMode = (props.algo == 0);
+ _btMode = (props.btMode != 0);
+
+ m_NumDivPasses = props.numPasses;
+ if (m_NumDivPasses == 0)
+ m_NumDivPasses = 1;
+ if (m_NumDivPasses == 1)
+ m_NumPasses = 1;
+ else if (m_NumDivPasses <= kNumDivPassesMax)
+ m_NumPasses = 2;
+ else
+ {
+ m_NumPasses = 2 + (m_NumDivPasses - kNumDivPassesMax);
+ m_NumDivPasses = kNumDivPassesMax;
+ }
+}
+
CCoder::CCoder(bool deflate64Mode):
m_Deflate64Mode(deflate64Mode),
- m_NumPasses(1),
- m_NumDivPasses(1),
- m_NumFastBytes(32),
- _fastMode(false),
- _btMode(true),
m_OnePosMatchesMemory(0),
m_DistanceMemory(0),
m_Created(false),
m_Values(0),
- m_Tables(0),
- m_MatchFinderCycles(0)
- // m_SetMfPasses(0)
+ m_Tables(0)
{
+ {
+ CEncProps props;
+ SetProps(&props);
+ }
m_MatchMaxLen = deflate64Mode ? kMatchMaxLen64 : kMatchMaxLen32;
m_NumLenCombinations = deflate64Mode ? kNumLenSymbols64 : kNumLenSymbols32;
m_LenStart = deflate64Mode ? kLenStart64 : kLenStart32;
@@ -160,56 +200,30 @@ HRESULT CCoder::Create()
COM_TRY_END
}
-HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
+HRESULT CCoder::BaseSetEncoderProperties2(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)
{
+ CEncProps props;
for (UInt32 i = 0; i < numProps; i++)
{
- const PROPVARIANT &prop = props[i];
- switch(propIDs[i])
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ if (propID >= NCoderPropID::kReduceSize)
+ continue;
+ if (prop.vt != VT_UI4)
+ return E_INVALIDARG;
+ UInt32 v = (UInt32)prop.ulVal;
+ switch (propID)
{
- case NCoderPropID::kNumPasses:
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- m_NumDivPasses = prop.ulVal;
- if (m_NumDivPasses == 0)
- m_NumDivPasses = 1;
- if (m_NumDivPasses == 1)
- m_NumPasses = 1;
- else if (m_NumDivPasses <= kNumDivPassesMax)
- m_NumPasses = 2;
- else
- {
- m_NumPasses = 2 + (m_NumDivPasses - kNumDivPassesMax);
- m_NumDivPasses = kNumDivPassesMax;
- }
- break;
- case NCoderPropID::kNumFastBytes:
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- m_NumFastBytes = prop.ulVal;
- if(m_NumFastBytes < kMatchMinLen || m_NumFastBytes > m_MatchMaxLen)
- return E_INVALIDARG;
- break;
- case NCoderPropID::kMatchFinderCycles:
- {
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- m_MatchFinderCycles = prop.ulVal;
- break;
- }
- case NCoderPropID::kAlgorithm:
- {
- if (prop.vt != VT_UI4)
- return E_INVALIDARG;
- UInt32 maximize = prop.ulVal;
- _fastMode = (maximize == 0);
- _btMode = !_fastMode;
- break;
- }
- default:
- return E_INVALIDARG;
+ case NCoderPropID::kNumPasses: props.numPasses = v; break;
+ case NCoderPropID::kNumFastBytes: props.fb = v; break;
+ case NCoderPropID::kMatchFinderCycles: props.mc = v; break;
+ case NCoderPropID::kAlgorithm: props.algo = v; break;
+ case NCoderPropID::kLevel: props.Level = v; break;
+ case NCoderPropID::kNumThreads: break;
+ default: return E_INVALIDARG;
}
}
+ SetProps(&props);
return S_OK;
}
diff --git a/CPP/7zip/Compress/DeflateEncoder.h b/CPP/7zip/Compress/DeflateEncoder.h
index 71c39e4e..f25d802e 100755
--- a/CPP/7zip/Compress/DeflateEncoder.h
+++ b/CPP/7zip/Compress/DeflateEncoder.h
@@ -52,6 +52,25 @@ typedef struct _CSeqInStream
CMyComPtr<ISequentialInStream> RealStream;
} CSeqInStream;
+struct CEncProps
+{
+ int Level;
+ int algo;
+ int fb;
+ int btMode;
+ UInt32 mc;
+ UInt32 numPasses;
+
+ CEncProps()
+ {
+ Level = -1;
+ mc = 0;
+ algo = fb = btMode = -1;
+ numPasses = (UInt32)(Int32)-1;
+ }
+ void Normalize();
+};
+
class CCoder
{
CMatchFinder _lzInWindow;
@@ -116,7 +135,6 @@ public:
COptimal m_Optimum[kNumOpts];
UInt32 m_MatchFinderCycles;
- // IMatchFinderSetNumPasses *m_SetMfPasses;
void GetMatches();
void MovePos(UInt32 num);
@@ -164,6 +182,7 @@ public:
UInt32 GetBlockPrice(int tableIndex, int numDivPasses);
void CodeBlock(int tableIndex, bool finalBlock);
+ void SetProps(const CEncProps *props2);
public:
CCoder(bool deflate64Mode = false);
~CCoder();
diff --git a/CPP/7zip/Compress/DeltaFilter.cpp b/CPP/7zip/Compress/DeltaFilter.cpp
index 2e421acf..d8378a60 100755
--- a/CPP/7zip/Compress/DeltaFilter.cpp
+++ b/CPP/7zip/Compress/DeltaFilter.cpp
@@ -62,9 +62,22 @@ STDMETHODIMP CDeltaEncoder::SetCoderProperties(const PROPID *propIDs, const PROP
for (UInt32 i = 0; i < numProps; i++)
{
const PROPVARIANT &prop = props[i];
- if (propIDs[i] != NCoderPropID::kDefaultProp || prop.vt != VT_UI4 || prop.ulVal < 1 || prop.ulVal > 256)
+ PROPID propID = propIDs[i];
+ if (propID >= NCoderPropID::kReduceSize)
+ continue;
+ if (prop.vt != VT_UI4)
return E_INVALIDARG;
- delta = prop.ulVal;
+ switch (propID)
+ {
+ case NCoderPropID::kDefaultProp:
+ delta = (UInt32)prop.ulVal;
+ if (delta < 1 || delta > 256)
+ return E_INVALIDARG;
+ break;
+ case NCoderPropID::kNumThreads: break;
+ case NCoderPropID::kLevel: break;
+ default: return E_INVALIDARG;
+ }
}
_delta = delta;
return S_OK;
diff --git a/CPP/7zip/Compress/DllExports2.cpp b/CPP/7zip/Compress/DllExports2.cpp
index 836f3fa4..286ef08b 100755
--- a/CPP/7zip/Compress/DllExports2.cpp
+++ b/CPP/7zip/Compress/DllExports2.cpp
@@ -9,7 +9,13 @@
#include "../Common/RegisterCodec.h"
extern "C"
-BOOL WINAPI DllMain(HINSTANCE /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/)
+BOOL WINAPI DllMain(
+ #ifdef UNDER_CE
+ HANDLE
+ #else
+ HINSTANCE
+ #endif
+ /* hInstance */, DWORD /* dwReason */, LPVOID /*lpReserved*/)
{
return TRUE;
}
@@ -25,4 +31,3 @@ STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
{
return CreateCoder(clsid, iid, outObject);
}
-
diff --git a/CPP/7zip/Compress/LzmaEncoder.cpp b/CPP/7zip/Compress/LzmaEncoder.cpp
index 9bdedaeb..80e12f18 100755
--- a/CPP/7zip/Compress/LzmaEncoder.cpp
+++ b/CPP/7zip/Compress/LzmaEncoder.cpp
@@ -73,6 +73,8 @@ static int ParseMatchFinder(const wchar_t *s, int *btMode, int *numHashBytes)
return 1;
}
+#define SET_PROP_32(_id_, _dest_) case NCoderPropID::_id_: ep._dest_ = v; break;
+
HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep)
{
if (propID == NCoderPropID::kMatchFinder)
@@ -81,18 +83,29 @@ HRESULT SetLzmaProp(PROPID propID, const PROPVARIANT &prop, CLzmaEncProps &ep)
return E_INVALIDARG;
return ParseMatchFinder(prop.bstrVal, &ep.btMode, &ep.numHashBytes) ? S_OK : E_INVALIDARG;
}
+ if (propID > NCoderPropID::kReduceSize)
+ return S_OK;
+ if (propID == NCoderPropID::kReduceSize)
+ {
+ if (prop.vt == VT_UI8 && prop.uhVal.QuadPart < (UInt32)(Int32)-1)
+ ep.reduceSize = (UInt32)prop.uhVal.QuadPart;
+ return S_OK;
+ }
if (prop.vt != VT_UI4)
return E_INVALIDARG;
UInt32 v = prop.ulVal;
switch (propID)
{
- case NCoderPropID::kNumFastBytes: ep.fb = v; break;
- case NCoderPropID::kMatchFinderCycles: ep.mc = v; break;
- case NCoderPropID::kAlgorithm: ep.algo = v; break;
- case NCoderPropID::kDictionarySize: ep.dictSize = v; break;
- case NCoderPropID::kPosStateBits: ep.pb = v; break;
- case NCoderPropID::kLitPosBits: ep.lp = v; break;
- case NCoderPropID::kLitContextBits: ep.lc = v; break;
+ case NCoderPropID::kDefaultProp: if (v > 31) return E_INVALIDARG; ep.dictSize = (UInt32)1 << (unsigned)v; break;
+ SET_PROP_32(kLevel, level)
+ SET_PROP_32(kNumFastBytes, fb)
+ SET_PROP_32(kMatchFinderCycles, mc)
+ SET_PROP_32(kAlgorithm, algo)
+ SET_PROP_32(kDictionarySize, dictSize)
+ SET_PROP_32(kPosStateBits, pb)
+ SET_PROP_32(kLitPosBits, lp)
+ SET_PROP_32(kLitContextBits, lc)
+ SET_PROP_32(kNumThreads, numThreads)
default: return E_INVALIDARG;
}
return S_OK;
@@ -112,8 +125,6 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs,
{
case NCoderPropID::kEndMarker:
if (prop.vt != VT_BOOL) return E_INVALIDARG; props.writeEndMark = (prop.boolVal == VARIANT_TRUE); break;
- case NCoderPropID::kNumThreads:
- if (prop.vt != VT_UI4) return E_INVALIDARG; props.numThreads = prop.ulVal; break;
default:
RINOK(SetLzmaProp(propID, prop, props));
}
diff --git a/CPP/7zip/Compress/LzxDecoder.cpp b/CPP/7zip/Compress/LzxDecoder.cpp
index d1027f1f..924229e9 100755
--- a/CPP/7zip/Compress/LzxDecoder.cpp
+++ b/CPP/7zip/Compress/LzxDecoder.cpp
@@ -360,6 +360,9 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
{
if (outSize == NULL)
return E_FAIL;
+ // flush calls m_x86ConvertOutStreamSpec->flush, so we must init x86Convert.
+ if (!_keepHistory)
+ m_x86ConvertOutStreamSpec->Init(false, 0);
_remainLen = kLenIdNeedInit;
m_OutWindowStream.Init(_keepHistory);
return S_OK;
diff --git a/CPP/7zip/Compress/PpmdEncoder.cpp b/CPP/7zip/Compress/PpmdEncoder.cpp
index d823ffe8..5bf83529 100755
--- a/CPP/7zip/Compress/PpmdEncoder.cpp
+++ b/CPP/7zip/Compress/PpmdEncoder.cpp
@@ -1,5 +1,4 @@
// PpmdEncoder.cpp
-// 2009-03-11 : Igor Pavlov : Public domain
#include "StdAfx.h"
@@ -19,11 +18,35 @@ static void *SzBigAlloc(void *, size_t size) { return BigAlloc(size); }
static void SzBigFree(void *, void *address) { BigFree(address); }
static ISzAlloc g_BigAlloc = { SzBigAlloc, SzBigFree };
+static const Byte kOrders[10] = { 3, 4, 4, 5, 5, 6, 8, 16, 24, 32 };
+
+void CEncProps::Normalize(int level)
+{
+ if (level < 0) level = 5;
+ if (level > 9) level = 9;
+ if (MemSize == (UInt32)(Int32)-1)
+ MemSize = level >= 9 ? ((UInt32)192 << 20) : ((UInt32)1 << (level + 19));
+ const unsigned kMult = 16;
+ if (MemSize / kMult > ReduceSize)
+ {
+ for (unsigned i = 16; i <= 31; i++)
+ {
+ UInt32 m = (UInt32)1 << i;
+ if (ReduceSize <= m / kMult)
+ {
+ if (MemSize > m)
+ MemSize = m;
+ break;
+ }
+ }
+ }
+ if (Order == -1) Order = kOrders[level];
+}
+
CEncoder::CEncoder():
- _inBuf(NULL),
- _usedMemSize(1 << 24),
- _order(6)
+ _inBuf(NULL)
{
+ _props.Normalize(-1);
_rangeEnc.Stream = &_outStream.p;
Ppmd7_Construct(&_ppmd);
}
@@ -34,30 +57,44 @@ CEncoder::~CEncoder()
Ppmd7_Free(&_ppmd, &g_BigAlloc);
}
-STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)
{
+ int level = -1;
+ CEncProps props;
for (UInt32 i = 0; i < numProps; i++)
{
- const PROPVARIANT &prop = props[i];
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ if (propID > NCoderPropID::kReduceSize)
+ continue;
+ if (propID == NCoderPropID::kReduceSize)
+ {
+ if (prop.vt == VT_UI8 && prop.uhVal.QuadPart < (UInt32)(Int32)-1)
+ props.ReduceSize = (UInt32)prop.uhVal.QuadPart;
+ continue;
+ }
if (prop.vt != VT_UI4)
return E_INVALIDARG;
UInt32 v = (UInt32)prop.ulVal;
- switch(propIDs[i])
+ switch (propID)
{
case NCoderPropID::kUsedMemorySize:
if (v < (1 << 16) || v > PPMD7_MAX_MEM_SIZE || (v & 3) != 0)
return E_INVALIDARG;
- _usedMemSize = v;
+ props.MemSize = v;
break;
case NCoderPropID::kOrder:
if (v < 2 || v > 32)
return E_INVALIDARG;
- _order = (Byte)v;
+ props.Order = (Byte)v;
break;
- default:
- return E_INVALIDARG;
+ case NCoderPropID::kNumThreads: break;
+ case NCoderPropID::kLevel: level = (int)v; break;
+ default: return E_INVALIDARG;
}
}
+ props.Normalize(level);
+ _props = props;
return S_OK;
}
@@ -65,8 +102,8 @@ STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
{
const UInt32 kPropSize = 5;
Byte props[kPropSize];
- props[0] = _order;
- SetUi32(props + 1, _usedMemSize);
+ props[0] = (Byte)_props.Order;
+ SetUi32(props + 1, _props.MemSize);
return WriteStream(outStream, props, kPropSize);
}
@@ -81,14 +118,14 @@ HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outS
}
if (!_outStream.Alloc(1 << 20))
return E_OUTOFMEMORY;
- if (!Ppmd7_Alloc(&_ppmd, _usedMemSize, &g_BigAlloc))
+ if (!Ppmd7_Alloc(&_ppmd, _props.MemSize, &g_BigAlloc))
return E_OUTOFMEMORY;
_outStream.Stream = outStream;
_outStream.Init();
Ppmd7z_RangeEnc_Init(&_rangeEnc);
- Ppmd7_Init(&_ppmd, _order);
+ Ppmd7_Init(&_ppmd, _props.Order);
UInt64 processed = 0;
for (;;)
diff --git a/CPP/7zip/Compress/PpmdEncoder.h b/CPP/7zip/Compress/PpmdEncoder.h
index ed8b3713..fb74cf57 100755
--- a/CPP/7zip/Compress/PpmdEncoder.h
+++ b/CPP/7zip/Compress/PpmdEncoder.h
@@ -1,5 +1,4 @@
// PpmdEncoder.h
-// 2009-03-11 : Igor Pavlov : Public domain
#ifndef __COMPRESS_PPMD_ENCODER_H
#define __COMPRESS_PPMD_ENCODER_H
@@ -15,6 +14,21 @@
namespace NCompress {
namespace NPpmd {
+struct CEncProps
+{
+ UInt32 MemSize;
+ UInt32 ReduceSize;
+ int Order;
+
+ CEncProps()
+ {
+ MemSize = (UInt32)(Int32)-1;
+ ReduceSize = (UInt32)(Int32)-1;
+ Order = -1;
+ }
+ void Normalize(int level);
+};
+
class CEncoder :
public ICompressCoder,
public ICompressSetCoderProperties,
@@ -25,20 +39,15 @@ class CEncoder :
CByteOutBufWrap _outStream;
CPpmd7z_RangeEnc _rangeEnc;
CPpmd7 _ppmd;
-
- UInt32 _usedMemSize;
- Byte _order;
-
+ CEncProps _props;
public:
MY_UNKNOWN_IMP2(
ICompressSetCoderProperties,
ICompressWriteCoderProperties)
-
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
-
CEncoder();
~CEncoder();
};
diff --git a/CPP/7zip/Compress/PpmdZip.cpp b/CPP/7zip/Compress/PpmdZip.cpp
index e83d979c..036f3c72 100755
--- a/CPP/7zip/Compress/PpmdZip.cpp
+++ b/CPP/7zip/Compress/PpmdZip.cpp
@@ -1,10 +1,10 @@
// PpmdZip.cpp
-// 2010-03-24 : Igor Pavlov : Public domain
#include "StdAfx.h"
#include "../../../C/CpuArch.h"
+#include "../Common/RegisterCodec.h"
#include "../Common/StreamUtils.h"
#include "PpmdZip.h"
@@ -128,69 +128,109 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
// ---------- Encoder ----------
+void CEncProps::Normalize(int level)
+{
+ if (level < 0) level = 5;
+ if (level == 0) level = 1;
+ if (level > 9) level = 9;
+ if (MemSizeMB == (UInt32)(Int32)-1)
+ MemSizeMB = (1 << ((level > 8 ? 8 : level) - 1));
+ const unsigned kMult = 16;
+ if ((MemSizeMB << 20) / kMult > ReduceSize)
+ {
+ for (UInt32 m = (1 << 20); m <= (1 << 28); m <<= 1)
+ {
+ if (ReduceSize <= m / kMult)
+ {
+ m >>= 20;
+ if (MemSizeMB > m)
+ MemSizeMB = m;
+ break;
+ }
+ }
+ }
+ if (Order == -1) Order = 3 + level;
+ if (Restor == -1)
+ Restor = level < 7 ?
+ PPMD8_RESTORE_METHOD_RESTART :
+ PPMD8_RESTORE_METHOD_CUT_OFF;
+}
+
CEncoder::~CEncoder()
{
Ppmd8_Free(&_ppmd, &g_BigAlloc);
}
-HRESULT CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
+STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *coderProps, UInt32 numProps)
{
+ int level = -1;
+ CEncProps props;
for (UInt32 i = 0; i < numProps; i++)
{
- const PROPVARIANT &prop = props[i];
+ const PROPVARIANT &prop = coderProps[i];
+ PROPID propID = propIDs[i];
+ if (propID > NCoderPropID::kReduceSize)
+ continue;
+ if (propID == NCoderPropID::kReduceSize)
+ {
+ if (prop.vt == VT_UI8 && prop.uhVal.QuadPart < (UInt32)(Int32)-1)
+ props.ReduceSize = (UInt32)prop.uhVal.QuadPart;
+ continue;
+ }
if (prop.vt != VT_UI4)
return E_INVALIDARG;
UInt32 v = (UInt32)prop.ulVal;
- switch(propIDs[i])
+ switch (propID)
{
- case NCoderPropID::kAlgorithm:
- if (v > 1)
- return E_INVALIDARG;
- _restor = v;
- break;
case NCoderPropID::kUsedMemorySize:
if (v < (1 << 20) || v > (1 << 28))
return E_INVALIDARG;
- _usedMemInMB = v >> 20;
+ props.MemSizeMB = v >> 20;
break;
case NCoderPropID::kOrder:
if (v < PPMD8_MIN_ORDER || v > PPMD8_MAX_ORDER)
return E_INVALIDARG;
- _order = (Byte)v;
+ props.Order = (Byte)v;
+ break;
+ case NCoderPropID::kNumThreads: break;
+ case NCoderPropID::kLevel: level = (int)v; break;
+ case NCoderPropID::kAlgorithm:
+ if (v > 1)
+ return E_INVALIDARG;
+ props.Restor = v;
break;
- default:
- return E_INVALIDARG;
+ default: return E_INVALIDARG;
}
}
+ props.Normalize(level);
+ _props = props;
return S_OK;
}
-CEncoder::CEncoder():
- _usedMemInMB(16),
- _order(6),
- _restor(PPMD8_RESTORE_METHOD_RESTART)
+CEncoder::CEncoder()
{
+ _props.Normalize(-1);
_ppmd.Stream.Out = &_outStream.p;
Ppmd8_Construct(&_ppmd);
}
-HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
+STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
{
if (!_inStream.Alloc())
return E_OUTOFMEMORY;
if (!_outStream.Alloc(1 << 20))
return E_OUTOFMEMORY;
- if (!Ppmd8_Alloc(&_ppmd, _usedMemInMB << 20, &g_BigAlloc))
+ if (!Ppmd8_Alloc(&_ppmd, _props.MemSizeMB << 20, &g_BigAlloc))
return E_OUTOFMEMORY;
_outStream.Stream = outStream;
_outStream.Init();
Ppmd8_RangeEnc_Init(&_ppmd);
- Ppmd8_Init(&_ppmd, _order, _restor);
+ Ppmd8_Init(&_ppmd, _props.Order, _props.Restor);
- UInt32 val = (UInt32)((_order - 1) + ((_usedMemInMB - 1) << 4) + (_restor << 12));
+ UInt32 val = (UInt32)((_props.Order - 1) + ((_props.MemSizeMB - 1) << 4) + (_props.Restor << 12));
_outStream.WriteByte((Byte)(val & 0xFF));
_outStream.WriteByte((Byte)(val >> 8));
RINOK(_outStream.Res);
@@ -220,4 +260,14 @@ HRESULT CEncoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outS
}
}
+/*
+static void *CreateCodec() { return (void *)(ICompressCoder *)(new CDecoder(false)); }
+static void *CreateCodecOut() { return (void *)(ICompressCoder *)(new CEncoder); }
+
+static CCodecInfo g_CodecInfo =
+ { CreateCodec, CreateCodecOut, 0x040162, L"PPMdZIP", 1, false };
+
+REGISTER_CODEC(PPMdZIP)
+*/
+
}}
diff --git a/CPP/7zip/Compress/PpmdZip.h b/CPP/7zip/Compress/PpmdZip.h
index c2288b5a..e15a060d 100755
--- a/CPP/7zip/Compress/PpmdZip.h
+++ b/CPP/7zip/Compress/PpmdZip.h
@@ -1,5 +1,4 @@
// PpmdZip.h
-// 2010-03-11 : Igor Pavlov : Public domain
#ifndef __COMPRESS_PPMD_ZIP_H
#define __COMPRESS_PPMD_ZIP_H
@@ -48,21 +47,37 @@ public:
~CDecoder();
};
+struct CEncProps
+{
+ UInt32 MemSizeMB;
+ UInt32 ReduceSize;
+ int Order;
+ int Restor;
+
+ CEncProps()
+ {
+ MemSizeMB = (UInt32)(Int32)-1;
+ ReduceSize = (UInt32)(Int32)-1;
+ Order = -1;
+ Restor = -1;
+ }
+ void Normalize(int level);
+};
+
class CEncoder :
public ICompressCoder,
+ public ICompressSetCoderProperties,
public CMyUnknownImp
{
CByteOutBufWrap _outStream;
CBuf _inStream;
CPpmd8 _ppmd;
- UInt32 _usedMemInMB;
- unsigned _order;
- unsigned _restor;
+ CEncProps _props;
public:
- MY_UNKNOWN_IMP
+ MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
- HRESULT SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
+ STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
CEncoder();
~CEncoder();
};
diff --git a/CPP/7zip/Compress/QuantumDecoder.cpp b/CPP/7zip/Compress/QuantumDecoder.cpp
index 501bd0e1..63da32cc 100755
--- a/CPP/7zip/Compress/QuantumDecoder.cpp
+++ b/CPP/7zip/Compress/QuantumDecoder.cpp
@@ -33,14 +33,6 @@ HRESULT CDecoder::CodeSpec(UInt32 curSize)
{
if (_remainLen == kLenIdNeedInit)
{
- if (!_keepHistory)
- {
- if (!_outWindowStream.Create((UInt32)1 << _numDictBits))
- return E_OUTOFMEMORY;
- Init();
- }
- if (!_rangeDecoder.Create(1 << 20))
- return E_OUTOFMEMORY;
_rangeDecoder.Init();
_remainLen = 0;
}
@@ -169,6 +161,20 @@ STDMETHODIMP CDecoder::SetOutStreamSize(const UInt64 *outSize)
return E_FAIL;
_remainLen = kLenIdNeedInit;
_outWindowStream.Init(_keepHistory);
+ if (!_keepHistory)
+ Init();
+ return S_OK;
+}
+
+HRESULT CDecoder::SetParams(int numDictBits)
+{
+ if (numDictBits > 21)
+ return E_INVALIDARG;
+ _numDictBits = numDictBits;
+ if (!_outWindowStream.Create((UInt32)1 << _numDictBits))
+ return E_OUTOFMEMORY;
+ if (!_rangeDecoder.Create(1 << 20))
+ return E_OUTOFMEMORY;
return S_OK;
}
diff --git a/CPP/7zip/Compress/QuantumDecoder.h b/CPP/7zip/Compress/QuantumDecoder.h
index e9ab023b..a5f78358 100755
--- a/CPP/7zip/Compress/QuantumDecoder.h
+++ b/CPP/7zip/Compress/QuantumDecoder.h
@@ -253,7 +253,7 @@ public:
STDMETHOD(ReleaseInStream)();
STDMETHOD(SetOutStreamSize)(const UInt64 *outSize);
- void SetParams(int numDictBits) { _numDictBits = numDictBits; }
+ HRESULT SetParams(int numDictBits);
void SetKeepHistory(bool keepHistory) { _keepHistory = keepHistory; }
CDecoder(): _keepHistory(false) {}
virtual ~CDecoder() {}
diff --git a/CPP/7zip/Crypto/RandGen.cpp b/CPP/7zip/Crypto/RandGen.cpp
index e0e2e3ab..3a8c9fbd 100755
--- a/CPP/7zip/Crypto/RandGen.cpp
+++ b/CPP/7zip/Crypto/RandGen.cpp
@@ -2,8 +2,8 @@
#include "StdAfx.h"
-#include <stdio.h>
#include "Windows/Synchronization.h"
+
#include "RandGen.h"
#ifndef _WIN32
@@ -25,29 +25,31 @@
// Other generated data blocks depend from previous state
// Maybe it's possible to restore original timer value from generated value.
+#define HASH_UPD(x) Sha256_Update(&hash, (const Byte *)&x, sizeof(x));
+
void CRandomGenerator::Init()
{
- NCrypto::NSha1::CContext hash;
- hash.Init();
+ CSha256 hash;
+ Sha256_Init(&hash);
#ifdef _WIN32
DWORD w = ::GetCurrentProcessId();
- hash.Update((const Byte *)&w, sizeof(w));
+ HASH_UPD(w);
w = ::GetCurrentThreadId();
- hash.Update((const Byte *)&w, sizeof(w));
+ HASH_UPD(w);
#else
pid_t pid = getpid();
- hash.Update((const Byte *)&pid, sizeof(pid));
+ HASH_UPD(pid);
pid = getppid();
- hash.Update((const Byte *)&pid, sizeof(pid));
+ HASH_UPD(pid);
#endif
- for (int i = 0; i < 1000; i++)
+ for (unsigned i = 0; i < 1000; i++)
{
#ifdef _WIN32
LARGE_INTEGER v;
if (::QueryPerformanceCounter(&v))
- hash.Update((const Byte *)&v.QuadPart, sizeof(v.QuadPart));
+ HASH_UPD(v.QuadPart);
#endif
#ifdef USE_POSIX_TIME
@@ -55,50 +57,50 @@ void CRandomGenerator::Init()
timeval v;
if (gettimeofday(&v, 0) == 0)
{
- hash.Update((const Byte *)&v.tv_sec, sizeof(v.tv_sec));
- hash.Update((const Byte *)&v.tv_usec, sizeof(v.tv_usec));
+ HASH_UPD(v.tv_sec);
+ HASH_UPD(v.tv_usec);
}
#endif
time_t v2 = time(NULL);
- hash.Update((const Byte *)&v2, sizeof(v2));
+ HASH_UPD(v2);
#endif
DWORD tickCount = ::GetTickCount();
- hash.Update((const Byte *)&tickCount, sizeof(tickCount));
+ HASH_UPD(tickCount);
- for (int j = 0; j < 100; j++)
+ for (unsigned j = 0; j < 100; j++)
{
- hash.Final(_buff);
- hash.Init();
- hash.Update(_buff, NCrypto::NSha1::kDigestSize);
+ Sha256_Final(&hash, _buff);
+ Sha256_Init(&hash);
+ Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE);
}
}
- hash.Final(_buff);
+ Sha256_Final(&hash, _buff);
_needInit = false;
}
static NWindows::NSynchronization::CCriticalSection g_CriticalSection;
-void CRandomGenerator::Generate(Byte *data, unsigned int size)
+void CRandomGenerator::Generate(Byte *data, unsigned size)
{
g_CriticalSection.Enter();
if (_needInit)
Init();
while (size > 0)
{
- NCrypto::NSha1::CContext hash;
+ CSha256 hash;
- hash.Init();
- hash.Update(_buff, NCrypto::NSha1::kDigestSize);
- hash.Final(_buff);
+ Sha256_Init(&hash);
+ Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE);
+ Sha256_Final(&hash, _buff);
- hash.Init();
+ Sha256_Init(&hash);
UInt32 salt = 0xF672ABD1;
- hash.Update((const Byte *)&salt, sizeof(salt));
- hash.Update(_buff, NCrypto::NSha1::kDigestSize);
- Byte buff[NCrypto::NSha1::kDigestSize];
- hash.Final(buff);
- for (unsigned int i = 0; i < NCrypto::NSha1::kDigestSize && size > 0; i++, size--)
+ HASH_UPD(salt);
+ Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE);
+ Byte buff[SHA256_DIGEST_SIZE];
+ Sha256_Final(&hash, buff);
+ for (unsigned i = 0; i < SHA256_DIGEST_SIZE && size > 0; i++, size--)
*data++ = buff[i];
}
g_CriticalSection.Leave();
diff --git a/CPP/7zip/Crypto/RandGen.h b/CPP/7zip/Crypto/RandGen.h
index 209445c4..cfdcd60d 100755
--- a/CPP/7zip/Crypto/RandGen.h
+++ b/CPP/7zip/Crypto/RandGen.h
@@ -3,11 +3,11 @@
#ifndef __CRYPTO_RAND_GEN_H
#define __CRYPTO_RAND_GEN_H
-#include "Sha1.h"
+#include "../../../C/Sha256.h"
class CRandomGenerator
{
- Byte _buff[NCrypto::NSha1::kDigestSize];
+ Byte _buff[SHA256_DIGEST_SIZE];
bool _needInit;
void Init();
diff --git a/CPP/7zip/Guid.txt b/CPP/7zip/Guid.txt
index 59a743b9..0db316a5 100755
--- a/CPP/7zip/Guid.txt
+++ b/CPP/7zip/Guid.txt
@@ -84,7 +84,7 @@
03 IFolderGetPath
04 IFolderWasChanged
05 // IFolderReload
- 06 IFolderOperations
+ 06 // IFolderOperations old
07 IFolderGetSystemIconIndex
08 IFolderGetItemFullSize
09 IFolderClone
@@ -96,6 +96,7 @@
0F
10 IFolderArcProps
11 IGetFolderArcProps
+ 12 IFolderOperations
09 IFolder.h :: FOLDER_MANAGER_INTERFACE
@@ -128,6 +129,9 @@ Handler GUIDs:
0C xz
0D ppmd
+ CF TE
+ D0 UEFIc
+ D1 UEFIs
D2 SquashFS
D3 CramFS
D4 APM
@@ -150,7 +154,7 @@ Handler GUIDs:
E5 Compound
E6 Wim
E7 Iso
- E8 Bkf
+ E8
E9 Chm
EA Split
EB Rpm
diff --git a/CPP/7zip/ICoder.h b/CPP/7zip/ICoder.h
index a518de46..b43997d4 100755
--- a/CPP/7zip/ICoder.h
+++ b/CPP/7zip/ICoder.h
@@ -44,7 +44,9 @@ namespace NCoderPropID
kNumPasses,
kAlgorithm,
kNumThreads,
- kEndMarker
+ kEndMarker,
+ kLevel,
+ kReduceSize // estimated size of data that will be compressed. Encoder can use this value to reduce dictionary size.
};
}
diff --git a/CPP/7zip/MyVersion.h b/CPP/7zip/MyVersion.h
index eda88db0..b6f541c1 100755
--- a/CPP/7zip/MyVersion.h
+++ b/CPP/7zip/MyVersion.h
@@ -1,8 +1,8 @@
#define MY_VER_MAJOR 9
-#define MY_VER_MINOR 20
-#define MY_VER_BUILD 0
-#define MY_VERSION "9.20"
-#define MY_7ZIP_VERSION "7-Zip 9.20"
-#define MY_DATE "2010-11-18"
-#define MY_COPYRIGHT "Copyright (c) 1999-2010 Igor Pavlov"
+#define MY_VER_MINOR 21
+#define MY_VER_BUILD 00
+#define MY_VERSION "9.21 beta"
+#define MY_7ZIP_VERSION "7-Zip 9.21 beta"
+#define MY_DATE "2011-04-11"
+#define MY_COPYRIGHT "Copyright (c) 1999-2011 Igor Pavlov"
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " " MY_DATE
diff --git a/CPP/7zip/UI/Agent/Agent.cpp b/CPP/7zip/UI/Agent/Agent.cpp
index 4a099308..c11bd490 100755
--- a/CPP/7zip/UI/Agent/Agent.cpp
+++ b/CPP/7zip/UI/Agent/Agent.cpp
@@ -18,7 +18,7 @@ STDMETHODIMP CAgentFolder::GetAgentFolder(CAgentFolder **agentFolder)
return S_OK;
}
-void CAgentFolder::LoadFolder(CProxyFolder *folder)
+void CAgentFolder::LoadFolder(const CProxyFolder *folder)
{
int i;
CProxyItem item;
@@ -56,22 +56,15 @@ STDMETHODIMP CAgentFolder::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
+#define SET_realIndex_AND_folder \
+ UInt32 realIndex; const CProxyFolder *folder; \
+ if (_flatMode) { const CProxyItem &item = _items[index]; folder = item.Folder; realIndex = item.Index; } \
+ else { folder = _proxyFolderItem; realIndex = index; }
+
+
UString CAgentFolder::GetName(UInt32 index) const
{
- UInt32 realIndex;
- const CProxyFolder *folder;
- if (_flatMode)
- {
- const CProxyItem &item = _items[index];
- folder = item.Folder;
- realIndex = item.Index;
- }
- else
- {
- folder = _proxyFolderItem;
- realIndex = index;
- }
-
+ SET_realIndex_AND_folder
if (realIndex < (UInt32)folder->Folders.Size())
return folder->Folders[realIndex].Name;
return folder->Files[realIndex - folder->Folders.Size()].Name;
@@ -97,32 +90,17 @@ UString CAgentFolder::GetFullPathPrefixPlusPrefix(UInt32 index) const
return _proxyFolderItem->GetFullPathPrefix() + GetPrefix(index);
}
-void CAgentFolder::GetPrefixIfAny(UInt32 index, NCOM::CPropVariant &prop) const
-{
- if (!_flatMode)
- return;
- prop = GetPrefix(index);
-}
-
-
-STDMETHODIMP CAgentFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value)
+STDMETHODIMP CAgentFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
+ COM_TRY_BEGIN
NCOM::CPropVariant prop;
- const CProxyFolder *folder;
- UInt32 realIndex;
- if (_flatMode)
+ SET_realIndex_AND_folder
+ if (propID == kpidPrefix)
{
- const CProxyItem &item = _items[itemIndex];
- folder = item.Folder;
- realIndex = item.Index;
+ if (_flatMode)
+ prop = GetPrefix(index);
}
- else
- {
- folder = _proxyFolderItem;
- realIndex = itemIndex;
- }
-
- if (realIndex < (UInt32)folder->Folders.Size())
+ else if (realIndex < (UInt32)folder->Folders.Size())
{
const CProxyFolder &item = folder->Folders[realIndex];
if (!_flatMode && propID == kpidSize)
@@ -130,12 +108,12 @@ STDMETHODIMP CAgentFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARI
else if (!_flatMode && propID == kpidPackSize)
prop = item.PackSize;
else
- switch(propID)
+ switch (propID)
{
- case kpidIsDir: prop = true; break;
+ case kpidIsDir: prop = true; break;
case kpidNumSubDirs: prop = item.NumSubFolders; break;
- case kpidNumSubFiles: prop = item.NumSubFiles; break;
- case kpidName: prop = item.Name; break;
+ case kpidNumSubFiles: prop = item.NumSubFiles; break;
+ case kpidName: prop = item.Name; break;
case kpidCRC:
{
if (item.IsLeaf)
@@ -146,8 +124,6 @@ STDMETHODIMP CAgentFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARI
prop = item.Crc;
break;
}
- case kpidPrefix: GetPrefixIfAny(itemIndex, prop); break;
-
default:
if (item.IsLeaf)
return _agentSpec->GetArchive()->GetProperty(item.Index, propID, value);
@@ -155,22 +131,21 @@ STDMETHODIMP CAgentFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARI
}
else
{
- realIndex -= folder->Folders.Size();
- const CProxyFile &item = folder->Files[realIndex];
- switch(propID)
+ const CProxyFile &item = folder->Files[realIndex - folder->Folders.Size()];
+ switch (propID)
{
case kpidIsDir: prop = false; break;
case kpidName: prop = item.Name; break;
- case kpidPrefix: GetPrefixIfAny(itemIndex, prop); break;
default:
return _agentSpec->GetArchive()->GetProperty(item.Index, propID, value);
}
}
prop.Detach(value);
return S_OK;
+ COM_TRY_END
}
-HRESULT CAgentFolder::BindToFolder(CProxyFolder *folder, IFolderFolder **resultFolder)
+HRESULT CAgentFolder::BindToFolder(const CProxyFolder *folder, IFolderFolder **resultFolder)
{
CMyComPtr<IFolderFolder> parentFolder;
if (folder->Parent != _proxyFolderItem)
@@ -189,20 +164,7 @@ HRESULT CAgentFolder::BindToFolder(CProxyFolder *folder, IFolderFolder **resultF
STDMETHODIMP CAgentFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder)
{
COM_TRY_BEGIN
-
- CProxyFolder *folder;
- UInt32 realIndex;
- if (_flatMode)
- {
- const CProxyItem &item = _items[index];
- folder = item.Folder;
- realIndex = item.Index;
- }
- else
- {
- folder = _proxyFolderItem;
- realIndex = index;
- }
+ SET_realIndex_AND_folder
if (realIndex >= (UInt32)folder->Folders.Size())
return E_INVALIDARG;
return BindToFolder(&folder->Folders[realIndex], resultFolder);
@@ -235,19 +197,7 @@ STDMETHODIMP CAgentFolder::GetStream(UInt32 index, ISequentialInStream **stream)
if (!getStream)
return S_OK;
- const CProxyFolder *folder;
- UInt32 realIndex;
- if (_flatMode)
- {
- const CProxyItem &item = _items[index];
- folder = item.Folder;
- realIndex = item.Index;
- }
- else
- {
- folder = _proxyFolderItem;
- realIndex = index;
- }
+ SET_realIndex_AND_folder
UInt32 indexInArchive;
if (realIndex < (UInt32)folder->Folders.Size())
@@ -262,7 +212,7 @@ STDMETHODIMP CAgentFolder::GetStream(UInt32 index, ISequentialInStream **stream)
return getStream->GetStream(indexInArchive, stream);
}
-STATPROPSTG kProperties[] =
+static const STATPROPSTG kProperties[] =
{
{ NULL, kpidNumSubDirs, VT_UI4},
{ NULL, kpidNumSubFiles, VT_UI4},
@@ -325,7 +275,7 @@ STDMETHODIMP CAgentFolder::GetPropertyInfo(UInt32 index, BSTR *name, PROPID *pro
COM_TRY_END
}
-STATPROPSTG kFolderProps[] =
+static const STATPROPSTG kFolderProps[] =
{
{ NULL, kpidSize, VT_UI8},
{ NULL, kpidPackSize, VT_UI8},
@@ -340,7 +290,7 @@ STDMETHODIMP CAgentFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
- switch(propID)
+ switch (propID)
{
case kpidSize: prop = _proxyFolderItem->Size; break;
case kpidPackSize: prop = _proxyFolderItem->PackSize; break;
@@ -399,7 +349,7 @@ void CAgentFolder::GetRealIndices(const UInt32 *indices, UInt32 numItems, CUIntV
return;
}
realIndices.Clear();
- for(UInt32 i = 0; i < numItems; i++)
+ for (UInt32 i = 0; i < numItems; i++)
{
const CProxyItem &item = _items[indices[i]];
const CProxyFolder *folder = item.Folder;
@@ -423,13 +373,8 @@ STDMETHODIMP CAgentFolder::Extract(const UInt32 *indices,
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
UStringVector pathParts;
- CProxyFolder *currentProxyFolder = _proxyFolderItem;
- while (currentProxyFolder->Parent)
- {
- pathParts.Insert(0, currentProxyFolder->Name);
- currentProxyFolder = currentProxyFolder->Parent;
- }
-
+ _proxyFolderItem->GetPathParts(pathParts);
+
/*
if (_flatMode)
pathMode = NExtract::NPathMode::kNoPathnames;
@@ -437,10 +382,13 @@ STDMETHODIMP CAgentFolder::Extract(const UInt32 *indices,
extractCallbackSpec->InitForMulti(false, pathMode, overwriteMode);
+ FString pathU;
+ if (path)
+ pathU = us2fs(path);
extractCallbackSpec->Init(NULL, &_agentSpec->GetArc(),
extractCallback2,
false, testMode ? true : false, false,
- (path ? path : L""),
+ path ? pathU : FTEXT(""),
pathParts,
(UInt64)(Int64)-1);
CUIntVector realIndices;
@@ -474,10 +422,10 @@ STDMETHODIMP CAgent::Open(
{
COM_TRY_BEGIN
_archiveFilePath = filePath;
- NFile::NFind::CFileInfoW fi;
+ NFile::NFind::CFileInfo fi;
if (!inStream)
{
- if (!fi.Find(_archiveFilePath))
+ if (!fi.Find(us2fs(_archiveFilePath)))
return ::GetLastError();
if (fi.IsDir())
return E_FAIL;
@@ -571,7 +519,7 @@ STDMETHODIMP CAgent::Extract(
extractCallbackSpec->Init(NULL, &GetArc(),
extractCallback2,
false, testMode ? true : false, false,
- path,
+ us2fs(path),
UStringVector(),
(UInt64)(Int64)-1);
return GetArchive()->Extract(0, (UInt32)(Int32)-1, testMode, extractCallback);
@@ -607,7 +555,7 @@ STDMETHODIMP CAgent::GetArcProp(UInt32 level, PROPID propID, PROPVARIANT *value)
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
CArc &arc = _archiveLink.Arcs[level];
- switch(propID)
+ switch (propID)
{
case kpidType: prop = GetTypeOfArc(arc); break;
case kpidPath: prop = arc.Path; break;
diff --git a/CPP/7zip/UI/Agent/Agent.h b/CPP/7zip/UI/Agent/Agent.h
index 454964bc..cc92b0dd 100755
--- a/CPP/7zip/UI/Agent/Agent.h
+++ b/CPP/7zip/UI/Agent/Agent.h
@@ -27,12 +27,21 @@ DECL_INTERFACE(IArchiveFolderInternal, 0x01, 0xC)
struct CProxyItem
{
- CProxyFolder *Folder;
+ const CProxyFolder *Folder;
UInt32 Index;
};
class CAgent;
+enum AGENT_OP
+{
+ AGENT_OP_Uni,
+ AGENT_OP_Delete,
+ AGENT_OP_CreateFolder,
+ AGENT_OP_Rename,
+ AGENT_OP_CopyFromFile
+};
+
class CAgentFolder:
public IFolderFolder,
public IFolderProperties,
@@ -46,6 +55,7 @@ class CAgentFolder:
#endif
public CMyUnknownImp
{
+ void LoadFolder(const CProxyFolder *folder);
public:
MY_QUERYINTERFACE_BEGIN2(IFolderFolder)
@@ -61,8 +71,7 @@ public:
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
- void LoadFolder(CProxyFolder *folder);
- HRESULT BindToFolder(CProxyFolder *folder, IFolderFolder **resultFolder);
+ HRESULT BindToFolder(const CProxyFolder *folder, IFolderFolder **resultFolder);
void GetRealIndices(const UINT32 *indices, UINT32 numItems, CUIntVector &realIndices) const;
INTERFACE_FolderFolder(;)
@@ -90,8 +99,8 @@ public:
CAgentFolder(): _proxyFolderItem(NULL), _flatMode(0) {}
- void Init(CProxyArchive *proxyHandler,
- CProxyFolder *proxyFolderItem,
+ void Init(const CProxyArchive *proxyHandler,
+ const CProxyFolder *proxyFolderItem,
IFolderFolder *parentFolder,
CAgent *agent)
{
@@ -104,9 +113,7 @@ public:
void GetPathParts(UStringVector &pathParts);
HRESULT CommonUpdateOperation(
- bool deleteOperation,
- bool createFolderOperation,
- bool renameOperation,
+ AGENT_OP operation,
const wchar_t *newItemName,
const NUpdateArchive::CActionSet *actionSet,
const UINT32 *indices, UINT32 numItems,
@@ -116,11 +123,10 @@ public:
UString GetPrefix(UInt32 index) const;
UString GetName(UInt32 index) const;
UString GetFullPathPrefixPlusPrefix(UInt32 index) const;
- void GetPrefixIfAny(UInt32 index, NWindows::NCOM::CPropVariant &propVariant) const;
public:
- CProxyArchive *_proxyArchive;
- CProxyFolder *_proxyFolderItem;
+ const CProxyArchive *_proxyArchive;
+ const CProxyFolder *_proxyFolderItem;
CMyComPtr<IFolderFolder> _parentFolder;
CMyComPtr<IInFolderArchive> _agent;
CAgent *_agentSpec;
@@ -156,21 +162,19 @@ public:
#ifndef EXTRACT_ONLY
INTERFACE_IOutFolderArchive(;)
- HRESULT CommonUpdate(
- const wchar_t *newArchiveName,
- int numUpdateItems,
- IArchiveUpdateCallback *updateCallback);
+ HRESULT CommonUpdate(ISequentialOutStream *outArchiveStream,
+ int numUpdateItems, IArchiveUpdateCallback *updateCallback);
- HRESULT CreateFolder(
- const wchar_t *newArchiveName,
- const wchar_t *folderName,
- IFolderArchiveUpdateCallback *updateCallback100);
+ HRESULT CreateFolder(ISequentialOutStream *outArchiveStream,
+ const wchar_t *folderName, IFolderArchiveUpdateCallback *updateCallback100);
- HRESULT RenameItem(
- const wchar_t *newArchiveName,
- const UINT32 *indices, UINT32 numItems,
- const wchar_t *newItemName,
- IFolderArchiveUpdateCallback *updateCallback100);
+ HRESULT RenameItem(ISequentialOutStream *outArchiveStream,
+ const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName,
+ IFolderArchiveUpdateCallback *updateCallback100);
+
+ HRESULT UpdateOneFile(ISequentialOutStream *outArchiveStream,
+ const UInt32 *indices, UInt32 numItems, const wchar_t *diskFilePath,
+ IFolderArchiveUpdateCallback *updateCallback100);
// ISetProperties
STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties);
@@ -190,8 +194,8 @@ public:
UString ArchiveType;
- UStringVector _names;
- UString _folderPrefix;
+ FStringVector _names;
+ FString _folderPrefix;
UString _archiveNamePrefix;
CAgentFolder *_agentFolder;
@@ -203,8 +207,8 @@ public:
CObjectVector<NWindows::NCOM::CPropVariant> m_PropValues;
#endif
- const CArc &GetArc() { return _archiveLink.Arcs.Back(); }
- IInArchive *GetArchive() { if ( _archiveLink.Arcs.IsEmpty()) return 0; return GetArc().Archive; }
+ const CArc &GetArc() const { return _archiveLink.Arcs.Back(); }
+ IInArchive *GetArchive() const { if ( _archiveLink.Arcs.IsEmpty()) return 0; return GetArc().Archive; }
bool CanUpdate() const { return _archiveLink.Arcs.Size() <= 1; }
UString GetTypeOfArc(const CArc &arc) const { return _codecs->Formats[arc.FormatIndex].Name; }
diff --git a/CPP/7zip/UI/Agent/AgentOut.cpp b/CPP/7zip/UI/Agent/AgentOut.cpp
index 5d9ae62d..17f5443a 100755
--- a/CPP/7zip/UI/Agent/AgentOut.cpp
+++ b/CPP/7zip/UI/Agent/AgentOut.cpp
@@ -2,23 +2,14 @@
#include "StdAfx.h"
-#include "Common/IntToString.h"
-#include "Common/StringConvert.h"
-
#include "Windows/FileDir.h"
-#include "Windows/PropVariant.h"
-#include "Windows/PropVariantConversions.h"
+#include "Windows/FileName.h"
#include "Windows/Time.h"
#include "../../Compress/CopyCoder.h"
#include "../../Common/FileStreams.h"
-#include "../Common/EnumDirItems.h"
-#include "../Common/OpenArchive.h"
-#include "../Common/UpdateCallback.h"
-#include "../Common/UpdatePair.h"
-
#include "Agent.h"
#include "UpdateCallbackAgent.h"
@@ -33,7 +24,7 @@ STDMETHODIMP CAgent::SetFolder(IFolderFolder *folder)
_agentFolder = NULL;
return S_OK;
}
- else
+
{
CMyComPtr<IFolderFolder> archiveFolder = folder;
CMyComPtr<IArchiveFolderInternal> archiveFolderInternal;
@@ -41,40 +32,18 @@ STDMETHODIMP CAgent::SetFolder(IFolderFolder *folder)
RINOK(archiveFolderInternal->GetAgentFolder(&_agentFolder));
}
- UStringVector pathParts;
- pathParts.Clear();
- CMyComPtr<IFolderFolder> folderItem = folder;
- if (folderItem != NULL)
- for (;;)
- {
- CMyComPtr<IFolderFolder> newFolder;
- folderItem->BindToParentFolder(&newFolder);
- if (newFolder == NULL)
- break;
-
- NCOM::CPropVariant prop;
- if (folderItem->GetFolderProperty(kpidName, &prop) == S_OK)
- if (prop.vt == VT_BSTR)
- pathParts.Insert(0, (const wchar_t *)prop.bstrVal);
- folderItem = newFolder;
- }
-
- for (int i = 0; i < pathParts.Size(); i++)
- {
- _archiveNamePrefix += pathParts[i];
- _archiveNamePrefix += WCHAR_PATH_SEPARATOR;
- }
+ _archiveNamePrefix = _agentFolder->_proxyFolderItem->GetFullPathPrefix();
return S_OK;
}
STDMETHODIMP CAgent::SetFiles(const wchar_t *folderPrefix,
const wchar_t **names, UInt32 numNames)
{
- _folderPrefix = folderPrefix;
+ _folderPrefix = us2fs(folderPrefix);
_names.Clear();
_names.Reserve(numNames);
for (UInt32 i = 0; i < numNames; i++)
- _names.Add(names[i]);
+ _names.Add(us2fs(names[i]));
return S_OK;
}
@@ -89,12 +58,7 @@ static HRESULT EnumerateArchiveItems(CAgent *agent,
const CProxyFile &fileItem = item.Files[i];
CArcItem ai;
RINOK(agent->GetArc().GetItemMTime(fileItem.Index, ai.MTime, ai.MTimeDefined));
-
- CPropVariant property;
- agent->GetArchive()->GetProperty(fileItem.Index, kpidSize, &property);
- ai.SizeDefined = (property.vt != VT_EMPTY);
- if (ai.SizeDefined)
- ai.Size = ConvertPropVariantToUInt64(property);
+ RINOK(agent->GetArc().GetItemSize(fileItem.Index, ai.Size, ai.SizeDefined));
ai.IsDir = false;
ai.Name = prefix + fileItem.Name;
ai.Censored = true; // test it
@@ -139,7 +103,7 @@ HRESULT CAgUpCallbackImp::ShowDeleteFile(int arcIndex)
STDMETHODIMP CAgent::DoOperation(
CCodecs *codecs,
int formatIndex,
- const wchar_t *newArchiveName,
+ ISequentialOutStream *outArchiveStream,
const Byte *stateActions,
const wchar_t *sfxModule,
IFolderArchiveUpdateCallback *updateCallback100)
@@ -154,9 +118,9 @@ STDMETHODIMP CAgent::DoOperation(
CDirItems dirItems;
{
- UString folderPrefix = _folderPrefix;
+ FString folderPrefix = _folderPrefix;
NFile::NName::NormalizeDirPathPrefix(folderPrefix);
- UStringVector errorPaths;
+ FStringVector errorPaths;
CRecordVector<DWORD> errorCodes;
dirItems.EnumerateDirItems2(folderPrefix, _archiveNamePrefix, _names, errorPaths, errorCodes);
if (errorCodes.Size() > 0)
@@ -239,22 +203,6 @@ STDMETHODIMP CAgent::DoOperation(
updateCallbackSpec->Archive = GetArchive();
updateCallbackSpec->Callback = &updateCallbackAgent;
- COutFileStream *outStreamSpec = new COutFileStream;
- CMyComPtr<IOutStream> outStream(outStreamSpec);
- UString archiveName = newArchiveName;
- {
- UString resultPath;
- int pos;
- if (!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
- return E_FAIL;
- NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
- }
- if (!outStreamSpec->Create(archiveName, true))
- {
- // ShowLastErrorMessage();
- return E_FAIL;
- }
-
CMyComPtr<ISetProperties> setProperties;
if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK)
{
@@ -268,7 +216,7 @@ STDMETHODIMP CAgent::DoOperation(
for(i = 0; i < m_PropNames.Size(); i++)
names.Add((const wchar_t *)m_PropNames[i]);
- NWindows::NCOM::CPropVariant *propValues = new NWindows::NCOM::CPropVariant[m_PropValues.Size()];
+ CPropVariant *propValues = new CPropVariant[m_PropValues.Size()];
try
{
for (int i = 0; i < m_PropValues.Size(); i++)
@@ -290,88 +238,38 @@ STDMETHODIMP CAgent::DoOperation(
{
CInFileStream *sfxStreamSpec = new CInFileStream;
CMyComPtr<IInStream> sfxStream(sfxStreamSpec);
- if (!sfxStreamSpec->Open(sfxModule))
+ if (!sfxStreamSpec->Open(us2fs(sfxModule)))
return E_FAIL;
// throw "Can't open sfx module";
- RINOK(NCompress::CopyStream(sfxStream, outStream, NULL));
+ RINOK(NCompress::CopyStream(sfxStream, outArchiveStream, NULL));
}
- RINOK(outArchive->UpdateItems(outStream, updatePairs2.Size(),updateCallback));
- return outStreamSpec->Close();
+ return outArchive->UpdateItems(outArchiveStream, updatePairs2.Size(),updateCallback);
}
-STDMETHODIMP CAgent::DoOperation2(
- const wchar_t *newArchiveName,
- const Byte *stateActions,
- const wchar_t *sfxModule,
- IFolderArchiveUpdateCallback *updateCallback100)
+STDMETHODIMP CAgent::DoOperation2(ISequentialOutStream *outArchiveStream,
+ const Byte *stateActions, const wchar_t *sfxModule, IFolderArchiveUpdateCallback *updateCallback100)
{
- return DoOperation(_codecs, -1, newArchiveName,
- stateActions, sfxModule, updateCallback100);
+ return DoOperation(_codecs, -1, outArchiveStream, stateActions, sfxModule, updateCallback100);
}
-HRESULT CAgent::CommonUpdate(
- const wchar_t *newArchiveName,
- int numUpdateItems,
- IArchiveUpdateCallback *updateCallback)
+HRESULT CAgent::CommonUpdate(ISequentialOutStream *outArchiveStream,
+ int numUpdateItems, IArchiveUpdateCallback *updateCallback)
{
if (!CanUpdate())
return E_NOTIMPL;
CMyComPtr<IOutArchive> outArchive;
RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive));
-
- COutFileStream *outStreamSpec = new COutFileStream;
- CMyComPtr<IOutStream> outStream(outStreamSpec);
-
- UString archiveName = newArchiveName;
- {
- UString resultPath;
- int pos;
- if (!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos))
- throw 141716;
- NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
- }
-
- /*
- bool isOK = false;
- for (int i = 0; i < (1 << 16); i++)
- {
- resultName = newArchiveName;
- if (i > 0)
- {
- wchar_t s[16];
- ConvertUInt32ToString(i, s);
- resultName += s;
- }
- if (outStreamSpec->Open(realPath))
- {
- isOK = true;
- break;
- }
- if (::GetLastError() != ERROR_FILE_EXISTS)
- return ::GetLastError();
- }
- if (!isOK)
- return ::GetLastError();
- */
- if (!outStreamSpec->Create(archiveName, true))
- {
- // ShowLastErrorMessage();
- return E_FAIL;
- }
-
- RINOK(outArchive->UpdateItems(outStream, numUpdateItems, updateCallback));
- return outStreamSpec->Close();
+ return outArchive->UpdateItems(outArchiveStream, numUpdateItems, updateCallback);
}
-
-STDMETHODIMP CAgent::DeleteItems(
- const wchar_t *newArchiveName,
+STDMETHODIMP CAgent::DeleteItems(ISequentialOutStream *outArchiveStream,
const UInt32 *indices, UInt32 numItems,
IFolderArchiveUpdateCallback *updateCallback100)
{
if (!CanUpdate())
return E_NOTIMPL;
+ CRecordVector<CUpdatePair2> updatePairs;
CUpdateCallbackAgent updateCallbackAgent;
updateCallbackAgent.SetCallback(updateCallback100);
CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
@@ -379,7 +277,6 @@ STDMETHODIMP CAgent::DeleteItems(
CUIntVector realIndices;
_agentFolder->GetRealIndices(indices, numItems, realIndices);
- CRecordVector<CUpdatePair2> updatePairs;
int curIndex = 0;
UInt32 numItemsInArchive;
RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
@@ -400,22 +297,21 @@ STDMETHODIMP CAgent::DeleteItems(
updateCallbackSpec->UpdatePairs = &updatePairs;
updateCallbackSpec->Archive = GetArchive();
updateCallbackSpec->Callback = &updateCallbackAgent;
- return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback);
+ return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback);
}
-HRESULT CAgent::CreateFolder(
- const wchar_t *newArchiveName,
- const wchar_t *folderName,
- IFolderArchiveUpdateCallback *updateCallback100)
+HRESULT CAgent::CreateFolder(ISequentialOutStream *outArchiveStream,
+ const wchar_t *folderName, IFolderArchiveUpdateCallback *updateCallback100)
{
if (!CanUpdate())
return E_NOTIMPL;
+ CRecordVector<CUpdatePair2> updatePairs;
+ CDirItems dirItems;
CUpdateCallbackAgent updateCallbackAgent;
updateCallbackAgent.SetCallback(updateCallback100);
CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
- CRecordVector<CUpdatePair2> updatePairs;
UInt32 numItemsInArchive;
RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
for (UInt32 i = 0; i < numItemsInArchive; i++)
@@ -435,7 +331,6 @@ HRESULT CAgent::CreateFolder(
updatePairs.ReserveDown();
- CDirItems dirItems;
CDirItem di;
di.Attrib = FILE_ATTRIBUTE_DIRECTORY;
@@ -452,20 +347,19 @@ HRESULT CAgent::CreateFolder(
updateCallbackSpec->DirItems = &dirItems;
updateCallbackSpec->UpdatePairs = &updatePairs;
updateCallbackSpec->Archive = GetArchive();
- return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback);
+ return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback);
}
-HRESULT CAgent::RenameItem(
- const wchar_t *newArchiveName,
- const UInt32 *indices, UInt32 numItems,
- const wchar_t *newItemName,
+HRESULT CAgent::RenameItem(ISequentialOutStream *outArchiveStream,
+ const UInt32 *indices, UInt32 numItems, const wchar_t *newItemName,
IFolderArchiveUpdateCallback *updateCallback100)
{
if (!CanUpdate())
return E_NOTIMPL;
if (numItems != 1)
return E_INVALIDARG;
+ CRecordVector<CUpdatePair2> updatePairs;
CUpdateCallbackAgent updateCallbackAgent;
updateCallbackAgent.SetCallback(updateCallback100);
CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
@@ -478,7 +372,6 @@ HRESULT CAgent::RenameItem(
UString oldItemPath = fullPrefix + _agentFolder->GetName(indices[0]);
UString newItemPath = fullPrefix + newItemName;
- CRecordVector<CUpdatePair2> updatePairs;
UStringVector newNames;
int curIndex = 0;
@@ -516,7 +409,64 @@ HRESULT CAgent::RenameItem(
updateCallbackSpec->UpdatePairs = &updatePairs;
updateCallbackSpec->NewNames = &newNames;
updateCallbackSpec->Archive = GetArchive();
- return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback);
+ return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback);
+}
+
+HRESULT CAgent::UpdateOneFile(ISequentialOutStream *outArchiveStream,
+ const UInt32 *indices, UInt32 numItems, const wchar_t *diskFilePath,
+ IFolderArchiveUpdateCallback *updateCallback100)
+{
+ if (!CanUpdate())
+ return E_NOTIMPL;
+ CRecordVector<CUpdatePair2> updatePairs;
+ CDirItems dirItems;
+ CUpdateCallbackAgent updateCallbackAgent;
+ updateCallbackAgent.SetCallback(updateCallback100);
+ CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
+ CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
+
+ UInt32 realIndex;
+ {
+ CUIntVector realIndices;
+ _agentFolder->GetRealIndices(indices, numItems, realIndices);
+ if (realIndices.Size() != 1)
+ return E_FAIL;
+ realIndex = realIndices[0];
+ }
+
+ {
+ FStringVector filePaths;
+ filePaths.Add(us2fs(diskFilePath));
+ FStringVector errorPaths;
+ CRecordVector<DWORD> errorCodes;
+ dirItems.EnumerateDirItems2(FString(), UString(), filePaths, errorPaths, errorCodes);
+ if (dirItems.Items.Size() != 1)
+ return E_FAIL;
+ }
+
+ UInt32 numItemsInArchive;
+ RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive));
+ for (UInt32 i = 0; i < numItemsInArchive; i++)
+ {
+ CUpdatePair2 up2;
+ up2.ArcIndex = i;
+ up2.IsAnti = false;
+ up2.NewData = false;
+ up2.NewProps = false;
+ if (realIndex == i)
+ {
+ up2.DirIndex = 0;
+ up2.NewData = true;
+ up2.NewProps = true;
+ }
+ updatePairs.Add(up2);
+ }
+ updateCallbackSpec->DirItems = &dirItems;
+ updateCallbackSpec->Callback = &updateCallbackAgent;
+ updateCallbackSpec->UpdatePairs = &updatePairs;
+ updateCallbackSpec->Archive = GetArchive();
+ updateCallbackSpec->KeepOriginalItemNames = true;
+ return CommonUpdate(outArchiveStream, updatePairs.Size(), updateCallback);
}
STDMETHODIMP CAgent::SetProperties(const wchar_t **names,
diff --git a/CPP/7zip/UI/Agent/AgentProxy.cpp b/CPP/7zip/UI/Agent/AgentProxy.cpp
index 9686cf34..ce9b3bfb 100755
--- a/CPP/7zip/UI/Agent/AgentProxy.cpp
+++ b/CPP/7zip/UI/Agent/AgentProxy.cpp
@@ -7,8 +7,6 @@
#include "Windows/PropVariant.h"
#include "Windows/PropVariantConversions.h"
-#include "../Common/OpenArchive.h"
-
#include "AgentProxy.h"
using namespace NWindows;
@@ -79,11 +77,10 @@ void CProxyFolder::Clear()
void CProxyFolder::GetPathParts(UStringVector &pathParts) const
{
pathParts.Clear();
- UString result;
const CProxyFolder *current = this;
while (current->Parent != NULL)
{
- pathParts.Insert(0, (const wchar_t *)current->Name);
+ pathParts.Insert(0, current->Name);
current = current->Parent;
}
}
@@ -100,13 +97,6 @@ UString CProxyFolder::GetFullPathPrefix() const
return result;
}
-UString CProxyFolder::GetItemName(UInt32 index) const
-{
- if (index < (UInt32)Folders.Size())
- return Folders[index].Name;
- return Files[index - Folders.Size()].Name;
-}
-
void CProxyFolder::AddRealIndices(CUIntVector &realIndices) const
{
if (IsLeaf)
diff --git a/CPP/7zip/UI/Agent/AgentProxy.h b/CPP/7zip/UI/Agent/AgentProxy.h
index d4caca16..dcf52f04 100755
--- a/CPP/7zip/UI/Agent/AgentProxy.h
+++ b/CPP/7zip/UI/Agent/AgentProxy.h
@@ -3,8 +3,6 @@
#ifndef __AGENT_PROXY_H
#define __AGENT_PROXY_H
-#include "Common/MyString.h"
-
#include "../Common/OpenArchive.h"
struct CProxyFile
@@ -13,8 +11,11 @@ struct CProxyFile
UString Name;
};
-struct CProxyFolder: public CProxyFile
+class CProxyFolder: public CProxyFile
{
+ int FindDirSubItemIndex(const UString &name, int &insertPos) const;
+ void AddRealIndices(CUIntVector &realIndices) const;
+public:
CProxyFolder *Parent;
CObjectVector<CProxyFolder> Folders;
CObjectVector<CProxyFile> Files;
@@ -28,7 +29,6 @@ struct CProxyFolder: public CProxyFile
UInt32 NumSubFiles;
CProxyFolder(): Parent(NULL) {};
- int FindDirSubItemIndex(const UString &name, int &insertPos) const;
int FindDirSubItemIndex(const UString &name) const;
CProxyFolder* AddDirSubItem(UInt32 index, bool leaf, const UString &name);
void AddFileSubItem(UInt32 index, const UString &name);
@@ -36,8 +36,6 @@ struct CProxyFolder: public CProxyFile
void GetPathParts(UStringVector &pathParts) const;
UString GetFullPathPrefix() const;
- UString GetItemName(UInt32 index) const;
- void AddRealIndices(CUIntVector &realIndices) const;
void GetRealIndices(const UInt32 *indices, UInt32 numItems, CUIntVector &realIndices) const;
void CalculateSizes(IInArchive *archive);
};
diff --git a/CPP/7zip/UI/Agent/ArchiveFolder.cpp b/CPP/7zip/UI/Agent/ArchiveFolder.cpp
index 57975e7d..237afa05 100755
--- a/CPP/7zip/UI/Agent/ArchiveFolder.cpp
+++ b/CPP/7zip/UI/Agent/ArchiveFolder.cpp
@@ -8,46 +8,20 @@
#include "Agent.h"
-using namespace NWindows;
-using namespace NCOM;
-
STDMETHODIMP CAgentFolder::CopyTo(const UInt32 *indices, UInt32 numItems,
const wchar_t *path, IFolderOperationsExtractCallback *callback)
{
COM_TRY_BEGIN
- CArchiveExtractCallback *extractCallbackSpec = new
- CArchiveExtractCallback;
- CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
- UStringVector pathParts;
- CProxyFolder *currentProxyFolder = _proxyFolderItem;
- while (currentProxyFolder->Parent)
- {
- pathParts.Insert(0, currentProxyFolder->Name);
- currentProxyFolder = currentProxyFolder->Parent;
- }
-
CMyComPtr<IFolderArchiveExtractCallback> extractCallback2;
{
CMyComPtr<IFolderOperationsExtractCallback> callbackWrap = callback;
- RINOK(callbackWrap.QueryInterface(
- IID_IFolderArchiveExtractCallback, &extractCallback2));
+ RINOK(callbackWrap.QueryInterface(IID_IFolderArchiveExtractCallback, &extractCallback2));
}
-
NExtract::NPathMode::EEnum pathMode = _flatMode ?
NExtract::NPathMode::kNoPathnames :
NExtract::NPathMode::kCurrentPathnames;
-
- extractCallbackSpec->InitForMulti(false, pathMode, NExtract::NOverwriteMode::kAskBefore);
- extractCallbackSpec->Init(NULL, &_agentSpec->GetArc(),
- extractCallback2,
- false, false, false,
- path,
- pathParts,
- (UInt64)(Int64)-1);
- CUIntVector realIndices;
- GetRealIndices(indices, numItems, realIndices);
- return _agentSpec->GetArchive()->Extract(&realIndices.Front(),
- realIndices.Size(), BoolToInt(false), extractCallback);
+ return Extract(indices,numItems, pathMode, NExtract::NOverwriteMode::kAskBefore,
+ path, BoolToInt(false), extractCallback2);
COM_TRY_END
}
@@ -56,4 +30,3 @@ STDMETHODIMP CAgentFolder::MoveTo(const UInt32 * /* indices */, UInt32 /* numIte
{
return E_NOTIMPL;
}
-
diff --git a/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp b/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp
index 477e052c..3a16a667 100755
--- a/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp
+++ b/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp
@@ -1,22 +1,9 @@
-// Zip/ArchiveFolder.cpp
+// Agent/ArchiveFolderOpen.cpp
#include "StdAfx.h"
#include "Agent.h"
-#include "Common/StringConvert.h"
-
-extern HINSTANCE g_hInstance;
-
-static inline UINT GetCurrentFileCodePage()
-{
- #ifdef UNDER_CE
- return CP_ACP;
- #else
- return AreFileApisANSI() ? CP_ACP : CP_OEMCP;
- #endif
-}
-
void CArchiveFolderManager::LoadFormats()
{
if (!_codecs)
@@ -39,7 +26,7 @@ STDMETHODIMP CArchiveFolderManager::OpenFolderFile(IInStream *inStream,
IFolderFolder **resultFolder, IProgress *progress)
{
CMyComPtr<IArchiveOpenCallback> openArchiveCallback;
- if (progress != 0)
+ if (progress)
{
CMyComPtr<IProgress> progressWrapper = progress;
progressWrapper.QueryInterface(IID_IArchiveOpenCallback, &openArchiveCallback);
@@ -104,16 +91,18 @@ STDMETHODIMP CArchiveFolderManager::GetIconPath(const wchar_t *ext, BSTR *iconPa
if (lib.FindIconIndex(ext, ii))
{
*iconIndex = ii;
- return StringToBstr(GetUnicodeString(lib.Path, GetCurrentFileCodePage()), iconPath);
+ return StringToBstr(fs2us(lib.Path), iconPath);
}
}
int ii;
if (_codecs->InternalIcons.FindIconIndex(ext, ii))
{
- *iconIndex = ii;
- UString path;
- NWindows::NDLL::MyGetModuleFileName(g_hInstance, path);
- return StringToBstr(path, iconPath);
+ FString path;
+ if (NWindows::NDLL::MyGetModuleFileName(path))
+ {
+ *iconIndex = ii;
+ return StringToBstr(fs2us(path), iconPath);
+ }
}
return S_OK;
}
diff --git a/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp b/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp
index cf3e2d5a..656602cb 100755
--- a/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp
+++ b/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp
@@ -6,6 +6,7 @@
#include "Windows/FileDir.h"
+#include "../../Common/FileStreams.h"
#include "../Common/WorkDir.h"
#include "Agent.h"
@@ -14,32 +15,20 @@ using namespace NWindows;
using namespace NFile;
using namespace NDirectory;
-static LPCWSTR kTempArcivePrefix = L"7zA";
-
void CAgentFolder::GetPathParts(UStringVector &pathParts)
{
_proxyFolderItem->GetPathParts(pathParts);
}
HRESULT CAgentFolder::CommonUpdateOperation(
- bool deleteOperation,
- bool createFolderOperation,
- bool renameOperation,
+ AGENT_OP operation,
const wchar_t *newItemName,
const NUpdateArchive::CActionSet *actionSet,
const UINT32 *indices, UINT32 numItems,
IFolderArchiveUpdateCallback *updateCallback100)
{
- NWorkDir::CInfo workDirInfo;
- workDirInfo.Load();
- UString archiveFilePath = _agentSpec->_archiveFilePath;
- UString workDir = GetWorkDir(workDirInfo, archiveFilePath);
- CreateComplexDirectory(workDir);
-
- CTempFileW tempFile;
- UString tempFileName;
- if (tempFile.Create(workDir, kTempArcivePrefix, tempFileName) == 0)
- return E_FAIL;
+ CWorkDirTempFile tempFile;
+ RINOK(tempFile.CreateTempFile(us2fs(_agentSpec->_archiveFilePath)));
/*
if (SetOutProperties(anOutArchive, aCompressionInfo.Method) != S_OK)
@@ -53,44 +42,39 @@ HRESULT CAgentFolder::CommonUpdateOperation(
GetPathParts(pathParts);
HRESULT result;
- if (deleteOperation)
- result = _agentSpec->DeleteItems(tempFileName,
- indices, numItems, updateCallback100);
- else if (createFolderOperation)
+ switch (operation)
{
- result = _agentSpec->CreateFolder(tempFileName,
- newItemName, updateCallback100);
- }
- else if (renameOperation)
- {
- result = _agentSpec->RenameItem(
- tempFileName,
- indices, numItems,
- newItemName,
- updateCallback100);
- }
- else
- {
- Byte actionSetByte[NUpdateArchive::NPairState::kNumValues];
- for (int i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
- actionSetByte[i] = (Byte)actionSet->StateActions[i];
- result = _agentSpec->DoOperation2(tempFileName, actionSetByte, NULL, updateCallback100);
+ case AGENT_OP_Delete:
+ result = _agentSpec->DeleteItems(tempFile.OutStream, indices, numItems, updateCallback100);
+ break;
+ case AGENT_OP_CreateFolder:
+ result = _agentSpec->CreateFolder(tempFile.OutStream, newItemName, updateCallback100);
+ break;
+ case AGENT_OP_Rename:
+ result = _agentSpec->RenameItem(tempFile.OutStream, indices, numItems, newItemName, updateCallback100);
+ break;
+ case AGENT_OP_CopyFromFile:
+ result = _agentSpec->UpdateOneFile(tempFile.OutStream, indices, numItems, newItemName, updateCallback100);
+ break;
+ case AGENT_OP_Uni:
+ {
+ Byte actionSetByte[NUpdateArchive::NPairState::kNumValues];
+ for (int i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
+ actionSetByte[i] = (Byte)actionSet->StateActions[i];
+ result = _agentSpec->DoOperation2(tempFile.OutStream, actionSetByte, NULL, updateCallback100);
+ break;
+ }
+ default:
+ return E_FAIL;
}
- if (result != S_OK)
- return result;
+ RINOK(result);
_agentSpec->Close();
// m_FolderItem = NULL;
- if (NFind::DoesFileExist(archiveFilePath))
- if (!DeleteFileAlways(archiveFilePath))
- return GetLastError();
-
- tempFile.DisableDeleting();
- if (!MyMoveFile(tempFileName, archiveFilePath))
- return GetLastError();
+ RINOK(tempFile.MoveToOriginal(true));
{
CMyComPtr<IArchiveOpenCallback> openCallback;
@@ -134,7 +118,7 @@ STDMETHODIMP CAgentFolder::CopyFrom(
{
COM_TRY_BEGIN
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
- if (progress != 0)
+ if (progress)
{
RINOK(progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&updateCallback100));
}
@@ -142,7 +126,7 @@ STDMETHODIMP CAgentFolder::CopyFrom(
{
RINOK(_agentSpec->SetFiles(fromFolderPath, itemsPaths, numItems));
RINOK(_agentSpec->SetFolder(this));
- return CommonUpdateOperation(false, false, false, NULL,
+ return CommonUpdateOperation(AGENT_OP_Uni, NULL,
&NUpdateArchive::kAddActionSet, 0, 0, updateCallback100);
}
catch(const UString &s)
@@ -153,18 +137,43 @@ STDMETHODIMP CAgentFolder::CopyFrom(
COM_TRY_END
}
+STDMETHODIMP CAgentFolder::CopyFromFile(UInt32 destIndex, const wchar_t *itemPath, IProgress * progress)
+{
+ COM_TRY_BEGIN
+ CUIntVector indices;
+ indices.Add(destIndex);
+ CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
+ if (progress)
+ {
+ RINOK(progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&updateCallback100));
+ }
+ try
+ {
+ RINOK(_agentSpec->SetFolder(this));
+ return CommonUpdateOperation(AGENT_OP_CopyFromFile, itemPath,
+ &NUpdateArchive::kAddActionSet,
+ &indices.Front(), indices.Size(), updateCallback100);
+ }
+ catch(const UString &s)
+ {
+ RINOK(updateCallback100->UpdateErrorMessage(UString(L"Error: ") + s));
+ return E_FAIL;
+ }
+ COM_TRY_END
+}
+
STDMETHODIMP CAgentFolder::Delete(const UINT32 *indices, UINT32 numItems, IProgress *progress)
{
COM_TRY_BEGIN
RINOK(_agentSpec->SetFolder(this));
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
- if (progress != 0)
+ if (progress)
{
CMyComPtr<IProgress> progressWrapper = progress;
RINOK(progressWrapper.QueryInterface(
IID_IFolderArchiveUpdateCallback, &updateCallback100));
}
- return CommonUpdateOperation(true, false, false, NULL,
+ return CommonUpdateOperation(AGENT_OP_Delete, NULL,
&NUpdateArchive::kDeleteActionSet, indices, numItems, updateCallback100);
COM_TRY_END
}
@@ -176,12 +185,12 @@ STDMETHODIMP CAgentFolder::CreateFolder(const wchar_t *name, IProgress *progress
return ERROR_ALREADY_EXISTS;
RINOK(_agentSpec->SetFolder(this));
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
- if (progress != 0)
+ if (progress)
{
CMyComPtr<IProgress> progressWrapper = progress;
RINOK(progressWrapper.QueryInterface(IID_IFolderArchiveUpdateCallback, &updateCallback100));
}
- return CommonUpdateOperation(false, true, false, name, NULL, NULL, 0, updateCallback100);
+ return CommonUpdateOperation(AGENT_OP_CreateFolder, name, NULL, NULL, 0, updateCallback100);
COM_TRY_END
}
@@ -192,12 +201,12 @@ STDMETHODIMP CAgentFolder::Rename(UINT32 index, const wchar_t *newName, IProgres
indices.Add(index);
RINOK(_agentSpec->SetFolder(this));
CMyComPtr<IFolderArchiveUpdateCallback> updateCallback100;
- if (progress != 0)
+ if (progress)
{
CMyComPtr<IProgress> progressWrapper = progress;
RINOK(progressWrapper.QueryInterface(IID_IFolderArchiveUpdateCallback, &updateCallback100));
}
- return CommonUpdateOperation(false, false, true, newName, NULL, &indices.Front(),
+ return CommonUpdateOperation(AGENT_OP_Rename, newName, NULL, &indices.Front(),
indices.Size(), updateCallback100);
COM_TRY_END
}
diff --git a/CPP/7zip/UI/Agent/IFolderArchive.h b/CPP/7zip/UI/Agent/IFolderArchive.h
index 867ae279..2357af31 100755
--- a/CPP/7zip/UI/Agent/IFolderArchive.h
+++ b/CPP/7zip/UI/Agent/IFolderArchive.h
@@ -3,7 +3,6 @@
#ifndef __IFOLDER_ARCHIVE_H
#define __IFOLDER_ARCHIVE_H
-#include "../../IDecl.h"
#include "../../Archive/IArchive.h"
#include "../../UI/Common/LoadCodecs.h"
#include "../../UI/FileManager/IFolder.h"
@@ -57,13 +56,14 @@ FOLDER_ARCHIVE_INTERFACE_SUB(IFolderArchiveUpdateCallback, IProgress, 0x0B)
#define INTERFACE_IOutFolderArchive(x) \
STDMETHOD(SetFolder)(IFolderFolder *folder) x; \
STDMETHOD(SetFiles)(const wchar_t *folderPrefix, const wchar_t **names, UInt32 numNames) x; \
- STDMETHOD(DeleteItems)(const wchar_t *newArchiveName, \
+ STDMETHOD(DeleteItems)(ISequentialOutStream *outArchiveStream, \
const UInt32 *indices, UInt32 numItems, IFolderArchiveUpdateCallback *updateCallback) x; \
STDMETHOD(DoOperation)(CCodecs *codecs, int index, \
- const wchar_t *newArchiveName, const Byte *stateActions, const wchar_t *sfxModule, \
+ ISequentialOutStream *outArchiveStream, const Byte *stateActions, const wchar_t *sfxModule, \
+ IFolderArchiveUpdateCallback *updateCallback) x; \
+ STDMETHOD(DoOperation2)( \
+ ISequentialOutStream *outArchiveStream, const Byte *stateActions, const wchar_t *sfxModule, \
IFolderArchiveUpdateCallback *updateCallback) x; \
- STDMETHOD(DoOperation2)(const wchar_t *newArchiveName, const Byte *stateActions, \
- const wchar_t *sfxModule, IFolderArchiveUpdateCallback *updateCallback) x; \
FOLDER_ARCHIVE_INTERFACE(IOutFolderArchive, 0x0A)
{
diff --git a/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp b/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp
index e4aa4438..3687c3d0 100755
--- a/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp
+++ b/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp
@@ -66,7 +66,7 @@ HRESULT CUpdateCallbackAgent::OpenFileError(const wchar_t *name, DWORD systemErr
UString(L"WARNING: ") +
NError::MyFormatMessageW(systemError) +
UString(L": ") +
- UString(name)));
+ name));
return S_FALSE;
}
}
diff --git a/CPP/7zip/UI/Client7z/Client7z.cpp b/CPP/7zip/UI/Client7z/Client7z.cpp
index 410b800d..d181843d 100755
--- a/CPP/7zip/UI/Client7z/Client7z.cpp
+++ b/CPP/7zip/UI/Client7z/Client7z.cpp
@@ -21,6 +21,10 @@
#include "../../IPassword.h"
#include "../../MyVersion.h"
+#ifdef _WIN32
+HINSTANCE g_hInstance = 0;
+#endif
+
// use another CLSIDs, if you want to support other formats (zip, rar, ...).
// {23170F69-40C1-278A-1000-000110070000}
DEFINE_GUID(CLSID_CFormat7z,
@@ -30,9 +34,9 @@ using namespace NWindows;
#define kDllName "7z.dll"
-static const char *kCopyrightString = MY_7ZIP_VERSION
+static const char *kCopyrightString = "\n" MY_7ZIP_VERSION
" (" kDllName " client) "
-MY_COPYRIGHT " " MY_DATE;
+MY_COPYRIGHT " " MY_DATE "\n";
static const char *kHelpString =
"Usage: Client7z.exe [a | l | x ] archive.7z [fileName ...]\n"
@@ -48,28 +52,46 @@ typedef UINT32 (WINAPI * CreateObjectFunc)(
void **outObject);
-void PrintString(const UString &s)
+static AString FStringToConsoleString(const FString &s)
+{
+ return GetOemString(fs2us(s));
+}
+
+static FString CmdStringToFString(const char *s)
+{
+ return us2fs(GetUnicodeString(s));
+}
+
+static void PrintString(const UString &s)
{
printf("%s", (LPCSTR)GetOemString(s));
}
-void PrintString(const AString &s)
+static void PrintString(const AString &s)
{
printf("%s", (LPCSTR)s);
}
-void PrintNewLine()
+static void PrintNewLine()
{
PrintString("\n");
}
-void PrintStringLn(const AString &s)
+static void PrintStringLn(const AString &s)
{
PrintString(s);
PrintNewLine();
}
-void PrintError(const AString &s)
+static void PrintError(const char *message, const FString &name)
+{
+ printf("Error: %s", (LPCSTR)message);
+ PrintNewLine();
+ PrintString(FStringToConsoleString(name));
+ PrintNewLine();
+}
+
+static void PrintError(const AString &s)
{
PrintNewLine();
PrintString(s);
@@ -148,8 +170,6 @@ STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password)
//////////////////////////////////////////////////////////////
// Archive Extracting callback class
-static const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file ";
-
static const char *kTestingString = "Testing ";
static const char *kExtractingString = "Extracting ";
static const char *kSkippingString = "Skipping ";
@@ -181,9 +201,9 @@ public:
private:
CMyComPtr<IInArchive> _archiveHandler;
- UString _directoryPath; // Output directory
+ FString _directoryPath; // Output directory
UString _filePath; // name inside arcvhive
- UString _diskFilePath; // full path to file on disk
+ FString _diskFilePath; // full path to file on disk
bool _extractMode;
struct CProcessedFileInfo
{
@@ -198,7 +218,7 @@ private:
CMyComPtr<ISequentialOutStream> _outFileStream;
public:
- void Init(IInArchive *archiveHandler, const UString &directoryPath);
+ void Init(IInArchive *archiveHandler, const FString &directoryPath);
UInt64 NumErrors;
bool PasswordIsDefined;
@@ -207,7 +227,7 @@ public:
CArchiveExtractCallback() : PasswordIsDefined(false) {}
};
-void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const UString &directoryPath)
+void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const FString &directoryPath)
{
NumErrors = 0;
_archiveHandler = archiveHandler;
@@ -305,10 +325,10 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
// Create folders for file
int slashPos = _filePath.ReverseFind(WCHAR_PATH_SEPARATOR);
if (slashPos >= 0)
- NFile::NDirectory::CreateComplexDirectory(_directoryPath + _filePath.Left(slashPos));
+ NFile::NDirectory::CreateComplexDirectory(_directoryPath + us2fs(_filePath.Left(slashPos)));
}
- UString fullProcessedPath = _directoryPath + _filePath;
+ FString fullProcessedPath = _directoryPath + us2fs(_filePath);
_diskFilePath = fullProcessedPath;
if (_processedFileInfo.isDir)
@@ -317,12 +337,12 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
}
else
{
- NFile::NFind::CFileInfoW fi;
+ NFile::NFind::CFileInfo fi;
if (fi.Find(fullProcessedPath))
{
if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))
{
- PrintString(UString(kCantDeleteOutputFile) + fullProcessedPath);
+ PrintError("Can not delete output file", fullProcessedPath);
return E_ABORT;
}
}
@@ -331,7 +351,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
if (!_outFileStreamSpec->Open(fullProcessedPath, CREATE_ALWAYS))
{
- PrintString((UString)L"can not open output file " + fullProcessedPath);
+ PrintError("Can not open output file", fullProcessedPath);
return E_ABORT;
}
_outFileStream = outStreamLoc;
@@ -423,7 +443,7 @@ struct CDirItem
FILETIME ATime;
FILETIME MTime;
UString Name;
- UString FullPath;
+ FString FullPath;
UInt32 Attrib;
bool isDir() const { return (Attrib & FILE_ATTRIBUTE_DIRECTORY) != 0 ; }
@@ -458,7 +478,7 @@ public:
UString VolName;
UString VolExt;
- UString DirPrefix;
+ FString DirPrefix;
const CObjectVector<CDirItem> *DirItems;
bool PasswordIsDefined;
@@ -467,7 +487,7 @@ public:
bool m_NeedBeClosed;
- UStringVector FailedFiles;
+ FStringVector FailedFiles;
CRecordVector<HRESULT> FailedCodes;
CArchiveUpdateCallback(): PasswordIsDefined(false), AskPassword(false), DirItems(0) {};
@@ -514,7 +534,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */,
STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
- NWindows::NCOM::CPropVariant prop;
+ NCOM::CPropVariant prop;
if (propID == kpidIsAnti)
{
@@ -571,7 +591,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream
{
CInFileStream *inStreamSpec = new CInFileStream;
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
- UString path = DirPrefix + dirItem.FullPath;
+ FString path = DirPrefix + dirItem.FullPath;
if (!inStreamSpec->Open(path))
{
DWORD sysError = ::GetLastError();
@@ -620,7 +640,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOu
fileName += VolExt;
COutFileStream *streamSpec = new COutFileStream;
CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
- if (!streamSpec->Create(fileName, false))
+ if (!streamSpec->Create(us2fs(fileName), false))
return ::GetLastError();
*volumeStream = streamLoc.Detach();
return S_OK;
@@ -643,8 +663,6 @@ STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDef
return StringToBstr(Password, password);
}
-
-
//////////////////////////////////////////////////////////////////////////
// Main function
@@ -661,8 +679,8 @@ int MY_CDECL main(int numArgs, const char *args[])
PrintStringLn(kHelpString);
return 1;
}
- NWindows::NDLL::CLibrary lib;
- if (!lib.Load(TEXT(kDllName)))
+ NDLL::CLibrary lib;
+ if (!lib.Load(NDLL::GetModuleDirPrefix() + FTEXT(kDllName)))
{
PrintError("Can not load 7-zip library");
return 1;
@@ -682,10 +700,10 @@ int MY_CDECL main(int numArgs, const char *args[])
PrintError("incorrect command");
return 1;
}
- c = MyCharLower(command[0]);
+ c = (char)MyCharUpper(command[0]);
}
- UString archiveName = GetUnicodeString(args[2]);
- if (c == 'a')
+ FString archiveName = CmdStringToFString(args[2]);
+ if (c == 'A')
{
// create archive command
if (numArgs < 4)
@@ -698,12 +716,12 @@ int MY_CDECL main(int numArgs, const char *args[])
for (i = 3; i < numArgs; i++)
{
CDirItem di;
- UString name = GetUnicodeString(args[i]);
+ FString name = CmdStringToFString(args[i]);
- NFile::NFind::CFileInfoW fi;
+ NFile::NFind::CFileInfo fi;
if (!fi.Find(name))
{
- PrintString(UString(L"Can't find file") + name);
+ PrintError("Can't find file", name);
return 1;
}
@@ -712,7 +730,7 @@ int MY_CDECL main(int numArgs, const char *args[])
di.CTime = fi.CTime;
di.ATime = fi.ATime;
di.MTime = fi.MTime;
- di.Name = name;
+ di.Name = fs2us(name);
di.FullPath = name;
dirItems.Add(di);
}
@@ -745,7 +763,7 @@ int MY_CDECL main(int numArgs, const char *args[])
L"x"
};
const int kNumProps = sizeof(names) / sizeof(names[0]);
- NWindows::NCOM::CPropVariant values[kNumProps] =
+ NCOM::CPropVariant values[kNumProps] =
{
false, // solid mode OFF
(UInt32)9 // compression level = 9 - ultra
@@ -771,7 +789,7 @@ int MY_CDECL main(int numArgs, const char *args[])
for (i = 0; i < updateCallbackSpec->FailedFiles.Size(); i++)
{
PrintNewLine();
- PrintString((UString)L"Error for file: " + updateCallbackSpec->FailedFiles[i]);
+ PrintError("Error for file", updateCallbackSpec->FailedFiles[i]);
}
if (updateCallbackSpec->FailedFiles.Size() != 0)
return 1;
@@ -785,9 +803,9 @@ int MY_CDECL main(int numArgs, const char *args[])
}
bool listCommand;
- if (c == 'l')
+ if (c == 'L')
listCommand = true;
- else if (c == 'x')
+ else if (c == 'X')
listCommand = false;
else
{
@@ -807,7 +825,7 @@ int MY_CDECL main(int numArgs, const char *args[])
if (!fileSpec->Open(archiveName))
{
- PrintError("Can not open archive file");
+ PrintError("Can not open archive file", archiveName);
return 1;
}
@@ -820,7 +838,7 @@ int MY_CDECL main(int numArgs, const char *args[])
if (archive->Open(file, 0, openCallback) != S_OK)
{
- PrintError("Can not open archive");
+ PrintError("Can not open file as archive", archiveName);
return 1;
}
}
@@ -834,7 +852,7 @@ int MY_CDECL main(int numArgs, const char *args[])
{
{
// Get uncompressed size of file
- NWindows::NCOM::CPropVariant prop;
+ NCOM::CPropVariant prop;
archive->GetProperty(i, kpidSize, &prop);
UString s = ConvertPropVariantToString(prop);
PrintString(s);
@@ -842,12 +860,12 @@ int MY_CDECL main(int numArgs, const char *args[])
}
{
// Get name of file
- NWindows::NCOM::CPropVariant prop;
+ NCOM::CPropVariant prop;
archive->GetProperty(i, kpidPath, &prop);
UString s = ConvertPropVariantToString(prop);
PrintString(s);
}
- PrintString("\n");
+ PrintNewLine();
}
}
else
@@ -855,7 +873,7 @@ int MY_CDECL main(int numArgs, const char *args[])
// Extract command
CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback;
CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);
- extractCallbackSpec->Init(archive, L""); // second parameter is output folder path
+ extractCallbackSpec->Init(archive, FTEXT("")); // second parameter is output folder path
extractCallbackSpec->PasswordIsDefined = false;
// extractCallbackSpec->PasswordIsDefined = true;
// extractCallbackSpec->Password = L"1";
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
index 8ae2e15e..85ec17b4 100755
--- a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
+++ b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp
@@ -283,9 +283,9 @@ static void AddToCensorFromListFile(NWildcard::CCensor &wildcardCensor,
LPCWSTR fileName, bool include, NRecursedType::EEnum type, UINT codePage)
{
UStringVector names;
- if (!NFind::DoesFileExist(fileName))
+ if (!NFind::DoesFileExist(us2fs(fileName)))
throw kCannotFindListFile;
- if (!ReadNamesFromListFile(fileName, names, codePage))
+ if (!ReadNamesFromListFile(us2fs(fileName), names, codePage))
throw kIncorrectListFile;
for (int i = 0; i < names.Size(); i++)
AddNameToCensor(wildcardCensor, names[i], include, type);
@@ -420,9 +420,9 @@ static void ConvertToLongName(const UString &prefix, UString &name)
{
if (name.IsEmpty() || DoesNameContainWildCard(name))
return;
- NFind::CFileInfoW fi;
- if (fi.Find(prefix + name))
- name = fi.Name;
+ NFind::CFileInfo fi;
+ if (fi.Find(us2fs(prefix + name)))
+ name = fs2us(fi.Name);
}
static void ConvertToLongNames(const UString &prefix, CObjectVector<NWildcard::CItem> &items)
@@ -463,7 +463,7 @@ static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &no
for (i = 0; i < node.SubNodes.Size(); i++)
{
NWildcard::CCensorNode &nextNode = node.SubNodes[i];
- ConvertToLongNames(prefix + nextNode.Name + wchar_t(NFile::NName::kDirDelimiter), nextNode);
+ ConvertToLongNames(prefix + nextNode.Name + WCHAR_PATH_SEPARATOR, nextNode);
}
}
@@ -647,11 +647,11 @@ static void SetAddCommandOptions(
if (postString.IsEmpty())
NDirectory::MyGetTempPath(options.WorkingDir);
else
- options.WorkingDir = postString;
+ options.WorkingDir = us2fs(postString);
}
options.SfxMode = parser[NKey::kSfx].ThereIs;
if (options.SfxMode)
- options.SfxModule = parser[NKey::kSfx].PostStrings[0];
+ options.SfxModule = us2fs(parser[NKey::kSfx].PostStrings[0]);
if (parser[NKey::kVolume].ThereIs)
{
@@ -670,7 +670,6 @@ static void SetMethodOptions(const CParser &parser, CObjectVector<CProperty> &pr
{
if (parser[NKey::kProperty].ThereIs)
{
- // options.MethodMode.Properties.Clear();
for (int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++)
{
CProperty property;
@@ -774,7 +773,7 @@ void EnumerateDirItemsAndSort(NWildcard::CCensor &wildcardCensor,
{
CDirItems dirItems;
{
- UStringVector errorPaths;
+ FStringVector errorPaths;
CRecordVector<DWORD> errorCodes;
HRESULT res = EnumerateItems(wildcardCensor, dirItems, NULL, errorPaths, errorCodes);
if (res != S_OK || errorPaths.Size() > 0)
@@ -796,9 +795,9 @@ void EnumerateDirItemsAndSort(NWildcard::CCensor &wildcardCensor,
int i;
for (i = 0; i < paths.Size(); i++)
{
- UString fullPath;
- NFile::NDirectory::MyGetFullPathName(paths[i], fullPath);
- fullPaths.Add(fullPath);
+ FString fullPath;
+ NFile::NDirectory::MyGetFullPathName(us2fs(paths[i]), fullPath);
+ fullPaths.Add(fs2us(fullPath));
}
CIntVector indices;
SortFileNames(fullPaths, indices);
@@ -886,6 +885,8 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
if (parser[NKey::kArchiveType].ThereIs)
options.ArcType = parser[NKey::kArchiveType].PostStrings[0];
+ SetMethodOptions(parser, options.Properties);
+
if (isExtractOrList)
{
if (!options.WildcardCensor.AllAreRelative())
@@ -924,12 +925,11 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
if (isExtractGroupCommand)
{
- SetMethodOptions(parser, options.ExtractProperties);
if (options.StdOutMode && options.IsStdOutTerminal && options.IsStdErrTerminal)
throw kSameTerminalError;
if (parser[NKey::kOutputDir].ThereIs)
{
- options.OutputDir = parser[NKey::kOutputDir].PostStrings[0];
+ options.OutputDir = us2fs(parser[NKey::kOutputDir].PostStrings[0]);
NFile::NName::NormalizeDirPathPrefix(options.OutputDir);
}
@@ -946,7 +946,7 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
SetAddCommandOptions(options.Command.CommandType, parser, updateOptions);
- SetMethodOptions(parser, updateOptions.MethodMode.Properties);
+ updateOptions.MethodMode.Properties = options.Properties;
if (parser[NKey::kShareForWrite].ThereIs)
updateOptions.OpenShareForWrite = true;
@@ -988,50 +988,12 @@ void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options)
}
else if (options.Command.CommandType == NCommandType::kBenchmark)
{
- options.NumThreads = (UInt32)-1;
- options.DictionarySize = (UInt32)-1;
options.NumIterations = 1;
if (curCommandIndex < numNonSwitchStrings)
{
if (!ConvertStringToUInt32(nonSwitchStrings[curCommandIndex++], options.NumIterations))
ThrowUserErrorException();
}
- for (int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++)
- {
- UString postString = parser[NKey::kProperty].PostStrings[i];
- postString.MakeUpper();
- if (postString.Length() < 2)
- ThrowUserErrorException();
- if (postString[0] == 'D')
- {
- int pos = 1;
- if (postString[pos] == '=')
- pos++;
- UInt32 logSize;
- if (!ConvertStringToUInt32((const wchar_t *)postString + pos, logSize))
- ThrowUserErrorException();
- if (logSize > 31)
- ThrowUserErrorException();
- options.DictionarySize = 1 << logSize;
- }
- else if (postString[0] == 'M' && postString[1] == 'T' )
- {
- int pos = 2;
- if (postString[pos] == '=')
- pos++;
- if (postString[pos] != 0)
- if (!ConvertStringToUInt32((const wchar_t *)postString + pos, options.NumThreads))
- ThrowUserErrorException();
- }
- else if (postString[0] == 'M' && postString[1] == '=' )
- {
- int pos = 2;
- if (postString[pos] != 0)
- options.Method = postString.Mid(2);
- }
- else
- ThrowUserErrorException();
- }
}
else if (options.Command.CommandType == NCommandType::kInfo)
{
diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.h b/CPP/7zip/UI/Common/ArchiveCommandLine.h
index e8f601df..96646d60 100755
--- a/CPP/7zip/UI/Common/ArchiveCommandLine.h
+++ b/CPP/7zip/UI/Common/ArchiveCommandLine.h
@@ -75,11 +75,11 @@ struct CArchiveCommandLineOptions
// Extract
bool CalcCrc;
bool AppendName;
- UString OutputDir;
+ FString OutputDir;
NExtract::NOverwriteMode::EEnum OverwriteMode;
UStringVector ArchivePathsSorted;
UStringVector ArchivePathsFullSorted;
- CObjectVector<CProperty> ExtractProperties;
+ CObjectVector<CProperty> Properties;
CUpdateOptions UpdateOptions;
UString ArcType;
@@ -87,10 +87,6 @@ struct CArchiveCommandLineOptions
// Benchmark
UInt32 NumIterations;
- UInt32 NumThreads;
- UInt32 DictionarySize;
- UString Method;
-
CArchiveCommandLineOptions(): StdInMode(false), StdOutMode(false) {};
};
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
index 4c0cc90b..9c9c0422 100755
--- a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
+++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp
@@ -3,10 +3,12 @@
#include "StdAfx.h"
#include "Common/ComTry.h"
+#include "Common/StringConvert.h"
#include "Common/Wildcard.h"
#include "Windows/FileDir.h"
#include "Windows/FileFind.h"
+#include "Windows/FileName.h"
#include "Windows/PropVariant.h"
#include "Windows/PropVariantConversions.h"
@@ -18,16 +20,16 @@
using namespace NWindows;
-static const wchar_t *kCantAutoRename = L"ERROR: Can not create file with auto name";
-static const wchar_t *kCantRenameFile = L"ERROR: Can not rename existing file ";
-static const wchar_t *kCantDeleteOutputFile = L"ERROR: Can not delete output file ";
+static const char *kCantAutoRename = "ERROR: Can not create file with auto name";
+static const char *kCantRenameFile = "ERROR: Can not rename existing file ";
+static const char *kCantDeleteOutputFile = "ERROR: Can not delete output file ";
void CArchiveExtractCallback::Init(
const NWildcard::CCensorNode *wildcardCensor,
const CArc *arc,
IFolderArchiveExtractCallback *extractCallback2,
bool stdOutMode, bool testMode, bool crcMode,
- const UString &directoryPath,
+ const FString &directoryPath,
const UStringVector &removePathParts,
UInt64 packSize)
{
@@ -107,14 +109,14 @@ STDMETHODIMP CArchiveExtractCallback::SetRatioInfo(const UInt64 *inSize, const U
COM_TRY_END
}
-void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath)
+void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath)
{
fullPath = _directoryPath;
for (int i = 0; i < dirPathParts.Size(); i++)
{
if (i > 0)
- fullPath += wchar_t(NFile::NName::kDirDelimiter);
- fullPath += dirPathParts[i];
+ fullPath += FCHAR_PATH_SEPARATOR;
+ fullPath += us2fs(dirPathParts[i]);
NFile::NDirectory::MyCreateDirectory(fullPath);
}
}
@@ -136,12 +138,12 @@ HRESULT CArchiveExtractCallback::GetTime(int index, PROPID propID, FILETIME &fil
HRESULT CArchiveExtractCallback::GetUnpackSize()
{
- NCOM::CPropVariant prop;
- RINOK(_arc->Archive->GetProperty(_index, kpidSize, &prop));
- _curSizeDefined = (prop.vt != VT_EMPTY);
- if (_curSizeDefined)
- _curSize = ConvertPropVariantToUInt64(prop);
- return S_OK;
+ return _arc->GetItemSize(_index, _curSize, _curSizeDefined);
+}
+
+HRESULT CArchiveExtractCallback::SendMessageError(const char *message, const FString &path)
+{
+ return _extractCallback2->MessageError(GetUnicodeString(message) + fs2us(path));
}
STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode)
@@ -256,7 +258,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
if (!pathParts.IsEmpty())
{
- UString fullPathNew;
+ FString fullPathNew;
CreateComplexDirectory(pathParts, fullPathNew);
if (_fi.IsDir)
NFile::NDirectory::SetDirTime(fullPathNew,
@@ -267,7 +269,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
}
- UString fullProcessedPath = _directoryPath + processedPath;
+ FString fullProcessedPath = _directoryPath + us2fs(processedPath);
if (_fi.IsDir)
{
@@ -279,7 +281,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
if (!_isSplit)
{
- NFile::NFind::CFileInfoW fileInfo;
+ NFile::NFind::CFileInfo fileInfo;
if (fileInfo.Find(fullProcessedPath))
{
switch(_overwriteMode)
@@ -290,7 +292,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
{
Int32 overwiteResult;
RINOK(_extractCallback2->AskOverwrite(
- fullProcessedPath, &fileInfo.MTime, &fileInfo.Size, fullPath,
+ fs2us(fullProcessedPath), &fileInfo.MTime, &fileInfo.Size, fullPath,
_fi.MTimeDefined ? &_fi.MTime : NULL,
_curSizeDefined ? &_curSize : NULL,
&overwiteResult))
@@ -321,32 +323,28 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
{
if (!AutoRenamePath(fullProcessedPath))
{
- UString message = UString(kCantAutoRename) + fullProcessedPath;
- RINOK(_extractCallback2->MessageError(message));
+ RINOK(SendMessageError(kCantAutoRename, fullProcessedPath));
return E_FAIL;
}
}
else if (_overwriteMode == NExtract::NOverwriteMode::kAutoRenameExisting)
{
- UString existPath = fullProcessedPath;
+ FString existPath = fullProcessedPath;
if (!AutoRenamePath(existPath))
{
- UString message = kCantAutoRename + fullProcessedPath;
- RINOK(_extractCallback2->MessageError(message));
+ RINOK(SendMessageError(kCantAutoRename, fullProcessedPath));
return E_FAIL;
}
if (!NFile::NDirectory::MyMoveFile(fullProcessedPath, existPath))
{
- UString message = UString(kCantRenameFile) + fullProcessedPath;
- RINOK(_extractCallback2->MessageError(message));
+ RINOK(SendMessageError(kCantRenameFile, fullProcessedPath));
return E_FAIL;
}
}
else
if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath))
{
- UString message = UString(kCantDeleteOutputFile) + fullProcessedPath;
- RINOK(_extractCallback2->MessageError(message));
+ RINOK(SendMessageError(kCantDeleteOutputFile, fullProcessedPath));
return S_OK;
// return E_FAIL;
}
@@ -360,8 +358,7 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
{
// if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit)
{
- UString message = L"can not open output file " + fullProcessedPath;
- RINOK(_extractCallback2->MessageError(message));
+ RINOK(SendMessageError("can not open output file ", fullProcessedPath));
return S_OK;
}
}
@@ -485,4 +482,3 @@ STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
return _cryptoGetTextPassword->CryptoGetTextPassword(password);
COM_TRY_END
}
-
diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.h b/CPP/7zip/UI/Common/ArchiveExtractCallback.h
index 367e4b07..cee7c5b6 100755
--- a/CPP/7zip/UI/Common/ArchiveExtractCallback.h
+++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.h
@@ -31,11 +31,11 @@ class CArchiveExtractCallback:
CMyComPtr<IFolderArchiveExtractCallback> _extractCallback2;
CMyComPtr<ICompressProgressInfo> _compressProgress;
CMyComPtr<ICryptoGetTextPassword> _cryptoGetTextPassword;
- UString _directoryPath;
+ FString _directoryPath;
NExtract::NPathMode::EEnum _pathMode;
NExtract::NOverwriteMode::EEnum _overwriteMode;
- UString _diskFilePath;
+ FString _diskFilePath;
UString _filePath;
UInt64 _position;
bool _isSplit;
@@ -83,10 +83,12 @@ class CArchiveExtractCallback:
UInt64 _packTotal;
UInt64 _unpTotal;
- void CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath);
+ void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath);
HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
HRESULT GetUnpackSize();
+ HRESULT SendMessageError(const char *message, const FString &path);
+
public:
CLocalProgress *LocalProgressSpec;
@@ -134,7 +136,7 @@ public:
const CArc *arc,
IFolderArchiveExtractCallback *extractCallback2,
bool stdOutMode, bool testMode, bool crcMode,
- const UString &directoryPath,
+ const FString &directoryPath,
const UStringVector &removePathParts,
UInt64 packSize);
diff --git a/CPP/7zip/UI/Common/ArchiveName.cpp b/CPP/7zip/UI/Common/ArchiveName.cpp
index c3684def..17947dce 100755
--- a/CPP/7zip/UI/Common/ArchiveName.cpp
+++ b/CPP/7zip/UI/Common/ArchiveName.cpp
@@ -9,19 +9,19 @@
using namespace NWindows;
-static UString CreateArchiveName2(const UString &srcName, bool fromPrev, bool keepName)
+static FString CreateArchiveName2(const FString &srcName, bool fromPrev, bool keepName)
{
- UString resultName = L"Archive";
+ FString resultName = FTEXT("Archive");
if (fromPrev)
{
- UString dirPrefix;
+ FString dirPrefix;
if (NFile::NDirectory::GetOnlyDirPrefix(srcName, dirPrefix))
{
if (dirPrefix.Length() > 0)
- if (dirPrefix[dirPrefix.Length() - 1] == WCHAR_PATH_SEPARATOR)
+ if (dirPrefix.Back() == FCHAR_PATH_SEPARATOR)
{
- dirPrefix.Delete(dirPrefix.Length() - 1);
- NFile::NFind::CFileInfoW fileInfo;
+ dirPrefix.DeleteBack();
+ NFile::NFind::CFileInfo fileInfo;
if (fileInfo.Find(dirPrefix))
resultName = fileInfo.Name;
}
@@ -29,7 +29,7 @@ static UString CreateArchiveName2(const UString &srcName, bool fromPrev, bool ke
}
else
{
- NFile::NFind::CFileInfoW fileInfo;
+ NFile::NFind::CFileInfo fileInfo;
if (!fileInfo.Find(srcName))
// return resultName;
return srcName;
@@ -39,8 +39,8 @@ static UString CreateArchiveName2(const UString &srcName, bool fromPrev, bool ke
int dotPos = resultName.ReverseFind('.');
if (dotPos > 0)
{
- UString archiveName2 = resultName.Left(dotPos);
- if (archiveName2.ReverseFind('.') < 0)
+ FString archiveName2 = resultName.Left(dotPos);
+ if (archiveName2.ReverseFind(FTEXT('.')) < 0)
resultName = archiveName2;
}
}
@@ -50,5 +50,5 @@ static UString CreateArchiveName2(const UString &srcName, bool fromPrev, bool ke
UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName)
{
- return GetCorrectFsPath(CreateArchiveName2(srcName, fromPrev, keepName));
+ return GetCorrectFsPath(fs2us(CreateArchiveName2(us2fs(srcName), fromPrev, keepName)));
}
diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
index e7e61713..be20940c 100755
--- a/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
+++ b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp
@@ -2,7 +2,6 @@
#include "StdAfx.h"
-#include "Common/StringConvert.h"
#include "Common/ComTry.h"
#include "Windows/PropVariant.h"
@@ -94,7 +93,7 @@ STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStre
RINOK(Callback->Open_CheckBreak());
}
*inStream = NULL;
- UString fullPath = _folderPrefix + name;
+ FString fullPath = _folderPrefix + us2fs(name);
if (!_fileInfo.Find(fullPath))
return S_FALSE;
if (_fileInfo.IsDir())
@@ -130,4 +129,3 @@ STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password)
COM_TRY_END
}
#endif
-
diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.h b/CPP/7zip/UI/Common/ArchiveOpenCallback.h
index c6651e8f..afada4a6 100755
--- a/CPP/7zip/UI/Common/ArchiveOpenCallback.h
+++ b/CPP/7zip/UI/Common/ArchiveOpenCallback.h
@@ -77,8 +77,8 @@ public:
}
private:
- UString _folderPrefix;
- NWindows::NFile::NFind::CFileInfoW _fileInfo;
+ FString _folderPrefix;
+ NWindows::NFile::NFind::CFileInfo _fileInfo;
bool _subArchiveMode;
UString _subArchiveName;
public:
@@ -88,7 +88,7 @@ public:
UInt64 TotalSize;
COpenCallbackImp(): Callback(NULL) {}
- void Init(const UString &folderPrefix, const UString &fileName)
+ void Init(const FString &folderPrefix, const FString &fileName)
{
_folderPrefix = folderPrefix;
if (!_fileInfo.Find(_folderPrefix + fileName))
diff --git a/CPP/7zip/UI/Common/Bench.cpp b/CPP/7zip/UI/Common/Bench.cpp
index 282f405f..5adfcc20 100755
--- a/CPP/7zip/UI/Common/Bench.cpp
+++ b/CPP/7zip/UI/Common/Bench.cpp
@@ -2,8 +2,6 @@
#include "StdAfx.h"
-#include "Bench.h"
-
#ifndef _WIN32
#define USE_POSIX_TIME
#define USE_POSIX_TIME2
@@ -31,18 +29,30 @@
#include "../../../../C/7zCrc.h"
#include "../../../../C/Alloc.h"
+#if !defined(_7ZIP_ST) || defined(_WIN32)
+#include "../../../Windows/System.h"
+#endif
+
#ifndef _7ZIP_ST
#include "../../../Windows/Synchronization.h"
#include "../../../Windows/Thread.h"
#endif
-#include "../../../Windows/PropVariant.h"
+#include "../../../Common/IntToString.h"
+#include "../../../Common/StringConvert.h"
+#include "../../../Common/StringToInt.h"
+
+#include "../../Common/MethodProps.h"
+
+#include "Bench.h"
+
+using namespace NWindows;
-static const UInt32 kUncompressMinBlockSize =
+static const UInt64 kUncompressMinBlockSize =
#ifdef UNDER_CE
-1 << 24;
+(UInt64)1 << 30;
#else
-1 << 26;
+(UInt64)1 << 33;
#endif
static const UInt32 kCrcBlockSize =
@@ -52,6 +62,8 @@ static const UInt32 kCrcBlockSize =
1 << 30;
#endif
+static const unsigned kOldLzmaDictBits = 30;
+
static const UInt32 kAdditionalSize = (1 << 16);
static const UInt32 kCompressedAdditionalSize = (1 << 10);
static const UInt32 kMaxLzmaPropSize = 5;
@@ -99,7 +111,7 @@ class CBenchRandomGenerator: public CBenchBuffer
CBaseRandomGenerator *RG;
public:
void Set(CBaseRandomGenerator *rg) { RG = rg; }
- UInt32 GetVal(UInt32 &res, int numBits)
+ UInt32 GetVal(UInt32 &res, unsigned numBits)
{
UInt32 val = res & (((UInt32)1 << numBits) - 1);
res >>= numBits;
@@ -110,7 +122,7 @@ public:
UInt32 len = GetVal(res, 2);
return GetVal(res, 1 + len);
}
- void Generate()
+ void Generate(unsigned dictBits)
{
UInt32 pos = 0;
UInt32 rep0 = 1;
@@ -131,7 +143,7 @@ public:
{
UInt32 ppp = GetVal(res, 5) + 6;
res = RG->GetRnd();
- if (ppp > 30)
+ if (ppp > dictBits)
continue;
rep0 = /* (1 << ppp) +*/ GetVal(res, ppp);
res = RG->GetRnd();
@@ -275,15 +287,33 @@ static UInt64 GetFreq()
#endif
}
-#ifndef USE_POSIX_TIME
-static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; }
-#endif
+#ifdef USE_POSIX_TIME
-static UInt64 GetUserTime()
+struct CUserTime
+{
+ UInt64 Sum;
+ clock_t Prev;
+
+ void Init()
+ {
+ Prev = clock();
+ Sum = 0;
+ }
+
+ UInt64 GetUserTime()
+ {
+ clock_t v = clock();
+ Sum += v - Prev;
+ Prev = v;
+ return Sum;
+ }
+};
+
+#else
+
+static inline UInt64 GetTime64(const FILETIME &t) { return ((UInt64)t.dwHighDateTime << 32) | t.dwLowDateTime; }
+UInt64 GetWinUserTime()
{
- #ifdef USE_POSIX_TIME
- return clock();
- #else
FILETIME creationTime, exitTime, kernelTime, userTime;
if (
#ifdef UNDER_CE
@@ -294,9 +324,18 @@ static UInt64 GetUserTime()
, &creationTime, &exitTime, &kernelTime, &userTime) != 0)
return GetTime64(userTime) + GetTime64(kernelTime);
return (UInt64)GetTickCount() * 10000;
- #endif
}
+struct CUserTime
+{
+ UInt64 StartTime;
+
+ void Init() { StartTime = GetWinUserTime(); }
+ UInt64 GetUserTime() { return GetWinUserTime() - StartTime; }
+};
+
+#endif
+
static UInt64 GetUserFreq()
{
#ifdef USE_POSIX_TIME
@@ -309,7 +348,7 @@ static UInt64 GetUserFreq()
class CBenchProgressStatus
{
#ifndef _7ZIP_ST
- NWindows::NSynchronization::CCriticalSection CS;
+ NSynchronization::CCriticalSection CS;
#endif
public:
HRESULT Res;
@@ -317,14 +356,14 @@ public:
void SetResult(HRESULT res)
{
#ifndef _7ZIP_ST
- NWindows::NSynchronization::CCriticalSectionLock lock(CS);
+ NSynchronization::CCriticalSectionLock lock(CS);
#endif
Res = res;
}
HRESULT GetResult()
{
#ifndef _7ZIP_ST
- NWindows::NSynchronization::CCriticalSectionLock lock(CS);
+ NSynchronization::CCriticalSectionLock lock(CS);
#endif
return Res;
}
@@ -337,27 +376,31 @@ class CBenchProgressInfo:
public:
CBenchProgressStatus *Status;
CBenchInfo BenchInfo;
+ CUserTime UserTime;
HRESULT Res;
- IBenchCallback *callback;
- CBenchProgressInfo(): callback(0) {}
+ IBenchCallback *Callback;
+
+ CBenchProgressInfo(): Callback(0) {}
+ void SetStartTime();
+ void SetFinishTime(CBenchInfo &dest);
MY_UNKNOWN_IMP
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
};
-static void SetStartTime(CBenchInfo &bi)
+void CBenchProgressInfo::SetStartTime()
{
- bi.GlobalFreq = GetFreq();
- bi.UserFreq = GetUserFreq();
- bi.GlobalTime = ::GetTimeCount();
- bi.UserTime = ::GetUserTime();
+ BenchInfo.GlobalFreq = GetFreq();
+ BenchInfo.UserFreq = GetUserFreq();
+ BenchInfo.GlobalTime = ::GetTimeCount();
+ BenchInfo.UserTime = 0;
+ UserTime.Init();
}
-static void SetFinishTime(const CBenchInfo &biStart, CBenchInfo &dest)
+void CBenchProgressInfo::SetFinishTime(CBenchInfo &dest)
{
- dest.GlobalFreq = GetFreq();
- dest.UserFreq = GetUserFreq();
- dest.GlobalTime = ::GetTimeCount() - biStart.GlobalTime;
- dest.UserTime = ::GetUserTime() - biStart.UserTime;
+ dest = BenchInfo;
+ dest.GlobalTime = ::GetTimeCount() - BenchInfo.GlobalTime;
+ dest.UserTime = UserTime.GetUserTime();
}
STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
@@ -365,21 +408,21 @@ STDMETHODIMP CBenchProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64
HRESULT res = Status->GetResult();
if (res != S_OK)
return res;
- if (!callback)
+ if (!Callback)
return res;
- CBenchInfo info = BenchInfo;
- SetFinishTime(BenchInfo, info);
+ CBenchInfo info;
+ SetFinishTime(info);
if (Status->EncodeMode)
{
info.UnpackSize = *inSize;
info.PackSize = *outSize;
- res = callback->SetEncodeResult(info, false);
+ res = Callback->SetEncodeResult(info, false);
}
else
{
info.PackSize = BenchInfo.PackSize + *inSize;
info.UnpackSize = BenchInfo.UnpackSize + *outSize;
- res = callback->SetDecodeResult(info, false);
+ res = Callback->SetDecodeResult(info, false);
}
if (res != S_OK)
Status->SetResult(res);
@@ -406,12 +449,12 @@ static void NormalizeVals(UInt64 &v1, UInt64 &v2)
}
}
-UInt64 GetUsage(const CBenchInfo &info)
+UInt64 CBenchInfo::GetUsage() const
{
- UInt64 userTime = info.UserTime;
- UInt64 userFreq = info.UserFreq;
- UInt64 globalTime = info.GlobalTime;
- UInt64 globalFreq = info.GlobalFreq;
+ UInt64 userTime = UserTime;
+ UInt64 userFreq = UserFreq;
+ UInt64 globalTime = GlobalTime;
+ UInt64 globalFreq = GlobalFreq;
NormalizeVals(userTime, userFreq);
NormalizeVals(globalFreq, globalTime);
if (userFreq == 0)
@@ -421,19 +464,19 @@ UInt64 GetUsage(const CBenchInfo &info)
return userTime * globalFreq * 1000000 / userFreq / globalTime;
}
-UInt64 GetRatingPerUsage(const CBenchInfo &info, UInt64 rating)
+UInt64 CBenchInfo::GetRatingPerUsage(UInt64 rating) const
{
- UInt64 userTime = info.UserTime;
- UInt64 userFreq = info.UserFreq;
- UInt64 globalTime = info.GlobalTime;
- UInt64 globalFreq = info.GlobalFreq;
+ UInt64 userTime = UserTime;
+ UInt64 userFreq = UserFreq;
+ UInt64 globalTime = GlobalTime;
+ UInt64 globalFreq = GlobalFreq;
NormalizeVals(userFreq, userTime);
NormalizeVals(globalTime, globalFreq);
if (globalFreq == 0)
globalFreq = 1;
if (userTime == 0)
userTime = 1;
- return userFreq * globalTime / globalFreq * rating / userTime;
+ return userFreq * globalTime / globalFreq * rating / userTime;
}
static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq)
@@ -445,26 +488,74 @@ static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq)
return value * freq / elTime;
}
-UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 freq, UInt64 size)
+struct CBenchProps
+{
+ bool LzmaRatingMode;
+
+ UInt32 EncComplex;
+ UInt32 DecComplexCompr;
+ UInt32 DecComplexUnc;
+
+ CBenchProps(): LzmaRatingMode(false) {}
+ void SetLzmaCompexity();
+
+ UInt64 GeDecomprCommands(UInt64 packSize, UInt64 unpackSize)
+ {
+ return (packSize * DecComplexCompr + unpackSize * DecComplexUnc);
+ }
+
+ UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size);
+ UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations);
+};
+
+void CBenchProps::SetLzmaCompexity()
+{
+ DecComplexUnc = 4;
+ DecComplexCompr = 200;
+ LzmaRatingMode = true;
+}
+
+UInt64 CBenchProps::GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size)
{
- UInt64 t = GetLogSize(dictionarySize) - (kBenchMinDicLogSize << kSubBits);
- UInt64 numCommandsForOne = 870 + ((t * t * 5) >> (2 * kSubBits));
- UInt64 numCommands = (UInt64)(size) * numCommandsForOne;
+ if (dictSize < (1 << kBenchMinDicLogSize))
+ dictSize = (1 << kBenchMinDicLogSize);
+ UInt64 encComplex = EncComplex;
+ if (LzmaRatingMode)
+ {
+ UInt64 t = GetLogSize(dictSize) - (kBenchMinDicLogSize << kSubBits);
+ encComplex = 870 + ((t * t * 5) >> (2 * kSubBits));
+ }
+ UInt64 numCommands = (UInt64)size * encComplex;
return MyMultDiv64(numCommands, elapsedTime, freq);
}
-UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations)
+UInt64 CBenchProps::GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations)
{
- UInt64 numCommands = (inSize * 200 + outSize * 4) * numIterations;
+ UInt64 numCommands = (inSize * DecComplexCompr + outSize * DecComplexUnc) * numIterations;
return MyMultDiv64(numCommands, elapsedTime, freq);
}
+UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size)
+{
+ CBenchProps props;
+ props.SetLzmaCompexity();
+ return props.GetCompressRating(dictSize, elapsedTime, freq, size);
+}
+
+UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations)
+{
+ CBenchProps props;
+ props.SetLzmaCompexity();
+ return props.GetDecompressRating(elapsedTime, freq, outSize, inSize, numIterations);
+}
+
struct CEncoderInfo;
struct CEncoderInfo
{
#ifndef _7ZIP_ST
NWindows::CThread thread[2];
+ UInt32 NumDecoderSubThreads;
#endif
CMyComPtr<ICompressCoder> encoder;
CBenchProgressInfo *progressInfoSpec[2];
@@ -490,17 +581,22 @@ struct CEncoderInfo
CBenchmarkOutStream *outStreamSpec;
CMyComPtr<ISequentialOutStream> outStream;
IBenchCallback *callback;
+ IBenchPrintCallback *printCallback;
UInt32 crc;
UInt32 kBufferSize;
UInt32 compressedSize;
CBenchRandomGenerator rg;
CBenchmarkOutStream *propStreamSpec;
CMyComPtr<ISequentialOutStream> propStream;
- HRESULT Init(UInt32 dictionarySize, UInt32 numThreads, CBaseRandomGenerator *rg);
+ HRESULT Init(
+ const COneMethodInfo &method,
+ UInt32 uncompressedDataSize,
+ unsigned generateDictBits,
+ CBaseRandomGenerator *rg);
HRESULT Encode();
HRESULT Decode(UInt32 decoderIndex);
- CEncoderInfo(): outStreamSpec(0), callback(0), propStreamSpec(0) {}
+ CEncoderInfo(): outStreamSpec(0), callback(0), printCallback(0), propStreamSpec(0) {}
#ifndef _7ZIP_ST
static THREAD_FUNC_DECL EncodeThreadFunction(void *param)
@@ -550,14 +646,20 @@ struct CEncoderInfo
#endif
};
-HRESULT CEncoderInfo::Init(UInt32 dictionarySize, UInt32 numThreads, CBaseRandomGenerator *rgLoc)
+static const UInt32 k_LZMA = 0x030101;
+
+HRESULT CEncoderInfo::Init(
+ const COneMethodInfo &method,
+ UInt32 uncompressedDataSize,
+ unsigned generateDictBits,
+ CBaseRandomGenerator *rgLoc)
{
rg.Set(rgLoc);
- kBufferSize = dictionarySize + kAdditionalSize;
- UInt32 kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize;
+ kBufferSize = uncompressedDataSize;
+ UInt32 kCompressedBufferSize = (kBufferSize - kBufferSize / 4) + kCompressedAdditionalSize;
if (!rg.Alloc(kBufferSize))
return E_OUTOFMEMORY;
- rg.Generate();
+ rg.Generate(generateDictBits);
crc = CrcCalc(rg.Buffer, rg.BufferSize);
outStreamSpec = new CBenchmarkOutStream;
@@ -576,31 +678,26 @@ HRESULT CEncoderInfo::Init(UInt32 dictionarySize, UInt32 numThreads, CBaseRandom
return E_OUTOFMEMORY;
propStreamSpec->Init();
- PROPID propIDs[] =
+
{
- NCoderPropID::kDictionarySize,
- NCoderPropID::kNumThreads
- };
- const int kNumProps = sizeof(propIDs) / sizeof(propIDs[0]);
- PROPVARIANT props[kNumProps];
- props[0].vt = VT_UI4;
- props[0].ulVal = dictionarySize;
-
- props[1].vt = VT_UI4;
- props[1].ulVal = numThreads;
+ CMyComPtr<ICompressSetCoderProperties> scp;
+ encoder.QueryInterface(IID_ICompressSetCoderProperties, &scp);
+ if (scp)
+ {
+ UInt64 reduceSize = uncompressedDataSize;
+ RINOK(method.SetCoderProps(scp, &reduceSize));
+ }
+ else
+ {
+ if (method.AreThereNonOptionalProps())
+ return E_FAIL;
+ }
- {
- CMyComPtr<ICompressSetCoderProperties> setCoderProperties;
- RINOK(encoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties));
- if (!setCoderProperties)
- return E_FAIL;
- RINOK(setCoderProperties->SetCoderProperties(propIDs, props, kNumProps));
-
- CMyComPtr<ICompressWriteCoderProperties> writeCoderProperties;
- encoder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProperties);
- if (writeCoderProperties)
+ CMyComPtr<ICompressWriteCoderProperties> writeCoderProps;
+ encoder.QueryInterface(IID_ICompressWriteCoderProperties, &writeCoderProps);
+ if (writeCoderProps)
{
- RINOK(writeCoderProperties->WriteCoderProperties(propStream));
+ RINOK(writeCoderProps->WriteCoderProperties(propStream));
}
}
return S_OK;
@@ -625,9 +722,9 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
CMyComPtr<ISequentialInStream> inStream = inStreamSpec;
CMyComPtr<ICompressCoder> &decoder = decoders[decoderIndex];
- CMyComPtr<ICompressSetDecoderProperties2> compressSetDecoderProperties;
- decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &compressSetDecoderProperties);
- if (!compressSetDecoderProperties)
+ CMyComPtr<ICompressSetDecoderProperties2> setDecProps;
+ decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecProps);
+ if (!setDecProps && propStreamSpec->Pos != 0)
return E_FAIL;
CCrcOutStream *crcOutStreamSpec = new CCrcOutStream;
@@ -637,12 +734,30 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
pi->BenchInfo.UnpackSize = 0;
pi->BenchInfo.PackSize = 0;
+ #ifndef _7ZIP_ST
+ {
+ CMyComPtr<ICompressSetCoderMt> setCoderMt;
+ decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt);
+ if (setCoderMt)
+ {
+ RINOK(setCoderMt->SetNumberOfThreads(NumDecoderSubThreads));
+ }
+ }
+ #endif
+
for (UInt32 j = 0; j < NumIterations; j++)
{
+ if (printCallback)
+ {
+ RINOK(printCallback->CheckBreak());
+ }
inStreamSpec->Init(outStreamSpec->Buffer, compressedSize);
crcOutStreamSpec->Init();
- RINOK(compressSetDecoderProperties->SetDecoderProperties2(propStreamSpec->Buffer, propStreamSpec->Pos));
+ if (setDecProps)
+ {
+ RINOK(setDecProps->SetDecoderProperties2(propStreamSpec->Buffer, propStreamSpec->Pos));
+ }
UInt64 outSize = kBufferSize;
RINOK(decoder->Code(inStream, crcOutStream, 0, &outSize, progressInfo[decoderIndex]));
if (CRC_GET_DIGEST(crcOutStreamSpec->Crc) != crc)
@@ -654,7 +769,7 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
return S_OK;
}
-static const UInt32 kNumThreadsMax = (1 << 16);
+static const UInt32 kNumThreadsMax = (1 << 12);
struct CBenchEncoders
{
@@ -663,44 +778,66 @@ struct CBenchEncoders
~CBenchEncoders() { delete []encoders; }
};
-HRESULT LzmaBench(
- DECL_EXTERNAL_CODECS_LOC_VARS
- UInt32 numThreads, UInt32 dictionarySize, IBenchCallback *callback)
+static HRESULT MethodBench(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ bool oldLzmaBenchMode,
+ UInt32 numThreads,
+ const COneMethodInfo &method2,
+ UInt32 uncompressedDataSize,
+ unsigned generateDictBits,
+ IBenchPrintCallback *printCallback,
+ IBenchCallback *callback,
+ CBenchProps *benchProps)
{
- UInt32 numEncoderThreads =
- #ifndef _7ZIP_ST
- (numThreads > 1 ? numThreads / 2 : 1);
- #else
- 1;
- #endif
- UInt32 numSubDecoderThreads =
- #ifndef _7ZIP_ST
- (numThreads > 1 ? 2 : 1);
- #else
- 1;
- #endif
- if (dictionarySize < (1 << kBenchMinDicLogSize) || numThreads < 1 || numEncoderThreads > kNumThreadsMax)
- {
+ COneMethodInfo method = method2;
+ UInt64 methodId;
+ UInt32 numInStreams, numOutStreams;
+ if (!FindMethod(
+ EXTERNAL_CODECS_LOC_VARS
+ method.MethodName, methodId, numInStreams, numOutStreams))
+ return E_NOTIMPL;
+ if (numInStreams != 1 || numOutStreams != 1)
+ return E_INVALIDARG;
+
+ UInt32 numEncoderThreads = 1;
+ UInt32 numSubDecoderThreads = 1;
+
+ #ifndef _7ZIP_ST
+ numEncoderThreads = numThreads;
+
+ if (oldLzmaBenchMode && methodId == k_LZMA)
+ {
+ bool fixedNumber;
+ UInt32 numLzmaThreads = method.Get_Lzma_NumThreads(fixedNumber);
+ if (!fixedNumber && numThreads == 1)
+ method.AddNumThreadsProp(1);
+ if (numThreads > 1 && numLzmaThreads > 1)
+ {
+ numEncoderThreads = numThreads / 2;
+ numSubDecoderThreads = 2;
+ }
+ }
+ #endif
+
+ if (numThreads < 1 || numEncoderThreads > kNumThreadsMax)
return E_INVALIDARG;
- }
CBenchEncoders encodersSpec(numEncoderThreads);
CEncoderInfo *encoders = encodersSpec.encoders;
-
UInt32 i;
for (i = 0; i < numEncoderThreads; i++)
{
CEncoderInfo &encoder = encoders[i];
encoder.callback = (i == 0) ? callback : 0;
+ encoder.printCallback = printCallback;
- const UInt32 kLzmaId = 0x030101;
- RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS kLzmaId, encoder.encoder, true));
+ RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, encoder.encoder, true));
if (!encoder.encoder)
return E_NOTIMPL;
for (UInt32 j = 0; j < numSubDecoderThreads; j++)
{
- RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS kLzmaId, encoder.decoders[j], false));
+ RINOK(CreateCoder(EXTERNAL_CODECS_LOC_VARS methodId, encoder.decoders[j], false));
if (!encoder.decoders[j])
return E_NOTIMPL;
}
@@ -710,7 +847,7 @@ HRESULT LzmaBench(
rg.Init();
for (i = 0; i < numEncoderThreads; i++)
{
- RINOK(encoders[i].Init(dictionarySize, numThreads, &rg));
+ RINOK(encoders[i].Init(method, uncompressedDataSize, generateDictBits, &rg));
}
CBenchProgressStatus status;
@@ -727,9 +864,10 @@ HRESULT LzmaBench(
}
if (i == 0)
{
- encoder.progressInfoSpec[0]->callback = callback;
- encoder.progressInfoSpec[0]->BenchInfo.NumIterations = numEncoderThreads;
- SetStartTime(encoder.progressInfoSpec[0]->BenchInfo);
+ CBenchProgressInfo *bpi = encoder.progressInfoSpec[0];
+ bpi->Callback = callback;
+ bpi->BenchInfo.NumIterations = numEncoderThreads;
+ bpi->SetStartTime();
}
#ifndef _7ZIP_ST
@@ -756,7 +894,7 @@ HRESULT LzmaBench(
CBenchInfo info;
- SetFinishTime(encoders[0].progressInfoSpec[0]->BenchInfo, info);
+ encoders[0].progressInfoSpec[0]->SetFinishTime(info);
info.UnpackSize = 0;
info.PackSize = 0;
info.NumIterations = 1; // progressInfoSpec->NumIterations;
@@ -776,16 +914,24 @@ HRESULT LzmaBench(
for (i = 0; i < numEncoderThreads; i++)
{
CEncoderInfo &encoder = encoders[i];
- encoder.NumIterations = 2 + kUncompressMinBlockSize / encoder.kBufferSize;
if (i == 0)
{
- encoder.progressInfoSpec[0]->callback = callback;
- encoder.progressInfoSpec[0]->BenchInfo.NumIterations = numDecoderThreads;
- SetStartTime(encoder.progressInfoSpec[0]->BenchInfo);
+ encoder.NumIterations = (UInt32)(1 + kUncompressMinBlockSize /
+ benchProps->GeDecomprCommands(encoder.compressedSize, encoder.kBufferSize));
+ CBenchProgressInfo *bpi = encoder.progressInfoSpec[0];
+ bpi->Callback = callback;
+ bpi->BenchInfo.NumIterations = numDecoderThreads;
+ bpi->SetStartTime();
}
+ else
+ encoder.NumIterations = encoders[0].NumIterations;
#ifndef _7ZIP_ST
+ {
+ int numSubThreads = method.Get_NumThreads();
+ encoder.NumDecoderSubThreads = (numSubThreads <= 0) ? 1 : numSubThreads;
+ }
if (numDecoderThreads > 1)
{
for (UInt32 j = 0; j < numSubDecoderThreads; j++)
@@ -818,7 +964,7 @@ HRESULT LzmaBench(
RINOK(res);
#endif
RINOK(status.Res);
- SetFinishTime(encoders[0].progressInfoSpec[0]->BenchInfo, info);
+ encoders[0].progressInfoSpec[0]->SetFinishTime(info);
#ifndef _7ZIP_ST
#ifdef UNDER_CE
if (numDecoderThreads > 1)
@@ -966,7 +1112,7 @@ bool CrcInternalTest()
return true;
}
-HRESULT CrcBench(UInt32 numThreads, UInt32 bufferSize, UInt64 &speed)
+static HRESULT CrcBench(UInt32 numThreads, UInt32 bufferSize, UInt64 &speed)
{
if (numThreads == 0)
numThreads = 1;
@@ -1026,3 +1172,462 @@ HRESULT CrcBench(UInt32 numThreads, UInt32 bufferSize, UInt64 &speed)
speed = MyMultDiv64(size, timeVal, GetFreq());
return S_OK;
}
+
+struct CBenchMethod
+{
+ unsigned dictBits;
+ UInt32 EncComplex;
+ UInt32 DecComplexCompr;
+ UInt32 DecComplexUnc;
+ const char *Name;
+};
+
+static const CBenchMethod g_Bench[] =
+{
+ { 17, 340, 155, 20, "LZMA:x1" },
+ { 24, 1182, 155, 20, "LZMA:x5:mt1" },
+ { 24, 1182, 155, 20, "LZMA:x5:mt2" },
+ { 16, 124, 47, 14, "Deflate:x1" },
+ { 16, 376, 47, 14, "Deflate:x5" },
+ { 16, 1084, 47, 14, "Deflate:x7" },
+ { 17, 420, 47, 14, "Deflate64:x5" },
+ { 15, 590, 69, 70, "BZip2:x1" },
+ { 19, 792, 119, 119, "BZip2:x5" },
+ #ifndef UNDER_CE
+ { 19, 792, 119, 119, "BZip2:x5:mt2" },
+ #endif
+ { 19, 2500, 118, 118, "BZip2:x7" },
+ { 18, 1010, 0, 1155, "PPMD:x1" },
+ { 22, 1650, 0, 1830, "PPMD:x5" }
+};
+
+struct CTotalBenchRes
+{
+ UInt64 NumIterations;
+ UInt64 Rating;
+ UInt64 Usage;
+ UInt64 RPU;
+ void Init() { NumIterations = 0; Rating = 0; Usage = 0; RPU = 0; }
+ void Normalize()
+ {
+ if (NumIterations == 0)
+ return;
+ Rating /= NumIterations;
+ Usage /= NumIterations;
+ RPU /= NumIterations;
+ NumIterations = 1;
+ }
+ void SetMid(const CTotalBenchRes &r1, const CTotalBenchRes &r2)
+ {
+ Rating = (r1.Rating + r2.Rating) / 2;
+ Usage = (r1.Usage + r2.Usage) / 2;
+ RPU = (r1.RPU + r2.RPU) / 2;
+ NumIterations = (r1.NumIterations + r2.NumIterations) / 2;
+ }
+};
+
+static void PrintNumber(IBenchPrintCallback &f, UInt64 value, int size, bool withSpace = true)
+{
+ char s[128];
+ int startPos = (int)sizeof(s) - 32;
+ memset(s, ' ', startPos);
+ ConvertUInt64ToString(value, s + startPos);
+ if (withSpace)
+ {
+ startPos--;
+ size++;
+ }
+ int len = (int)strlen(s + startPos);
+ if (size > len)
+ {
+ startPos -= (size - len);
+ if (startPos < 0)
+ startPos = 0;
+ }
+ f.Print(s + startPos);
+}
+
+static void PrintRating(IBenchPrintCallback &f, UInt64 rating)
+{
+ PrintNumber(f, rating / 1000000, 6);
+}
+
+static void PrintResults(IBenchPrintCallback &f, UInt64 usage, UInt64 rpu, UInt64 rating)
+{
+ PrintNumber(f, (usage + 5000) / 10000, 5);
+ PrintRating(f, rpu);
+ PrintRating(f, rating);
+}
+
+static void PrintResults(IBenchPrintCallback &f, const CBenchInfo &info, UInt64 rating, CTotalBenchRes &res)
+{
+ UInt64 speed = MyMultDiv64(info.UnpackSize, info.GlobalTime, info.GlobalFreq);
+ PrintNumber(f, speed / 1024, 7);
+ UInt64 usage = info.GetUsage();
+ UInt64 rpu = info.GetRatingPerUsage(rating);
+ PrintResults(f, usage, rpu, rating);
+ res.NumIterations++;
+ res.RPU += rpu;
+ res.Rating += rating;
+ res.Usage += usage;
+}
+
+static void PrintTotals(IBenchPrintCallback &f, const CTotalBenchRes &res)
+{
+ f.Print(" ");
+ PrintResults(f, res.Usage, res.RPU, res.Rating);
+}
+
+static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString, UInt64 size, const char *threadsString, UInt32 numThreads)
+{
+ f.Print("RAM ");
+ f.Print(sizeString);
+ PrintNumber(f, (size >> 20), 5, true);
+ f.Print(" MB, # ");
+ f.Print(threadsString);
+ PrintNumber(f, numThreads, 3, true);
+ f.NewLine();
+}
+
+struct CBenchCallbackToPrint: public IBenchCallback
+{
+ CBenchProps BenchProps;
+ CTotalBenchRes EncodeRes;
+ CTotalBenchRes DecodeRes;
+ IBenchPrintCallback *_file;
+ UInt32 DictSize;
+
+ void Init() { EncodeRes.Init(); DecodeRes.Init(); }
+ void Normalize() { EncodeRes.Normalize(); DecodeRes.Normalize(); }
+ HRESULT SetEncodeResult(const CBenchInfo &info, bool final);
+ HRESULT SetDecodeResult(const CBenchInfo &info, bool final);
+ void Print(const char *string);
+ void NewLine();
+ void PrintLeftAligned(const char *string, unsigned size);
+};
+
+HRESULT CBenchCallbackToPrint::SetEncodeResult(const CBenchInfo &info, bool final)
+{
+ RINOK(_file->CheckBreak());
+ if (final)
+ {
+ UInt64 rating = BenchProps.GetCompressRating(DictSize, info.GlobalTime, info.GlobalFreq, info.UnpackSize);
+ PrintResults(*_file, info, rating, EncodeRes);
+ }
+ return S_OK;
+}
+
+static const char *kSep = " | ";
+
+
+HRESULT CBenchCallbackToPrint::SetDecodeResult(const CBenchInfo &info, bool final)
+{
+ RINOK(_file->CheckBreak());
+ if (final)
+ {
+ UInt64 rating = BenchProps.GetDecompressRating(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations);
+ _file->Print(kSep);
+ CBenchInfo info2 = info;
+ info2.UnpackSize *= info2.NumIterations;
+ info2.PackSize *= info2.NumIterations;
+ info2.NumIterations = 1;
+ PrintResults(*_file, info2, rating, DecodeRes);
+ }
+ return S_OK;
+}
+
+void CBenchCallbackToPrint::Print(const char *s)
+{
+ _file->Print(s);
+}
+
+void CBenchCallbackToPrint::NewLine()
+{
+ _file->NewLine();
+}
+
+void CBenchCallbackToPrint::PrintLeftAligned(const char *s, unsigned size)
+{
+ AString s2 = s;
+ for (unsigned len = (unsigned)strlen(s); len < size; len++)
+ s2 += ' ';
+ Print(s2);
+}
+
+static HRESULT TotalBench(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ UInt32 numThreads, UInt32 unpackSize, IBenchPrintCallback *printCallback, CBenchCallbackToPrint *callback)
+{
+ for (unsigned i = 0; i < sizeof(g_Bench) / sizeof(g_Bench[0]); i++)
+ {
+ CBenchMethod bench = g_Bench[i];
+ callback->PrintLeftAligned(bench.Name, 12);
+ callback->BenchProps.DecComplexUnc = bench.DecComplexUnc;
+ callback->BenchProps.DecComplexCompr = bench.DecComplexCompr;
+ callback->BenchProps.EncComplex = bench.EncComplex;
+ COneMethodInfo method;
+ NCOM::CPropVariant propVariant;
+ propVariant = bench.Name;
+ RINOK(method.ParseMethodFromPROPVARIANT(L"", propVariant));
+
+ HRESULT res = MethodBench(
+ EXTERNAL_CODECS_LOC_VARS
+ false, numThreads, method, unpackSize, bench.dictBits,
+ printCallback, callback, &callback->BenchProps);
+ if (res == E_NOTIMPL)
+ callback->Print(" ---");
+ else
+ {
+ RINOK(res);
+ }
+ callback->NewLine();
+ }
+ return S_OK;
+}
+
+struct CTempValues
+{
+ UInt64 *Values;
+ CTempValues(UInt32 num) { Values = new UInt64[num]; }
+ ~CTempValues() { delete []Values; }
+};
+
+static void String_to_PropVariant(const UString &s, NCOM::CPropVariant &prop)
+{
+ const wchar_t *endPtr;
+ UInt64 result = ConvertStringToUInt64(s, &endPtr);
+ if (endPtr - (const wchar_t *)s != s.Length())
+ prop = s;
+ else if (result <= 0xFFFFFFFF)
+ prop = (UInt32)result;
+ else
+ prop = result;
+}
+
+HRESULT Bench(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ IBenchPrintCallback *printCallback,
+ IBenchCallback *benchCallback,
+ const CObjectVector<CProperty> props,
+ UInt32 numIterations,
+ bool multiDict)
+{
+ if (!CrcInternalTest())
+ return S_FALSE;
+
+ UInt32 numCPUs = 1;
+ UInt64 ramSize = (UInt64)512 << 20;
+ #ifndef _7ZIP_ST
+ numCPUs = NSystem::GetNumberOfProcessors();
+ #endif
+ #if !defined(_7ZIP_ST) || defined(_WIN32)
+ ramSize = NSystem::GetRamSize();
+ #endif
+ UInt32 numThreads = numCPUs;
+
+ if (printCallback)
+ PrintRequirements(*printCallback, "size: ", ramSize, "CPU hardware threads:", numCPUs);
+
+ COneMethodInfo method;
+ int i;
+ for (i = 0; i < props.Size(); i++)
+ {
+ const CProperty &property = props[i];
+ NCOM::CPropVariant propVariant;
+ UString name = property.Name;
+ name.MakeUpper();
+ if (!property.Value.IsEmpty())
+ String_to_PropVariant(property.Value, propVariant);
+ if (name.Left(2).CompareNoCase(L"MT") == 0)
+ {
+ #ifndef _7ZIP_ST
+ RINOK(ParseMtProp(name.Mid(2), propVariant, numCPUs, numThreads));
+ #endif
+ continue;
+ }
+ RINOK(method.ParseMethodFromPROPVARIANT(name, propVariant));
+ }
+
+ UInt32 dict;
+ bool dictIsDefined = method.Get_DicSize(dict);
+
+ if (method.MethodName.IsEmpty())
+ method.MethodName = L"LZMA";
+
+ if (benchCallback)
+ {
+ CBenchProps benchProps;
+ benchProps.SetLzmaCompexity();
+ UInt32 dictSize = method.Get_Lzma_DicSize();
+ UInt32 uncompressedDataSize = kAdditionalSize + dictSize;
+ return MethodBench(
+ EXTERNAL_CODECS_LOC_VARS
+ true, numThreads,
+ method, uncompressedDataSize,
+ kOldLzmaDictBits, printCallback, benchCallback, &benchProps);
+ }
+
+ if (method.MethodName.CompareNoCase(L"CRC") == 0)
+ {
+ if (!printCallback)
+ return S_FALSE;
+ IBenchPrintCallback &f = *printCallback;
+ if (!dictIsDefined)
+ dict = (1 << 24);
+
+ CTempValues speedTotals(numThreads);
+ f.NewLine();
+ f.Print("Size");
+ for (UInt32 ti = 0; ti < numThreads; ti++)
+ {
+ PrintNumber(f, ti + 1, 5);
+ speedTotals.Values[ti] = 0;
+ }
+ f.NewLine();
+ f.NewLine();
+
+ UInt64 numSteps = 0;
+ for (UInt32 i = 0; i < numIterations; i++)
+ {
+ for (int pow = 10; pow < 32; pow++)
+ {
+ UInt32 bufSize = (UInt32)1 << pow;
+ if (bufSize > dict)
+ break;
+ PrintNumber(f, pow, 2, false);
+ f.Print(": ");
+ for (UInt32 ti = 0; ti < numThreads; ti++)
+ {
+ RINOK(f.CheckBreak());
+ UInt64 speed;
+ RINOK(CrcBench(ti + 1, bufSize, speed));
+ PrintNumber(f, (speed >> 20), 5);
+ speedTotals.Values[ti] += speed;
+ }
+ f.NewLine();
+ numSteps++;
+ }
+ }
+ if (numSteps != 0)
+ {
+ f.NewLine();
+ f.Print("Avg:");
+ for (UInt32 ti = 0; ti < numThreads; ti++)
+ PrintNumber(f, ((speedTotals.Values[ti] / numSteps) >> 20), 5);
+ f.NewLine();
+ }
+ return S_OK;
+ }
+
+ CBenchCallbackToPrint callback;
+ callback.Init();
+ callback._file = printCallback;
+
+ if (!dictIsDefined)
+ {
+ int dicSizeLog;
+ for (dicSizeLog = 25; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--)
+ if (GetBenchMemoryUsage(numThreads, ((UInt32)1 << dicSizeLog)) + (8 << 20) <= ramSize)
+ break;
+ dict = (1 << dicSizeLog);
+ }
+
+ IBenchPrintCallback &f = *printCallback;
+ PrintRequirements(f, "usage:", GetBenchMemoryUsage(numThreads, dict), "Benchmark threads: ", numThreads);
+
+ bool totalBenchMode = (method.MethodName == L"*");
+ f.NewLine();
+ f.Print(totalBenchMode ? "Method " : "Dict");
+ f.Print(" Compressing | Decompressing");
+ f.NewLine();
+ const char *kSpaces = totalBenchMode ? " " : " ";
+ f.Print(kSpaces);
+ int j;
+
+ for (j = 0; j < 2; j++)
+ {
+ f.Print(" Speed Usage R/U Rating");
+ if (j == 0)
+ f.Print(kSep);
+ }
+ f.NewLine();
+ f.Print(kSpaces);
+ for (j = 0; j < 2; j++)
+ {
+ f.Print(" KB/s % MIPS MIPS");
+ if (j == 0)
+ f.Print(kSep);
+ }
+ f.NewLine();
+ f.NewLine();
+
+ if (totalBenchMode)
+ {
+ if (!dictIsDefined)
+ dict =
+ #ifdef UNDER_CE
+ (UInt64)1 << 20;
+ #else
+ (UInt64)1 << 24;
+ #endif
+ for (UInt32 i = 0; i < numIterations; i++)
+ {
+ if (i != 0)
+ printCallback->NewLine();
+ HRESULT res = TotalBench(
+ EXTERNAL_CODECS_LOC_VARS
+ numThreads, dict, printCallback, &callback);
+ RINOK(res);
+ }
+ }
+ else
+ {
+
+ callback.BenchProps.SetLzmaCompexity();
+
+ for (i = 0; i < (int)numIterations; i++)
+ {
+ const int kStartDicLog = 22;
+ int pow = (dict < ((UInt32)1 << kStartDicLog)) ? kBenchMinDicLogSize : kStartDicLog;
+ if (!multiDict)
+ pow = 31;
+ while (((UInt32)1 << pow) > dict)
+ pow--;
+ for (; ((UInt32)1 << pow) <= dict; pow++)
+ {
+ PrintNumber(f, pow, 2, false);
+ f.Print(":");
+ callback.DictSize = (UInt32)1 << pow;
+
+ UInt32 uncompressedDataSize = kAdditionalSize + callback.DictSize;
+
+ HRESULT res = MethodBench(
+ EXTERNAL_CODECS_LOC_VARS
+ true, numThreads,
+ method, uncompressedDataSize,
+ kOldLzmaDictBits, printCallback, &callback, &callback.BenchProps);
+ f.NewLine();
+ RINOK(res);
+ if (!multiDict)
+ break;
+ }
+ }
+ }
+ callback.Normalize();
+ f.Print("----------------------------------------------------------------");
+ f.NewLine();
+ f.Print("Avr:");
+ const char *kSpaces2 = totalBenchMode ? " " : "";
+ f.Print(kSpaces2);
+ PrintTotals(f, callback.EncodeRes);
+ f.Print(" ");
+ PrintTotals(f, callback.DecodeRes);
+ f.NewLine();
+ f.Print("Tot:");
+ f.Print(kSpaces2);
+ CTotalBenchRes midRes;
+ midRes.SetMid(callback.EncodeRes, callback.DecodeRes);
+ PrintTotals(f, midRes);
+ f.NewLine();
+ return S_OK;
+}
diff --git a/CPP/7zip/UI/Common/Bench.h b/CPP/7zip/UI/Common/Bench.h
index a8d02a19..46146e24 100755
--- a/CPP/7zip/UI/Common/Bench.h
+++ b/CPP/7zip/UI/Common/Bench.h
@@ -4,6 +4,7 @@
#define __7ZIP_BENCH_H
#include "../../Common/CreateCoder.h"
+#include "../../UI/Common/Property.h"
struct CBenchInfo
{
@@ -14,7 +15,10 @@ struct CBenchInfo
UInt64 UnpackSize;
UInt64 PackSize;
UInt32 NumIterations;
+
CBenchInfo(): NumIterations(0) {}
+ UInt64 GetUsage() const;
+ UInt64 GetRatingPerUsage(UInt64 rating) const;
};
struct IBenchCallback
@@ -23,20 +27,27 @@ struct IBenchCallback
virtual HRESULT SetDecodeResult(const CBenchInfo &info, bool final) = 0;
};
-UInt64 GetUsage(const CBenchInfo &benchOnfo);
-UInt64 GetRatingPerUsage(const CBenchInfo &info, UInt64 rating);
-UInt64 GetCompressRating(UInt32 dictionarySize, UInt64 elapsedTime, UInt64 freq, UInt64 size);
+UInt64 GetCompressRating(UInt32 dictSize, UInt64 elapsedTime, UInt64 freq, UInt64 size);
UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt64 inSize, UInt32 numIterations);
-HRESULT LzmaBench(
- DECL_EXTERNAL_CODECS_LOC_VARS
- UInt32 numThreads, UInt32 dictionarySize, IBenchCallback *callback);
-
const int kBenchMinDicLogSize = 18;
UInt64 GetBenchMemoryUsage(UInt32 numThreads, UInt32 dictionary);
-bool CrcInternalTest();
-HRESULT CrcBench(UInt32 numThreads, UInt32 bufferSize, UInt64 &speed);
+struct IBenchPrintCallback
+{
+ virtual void Print(const char *s) = 0;
+ virtual void NewLine() = 0;
+ virtual HRESULT CheckBreak() = 0;
+};
+
+HRESULT Bench(
+ DECL_EXTERNAL_CODECS_LOC_VARS
+ IBenchPrintCallback *printCallback,
+ IBenchCallback *benchCallback,
+ const CObjectVector<CProperty> props,
+ UInt32 numIterations,
+ bool multiDict
+ );
#endif
diff --git a/CPP/7zip/UI/Common/CompressCall.cpp b/CPP/7zip/UI/Common/CompressCall.cpp
index c2685f79..eb20d5cc 100755
--- a/CPP/7zip/UI/Common/CompressCall.cpp
+++ b/CPP/7zip/UI/Common/CompressCall.cpp
@@ -7,12 +7,13 @@
#include "Common/Random.h"
#include "Common/StringConvert.h"
+#include "Windows/DLL.h"
+#include "Windows/Error.h"
#include "Windows/FileDir.h"
#include "Windows/FileMapping.h"
#include "Windows/Process.h"
#include "Windows/Synchronization.h"
-#include "../FileManager/ProgramLocation.h"
#include "../FileManager/RegistryUtils.h"
#include "CompressCall.h"
@@ -31,10 +32,13 @@ static LPCWSTR kArcIncludeSwitches = L" -an -ai";
static LPCWSTR kStopSwitchParsing = L" --";
static LPCWSTR kLargePagesDisable = L" -slp-";
+extern HWND g_HWND;
+
UString GetQuotedString(const UString &s)
{
return UString(L'\"') + s + UString(L'\"');
}
+
static void ErrorMessage(LPCWSTR message)
{
MessageBoxW(g_HWND, message, L"7-Zip", MB_ICONERROR | MB_OK);
@@ -42,7 +46,7 @@ static void ErrorMessage(LPCWSTR message)
static void ErrorMessageHRESULT(HRESULT res, LPCWSTR s = NULL)
{
- UString s2 = HResultToMessage(res);
+ UString s2 = NError::MyFormatMessageW(res);
if (s)
{
s2 += L'\n';
@@ -80,9 +84,7 @@ static void AddLagePagesSwitch(UString &params)
static UString Get7zGuiPath()
{
- UString path;
- GetProgramFolderPath(path);
- return path + L"7zG.exe";
+ return fs2us(NWindows::NDLL::GetModuleDirPrefix()) + L"7zG.exe";
}
class CRandNameGenerator
@@ -238,9 +240,9 @@ HRESULT TestArchives(const UStringVector &arcPaths)
MY_TRY_FINISH
}
-HRESULT Benchmark()
+HRESULT Benchmark(bool totalMode)
{
MY_TRY_BEGIN
- return MyCreateProcess(Get7zGuiPath(), L'b', 0, false, NULL);
+ return MyCreateProcess(Get7zGuiPath(), totalMode ? L"b -mm=*" : L"b", 0, false, NULL);
MY_TRY_FINISH
}
diff --git a/CPP/7zip/UI/Common/CompressCall.h b/CPP/7zip/UI/Common/CompressCall.h
index fc18df57..f777b9f2 100755
--- a/CPP/7zip/UI/Common/CompressCall.h
+++ b/CPP/7zip/UI/Common/CompressCall.h
@@ -7,9 +7,6 @@
UString GetQuotedString(const UString &s);
-extern HWND g_HWND;
-UString HResultToMessage(HRESULT errorCode);
-
HRESULT CompressFiles(
const UString &arcPathPrefix,
const UString &arcName,
@@ -19,6 +16,6 @@ HRESULT CompressFiles(
HRESULT ExtractArchives(const UStringVector &arcPaths, const UString &outFolder, bool showDialog);
HRESULT TestArchives(const UStringVector &arcPaths);
-HRESULT Benchmark();
+HRESULT Benchmark(bool totalMode);
#endif
diff --git a/CPP/7zip/UI/Common/CompressCall2.cpp b/CPP/7zip/UI/Common/CompressCall2.cpp
index 473f7d93..ab483d2f 100755
--- a/CPP/7zip/UI/Common/CompressCall2.cpp
+++ b/CPP/7zip/UI/Common/CompressCall2.cpp
@@ -14,6 +14,8 @@
#include "CompressCall.h"
+extern HWND g_HWND;
+
#define MY_TRY_BEGIN try {
#define MY_TRY_FINISH } \
catch(CSystemException &e) { result = e.ErrorCode; } \
@@ -110,7 +112,7 @@ static HRESULT ExtractGroupCommand(const UStringVector &arcPaths,
CREATE_CODECS
CExtractOptions eo;
- eo.OutputDir = outFolder;
+ eo.OutputDir = us2fs(outFolder);
eo.TestMode = testMode;
CExtractCallbackImp *ecs = new CExtractCallbackImp;
@@ -158,7 +160,7 @@ HRESULT TestArchives(const UStringVector &arcPaths)
return ExtractGroupCommand(arcPaths, true, UString(), true);
}
-HRESULT Benchmark()
+HRESULT Benchmark(bool totalMode)
{
HRESULT result;
MY_TRY_BEGIN
@@ -168,11 +170,19 @@ HRESULT Benchmark()
CObjectVector<CCodecInfoEx> externalCodecs;
RINOK(LoadExternalCodecs(codecs, externalCodecs));
#endif
+ CObjectVector<CProperty> props;
+ if (totalMode)
+ {
+ CProperty prop;
+ prop.Name = L"m";
+ prop.Value = L"*";
+ props.Add(prop);
+ }
result = Benchmark(
#ifdef EXTERNAL_CODECS
codecs, &externalCodecs,
#endif
- (UInt32)-1, (UInt32)-1, g_HWND);
+ props, g_HWND);
MY_TRY_FINISH
return result;
}
diff --git a/CPP/7zip/UI/Common/DirItem.h b/CPP/7zip/UI/Common/DirItem.h
index 29cc60d9..6d6dc673 100755
--- a/CPP/7zip/UI/Common/DirItem.h
+++ b/CPP/7zip/UI/Common/DirItem.h
@@ -39,14 +39,14 @@ public:
int AddPrefix(int phyParent, int logParent, const UString &prefix);
void DeleteLastPrefix();
- void EnumerateDirectory(int phyParent, int logParent, const UString &phyPrefix,
- UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes);
+ void EnumerateDirectory(int phyParent, int logParent, const FString &phyPrefix,
+ FStringVector &errorPaths, CRecordVector<DWORD> &errorCodes);
void EnumerateDirItems2(
- const UString &phyPrefix,
+ const FString &phyPrefix,
const UString &logPrefix,
- const UStringVector &filePaths,
- UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes);
+ const FStringVector &filePaths,
+ FStringVector &errorPaths, CRecordVector<DWORD> &errorCodes);
void ReserveDown();
};
diff --git a/CPP/7zip/UI/Common/EnumDirItems.cpp b/CPP/7zip/UI/Common/EnumDirItems.cpp
index ba03ea35..8c83a9fb 100755
--- a/CPP/7zip/UI/Common/EnumDirItems.cpp
+++ b/CPP/7zip/UI/Common/EnumDirItems.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "Windows/FileName.h"
+
#include "EnumDirItems.h"
using namespace NWindows;
@@ -9,7 +11,7 @@ using namespace NFile;
using namespace NName;
void AddDirFileInfo(int phyParent, int logParent,
- const NFind::CFileInfoW &fi, CObjectVector<CDirItem> &dirItems)
+ const NFind::CFileInfo &fi, CObjectVector<CDirItem> &dirItems)
{
CDirItem di;
di.Size = fi.Size;
@@ -19,7 +21,7 @@ void AddDirFileInfo(int phyParent, int logParent,
di.Attrib = fi.Attrib;
di.PhyParent = phyParent;
di.LogParent = logParent;
- di.Name = fi.Name;
+ di.Name = fs2us(fi.Name);
dirItems.Add(di);
}
@@ -79,13 +81,13 @@ void CDirItems::DeleteLastPrefix()
Prefixes.DeleteBack();
}
-void CDirItems::EnumerateDirectory(int phyParent, int logParent, const UString &phyPrefix,
- UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes)
+void CDirItems::EnumerateDirectory(int phyParent, int logParent, const FString &phyPrefix,
+ FStringVector &errorPaths, CRecordVector<DWORD> &errorCodes)
{
- NFind::CEnumeratorW enumerator(phyPrefix + (wchar_t)kAnyStringWildcard);
+ NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK);
for (;;)
{
- NFind::CFileInfoW fi;
+ NFind::CFileInfo fi;
bool found;
if (!enumerator.Next(fi, found))
{
@@ -98,43 +100,43 @@ void CDirItems::EnumerateDirectory(int phyParent, int logParent, const UString &
AddDirFileInfo(phyParent, logParent, fi, Items);
if (fi.IsDir())
{
- const UString name2 = fi.Name + (wchar_t)kDirDelimiter;
- int parent = AddPrefix(phyParent, logParent, name2);
+ const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR;
+ int parent = AddPrefix(phyParent, logParent, fs2us(name2));
EnumerateDirectory(parent, parent, phyPrefix + name2, errorPaths, errorCodes);
}
}
}
-void CDirItems::EnumerateDirItems2(const UString &phyPrefix, const UString &logPrefix,
- const UStringVector &filePaths, UStringVector &errorPaths, CRecordVector<DWORD> &errorCodes)
+void CDirItems::EnumerateDirItems2(const FString &phyPrefix, const UString &logPrefix,
+ const FStringVector &filePaths, FStringVector &errorPaths, CRecordVector<DWORD> &errorCodes)
{
- int phyParent = phyPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, phyPrefix);
+ int phyParent = phyPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, fs2us(phyPrefix));
int logParent = logPrefix.IsEmpty() ? -1 : AddPrefix(-1, -1, logPrefix);
for (int i = 0; i < filePaths.Size(); i++)
{
- const UString &filePath = filePaths[i];
- NFind::CFileInfoW fi;
- const UString phyPath = phyPrefix + filePath;
+ const FString &filePath = filePaths[i];
+ NFind::CFileInfo fi;
+ const FString phyPath = phyPrefix + filePath;
if (!fi.Find(phyPath))
{
errorCodes.Add(::GetLastError());
errorPaths.Add(phyPath);
continue;
}
- int delimiter = filePath.ReverseFind((wchar_t)kDirDelimiter);
- UString phyPrefixCur;
+ int delimiter = filePath.ReverseFind(FCHAR_PATH_SEPARATOR);
+ FString phyPrefixCur;
int phyParentCur = phyParent;
if (delimiter >= 0)
{
phyPrefixCur = filePath.Left(delimiter + 1);
- phyParentCur = AddPrefix(phyParent, logParent, phyPrefixCur);
+ phyParentCur = AddPrefix(phyParent, logParent, fs2us(phyPrefixCur));
}
AddDirFileInfo(phyParentCur, logParent, fi, Items);
if (fi.IsDir())
{
- const UString name2 = fi.Name + (wchar_t)kDirDelimiter;
- int parent = AddPrefix(phyParentCur, logParent, name2);
+ const FString name2 = fi.Name + FCHAR_PATH_SEPARATOR;
+ int parent = AddPrefix(phyParentCur, logParent, fs2us(name2));
EnumerateDirectory(parent, parent, phyPrefix + phyPrefixCur + name2, errorPaths, errorCodes);
}
}
@@ -142,27 +144,27 @@ void CDirItems::EnumerateDirItems2(const UString &phyPrefix, const UString &logP
}
static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
- int phyParent, int logParent, const UString &phyPrefix,
+ int phyParent, int logParent, const FString &phyPrefix,
const UStringVector &addArchivePrefix,
CDirItems &dirItems,
bool enterToSubFolders,
IEnumDirItemCallback *callback,
- UStringVector &errorPaths,
+ FStringVector &errorPaths,
CRecordVector<DWORD> &errorCodes);
static HRESULT EnumerateDirItems_Spec(const NWildcard::CCensorNode &curNode,
- int phyParent, int logParent, const UString &curFolderName,
- const UString &phyPrefix,
+ int phyParent, int logParent, const FString &curFolderName,
+ const FString &phyPrefix,
const UStringVector &addArchivePrefix,
CDirItems &dirItems,
bool enterToSubFolders,
IEnumDirItemCallback *callback,
- UStringVector &errorPaths,
+ FStringVector &errorPaths,
CRecordVector<DWORD> &errorCodes)
{
- const UString name2 = curFolderName + (wchar_t)kDirDelimiter;
- int parent = dirItems.AddPrefix(phyParent, logParent, name2);
+ const FString name2 = curFolderName + FCHAR_PATH_SEPARATOR;
+ int parent = dirItems.AddPrefix(phyParent, logParent, fs2us(name2));
int numItems = dirItems.Items.Size();
HRESULT res = EnumerateDirItems(curNode, parent, parent, phyPrefix + name2,
addArchivePrefix, dirItems, enterToSubFolders, callback, errorPaths, errorCodes);
@@ -173,19 +175,19 @@ static HRESULT EnumerateDirItems_Spec(const NWildcard::CCensorNode &curNode,
static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
- int phyParent, int logParent, const UString &phyPrefix,
+ int phyParent, int logParent, const FString &phyPrefix,
const UStringVector &addArchivePrefix, // prefix from curNode
CDirItems &dirItems,
bool enterToSubFolders,
IEnumDirItemCallback *callback,
- UStringVector &errorPaths,
+ FStringVector &errorPaths,
CRecordVector<DWORD> &errorCodes)
{
if (!enterToSubFolders)
if (curNode.NeedCheckSubDirs())
enterToSubFolders = true;
if (callback)
- RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), phyPrefix));
+ RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), fs2us(phyPrefix)));
// try direct_names case at first
if (addArchivePrefix.IsEmpty() && !enterToSubFolders)
@@ -210,8 +212,8 @@ static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
{
const NWildcard::CItem &item = curNode.IncludeItems[i];
const UString &name = item.PathParts.Front();
- const UString fullPath = phyPrefix + name;
- NFind::CFileInfoW fi;
+ const FString fullPath = phyPrefix + us2fs(name);
+ NFind::CFileInfo fi;
if (!fi.Find(fullPath))
{
errorCodes.Add(::GetLastError());
@@ -227,7 +229,7 @@ static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
}
{
UStringVector pathParts;
- pathParts.Add(fi.Name);
+ pathParts.Add(fs2us(fi.Name));
if (curNode.CheckPathToRoot(false, pathParts, !isDir))
continue;
}
@@ -260,8 +262,8 @@ static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
if (!needEnterVector[i])
continue;
const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i];
- const UString fullPath = phyPrefix + nextNode.Name;
- NFind::CFileInfoW fi;
+ const FString fullPath = phyPrefix + us2fs(nextNode.Name);
+ NFind::CFileInfo fi;
if (!fi.Find(fullPath))
{
if (!nextNode.AreThereIncludeItems())
@@ -285,10 +287,10 @@ static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
}
- NFind::CEnumeratorW enumerator(phyPrefix + wchar_t(kAnyStringWildcard));
+ NFind::CEnumerator enumerator(phyPrefix + FCHAR_ANY_MASK);
for (int ttt = 0; ; ttt++)
{
- NFind::CFileInfoW fi;
+ NFind::CFileInfo fi;
bool found;
if (!enumerator.Next(fi, found))
{
@@ -300,8 +302,8 @@ static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
break;
if (callback && (ttt & 0xFF) == 0xFF)
- RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), phyPrefix));
- const UString &name = fi.Name;
+ RINOK(callback->ScanProgress(dirItems.GetNumFolders(), dirItems.Items.Size(), fs2us(phyPrefix)));
+ const UString &name = fs2us(fi.Name);
bool enterToSubFolders2 = enterToSubFolders;
UStringVector addArchivePrefixNew = addArchivePrefix;
addArchivePrefixNew.Add(name);
@@ -336,7 +338,7 @@ static HRESULT EnumerateDirItems(const NWildcard::CCensorNode &curNode,
addArchivePrefixNew.Add(name);
}
- RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, name, phyPrefix,
+ RINOK(EnumerateDirItems_Spec(*nextNode, phyParent, logParent, fi.Name, phyPrefix,
addArchivePrefixNew, dirItems, enterToSubFolders2, callback, errorPaths, errorCodes));
}
return S_OK;
@@ -346,14 +348,14 @@ HRESULT EnumerateItems(
const NWildcard::CCensor &censor,
CDirItems &dirItems,
IEnumDirItemCallback *callback,
- UStringVector &errorPaths,
+ FStringVector &errorPaths,
CRecordVector<DWORD> &errorCodes)
{
for (int i = 0; i < censor.Pairs.Size(); i++)
{
const NWildcard::CPair &pair = censor.Pairs[i];
int phyParent = pair.Prefix.IsEmpty() ? -1 : dirItems.AddPrefix(-1, -1, pair.Prefix);
- RINOK(EnumerateDirItems(pair.Head, phyParent, -1, pair.Prefix, UStringVector(), dirItems, false,
+ RINOK(EnumerateDirItems(pair.Head, phyParent, -1, us2fs(pair.Prefix), UStringVector(), dirItems, false,
callback, errorPaths, errorCodes));
}
dirItems.ReserveDown();
diff --git a/CPP/7zip/UI/Common/EnumDirItems.h b/CPP/7zip/UI/Common/EnumDirItems.h
index d0ce950e..c96c7b9e 100755
--- a/CPP/7zip/UI/Common/EnumDirItems.h
+++ b/CPP/7zip/UI/Common/EnumDirItems.h
@@ -8,7 +8,7 @@
#include "DirItem.h"
void AddDirFileInfo(int phyParent, int logParent,
- const NWindows::NFile::NFind::CFileInfoW &fi, CObjectVector<CDirItem> &dirItems);
+ const NWindows::NFile::NFind::CFileInfo &fi, CObjectVector<CDirItem> &dirItems);
struct IEnumDirItemCallback
{
@@ -19,7 +19,7 @@ HRESULT EnumerateItems(
const NWildcard::CCensor &censor,
CDirItems &dirItems,
IEnumDirItemCallback *callback,
- UStringVector &errorPaths,
+ FStringVector &errorPaths,
CRecordVector<DWORD> &errorCodes);
#endif
diff --git a/CPP/7zip/UI/Common/Extract.cpp b/CPP/7zip/UI/Common/Extract.cpp
index ca2c8c73..81186772 100755
--- a/CPP/7zip/UI/Common/Extract.cpp
+++ b/CPP/7zip/UI/Common/Extract.cpp
@@ -52,8 +52,8 @@ static HRESULT DecompressArchive(
UStringVector removePathParts;
- UString outDir = options.OutputDir;
- outDir.Replace(L"*", GetCorrectFsPath(arc.DefaultName));
+ FString outDir = options.OutputDir;
+ outDir.Replace(FSTRING_ANY_MASK, us2fs(GetCorrectFsPath(arc.DefaultName)));
#ifdef _WIN32
// GetCorrectFullFsPath doesn't like "..".
// outDir.TrimRight();
@@ -66,7 +66,7 @@ static HRESULT DecompressArchive(
HRESULT res = ::GetLastError();
if (res == S_OK)
res = E_FAIL;
- errorMessage = ((UString)L"Can not create output directory ") + outDir;
+ errorMessage = ((UString)L"Can not create output directory ") + fs2us(outDir);
return res;
}
@@ -118,11 +118,11 @@ HRESULT DecompressArchives(
for (i = 0; i < numArcs; i++)
{
- NFile::NFind::CFileInfoW fi;
+ NFile::NFind::CFileInfo fi;
fi.Size = 0;
if (!options.StdInMode)
{
- const UString &arcPath = arcPaths[i];
+ const FString &arcPath = us2fs(arcPaths[i]);
if (!fi.Find(arcPath))
throw "there is no such archive";
if (fi.IsDir())
@@ -142,7 +142,7 @@ HRESULT DecompressArchives(
for (i = 0; i < numArcs; i++)
{
const UString &arcPath = arcPaths[i];
- NFile::NFind::CFileInfoW fi;
+ NFile::NFind::CFileInfo fi;
if (options.StdInMode)
{
fi.Size = 0;
@@ -150,7 +150,7 @@ HRESULT DecompressArchives(
}
else
{
- if (!fi.Find(arcPath) || fi.IsDir())
+ if (!fi.Find(us2fs(arcPath)) || fi.IsDir())
throw "there is no such archive";
}
diff --git a/CPP/7zip/UI/Common/Extract.h b/CPP/7zip/UI/Common/Extract.h
index 5a939ed2..2904a0ab 100755
--- a/CPP/7zip/UI/Common/Extract.h
+++ b/CPP/7zip/UI/Common/Extract.h
@@ -23,7 +23,7 @@ struct CExtractOptions
bool CalcCrc;
NExtract::NPathMode::EEnum PathMode;
NExtract::NOverwriteMode::EEnum OverwriteMode;
- UString OutputDir;
+ FString OutputDir;
// bool ShowDialog;
// bool PasswordEnabled;
diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/CPP/7zip/UI/Common/ExtractingFilePath.cpp
index 8f31708b..25494d0e 100755
--- a/CPP/7zip/UI/Common/ExtractingFilePath.cpp
+++ b/CPP/7zip/UI/Common/ExtractingFilePath.cpp
@@ -20,8 +20,8 @@ static UString ReplaceIncorrectChars(const UString &s)
res += c;
}
res.TrimRight();
- while (!res.IsEmpty() && res[res.Length() - 1] == '.')
- res.Delete(res.Length() - 1);
+ while (!res.IsEmpty() && res.Back() == '.')
+ res.DeleteBack();
return res;
#else
return s;
@@ -132,8 +132,8 @@ UString GetCorrectFullFsPath(const UString &path)
{
UString &s = parts[i];
#ifdef _WIN32
- while (!s.IsEmpty() && s[s.Length() - 1] == '.')
- s.Delete(s.Length() - 1);
+ while (!s.IsEmpty() && s.Back() == '.')
+ s.DeleteBack();
if (!IsSupportedName(s))
s = (UString)L"_" + s;
#endif
diff --git a/CPP/7zip/UI/Common/LoadCodecs.cpp b/CPP/7zip/UI/Common/LoadCodecs.cpp
index 856e47fb..cb4f83ee 100755
--- a/CPP/7zip/UI/Common/LoadCodecs.cpp
+++ b/CPP/7zip/UI/Common/LoadCodecs.cpp
@@ -22,6 +22,7 @@ static const UINT kIconTypesResId = 100;
#endif
#ifdef _WIN32
+#include "Windows/FileName.h"
#include "Windows/Registry.h"
#endif
@@ -32,53 +33,52 @@ using namespace NFile;
extern HINSTANCE g_hInstance;
#endif
-static CSysString GetLibraryFolderPrefix()
-{
- #ifdef _WIN32
- TCHAR fullPath[MAX_PATH + 1];
- ::GetModuleFileName(g_hInstance, fullPath, MAX_PATH);
- CSysString path = fullPath;
- int pos = path.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
- return path.Left(pos + 1);
- #else
- return CSysString(); // FIX IT
- #endif
-}
-
-#define kCodecsFolderName TEXT("Codecs")
-#define kFormatsFolderName TEXT("Formats")
-static const TCHAR *kMainDll = TEXT("7z.dll");
+#define kCodecsFolderName FTEXT("Codecs")
+#define kFormatsFolderName FTEXT("Formats")
+static CFSTR kMainDll = FTEXT("7z.dll");
#ifdef _WIN32
+
static LPCTSTR kRegistryPath = TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-zip");
-static LPCTSTR kProgramPathValue = TEXT("Path");
-static bool ReadPathFromRegistry(HKEY baseKey, CSysString &path)
+static LPCWSTR kProgramPathValue = L"Path";
+static LPCWSTR kProgramPath2Value = L"Path"
+ #ifdef _WIN64
+ L"64";
+ #else
+ L"32";
+ #endif
+
+static bool ReadPathFromRegistry(HKEY baseKey, LPCWSTR value, FString &path)
{
NRegistry::CKey key;
- if(key.Open(baseKey, kRegistryPath, KEY_READ) == ERROR_SUCCESS)
- if (key.QueryValue(kProgramPathValue, path) == ERROR_SUCCESS)
+ if (key.Open(baseKey, kRegistryPath, KEY_READ) == ERROR_SUCCESS)
+ {
+ UString pathU;
+ if (key.QueryValue(value, pathU) == ERROR_SUCCESS)
{
+ path = us2fs(pathU);
NName::NormalizeDirPathPrefix(path);
- return true;
+ return NFind::DoesFileExist(path + kMainDll);
}
+ }
return false;
}
#endif
-CSysString GetBaseFolderPrefixFromRegistry()
+static FString GetBaseFolderPrefixFromRegistry()
{
- CSysString moduleFolderPrefix = GetLibraryFolderPrefix();
+ FString moduleFolderPrefix = NDLL::GetModuleDirPrefix();
#ifdef _WIN32
if (!NFind::DoesFileExist(moduleFolderPrefix + kMainDll) &&
!NFind::DoesDirExist(moduleFolderPrefix + kCodecsFolderName) &&
!NFind::DoesDirExist(moduleFolderPrefix + kFormatsFolderName))
{
- CSysString path;
- if (ReadPathFromRegistry(HKEY_CURRENT_USER, path))
- return path;
- if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, path))
- return path;
+ FString path;
+ if (ReadPathFromRegistry(HKEY_CURRENT_USER, kProgramPath2Value, path)) return path;
+ if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, kProgramPath2Value, path)) return path;
+ if (ReadPathFromRegistry(HKEY_CURRENT_USER, kProgramPathValue, path)) return path;
+ if (ReadPathFromRegistry(HKEY_LOCAL_MACHINE, kProgramPathValue, path)) return path;
}
#endif
return moduleFolderPrefix;
@@ -210,6 +210,14 @@ static void SplitString(const UString &srcString, UStringVector &destStrings)
destStrings.Add(s);
}
+int CArcInfoEx::FindExtension(const UString &ext) const
+{
+ for (int i = 0; i < Exts.Size(); i++)
+ if (ext.CompareNoCase(Exts[i].Ext) == 0)
+ return i;
+ return -1;
+}
+
void CArcInfoEx::AddExts(const wchar_t *ext, const wchar_t *addExt)
{
UStringVector exts, addExts;
@@ -344,7 +352,7 @@ extern "C"
}
#endif
-HRESULT CCodecs::LoadDll(const CSysString &dllPath, bool needCheckDll)
+HRESULT CCodecs::LoadDll(const FString &dllPath, bool needCheckDll)
{
if (needCheckDll)
{
@@ -393,9 +401,9 @@ HRESULT CCodecs::LoadDll(const CSysString &dllPath, bool needCheckDll)
return res;
}
-HRESULT CCodecs::LoadDllsFromFolder(const CSysString &folderPrefix)
+HRESULT CCodecs::LoadDllsFromFolder(const FString &folderPrefix)
{
- NFile::NFind::CEnumerator enumerator(folderPrefix + CSysString(TEXT("*")));
+ NFile::NFind::CEnumerator enumerator(folderPrefix + FCHAR_ANY_MASK);
NFile::NFind::CFileInfo fi;
while (enumerator.Next(fi))
{
@@ -443,10 +451,10 @@ HRESULT CCodecs::Load()
Formats.Add(item);
}
#ifdef EXTERNAL_CODECS
- const CSysString baseFolder = GetBaseFolderPrefixFromRegistry();
+ const FString baseFolder = GetBaseFolderPrefixFromRegistry();
RINOK(LoadDll(baseFolder + kMainDll, false));
- RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName TEXT(STRING_PATH_SEPARATOR)));
- RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName TEXT(STRING_PATH_SEPARATOR)));
+ RINOK(LoadDllsFromFolder(baseFolder + kCodecsFolderName FSTRING_PATH_SEPARATOR));
+ RINOK(LoadDllsFromFolder(baseFolder + kFormatsFolderName FSTRING_PATH_SEPARATOR));
#endif
return S_OK;
}
@@ -455,12 +463,11 @@ HRESULT CCodecs::Load()
int CCodecs::FindFormatForArchiveName(const UString &arcPath) const
{
- int slashPos1 = arcPath.ReverseFind(WCHAR_PATH_SEPARATOR);
- int slashPos2 = arcPath.ReverseFind(L'.');
+ int slashPos = arcPath.ReverseFind(WCHAR_PATH_SEPARATOR);
int dotPos = arcPath.ReverseFind(L'.');
- if (dotPos < 0 || dotPos < slashPos1 || dotPos < slashPos2)
+ if (dotPos < 0 || dotPos < slashPos)
return -1;
- UString ext = arcPath.Mid(dotPos + 1);
+ const UString ext = arcPath.Mid(dotPos + 1);
for (int i = 0; i < Formats.Size(); i++)
{
const CArcInfoEx &arc = Formats[i];
diff --git a/CPP/7zip/UI/Common/LoadCodecs.h b/CPP/7zip/UI/Common/LoadCodecs.h
index a633dd2e..f5963ed6 100755
--- a/CPP/7zip/UI/Common/LoadCodecs.h
+++ b/CPP/7zip/UI/Common/LoadCodecs.h
@@ -1,9 +1,8 @@
// LoadCodecs.h
-#ifndef __LOADCODECS_H
-#define __LOADCODECS_H
+#ifndef __LOAD_CODECS_H
+#define __LOAD_CODECS_H
-#include "../../../Common/Types.h"
#include "../../../Common/MyCom.h"
#include "../../../Common/MyString.h"
#include "../../../Common/Buffer.h"
@@ -58,19 +57,16 @@ struct CArcInfoEx
#endif
#endif
bool KeepName;
+
UString GetMainExt() const
{
if (Exts.IsEmpty())
return UString();
return Exts[0].Ext;
}
- int FindExtension(const UString &ext) const
- {
- for (int i = 0; i < Exts.Size(); i++)
- if (ext.CompareNoCase(Exts[i].Ext) == 0)
- return i;
- return -1;
- }
+ int FindExtension(const UString &ext) const;
+
+ /*
UString GetAllExtensions() const
{
UString s;
@@ -82,6 +78,7 @@ struct CArcInfoEx
}
return s;
}
+ */
void AddExts(const wchar_t* ext, const wchar_t* addExt);
@@ -125,7 +122,7 @@ struct CCodecLib
GetMethodPropertyFunc GetMethodProperty;
CreateObjectFunc CreateObject;
#ifdef NEW_FOLDER_INTERFACE
- CSysString Path;
+ FString Path;
void LoadIcons() { CCodecIcons::LoadIcons((HMODULE)Lib); }
#endif
CCodecLib(): GetMethodProperty(0) {}
@@ -151,8 +148,8 @@ public:
HRESULT LoadCodecs();
HRESULT LoadFormats();
- HRESULT LoadDll(const CSysString &path, bool needCheckDll);
- HRESULT LoadDllsFromFolder(const CSysString &folderPrefix);
+ HRESULT LoadDll(const FString &path, bool needCheckDll);
+ HRESULT LoadDllsFromFolder(const FString &folderPrefix);
HRESULT CreateArchiveHandler(const CArcInfoEx &ai, void **archive, bool outHandler) const
{
diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp
index 56a63046..60d2f6f5 100755
--- a/CPP/7zip/UI/Common/OpenArchive.cpp
+++ b/CPP/7zip/UI/Common/OpenArchive.cpp
@@ -63,6 +63,25 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
return S_OK;
}
+HRESULT CArc::GetItemSize(UInt32 index, UInt64 &size, bool &defined) const
+{
+ NCOM::CPropVariant prop;
+ defined = false;
+ size = 0;
+ RINOK(Archive->GetProperty(index, kpidSize, &prop));
+ switch (prop.vt)
+ {
+ case VT_UI1: size = prop.bVal; break;
+ case VT_UI2: size = prop.uiVal; break;
+ case VT_UI4: size = prop.ulVal; break;
+ case VT_UI8: size = (UInt64)prop.uhVal.QuadPart; break;
+ case VT_EMPTY: return S_OK;
+ default: return E_FAIL;
+ }
+ defined = true;
+ return S_OK;
+}
+
HRESULT CArc::GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const
{
NCOM::CPropVariant prop;
@@ -339,7 +358,7 @@ HRESULT CArc::OpenStreamOrFile(
{
CInFileStream *fileStreamSpec = new CInFileStream;
fileStream = fileStreamSpec;
- if (!fileStreamSpec->Open(Path))
+ if (!fileStreamSpec->Open(us2fs(Path)))
return GetLastError();
stream = fileStream;
}
@@ -461,7 +480,7 @@ HRESULT CArchiveLink::Open(
return S_OK;
}
-static void SetCallback(const UString &filePath,
+static void SetCallback(const FString &filePath,
IOpenCallbackUI *callbackUI,
IArchiveOpenCallback *reOpenCallback,
CMyComPtr<IArchiveOpenCallback> &callback)
@@ -471,12 +490,9 @@ static void SetCallback(const UString &filePath,
openCallbackSpec->Callback = callbackUI;
openCallbackSpec->ReOpenCallback = reOpenCallback;
- UString fullName;
- int fileNamePartStartIndex;
- NFile::NDirectory::MyGetFullPathName(filePath, fullName, fileNamePartStartIndex);
- openCallbackSpec->Init(
- fullName.Left(fileNamePartStartIndex),
- fullName.Mid(fileNamePartStartIndex));
+ FString dirPrefix, fileName;
+ NFile::NDirectory::GetFullPathAndSplit(filePath, dirPrefix, fileName);
+ openCallbackSpec->Init(dirPrefix, fileName);
}
HRESULT CArchiveLink::Open2(CCodecs *codecs,
@@ -491,14 +507,10 @@ HRESULT CArchiveLink::Open2(CCodecs *codecs,
CMyComPtr<IArchiveOpenCallback> callback = openCallbackSpec;
openCallbackSpec->Callback = callbackUI;
- UString fullName, prefix, name;
+ FString prefix, name;
if (!stream && !stdInMode)
{
- int fileNamePartStartIndex;
- if (!NFile::NDirectory::MyGetFullPathName(filePath, fullName, fileNamePartStartIndex))
- return GetLastError();
- prefix = fullName.Left(fileNamePartStartIndex);
- name = fullName.Mid(fileNamePartStartIndex);
+ NFile::NDirectory::GetFullPathAndSplit(us2fs(filePath), prefix, name);
openCallbackSpec->Init(prefix, name);
}
else
@@ -507,9 +519,9 @@ HRESULT CArchiveLink::Open2(CCodecs *codecs,
}
RINOK(Open(codecs, formatIndices, stdInMode, stream, filePath, callback));
- VolumePaths.Add(prefix + name);
+ VolumePaths.Add(fs2us(prefix + name));
for (int i = 0; i < openCallbackSpec->FileNames.Size(); i++)
- VolumePaths.Add(prefix + openCallbackSpec->FileNames[i]);
+ VolumePaths.Add(fs2us(prefix) + openCallbackSpec->FileNames[i]);
VolumesSize = openCallbackSpec->TotalSize;
return S_OK;
}
@@ -524,11 +536,11 @@ HRESULT CArchiveLink::ReOpen(CCodecs *codecs, const UString &filePath,
return Open2(codecs, CIntVector(), false, NULL, filePath, 0);
CMyComPtr<IArchiveOpenCallback> openCallbackNew;
- SetCallback(filePath, NULL, callback, openCallbackNew);
+ SetCallback(us2fs(filePath), NULL, callback, openCallbackNew);
CInFileStream *fileStreamSpec = new CInFileStream;
CMyComPtr<IInStream> stream(fileStreamSpec);
- if (!fileStreamSpec->Open(filePath))
+ if (!fileStreamSpec->Open(us2fs(filePath)))
return GetLastError();
HRESULT res = GetArchive()->Open(stream, &kMaxCheckStartPosition, callback);
IsOpen = (res == S_OK);
diff --git a/CPP/7zip/UI/Common/OpenArchive.h b/CPP/7zip/UI/Common/OpenArchive.h
index 4a003ee6..25f739e3 100755
--- a/CPP/7zip/UI/Common/OpenArchive.h
+++ b/CPP/7zip/UI/Common/OpenArchive.h
@@ -29,6 +29,7 @@ struct CArc
CArc(): MTimeDefined(false) {}
HRESULT GetItemPath(UInt32 index, UString &result) const;
+ HRESULT GetItemSize(UInt32 index, UInt64 &size, bool &defined) const;
HRESULT GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const;
HRESULT IsItemAnti(UInt32 index, bool &result) const
{ return GetArchiveItemBoolProp(Archive, index, kpidIsAnti, result); }
diff --git a/CPP/7zip/UI/Common/Property.h b/CPP/7zip/UI/Common/Property.h
index 9fd340cb..8b57a2a6 100755
--- a/CPP/7zip/UI/Common/Property.h
+++ b/CPP/7zip/UI/Common/Property.h
@@ -1,9 +1,9 @@
// Property.h
-#ifndef __PROPERTY_H
-#define __PROPERTY_H
+#ifndef __7Z_PROPERTY_H
+#define __7Z_PROPERTY_H
-#include "Common/MyString.h"
+#include "../../../Common/MyString.h"
struct CProperty
{
diff --git a/CPP/7zip/UI/Common/SetProperties.cpp b/CPP/7zip/UI/Common/SetProperties.cpp
index 4827f2a7..ac9b59a3 100755
--- a/CPP/7zip/UI/Common/SetProperties.cpp
+++ b/CPP/7zip/UI/Common/SetProperties.cpp
@@ -49,13 +49,13 @@ HRESULT SetProperties(IUnknown *unknown, const CObjectVector<CProperty> &propert
{
if (!name.IsEmpty())
{
- wchar_t c = name[name.Length() - 1];
+ wchar_t c = name.Back();
if (c == L'-')
propVariant = false;
else if (c == L'+')
propVariant = true;
if (propVariant.vt != VT_EMPTY)
- name = name.Left(name.Length() - 1);
+ name.DeleteBack();
}
}
else
diff --git a/CPP/7zip/UI/Common/TempFiles.cpp b/CPP/7zip/UI/Common/TempFiles.cpp
index eeaec180..c799c7bf 100755
--- a/CPP/7zip/UI/Common/TempFiles.cpp
+++ b/CPP/7zip/UI/Common/TempFiles.cpp
@@ -5,16 +5,15 @@
#include "TempFiles.h"
#include "Windows/FileDir.h"
-#include "Windows/FileIO.h"
using namespace NWindows;
using namespace NFile;
void CTempFiles::Clear()
{
- while(!Paths.IsEmpty())
+ while (!Paths.IsEmpty())
{
- NDirectory::DeleteFileAlways((LPCWSTR)Paths.Back());
+ NDirectory::DeleteFileAlways(Paths.Back());
Paths.DeleteBack();
}
}
diff --git a/CPP/7zip/UI/Common/TempFiles.h b/CPP/7zip/UI/Common/TempFiles.h
index eb474a76..5dcda5b6 100755
--- a/CPP/7zip/UI/Common/TempFiles.h
+++ b/CPP/7zip/UI/Common/TempFiles.h
@@ -1,7 +1,7 @@
// TempFiles.h
-#ifndef __TEMPFILES_H
-#define __TEMPFILES_H
+#ifndef __TEMP_FILES_H
+#define __TEMP_FILES_H
#include "Common/MyString.h"
@@ -9,7 +9,7 @@ class CTempFiles
{
void Clear();
public:
- UStringVector Paths;
+ FStringVector Paths;
~CTempFiles() { Clear(); }
};
diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp
index a57ec2a6..e740e8a7 100755
--- a/CPP/7zip/UI/Common/Update.cpp
+++ b/CPP/7zip/UI/Common/Update.cpp
@@ -7,10 +7,7 @@
#include "Common/IntToString.h"
#include "Common/StringConvert.h"
-#ifdef _WIN32
#include "Windows/DLL.h"
-#endif
-
#include "Windows/FileDir.h"
#include "Windows/FileFind.h"
#include "Windows/FileName.h"
@@ -40,7 +37,7 @@ using namespace NCOM;
using namespace NFile;
using namespace NName;
-static const wchar_t *kTempFolderPrefix = L"7zE";
+static CFSTR kTempFolderPrefix = FTEXT("7zE");
using namespace NUpdateArchive;
@@ -57,7 +54,7 @@ class COutMultiVolStream:
{
COutFileStream *StreamSpec;
CMyComPtr<IOutStream> Stream;
- UString Name;
+ FString Name;
UInt64 Pos;
UInt64 RealSize;
};
@@ -65,7 +62,7 @@ class COutMultiVolStream:
public:
// CMyComPtr<IArchiveUpdateCallback2> VolumeCallback;
CRecordVector<UInt64> Sizes;
- UString Prefix;
+ FString Prefix;
CTempFiles *TempFiles;
void Init()
@@ -107,18 +104,18 @@ STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *pr
{
if (processedSize != NULL)
*processedSize = 0;
- while(size > 0)
+ while (size > 0)
{
if (_streamIndex >= Streams.Size())
{
CSubStreamInfo subStream;
- wchar_t temp[16];
+ FChar temp[16];
ConvertUInt32ToString(_streamIndex + 1, temp);
- UString res = temp;
+ FString res = temp;
while (res.Length() < 3)
- res = UString(L'0') + res;
- UString name = Prefix + res;
+ res = FString(FTEXT('0')) + res;
+ FString name = Prefix + res;
subStream.StreamSpec = new COutFileStream;
subStream.Stream = subStream.StreamSpec;
if (!subStream.StreamSpec->Create(name, false))
@@ -311,7 +308,7 @@ static HRESULT Compress(
bool stdOutMode,
const CDirItems &dirItems,
bool sfxMode,
- const UString &sfxModule,
+ const FString &sfxModule,
const CRecordVector<UInt64> &volumesSizes,
CTempFiles &tempFiles,
CUpdateErrorInfo &errorInfo,
@@ -389,11 +386,10 @@ static HRESULT Compress(
if (!stdOutMode)
{
- UString resultPath;
- int pos;
- if (!NFile::NDirectory::MyGetFullPathName(archivePath.GetFinalPath(), resultPath, pos))
+ FString dirPrefix;
+ if (!NFile::NDirectory::GetOnlyDirPrefix(us2fs(archivePath.GetFinalPath()), dirPrefix))
throw 1417161;
- NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos));
+ NFile::NDirectory::CreateComplexDirectory(dirPrefix);
}
COutFileStream *outStreamSpec = NULL;
@@ -408,21 +404,21 @@ static HRESULT Compress(
outStreamSpec = new COutFileStream;
outStream = outStreamSpec;
bool isOK = false;
- UString realPath;
+ FString realPath;
for (int i = 0; i < (1 << 16); i++)
{
if (archivePath.Temp)
{
if (i > 0)
{
- wchar_t s[16];
+ FChar s[16];
ConvertUInt32ToString(i, s);
archivePath.TempPostfix = s;
}
realPath = archivePath.GetTempPath();
}
else
- realPath = archivePath.GetFinalPath();
+ realPath = us2fs(archivePath.GetFinalPath());
if (outStreamSpec->Create(realPath, false))
{
tempFiles.Paths.Add(realPath);
@@ -450,7 +446,7 @@ static HRESULT Compress(
volStreamSpec = new COutMultiVolStream;
outStream = volStreamSpec;
volStreamSpec->Sizes = volumesSizes;
- volStreamSpec->Prefix = archivePath.GetFinalPath() + UString(L".");
+ volStreamSpec->Prefix = us2fs(archivePath.GetFinalPath() + L".");
volStreamSpec->TempFiles = &tempFiles;
volStreamSpec->Init();
@@ -484,7 +480,7 @@ static HRESULT Compress(
{
outStreamSpec = new COutFileStream;
sfxOutStream = outStreamSpec;
- UString realPath = archivePath.GetFinalPath();
+ FString realPath = us2fs(archivePath.GetFinalPath());
if (!outStreamSpec->Create(realPath, false))
{
errorInfo.SystemError = ::GetLastError();
@@ -527,14 +523,7 @@ HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor,
RINOK(IsArchiveItemFolder(archive, i, ai.IsDir));
ai.Censored = censor.CheckPath(ai.Name, !ai.IsDir);
RINOK(arc.GetItemMTime(i, ai.MTime, ai.MTimeDefined));
-
- {
- CPropVariant prop;
- RINOK(archive->GetProperty(i, kpidSize, &prop));
- ai.SizeDefined = (prop.vt != VT_EMPTY);
- if (ai.SizeDefined)
- ai.Size = ConvertPropVariantToUInt64(prop);
- }
+ RINOK(arc.GetItemSize(i, ai.Size, ai.SizeDefined));
{
CPropVariant prop;
@@ -608,11 +597,11 @@ static HRESULT UpdateWithItemLists(
#if defined(_WIN32) && !defined(UNDER_CE)
class CCurrentDirRestorer
{
- UString _path;
+ FString _path;
public:
CCurrentDirRestorer() { NFile::NDirectory::MyGetCurrentDirectory(_path); }
~CCurrentDirRestorer() { RestoreDirectory();}
- bool RestoreDirectory() { return BOOLToBool(NFile::NDirectory::MySetCurrentDirectory(_path)); }
+ bool RestoreDirectory() const { return BOOLToBool(NFile::NDirectory::MySetCurrentDirectory(_path)); }
};
#endif
@@ -661,17 +650,25 @@ HRESULT UpdateArchive(
errorInfo.Message = L"SFX file is not specified";
return E_FAIL;
}
- UString name = options.SfxModule;
- #ifdef UNDER_CE
- if (!NFind::DoesFileExist(name))
- #else
- if (!NDirectory::MySearchPath(NULL, name, NULL, options.SfxModule))
- #endif
+ bool found = false;
+ if (options.SfxModule.Find(FCHAR_PATH_SEPARATOR) < 0)
{
- errorInfo.SystemError = ::GetLastError();
- errorInfo.Message = L"7-Zip cannot find specified SFX module";
- errorInfo.FileName = name;
- return E_FAIL;
+ const FString fullName = NDLL::GetModuleDirPrefix() + options.SfxModule;
+ if (NFind::DoesFileExist(fullName))
+ {
+ options.SfxModule = fullName;
+ found = true;
+ }
+ }
+ if (!found)
+ {
+ if (!NFind::DoesFileExist(options.SfxModule))
+ {
+ errorInfo.SystemError = ::GetLastError();
+ errorInfo.Message = L"7-Zip cannot find specified SFX module";
+ errorInfo.FileName = options.SfxModule;
+ return E_FAIL;
+ }
}
}
@@ -681,8 +678,8 @@ HRESULT UpdateArchive(
if (!options.ArchivePath.OriginalPath.IsEmpty())
{
- NFind::CFileInfoW fi;
- if (fi.Find(arcPath))
+ NFind::CFileInfo fi;
+ if (fi.Find(us2fs(arcPath)))
{
if (fi.IsDir())
throw "there is no such archive";
@@ -738,12 +735,12 @@ HRESULT UpdateArchive(
CEnumDirItemUpdateCallback enumCallback;
enumCallback.Callback = callback;
RINOK(callback->StartScanning());
- UStringVector errorPaths;
+ FStringVector errorPaths;
CRecordVector<DWORD> errorCodes;
HRESULT res = EnumerateItems(censor, dirItems, &enumCallback, errorPaths, errorCodes);
for (int i = 0; i < errorPaths.Size(); i++)
{
- RINOK(callback->CanNotFindError(errorPaths[i], errorCodes[i]));
+ RINOK(callback->CanNotFindError(fs2us(errorPaths[i]), errorCodes[i]));
}
if (res != S_OK)
{
@@ -755,11 +752,11 @@ HRESULT UpdateArchive(
}
}
- UString tempDirPrefix;
+ FString tempDirPrefix;
bool usesTempDir = false;
#ifdef _WIN32
- NDirectory::CTempDirectoryW tempDirectory;
+ NDirectory::CTempDir tempDirectory;
if (options.EMailMode && options.EMailRemoveAfter)
{
tempDirectory.Create(kTempFolderPrefix);
@@ -792,20 +789,20 @@ HRESULT UpdateArchive(
}
}
- for(int i = 0; i < options.Commands.Size(); i++)
+ for (int i = 0; i < options.Commands.Size(); i++)
{
CArchivePath &ap = options.Commands[i].ArchivePath;
if (usesTempDir)
{
// Check it
- ap.Prefix = tempDirPrefix;
+ ap.Prefix = fs2us(tempDirPrefix);
// ap.Temp = true;
// ap.TempPrefix = tempDirPrefix;
}
if (!options.StdOutMode &&
(i > 0 || !createTempFile))
{
- const UString &path = ap.GetFinalPath();
+ const FString path = us2fs(ap.GetFinalPath());
if (NFind::DoesFileOrDirExist(path))
{
errorInfo.SystemError = 0;
@@ -839,21 +836,21 @@ HRESULT UpdateArchive(
try
{
CArchivePath &ap = options.Commands[0].ArchivePath;
- const UString &tempPath = ap.GetTempPath();
+ const FString &tempPath = ap.GetTempPath();
if (thereIsInArchive)
- if (!NDirectory::DeleteFileAlways(arcPath))
+ if (!NDirectory::DeleteFileAlways(us2fs(arcPath)))
{
errorInfo.SystemError = ::GetLastError();
errorInfo.Message = L"7-Zip cannot delete the file";
- errorInfo.FileName = arcPath;
+ errorInfo.FileName = us2fs(arcPath);
return E_FAIL;
}
- if (!NDirectory::MyMoveFile(tempPath, arcPath))
+ if (!NDirectory::MyMoveFile(tempPath, us2fs(arcPath)))
{
errorInfo.SystemError = ::GetLastError();
errorInfo.Message = L"7-Zip cannot move the file";
errorInfo.FileName = tempPath;
- errorInfo.FileName2 = arcPath;
+ errorInfo.FileName2 = us2fs(arcPath);
return E_FAIL;
}
}
@@ -867,7 +864,7 @@ HRESULT UpdateArchive(
if (options.EMailMode)
{
NDLL::CLibrary mapiLib;
- if (!mapiLib.Load(TEXT("Mapi32.dll")))
+ if (!mapiLib.Load(FTEXT("Mapi32.dll")))
{
errorInfo.SystemError = ::GetLastError();
errorInfo.Message = L"7-Zip cannot load Mapi32.dll";
@@ -880,13 +877,13 @@ HRESULT UpdateArchive(
errorInfo.Message = L"7-Zip cannot find MAPISendDocuments function";
return E_FAIL;
}
- UStringVector fullPaths;
+ FStringVector fullPaths;
int i;
- for(i = 0; i < options.Commands.Size(); i++)
+ for (i = 0; i < options.Commands.Size(); i++)
{
CArchivePath &ap = options.Commands[i].ArchivePath;
- UString arcPath;
- if (!NFile::NDirectory::MyGetFullPathName(ap.GetFinalPath(), arcPath))
+ FString arcPath;
+ if (!NFile::NDirectory::MyGetFullPathName(us2fs(ap.GetFinalPath()), arcPath))
{
errorInfo.SystemError = ::GetLastError();
errorInfo.Message = L"GetFullPathName error";
@@ -895,9 +892,9 @@ HRESULT UpdateArchive(
fullPaths.Add(arcPath);
}
CCurrentDirRestorer curDirRestorer;
- for(i = 0; i < fullPaths.Size(); i++)
+ for (i = 0; i < fullPaths.Size(); i++)
{
- UString arcPath = fullPaths[i];
+ UString arcPath = fs2us(fullPaths[i]);
UString fileName = ExtractFileNameFromPath(arcPath);
AString path = GetAnsiString(arcPath);
AString name = GetAnsiString(fileName);
diff --git a/CPP/7zip/UI/Common/Update.h b/CPP/7zip/UI/Common/Update.h
index 49af0092..43a3c0fd 100755
--- a/CPP/7zip/UI/Common/Update.h
+++ b/CPP/7zip/UI/Common/Update.h
@@ -21,8 +21,8 @@ struct CArchivePath
UString VolExtension; // archive type extension for volumes
bool Temp;
- UString TempPrefix; // path(folder) for temp location
- UString TempPostfix;
+ FString TempPrefix; // path(folder) for temp location
+ FString TempPostfix;
CArchivePath(): Temp(false) {};
@@ -63,12 +63,12 @@ struct CArchivePath
}
- UString GetTempPath() const
+ FString GetTempPath() const
{
- UString path = TempPrefix + Name;
+ FString path = TempPrefix + us2fs(Name);
if (!BaseExtension.IsEmpty())
- path += UString(L'.') + BaseExtension;
- path += L".tmp";
+ path += FString(FTEXT('.')) + us2fs(BaseExtension);
+ path += FTEXT(".tmp");
path += TempPostfix;
return path;
}
@@ -97,7 +97,7 @@ struct CUpdateOptions
CArchivePath ArchivePath;
bool SfxMode;
- UString SfxModule;
+ FString SfxModule;
bool OpenShareForWrite;
@@ -109,7 +109,7 @@ struct CUpdateOptions
bool EMailRemoveAfter;
UString EMailAddress;
- UString WorkingDir;
+ FString WorkingDir;
bool Init(const CCodecs *codecs, const CIntVector &formatIndices, const UString &arcPath);
@@ -137,8 +137,8 @@ struct CUpdateOptions
struct CErrorInfo
{
DWORD SystemError;
- UString FileName;
- UString FileName2;
+ FString FileName;
+ FString FileName2;
UString Message;
// UStringVector ErrorPaths;
// CRecordVector<DWORD> ErrorCodes;
diff --git a/CPP/7zip/UI/Common/UpdateCallback.cpp b/CPP/7zip/UI/Common/UpdateCallback.cpp
index 0f229058..21146bb0 100755
--- a/CPP/7zip/UI/Common/UpdateCallback.cpp
+++ b/CPP/7zip/UI/Common/UpdateCallback.cpp
@@ -22,7 +22,8 @@ CArchiveUpdateCallback::CArchiveUpdateCallback():
DirItems(0),
ArcItems(0),
UpdatePairs(0),
- NewNames(0)
+ NewNames(0),
+ KeepOriginalItemNames(0)
{}
@@ -120,7 +121,22 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
const CDirItem &di = DirItems->Items[up.DirIndex];
switch(propID)
{
- case kpidPath: prop = DirItems->GetLogPath(up.DirIndex); break;
+ case kpidPath:
+ {
+ if (KeepOriginalItemNames)
+ {
+ if (up.ExistInArchive() && Archive)
+ {
+ UInt32 indexInArchive;
+ if (ArcItems == 0)
+ indexInArchive = up.ArcIndex;
+ else
+ indexInArchive = (*ArcItems)[up.ArcIndex].IndexInServer;
+ return Archive->GetProperty(indexInArchive, propID, value);
+ }
+ }
+ prop = DirItems->GetLogPath(up.DirIndex); break;
+ }
case kpidIsDir: prop = di.IsDir(); break;
case kpidSize: prop = di.Size; break;
case kpidAttrib: prop = di.Attrib; break;
@@ -186,7 +202,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream
CInFileStream *inStreamSpec = new CInFileStream;
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
const UString path = DirItems->GetPhyPath(up.DirIndex);
- if (!inStreamSpec->OpenShared(path, ShareForWrite))
+ if (!inStreamSpec->OpenShared(us2fs(path), ShareForWrite))
{
return Callback->OpenFileError(path, ::GetLastError());
}
@@ -216,12 +232,12 @@ STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
{
COM_TRY_BEGIN
- wchar_t temp[16];
+ FChar temp[16];
ConvertUInt32ToString(index + 1, temp);
- UString res = temp;
+ FString res = temp;
while (res.Length() < 2)
- res = UString(L'0') + res;
- UString fileName = VolName;
+ res = FString(FTEXT('0')) + res;
+ FString fileName = VolName;
fileName += L'.';
fileName += res;
fileName += VolExt;
diff --git a/CPP/7zip/UI/Common/UpdateCallback.h b/CPP/7zip/UI/Common/UpdateCallback.h
index 9a20c315..09f1c0d3 100755
--- a/CPP/7zip/UI/Common/UpdateCallback.h
+++ b/CPP/7zip/UI/Common/UpdateCallback.h
@@ -55,8 +55,8 @@ public:
public:
CRecordVector<UInt64> VolumesSizes;
- UString VolName;
- UString VolExt;
+ FString VolName;
+ FString VolExt;
IUpdateCallbackUI *Callback;
@@ -67,6 +67,7 @@ public:
const CRecordVector<CUpdatePair2> *UpdatePairs;
const UStringVector *NewNames;
CMyComPtr<IInArchive> Archive;
+ bool KeepOriginalItemNames;
CArchiveUpdateCallback();
};
diff --git a/CPP/7zip/UI/Common/WorkDir.cpp b/CPP/7zip/UI/Common/WorkDir.cpp
index 164118e2..1ecb5b54 100755
--- a/CPP/7zip/UI/Common/WorkDir.cpp
+++ b/CPP/7zip/UI/Common/WorkDir.cpp
@@ -5,23 +5,23 @@
#include "Common/StringConvert.h"
#include "Common/Wildcard.h"
-#include "Windows/FileDir.h"
#include "Windows/FileName.h"
#include "WorkDir.h"
using namespace NWindows;
using namespace NFile;
+using namespace NDirectory;
-UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path)
+FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FString &fileName)
{
NWorkDir::NMode::EEnum mode = workDirInfo.Mode;
#ifndef UNDER_CE
if (workDirInfo.ForRemovableOnly)
{
mode = NWorkDir::NMode::kCurrent;
- UString prefix = path.Left(3);
- if (prefix[1] == L':' && prefix[2] == L'\\')
+ FString prefix = path.Left(3);
+ if (prefix[1] == FTEXT(':') && prefix[2] == FTEXT('\\'))
{
UINT driveType = GetDriveType(GetSystemString(prefix, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP));
if (driveType == DRIVE_CDROM || driveType == DRIVE_REMOVABLE)
@@ -36,24 +36,56 @@ UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path)
*/
}
#endif
- switch(mode)
+ int pos = path.ReverseFind(FCHAR_PATH_SEPARATOR) + 1;
+ fileName = path.Mid(pos);
+ switch (mode)
{
case NWorkDir::NMode::kCurrent:
{
- return ExtractDirPrefixFromPath(path);
+ return path.Left(pos);;
}
case NWorkDir::NMode::kSpecified:
{
- UString tempDir = workDirInfo.Path;
+ FString tempDir = workDirInfo.Path;
NName::NormalizeDirPathPrefix(tempDir);
return tempDir;
}
default:
{
- UString tempDir;
- if (!NDirectory::MyGetTempPath(tempDir))
+ FString tempDir;
+ if (!MyGetTempPath(tempDir))
throw 141717;
return tempDir;
}
}
}
+
+HRESULT CWorkDirTempFile::CreateTempFile(const FString &originalPath)
+{
+ NWorkDir::CInfo workDirInfo;
+ workDirInfo.Load();
+ FString namePart;
+ FString workDir = GetWorkDir(workDirInfo, originalPath, namePart);
+ CreateComplexDirectory(workDir);
+ CTempFile tempFile;
+ _outStreamSpec = new COutFileStream;
+ OutStream = _outStreamSpec;
+ if (!_tempFile.Create(workDir + namePart, &_outStreamSpec->File))
+ {
+ DWORD error = GetLastError();
+ return error ? error : E_FAIL;
+ }
+ _originalPath = originalPath;
+ return S_OK;
+}
+
+HRESULT CWorkDirTempFile::MoveToOriginal(bool deleteOriginal)
+{
+ OutStream.Release();
+ if (!_tempFile.MoveTo(_originalPath, deleteOriginal))
+ {
+ DWORD error = GetLastError();
+ return error ? error : E_FAIL;
+ }
+ return S_OK;
+}
diff --git a/CPP/7zip/UI/Common/WorkDir.h b/CPP/7zip/UI/Common/WorkDir.h
index 0643d67a..79ea2b9d 100755
--- a/CPP/7zip/UI/Common/WorkDir.h
+++ b/CPP/7zip/UI/Common/WorkDir.h
@@ -1,10 +1,26 @@
// WorkDir.h
-#ifndef __WORKDIR_H
-#define __WORKDIR_H
+#ifndef __WORK_DIR_H
+#define __WORK_DIR_H
+
+#include "Windows/FileDir.h"
#include "ZipRegistry.h"
-UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path);
+#include "../../Common/FileStreams.h"
+
+FString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const FString &path, FString &fileName);
+
+class CWorkDirTempFile
+{
+ FString _originalPath;
+ NWindows::NFile::NDirectory::CTempFile _tempFile;
+ COutFileStream *_outStreamSpec;
+public:
+ CMyComPtr<IOutStream> OutStream;
+
+ HRESULT CreateTempFile(const FString &originalPath);
+ HRESULT MoveToOriginal(bool deleteOriginal);
+};
#endif
diff --git a/CPP/7zip/UI/Common/ZipRegistry.cpp b/CPP/7zip/UI/Common/ZipRegistry.cpp
index ac178078..d2aec4c6 100755
--- a/CPP/7zip/UI/Common/ZipRegistry.cpp
+++ b/CPP/7zip/UI/Common/ZipRegistry.cpp
@@ -3,7 +3,6 @@
#include "StdAfx.h"
#include "Common/IntToString.h"
-#include "Common/StringConvert.h"
#include "Windows/FileDir.h"
#include "Windows/Registry.h"
@@ -53,6 +52,13 @@ void CInfo::Save() const
key.SetValue_Strings(kPathHistory, Paths);
}
+void Save_ShowPassword(bool showPassword)
+{
+ CS_LOCK
+ CKey key;
+ CreateMainKey(key, kKeyName);
+ key.SetValue(kShowPassword, showPassword);
+}
void CInfo::Load()
{
@@ -75,6 +81,17 @@ void CInfo::Load()
key.GetValue_IfOk(kShowPassword, ShowPassword);
}
+bool Read_ShowPassword()
+{
+ CS_LOCK
+ CKey key;
+ bool showPassword = false;
+ if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS)
+ return showPassword;
+ key.GetValue_IfOk(kShowPassword, showPassword);
+ return showPassword;
+}
+
}
namespace NCompression
@@ -234,7 +251,7 @@ void CInfo::Save()const
CKey key;
CreateMainKey(key, kOptionsInfoKeyName);
key.SetValue(kWorkDirType, (UInt32)Mode);
- key.SetValue(kWorkDirPath, Path);
+ key.SetValue(kWorkDirPath, fs2us(Path));
key.SetValue(kTempRemovableOnly, ForRemovableOnly);
}
@@ -257,7 +274,10 @@ void CInfo::Load()
case NMode::kSpecified:
Mode = (NMode::EEnum)dirType;
}
- if (key.QueryValue(kWorkDirPath, Path) != ERROR_SUCCESS)
+ UString pathU;
+ if (key.QueryValue(kWorkDirPath, pathU) == ERROR_SUCCESS)
+ Path = us2fs(pathU);
+ else
{
Path.Empty();
if (Mode == NMode::kSpecified)
diff --git a/CPP/7zip/UI/Common/ZipRegistry.h b/CPP/7zip/UI/Common/ZipRegistry.h
index 37835386..6d8b7c13 100755
--- a/CPP/7zip/UI/Common/ZipRegistry.h
+++ b/CPP/7zip/UI/Common/ZipRegistry.h
@@ -20,6 +20,8 @@ namespace NExtract
void Save() const;
void Load();
};
+ void Save_ShowPassword(bool showPassword);
+ bool Read_ShowPassword();
}
namespace NCompression
@@ -76,7 +78,7 @@ namespace NWorkDir
struct CInfo
{
NMode::EEnum Mode;
- UString Path;
+ FString Path;
bool ForRemovableOnly;
void SetForRemovableOnlyDefault() { ForRemovableOnly = true; }
diff --git a/CPP/7zip/UI/Console/BenchCon.cpp b/CPP/7zip/UI/Console/BenchCon.cpp
index 35e868c9..d0e43222 100755
--- a/CPP/7zip/UI/Console/BenchCon.cpp
+++ b/CPP/7zip/UI/Console/BenchCon.cpp
@@ -2,296 +2,41 @@
#include "StdAfx.h"
-#include "../../../Common/IntToString.h"
-#include "../../../Common/MyCom.h"
-
-#if !defined(_7ZIP_ST) || defined(_WIN32)
-#include "../../../Windows/System.h"
-#endif
-
#include "../Common/Bench.h"
#include "BenchCon.h"
#include "ConsoleClose.h"
-struct CTotalBenchRes
+struct CPrintBenchCallback: public IBenchPrintCallback
{
- UInt64 NumIterations;
- UInt64 Rating;
- UInt64 Usage;
- UInt64 RPU;
- void Init() { NumIterations = 0; Rating = 0; Usage = 0; RPU = 0; }
- void Normalize()
- {
- if (NumIterations == 0)
- return;
- Rating /= NumIterations;
- Usage /= NumIterations;
- RPU /= NumIterations;
- NumIterations = 1;
- }
- void SetMid(const CTotalBenchRes &r1, const CTotalBenchRes &r2)
- {
- Rating = (r1.Rating + r2.Rating) / 2;
- Usage = (r1.Usage + r2.Usage) / 2;
- RPU = (r1.RPU + r2.RPU) / 2;
- NumIterations = (r1.NumIterations + r2.NumIterations) / 2;
- }
-};
+ FILE *_file;
-struct CBenchCallback: public IBenchCallback
-{
- CTotalBenchRes EncodeRes;
- CTotalBenchRes DecodeRes;
- FILE *f;
- void Init() { EncodeRes.Init(); DecodeRes.Init(); }
- void Normalize() { EncodeRes.Normalize(); DecodeRes.Normalize(); }
- UInt32 dictionarySize;
- HRESULT SetEncodeResult(const CBenchInfo &info, bool final);
- HRESULT SetDecodeResult(const CBenchInfo &info, bool final);
+ void Print(const char *s);
+ void NewLine();
+ HRESULT CheckBreak();
};
-static void NormalizeVals(UInt64 &v1, UInt64 &v2)
-{
- while (v1 > 1000000)
- {
- v1 >>= 1;
- v2 >>= 1;
- }
-}
-
-static UInt64 MyMultDiv64(UInt64 value, UInt64 elapsedTime, UInt64 freq)
-{
- UInt64 elTime = elapsedTime;
- NormalizeVals(freq, elTime);
- if (elTime == 0)
- elTime = 1;
- return value * freq / elTime;
-}
-
-static void PrintNumber(FILE *f, UInt64 value, int size)
-{
- char s[32];
- ConvertUInt64ToString(value, s);
- fprintf(f, " ");
- for (int len = (int)strlen(s); len < size; len++)
- fprintf(f, " ");
- fputs(s, f);
-}
-
-static void PrintRating(FILE *f, UInt64 rating)
-{
- PrintNumber(f, rating / 1000000, 6);
-}
-
-static void PrintResults(FILE *f, UInt64 usage, UInt64 rpu, UInt64 rating)
-{
- PrintNumber(f, (usage + 5000) / 10000, 5);
- PrintRating(f, rpu);
- PrintRating(f, rating);
-}
-
-
-static void PrintResults(FILE *f, const CBenchInfo &info, UInt64 rating, CTotalBenchRes &res)
+void CPrintBenchCallback::Print(const char *s)
{
- UInt64 speed = MyMultDiv64(info.UnpackSize, info.GlobalTime, info.GlobalFreq);
- PrintNumber(f, speed / 1024, 7);
- UInt64 usage = GetUsage(info);
- UInt64 rpu = GetRatingPerUsage(info, rating);
- PrintResults(f, usage, rpu, rating);
- res.NumIterations++;
- res.RPU += rpu;
- res.Rating += rating;
- res.Usage += usage;
+ fputs(s, _file);
}
-static void PrintTotals(FILE *f, const CTotalBenchRes &res)
+void CPrintBenchCallback::NewLine()
{
- fprintf(f, " ");
- PrintResults(f, res.Usage, res.RPU, res.Rating);
+ Print("\n");
}
-
-HRESULT CBenchCallback::SetEncodeResult(const CBenchInfo &info, bool final)
-{
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- if (final)
- {
- UInt64 rating = GetCompressRating(dictionarySize, info.GlobalTime, info.GlobalFreq, info.UnpackSize);
- PrintResults(f, info, rating, EncodeRes);
- }
- return S_OK;
-}
-
-static const char *kSep = " | ";
-
-
-HRESULT CBenchCallback::SetDecodeResult(const CBenchInfo &info, bool final)
-{
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- if (final)
- {
- UInt64 rating = GetDecompressRating(info.GlobalTime, info.GlobalFreq, info.UnpackSize, info.PackSize, info.NumIterations);
- fputs(kSep, f);
- CBenchInfo info2 = info;
- info2.UnpackSize *= info2.NumIterations;
- info2.PackSize *= info2.NumIterations;
- info2.NumIterations = 1;
- PrintResults(f, info2, rating, DecodeRes);
- }
- return S_OK;
-}
-
-static void PrintRequirements(FILE *f, const char *sizeString, UInt64 size, const char *threadsString, UInt32 numThreads)
-{
- fprintf(f, "\nRAM %s ", sizeString);
- PrintNumber(f, (size >> 20), 5);
- fprintf(f, " MB, # %s %3d", threadsString, (unsigned int)numThreads);
-}
-
-HRESULT LzmaBenchCon(
- DECL_EXTERNAL_CODECS_LOC_VARS
- FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary)
+HRESULT CPrintBenchCallback::CheckBreak()
{
- if (!CrcInternalTest())
- return S_FALSE;
- #ifndef _7ZIP_ST
- UInt64 ramSize = NWindows::NSystem::GetRamSize(); //
- UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();
- PrintRequirements(f, "size: ", ramSize, "CPU hardware threads:", numCPUs);
- if (numThreads == (UInt32)-1)
- numThreads = numCPUs;
- if (numThreads > 1)
- numThreads &= ~1;
- if (dictionary == (UInt32)-1)
- {
- int dicSizeLog;
- for (dicSizeLog = 25; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--)
- if (GetBenchMemoryUsage(numThreads, ((UInt32)1 << dicSizeLog)) + (8 << 20) <= ramSize)
- break;
- dictionary = (1 << dicSizeLog);
- }
- #else
- if (dictionary == (UInt32)-1)
- dictionary = (1 << 22);
- numThreads = 1;
- #endif
-
- PrintRequirements(f, "usage:", GetBenchMemoryUsage(numThreads, dictionary), "Benchmark threads: ", numThreads);
-
- CBenchCallback callback;
- callback.Init();
- callback.f = f;
-
- fprintf(f, "\n\nDict Compressing | Decompressing\n ");
- int j;
- for (j = 0; j < 2; j++)
- {
- fprintf(f, " Speed Usage R/U Rating");
- if (j == 0)
- fputs(kSep, f);
- }
- fprintf(f, "\n ");
- for (j = 0; j < 2; j++)
- {
- fprintf(f, " KB/s %% MIPS MIPS");
- if (j == 0)
- fputs(kSep, f);
- }
- fprintf(f, "\n\n");
- for (UInt32 i = 0; i < numIterations; i++)
- {
- const int kStartDicLog = 22;
- int pow = (dictionary < ((UInt32)1 << kStartDicLog)) ? kBenchMinDicLogSize : kStartDicLog;
- while (((UInt32)1 << pow) > dictionary)
- pow--;
- for (; ((UInt32)1 << pow) <= dictionary; pow++)
- {
- fprintf(f, "%2d:", pow);
- callback.dictionarySize = (UInt32)1 << pow;
- HRESULT res = LzmaBench(
- EXTERNAL_CODECS_LOC_VARS
- numThreads, callback.dictionarySize, &callback);
- fprintf(f, "\n");
- RINOK(res);
- }
- }
- callback.Normalize();
- fprintf(f, "----------------------------------------------------------------\nAvr:");
- PrintTotals(f, callback.EncodeRes);
- fprintf(f, " ");
- PrintTotals(f, callback.DecodeRes);
- fprintf(f, "\nTot:");
- CTotalBenchRes midRes;
- midRes.SetMid(callback.EncodeRes, callback.DecodeRes);
- PrintTotals(f, midRes);
- fprintf(f, "\n");
- return S_OK;
+ return NConsoleClose::TestBreakSignal() ? E_ABORT: S_OK;
}
-struct CTempValues
-{
- UInt64 *Values;
- CTempValues(UInt32 num) { Values = new UInt64[num]; }
- ~CTempValues() { delete []Values; }
-};
-
-HRESULT CrcBenchCon(FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary)
+HRESULT BenchCon(DECL_EXTERNAL_CODECS_LOC_VARS
+ const CObjectVector<CProperty> props, UInt32 numIterations, FILE *f)
{
- if (!CrcInternalTest())
- return S_FALSE;
-
- #ifndef _7ZIP_ST
- UInt64 ramSize = NWindows::NSystem::GetRamSize();
- UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors();
- PrintRequirements(f, "size: ", ramSize, "CPU hardware threads:", numCPUs);
- if (numThreads == (UInt32)-1)
- numThreads = numCPUs;
- #else
- numThreads = 1;
- #endif
- if (dictionary == (UInt32)-1)
- dictionary = (1 << 24);
-
- CTempValues speedTotals(numThreads);
- fprintf(f, "\n\nSize");
- for (UInt32 ti = 0; ti < numThreads; ti++)
- {
- fprintf(f, " %5d", ti + 1);
- speedTotals.Values[ti] = 0;
- }
- fprintf(f, "\n\n");
-
- UInt64 numSteps = 0;
- for (UInt32 i = 0; i < numIterations; i++)
- {
- for (int pow = 10; pow < 32; pow++)
- {
- UInt32 bufSize = (UInt32)1 << pow;
- if (bufSize > dictionary)
- break;
- fprintf(f, "%2d: ", pow);
- UInt64 speed;
- for (UInt32 ti = 0; ti < numThreads; ti++)
- {
- if (NConsoleClose::TestBreakSignal())
- return E_ABORT;
- RINOK(CrcBench(ti + 1, bufSize, speed));
- PrintNumber(f, (speed >> 20), 5);
- speedTotals.Values[ti] += speed;
- }
- fprintf(f, "\n");
- numSteps++;
- }
- }
- if (numSteps != 0)
- {
- fprintf(f, "\nAvg:");
- for (UInt32 ti = 0; ti < numThreads; ti++)
- PrintNumber(f, ((speedTotals.Values[ti] / numSteps) >> 20), 5);
- fprintf(f, "\n");
- }
- return S_OK;
+ CPrintBenchCallback callback;
+ callback._file = f;
+ callback.NewLine();
+ return Bench(EXTERNAL_CODECS_LOC_VARS
+ &callback, NULL, props, numIterations, true);
}
diff --git a/CPP/7zip/UI/Console/BenchCon.h b/CPP/7zip/UI/Console/BenchCon.h
index 966a83a6..73972186 100755
--- a/CPP/7zip/UI/Console/BenchCon.h
+++ b/CPP/7zip/UI/Console/BenchCon.h
@@ -6,11 +6,9 @@
#include <stdio.h>
#include "../../Common/CreateCoder.h"
+#include "../../UI/Common/Property.h"
-HRESULT LzmaBenchCon(
- DECL_EXTERNAL_CODECS_LOC_VARS
- FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary);
-
-HRESULT CrcBenchCon(FILE *f, UInt32 numIterations, UInt32 numThreads, UInt32 dictionary);
+HRESULT BenchCon(DECL_EXTERNAL_CODECS_LOC_VARS
+ const CObjectVector<CProperty> props, UInt32 numIterations, FILE *f);
#endif
diff --git a/CPP/7zip/UI/Console/Console.dsp b/CPP/7zip/UI/Console/Console.dsp
index 09633ee5..7c1719da 100755
--- a/CPP/7zip/UI/Console/Console.dsp
+++ b/CPP/7zip/UI/Console/Console.dsp
@@ -628,14 +628,6 @@ SOURCE=..\Common\UpdateProduce.h
# End Source File
# Begin Source File
-SOURCE=..\Common\WorkDir.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\Common\WorkDir.h
-# End Source File
-# Begin Source File
-
SOURCE=..\Common\ZipRegistry.h
# End Source File
# End Group
@@ -676,6 +668,14 @@ SOURCE=..\..\Common\FilterCoder.h
# End Source File
# Begin Source File
+SOURCE=..\..\Common\MethodProps.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MethodProps.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Common\ProgressUtils.cpp
# End Source File
# Begin Source File
diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
index af65739c..af379861 100755
--- a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
+++ b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp
@@ -182,7 +182,7 @@ HRESULT CExtractCallbackConsole::OpenResult(const wchar_t * /* name */, HRESULT
if (result == E_OUTOFMEMORY)
(*OutStream) << "Can't allocate required memory";
else
- (*OutStream) << NError::MyFormatMessage(result);
+ (*OutStream) << NError::MyFormatMessageW(result);
}
(*OutStream) << endl;
NumArchiveErrors++;
@@ -218,11 +218,7 @@ HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result)
if (result == E_OUTOFMEMORY)
(*OutStream) << kMemoryExceptionMessage;
else
- {
- UString message;
- NError::MyFormatMessage(result, message);
- (*OutStream) << message;
- }
+ (*OutStream) << NError::MyFormatMessageW(result);
(*OutStream) << endl;
return S_OK;
}
diff --git a/CPP/7zip/UI/Console/List.cpp b/CPP/7zip/UI/Console/List.cpp
index f747cfda..7de2379a 100755
--- a/CPP/7zip/UI/Console/List.cpp
+++ b/CPP/7zip/UI/Console/List.cpp
@@ -437,8 +437,8 @@ HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices,
UInt64 arcPackSize = 0;
if (!stdInMode)
{
- NFile::NFind::CFileInfoW fi;
- if (!fi.Find(archiveName) || fi.IsDir())
+ NFile::NFind::CFileInfo fi;
+ if (!fi.Find(us2fs(archiveName)) || fi.IsDir())
{
g_StdOut << endl << "Error: " << archiveName << " is not file" << endl;
numErrors++;
@@ -477,7 +477,7 @@ HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices,
else if (result == E_OUTOFMEMORY)
g_StdOut << "Can't allocate required memory";
else
- g_StdOut << NError::MyFormatMessage(result);
+ g_StdOut << NError::MyFormatMessageW(result);
g_StdOut << endl;
numErrors++;
continue;
diff --git a/CPP/7zip/UI/Console/Main.cpp b/CPP/7zip/UI/Console/Main.cpp
index 9bd451f8..722b09e2 100755
--- a/CPP/7zip/UI/Console/Main.cpp
+++ b/CPP/7zip/UI/Console/Main.cpp
@@ -39,7 +39,9 @@ using namespace NWindows;
using namespace NFile;
using namespace NCommandLineParser;
+#ifdef _WIN32
HINSTANCE g_hInstance = 0;
+#endif
extern CStdOutStream *g_StdStream;
static const char *kCopyrightString = "\n7-Zip"
@@ -111,7 +113,7 @@ static const char *kUserErrorMessage = "Incorrect command line";
static const char *kNoFormats = "7-Zip cannot find the code that works with archives.";
static const char *kUnsupportedArcTypeMessage = "Unsupported archive type";
-static const wchar_t *kDefaultSfxModule = L"7zCon.sfx";
+static CFSTR kDefaultSfxModule = FTEXT("7zCon.sfx");
static void ShowMessageAndThrowException(CStdOutStream &s, LPCSTR message, NExitCode::EEnum code)
{
@@ -338,20 +340,6 @@ int Main2(
}
else if (options.Command.CommandType == NCommandType::kBenchmark)
{
- if (options.Method.CompareNoCase(L"CRC") == 0)
- {
- HRESULT res = CrcBenchCon((FILE *)stdStream, options.NumIterations, options.NumThreads, options.DictionarySize);
- if (res != S_OK)
- {
- if (res == S_FALSE)
- {
- stdStream << "\nCRC Error\n";
- return NExitCode::kFatalError;
- }
- throw CSystemException(res);
- }
- }
- else
{
HRESULT res;
#ifdef EXTERNAL_CODECS
@@ -360,11 +348,11 @@ int Main2(
if (res != S_OK)
throw CSystemException(res);
#endif
- res = LzmaBenchCon(
+ res = BenchCon(
#ifdef EXTERNAL_CODECS
compressCodecsInfo, &externalCodecs,
#endif
- (FILE *)stdStream, options.NumIterations, options.NumThreads, options.DictionarySize);
+ options.Properties, options.NumIterations, (FILE *)stdStream);
if (res != S_OK)
{
if (res == S_FALSE)
@@ -410,7 +398,7 @@ int Main2(
eo.YesToAll = options.YesToAll;
eo.CalcCrc = options.CalcCrc;
#if !defined(_7ZIP_ST) && !defined(_SFX)
- eo.Properties = options.ExtractProperties;
+ eo.Properties = options.Properties;
#endif
UString errorMessage;
CDecompressStat stat;
@@ -480,7 +468,7 @@ int Main2(
numErrors);
if (numErrors > 0)
{
- g_StdOut << endl << "Errors: " << numErrors;
+ g_StdOut << endl << "Errors: " << numErrors << endl;
return NExitCode::kFatalError;
}
if (result != S_OK)
@@ -551,12 +539,12 @@ int Main2(
}
if (!errorInfo.FileName.IsEmpty())
{
- message += errorInfo.FileName;
+ message += fs2us(errorInfo.FileName);
message += L"\n";
}
if (!errorInfo.FileName2.IsEmpty())
{
- message += errorInfo.FileName2;
+ message += fs2us(errorInfo.FileName2);
message += L"\n";
}
if (errorInfo.SystemError != 0)
diff --git a/CPP/7zip/UI/Console/MainAr.cpp b/CPP/7zip/UI/Console/MainAr.cpp
index c54a3d09..25f4bd0d 100755
--- a/CPP/7zip/UI/Console/MainAr.cpp
+++ b/CPP/7zip/UI/Console/MainAr.cpp
@@ -79,9 +79,8 @@ int MY_CDECL main
(*g_StdStream) << endl << kUserBreak;
return (NExitCode::kUserBreak);
}
- UString message;
- NError::MyFormatMessage(systemError.ErrorCode, message);
- (*g_StdStream) << endl << endl << "System error:" << endl << message << endl;
+ (*g_StdStream) << endl << endl << "System error:" << endl <<
+ NError::MyFormatMessageW(systemError.ErrorCode) << endl;
return (NExitCode::kFatalError);
}
catch(NExitCode::EEnum &exitCode)
diff --git a/CPP/7zip/UI/Console/PercentPrinter.cpp b/CPP/7zip/UI/Console/PercentPrinter.cpp
index 28452b17..786db1bc 100755
--- a/CPP/7zip/UI/Console/PercentPrinter.cpp
+++ b/CPP/7zip/UI/Console/PercentPrinter.cpp
@@ -7,13 +7,13 @@
#include "PercentPrinter.h"
-const int kPaddingSize = 2;
-const int kPercentsSize = 4;
-const int kMaxExtraSize = kPaddingSize + 32 + kPercentsSize;
+static const unsigned kPaddingSize = 2;
+static const unsigned kPercentsSize = 4;
+static const unsigned kMaxExtraSize = kPaddingSize + 32 + kPercentsSize;
-static void ClearPrev(char *p, int num)
+static void ClearPrev(char *p, unsigned num)
{
- int i;
+ unsigned i;
for (i = 0; i < num; i++) *p++ = '\b';
for (i = 0; i < num; i++) *p++ = ' ';
for (i = 0; i < num; i++) *p++ = '\b';
@@ -51,18 +51,30 @@ void CPercentPrinter::PrintNewLine()
void CPercentPrinter::RePrintRatio()
{
char s[32];
- ConvertUInt64ToString(((m_Total == 0) ? 0 : (m_CurValue * 100 / m_Total)), s);
- int size = (int)strlen(s);
- s[size++] = '%';
- s[size] = '\0';
+ unsigned size;
+ {
+ char c = '%';
+ UInt64 value = 0;
+ if (m_Total == (UInt64)(Int64)-1)
+ {
+ value = m_CurValue >> 20;
+ c = 'M';
+ }
+ else if (m_Total != 0)
+ value = m_CurValue * 100 / m_Total;
+ ConvertUInt64ToString(value, s);
+ size = (unsigned)strlen(s);
+ s[size++] = c;
+ s[size] = '\0';
+ }
- int extraSize = kPaddingSize + MyMax(size, kPercentsSize);
+ unsigned extraSize = kPaddingSize + MyMax(size, kPercentsSize);
if (extraSize < m_NumExtraChars)
extraSize = m_NumExtraChars;
char fullString[kMaxExtraSize * 3];
char *p = fullString;
- int i;
+ unsigned i;
if (m_NumExtraChars == 0)
{
for (i = 0; i < extraSize; i++)
@@ -73,7 +85,7 @@ void CPercentPrinter::RePrintRatio()
for (i = 0; i < m_NumExtraChars; i++)
*p++ = '\b';
m_NumExtraChars = extraSize;
- for (; size < m_NumExtraChars; size++)
+ for (; size < extraSize; size++)
*p++ = ' ';
MyStringCopy(p, s);
(*OutStream) << fullString;
diff --git a/CPP/7zip/UI/Console/PercentPrinter.h b/CPP/7zip/UI/Console/PercentPrinter.h
index 97f2e6ad..d970cc4b 100755
--- a/CPP/7zip/UI/Console/PercentPrinter.h
+++ b/CPP/7zip/UI/Console/PercentPrinter.h
@@ -1,9 +1,8 @@
// PercentPrinter.h
-#ifndef __PERCENTPRINTER_H
-#define __PERCENTPRINTER_H
+#ifndef __PERCENT_PRINTER_H
+#define __PERCENT_PRINTER_H
-#include "Common/Types.h"
#include "Common/StdOutStream.h"
class CPercentPrinter
@@ -12,12 +11,12 @@ class CPercentPrinter
UInt64 m_PrevValue;
UInt64 m_CurValue;
UInt64 m_Total;
- int m_NumExtraChars;
+ unsigned m_NumExtraChars;
public:
CStdOutStream *OutStream;
CPercentPrinter(UInt64 minStepSize = 1): m_MinStepSize(minStepSize),
- m_PrevValue(0), m_CurValue(0), m_Total(1), m_NumExtraChars(0) {}
+ m_PrevValue(0), m_CurValue(0), m_Total((UInt64)(Int64)-1), m_NumExtraChars(0) {}
void SetTotal(UInt64 total) { m_Total = total; m_PrevValue = 0; }
void SetRatio(UInt64 doneValue) { m_CurValue = doneValue; }
void PrintString(const char *s);
diff --git a/CPP/7zip/UI/Console/makefile b/CPP/7zip/UI/Console/makefile
index 9b8fc37a..f100f635 100755
--- a/CPP/7zip/UI/Console/makefile
+++ b/CPP/7zip/UI/Console/makefile
@@ -54,6 +54,7 @@ WIN_OBJS = \
$O\FilePathAutoRename.obj \
$O\FileStreams.obj \
$O\FilterCoder.obj \
+ $O\MethodProps.obj \
$O\ProgressUtils.obj \
$O\StreamUtils.obj \
@@ -77,7 +78,6 @@ UI_COMMON_OBJS = \
$O\UpdateCallback.obj \
$O\UpdatePair.obj \
$O\UpdateProduce.obj \
- $O\WorkDir.obj \
AR_COMMON_OBJS = \
$O\OutStreamWithCRC.obj \
diff --git a/CPP/7zip/UI/Explorer/ContextMenu.cpp b/CPP/7zip/UI/Explorer/ContextMenu.cpp
index ca5bf816..4bdc397a 100755
--- a/CPP/7zip/UI/Explorer/ContextMenu.cpp
+++ b/CPP/7zip/UI/Explorer/ContextMenu.cpp
@@ -7,8 +7,10 @@
#include "Common/StringConvert.h"
#include "Windows/COM.h"
+#include "Windows/DLL.h"
#include "Windows/FileDir.h"
#include "Windows/FileFind.h"
+#include "Windows/FileName.h"
#include "Windows/Memory.h"
#include "Windows/Menu.h"
#include "Windows/Process.h"
@@ -20,7 +22,6 @@
#include "../Common/ZipRegistry.h"
#include "../FileManager/FormatUtils.h"
-#include "../FileManager/ProgramLocation.h"
#ifdef LANG
#include "../FileManager/LangUtils.h"
@@ -338,8 +339,9 @@ static const char *kExtractExludeExtensions =
static const char *kNoOpenAsExtensions =
" 7z arj bz2 cab chm cpio dmg flv gz lha lzh lzma rar swm tar tbz2 tgz wim xar xz z zip ";
-static bool FindExt(const char *p, const UString &name)
+static bool FindExt(const char *p, const FString &nameF)
{
+ const UString name = fs2us(nameF);
int extPos = name.ReverseFind('.');
if (extPos < 0)
return false;
@@ -357,7 +359,7 @@ static bool FindExt(const char *p, const UString &name)
return false;
}
-static bool DoNeedExtract(const UString &name)
+static bool DoNeedExtract(const FString &name)
{
return !FindExt(kExtractExludeExtensions, name);
}
@@ -408,11 +410,8 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if (_fileNames.Size() == 1 && currentCommandID + 6 <= commandIDLast)
{
const UString &fileName = _fileNames.Front();
- UString folderPrefix;
- NFile::NDirectory::GetOnlyDirPrefix(fileName, folderPrefix);
-
- NFile::NFind::CFileInfoW fileInfo;
- if (!fileInfo.Find(fileName))
+ NFile::NFind::CFileInfo fileInfo;
+ if (!fileInfo.Find(us2fs(fileName)))
return E_FAIL;
if (!fileInfo.IsDir() && DoNeedExtract(fileInfo.Name))
{
@@ -473,10 +472,10 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if (_fileNames.Size() > 0 && currentCommandID + 10 <= commandIDLast)
{
bool needExtract = false;
- for(int i = 0; i < _fileNames.Size(); i++)
+ for (int i = 0; i < _fileNames.Size(); i++)
{
- NFile::NFind::CFileInfoW fileInfo;
- if (!fileInfo.Find(_fileNames[i]))
+ NFile::NFind::CFileInfo fileInfo;
+ if (!fileInfo.Find(us2fs(_fileNames[i])))
return E_FAIL;
if (!fileInfo.IsDir() && DoNeedExtract(fileInfo.Name))
needExtract = true;
@@ -484,10 +483,10 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
const UString &fileName = _fileNames.Front();
if (needExtract)
{
- UString folderPrefix;
- NFile::NDirectory::GetOnlyDirPrefix(fileName, folderPrefix);
- NFile::NFind::CFileInfoW fileInfo;
- if (!fileInfo.Find(fileName))
+ FString folderPrefix;
+ NFile::NDirectory::GetOnlyDirPrefix(us2fs(fileName), folderPrefix);
+ NFile::NFind::CFileInfo fileInfo;
+ if (!fileInfo.Find(us2fs(fileName)))
return E_FAIL;
// Extract
if ((contextMenuFlags & NContextMenuFlags::kExtract) != 0)
@@ -497,8 +496,8 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if (_dropMode)
commandMapItem.Folder = _dropPath;
else
- commandMapItem.Folder = folderPrefix;
- commandMapItem.Folder += GetSubFolderNameForExtract(fileInfo.Name) + UString(WCHAR_PATH_SEPARATOR);
+ commandMapItem.Folder = fs2us(folderPrefix);
+ commandMapItem.Folder += GetSubFolderNameForExtract(fs2us(fileInfo.Name)) + UString(WCHAR_PATH_SEPARATOR);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
_commandMap.Add(commandMapItem);
}
@@ -512,7 +511,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if (_dropMode)
commandMapItem.Folder = _dropPath;
else
- commandMapItem.Folder = folderPrefix;
+ commandMapItem.Folder = fs2us(folderPrefix);
_commandMap.Add(commandMapItem);
}
@@ -524,13 +523,13 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
FillCommand(kExtractTo, s, commandMapItem);
UString folder;
if (_fileNames.Size() == 1)
- folder = GetSubFolderNameForExtract(fileInfo.Name);
+ folder = GetSubFolderNameForExtract(fs2us(fileInfo.Name));
else
folder = L'*';
if (_dropMode)
commandMapItem.Folder = _dropPath;
else
- commandMapItem.Folder = folderPrefix;
+ commandMapItem.Folder = fs2us(folderPrefix);
commandMapItem.Folder += folder;
s = MyFormatNew(s, GetQuotedReducedString(folder + UString(WCHAR_PATH_SEPARATOR)));
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s);
@@ -548,8 +547,8 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
UString archiveName = CreateArchiveName(fileName, _fileNames.Size() > 1, false);
UString archiveName7z = archiveName + L".7z";
UString archiveNameZip = archiveName + L".zip";
- UString archivePathPrefix;
- NFile::NDirectory::GetOnlyDirPrefix(fileName, archivePathPrefix);
+ FString archivePathPrefix;
+ NFile::NDirectory::GetOnlyDirPrefix(us2fs(fileName), archivePathPrefix);
// Compress
if ((contextMenuFlags & NContextMenuFlags::kCompress) != 0)
@@ -558,7 +557,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if (_dropMode)
commandMapItem.Folder = _dropPath;
else
- commandMapItem.Folder = archivePathPrefix;
+ commandMapItem.Folder = fs2us(archivePathPrefix);
commandMapItem.ArcName = archiveName;
FillCommand(kCompress, mainString, commandMapItem);
MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString);
@@ -586,7 +585,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if (_dropMode)
commandMapItem.Folder = _dropPath;
else
- commandMapItem.Folder = archivePathPrefix;
+ commandMapItem.Folder = fs2us(archivePathPrefix);
commandMapItem.ArcName = archiveName7z;
commandMapItem.ArcType = L"7z";
s = MyFormatNew(s, GetQuotedReducedString(archiveName7z));
@@ -618,7 +617,7 @@ STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu,
if (_dropMode)
commandMapItem.Folder = _dropPath;
else
- commandMapItem.Folder = archivePathPrefix;
+ commandMapItem.Folder = fs2us(archivePathPrefix);
commandMapItem.ArcName = archiveNameZip;
commandMapItem.ArcType = L"zip";
s = MyFormatNew(s, GetQuotedReducedString(archiveNameZip));
@@ -675,9 +674,7 @@ int CZipContextMenu::FindVerb(const UString &verb)
static UString Get7zFmPath()
{
- UString path;
- GetProgramFolderPath(path);
- return path + L"7zFM.exe";
+ return fs2us(NWindows::NDLL::GetModuleDirPrefix()) + L"7zFM.exe";
}
STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo)
diff --git a/CPP/7zip/UI/Explorer/DllExports.cpp b/CPP/7zip/UI/Explorer/DllExports.cpp
index bc8ae177..4f649f59 100755
--- a/CPP/7zip/UI/Explorer/DllExports.cpp
+++ b/CPP/7zip/UI/Explorer/DllExports.cpp
@@ -35,16 +35,6 @@ using namespace NWindows;
HINSTANCE g_hInstance = 0;
HWND g_HWND = 0;
-UString HResultToMessage(HRESULT errorCode)
-{
- UString message;
- if (!NError::MyFormatMessage(errorCode, message))
- message.Empty();
- if (message.IsEmpty())
- message = L"Error";
- return message;
-}
-
LONG g_DllRefCount = 0; // Reference count of this DLL.
static LPCWSTR kShellExtName = L"7-Zip Shell Extension";
@@ -191,14 +181,15 @@ static BOOL RegisterServer(CLSID clsid, LPCWSTR title)
if (!GetStringFromIID(clsid, clsidString, MAX_PATH))
return FALSE;
- UString modulePath;
- if (!NDLL::MyGetModuleFileName(g_hInstance, modulePath))
+ FString modulePath;
+ if (!NDLL::MyGetModuleFileName(modulePath))
return FALSE;
+ UString modulePathU = fs2us(modulePath);
CRegItem clsidEntries[] =
{
HKEY_CLASSES_ROOT, kClsidMask, NULL, title,
- HKEY_CLASSES_ROOT, kClsidInprocMask, NULL, modulePath,
+ HKEY_CLASSES_ROOT, kClsidInprocMask, NULL, modulePathU,
HKEY_CLASSES_ROOT, kClsidInprocMask, L"ThreadingModel", L"Apartment",
NULL, NULL, NULL, NULL
};
diff --git a/CPP/7zip/UI/Far/FarUtils.cpp b/CPP/7zip/UI/Far/FarUtils.cpp
index b980d846..9f55e8e5 100755
--- a/CPP/7zip/UI/Far/FarUtils.cpp
+++ b/CPP/7zip/UI/Far/FarUtils.cpp
@@ -449,8 +449,7 @@ bool WasEscPressed()
void ShowErrorMessage(DWORD errorCode)
{
- UString message;
- NError::MyFormatMessage(errorCode, message);
+ UString message = NError::MyFormatMessageW(errorCode);
message.Replace(L"\x0D", L"");
message.Replace(L"\x0A", L" ");
g_StartupInfo.ShowMessage(UnicodeStringToMultiByte(message, CP_OEMCP));
diff --git a/CPP/7zip/UI/Far/Main.cpp b/CPP/7zip/UI/Far/Main.cpp
index 5e017b80..7b58d0ca 100755
--- a/CPP/7zip/UI/Far/Main.cpp
+++ b/CPP/7zip/UI/Far/Main.cpp
@@ -87,12 +87,12 @@ class COpenArchiveCallback:
DWORD m_PrevTickCount;
- NWindows::NFile::NFind::CFileInfoW _fileInfo;
+ NWindows::NFile::NFind::CFileInfo _fileInfo;
public:
bool PasswordIsDefined;
UString Password;
- UString _folderPrefix;
+ FString _folderPrefix;
public:
MY_UNKNOWN_IMP3(
@@ -130,7 +130,7 @@ public:
}
void ShowMessage();
- void LoadFileInfo(const UString &folderPrefix, const UString &fileName)
+ void LoadFileInfo(const FString &folderPrefix, const FString &fileName)
{
_folderPrefix = folderPrefix;
if (!_fileInfo.Find(_folderPrefix + fileName))
@@ -251,7 +251,7 @@ STDMETHODIMP COpenArchiveCallback::GetStream(const wchar_t *name, IInStream **in
if (WasEscPressed())
return E_ABORT;
*inStream = NULL;
- UString fullPath = _folderPrefix + name;
+ FString fullPath = _folderPrefix + us2fs(name);
if (!_fileInfo.Find(fullPath))
return S_FALSE;
if (_fileInfo.IsDir())
@@ -333,16 +333,15 @@ HRESULT OpenArchive(const CSysString &fileName,
static HANDLE MyOpenFilePluginW(const wchar_t *name)
{
- UString normalizedName = name;
+ FString normalizedName = us2fs(name);
normalizedName.Trim();
- UString fullName;
- int fileNamePartStartIndex;
- NFile::NDirectory::MyGetFullPathName(normalizedName, fullName, fileNamePartStartIndex);
- NFile::NFind::CFileInfoW fileInfo;
+ FString fullName;
+ NFile::NDirectory::MyGetFullPathName(normalizedName, fullName);
+ NFile::NFind::CFileInfo fileInfo;
if (!fileInfo.Find(fullName))
return INVALID_HANDLE_VALUE;
if (fileInfo.IsDir())
- return INVALID_HANDLE_VALUE;
+ return INVALID_HANDLE_VALUE;
CMyComPtr<IInFolderArchive> archiveHandler;
@@ -360,9 +359,11 @@ static HANDLE MyOpenFilePluginW(const wchar_t *name)
// if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0)
openArchiveCallbackSpec->Init();
- openArchiveCallbackSpec->LoadFileInfo(
- fullName.Left(fileNamePartStartIndex),
- fullName.Mid(fileNamePartStartIndex));
+ {
+ FString dirPrefix, fileName;
+ NFile::NDirectory::GetFullPathAndSplit(fullName, dirPrefix, fileName);
+ openArchiveCallbackSpec->LoadFileInfo(dirPrefix, fileName);
+ }
// ::OutputDebugStringA("before OpenArchive\n");
@@ -449,7 +450,7 @@ EXTERN_C HANDLE WINAPI OpenPlugin(int openFrom, INT_PTR item)
if(fileName.IsEmpty())
return INVALID_HANDLE_VALUE;
if (fileName.Length() >= 2 &&
- fileName[0] == '\"' && fileName[fileName.Length() - 1] == '\"')
+ fileName[0] == '\"' && fileName.Back() == '\"')
fileName = fileName.Mid(1, fileName.Length() - 2);
return MyOpenFilePlugin(fileName);
diff --git a/CPP/7zip/UI/Far/Plugin.cpp b/CPP/7zip/UI/Far/Plugin.cpp
index a19b037c..8bdfb10d 100755
--- a/CPP/7zip/UI/Far/Plugin.cpp
+++ b/CPP/7zip/UI/Far/Plugin.cpp
@@ -18,7 +18,7 @@
using namespace NWindows;
using namespace NFar;
-CPlugin::CPlugin(const UString &fileName, IInFolderArchive *archiveHandler, UString archiveTypeName):
+CPlugin::CPlugin(const FString &fileName, IInFolderArchive *archiveHandler, UString archiveTypeName):
m_ArchiveHandler(archiveHandler),
m_FileName(fileName),
_archiveTypeName(archiveTypeName)
@@ -532,10 +532,10 @@ static void InsertSeparator(InfoPanelLine *lines, int &numItems)
void CPlugin::GetOpenPluginInfo(struct OpenPluginInfo *info)
{
info->StructSize = sizeof(*info);
- info->Flags = OPIF_USEFILTER | OPIF_USESORTGROUPS| OPIF_USEHIGHLIGHTING|
+ info->Flags = OPIF_USEFILTER | OPIF_USESORTGROUPS | OPIF_USEHIGHLIGHTING |
OPIF_ADDDOTS | OPIF_COMPAREFATTIME;
- COPY_STR_LIMITED(m_FileNameBuffer, UnicodeStringToMultiByte(m_FileName, CP_OEMCP));
+ COPY_STR_LIMITED(m_FileNameBuffer, UnicodeStringToMultiByte(fs2us(m_FileName), CP_OEMCP));
info->HostFile = m_FileNameBuffer; // test it it is not static
COPY_STR_LIMITED(m_CurrentDirBuffer, UnicodeStringToMultiByte(m_CurrentDir, CP_OEMCP));
@@ -545,10 +545,9 @@ void CPlugin::GetOpenPluginInfo(struct OpenPluginInfo *info)
UString name;
{
- UString fullName;
- int index;
- NFile::NDirectory::MyGetFullPathName(m_FileName, fullName, index);
- name = fullName.Mid(index);
+ FString dirPrefix, fileName;
+ NFile::NDirectory::GetFullPathAndSplit(m_FileName, dirPrefix, fileName);
+ name = fs2us(fileName);
}
m_PannelTitle =
@@ -852,14 +851,14 @@ int CPlugin::ProcessKey(int key, unsigned int controlState)
}
if ((controlState & PKF_ALT) != 0 && key == VK_F6)
{
- UString folderPath;
+ FString folderPath;
if (!NFile::NDirectory::GetOnlyDirPrefix(m_FileName, folderPath))
return FALSE;
PanelInfo panelInfo;
g_StartupInfo.ControlGetActivePanelInfo(panelInfo);
GetFilesReal(panelInfo.SelectedItems,
panelInfo.SelectedItemsNumber, FALSE,
- UnicodeStringToMultiByte(folderPath, CP_OEMCP), OPM_SILENT, true);
+ UnicodeStringToMultiByte(fs2us(folderPath), CP_OEMCP), OPM_SILENT, true);
g_StartupInfo.Control(this, FCTL_UPDATEPANEL, NULL);
g_StartupInfo.Control(this, FCTL_REDRAWPANEL, NULL);
g_StartupInfo.Control(this, FCTL_UPDATEANOTHERPANEL, NULL);
diff --git a/CPP/7zip/UI/Far/Plugin.h b/CPP/7zip/UI/Far/Plugin.h
index ab534e21..c4122c45 100755
--- a/CPP/7zip/UI/Far/Plugin.h
+++ b/CPP/7zip/UI/Far/Plugin.h
@@ -9,6 +9,8 @@
#include "Windows/FileFind.h"
#include "Windows/PropVariant.h"
+#include "../Common/WorkDir.h"
+
#include "../Agent/IFolderArchive.h"
#include "FarUtils.h"
@@ -36,9 +38,10 @@ class CPlugin
void EnterToDirectory(const UString &dirName);
void GetPathParts(UStringVector &pathParts);
void GetCurrentDir();
+ HRESULT AfterUpdate(CWorkDirTempFile &tempFile, const UStringVector &pathVector);
public:
- UString m_FileName;
- NWindows::NFile::NFind::CFileInfoW m_FileInfo;
+ FString m_FileName;
+ NWindows::NFile::NFind::CFileInfo m_FileInfo;
CMyComPtr<IInFolderArchive> m_ArchiveHandler;
CMyComPtr<IFolderFolder> _folder;
@@ -48,7 +51,7 @@ public:
bool PasswordIsDefined;
UString Password;
- CPlugin(const UString &fileName, IInFolderArchive *archiveHandler, UString archiveTypeName);
+ CPlugin(const FString &fileName, IInFolderArchive *archiveHandler, UString archiveTypeName);
~CPlugin();
void ReadPluginPanelItem(PluginPanelItem &panelItem, UInt32 itemIndex);
diff --git a/CPP/7zip/UI/Far/PluginDelete.cpp b/CPP/7zip/UI/Far/PluginDelete.cpp
index c8d784c3..3a3df300 100755
--- a/CPP/7zip/UI/Far/PluginDelete.cpp
+++ b/CPP/7zip/UI/Far/PluginDelete.cpp
@@ -2,20 +2,11 @@
#include "StdAfx.h"
-#include "Windows/FileDir.h"
-
-#include "../Common/WorkDir.h"
-
#include "Messages.h"
#include "Plugin.h"
#include "UpdateCallback100.h"
using namespace NFar;
-using namespace NWindows;
-using namespace NFile;
-using namespace NDirectory;
-
-static LPCWSTR kTempArchivePrefix = L"7zA";
int CPlugin::DeleteFiles(PluginPanelItem *panelItems, int numItems, int opMode)
{
@@ -67,18 +58,10 @@ int CPlugin::DeleteFiles(PluginPanelItem *panelItems, int numItems, int opMode)
g_StartupInfo.GetMsgString(NMessageID::kDeleting), 48);
}
- NWorkDir::CInfo workDirInfo;
- workDirInfo.Load();
-
- UString workDir = GetWorkDir(workDirInfo, m_FileName);
- CreateComplexDirectory(workDir);
-
- CTempFileW tempFile;
- UString tempFileName;
- if (tempFile.Create(workDir, kTempArchivePrefix, tempFileName) == 0)
+ CWorkDirTempFile tempFile;
+ if (tempFile.CreateTempFile(m_FileName) != S_OK)
return FALSE;
-
CRecordVector<UINT32> indices;
indices.Reserve(numItems);
int i;
@@ -101,61 +84,23 @@ int CPlugin::DeleteFiles(PluginPanelItem *panelItems, int numItems, int opMode)
outArchive->SetFolder(_folder);
CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp;
- CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec );
+ CMyComPtr<IFolderArchiveUpdateCallback> updateCallback(updateCallbackSpec);
updateCallbackSpec->Init(/* m_ArchiveHandler, */ progressBoxPointer);
-
- result = outArchive->DeleteItems(
- tempFileName,
- &indices.Front(), indices.Size(),
- updateCallback);
+ result = outArchive->DeleteItems(tempFile.OutStream, &indices.Front(), indices.Size(), updateCallback);
updateCallback.Release();
outArchive.Release();
- if (result != S_OK)
- {
- ShowErrorMessage(result);
- return FALSE;
- }
-
- _folder.Release();
- m_ArchiveHandler->Close();
-
- if (!DeleteFileAlways(m_FileName))
+ if (result == S_OK)
{
- ShowLastErrorMessage();
- return FALSE;
+ result = AfterUpdate(tempFile, pathVector);
}
-
- tempFile.DisableDeleting();
- if (!MyMoveFile(tempFileName, m_FileName))
- {
- ShowLastErrorMessage();
- return FALSE;
- }
-
- result = m_ArchiveHandler->ReOpen(NULL);
if (result != S_OK)
{
ShowErrorMessage(result);
return FALSE;
}
-
-
- ////////////////////////////
- // Restore _folder;
-
- m_ArchiveHandler->BindToRootFolder(&_folder);
- for (i = 0; i < pathVector.Size(); i++)
- {
- CMyComPtr<IFolderFolder> newFolder;
- _folder->BindToFolder(pathVector[i], &newFolder);
- if (!newFolder)
- break;
- _folder = newFolder;
- }
GetCurrentDir();
-
return TRUE;
}
diff --git a/CPP/7zip/UI/Far/PluginRead.cpp b/CPP/7zip/UI/Far/PluginRead.cpp
index 965030ea..a4450064 100755
--- a/CPP/7zip/UI/Far/PluginRead.cpp
+++ b/CPP/7zip/UI/Far/PluginRead.cpp
@@ -194,9 +194,11 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa
#ifdef UNDER_CE
destPathU = L"\\";
#else
- if (!NFile::NDirectory::MyGetCurrentDirectory(destPathU))
+ FString destPathF = us2fs(destPathU);
+ if (!NFile::NDirectory::MyGetCurrentDirectory(destPathF))
throw 318016;
- NFile::NName::NormalizeDirPathPrefix(destPathU);
+ NFile::NName::NormalizeDirPathPrefix(destPathF);
+ destPathU = fs2us(destPathF);
#endif
break;
}
@@ -251,7 +253,7 @@ NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *pa
passwordIsDefined = !password.IsEmpty();
}
- NFile::NDirectory::CreateComplexDirectory(destPathU);
+ NFile::NDirectory::CreateComplexDirectory(us2fs(destPathU));
/*
vector<int> realIndices;
diff --git a/CPP/7zip/UI/Far/PluginWrite.cpp b/CPP/7zip/UI/Far/PluginWrite.cpp
index be9616a4..e02f4d80 100755
--- a/CPP/7zip/UI/Far/PluginWrite.cpp
+++ b/CPP/7zip/UI/Far/PluginWrite.cpp
@@ -7,15 +7,10 @@
#include "Common/Wildcard.h"
#include "Common/StringConvert.h"
-#include "Windows/FileDir.h"
#include "Windows/FileName.h"
#include "Windows/FileFind.h"
-#include "Windows/Defs.h"
-#include "Windows/PropVariant.h"
#include "../Common/ZipRegistry.h"
-#include "../Common/WorkDir.h"
-#include "../Common/OpenArchive.h"
#include "../Agent/Agent.h"
@@ -30,13 +25,11 @@ using namespace NFar;
using namespace NUpdateArchive;
-static const char *kHelpTopic = "Update";
-
-static LPCWSTR kTempArcivePrefix = L"7zA";
+static const char *kHelpTopic = "Update";
static const char *kArchiveHistoryKeyName = "7-ZipArcName";
-static UINT32 g_MethodMap[] = { 0, 1, 3, 5, 7, 9 };
+static const UINT32 g_MethodMap[] = { 0, 1, 3, 5, 7, 9 };
static HRESULT SetOutProperties(IOutFolderArchive *outArchive, UINT32 method)
{
@@ -47,18 +40,39 @@ static HRESULT SetOutProperties(IOutFolderArchive *outArchive, UINT32 method)
realNames.Add(UString(L"x"));
NCOM::CPropVariant value = (UInt32)method;
CRecordVector<const wchar_t *> names;
- for(int i = 0; i < realNames.Size(); i++)
+ for (int i = 0; i < realNames.Size(); i++)
names.Add(realNames[i]);
RINOK(setProperties->SetProperties(&names.Front(), &value, names.Size()));
}
return S_OK;
}
+HRESULT CPlugin::AfterUpdate(CWorkDirTempFile &tempFile, const UStringVector &pathVector)
+{
+ _folder.Release();
+ m_ArchiveHandler->Close();
+
+ RINOK(tempFile.MoveToOriginal(true));
+
+ RINOK(m_ArchiveHandler->ReOpen(NULL)); // check it
+
+ m_ArchiveHandler->BindToRootFolder(&_folder);
+ for (int i = 0; i < pathVector.Size(); i++)
+ {
+ CMyComPtr<IFolderFolder> newFolder;
+ _folder->BindToFolder(pathVector[i], &newFolder);
+ if (!newFolder)
+ break;
+ _folder = newFolder;
+ }
+ return S_OK;
+}
+
NFileOperationReturnCode::EEnum CPlugin::PutFiles(
struct PluginPanelItem *panelItems, int numItems,
int moveMode, int opMode)
{
- if(moveMode != 0)
+ if (moveMode != 0)
{
g_StartupInfo.ShowMessage(NMessageID::kMoveIsNotSupported);
return NFileOperationReturnCode::kError;
@@ -153,20 +167,14 @@ NFileOperationReturnCode::EEnum CPlugin::PutFiles(
compressionInfo.Save();
- NWorkDir::CInfo workDirInfo;
- workDirInfo.Load();
- UString workDir = GetWorkDir(workDirInfo, m_FileName);
- CreateComplexDirectory(workDir);
-
- CTempFileW tempFile;
- UString tempFileName;
- if (tempFile.Create(workDir, kTempArcivePrefix, tempFileName) == 0)
+ CWorkDirTempFile tempFile;;
+ if (tempFile.CreateTempFile(m_FileName) != S_OK)
return NFileOperationReturnCode::kError;
/*
CSysStringVector fileNames;
- for(int i = 0; i < numItems; i++)
+ for (int i = 0; i < numItems; i++)
{
const PluginPanelItem &panelItem = panelItems[i];
CSysString fullName;
@@ -189,44 +197,28 @@ NFileOperationReturnCode::EEnum CPlugin::PutFiles(
g_StartupInfo.GetMsgString(NMessageID::kUpdating), 48);
}
- ////////////////////////////
- // Save FolderItem;
- UStringVector aPathVector;
- GetPathParts(aPathVector);
+ UStringVector pathVector;
+ GetPathParts(pathVector);
- /*
- UString anArchivePrefix;
- for(i = aPathVector.Size() - 1; i >= 0; i--)
- {
- anArchivePrefix += aPathVector[i];
- anArchivePrefix += wchar_t(NName::kDirDelimiter);
- }
- /////////////////////////////////
- */
-
UStringVector fileNames;
fileNames.Reserve(numItems);
- for(i = 0; i < numItems; i++)
+ for (i = 0; i < numItems; i++)
fileNames.Add(MultiByteToUnicodeString(panelItems[i].FindData.cFileName, CP_OEMCP));
CRecordVector<const wchar_t *> fileNamePointers;
fileNamePointers.Reserve(numItems);
- for(i = 0; i < numItems; i++)
+ for (i = 0; i < numItems; i++)
fileNamePointers.Add(fileNames[i]);
CMyComPtr<IOutFolderArchive> outArchive;
HRESULT result = m_ArchiveHandler.QueryInterface(IID_IOutFolderArchive, &outArchive);
- if(result != S_OK)
+ if (result != S_OK)
{
g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
return NFileOperationReturnCode::kError;
}
outArchive->SetFolder(_folder);
- // CSysString aCurrentFolder;
- // MyGetCurrentDirectory(aCurrentFolder);
- // outArchive->SetFiles(MultiByteToUnicodeString(aCurrentFolder, CP_OEMCP),
- outArchive->SetFiles(L"",
- &fileNamePointers.Front(), fileNamePointers.Size());
+ outArchive->SetFiles(L"", &fileNamePointers.Front(), fileNamePointers.Size());
BYTE actionSetByte[NUpdateArchive::NPairState::kNumValues];
for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
actionSetByte[i] = (BYTE)actionSet->StateActions[i];
@@ -239,42 +231,14 @@ NFileOperationReturnCode::EEnum CPlugin::PutFiles(
if (SetOutProperties(outArchive, compressionInfo.Level) != S_OK)
return NFileOperationReturnCode::kError;
- result = outArchive->DoOperation2(tempFileName, actionSetByte, NULL, updateCallback);
+ result = outArchive->DoOperation2(tempFile.OutStream, actionSetByte, NULL, updateCallback);
updateCallback.Release();
outArchive.Release();
- /*
- HRESULT result = Compress(fileNames, anArchivePrefix, *actionSet,
- m_ProxyHandler.get(),
- m_ArchiverInfo.ClassID, compressionInfo.Method == 0,
- compressionInfo.Method == 2, tempFileName, progressBoxPointer);
- */
-
- if (result != S_OK)
+ if (result == S_OK)
{
- ShowErrorMessage(result);
- return NFileOperationReturnCode::kError;
+ result = AfterUpdate(tempFile, pathVector);
}
-
- _folder.Release();
- m_ArchiveHandler->Close();
-
- // m_FolderItem = NULL;
-
- if (!DeleteFileAlways(m_FileName))
- {
- ShowLastErrorMessage();
- return NFileOperationReturnCode::kError;
- }
-
- tempFile.DisableDeleting();
- if (!MyMoveFile(tempFileName, m_FileName))
- {
- ShowLastErrorMessage();
- return NFileOperationReturnCode::kError;
- }
-
- m_ArchiveHandler->ReOpen(NULL);
if (result != S_OK)
{
ShowErrorMessage(result);
@@ -282,37 +246,17 @@ NFileOperationReturnCode::EEnum CPlugin::PutFiles(
}
/*
- if(m_ProxyHandler->ReInit(NULL) != S_OK)
- return NFileOperationReturnCode::kError;
- */
-
- ////////////////////////////
- // Restore FolderItem;
-
- m_ArchiveHandler->BindToRootFolder(&_folder);
- for (i = 0; i < aPathVector.Size(); i++)
+ if (moveMode != 0)
{
- CMyComPtr<IFolderFolder> newFolder;
- _folder->BindToFolder(aPathVector[i], &newFolder);
- if(!newFolder )
- break;
- _folder = newFolder;
- }
-
- /*
- if(moveMode != 0)
- {
- for(int i = 0; i < numItems; i++)
+ for (int i = 0; i < numItems; i++)
{
- const PluginPanelItem &aPluginPanelItem = panelItems[i];
+ const PluginPanelItem &pluginPanelItem = panelItems[i];
bool result;
- if(NFile::NFind::NAttributes::IsDir(aPluginPanelItem.FindData.dwFileAttributes))
- result = NFile::NDirectory::RemoveDirectoryWithSubItems(
- aPluginPanelItem.FindData.cFileName);
+ if (NFile::NFind::NAttributes::IsDir(pluginPanelItem.FindData.dwFileAttributes))
+ result = NFile::NDirectory::RemoveDirectoryWithSubItems(pluginPanelItem.FindData.cFileName);
else
- result = NFile::NDirectory::DeleteFileAlways(
- aPluginPanelItem.FindData.cFileName);
- if(!result)
+ result = NFile::NDirectory::DeleteFileAlways(pluginPanelItem.FindData.cFileName);
+ if (!result)
return NFileOperationReturnCode::kError;
}
}
@@ -361,11 +305,11 @@ void CParsedPath::ParsePath(const UString &path)
case NPathType::kLocal:
{
int posDiskDelimiter = path.Find(kDiskDelimiter);
- if(posDiskDelimiter >= 0)
+ if (posDiskDelimiter >= 0)
{
curPos = posDiskDelimiter + 1;
if (path.Length() > curPos)
- if(path[curPos] == kDirDelimiter)
+ if (path[curPos] == kDirDelimiter)
curPos++;
}
break;
@@ -373,7 +317,7 @@ void CParsedPath::ParsePath(const UString &path)
case NPathType::kUNC:
{
int curPos = path.Find(kDirDelimiter, 2);
- if(curPos < 0)
+ if (curPos < 0)
curPos = path.Length();
else
curPos++;
@@ -386,7 +330,7 @@ void CParsedPath::ParsePath(const UString &path)
UString CParsedPath::MergePath() const
{
UString result = Prefix;
- for(int i = 0; i < PathParts.Size(); i++)
+ for (int i = 0; i < PathParts.Size(); i++)
{
if (i != 0)
result += kDirDelimiter;
@@ -409,20 +353,20 @@ HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
UStringVector fileNames;
int i;
- for(i = 0; i < pluginPanelItems.Size(); i++)
+ for (i = 0; i < pluginPanelItems.Size(); i++)
{
const PluginPanelItem &panelItem = pluginPanelItems[i];
- UString fullName;
if (strcmp(panelItem.FindData.cFileName, "..") == 0 &&
NFind::NAttributes::IsDir(panelItem.FindData.dwFileAttributes))
return E_FAIL;
if (strcmp(panelItem.FindData.cFileName, ".") == 0 &&
NFind::NAttributes::IsDir(panelItem.FindData.dwFileAttributes))
return E_FAIL;
- UString fileNameUnicode = MultiByteToUnicodeString(panelItem.FindData.cFileName, CP_OEMCP);
- if (!MyGetFullPathName(fileNameUnicode, fullName))
+ FString fullPath;
+ FString fileNameUnicode = us2fs(MultiByteToUnicodeString(panelItem.FindData.cFileName, CP_OEMCP));
+ if (!MyGetFullPathName(fileNameUnicode, fullPath))
return E_FAIL;
- fileNames.Add(fullName);
+ fileNames.Add(fs2us(fullPath));
}
NCompression::CInfo compressionInfo;
@@ -453,7 +397,7 @@ HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
{
CParsedPath parsedPath;
parsedPath.ParsePath(fileNames.Front());
- if(parsedPath.PathParts.Size() == 0)
+ if (parsedPath.PathParts.Size() == 0)
return E_FAIL;
if (fileNames.Size() == 1 || parsedPath.PathParts.Size() == 1)
{
@@ -589,7 +533,7 @@ HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
{
CIntVector indices;
CSysStringVector archiverNames;
- for(int i = 0; i < codecs->Formats.Size(); i++)
+ for (int i = 0; i < codecs->Formats.Size(); i++)
{
const CArcInfoEx &arc = codecs->Formats[i];
if (arc.UpdateEnabled)
@@ -602,7 +546,7 @@ HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
int index = g_StartupInfo.Menu(FMENU_AUTOHIGHLIGHT,
g_StartupInfo.GetMsgString(NMessageID::kUpdateSelectArchiverMenuTitle),
NULL, archiverNames, archiverIndex);
- if(index >= 0)
+ if (index >= 0)
{
const CArcInfoEx &prevArchiverInfo = codecs->Formats[prevFormat];
if (prevArchiverInfo.KeepName)
@@ -653,18 +597,12 @@ HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
NWorkDir::CInfo workDirInfo;
workDirInfo.Load();
- UString fullArchiveName;
- if (!MyGetFullPathName(archiveName, fullArchiveName))
+ FString fullArchiveName;
+ if (!MyGetFullPathName(us2fs(archiveName), fullArchiveName))
return E_FAIL;
- UString workDir = GetWorkDir(workDirInfo, fullArchiveName);
- CreateComplexDirectory(workDir);
-
- CTempFileW tempFile;
- UString tempFileName;
- if (tempFile.Create(workDir, kTempArcivePrefix, tempFileName) == 0)
- return E_FAIL;
-
+ CWorkDirTempFile tempFile;
+ RINOK(tempFile.CreateTempFile(fullArchiveName));
CScreenRestorer screenRestorer;
CProgressBox progressBox;
@@ -678,12 +616,12 @@ HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
g_StartupInfo.GetMsgString(NMessageID::kUpdating), 48);
- NFind::CFileInfoW fileInfo;
+ NFind::CFileInfo fileInfo;
CMyComPtr<IOutFolderArchive> outArchive;
CMyComPtr<IInFolderArchive> archiveHandler;
- if(fileInfo.Find(fullArchiveName))
+ if (fileInfo.Find(fullArchiveName))
{
if (fileInfo.IsDir())
throw "There is Directory with such name";
@@ -702,7 +640,7 @@ HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
throw "Type of existing archive differs from specified type";
HRESULT result = archiveHandler.QueryInterface(
IID_IOutFolderArchive, &outArchive);
- if(result != S_OK)
+ if (result != S_OK)
{
g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive);
return E_FAIL;
@@ -726,15 +664,11 @@ HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
CRecordVector<const wchar_t *> fileNamePointers;
fileNamePointers.Reserve(fileNames.Size());
- for(i = 0; i < fileNames.Size(); i++)
+ for (i = 0; i < fileNames.Size(); i++)
fileNamePointers.Add(fileNames[i]);
outArchive->SetFolder(NULL);
- // CSysString aCurrentFolder;
- // MyGetCurrentDirectory(aCurrentFolder);
- // outArchive->SetFiles(MultiByteToUnicodeString(aCurrentFolder, CP_OEMCP),
- outArchive->SetFiles(L"",
- &fileNamePointers.Front(), fileNamePointers.Size());
+ outArchive->SetFiles(L"", &fileNamePointers.Front(), fileNamePointers.Size());
BYTE actionSetByte[NUpdateArchive::NPairState::kNumValues];
for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++)
actionSetByte[i] = (BYTE)actionSet->StateActions[i];
@@ -749,7 +683,7 @@ HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
HRESULT result = outArchive->DoOperation(
codecs, archiverIndex,
- tempFileName, actionSetByte,
+ tempFile.OutStream, actionSetByte,
NULL, updateCallback);
updateCallback.Release();
outArchive.Release();
@@ -760,21 +694,14 @@ HRESULT CompressFiles(const CObjectVector<PluginPanelItem> &pluginPanelItems)
return result;
}
- if(archiveHandler)
+ if (archiveHandler)
{
archiveHandler->Close();
- if (!DeleteFileAlways(fullArchiveName))
- {
- ShowLastErrorMessage();
- return NFileOperationReturnCode::kError;
- }
}
- tempFile.DisableDeleting();
- if (!MyMoveFile(tempFileName, fullArchiveName))
+ if (!tempFile.MoveToOriginal(archiveHandler != NULL))
{
ShowLastErrorMessage();
return E_FAIL;
}
-
return S_OK;
}
diff --git a/CPP/7zip/UI/FileManager/App.cpp b/CPP/7zip/UI/FileManager/App.cpp
index c195a79d..5f31f607 100755
--- a/CPP/7zip/UI/FileManager/App.cpp
+++ b/CPP/7zip/UI/FileManager/App.cpp
@@ -11,6 +11,8 @@
#include "Windows/COM.h"
#include "Windows/Error.h"
#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
+
#include "Windows/PropVariant.h"
#include "Windows/PropVariantConversions.h"
#include "Windows/Thread.h"
@@ -31,7 +33,7 @@ using namespace NFind;
extern DWORD g_ComCtl32Version;
extern HINSTANCE g_hInstance;
-static LPCWSTR kTempDirPrefix = L"7zE";
+static CFSTR kTempDirPrefix = FTEXT("7zE");
void CPanelCallbackImp::OnTab()
{
@@ -374,7 +376,7 @@ static void ReducePathToRealFileSystemPath(UString &path)
{
while (!path.IsEmpty())
{
- if (NFind::DoesDirExist(path))
+ if (NFind::DoesDirExist(us2fs(path)))
{
NName::NormalizeDirPathPrefix(path);
break;
@@ -510,6 +512,8 @@ UString CPanel::GetItemsInfoString(const CRecordVector<UInt32> &indices)
return info;
}
+bool IsCorrectFsName(const UString name);
+
void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
{
int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
@@ -599,10 +603,10 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
if (indices.Size() > 1 ||
(!destPath.IsEmpty() && destPath.Back() == WCHAR_PATH_SEPARATOR) ||
- NFind::DoesDirExist(destPath) ||
+ NFind::DoesDirExist(us2fs(destPath)) ||
srcPanel.IsArcFolder())
{
- NDirectory::CreateComplexDirectory(destPath);
+ NDirectory::CreateComplexDirectory(us2fs(destPath));
NName::NormalizeDirPathPrefix(destPath);
if (!CheckFolderPath(destPath))
{
@@ -616,11 +620,16 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
}
else
{
+ if (!IsCorrectFsName(destPath))
+ {
+ srcPanel.MessageBoxError(E_INVALIDARG);
+ return;
+ }
int pos = destPath.ReverseFind(WCHAR_PATH_SEPARATOR);
if (pos >= 0)
{
UString prefix = destPath.Left(pos + 1);
- NDirectory::CreateComplexDirectory(prefix);
+ NDirectory::CreateComplexDirectory(us2fs(prefix));
if (!CheckFolderPath(prefix))
{
srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208);
@@ -645,8 +654,8 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
bool useSrcPanel = (!useDestPanel || !srcPanel.IsFsOrDrivesFolder() || destPanel.IsFSFolder());
bool useTemp = useSrcPanel && useDestPanel;
- NFile::NDirectory::CTempDirectoryW tempDirectory;
- UString tempDirPrefix;
+ NFile::NDirectory::CTempDir tempDirectory;
+ FString tempDirPrefix;
if (useTemp)
{
tempDirectory.Create(kTempDirPrefix);
@@ -662,7 +671,7 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
HRESULT result;
if (useSrcPanel)
{
- UString folder = useTemp ? tempDirPrefix : destPath;
+ UString folder = useTemp ? fs2us(tempDirPrefix) : destPath;
result = srcPanel.CopyTo(indices, folder, move, true, 0);
if (result != S_OK)
{
@@ -681,7 +690,7 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
UStringVector filePaths;
UString folderPrefix;
if (useTemp)
- folderPrefix = tempDirPrefix;
+ folderPrefix = fs2us(tempDirPrefix);
else
folderPrefix = srcPanel._currentFolderPrefix;
filePaths.Reserve(indices.Size());
diff --git a/CPP/7zip/UI/FileManager/App.h b/CPP/7zip/UI/FileManager/App.h
index a057c34e..2af63b47 100755
--- a/CPP/7zip/UI/FileManager/App.h
+++ b/CPP/7zip/UI/FileManager/App.h
@@ -202,7 +202,7 @@ public:
void SelectSpec(bool selectMode) { GetFocusedPanel().SelectSpec(selectMode); }
void SelectByType(bool selectMode) { GetFocusedPanel().SelectByType(selectMode); }
- void RefreshStatusBar() { GetFocusedPanel().RefreshStatusBar(); }
+ void Refresh_StatusBar() { GetFocusedPanel().Refresh_StatusBar(); }
void SetListViewMode(UInt32 index) { GetFocusedPanel().SetListViewMode(index); }
UInt32 GetListViewMode() { return GetFocusedPanel().GetListViewMode(); }
diff --git a/CPP/7zip/UI/FileManager/BrowseDialog.cpp b/CPP/7zip/UI/FileManager/BrowseDialog.cpp
index 602b12f3..1c350064 100755
--- a/CPP/7zip/UI/FileManager/BrowseDialog.cpp
+++ b/CPP/7zip/UI/FileManager/BrowseDialog.cpp
@@ -2,13 +2,14 @@
#include "StdAfx.h"
-#ifdef UNDER_CE
+#include "BrowseDialog.h"
+
+#ifdef USE_MY_BROWSE_DIALOG
#include "Common/IntToString.h"
#include "Windows/PropVariantConversions.h"
-#include "BrowseDialog.h"
#include "LangUtils.h"
#include "PropertyNameRes.h"
@@ -60,7 +61,7 @@ bool CBrowseDialog::OnInit()
_list.Attach(GetItem(IDC_BROWSE_LIST));
#ifndef UNDER_CE
- _list.SetUnicodeFormat(true);
+ _list.SetUnicodeFormat();
#endif
#ifndef _SFX
@@ -191,8 +192,8 @@ int CBrowseDialog::CompareItems(LPARAM lParam1, LPARAM lParam2)
{
if (lParam1 == kParentIndex) return -1;
if (lParam2 == kParentIndex) return 1;
- const CFileInfoW &f1 = _files[(int)lParam1];
- const CFileInfoW &f2 = _files[(int)lParam2];
+ const CFileInfo &f1 = _files[(int)lParam1];
+ const CFileInfo &f2 = _files[(int)lParam2];
bool isDir1 = f1.IsDir();
bool isDir2 = f2.IsDir();
@@ -225,12 +226,12 @@ static HRESULT GetNormalizedError()
HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selectedName)
{
- CEnumeratorW enumerator(pathPrefix + L'*');
- CObjectVector<CFileInfoW> files;
+ CEnumerator enumerator(us2fs(pathPrefix + L'*'));
+ CObjectVector<CFileInfo> files;
for (;;)
{
bool found;
- CFileInfoW fi;
+ CFileInfo fi;
if (!enumerator.Next(fi, found))
return GetNormalizedError();
if (!found)
@@ -278,16 +279,17 @@ HRESULT CBrowseDialog::Reload(const UString &pathPrefix, const UString &selected
for (int i = 0; i < _files.Size(); i++)
{
- const CFileInfoW &fi = _files[i];
+ const CFileInfo &fi = _files[i];
item.iItem = index;
- if (fi.Name.CompareNoCase(selectedName) == 0)
+ const UString name = fs2us(fi.Name);
+ if (name.CompareNoCase(selectedName) == 0)
cursorIndex = item.iItem;
item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
int subItem = 0;
item.iSubItem = subItem++;
item.lParam = i;
- item.pszText = (wchar_t *)(const wchar_t *)fi.Name;
- item.iImage = _extToIconMap.GetIconIndex(fi.Attrib, Path + fi.Name);
+ item.pszText = (wchar_t *)(const wchar_t *)name;
+ item.iImage = _extToIconMap.GetIconIndex(fi.Attrib, Path + name);
if (item.iImage < 0)
item.iImage = 0;
_list.InsertItem(&item);
@@ -325,7 +327,7 @@ HRESULT CBrowseDialog::Reload()
{
int fileIndex = GetRealItemIndex(index);
if (fileIndex != kParentIndex)
- selectedCur = _files[fileIndex].Name;
+ selectedCur = fs2us(_files[fileIndex].Name);
}
return Reload(Path, selectedCur);
}
@@ -443,13 +445,13 @@ void CBrowseDialog::FinishOnOK()
OpenParentFolder();
return;
}
- const CFileInfoW &file = _files[fileIndex];
+ const CFileInfo &file = _files[fileIndex];
if (file.IsDir() != FolderMode)
{
ShowSelectError();
return;
}
- Path += file.Name;
+ Path += fs2us(file.Name);
}
End(IDOK);
}
@@ -464,7 +466,7 @@ void CBrowseDialog::OnItemEnter()
OpenParentFolder();
else
{
- const CFileInfoW &file = _files[fileIndex];
+ const CFileInfo &file = _files[fileIndex];
if (!file.IsDir())
{
if (!FolderMode)
@@ -473,7 +475,7 @@ void CBrowseDialog::OnItemEnter()
ShowSelectError();
return;
}
- HRESULT res = Reload(Path + file.Name + WCHAR_PATH_SEPARATOR, L"");
+ HRESULT res = Reload(Path + fs2us(file.Name) + WCHAR_PATH_SEPARATOR, L"");
if (res != S_OK)
ShowError(HResultToMessage(res));
}
@@ -481,6 +483,8 @@ void CBrowseDialog::OnItemEnter()
void CBrowseDialog::OnOK()
{
+ // When we press "Enter" in listview, windows sends message to first Button.
+ // We check that message was from listview;
if (GetFocus() == _list)
{
OnItemEnter();
diff --git a/CPP/7zip/UI/FileManager/BrowseDialog.h b/CPP/7zip/UI/FileManager/BrowseDialog.h
index 41eb6b50..f597d1c3 100755
--- a/CPP/7zip/UI/FileManager/BrowseDialog.h
+++ b/CPP/7zip/UI/FileManager/BrowseDialog.h
@@ -4,6 +4,10 @@
#define __BROWSE_DIALOG_H
#ifdef UNDER_CE
+#define USE_MY_BROWSE_DIALOG
+#endif
+
+#ifdef USE_MY_BROWSE_DIALOG
#include "Windows/FileFind.h"
@@ -16,7 +20,7 @@
class CBrowseDialog: public NWindows::NControl::CModalDialog
{
NWindows::NControl::CListView _list;
- CObjectVector<NWindows::NFile::NFind::CFileInfoW> _files;
+ CObjectVector<NWindows::NFile::NFind::CFileInfo> _files;
CExtToIconMap _extToIconMap;
int _sortIndex;
bool _ascending;
diff --git a/CPP/7zip/UI/FileManager/ExtractCallback.cpp b/CPP/7zip/UI/FileManager/ExtractCallback.cpp
index d27db23f..90076ebb 100755
--- a/CPP/7zip/UI/FileManager/ExtractCallback.cpp
+++ b/CPP/7zip/UI/FileManager/ExtractCallback.cpp
@@ -2,12 +2,18 @@
#include "StdAfx.h"
+#include "Common/StringConvert.h"
+
#include "Windows/Error.h"
#include "Windows/FileDir.h"
#include "Windows/FileFind.h"
#include "../../Common/FilePathAutoRename.h"
+#ifndef _SFX
+#include "../Common/ZipRegistry.h"
+#endif
+
#include "../GUI/ExtractRes.h"
#include "ExtractCallback.h"
@@ -177,6 +183,11 @@ STDMETHODIMP CExtractCallbackImp::MessageError(const wchar_t *message)
return S_OK;
}
+HRESULT CExtractCallbackImp::MessageError(const char *message, const FString &path)
+{
+ return MessageError(GetUnicodeString(message) + fs2us(path));
+}
+
STDMETHODIMP CExtractCallbackImp::ShowMessage(const wchar_t *message)
{
AddErrorMessage(message);
@@ -296,7 +307,7 @@ HRESULT CExtractCallbackImp::OpenResult(const wchar_t *name, HRESULT result, boo
MyLoadStringW(IDS_MEM_ERROR);
#endif
else
- NError::MyFormatMessage(result, message2);
+ message2 = NError::MyFormatMessageW(result);
message += message2;
}
MessageError(message);
@@ -339,11 +350,19 @@ STDMETHODIMP CExtractCallbackImp::CryptoGetTextPassword(BSTR *password)
if (!PasswordIsDefined)
{
CPasswordDialog dialog;
+ #ifndef _SFX
+ bool showPassword = NExtract::Read_ShowPassword();
+ dialog.ShowPassword = showPassword;
+ #endif
ProgressDialog->WaitCreating();
if (dialog.Create(*ProgressDialog) == IDCANCEL)
return E_ABORT;
Password = dialog.Password;
PasswordIsDefined = true;
+ #ifndef _SFX
+ if (dialog.ShowPassword != showPassword)
+ NExtract::Save_ShowPassword(dialog.ShowPassword);
+ #endif
}
return StringToBstr(Password, password);
}
@@ -366,19 +385,16 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
*writeAnswer = BoolToInt(false);
UString destPathSpec = destPath;
- UString destPathSys = destPathSpec;
+ FString destPathSys = us2fs(destPath);
bool srcIsFolderSpec = IntToBool(srcIsFolder);
- CFileInfoW destFileInfo;
+ CFileInfo destFileInfo;
if (destFileInfo.Find(destPathSys))
{
if (srcIsFolderSpec)
{
if (!destFileInfo.IsDir())
{
- UString message = UString(L"can not replace file \'")
- + destPathSpec +
- UString(L"\' with folder with same name");
- RINOK(MessageError(message));
+ RINOK(MessageError("can not replace file with folder with same name: ", destPathSys));
return E_ABORT;
}
*writeAnswer = BoolToInt(false);
@@ -386,10 +402,7 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
}
if (destFileInfo.IsDir())
{
- UString message = UString(L"can not replace folder \'")
- + destPathSpec +
- UString(L"\' with file with same name");
- RINOK(MessageError(message));
+ RINOK(MessageError("can not replace folder with file with same name: ", destPathSys));
return E_FAIL;
}
@@ -432,19 +445,15 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
{
if (!AutoRenamePath(destPathSys))
{
- UString message = UString(L"can not create name of file ")
- + destPathSys;
- RINOK(MessageError(message));
+ RINOK(MessageError("can not create name for file: ", destPathSys));
return E_ABORT;
}
- destPathResultTemp = destPathSys;
+ destPathResultTemp = fs2us(destPathSys);
}
else
if (!NFile::NDirectory::DeleteFileAlways(destPathSys))
{
- UString message = UString(L"can not delete output file ")
- + destPathSys;
- RINOK(MessageError(message));
+ RINOK(MessageError("can not delete output file: ", destPathSys));
return E_ABORT;
}
}
diff --git a/CPP/7zip/UI/FileManager/ExtractCallback.h b/CPP/7zip/UI/FileManager/ExtractCallback.h
index b4e88fd5..19c29e77 100755
--- a/CPP/7zip/UI/FileManager/ExtractCallback.h
+++ b/CPP/7zip/UI/FileManager/ExtractCallback.h
@@ -35,6 +35,7 @@ class CExtractCallbackImp:
#endif
public CMyUnknownImp
{
+ HRESULT MessageError(const char *message, const FString &path);
public:
MY_QUERYINTERFACE_BEGIN2(IFolderOperationsExtractCallback)
MY_QUERYINTERFACE_ENTRY(IFolderArchiveExtractCallback)
diff --git a/CPP/7zip/UI/FileManager/FM.cpp b/CPP/7zip/UI/FileManager/FM.cpp
index f3b48704..147a1fb7 100755
--- a/CPP/7zip/UI/FileManager/FM.cpp
+++ b/CPP/7zip/UI/FileManager/FM.cpp
@@ -33,7 +33,9 @@ using namespace NFind;
#define MENU_HEIGHT 26
+#ifdef _WIN32
HINSTANCE g_hInstance;
+#endif
HWND g_HWND;
bool g_OpenArchive = false;
static UString g_MainPath;
@@ -114,7 +116,7 @@ public:
};
static bool g_CanChangeSplitter = false;
-static UINT32 g_SplitterPos = 0;
+static UInt32 g_SplitterPos = 0;
static CSplitterPos g_Splitter;
static bool g_PanelsInfoDefined = false;
@@ -208,7 +210,7 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
ySize = rect.bottom - rect.top;
}
- UINT32 numPanels, currentPanel;
+ UInt32 numPanels, currentPanel;
g_PanelsInfoDefined = ReadPanelsInfo(numPanels, currentPanel, g_SplitterPos);
if (g_PanelsInfoDefined)
{
@@ -409,6 +411,30 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
{
#ifdef _WIN32
+ /*
+ #ifndef _WIN64
+ #ifndef UNDER_CE
+ {
+ HMODULE hMod = GetModuleHandle("Kernel32.dll");
+ if (hMod)
+ {
+ typedef BOOL (WINAPI *PSETDEP)(DWORD);
+ #define MY_PROCESS_DEP_ENABLE 1
+ PSETDEP procSet = (PSETDEP)GetProcAddress(hMod,"SetProcessDEPPolicy");
+ if (procSet)
+ procSet(MY_PROCESS_DEP_ENABLE);
+
+ typedef BOOL (WINAPI *HSI)(HANDLE, HEAP_INFORMATION_CLASS ,PVOID, SIZE_T);
+ HSI hsi = (HSI)GetProcAddress(hMod, "HeapSetInformation");
+ #define MY_HeapEnableTerminationOnCorruption ((HEAP_INFORMATION_CLASS)1)
+ if (hsi)
+ hsi(NULL, MY_HeapEnableTerminationOnCorruption, NULL, 0);
+ }
+ }
+ #endif
+ #endif
+ */
+
NT_CHECK
SetLargePageSize();
@@ -639,7 +665,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
bool needOpenFile = false;
if (!g_MainPath.IsEmpty() /* && g_OpenArchive */)
{
- if (NFile::NFind::DoesFileExist(g_MainPath))
+ if (NFile::NFind::DoesFileExist(us2fs(g_MainPath)))
needOpenFile = true;
}
HRESULT res = g_App.Create(hWnd, g_MainPath, g_ArcFormat, xSizes, archiveIsOpened, encrypted);
@@ -665,8 +691,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
if (res == E_OUTOFMEMORY)
message = LangString(IDS_MEM_ERROR, 0x0200060B);
else
- if (!NError::MyFormatMessage(res, message))
- message = L"Error";
+ message = NError::MyFormatMessageW(res);
}
}
MessageBoxW(0, message, L"7-zip", MB_ICONERROR);
diff --git a/CPP/7zip/UI/FileManager/FSDrives.cpp b/CPP/7zip/UI/FileManager/FSDrives.cpp
index 87ee3fc9..823b0826 100755
--- a/CPP/7zip/UI/FileManager/FSDrives.cpp
+++ b/CPP/7zip/UI/FileManager/FSDrives.cpp
@@ -26,9 +26,9 @@ using namespace NWindows;
using namespace NFile;
using namespace NFind;
-static const wchar_t *kVolPrefix = L"\\\\.\\";
+static CFSTR kVolPrefix = FTEXT("\\\\.\\");
-UString CDriveInfo::GetDeviceFileIoName() const
+FString CDriveInfo::GetDeviceFileIoName() const
{
return kVolPrefix + Name;
}
@@ -40,7 +40,7 @@ struct CPhysTempBuffer
~CPhysTempBuffer() { MidFree(buffer); }
};
-static HRESULT CopyFileSpec(LPCWSTR fromPath, LPCWSTR toPath, bool writeToDisk, UInt64 fileSize,
+static HRESULT CopyFileSpec(CFSTR fromPath, CFSTR toPath, bool writeToDisk, UInt64 fileSize,
UInt32 bufferSize, UInt64 progressStart, IProgress *progress)
{
NFile::NIO::CInFile inFile;
@@ -120,17 +120,17 @@ STDMETHODIMP CFSDrives::LoadItems()
{
_drives.Clear();
- UStringVector driveStrings;
+ FStringVector driveStrings;
MyGetLogicalDriveStrings(driveStrings);
for (int i = 0; i < driveStrings.Size(); i++)
{
CDriveInfo di;
- const UString &driveName = driveStrings[i];
+ const FString &driveName = driveStrings[i];
di.FullSystemName = driveName;
-
- di.Name = di.FullSystemName.Left(di.FullSystemName.Length() - 1);
+ if (!driveName.IsEmpty())
+ di.Name = driveName.Left(driveName.Length() - 1);
di.ClusterSize = 0;
di.DriveSize = 0;
di.FreeSpace = 0;
@@ -150,14 +150,11 @@ STDMETHODIMP CFSDrives::LoadItems()
}
if (needRead)
{
- UString volumeName, fileSystemName;
DWORD volumeSerialNumber, maximumComponentLength, fileSystemFlags;
NFile::NSystem::MyGetVolumeInformation(driveName,
- volumeName,
+ di.VolumeName,
&volumeSerialNumber, &maximumComponentLength, &fileSystemFlags,
- fileSystemName);
- di.VolumeName = volumeName;
- di.FileSystemName = fileSystemName;
+ di.FileSystemName);
NFile::NSystem::MyGetDiskFreeSpace(driveName,
di.ClusterSize, di.DriveSize, di.FreeSpace);
@@ -198,7 +195,7 @@ STDMETHODIMP CFSDrives::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT
return S_OK;
}
-HRESULT CFSDrives::BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder)
+HRESULT CFSDrives::BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder)
{
*resultFolder = 0;
if (_volumeMode)
@@ -232,7 +229,7 @@ STDMETHODIMP CFSDrives::BindToFolder(UInt32 index, IFolderFolder **resultFolder)
STDMETHODIMP CFSDrives::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder)
{
- return BindToFolderSpec(name, resultFolder);
+ return BindToFolderSpec(us2fs(name), resultFolder);
}
STDMETHODIMP CFSDrives::BindToParentFolder(IFolderFolder **resultFolder)
@@ -252,7 +249,7 @@ STDMETHODIMP CFSDrives::GetFolderProperty(PROPID propID, PROPVARIANT *value)
case kpidType: prop = L"FSDrives"; break;
case kpidPath:
if (_volumeMode)
- prop = kVolPrefix;
+ prop = fs2us(kVolPrefix);
else
prop = LangString(IDS_COMPUTER, 0x03020300) + UString(WCHAR_PATH_SEPARATOR);
break;
@@ -325,7 +322,7 @@ STDMETHODIMP CFSDrives::CopyTo(const UInt32 *indices, UInt32 numItems,
UString destPath = path;
if (destPath.IsEmpty())
return E_INVALIDARG;
- bool directName = (destPath[destPath.Length() - 1] != WCHAR_PATH_SEPARATOR);
+ bool directName = (destPath.Back() != WCHAR_PATH_SEPARATOR);
if (directName)
{
if (numItems > 1)
@@ -339,18 +336,18 @@ STDMETHODIMP CFSDrives::CopyTo(const UInt32 *indices, UInt32 numItems,
int index = indices[i];
const CDriveInfo &di = _drives[index];
UString destPath2 = destPath;
- UString name = di.Name;
+ UString name = fs2us(di.Name);
if (!directName)
{
UString destName = name;
- if (!destName.IsEmpty() && destName[destName.Length() - 1] == L':')
+ if (!destName.IsEmpty() && destName.Back() == L':')
{
- destName.Delete(destName.Length() - 1);
+ destName.DeleteBack();
destName += GetExt(index);
}
destPath2 += destName;
}
- UString srcPath = di.GetDeviceFileIoName();
+ FString srcPath = di.GetDeviceFileIoName();
UInt64 fileSize = 0;
if (GetLength(index, fileSize) != S_OK)
@@ -363,16 +360,16 @@ STDMETHODIMP CFSDrives::CopyTo(const UInt32 *indices, UInt32 numItems,
Int32 writeAskResult;
CMyComBSTR destPathResult;
- RINOK(callback->AskWrite(srcPath, BoolToInt(false), NULL, &fileSize,
+ RINOK(callback->AskWrite(fs2us(srcPath), BoolToInt(false), NULL, &fileSize,
destPath2, &destPathResult, &writeAskResult));
if (!IntToBool(writeAskResult))
continue;
- RINOK(callback->SetCurrentFilePath(srcPath));
+ RINOK(callback->SetCurrentFilePath(fs2us(srcPath)));
static const UInt32 kBufferSize = (4 << 20);
UInt32 bufferSize = (di.DriveType == DRIVE_REMOVABLE) ? (18 << 10) * 4 : kBufferSize;
- RINOK(CopyFileSpec(srcPath, destPathResult, false, fileSize, bufferSize, completedSize, callback));
+ RINOK(CopyFileSpec(srcPath, us2fs(destPathResult), false, fileSize, bufferSize, completedSize, callback));
completedSize += fileSize;
}
return S_OK;
@@ -393,6 +390,11 @@ STDMETHODIMP CFSDrives::CopyFrom(const wchar_t * /* fromFolderPath */,
return E_NOTIMPL;
}
+STDMETHODIMP CFSDrives::CopyFromFile(UInt32 /* index */, const wchar_t * /* fullFilePath */, IProgress * /* progress */)
+{
+ return E_NOTIMPL;
+}
+
STDMETHODIMP CFSDrives::CreateFolder(const wchar_t * /* name */, IProgress * /* progress */)
{
return E_NOTIMPL;
diff --git a/CPP/7zip/UI/FileManager/FSDrives.h b/CPP/7zip/UI/FileManager/FSDrives.h
index fc99bce7..a0cfd9be 100755
--- a/CPP/7zip/UI/FileManager/FSDrives.h
+++ b/CPP/7zip/UI/FileManager/FSDrives.h
@@ -10,8 +10,8 @@
struct CDriveInfo
{
- UString Name;
- UString FullSystemName;
+ FString Name;
+ FString FullSystemName;
bool KnownSizes;
UInt64 DriveSize;
UInt64 FreeSpace;
@@ -21,7 +21,7 @@ struct CDriveInfo
UString FileSystemName;
UINT DriveType;
- UString GetDeviceFileIoName() const;
+ FString GetDeviceFileIoName() const;
};
class CFSDrives:
@@ -33,7 +33,7 @@ class CFSDrives:
CObjectVector<CDriveInfo> _drives;
bool _volumeMode;
- HRESULT BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder);
+ HRESULT BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder);
UString GetExt(int index) const;
HRESULT GetLength(int index, UInt64 &length) const;
public:
diff --git a/CPP/7zip/UI/FileManager/FSFolder.cpp b/CPP/7zip/UI/FileManager/FSFolder.cpp
index 1b3837cf..e4cb9f27 100755
--- a/CPP/7zip/UI/FileManager/FSFolder.cpp
+++ b/CPP/7zip/UI/FileManager/FSFolder.cpp
@@ -24,7 +24,7 @@
namespace NWindows {
namespace NFile {
-bool GetLongPath(LPCWSTR path, UString &longPath);
+bool GetLongPath(CFSTR path, UString &longPath);
}}
@@ -47,7 +47,7 @@ static STATPROPSTG kProps[] =
{ NULL, kpidPrefix, VT_BSTR}
};
-HRESULT CFSFolder::Init(const UString &path, IFolderFolder *parentFolder)
+HRESULT CFSFolder::Init(const FString &path, IFolderFolder *parentFolder)
{
_parentFolder = parentFolder;
_path = path;
@@ -65,25 +65,25 @@ HRESULT CFSFolder::Init(const UString &path, IFolderFolder *parentFolder)
{
DWORD lastError = GetLastError();
CFindFile findFile;
- CFileInfoW fi;
- if (!findFile.FindFirst(_path + UString(L"*"), fi))
+ CFileInfo fi;
+ if (!findFile.FindFirst(_path + FCHAR_ANY_MASK, fi))
return lastError;
}
return S_OK;
}
-HRESULT GetFolderSize(const UString &path, UInt64 &numFolders, UInt64 &numFiles, UInt64 &size, IProgress *progress)
+static HRESULT GetFolderSize(const FString &path, UInt64 &numFolders, UInt64 &numFiles, UInt64 &size, IProgress *progress)
{
RINOK(progress->SetCompleted(NULL));
numFiles = numFolders = size = 0;
- CEnumeratorW enumerator(path + UString(WSTRING_PATH_SEPARATOR L"*"));
- CFileInfoW fi;
+ CEnumerator enumerator(path + FSTRING_PATH_SEPARATOR FSTRING_ANY_MASK);
+ CFileInfo fi;
while (enumerator.Next(fi))
{
if (fi.IsDir())
{
UInt64 subFolders, subFiles, subSize;
- RINOK(GetFolderSize(path + UString(WCHAR_PATH_SEPARATOR) + fi.Name, subFolders, subFiles, subSize, progress));
+ RINOK(GetFolderSize(path + FCHAR_PATH_SEPARATOR + fi.Name, subFolders, subFiles, subSize, progress));
numFolders += subFolders;
numFolders++;
numFiles += subFiles;
@@ -98,10 +98,10 @@ HRESULT GetFolderSize(const UString &path, UInt64 &numFolders, UInt64 &numFiles,
return S_OK;
}
-HRESULT CFSFolder::LoadSubItems(CDirItem &dirItem, const UString &path)
+HRESULT CFSFolder::LoadSubItems(CDirItem &dirItem, const FString &path)
{
{
- CEnumeratorW enumerator(path + L"*");
+ CEnumerator enumerator(path + FCHAR_ANY_MASK);
CDirItem fi;
while (enumerator.Next(fi))
{
@@ -128,7 +128,7 @@ HRESULT CFSFolder::LoadSubItems(CDirItem &dirItem, const UString &path)
{
CDirItem &item = dirItem.Files[i];
if (item.IsDir())
- LoadSubItems(item, path + item.Name + WCHAR_PATH_SEPARATOR);
+ LoadSubItems(item, path + item.Name + FCHAR_PATH_SEPARATOR);
}
return S_OK;
}
@@ -166,7 +166,7 @@ STDMETHODIMP CFSFolder::LoadItems()
return S_OK;
}
-static const wchar_t *kDescriptionFileName = L"descript.ion";
+static CFSTR kDescriptionFileName = FTEXT("descript.ion");
bool CFSFolder::LoadComments()
{
@@ -244,10 +244,10 @@ STDMETHODIMP CFSFolder::GetNumberOfSubFolders(UInt32 *numSubFolders)
*/
#ifndef UNDER_CE
-static bool MyGetCompressedFileSizeW(LPCWSTR fileName, UInt64 &size)
+static bool MyGetCompressedFileSizeW(CFSTR fileName, UInt64 &size)
{
DWORD highPart;
- DWORD lowPart = ::GetCompressedFileSizeW(fileName, &highPart);
+ DWORD lowPart = ::GetCompressedFileSizeW(fs2us(fileName), &highPart);
if (lowPart == INVALID_FILE_SIZE && ::GetLastError() != NO_ERROR)
{
#ifdef WIN_LONG_PATH
@@ -274,7 +274,7 @@ STDMETHODIMP CFSFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT
switch(propID)
{
case kpidIsDir: prop = fi.IsDir(); break;
- case kpidName: prop = fi.Name; break;
+ case kpidName: prop = fs2us(fi.Name); break;
case kpidSize: if (!fi.IsDir()) prop = fi.Size; break;
case kpidPackSize:
#ifdef UNDER_CE
@@ -298,7 +298,7 @@ STDMETHODIMP CFSFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT
{
LoadComments();
UString comment;
- if (_comments.GetValue(GetRelPath(fi), comment))
+ if (_comments.GetValue(fs2us(GetRelPath(fi)), comment))
prop = comment;
break;
}
@@ -313,29 +313,29 @@ STDMETHODIMP CFSFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT
return S_OK;
}
-HRESULT CFSFolder::BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder)
+HRESULT CFSFolder::BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder)
{
*resultFolder = 0;
CFSFolder *folderSpec = new CFSFolder;
CMyComPtr<IFolderFolder> subFolder = folderSpec;
- RINOK(folderSpec->Init(_path + name + UString(WCHAR_PATH_SEPARATOR), 0));
+ RINOK(folderSpec->Init(_path + name + FCHAR_PATH_SEPARATOR, 0));
*resultFolder = subFolder.Detach();
return S_OK;
}
-UString CFSFolder::GetPrefix(const CDirItem &item) const
+FString CFSFolder::GetPrefix(const CDirItem &item) const
{
- UString path;
+ FString path;
CDirItem *cur = item.Parent;
while (cur->Parent != 0)
{
- path = cur->Name + UString(WCHAR_PATH_SEPARATOR) + path;
+ path = cur->Name + FCHAR_PATH_SEPARATOR + path;
cur = cur->Parent;
}
return path;
}
-UString CFSFolder::GetRelPath(const CDirItem &item) const
+FString CFSFolder::GetRelPath(const CDirItem &item) const
{
return GetPrefix(item) + item.Name;
}
@@ -351,7 +351,7 @@ STDMETHODIMP CFSFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder)
STDMETHODIMP CFSFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder)
{
- return BindToFolderSpec(name, resultFolder);
+ return BindToFolderSpec(us2fs(name), resultFolder);
}
STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)
@@ -365,11 +365,11 @@ STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)
}
if (_path.IsEmpty())
return E_INVALIDARG;
- int pos = _path.ReverseFind(WCHAR_PATH_SEPARATOR);
+ int pos = _path.ReverseFind(FCHAR_PATH_SEPARATOR);
if (pos < 0 || pos != _path.Length() - 1)
return E_FAIL;
- UString parentPath = _path.Left(pos);
- pos = parentPath.ReverseFind(WCHAR_PATH_SEPARATOR);
+ FString parentPath = _path.Left(pos);
+ pos = parentPath.ReverseFind(FCHAR_PATH_SEPARATOR);
if (pos < 0)
{
#ifdef UNDER_CE
@@ -382,17 +382,17 @@ STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)
#endif
return S_OK;
}
- UString parentPathReduced = parentPath.Left(pos);
+ FString parentPathReduced = parentPath.Left(pos);
parentPath = parentPath.Left(pos + 1);
#ifndef UNDER_CE
- pos = parentPathReduced.ReverseFind(WCHAR_PATH_SEPARATOR);
+ pos = parentPathReduced.ReverseFind(FCHAR_PATH_SEPARATOR);
if (pos == 1)
{
- if (parentPath[0] != WCHAR_PATH_SEPARATOR)
+ if (parentPath[0] != FCHAR_PATH_SEPARATOR)
return E_FAIL;
CNetFolder *netFolderSpec = new CNetFolder;
CMyComPtr<IFolderFolder> netFolder = netFolderSpec;
- netFolderSpec->Init(parentPath);
+ netFolderSpec->Init(fs2us(parentPath));
*resultFolder = netFolder.Detach();
return S_OK;
}
@@ -421,7 +421,7 @@ STDMETHODIMP CFSFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
switch(propID)
{
case kpidType: prop = L"FSFolder"; break;
- case kpidPath: prop = _path; break;
+ case kpidPath: prop = fs2us(_path); break;
}
prop.Detach(value);
return S_OK;
@@ -532,13 +532,13 @@ STDMETHODIMP CFSFolder::GetItemFullSize(UInt32 index, PROPVARIANT *value, IProgr
return result;
}
-HRESULT CFSFolder::GetComplexName(const wchar_t *name, UString &resultPath)
+HRESULT CFSFolder::GetComplexName(CFSTR name, FString &resultPath)
{
- UString newName = name;
+ FString newName = name;
resultPath = _path + newName;
if (newName.Length() < 1)
return S_OK;
- if (newName[0] == WCHAR_PATH_SEPARATOR)
+ if (newName[0] == FCHAR_PATH_SEPARATOR)
{
resultPath = newName;
return S_OK;
@@ -552,11 +552,11 @@ HRESULT CFSFolder::GetComplexName(const wchar_t *name, UString &resultPath)
STDMETHODIMP CFSFolder::CreateFolder(const wchar_t *name, IProgress * /* progress */)
{
- UString processedName;
- RINOK(GetComplexName(name, processedName));
- if(NDirectory::MyCreateDirectory(processedName))
+ FString processedName;
+ RINOK(GetComplexName(us2fs(name), processedName));
+ if (NDirectory::MyCreateDirectory(processedName))
return S_OK;
- if(::GetLastError() == ERROR_ALREADY_EXISTS)
+ if (::GetLastError() == ERROR_ALREADY_EXISTS)
return ::GetLastError();
if (!NDirectory::CreateComplexDirectory(processedName))
return ::GetLastError();
@@ -565,8 +565,8 @@ STDMETHODIMP CFSFolder::CreateFolder(const wchar_t *name, IProgress * /* progres
STDMETHODIMP CFSFolder::CreateFile(const wchar_t *name, IProgress * /* progress */)
{
- UString processedName;
- RINOK(GetComplexName(name, processedName));
+ FString processedName;
+ RINOK(GetComplexName(us2fs(name), processedName));
NIO::COutFile outFile;
if (!outFile.Create(processedName, false))
return ::GetLastError();
@@ -576,8 +576,8 @@ STDMETHODIMP CFSFolder::CreateFile(const wchar_t *name, IProgress * /* progress
STDMETHODIMP CFSFolder::Rename(UInt32 index, const wchar_t *newName, IProgress * /* progress */)
{
const CDirItem &fi = *_refs[index];
- const UString fullPrefix = _path + GetPrefix(fi);
- if (!NDirectory::MyMoveFile(fullPrefix + fi.Name, fullPrefix + newName))
+ const FString fullPrefix = _path + GetPrefix(fi);
+ if (!NDirectory::MyMoveFile(fullPrefix + fi.Name, fullPrefix + us2fs(newName)))
return GetLastError();
return S_OK;
}
@@ -588,7 +588,7 @@ STDMETHODIMP CFSFolder::Delete(const UInt32 *indices, UInt32 numItems,IProgress
for (UInt32 i = 0; i < numItems; i++)
{
const CDirItem &fi = *_refs[indices[i]];
- const UString fullPath = _path + GetRelPath(fi);
+ const FString fullPath = _path + GetRelPath(fi);
bool result;
if (fi.IsDir())
result = NDirectory::RemoveDirectoryWithSubItems(fullPath);
@@ -614,7 +614,7 @@ STDMETHODIMP CFSFolder::SetProperty(UInt32 index, PROPID propID,
{
case kpidComment:
{
- UString filename = fi.Name;
+ UString filename = fs2us(fi.Name);
filename.Trim();
if (value->vt == VT_EMPTY)
_comments.DeletePair(filename);
diff --git a/CPP/7zip/UI/FileManager/FSFolder.h b/CPP/7zip/UI/FileManager/FSFolder.h
index e39004ad..13e9e018 100755
--- a/CPP/7zip/UI/FileManager/FSFolder.h
+++ b/CPP/7zip/UI/FileManager/FSFolder.h
@@ -1,7 +1,7 @@
// FSFolder.h
-#ifndef __FSFOLDER_H
-#define __FSFOLDER_H
+#ifndef __FS_FOLDER_H
+#define __FS_FOLDER_H
#include "Common/MyCom.h"
@@ -14,7 +14,7 @@ namespace NFsFolder {
class CFSFolder;
-struct CFileInfoEx: public NWindows::NFile::NFind::CFileInfoW
+struct CFileInfoEx: public NWindows::NFile::NFind::CFileInfo
{
#ifndef UNDER_CE
bool CompressedSizeIsDefined;
@@ -74,7 +74,7 @@ public:
STDMETHOD(GetSystemIconIndex)(UInt32 index, Int32 *iconIndex);
private:
- UString _path;
+ FString _path;
CDirItem _root;
CRecordVector<CDirItem *> _refs;
@@ -90,24 +90,24 @@ private:
HRESULT GetItemsFullSize(const UInt32 *indices, UInt32 numItems,
UInt64 &numFolders, UInt64 &numFiles, UInt64 &size, IProgress *progress);
HRESULT GetItemFullSize(int index, UInt64 &size, IProgress *progress);
- HRESULT GetComplexName(const wchar_t *name, UString &resultPath);
- HRESULT BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder);
+ HRESULT GetComplexName(CFSTR name, FString &resultPath);
+ HRESULT BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder);
bool LoadComments();
bool SaveComments();
- HRESULT LoadSubItems(CDirItem &dirItem, const UString &path);
+ HRESULT LoadSubItems(CDirItem &dirItem, const FString &path);
void AddRefs(CDirItem &dirItem);
public:
- HRESULT Init(const UString &path, IFolderFolder *parentFolder);
+ HRESULT Init(const FString &path, IFolderFolder *parentFolder);
#ifdef UNDER_CE
- HRESULT InitToRoot() { return Init(L"\\", NULL); }
+ HRESULT InitToRoot() { return Init(FTEXT("\\"), NULL); }
#endif
CFSFolder() : _flatMode(false) {}
- UString GetPrefix(const CDirItem &item) const;
- UString GetRelPath(const CDirItem &item) const;
- UString GetRelPath(UInt32 index) const { return GetRelPath(*_refs[index]); }
+ FString GetPrefix(const CDirItem &item) const;
+ FString GetRelPath(const CDirItem &item) const;
+ FString GetRelPath(UInt32 index) const { return GetRelPath(*_refs[index]); }
void Clear()
{
@@ -116,8 +116,6 @@ public:
}
};
-HRESULT GetFolderSize(const UString &path, UInt64 &numFolders, UInt64 &numFiles, UInt64 &size, IProgress *progress);
-
}
#endif
diff --git a/CPP/7zip/UI/FileManager/FSFolderCopy.cpp b/CPP/7zip/UI/FileManager/FSFolderCopy.cpp
index b6ffd574..c31498c7 100755
--- a/CPP/7zip/UI/FileManager/FSFolderCopy.cpp
+++ b/CPP/7zip/UI/FileManager/FSFolderCopy.cpp
@@ -102,13 +102,7 @@ typedef BOOL (WINAPI * CopyFileExPointerW)(
IN DWORD dwCopyFlags
);
-#ifndef _UNICODE
-static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
-static CSysString GetSysPath(LPCWSTR sysPath)
- { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
-#endif
-
-static bool MyCopyFile(LPCWSTR existingFile, LPCWSTR newFile, IProgress *progress, UInt64 &completedSize)
+static bool MyCopyFile(CFSTR existingFile, CFSTR newFile, IProgress *progress, UInt64 &completedSize)
{
CProgressInfo progressInfo;
progressInfo.Progress = progress;
@@ -128,8 +122,8 @@ static bool MyCopyFile(LPCWSTR existingFile, LPCWSTR newFile, IProgress *progres
CopyFileExPointerW copyFunctionW = (CopyFileExPointerW)
My_GetProcAddress(::GetModuleHandleW(k_DllName), "CopyFileExW");
if (copyFunctionW == 0)
- return BOOLToBool(::CopyFileW(existingFile, newFile, TRUE));
- if (copyFunctionW(existingFile, newFile, CopyProgressRoutine,
+ return BOOLToBool(::CopyFileW(fs2us(existingFile), fs2us(newFile), TRUE));
+ if (copyFunctionW(fs2us(existingFile), fs2us(newFile), CopyProgressRoutine,
&progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS))
return true;
#ifdef WIN_LONG_PATH
@@ -150,13 +144,13 @@ static bool MyCopyFile(LPCWSTR existingFile, LPCWSTR newFile, IProgress *progres
"CopyFileExA");
if (copyFunction != 0)
{
- if (copyFunction(GetSysPath(existingFile), GetSysPath(newFile),
+ if (copyFunction(fs2fas(existingFile), fs2fas(newFile),
CopyProgressRoutine,&progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS))
return true;
if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
return false;
}
- return BOOLToBool(::CopyFile(GetSysPath(existingFile), GetSysPath(newFile), TRUE));
+ return BOOLToBool(::CopyFile(fs2fas(existingFile), fs2fas(newFile), TRUE));
}
#endif
}
@@ -169,7 +163,7 @@ typedef BOOL (WINAPI * MoveFileWithProgressPointer)(
IN DWORD dwFlags
);
-static bool MyMoveFile(LPCWSTR existingFile, LPCWSTR newFile, IProgress *progress, UInt64 &completedSize)
+static bool MyMoveFile(CFSTR existingFile, CFSTR newFile, IProgress *progress, UInt64 &completedSize)
{
#ifndef UNDER_CE
// if (IsItWindows2000orHigher())
@@ -184,7 +178,7 @@ static bool MyMoveFile(LPCWSTR existingFile, LPCWSTR newFile, IProgress *progres
if (moveFunction != 0)
{
if (moveFunction(
- existingFile, newFile, CopyProgressRoutine,
+ fs2us(existingFile), fs2us(newFile), CopyProgressRoutine,
&progressInfo, MOVEFILE_COPY_ALLOWED))
return true;
if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
@@ -207,41 +201,48 @@ static bool MyMoveFile(LPCWSTR existingFile, LPCWSTR newFile, IProgress *progres
return NDirectory::MyMoveFile(existingFile, newFile);
}
+static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
+ const wchar_t *message, const FString &fileName)
+{
+ return callback->ShowMessage(message + fs2us(fileName));
+}
+
+static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
+ const char *message, const FString &fileName)
+{
+ return SendMessageError(callback, MultiByteToUnicodeString(message), fileName);
+}
+
static HRESULT MyCopyFile(
- const UString &srcPath,
- const CFileInfoW &srcFileInfo,
- const UString &destPathSpec,
+ const FString &srcPath,
+ const CFileInfo &srcFileInfo,
+ const FString &destPathSpec,
IFolderOperationsExtractCallback *callback,
UInt64 &completedSize)
{
- UString destPath = destPathSpec;
+ FString destPath = destPathSpec;
if (destPath.CompareNoCase(srcPath) == 0)
{
- UString message = UString(L"can not move file \'") + destPath + UString(L"\' onto itself");
- RINOK(callback->ShowMessage(message));
+ RINOK(SendMessageError(callback, "can not copy file onto itself: ", destPath));
return E_ABORT;
}
Int32 writeAskResult;
CMyComBSTR destPathResult;
RINOK(callback->AskWrite(
- srcPath,
+ fs2us(srcPath),
BoolToInt(false),
&srcFileInfo.MTime, &srcFileInfo.Size,
- destPath,
+ fs2us(destPath),
&destPathResult,
&writeAskResult));
if (IntToBool(writeAskResult))
{
- UString destPathNew = UString(destPathResult);
- RINOK(callback->SetCurrentFilePath(srcPath));
+ FString destPathNew = us2fs(destPathResult);
+ RINOK(callback->SetCurrentFilePath(fs2us(srcPath)));
if (!MyCopyFile(srcPath, destPathNew, callback, completedSize))
{
- UString message = NError::MyFormatMessageW(GetLastError()) +
- UString(L" \'") +
- UString(destPathNew) +
- UString(L"\'");
- RINOK(callback->ShowMessage(message));
+ RINOK(SendMessageError(callback, NError::MyFormatMessageW(GetLastError()) + L" : ", destPathNew));
return E_ABORT;
}
}
@@ -249,44 +250,41 @@ static HRESULT MyCopyFile(
return callback->SetCompleted(&completedSize);
}
-static UString CombinePath(const UString &folderPath, const UString &fileName)
+static FString CombinePath(const FString &folderPath, const FString &fileName)
{
- return folderPath + UString(WCHAR_PATH_SEPARATOR) + fileName;
+ return folderPath + FCHAR_PATH_SEPARATOR + fileName;
}
static HRESULT CopyFolder(
- const UString &srcPath,
- const UString &destPathSpec,
+ const FString &srcPath,
+ const FString &destPathSpec,
IFolderOperationsExtractCallback *callback,
UInt64 &completedSize)
{
RINOK(callback->SetCompleted(&completedSize));
- const UString destPath = destPathSpec;
+ const FString destPath = destPathSpec;
int len = srcPath.Length();
if (destPath.Length() >= len && srcPath.CompareNoCase(destPath.Left(len)) == 0)
{
- if (destPath.Length() == len || destPath[len] == WCHAR_PATH_SEPARATOR)
+ if (destPath.Length() == len || destPath[len] == FCHAR_PATH_SEPARATOR)
{
- UString message = UString(L"can not copy folder \'") +
- destPath + UString(L"\' onto itself");
- RINOK(callback->ShowMessage(message));
+ RINOK(SendMessageError(callback, "can not copy folder onto itself: ", destPath));
return E_ABORT;
}
}
if (!NDirectory::CreateComplexDirectory(destPath))
{
- UString message = UString(L"can not create folder ") + destPath;
- RINOK(callback->ShowMessage(message));
+ RINOK(SendMessageError(callback, "can not create folder: ", destPath));
return E_ABORT;
}
- CEnumeratorW enumerator(CombinePath(srcPath, L"*"));
+ CEnumerator enumerator(CombinePath(srcPath, FSTRING_ANY_MASK));
CFileInfoEx fi;
while (enumerator.Next(fi))
{
- const UString srcPath2 = CombinePath(srcPath, fi.Name);
- const UString destPath2 = CombinePath(destPath, fi.Name);
+ const FString srcPath2 = CombinePath(srcPath, fi.Name);
+ const FString destPath2 = CombinePath(destPath, fi.Name);
if (fi.IsDir())
{
RINOK(CopyFolder(srcPath2, destPath2, callback, completedSize))
@@ -313,7 +311,7 @@ STDMETHODIMP CFSFolder::CopyTo(const UInt32 *indices, UInt32 numItems,
UString destPath = path;
if (destPath.IsEmpty())
return E_INVALIDARG;
- bool directName = (destPath[destPath.Length() - 1] != WCHAR_PATH_SEPARATOR);
+ bool directName = (destPath.Back() != WCHAR_PATH_SEPARATOR);
if (directName)
{
if (numItems > 1)
@@ -337,10 +335,10 @@ STDMETHODIMP CFSFolder::CopyTo(const UInt32 *indices, UInt32 numItems,
for (UInt32 i = 0; i < numItems; i++)
{
const CDirItem &fi = *_refs[indices[i]];
- UString destPath2 = destPath;
+ FString destPath2 = us2fs(destPath);
if (!directName)
destPath2 += fi.Name;
- UString srcPath = _path + GetPrefix(fi) + fi.Name;
+ FString srcPath = _path + GetPrefix(fi) + fi.Name;
if (fi.IsDir())
{
RINOK(CopyFolder(srcPath, destPath2, callback, completedSize));
@@ -356,40 +354,35 @@ STDMETHODIMP CFSFolder::CopyTo(const UInt32 *indices, UInt32 numItems,
/////////////////////////////////////////////////
// Move Operations
-HRESULT MyMoveFile(
- const UString &srcPath,
- const CFileInfoW &srcFileInfo,
- const UString &destPathSpec,
+static HRESULT MyMoveFile(
+ const FString &srcPath,
+ const CFileInfo &srcFileInfo,
+ const FString &destPath,
IFolderOperationsExtractCallback *callback,
UInt64 &completedSize)
{
- UString destPath = destPathSpec;
if (destPath.CompareNoCase(srcPath) == 0)
{
- UString message = UString(L"can not move file \'")
- + destPath +
- UString(L"\' onto itself");
- RINOK(callback->ShowMessage(message));
+ RINOK(SendMessageError(callback, "can not move file onto itself: ", srcPath));
return E_ABORT;
}
Int32 writeAskResult;
CMyComBSTR destPathResult;
RINOK(callback->AskWrite(
- srcPath,
+ fs2us(srcPath),
BoolToInt(false),
&srcFileInfo.MTime, &srcFileInfo.Size,
- destPath,
+ fs2us(destPath),
&destPathResult,
&writeAskResult));
if (IntToBool(writeAskResult))
{
- UString destPathNew = UString(destPathResult);
- RINOK(callback->SetCurrentFilePath(srcPath));
+ FString destPathNew = us2fs(destPathResult);
+ RINOK(callback->SetCurrentFilePath(fs2us(srcPath)));
if (!MyMoveFile(srcPath, destPathNew, callback, completedSize))
{
- UString message = UString(L"can not move to file ") + destPathNew;
- RINOK(callback->ShowMessage(message));
+ RINOK(SendMessageError(callback, "can not move to file: ", destPathNew));
}
}
completedSize += srcFileInfo.Size;
@@ -397,21 +390,18 @@ HRESULT MyMoveFile(
return S_OK;
}
-HRESULT MyMoveFolder(
- const UString &srcPath,
- const UString &destPathSpec,
+static HRESULT MyMoveFolder(
+ const FString &srcPath,
+ const FString &destPath,
IFolderOperationsExtractCallback *callback,
UInt64 &completedSize)
{
- UString destPath = destPathSpec;
int len = srcPath.Length();
if (destPath.Length() >= len && srcPath.CompareNoCase(destPath.Left(len)) == 0)
{
- if (destPath.Length() == len || destPath[len] == WCHAR_PATH_SEPARATOR)
+ if (destPath.Length() == len || destPath[len] == FCHAR_PATH_SEPARATOR)
{
- UString message = UString(L"can not move folder \'") +
- destPath + UString(L"\' onto itself");
- RINOK(callback->ShowMessage(message));
+ RINOK(SendMessageError(callback, "can not move folder onto itself: ", destPath));
return E_ABORT;
}
}
@@ -421,17 +411,16 @@ HRESULT MyMoveFolder(
if (!NDirectory::CreateComplexDirectory(destPath))
{
- UString message = UString(L"can not create folder ") + destPath;
- RINOK(callback->ShowMessage(message));
+ RINOK(SendMessageError(callback, "can not create folder: ", destPath));
return E_ABORT;
}
{
- CEnumeratorW enumerator(CombinePath(srcPath, L"*"));
+ CEnumerator enumerator(CombinePath(srcPath, FSTRING_ANY_MASK));
CFileInfoEx fi;
while (enumerator.Next(fi))
{
- const UString srcPath2 = CombinePath(srcPath, fi.Name);
- const UString destPath2 = CombinePath(destPath, fi.Name);
+ const FString srcPath2 = CombinePath(srcPath, fi.Name);
+ const FString destPath2 = CombinePath(destPath, fi.Name);
if (fi.IsDir())
{
RINOK(MyMoveFolder(srcPath2, destPath2, callback, completedSize));
@@ -444,8 +433,7 @@ HRESULT MyMoveFolder(
}
if (!NDirectory::MyRemoveDirectory(srcPath))
{
- UString message = UString(L"can not remove folder") + srcPath;
- RINOK(callback->ShowMessage(message));
+ RINOK(SendMessageError(callback, "can not remove folder: ", srcPath));
return E_ABORT;
}
return S_OK;
@@ -465,10 +453,10 @@ STDMETHODIMP CFSFolder::MoveTo(
RINOK(callback->SetTotal(totalSize));
RINOK(callback->SetNumFiles(numFiles));
- UString destPath = path;
+ FString destPath = us2fs(path);
if (destPath.IsEmpty())
return E_INVALIDARG;
- bool directName = (destPath[destPath.Length() - 1] != WCHAR_PATH_SEPARATOR);
+ bool directName = (destPath.Back() != FCHAR_PATH_SEPARATOR);
if (directName)
{
if (numItems > 1)
@@ -477,9 +465,7 @@ STDMETHODIMP CFSFolder::MoveTo(
else
if (!NDirectory::CreateComplexDirectory(destPath))
{
- UString message = UString(L"can not create folder ") +
- destPath;
- RINOK(callback->ShowMessage(message));
+ RINOK(SendMessageError(callback, "can not create folder: ", destPath));
return E_ABORT;
}
@@ -488,10 +474,10 @@ STDMETHODIMP CFSFolder::MoveTo(
for (UInt32 i = 0; i < numItems; i++)
{
const CDirItem &fi = *_refs[indices[i]];
- UString destPath2 = destPath;
+ FString destPath2 = destPath;
if (!directName)
destPath2 += fi.Name;
- UString srcPath = _path + GetPrefix(fi) + fi.Name;
+ FString srcPath = _path + GetPrefix(fi) + fi.Name;
if (fi.IsDir())
{
RINOK(MyMoveFolder(srcPath, destPath2, callback, completedSize));
@@ -515,7 +501,7 @@ STDMETHODIMP CFSFolder::CopyFrom(const wchar_t * /* fromFolderPath */,
{
UString path = (UString)fromFolderPath + itemsPaths[i];
- CFileInfoW fi;
+ CFileInfo fi;
if (!FindFile(path, fi))
return ::GetLastError();
if (fi.IsDir())
@@ -544,4 +530,9 @@ STDMETHODIMP CFSFolder::CopyFrom(const wchar_t * /* fromFolderPath */,
return E_NOTIMPL;
}
+STDMETHODIMP CFSFolder::CopyFromFile(UInt32 /* index */, const wchar_t * /* fullFilePath */, IProgress * /* progress */)
+{
+ return E_NOTIMPL;
+}
+
}
diff --git a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp
index 08f15c18..d29ac44c 100755
--- a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp
+++ b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.cpp
@@ -4,6 +4,7 @@
#include "resource.h"
+#include "Windows/FileName.h"
#include "Windows/Thread.h"
#include "../Agent/Agent.h"
@@ -11,11 +12,9 @@
#include "LangUtils.h"
#include "OpenCallback.h"
#include "PluginLoader.h"
-#include "RegistryAssociations.h"
#include "RegistryPlugins.h"
using namespace NWindows;
-using namespace NRegistryAssociations;
struct CThreadArchiveOpen
{
@@ -56,9 +55,29 @@ static int FindPlugin(const CObjectVector<CPluginInfo> &plugins, const UString &
}
*/
+static const FChar kExtensionDelimiter = FTEXT('.');
+
+static void SplitNameToPureNameAndExtension(const FString &fullName,
+ FString &pureName, FString &extensionDelimiter, FString &extension)
+{
+ int index = fullName.ReverseFind(kExtensionDelimiter);
+ if (index < 0)
+ {
+ pureName = fullName;
+ extensionDelimiter.Empty();
+ extension.Empty();
+ }
+ else
+ {
+ pureName = fullName.Left(index);
+ extensionDelimiter = kExtensionDelimiter;
+ extension = fullName.Mid(index + 1);
+ }
+}
+
HRESULT OpenFileFolderPlugin(
IInStream *inStream,
- const UString &path,
+ const FString &path,
const UString &arcFormat,
HMODULE *module,
IFolderFolder **resultFolder,
@@ -68,11 +87,11 @@ HRESULT OpenFileFolderPlugin(
CObjectVector<CPluginInfo> plugins;
ReadFileFolderPluginInfoList(plugins);
- UString extension, name, pureName, dot;
+ FString extension, name, pureName, dot;
- int slashPos = path.ReverseFind(WCHAR_PATH_SEPARATOR);
- UString dirPrefix;
- UString fileName;
+ int slashPos = path.ReverseFind(FCHAR_PATH_SEPARATOR);
+ FString dirPrefix;
+ FString fileName;
if (slashPos >= 0)
{
dirPrefix = path.Left(slashPos + 1);
@@ -81,7 +100,7 @@ HRESULT OpenFileFolderPlugin(
else
fileName = path;
- NFile::NName::SplitNameToPureNameAndExtension(fileName, pureName, dot, extension);
+ SplitNameToPureNameAndExtension(fileName, pureName, dot, extension);
/*
if (!extension.IsEmpty())
@@ -124,12 +143,12 @@ HRESULT OpenFileFolderPlugin(
t.OpenCallbackSpec->ParentWindow = parentWindow;
if (inStream)
- t.OpenCallbackSpec->SetSubArchiveName(fileName);
+ t.OpenCallbackSpec->SetSubArchiveName(fs2us(fileName));
else
t.OpenCallbackSpec->LoadFileInfo(dirPrefix, fileName);
t.InStream = inStream;
- t.Path = path;
+ t.Path = fs2us(path);
t.ArcFormat = arcFormat;
UString progressTitle = LangString(IDS_OPENNING, 0x03020283);
diff --git a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h
index 85717efd..593880e9 100755
--- a/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h
+++ b/CPP/7zip/UI/FileManager/FileFolderPluginOpen.h
@@ -3,7 +3,7 @@
#ifndef __FILE_FOLDER_PLUGIN_OPEN_H
#define __FILE_FOLDER_PLUGIN_OPEN_H
-HRESULT OpenFileFolderPlugin(IInStream *inStream, const UString &path, const UString &arcFormat,
+HRESULT OpenFileFolderPlugin(IInStream *inStream, const FString &path, const UString &arcFormat,
HMODULE *module, IFolderFolder **resultFolder, HWND parentWindow, bool &encrypted, UString &password);
#endif
diff --git a/CPP/7zip/UI/FileManager/FilePlugins.cpp b/CPP/7zip/UI/FileManager/FilePlugins.cpp
index 22993383..b81850fd 100755
--- a/CPP/7zip/UI/FileManager/FilePlugins.cpp
+++ b/CPP/7zip/UI/FileManager/FilePlugins.cpp
@@ -2,73 +2,39 @@
#include "StdAfx.h"
-#include "Common/MyCom.h"
-
#include "../Agent/Agent.h"
#include "FilePlugins.h"
#include "PluginLoader.h"
#include "StringUtils.h"
-using namespace NRegistryAssociations;
-
-int CExtDatabase::FindExtInfoBig(const UString &ext)
-{
- for (int i = 0; i < ExtBigItems.Size(); i++)
- if (ExtBigItems[i].Ext.CompareNoCase(ext) == 0)
- return i;
- return -1;
-}
-
-int CExtDatabase::FindPlugin(const UString &plugin)
+int CExtDatabase::FindExt(const UString &ext)
{
- for (int i = 0; i < Plugins.Size(); i++)
- if (Plugins[i].Name.CompareNoCase(plugin) == 0)
+ for (int i = 0; i < Exts.Size(); i++)
+ if (Exts[i].Ext.CompareNoCase(ext) == 0)
return i;
return -1;
}
void CExtDatabase::Read()
{
- /*
- CObjectVector<CExtInfo> extItems;
- ReadInternalAssociations(extItems);
- */
ReadFileFolderPluginInfoList(Plugins);
- /*
- for (int i = 0; i < extItems.Size(); i++)
- {
- const CExtInfo &extInfo = extItems[i];
- CExtInfoBig extInfoBig;
- extInfoBig.Ext = extInfo.Ext;
- extInfoBig.Associated = false;
- for (int p = 0; p < extInfo.Plugins.Size(); p++)
- {
- int pluginIndex = FindPlugin(extInfo.Plugins[p]);
- if (pluginIndex >= 0)
- extInfoBig.PluginsPairs.Add(CPluginEnabledPair(pluginIndex, true));
- }
- ExtBigItems.Add(extInfoBig);
- }
- */
for (int pluginIndex = 0; pluginIndex < Plugins.Size(); pluginIndex++)
{
- const CPluginInfo &pluginInfo = Plugins[pluginIndex];
+ const CPluginInfo &plugin = Plugins[pluginIndex];
- CPluginLibrary pluginLibrary;
+ CPluginLibrary pluginLib;
CMyComPtr<IFolderManager> folderManager;
- if (pluginInfo.FilePath.IsEmpty())
+ if (plugin.FilePath.IsEmpty())
folderManager = new CArchiveFolderManager;
- else if (pluginLibrary.LoadAndCreateManager(pluginInfo.FilePath,
- pluginInfo.ClassID, &folderManager) != S_OK)
+ else if (pluginLib.LoadAndCreateManager(plugin.FilePath, plugin.ClassID, &folderManager) != S_OK)
continue;
CMyComBSTR extBSTR;
if (folderManager->GetExtensions(&extBSTR) != S_OK)
return;
- const UString ext2 = (const wchar_t *)extBSTR;
UStringVector exts;
- SplitString(ext2, exts);
+ SplitString((const wchar_t *)extBSTR, exts);
for (int i = 0; i < exts.Size(); i++)
{
const UString &ext = exts[i];
@@ -76,44 +42,28 @@ void CExtDatabase::Read()
if (ext == L"cab")
continue;
#endif
- int index = FindExtInfoBig(ext);
- if (index < 0)
- {
- CExtInfoBig extInfo;
- extInfo.PluginsPairs.Add(CPluginEnabledPair(pluginIndex, false));
- extInfo.Associated = false;
- extInfo.Ext = ext;
- ExtBigItems.Add(extInfo);
- }
+
+ Int32 iconIndex;
+ CMyComBSTR iconPath;
+ CPluginToIcon plugPair;
+ plugPair.PluginIndex = pluginIndex;
+ if (folderManager->GetIconPath(ext, &iconPath, &iconIndex) == S_OK)
+ if (iconPath != 0)
+ {
+ plugPair.IconPath = (const wchar_t *)iconPath;
+ plugPair.IconIndex = iconIndex;
+ }
+
+ int index = FindExt(ext);
+ if (index >= 0)
+ Exts[index].Plugins.Add(plugPair);
else
{
- CExtInfoBig &extInfo = ExtBigItems[index];
- int pluginIndexIndex = extInfo.FindPlugin(pluginIndex);
- if (pluginIndexIndex < 0)
- extInfo.PluginsPairs.Add(CPluginEnabledPair(pluginIndex, false));
+ CExtPlugins extInfo;
+ extInfo.Plugins.Add(plugPair);
+ extInfo.Ext = ext;
+ Exts.Add(extInfo);
}
}
}
}
-
-void CExtDatabase::Save()
-{
- /*
- CObjectVector<CExtInfo> extItems;
- for (int i = 0; i < ExtBigItems.Size(); i++)
- {
- const CExtInfoBig &extInfoBig = ExtBigItems[i];
- CExtInfo extInfo;
- // extInfo.Enabled = extInfoBig.Associated;
- extInfo.Ext = extInfoBig.Ext;
- for (int p = 0; p < extInfoBig.PluginsPairs.Size(); p++)
- {
- CPluginEnabledPair pluginPair = extInfoBig.PluginsPairs[p];
- if (pluginPair.Enabled)
- extInfo.Plugins.Add(Plugins[pluginPair.Index].Name);
- }
- extItems.Add(extInfo);
- }
- WriteInternalAssociations(extItems);
- */
-}
diff --git a/CPP/7zip/UI/FileManager/FilePlugins.h b/CPP/7zip/UI/FileManager/FilePlugins.h
index 1becb9d1..43b05f92 100755
--- a/CPP/7zip/UI/FileManager/FilePlugins.h
+++ b/CPP/7zip/UI/FileManager/FilePlugins.h
@@ -1,54 +1,33 @@
// FilePlugins.h
-#ifndef __FILEPLUGINS_H
-#define __FILEPLUGINS_H
+#ifndef __FILE_PLUGINS_H
+#define __FILE_PLUGINS_H
#include "RegistryPlugins.h"
-#include "RegistryAssociations.h"
-struct CPluginEnabledPair
+struct CPluginToIcon
{
- int Index;
- bool Enabled;
- CPluginEnabledPair(int index, bool enabled): Index(index),Enabled(enabled) {}
+ int PluginIndex;
+ UString IconPath;
+ int IconIndex;
+
+ CPluginToIcon(): IconIndex(-1) {}
};
-struct CExtInfoBig
+struct CExtPlugins
{
UString Ext;
- bool Associated;
- CRecordVector<CPluginEnabledPair> PluginsPairs;
- int FindPlugin(int pluginIndex)
- {
- for (int i = 0; i < PluginsPairs.Size(); i++)
- if (PluginsPairs[i].Index == pluginIndex)
- return i;
- return -1;
- }
+ CObjectVector<CPluginToIcon> Plugins;
};
class CExtDatabase
{
+ int FindExt(const UString &ext);
public:
- CObjectVector<CExtInfoBig> ExtBigItems;
+ CObjectVector<CExtPlugins> Exts;
CObjectVector<CPluginInfo> Plugins;
- int FindExtInfoBig(const UString &ext);
- int FindPlugin(const UString &plugin);
-
- UString GetMainPluginNameForExtItem(int extIndex) const
- {
- const CExtInfoBig &extInfo = ExtBigItems[extIndex];
- if (extInfo.PluginsPairs.IsEmpty())
- return UString();
- else
- return Plugins[extInfo.PluginsPairs.Front().Index].Name;
- }
-
+
void Read();
- void Save();
};
-
#endif
-
-
diff --git a/CPP/7zip/UI/FileManager/FoldersPage.cpp b/CPP/7zip/UI/FileManager/FoldersPage.cpp
index 068b9d47..b7366fed 100755
--- a/CPP/7zip/UI/FileManager/FoldersPage.cpp
+++ b/CPP/7zip/UI/FileManager/FoldersPage.cpp
@@ -42,7 +42,7 @@ bool CFoldersPage::OnInit()
m_WorkPath.Init(*this, IDC_FOLDERS_WORK_EDIT_PATH);
m_ButtonSetWorkPath.Init(*this, IDC_FOLDERS_WORK_BUTTON_PATH);
- m_WorkPath.SetText(m_WorkDirInfo.Path);
+ m_WorkPath.SetText(fs2us(m_WorkDirInfo.Path));
MyEnableControls();
@@ -66,7 +66,9 @@ void CFoldersPage::MyEnableControls()
void CFoldersPage::GetWorkDir(NWorkDir::CInfo &workDirInfo)
{
- m_WorkPath.GetText(workDirInfo.Path);
+ UString s;
+ m_WorkPath.GetText(s);
+ workDirInfo.Path = us2fs(s);
workDirInfo.ForRemovableOnly = IsButtonCheckedBool(IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE);
workDirInfo.Mode = NWorkDir::NMode::EEnum(GetWorkMode());
}
@@ -143,7 +145,7 @@ LONG CFoldersPage::OnApply()
return PSNRET_NOERROR;
}
-static LPCWSTR kFoldersTopic = L"fm/plugins/7-zip/options.htm#folders";
+static LPCWSTR kFoldersTopic = L"fm/options.htm#folders";
void CFoldersPage::OnNotifyHelp()
{
diff --git a/CPP/7zip/UI/FileManager/HelpUtils.cpp b/CPP/7zip/UI/FileManager/HelpUtils.cpp
index a1c17399..3128cb28 100755
--- a/CPP/7zip/UI/FileManager/HelpUtils.cpp
+++ b/CPP/7zip/UI/FileManager/HelpUtils.cpp
@@ -5,8 +5,8 @@
#include <HtmlHelp.h>
#include "Common/StringConvert.h"
+#include "Windows/DLL.h"
#include "HelpUtils.h"
-#include "ProgramLocation.h"
static LPCWSTR kHelpFileName = L"7-zip.chm::/";
@@ -17,11 +17,7 @@ void ShowHelpWindow(HWND, LPCWSTR)
#else
void ShowHelpWindow(HWND hwnd, LPCWSTR topicFile)
{
- UString path;
- if (!::GetProgramFolderPath(path))
- return;
- path += kHelpFileName;
- path += topicFile;
- HtmlHelp(hwnd, GetSystemString(path), HH_DISPLAY_TOPIC, NULL);
+ FString path = NWindows::NDLL::GetModuleDirPrefix();
+ HtmlHelp(hwnd, GetSystemString(fs2us(path) + kHelpFileName + topicFile), HH_DISPLAY_TOPIC, NULL);
}
#endif
diff --git a/CPP/7zip/UI/FileManager/IFolder.h b/CPP/7zip/UI/FileManager/IFolder.h
index 743017b8..d6cce88f 100755
--- a/CPP/7zip/UI/FileManager/IFolder.h
+++ b/CPP/7zip/UI/FileManager/IFolder.h
@@ -70,8 +70,9 @@ FOLDER_INTERFACE_SUB(IFolderOperationsExtractCallback, IProgress, 0x0B)
STDMETHOD(CopyFrom)(const wchar_t *fromFolderPath, \
const wchar_t **itemsPaths, UInt32 numItems, IProgress *progress) x; \
STDMETHOD(SetProperty)(UInt32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress) x; \
+ STDMETHOD(CopyFromFile)(UInt32 index, const wchar_t *fullFilePath, IProgress *progress) x; \
-FOLDER_INTERFACE(IFolderOperations, 0x06)
+FOLDER_INTERFACE(IFolderOperations, 0x12)
{
INTERFACE_FolderOperations(PURE)
};
diff --git a/CPP/7zip/UI/FileManager/LangUtils.cpp b/CPP/7zip/UI/FileManager/LangUtils.cpp
index 52f85348..20f4655b 100755
--- a/CPP/7zip/UI/FileManager/LangUtils.cpp
+++ b/CPP/7zip/UI/FileManager/LangUtils.cpp
@@ -2,14 +2,16 @@
#include "StdAfx.h"
-#include "LangUtils.h"
#include "Common/StringConvert.h"
#include "Common/StringToInt.h"
+
+#include "Windows/DLL.h"
+#include "Windows/FileFind.h"
#include "Windows/Synchronization.h"
#include "Windows/Window.h"
-#include "Windows/FileFind.h"
+
+#include "LangUtils.h"
#include "RegistryUtils.h"
-#include "ProgramLocation.h"
using namespace NWindows;
@@ -20,20 +22,23 @@ UString g_LangID;
extern bool g_IsNT;
#endif
+static FString GetLangDirPrefix()
+{
+ return NDLL::GetModuleDirPrefix() + FString(FTEXT("Lang") FSTRING_PATH_SEPARATOR);
+}
+
void ReloadLang()
{
ReadRegLang(g_LangID);
g_Lang.Clear();
if (!g_LangID.IsEmpty() && g_LangID != L"-")
{
- UString langPath = g_LangID;
+ FString langPath = us2fs(g_LangID);
if (langPath.Find(WCHAR_PATH_SEPARATOR) < 0)
{
- if (langPath.Find(L'.') < 0)
- langPath += L".txt";
- UString folderPath;
- if (GetProgramFolderPath(folderPath))
- langPath = folderPath + UString(L"Lang" WSTRING_PATH_SEPARATOR) + langPath;
+ if (langPath.Find(FTEXT('.')) < 0)
+ langPath += FTEXT(".txt");
+ langPath = GetLangDirPrefix() + langPath;
}
g_Lang.Open(langPath);
}
@@ -51,7 +56,7 @@ void LoadLangOneTime()
ReloadLang();
}
-void LangSetDlgItemsText(HWND dialogWindow, CIDLangPair *idLangPairs, int numItems)
+void LangSetDlgItemsText(HWND dialogWindow, const CIDLangPair *idLangPairs, int numItems)
{
for (int i = 0; i < numItems; i++)
{
@@ -85,30 +90,26 @@ UString LangString(UINT resourceID, UInt32 langID)
UString message;
if (g_Lang.GetMessage(langID, message))
return message;
- return NWindows::MyLoadStringW(resourceID);
+ return MyLoadStringW(resourceID);
}
void LoadLangs(CObjectVector<CLangEx> &langs)
{
langs.Clear();
- UString folderPath;
- if (!::GetProgramFolderPath(folderPath))
- return;
- folderPath += L"Lang" WSTRING_PATH_SEPARATOR;
- NWindows::NFile::NFind::CEnumeratorW enumerator(folderPath + L"*.txt");
- NWindows::NFile::NFind::CFileInfoW fileInfo;
- while (enumerator.Next(fileInfo))
+ const FString dirPrefix = GetLangDirPrefix();
+ NFile::NFind::CEnumerator enumerator(dirPrefix + FTEXT("*.txt"));
+ NFile::NFind::CFileInfo fi;
+ while (enumerator.Next(fi))
{
- if (fileInfo.IsDir())
+ if (fi.IsDir())
continue;
- CLangEx lang;
- UString filePath = folderPath + fileInfo.Name;
const int kExtSize = 4;
- const UString ext = fileInfo.Name.Right(kExtSize);
- if (ext.CompareNoCase(L".txt") != 0)
+ const FString ext = fi.Name.Right(kExtSize);
+ if (ext.CompareNoCase(FTEXT(".txt")) != 0)
continue;
- lang.ShortName = fileInfo.Name.Left(fileInfo.Name.Length() - kExtSize);
- if (lang.Lang.Open(filePath))
+ CLangEx lang;
+ lang.ShortName = fs2us(fi.Name.Left(fi.Name.Length() - kExtSize));
+ if (lang.Lang.Open(dirPrefix + fi.Name))
langs.Add(lang);
}
}
diff --git a/CPP/7zip/UI/FileManager/LangUtils.h b/CPP/7zip/UI/FileManager/LangUtils.h
index 40debdfe..d11082f6 100755
--- a/CPP/7zip/UI/FileManager/LangUtils.h
+++ b/CPP/7zip/UI/FileManager/LangUtils.h
@@ -1,7 +1,7 @@
// LangUtils.h
-#ifndef __LANGUTILS_H
-#define __LANGUTILS_H
+#ifndef __LANG_UTILS_H
+#define __LANG_UTILS_H
#include "Common/Lang.h"
#include "Windows/ResourceString.h"
@@ -26,7 +26,7 @@ struct CLangEx
void LoadLangs(CObjectVector<CLangEx> &langs);
-void LangSetDlgItemsText(HWND dialogWindow, CIDLangPair *idLangPairs, int numItems);
+void LangSetDlgItemsText(HWND dialogWindow, const CIDLangPair *idLangPairs, int numItems);
void LangSetWindowText(HWND window, UInt32 langID);
UString LangString(UInt32 langID);
diff --git a/CPP/7zip/UI/FileManager/ListViewDialog.cpp b/CPP/7zip/UI/FileManager/ListViewDialog.cpp
index f70572b9..b3e989c4 100755
--- a/CPP/7zip/UI/FileManager/ListViewDialog.cpp
+++ b/CPP/7zip/UI/FileManager/ListViewDialog.cpp
@@ -125,17 +125,12 @@ bool CListViewDialog::OnNotify(UINT /* controlID */, LPNMHDR header)
}
case 'A':
{
- // probably that code is unused ?
- /*
bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
if (ctrl)
{
- int numItems = _listView.GetItemCount();
- for (int i = 0; i < numItems; i++)
- _listView.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
+ _listView.SelectAll();
return true;
}
- */
}
}
}
diff --git a/CPP/7zip/UI/FileManager/MenuPage.cpp b/CPP/7zip/UI/FileManager/MenuPage.cpp
index e1041204..c3e013b5 100755
--- a/CPP/7zip/UI/FileManager/MenuPage.cpp
+++ b/CPP/7zip/UI/FileManager/MenuPage.cpp
@@ -23,7 +23,7 @@ static CIDLangPair kIDLangPairs[] =
{ IDC_SYSTEM_STATIC_CONTEXT_MENU_ITEMS, 0x01000310}
};
-static LPCWSTR kSystemTopic = L"fm/plugins/7-zip/options.htm#system";
+static LPCWSTR kSystemTopic = L"fm/options.htm#sevenZip";
struct CContextMenuItem
{
diff --git a/CPP/7zip/UI/FileManager/MessagesDialog.cpp b/CPP/7zip/UI/FileManager/MessagesDialog.cpp
index 3d73ade1..05aa823f 100755
--- a/CPP/7zip/UI/FileManager/MessagesDialog.cpp
+++ b/CPP/7zip/UI/FileManager/MessagesDialog.cpp
@@ -51,10 +51,7 @@ bool CMessagesDialog::OnInit()
LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
#endif
_messageList.Attach(GetItem(IDC_MESSAGE_LIST));
-
- #ifndef UNDER_CE
- _messageList.SetUnicodeFormat(true);
- #endif
+ _messageList.SetUnicodeFormat();
_messageList.InsertColumn(0, L"", 30);
diff --git a/CPP/7zip/UI/FileManager/MyLoadMenu.cpp b/CPP/7zip/UI/FileManager/MyLoadMenu.cpp
index ccfd33cc..b16e8948 100755
--- a/CPP/7zip/UI/FileManager/MyLoadMenu.cpp
+++ b/CPP/7zip/UI/FileManager/MyLoadMenu.cpp
@@ -513,6 +513,13 @@ bool ExecuteFileCommand(int id)
return true;
}
+static void MyBenchmark(bool totalMode)
+{
+ CPanel::CDisableTimerProcessing disableTimerProcessing1(g_App.Panels[0]);
+ CPanel::CDisableTimerProcessing disableTimerProcessing2(g_App.Panels[1]);
+ Benchmark(totalMode);
+}
+
bool OnMenuCommand(HWND hWnd, int id)
{
if (ExecuteFileCommand(id))
@@ -538,31 +545,31 @@ bool OnMenuCommand(HWND hWnd, int id)
break;
case IDM_SELECT_ALL:
g_App.SelectAll(true);
- g_App.RefreshStatusBar();
+ g_App.Refresh_StatusBar();
break;
case IDM_DESELECT_ALL:
g_App.SelectAll(false);
- g_App.RefreshStatusBar();
+ g_App.Refresh_StatusBar();
break;
case IDM_INVERT_SELECTION:
g_App.InvertSelection();
- g_App.RefreshStatusBar();
+ g_App.Refresh_StatusBar();
break;
case IDM_SELECT:
g_App.SelectSpec(true);
- g_App.RefreshStatusBar();
+ g_App.Refresh_StatusBar();
break;
case IDM_DESELECT:
g_App.SelectSpec(false);
- g_App.RefreshStatusBar();
+ g_App.Refresh_StatusBar();
break;
case IDM_SELECT_BY_TYPE:
g_App.SelectByType(true);
- g_App.RefreshStatusBar();
+ g_App.Refresh_StatusBar();
break;
case IDM_DESELECT_BY_TYPE:
g_App.SelectByType(false);
- g_App.RefreshStatusBar();
+ g_App.Refresh_StatusBar();
break;
//View
@@ -646,13 +653,9 @@ bool OnMenuCommand(HWND hWnd, int id)
OptionsDialog(hWnd, g_hInstance);
break;
- case IDM_BENCHMARK:
- {
- CPanel::CDisableTimerProcessing disableTimerProcessing1(g_App.Panels[0]);
- CPanel::CDisableTimerProcessing disableTimerProcessing2(g_App.Panels[1]);
- Benchmark();
- break;
- }
+ case IDM_BENCHMARK: MyBenchmark(false); break;
+ case IDM_BENCHMARK2: MyBenchmark(true); break;
+
// Help
case IDM_HELP_CONTENTS:
ShowHelpWindow(NULL, kFMHelpTopic);
diff --git a/CPP/7zip/UI/FileManager/NetFolder.cpp b/CPP/7zip/UI/FileManager/NetFolder.cpp
index e1fa1965..07387328 100755
--- a/CPP/7zip/UI/FileManager/NetFolder.cpp
+++ b/CPP/7zip/UI/FileManager/NetFolder.cpp
@@ -136,8 +136,8 @@ STDMETHODIMP CNetFolder::LoadItems()
resource.RemoteName = _path + resource.Name;
NFile::NFind::CFindFile findFile;
- NFile::NFind::CFileInfoW fileInfo;
- if (!findFile.FindFirst(resource.RemoteName + UString(WCHAR_PATH_SEPARATOR) + UString(L"*"), fileInfo))
+ NFile::NFind::CFileInfo fileInfo;
+ if (!findFile.FindFirst(us2fs(resource.RemoteName) + FString(FCHAR_PATH_SEPARATOR) + FCHAR_ANY_MASK, fileInfo))
continue;
resource.Usage = RESOURCEUSAGE_CONNECTABLE;
resource.LocalNameIsDefined = false;
@@ -185,7 +185,7 @@ STDMETHODIMP CNetFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder
{
NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder;
CMyComPtr<IFolderFolder> subFolder = fsFolderSpec;
- RINOK(fsFolderSpec->Init(resource.RemoteName + WCHAR_PATH_SEPARATOR, this));
+ RINOK(fsFolderSpec->Init(us2fs(resource.RemoteName + WCHAR_PATH_SEPARATOR), this));
*resultFolder = subFolder.Detach();
}
else
@@ -253,7 +253,7 @@ STDMETHODIMP CNetFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex)
if (resource.DisplayType == RESOURCEDISPLAYTYPE_SERVER ||
resource.Usage == RESOURCEUSAGE_CONNECTABLE)
{
- if (GetRealIconIndex(resource.RemoteName, 0, iconIndexTemp))
+ if (GetRealIconIndex(us2fs(resource.RemoteName), 0, iconIndexTemp))
{
*iconIndex = iconIndexTemp;
return S_OK;
@@ -261,7 +261,7 @@ STDMETHODIMP CNetFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex)
}
else
{
- if (GetRealIconIndex(TEXT(""), FILE_ATTRIBUTE_DIRECTORY, iconIndexTemp))
+ if (GetRealIconIndex(FTEXT(""), FILE_ATTRIBUTE_DIRECTORY, iconIndexTemp))
{
*iconIndex = iconIndexTemp;
return S_OK;
diff --git a/CPP/7zip/UI/FileManager/OpenCallback.cpp b/CPP/7zip/UI/FileManager/OpenCallback.cpp
index 72245ac4..95daf37a 100755
--- a/CPP/7zip/UI/FileManager/OpenCallback.cpp
+++ b/CPP/7zip/UI/FileManager/OpenCallback.cpp
@@ -8,6 +8,8 @@
#include "../../Common/FileStreams.h"
+#include "../Common/ZipRegistry.h"
+
#include "OpenCallback.h"
#include "PasswordDialog.h"
@@ -82,16 +84,15 @@ STDMETHODIMP COpenArchiveCallback::GetProperty(PROPID propID, PROPVARIANT *value
return S_OK;
}
-STDMETHODIMP COpenArchiveCallback::GetStream(const wchar_t *name,
- IInStream **inStream)
+STDMETHODIMP COpenArchiveCallback::GetStream(const wchar_t *name, IInStream **inStream)
{
*inStream = NULL;
if (_subArchiveMode)
return S_FALSE;
- NFile::NFind::CFileInfoW fileInfo;
+ NFile::NFind::CFileInfo fileInfo;
- UString fullPath = _folderPrefix + name;
+ FString fullPath = _folderPrefix + us2fs(name);
if (!fileInfo.Find(fullPath))
return S_FALSE;
_fileInfo = fileInfo;
@@ -111,6 +112,8 @@ STDMETHODIMP COpenArchiveCallback::CryptoGetTextPassword(BSTR *password)
if (!PasswordIsDefined)
{
CPasswordDialog dialog;
+ bool showPassword = NExtract::Read_ShowPassword();
+ dialog.ShowPassword = showPassword;
ProgressDialog.WaitCreating();
if (dialog.Create(ProgressDialog) == IDCANCEL)
@@ -118,6 +121,8 @@ STDMETHODIMP COpenArchiveCallback::CryptoGetTextPassword(BSTR *password)
Password = dialog.Password;
PasswordIsDefined = true;
+ if (dialog.ShowPassword != showPassword)
+ NExtract::Save_ShowPassword(dialog.ShowPassword);
}
return StringToBstr(Password, password);
}
diff --git a/CPP/7zip/UI/FileManager/OpenCallback.h b/CPP/7zip/UI/FileManager/OpenCallback.h
index 559eb8fc..a0c0167e 100755
--- a/CPP/7zip/UI/FileManager/OpenCallback.h
+++ b/CPP/7zip/UI/FileManager/OpenCallback.h
@@ -27,8 +27,8 @@ class COpenArchiveCallback:
public ICryptoGetTextPassword,
public CMyUnknownImp
{
- UString _folderPrefix;
- NWindows::NFile::NFind::CFileInfoW _fileInfo;
+ FString _folderPrefix;
+ NWindows::NFile::NFind::CFileInfo _fileInfo;
NWindows::NSynchronization::CCriticalSection _criticalSection;
bool _subArchiveMode;
UString _subArchiveName;
@@ -75,7 +75,7 @@ public:
_subArchiveMode = false;
}
*/
- void LoadFileInfo(const UString &folderPrefix, const UString &fileName)
+ void LoadFileInfo(const FString &folderPrefix, const FString &fileName)
{
_folderPrefix = folderPrefix;
if (!_fileInfo.Find(_folderPrefix + fileName))
diff --git a/CPP/7zip/UI/FileManager/OptionsDialog.cpp b/CPP/7zip/UI/FileManager/OptionsDialog.cpp
index 7a7e90fb..a1ef1b1d 100755
--- a/CPP/7zip/UI/FileManager/OptionsDialog.cpp
+++ b/CPP/7zip/UI/FileManager/OptionsDialog.cpp
@@ -24,7 +24,6 @@
#include "App.h"
#include "LangUtils.h"
#include "MyLoadMenu.h"
-#include "ProgramLocation.h"
#include "resource.h"
@@ -42,11 +41,10 @@ static void ShowMenuErrorMessage(const wchar_t *m)
static int DllRegisterServer2(const char *name)
{
- NWindows::NDLL::CLibrary lib;
+ NDLL::CLibrary lib;
- UString prefix;
- GetProgramFolderPath(prefix);
- if (!lib.Load(prefix + L"7-zip.dll"))
+ FString prefix = NDLL::GetModuleDirPrefix();
+ if (!lib.Load(prefix + FTEXT("7-zip.dll")))
{
ShowMenuErrorMessage(L"7-Zip cannot load 7-zip.dll");
return E_FAIL;
@@ -94,7 +92,7 @@ void OptionsDialog(HWND hwndOwner, HINSTANCE /* hInstance */)
CFoldersPage foldersPage;
CObjectVector<NControl::CPageInfo> pages;
- UINT32 langIDs[] = { 0x03010300,
+ const UInt32 langIDs[] = { 0x03010300,
// 0x03010100,
0xFFFFFFFF,
0x01000200, 0x03010200, 0x03010400, 0x01000400};
diff --git a/CPP/7zip/UI/FileManager/Panel.cpp b/CPP/7zip/UI/FileManager/Panel.cpp
index 27aa7a54..ebbe12b9 100755
--- a/CPP/7zip/UI/FileManager/Panel.cpp
+++ b/CPP/7zip/UI/FileManager/Panel.cpp
@@ -79,6 +79,7 @@ HRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id,
_mainWindow = mainWindow;
_processTimer = true;
_processNotify = true;
+ _processStatusBar = true;
_panelCallback = panelCallback;
_appState = appState;
@@ -91,8 +92,11 @@ HRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id,
if (!currentFolderPrefix.IsEmpty())
if (currentFolderPrefix[0] == L'.')
- if (!NFile::NDirectory::MyGetFullPathName(currentFolderPrefix, cfp))
- cfp = currentFolderPrefix;
+ {
+ FString cfpF;
+ if (NFile::NDirectory::MyGetFullPathName(us2fs(currentFolderPrefix), cfpF))
+ cfp = fs2us(cfpF);
+ }
RINOK(BindToPath(cfp, arcFormat, archiveIsOpened, encrypted));
if (!CreateEx(0, kClassName, 0, WS_CHILD | WS_VISIBLE,
@@ -104,7 +108,7 @@ HRESULT CPanel::Create(HWND mainWindow, HWND parentWindow, UINT id,
LRESULT CPanel::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
{
- switch(message)
+ switch (message)
{
case kShiftSelectMessage:
OnShiftSelectMessage();
@@ -117,12 +121,15 @@ LRESULT CPanel::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
return 0;
case kOpenItemChanged:
return OnOpenItemChanged(lParam);
- case kRefreshStatusBar:
- OnRefreshStatusBar();
+ case kRefresh_StatusBar:
+ if (_processStatusBar)
+ Refresh_StatusBar();
return 0;
- case kRefreshHeaderComboBox:
+ #ifdef UNDER_CE
+ case kRefresh_HeaderComboBox:
LoadFullPathAndShow();
return 0;
+ #endif
case WM_TIMER:
OnTimer();
return 0;
@@ -139,15 +146,6 @@ LRESULT CPanel::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
return CWindow2::OnMessage(message, wParam, lParam);
}
-static LRESULT APIENTRY ListViewSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- CWindow tempDialog(hwnd);
- CMyListView *w = (CMyListView *)(tempDialog.GetUserDataLongPtr());
- if (w == NULL)
- return 0;
- return w->OnMessage(message, wParam, lParam);
-}
-
LRESULT CMyListView::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_CHAR)
@@ -187,7 +185,7 @@ LRESULT CMyListView::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
// bool leftCtrl = (::GetKeyState(VK_LCONTROL) & 0x8000) != 0;
// bool RightCtrl = (::GetKeyState(VK_RCONTROL) & 0x8000) != 0;
bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
- switch(wParam)
+ switch (wParam)
{
/*
case VK_RETURN:
@@ -233,12 +231,7 @@ LRESULT CMyListView::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
_panel->_lastFocusedIsList = true;
_panel->_panelCallback->PanelWasFocused();
}
- #ifndef _UNICODE
- if (g_IsNT)
- return CallWindowProcW(_origWindowProc, *this, message, wParam, lParam);
- else
- #endif
- return CallWindowProc(_origWindowProc, *this, message, wParam, lParam);
+ return CListView2::OnMessage(message, wParam, lParam);
}
/*
@@ -365,21 +358,9 @@ bool CPanel::OnCreate(CREATESTRUCT * /* createStruct */)
HWND(*this), (HMENU)(UINT_PTR)(_baseID + 1), g_hInstance, NULL))
return false;
- #ifndef UNDER_CE
- _listView.SetUnicodeFormat(true);
- #endif
-
- _listView.SetUserDataLongPtr(LONG_PTR(&_listView));
+ _listView.SetUnicodeFormat();
_listView._panel = this;
-
- #ifndef _UNICODE
- if(g_IsNT)
- _listView._origWindowProc =
- (WNDPROC)_listView.SetLongPtrW(GWLP_WNDPROC, LONG_PTR(ListViewSubclassProc));
- else
- #endif
- _listView._origWindowProc =
- (WNDPROC)_listView.SetLongPtr(GWLP_WNDPROC, LONG_PTR(ListViewSubclassProc));
+ _listView.SetWindowProc();
_listView.SetImageList(GetSysImageList(true), LVSIL_SMALL);
_listView.SetImageList(GetSysImageList(false), LVSIL_NORMAL);
@@ -552,7 +533,6 @@ bool CPanel::OnCreate(CREATESTRUCT * /* createStruct */)
// InitListCtrl();
RefreshListCtrl();
- RefreshStatusBar();
return true;
}
@@ -614,7 +594,7 @@ bool CPanel::OnSize(WPARAM /* wParam */, int xSize, int ySize)
bool CPanel::OnNotifyReBar(LPNMHDR header, LRESULT & /* result */)
{
- switch(header->code)
+ switch (header->code)
{
case RBN_HEIGHTCHANGE:
{
@@ -790,9 +770,10 @@ void CPanel::ChangeFlatMode()
}
-void CPanel::RefreshStatusBar()
+void CPanel::Post_Refresh_StatusBar()
{
- PostMessage(kRefreshStatusBar);
+ if (_processStatusBar)
+ PostMessage(kRefresh_StatusBar);
}
void CPanel::AddToArchive()
@@ -953,6 +934,12 @@ void CPanel::TestArchives()
extracter.ExtractCallbackSpec = new CExtractCallbackImp;
extracter.ExtractCallback = extracter.ExtractCallbackSpec;
extracter.ExtractCallbackSpec->ProgressDialog = &extracter.ProgressDialog;
+ if (!_parentFolders.IsEmpty())
+ {
+ const CFolderLink &fl = _parentFolders.Back();
+ extracter.ExtractCallbackSpec->PasswordIsDefined = fl.UsePassword;
+ extracter.ExtractCallbackSpec->Password = fl.Password;
+ }
if (indices.IsEmpty())
return;
diff --git a/CPP/7zip/UI/FileManager/Panel.h b/CPP/7zip/UI/FileManager/Panel.h
index 9cda94a4..e33a37a2 100755
--- a/CPP/7zip/UI/FileManager/Panel.h
+++ b/CPP/7zip/UI/FileManager/Panel.h
@@ -85,13 +85,14 @@ public:
struct CTempFileInfo
{
- UString ItemName;
- UString FolderPath;
- UString FilePath;
- NWindows::NFile::NFind::CFileInfoW FileInfo;
+ UInt32 FileIndex; // index of file in folder
+ UString RelPath; // Relative path of file from Folder
+ FString FolderPath;
+ FString FilePath;
+ NWindows::NFile::NFind::CFileInfo FileInfo;
bool NeedDelete;
- CTempFileInfo(): NeedDelete(false) {}
+ CTempFileInfo(): FileIndex((UInt32)(Int32)-1), NeedDelete(false) {}
void DeleteDirAndFile() const
{
if (NeedDelete)
@@ -100,7 +101,7 @@ struct CTempFileInfo
NWindows::NFile::NDirectory::MyRemoveDirectory(FolderPath);
}
}
- bool WasChanged(const NWindows::NFile::NFind::CFileInfoW &newFileInfo) const
+ bool WasChanged(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const
{
return newFileInfo.Size != FileInfo.Size ||
CompareFileTime(&newFileInfo.MTime, &FileInfo.MTime) != 0;
@@ -118,7 +119,7 @@ struct CFolderLink: public CTempFileInfo
UString VirtualPath;
CFolderLink(): UsePassword(false), IsVirtual(false) {}
- bool WasChanged(const NWindows::NFile::NFind::CFileInfoW &newFileInfo) const
+ bool WasChanged(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const
{
return IsVirtual || CTempFileInfo::WasChanged(newFileInfo);
}
@@ -131,18 +132,19 @@ enum MyMessages
kReLoadMessage,
kSetFocusToListView,
kOpenItemChanged,
- kRefreshStatusBar,
- kRefreshHeaderComboBox
+ kRefresh_StatusBar
+ #ifdef UNDER_CE
+ , kRefresh_HeaderComboBox
+ #endif
};
UString GetFolderPath(IFolderFolder * folder);
class CPanel;
-class CMyListView: public NWindows::NControl::CListView
+class CMyListView: public NWindows::NControl::CListView2
{
public:
- WNDPROC _origWindowProc;
CPanel *_panel;
LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
};
@@ -482,34 +484,33 @@ public:
bool _processTimer;
bool _processNotify;
+ bool _processStatusBar;
class CDisableTimerProcessing
{
bool _processTimerMem;
bool _processNotifyMem;
+ bool _processStatusBarMem;
CPanel &_panel;
public:
- CDisableTimerProcessing(CPanel &panel): _panel(panel)
- {
- Disable();
- }
+ CDisableTimerProcessing(CPanel &panel): _panel(panel) { Disable(); }
+ ~CDisableTimerProcessing() { Restore(); }
void Disable()
{
_processTimerMem = _panel._processTimer;
_processNotifyMem = _panel._processNotify;
+ _processStatusBarMem = _panel._processStatusBar;
_panel._processTimer = false;
_panel._processNotify = false;
+ _panel._processStatusBar = false;
}
void Restore()
{
_panel._processTimer = _processTimerMem;
_panel._processNotify = _processNotifyMem;
- }
- ~CDisableTimerProcessing()
- {
- Restore();
+ _panel._processStatusBar = _processStatusBarMem;
}
CDisableTimerProcessing& operator=(const CDisableTimerProcessing &) {; }
};
@@ -544,11 +545,11 @@ public:
const UString &virtualFilePath,
const UString &arcFormat,
bool &encrypted);
- HRESULT OpenItemAsArchive(const UString &name, const UString &arcFormat, bool &encrypted);
+ HRESULT OpenItemAsArchive(const UString &relPath, const UString &arcFormat, bool &encrypted);
HRESULT OpenItemAsArchive(int index);
void OpenItemInArchive(int index, bool tryInternal, bool tryExternal,
bool editMode);
- HRESULT OnOpenItemChanged(const UString &folderPath, const UString &itemName, bool usePassword, const UString &password);
+ HRESULT OnOpenItemChanged(UInt32 index, const wchar_t *fullFilePath, bool usePassword, const UString &password);
LRESULT OnOpenItemChanged(LPARAM lParam);
void OpenItem(int index, bool tryInternal, bool tryExternal);
@@ -565,8 +566,8 @@ public:
void ChangeFlatMode();
bool GetFlatMode() const { return _flatMode; }
- void RefreshStatusBar();
- void OnRefreshStatusBar();
+ void Post_Refresh_StatusBar();
+ void Refresh_StatusBar();
void AddToArchive();
diff --git a/CPP/7zip/UI/FileManager/PanelCrc.cpp b/CPP/7zip/UI/FileManager/PanelCrc.cpp
index 6b00a9b5..2dd5e7ce 100755
--- a/CPP/7zip/UI/FileManager/PanelCrc.cpp
+++ b/CPP/7zip/UI/FileManager/PanelCrc.cpp
@@ -29,13 +29,13 @@ static const UInt32 kBufSize = (1 << 15);
struct CDirEnumerator
{
bool FlatMode;
- UString BasePrefix;
- UStringVector FileNames;
+ FString BasePrefix;
+ FStringVector FileNames;
- CObjectVector<NFind::CEnumeratorW> Enumerators;
- UStringVector Prefixes;
+ CObjectVector<NFind::CEnumerator> Enumerators;
+ FStringVector Prefixes;
int Index;
- HRESULT GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, UString &fullPath);
+ HRESULT GetNextFile(NFind::CFileInfo &fileInfo, bool &filled, FString &fullPath);
void Init();
CDirEnumerator(): FlatMode(false) {};
@@ -54,7 +54,7 @@ static HRESULT GetNormalizedError()
return (errorCode == 0) ? E_FAIL : errorCode;
}
-HRESULT CDirEnumerator::GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, UString &resPath)
+HRESULT CDirEnumerator::GetNextFile(NFind::CFileInfo &fileInfo, bool &filled, FString &resPath)
{
filled = false;
for (;;)
@@ -63,8 +63,8 @@ HRESULT CDirEnumerator::GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, U
{
if (Index >= FileNames.Size())
return S_OK;
- const UString &path = FileNames[Index];
- int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR);
+ const FString &path = FileNames[Index];
+ int pos = path.ReverseFind(FCHAR_PATH_SEPARATOR);
resPath.Empty();
if (pos >= 0)
resPath = path.Left(pos + 1);
@@ -106,8 +106,8 @@ HRESULT CDirEnumerator::GetNextFile(NFind::CFileInfoW &fileInfo, bool &filled, U
resPath += fileInfo.Name;
if (!FlatMode && fileInfo.IsDir())
{
- UString prefix = resPath + WCHAR_PATH_SEPARATOR;
- Enumerators.Add(NFind::CEnumeratorW(BasePrefix + prefix + (UString)(wchar_t)NName::kAnyStringWildcard));
+ FString prefix = resPath + FCHAR_PATH_SEPARATOR;
+ Enumerators.Add(NFind::CEnumerator(BasePrefix + prefix + FCHAR_ANY_MASK));
Prefixes.Add(prefix);
}
filled = true;
@@ -212,13 +212,13 @@ HRESULT CThreadCrc::ProcessVirt()
for (;;)
{
- NFind::CFileInfoW fileInfo;
+ NFind::CFileInfo fileInfo;
bool filled;
- UString resPath;
+ FString resPath;
HRESULT errorCode = Enumerator.GetNextFile(fileInfo, filled, resPath);
if (errorCode != 0)
{
- ErrorPath1 = resPath;
+ SetErrorPath1(resPath);
return errorCode;
}
if (!filled)
@@ -228,7 +228,7 @@ HRESULT CThreadCrc::ProcessVirt()
totalSize += fileInfo.Size;
NumFilesScan++;
}
- sync.SetCurrentFileName(scanningStr + resPath);
+ sync.SetCurrentFileName(scanningStr + fs2us(resPath));
sync.SetProgress(totalSize, 0);
RINOK(sync.SetPosAndCheckPaused(0));
}
@@ -239,13 +239,13 @@ HRESULT CThreadCrc::ProcessVirt()
for (;;)
{
- NFind::CFileInfoW fileInfo;
+ NFind::CFileInfo fileInfo;
bool filled;
- UString resPath;
+ FString resPath;
HRESULT errorCode = Enumerator.GetNextFile(fileInfo, filled, resPath);
if (errorCode != 0)
{
- ErrorPath1 = resPath;
+ SetErrorPath1(resPath);
return errorCode;
}
if (!filled)
@@ -263,10 +263,10 @@ HRESULT CThreadCrc::ProcessVirt()
if (!inFile.Open(Enumerator.BasePrefix + resPath))
{
errorCode = GetNormalizedError();
- ErrorPath1 = resPath;
+ SetErrorPath1(resPath);
return errorCode;
}
- sync.SetCurrentFileName(resPath);
+ sync.SetCurrentFileName(fs2us(resPath));
sync.SetNumFilesCur(NumFiles);
NumFiles++;
for (;;)
@@ -275,7 +275,7 @@ HRESULT CThreadCrc::ProcessVirt()
if (!inFile.Read(buffer, kBufSize, processedSize))
{
errorCode = GetNormalizedError();
- ErrorPath1 = resPath;
+ SetErrorPath1(resPath);
return errorCode;
}
if (processedSize == 0)
@@ -323,8 +323,8 @@ void CApp::CalculateCrc()
{
CThreadCrc t;
for (int i = 0; i < indices.Size(); i++)
- t.Enumerator.FileNames.Add(srcPanel.GetItemRelPath(indices[i]));
- t.Enumerator.BasePrefix = srcPanel.GetFsPath();
+ t.Enumerator.FileNames.Add(us2fs(srcPanel.GetItemRelPath(indices[i])));
+ t.Enumerator.BasePrefix = us2fs(srcPanel.GetFsPath());
t.Enumerator.FlatMode = GetFlatMode();
t.ProgressDialog.ShowCompressionInfo = false;
diff --git a/CPP/7zip/UI/FileManager/PanelDrag.cpp b/CPP/7zip/UI/FileManager/PanelDrag.cpp
index eb5ad871..02bccc03 100755
--- a/CPP/7zip/UI/FileManager/PanelDrag.cpp
+++ b/CPP/7zip/UI/FileManager/PanelDrag.cpp
@@ -10,6 +10,7 @@
#include "Windows/Memory.h"
#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
#include "Windows/Shell.h"
#include "../Common/ArchiveName.h"
@@ -26,7 +27,7 @@ using namespace NWindows;
extern bool g_IsNT;
#endif
-static wchar_t *kTempDirPrefix = L"7zE";
+static CFSTR kTempDirPrefix = FTEXT("7zE");
static LPCTSTR kSvenZipSetFolderFormat = TEXT("7-Zip::SetTargetFolder");
////////////////////////////////////////////////////////
@@ -304,12 +305,12 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
// CSelectedState selState;
// SaveSelectedState(selState);
- UString dirPrefix;
- NFile::NDirectory::CTempDirectoryW tempDirectory;
+ FString dirPrefix;
+ NFile::NDirectory::CTempDir tempDirectory;
bool isFSFolder = IsFSFolder();
if (isFSFolder)
- dirPrefix = _currentFolderPrefix;
+ dirPrefix = us2fs(_currentFolderPrefix);
else
{
tempDirectory.Create(kTempDirPrefix);
@@ -330,7 +331,7 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
s = GetItemRelPath(index);
else
s = GetItemName(index);
- names.Add(dirPrefix + s);
+ names.Add(fs2us(dirPrefix) + s);
}
if (!CopyNamesToHGlobal(dataObjectSpec->hGlobal, names))
return;
@@ -341,7 +342,7 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
dropSourceSpec->NeedExtract = !isFSFolder;
dropSourceSpec->Panel = this;
dropSourceSpec->Indices = indices;
- dropSourceSpec->Folder = dirPrefix;
+ dropSourceSpec->Folder = fs2us(dirPrefix);
dropSourceSpec->DataObjectSpec = dataObjectSpec;
dropSourceSpec->DataObject = dataObjectSpec;
@@ -748,9 +749,9 @@ void CPanel::CompressDropFiles(HDROP dr)
}
*/
-static bool IsFolderInTemp(const UString &path)
+static bool IsFolderInTemp(const FString &path)
{
- UString tempPath;
+ FString tempPath;
if (!NFile::NDirectory::MyGetTempPath(tempPath))
return false;
if (tempPath.IsEmpty())
@@ -760,9 +761,10 @@ static bool IsFolderInTemp(const UString &path)
static bool AreThereNamesFromTemp(const UStringVector &fileNames)
{
- UString tempPath;
- if (!NFile::NDirectory::MyGetTempPath(tempPath))
+ FString tempPathF;
+ if (!NFile::NDirectory::MyGetTempPath(tempPathF))
return false;
+ UString tempPath = fs2us(tempPathF);
if (tempPath.IsEmpty())
return false;
for (int i = 0; i < fileNames.Size(); i++)
@@ -784,8 +786,10 @@ void CPanel::CompressDropFiles(const UStringVector &fileNames, const UString &fo
UString folderPath2 = folderPath;
if (folderPath2.IsEmpty())
{
- NFile::NDirectory::GetOnlyDirPrefix(fileNames.Front(), folderPath2);
- if (IsFolderInTemp(folderPath2))
+ FString folderPath2F;
+ NFile::NDirectory::GetOnlyDirPrefix(us2fs(fileNames.Front()), folderPath2F);
+ folderPath2 = fs2us(folderPath2F);
+ if (IsFolderInTemp(folderPath2F))
folderPath2 = ROOT_FS_FOLDER;
}
const UString archiveName = CreateArchiveName(fileNames.Front(), (fileNames.Size() > 1), false);
diff --git a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
index afa4c041..995124be 100755
--- a/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
+++ b/CPP/7zip/UI/FileManager/PanelFolderChange.cpp
@@ -5,6 +5,7 @@
#include "Common/StringConvert.h"
#include "Common/Wildcard.h"
+#include "Windows/FileName.h"
#include "Windows/PropVariant.h"
#include "../../PropID.h"
@@ -73,11 +74,11 @@ HRESULT CPanel::BindToPath(const UString &fullPath, const UString &arcFormat, bo
CloseOpenFolders();
UString sysPath = fullPath;
- CFileInfoW fileInfo;
+ CFileInfo fileInfo;
UStringVector reducedParts;
while (!sysPath.IsEmpty())
{
- if (fileInfo.Find(sysPath))
+ if (fileInfo.Find(us2fs(sysPath)))
break;
int pos = sysPath.ReverseFind(WCHAR_PATH_SEPARATOR);
if (pos < 0)
@@ -104,17 +105,14 @@ HRESULT CPanel::BindToPath(const UString &fullPath, const UString &arcFormat, bo
}
else
{
- UString dirPrefix;
- if (!NDirectory::GetOnlyDirPrefix(sysPath, dirPrefix))
- dirPrefix.Empty();
- if (_folder->BindToFolder(dirPrefix, &newFolder) == S_OK)
+ FString dirPrefix, fileName;
+ NDirectory::GetFullPathAndSplit(us2fs(sysPath), dirPrefix, fileName);
+ if (_folder->BindToFolder(fs2us(dirPrefix), &newFolder) == S_OK)
{
_folder = newFolder;
LoadFullPath();
- UString fileName;
- if (NDirectory::GetOnlyName(sysPath, fileName))
{
- HRESULT res = OpenItemAsArchive(fileName, arcFormat, encrypted);
+ HRESULT res = OpenItemAsArchive(fs2us(fileName), arcFormat, encrypted);
if (res != S_FALSE)
{
RINOK(res);
@@ -176,14 +174,14 @@ void CPanel::LoadFullPath()
{
const CFolderLink &folderLink = _parentFolders[i];
_currentFolderPrefix += GetFolderPath(folderLink.ParentFolder);
- _currentFolderPrefix += folderLink.ItemName;
+ _currentFolderPrefix += folderLink.RelPath;
_currentFolderPrefix += WCHAR_PATH_SEPARATOR;
}
if (_folder)
_currentFolderPrefix += GetFolderPath(_folder);
}
-static int GetRealIconIndex(LPCWSTR path, DWORD attributes)
+static int GetRealIconIndex(CFSTR path, DWORD attributes)
{
int index = -1;
if (GetRealIconIndex(path, attributes, index) != 0)
@@ -209,15 +207,22 @@ void CPanel::LoadFullPathAndShow()
#else
1
#endif
- && path[path.Length() - 1] == WCHAR_PATH_SEPARATOR)
- path.Delete(path.Length() - 1);
+ && path.Back() == WCHAR_PATH_SEPARATOR)
+ path.DeleteBack();
- CFileInfoW info;
DWORD attrib = FILE_ATTRIBUTE_DIRECTORY;
- if (info.Find(path))
- attrib = info.Attrib;
-
- item.iImage = GetRealIconIndex(path, attrib);
+
+ // GetRealIconIndex is slow for direct DVD/UDF path. So we use dummy path
+ UString excludePrefix = L"\\\\.\\";
+ UString path2 = L"_TestFolder_";
+ if (excludePrefix != path.Left(excludePrefix.Length()))
+ {
+ path2 = path;
+ CFileInfo info;
+ if (info.Find(us2fs(path)))
+ attrib = info.Attrib;
+ }
+ item.iImage = GetRealIconIndex(us2fs(path2), attrib);
if (item.iImage >= 0)
{
@@ -356,11 +361,11 @@ bool CPanel::OnComboBoxCommand(UINT code, LPARAM /* param */, LRESULT &result)
UString name = pathParts[i];
sumPass += name;
sumPass += WCHAR_PATH_SEPARATOR;
- CFileInfoW info;
+ CFileInfo info;
DWORD attrib = FILE_ATTRIBUTE_DIRECTORY;
- if (info.Find(sumPass))
+ if (info.Find(us2fs(sumPass)))
attrib = info.Attrib;
- AddComboBoxItem(name.IsEmpty() ? L"\\" : name, GetRealIconIndex(sumPass, attrib), i, false);
+ AddComboBoxItem(name.IsEmpty() ? L"\\" : name, GetRealIconIndex(us2fs(sumPass), attrib), i, false);
ComboBoxPaths.Add(sumPass);
}
@@ -374,16 +379,16 @@ bool CPanel::OnComboBoxCommand(UINT code, LPARAM /* param */, LRESULT &result)
name = RootFolder_GetName_Computer(iconIndex);
AddComboBoxItem(name, iconIndex, 0, true);
- UStringVector driveStrings;
+ FStringVector driveStrings;
MyGetLogicalDriveStrings(driveStrings);
for (i = 0; i < driveStrings.Size(); i++)
{
- UString s = driveStrings[i];
- ComboBoxPaths.Add(s);
+ FString s = driveStrings[i];
+ ComboBoxPaths.Add(fs2us(s));
int iconIndex = GetRealIconIndex(s, 0);
- if (s.Length() > 0 && s[s.Length() - 1] == WCHAR_PATH_SEPARATOR)
- s.Delete(s.Length() - 1);
- AddComboBoxItem(s, iconIndex, 1, false);
+ if (s.Length() > 0 && s.Back() == FCHAR_PATH_SEPARATOR)
+ s.DeleteBack();
+ AddComboBoxItem(fs2us(s), iconIndex, 1, false);
}
name = RootFolder_GetName_Network(iconIndex);
@@ -407,9 +412,8 @@ bool CPanel::OnComboBoxCommand(UINT code, LPARAM /* param */, LRESULT &result)
{
PostMessage(kSetFocusToListView);
#ifdef UNDER_CE
- PostMessage(kRefreshHeaderComboBox);
+ PostMessage(kRefresh_HeaderComboBox);
#endif
-
return true;
}
}
@@ -522,7 +526,7 @@ void CPanel::OpenParentFolder()
CFolderLink &link = _parentFolders.Back();
_folder = link.ParentFolder;
_library.Attach(link.Library.Detach());
- focucedName = link.ItemName;
+ focucedName = link.RelPath;
if (_parentFolders.Size() > 1)
OpenParentArchiveFolder();
_parentFolders.DeleteBack();
@@ -540,7 +544,6 @@ void CPanel::OpenParentFolder()
// ::SetCurrentDirectory(::_currentFolderPrefix);
RefreshListCtrl(focucedName, -1, true, selectedItems);
_listView.EnsureVisible(_listView.GetFocusedItem(), false);
- RefreshStatusBar();
}
void CPanel::CloseOpenFolders()
@@ -607,7 +610,6 @@ void CPanel::OpenFolder(int index)
LoadFullPath();
// ::SetCurrentDirectory(::_currentFolderPrefix);
RefreshListCtrl();
- UINT state = LVIS_SELECTED;
- _listView.SetItemState(_listView.GetFocusedItem(), state, state);
+ _listView.SetItemState_Selected(_listView.GetFocusedItem());
_listView.EnsureVisible(_listView.GetFocusedItem(), false);
}
diff --git a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
index 934e98d3..6c4309c6 100755
--- a/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
+++ b/CPP/7zip/UI/FileManager/PanelItemOpen.cpp
@@ -2,12 +2,15 @@
#include "StdAfx.h"
+#include <tlhelp32.h>
+
#include "Common/AutoPtr.h"
#include "Common/StringConvert.h"
#include "Windows/Error.h"
#include "Windows/FileDir.h"
#include "Windows/FileFind.h"
+#include "Windows/FileName.h"
#include "Windows/Process.h"
#include "Windows/PropVariant.h"
#include "Windows/Thread.h"
@@ -33,8 +36,122 @@ using namespace NDirectory;
extern bool g_IsNT;
#endif
-static wchar_t *kTempDirPrefix = L"7zO";
+static CFSTR kTempDirPrefix = FTEXT("7zO");
+
+#ifndef UNDER_CE
+
+class CProcessSnapshot
+{
+ HANDLE _handle;
+public:
+ CProcessSnapshot(): _handle(INVALID_HANDLE_VALUE) {};
+ ~CProcessSnapshot() { Close(); }
+
+ bool Close()
+ {
+ if (_handle == INVALID_HANDLE_VALUE)
+ return true;
+ if (!::CloseHandle(_handle))
+ return false;
+ _handle = INVALID_HANDLE_VALUE;
+ return true;
+ }
+
+ bool Create()
+ {
+ _handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ return (_handle != INVALID_HANDLE_VALUE);
+ }
+
+ bool GetFirstProcess(PROCESSENTRY32 *pe) { return BOOLToBool(Process32First(_handle, pe)); }
+ bool GetNextProcess(PROCESSENTRY32 *pe) { return BOOLToBool(Process32Next(_handle, pe)); }
+};
+
+#endif
+
+typedef DWORD (WINAPI *GetProcessIdFunc)(HANDLE process);
+
+class CChildProcesses
+{
+ #ifndef UNDER_CE
+ CRecordVector<DWORD> _ids;
+ #endif
+public:
+ CRecordVector<HANDLE> Handles;
+ CRecordVector<bool> NeedWait;
+
+ ~CChildProcesses() { CloseAll(); }
+ void DisableWait(int index) { NeedWait[index] = false; }
+
+ void CloseAll()
+ {
+ for (int i = 0; i < Handles.Size(); i++)
+ {
+ HANDLE h = Handles[i];
+ if (h != NULL)
+ CloseHandle(h);
+ }
+ Handles.Clear();
+ NeedWait.Clear();
+ }
+
+ void AddProcess(HANDLE h)
+ {
+ #ifndef UNDER_CE
+ GetProcessIdFunc func = (GetProcessIdFunc)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "GetProcessId");
+ if (func)
+ _ids.AddToUniqueSorted(func(h));
+ #endif
+ Handles.Add(h);
+ NeedWait.Add(true);
+ }
+
+ void Update()
+ {
+ #ifndef UNDER_CE
+ CRecordVector<DWORD> ids, parents;
+ {
+ CProcessSnapshot snapshot;
+ if (snapshot.Create())
+ {
+ PROCESSENTRY32 pe;
+ memset(&pe, 0, sizeof(pe));
+ pe.dwSize = sizeof(pe);
+ BOOL res = snapshot.GetFirstProcess(&pe);
+ while (res)
+ {
+ ids.Add(pe.th32ProcessID);
+ parents.Add(pe.th32ParentProcessID);
+ res = snapshot.GetNextProcess(&pe);
+ }
+ }
+ }
+ for (;;)
+ {
+ int i;
+ for (i = 0; i < ids.Size(); i++)
+ {
+ DWORD id = ids[i];
+ if (_ids.FindInSorted(parents[i]) >= 0 &&
+ _ids.FindInSorted(id) < 0)
+ {
+ HANDLE hProcess = OpenProcess(SYNCHRONIZE, FALSE, id);
+ if (hProcess)
+ {
+ _ids.AddToUniqueSorted(id);
+ Handles.Add(hProcess);
+ NeedWait.Add(true);
+ break;
+ }
+ }
+ }
+ if (i == ids.Size())
+ break;
+ }
+ #endif
+ }
+};
static bool IsNameVirus(const UString &name)
{
@@ -43,11 +160,12 @@ static bool IsNameVirus(const UString &name)
struct CTmpProcessInfo: public CTempFileInfo
{
- HANDLE ProcessHandle;
+ CChildProcesses Processes;
HWND Window;
UString FullPathFolderPrefix;
bool UsePassword;
UString Password;
+
CTmpProcessInfo(): UsePassword(false) {}
};
@@ -56,8 +174,8 @@ class CTmpProcessInfoRelease
CTmpProcessInfo *_tmpProcessInfo;
public:
bool _needDelete;
- CTmpProcessInfoRelease(CTmpProcessInfo &tmpProcessInfo):
- _tmpProcessInfo(&tmpProcessInfo), _needDelete(true) {}
+ CTmpProcessInfoRelease(CTmpProcessInfo &tpi):
+ _tmpProcessInfo(&tpi), _needDelete(true) {}
~CTmpProcessInfoRelease()
{
if (_needDelete)
@@ -96,7 +214,7 @@ HRESULT CPanel::OpenItemAsArchive(IInStream *inStream,
UString password;
RINOK(OpenFileFolderPlugin(inStream,
- folderLink.FilePath.IsEmpty() ? virtualFilePath : folderLink.FilePath,
+ folderLink.FilePath.IsEmpty() ? us2fs(virtualFilePath) : folderLink.FilePath,
arcFormat,
&library, &newFolder, GetParent(), encrypted, password));
@@ -157,13 +275,14 @@ HRESULT CPanel::OpenItemAsArchive(IInStream *inStream,
return S_OK;
}
-HRESULT CPanel::OpenItemAsArchive(const UString &name, const UString &arcFormat, bool &encrypted)
+HRESULT CPanel::OpenItemAsArchive(const UString &relPath, const UString &arcFormat, bool &encrypted)
{
CTempFileInfo tfi;
- tfi.ItemName = name;
- tfi.FolderPath = _currentFolderPrefix;
- tfi.FilePath = _currentFolderPrefix + name;
- return OpenItemAsArchive(NULL, tfi, _currentFolderPrefix + name, arcFormat, encrypted);
+ tfi.RelPath = relPath;
+ tfi.FolderPath = us2fs(_currentFolderPrefix);
+ const UString fullPath = _currentFolderPrefix + relPath;
+ tfi.FilePath = us2fs(fullPath);
+ return OpenItemAsArchive(NULL, tfi, fullPath, arcFormat, encrypted);
}
HRESULT CPanel::OpenItemAsArchive(int index)
@@ -180,21 +299,21 @@ HRESULT CPanel::OpenParentArchiveFolder()
CDisableTimerProcessing disableTimerProcessing1(*this);
if (_parentFolders.Size() < 2)
return S_OK;
+ const CFolderLink &folderLinkPrev = _parentFolders[_parentFolders.Size() - 2];
const CFolderLink &folderLink = _parentFolders.Back();
- NFind::CFileInfoW newFileInfo;
+ NFind::CFileInfo newFileInfo;
if (newFileInfo.Find(folderLink.FilePath))
{
if (folderLink.WasChanged(newFileInfo))
{
- UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE,
- 0x03020280, folderLink.ItemName);
+ UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, 0x03020280, folderLink.RelPath);
if (::MessageBoxW(HWND(*this), message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
{
- if (OnOpenItemChanged(folderLink.FolderPath, folderLink.ItemName,
- folderLink.UsePassword, folderLink.Password) != S_OK)
+ if (OnOpenItemChanged(folderLink.FileIndex, folderLink.FilePath,
+ folderLinkPrev.UsePassword, folderLinkPrev.Password) != S_OK)
{
::MessageBoxW(HWND(*this), MyFormatNew(IDS_CANNOT_UPDATE_FILE,
- 0x03020281, folderLink.FilePath), L"7-Zip", MB_OK | MB_ICONSTOP);
+ 0x03020281, fs2us(folderLink.FilePath)), L"7-Zip", MB_OK | MB_ICONSTOP);
return S_OK;
}
}
@@ -263,9 +382,11 @@ static HRESULT StartEditApplication(const UString &path, HWND window, CProcess &
#ifdef UNDER_CE
command = L"\\Windows\\";
#else
- if (!MyGetWindowsDirectory(command))
+ FString winDir;
+ if (!MyGetWindowsDirectory(winDir))
return 0;
- NFile::NName::NormalizeDirPathPrefix(command);
+ NFile::NName::NormalizeDirPathPrefix(winDir);
+ command = fs2us(winDir);
#endif
command += L"notepad.exe";
}
@@ -466,8 +587,8 @@ class CThreadCopyFrom: public CProgressThreadVirt
{
HRESULT ProcessVirt();
public:
- UString PathPrefix;
- UString Name;
+ UString FullPath;
+ UInt32 ItemIndex;
CMyComPtr<IFolderOperations> FolderOperations;
CMyComPtr<IProgress> UpdateCallback;
@@ -476,14 +597,10 @@ public:
HRESULT CThreadCopyFrom::ProcessVirt()
{
- UStringVector fileNames;
- CRecordVector<const wchar_t *> fileNamePointers;
- fileNames.Add(Name);
- fileNamePointers.Add(fileNames[0]);
- return FolderOperations->CopyFrom(PathPrefix, &fileNamePointers.Front(), fileNamePointers.Size(), UpdateCallback);
+ return FolderOperations->CopyFromFile(ItemIndex, FullPath, UpdateCallback);
}
-HRESULT CPanel::OnOpenItemChanged(const UString &folderPath, const UString &itemName,
+HRESULT CPanel::OnOpenItemChanged(UInt32 index, const wchar_t *fullFilePath,
bool usePassword, const UString &password)
{
CMyComPtr<IFolderOperations> folderOperations;
@@ -497,41 +614,48 @@ HRESULT CPanel::OnOpenItemChanged(const UString &folderPath, const UString &item
t.UpdateCallbackSpec = new CUpdateCallback100Imp;
t.UpdateCallback = t.UpdateCallbackSpec;
t.UpdateCallbackSpec->ProgressDialog = &t.ProgressDialog;
- t.Name = itemName;
- t.PathPrefix = folderPath;
- NName::NormalizeDirPathPrefix(t.PathPrefix);
+ t.ItemIndex = index;
+ t.FullPath = fullFilePath;
t.FolderOperations = folderOperations;
t.UpdateCallbackSpec->Init(usePassword, password);
- RINOK(t.Create(itemName, (HWND)*this));
+ RINOK(t.Create(GetItemName(index), (HWND)*this));
return t.Result;
}
LRESULT CPanel::OnOpenItemChanged(LPARAM lParam)
{
- CTmpProcessInfo &tmpProcessInfo = *(CTmpProcessInfo *)lParam;
- // LoadCurrentPath()
- if (tmpProcessInfo.FullPathFolderPrefix != _currentFolderPrefix)
+ CTmpProcessInfo &tpi = *(CTmpProcessInfo *)lParam;
+ if (tpi.FullPathFolderPrefix != _currentFolderPrefix)
return 0;
+ UInt32 fileIndex = tpi.FileIndex;
+ UInt32 numItems;
+ _folder->GetNumberOfItems(&numItems);
+
+ // This code is not 100% OK for cases when there are several files with
+ // tpi.RelPath name and there are changes in archive before update.
+ // So tpi.FileIndex can point to another file.
+
+ if (fileIndex >= numItems || GetItemRelPath(fileIndex) != tpi.RelPath)
+ {
+ UInt32 i;
+ for (i = 0; i < numItems; i++)
+ if (GetItemRelPath(i) == tpi.RelPath)
+ break;
+ if (i == numItems)
+ return 0;
+ fileIndex = i;
+ }
CSelectedState state;
SaveSelectedState(state);
- HRESULT result = OnOpenItemChanged(tmpProcessInfo.FolderPath, tmpProcessInfo.ItemName,
- tmpProcessInfo.UsePassword, tmpProcessInfo.Password);
+ HRESULT result = OnOpenItemChanged(fileIndex, tpi.FilePath, tpi.UsePassword, tpi.Password);
if (result != S_OK)
return 0;
RefreshListCtrl(state);
return 1;
}
-/*
-class CTmpProcessInfoList
-{
-public:
- CObjectVector<CTmpProcessInfo> _items;
-} g_TmpProcessInfoList;
-*/
-
class CExitEventLauncher
{
public:
@@ -547,42 +671,64 @@ public:
static THREAD_FUNC_DECL MyThreadFunction(void *param)
{
CMyAutoPtr<CTmpProcessInfo> tmpProcessInfoPtr((CTmpProcessInfo *)param);
- const CTmpProcessInfo *tmpProcessInfo = tmpProcessInfoPtr.get();
+ CTmpProcessInfo *tpi = tmpProcessInfoPtr.get();
+ CChildProcesses &processes = tpi->Processes;
- HANDLE hProcess = tmpProcessInfo->ProcessHandle;
- HANDLE events[2] = { g_ExitEventLauncher._exitEvent, hProcess};
- DWORD waitResult = ::WaitForMultipleObjects(2, events, FALSE, INFINITE);
- ::CloseHandle(hProcess);
- if (waitResult == WAIT_OBJECT_0 + 0)
- return 0;
- if (waitResult != WAIT_OBJECT_0 + 1)
- return 1;
- Sleep(200);
- NFind::CFileInfoW newFileInfo;
- if (newFileInfo.Find(tmpProcessInfo->FilePath))
+ for (;;)
+ {
+ CRecordVector<HANDLE> handles;
+ CRecordVector<int> indices;
+ for (int i = 0; i < processes.Handles.Size(); i++)
+ {
+ if (processes.NeedWait[i])
+ {
+ handles.Add(processes.Handles[i]);
+ indices.Add(i);
+ }
+ }
+ if (handles.IsEmpty())
+ break;
+
+ handles.Add(g_ExitEventLauncher._exitEvent);
+
+ DWORD waitResult = ::WaitForMultipleObjects(handles.Size(), &handles.Front(), FALSE, INFINITE);
+
+ if (waitResult >= (DWORD)handles.Size() - 1)
+ {
+ processes.CloseAll();
+ return waitResult >= (DWORD)handles.Size() ? 1 : 0;
+ }
+ processes.Update();
+ processes.DisableWait(indices[waitResult]);
+ }
+
+ NFind::CFileInfo newFileInfo;
+ if (newFileInfo.Find(tpi->FilePath))
{
- if (tmpProcessInfo->WasChanged(newFileInfo))
+ if (tpi->WasChanged(newFileInfo))
{
UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE,
- 0x03020280, tmpProcessInfo->ItemName);
+ 0x03020280, tpi->RelPath);
if (::MessageBoxW(g_HWND, message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
{
- if (SendMessage(tmpProcessInfo->Window, kOpenItemChanged, 0, (LONG_PTR)tmpProcessInfo) != 1)
+ if (SendMessage(tpi->Window, kOpenItemChanged, 0, (LONG_PTR)tpi) != 1)
{
::MessageBoxW(g_HWND, MyFormatNew(IDS_CANNOT_UPDATE_FILE,
- 0x03020281, tmpProcessInfo->FilePath), L"7-Zip", MB_OK | MB_ICONSTOP);
+ 0x03020281, fs2us(tpi->FilePath)), L"7-Zip", MB_OK | MB_ICONSTOP);
return 0;
}
}
}
}
- tmpProcessInfo->DeleteDirAndFile();
+ tpi->DeleteDirAndFile();
return 0;
}
void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bool editMode)
{
const UString name = GetItemName(index);
+ const UString relPath = GetItemRelPath(index);
+
if (IsNameVirus(name))
{
MessageBoxErrorLang(IDS_VIRUS, 0x03020284);
@@ -598,18 +744,22 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
bool tryAsArchive = tryInternal && (!tryExternal || !DoItemAlwaysStart(name));
- UString fullVirtPath = _currentFolderPrefix + name;
+ UString fullVirtPath = _currentFolderPrefix + relPath;
- NFile::NDirectory::CTempDirectoryW tempDirectory;
- tempDirectory.Create(kTempDirPrefix);
- UString tempDir = tempDirectory.GetPath();
- UString tempDirNorm = tempDir;
+ NFile::NDirectory::CTempDir tempDirectory;
+ if (!tempDirectory.Create(kTempDirPrefix))
+ {
+ MessageBoxLastError();
+ return;
+ }
+ FString tempDir = tempDirectory.GetPath();
+ FString tempDirNorm = tempDir;
NFile::NName::NormalizeDirPathPrefix(tempDirNorm);
-
- UString tempFilePath = tempDirNorm + GetCorrectFsPath(name);
+ FString tempFilePath = tempDirNorm + us2fs(GetCorrectFsPath(name));
CTempFileInfo tempFileInfo;
- tempFileInfo.ItemName = name;
+ tempFileInfo.FileIndex = index;
+ tempFileInfo.RelPath = relPath;
tempFileInfo.FolderPath = tempDir;
tempFileInfo.FilePath = tempFilePath;
tempFileInfo.NeedDelete = true;
@@ -655,7 +805,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
password = fl.Password;
}
- HRESULT result = CopyTo(indices, tempDirNorm, false, true, &messages, usePassword, password);
+ HRESULT result = CopyTo(indices, fs2us(tempDirNorm), false, true, &messages, usePassword, password);
if (_parentFolders.Size() > 0)
{
@@ -686,17 +836,17 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
}
CMyAutoPtr<CTmpProcessInfo> tmpProcessInfoPtr(new CTmpProcessInfo());
- CTmpProcessInfo *tmpProcessInfo = tmpProcessInfoPtr.get();
- tmpProcessInfo->FolderPath = tempDir;
- tmpProcessInfo->FilePath = tempFilePath;
- tmpProcessInfo->NeedDelete = true;
- tmpProcessInfo->UsePassword = usePassword;
- tmpProcessInfo->Password = password;
-
- if (!tmpProcessInfo->FileInfo.Find(tempFilePath))
+ CTmpProcessInfo *tpi = tmpProcessInfoPtr.get();
+ tpi->FolderPath = tempDir;
+ tpi->FilePath = tempFilePath;
+ tpi->NeedDelete = true;
+ tpi->UsePassword = usePassword;
+ tpi->Password = password;
+
+ if (!tpi->FileInfo.Find(tempFilePath))
return;
- CTmpProcessInfoRelease tmpProcessInfoRelease(*tmpProcessInfo);
+ CTmpProcessInfoRelease tmpProcessInfoRelease(*tpi);
if (!tryExternal)
return;
@@ -704,20 +854,21 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
CProcess process;
HRESULT res;
if (editMode)
- res = StartEditApplication(tempFilePath, (HWND)*this, process);
+ res = StartEditApplication(fs2us(tempFilePath), (HWND)*this, process);
else
- res = StartApplication(tempDirNorm, tempFilePath, (HWND)*this, process);
+ res = StartApplication(fs2us(tempDirNorm), fs2us(tempFilePath), (HWND)*this, process);
if ((HANDLE)process == 0)
return;
- tmpProcessInfo->Window = (HWND)(*this);
- tmpProcessInfo->FullPathFolderPrefix = _currentFolderPrefix;
- tmpProcessInfo->ItemName = name;
- tmpProcessInfo->ProcessHandle = process.Detach();
+ tpi->Window = (HWND)(*this);
+ tpi->FullPathFolderPrefix = _currentFolderPrefix;
+ tpi->FileIndex = index;
+ tpi->RelPath = relPath;
+ tpi->Processes.AddProcess(process.Detach());
NWindows::CThread thread;
- if (thread.Create(MyThreadFunction, tmpProcessInfo) != S_OK)
+ if (thread.Create(MyThreadFunction, tpi) != S_OK)
throw 271824;
tempDirectory.DisableDeleting();
tmpProcessInfoPtr.release();
@@ -744,7 +895,7 @@ void DeleteOldTempFiles()
UString searchWildCard = tempPath + kTempDirPrefix + L"*.tmp";
searchWildCard += WCHAR(NName::kAnyStringWildcard);
NFind::CEnumeratorW enumerator(searchWildCard);
- NFind::CFileInfoW fileInfo;
+ NFind::CFileInfo fileInfo;
while(enumerator.Next(fileInfo))
{
if (!fileInfo.IsDir())
diff --git a/CPP/7zip/UI/FileManager/PanelItems.cpp b/CPP/7zip/UI/FileManager/PanelItems.cpp
index 17cc3fcb..daa150c6 100755
--- a/CPP/7zip/UI/FileManager/PanelItems.cpp
+++ b/CPP/7zip/UI/FileManager/PanelItems.cpp
@@ -416,7 +416,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
if (_currentFolderPrefix.IsEmpty())
{
int iconIndexTemp;
- GetRealIconIndex(itemName + WCHAR_PATH_SEPARATOR, attrib, iconIndexTemp);
+ GetRealIconIndex(us2fs(itemName) + FCHAR_PATH_SEPARATOR, attrib, iconIndexTemp);
item.iImage = iconIndexTemp;
}
else
@@ -450,6 +450,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
/*
_listView.UpdateWindow();
*/
+ Refresh_StatusBar();
return S_OK;
}
@@ -458,7 +459,7 @@ void CPanel::GetSelectedItemsIndices(CRecordVector<UInt32> &indices) const
indices.Clear();
/*
int itemIndex = -1;
- while ((itemIndex = _listView.GetNextItem(itemIndex, LVNI_SELECTED)) != -1)
+ while ((itemIndex = _listView.GetNextSelectedItem(itemIndex)) != -1)
{
LPARAM param;
if (_listView.GetItemParam(itemIndex, param))
@@ -481,7 +482,7 @@ void CPanel::GetOperatedItemIndices(CRecordVector<UInt32> &indices) const
int focusedItem = _listView.GetFocusedItem();
if (focusedItem >= 0)
{
- if (_listView.GetItemState(focusedItem, LVIS_SELECTED) == LVIS_SELECTED)
+ if (_listView.IsItemSelected(focusedItem))
{
int realIndex = GetRealItemIndex(focusedItem);
if (realIndex != kParentIndex)
@@ -565,8 +566,7 @@ void CPanel::OpenSelectedItems(bool tryInternal)
if (focusedItem >= 0)
{
int realIndex = GetRealItemIndex(focusedItem);
- if (realIndex == kParentIndex && (tryInternal || indices.Size() == 0) &&
- _listView.GetItemState(focusedItem, LVIS_SELECTED) == LVIS_SELECTED)
+ if (realIndex == kParentIndex && (tryInternal || indices.Size() == 0) && _listView.IsItemSelected(focusedItem))
indices.Insert(0, realIndex);
}
@@ -787,7 +787,6 @@ void CPanel::OnReload()
HRESULT res = RefreshListCtrlSaveFocused();
if (res != S_OK)
MessageBoxError(res);
- OnRefreshStatusBar();
}
void CPanel::OnTimer()
diff --git a/CPP/7zip/UI/FileManager/PanelListNotify.cpp b/CPP/7zip/UI/FileManager/PanelListNotify.cpp
index 2051b5c6..f28311a4 100755
--- a/CPP/7zip/UI/FileManager/PanelListNotify.cpp
+++ b/CPP/7zip/UI/FileManager/PanelListNotify.cpp
@@ -77,7 +77,7 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
if (_dontShowMode)
return 0;
- UINT32 realIndex = GetRealIndex(item);
+ UInt32 realIndex = GetRealIndex(item);
/*
if ((item.mask & LVIF_IMAGE) != 0)
{
@@ -113,7 +113,7 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
if (realIndex == kParentIndex)
return 0;
UString s;
- UINT32 subItemIndex = item.iSubItem;
+ UInt32 subItemIndex = item.iSubItem;
PROPID propID = _visibleProperties[subItemIndex].ID;
/*
{
@@ -222,7 +222,7 @@ bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result)
{
if (!_mySelectMode)
OnItemChanged((LPNMLISTVIEW)header);
- RefreshStatusBar();
+ Post_Refresh_StatusBar();
}
return false;
}
@@ -248,7 +248,7 @@ bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result)
case LVN_KEYDOWN:
{
bool boolResult = OnKeyDown(LPNMLVKEYDOWN(header), result);
- RefreshStatusBar();
+ Post_Refresh_StatusBar();
return boolResult;
}
@@ -273,7 +273,7 @@ bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result)
break;
case NM_RCLICK:
- RefreshStatusBar();
+ Post_Refresh_StatusBar();
break;
/*
@@ -301,7 +301,7 @@ bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result)
{
// we need SetFocusToList, if we drag-select items from other panel.
SetFocusToList();
- RefreshStatusBar();
+ Post_Refresh_StatusBar();
if (_mySelectMode)
#ifndef UNDER_CE
if (g_ComCtl32Version >= MAKELONG(71, 4))
@@ -325,7 +325,7 @@ bool CPanel::OnNotifyList(LPNMHDR header, LRESULT &result)
case LVN_BEGINDRAG:
{
OnDrag((LPNMLISTVIEW)header);
- RefreshStatusBar();
+ Post_Refresh_StatusBar();
break;
}
// case LVN_BEGINRDRAG:
@@ -390,9 +390,9 @@ bool CPanel::OnCustomDraw(LPNMLVCUSTOMDRAW lplvcd, LRESULT &result)
return false;
}
-void CPanel::OnRefreshStatusBar()
+void CPanel::Refresh_StatusBar()
{
- CRecordVector<UINT32> indices;
+ CRecordVector<UInt32> indices;
GetOperatedItemIndices(indices);
_statusBar.SetText(0, MyFormatNew(IDS_N_SELECTED_ITEMS, 0x02000301, NumberToString(indices.Size())));
diff --git a/CPP/7zip/UI/FileManager/PanelMenu.cpp b/CPP/7zip/UI/FileManager/PanelMenu.cpp
index 549b28da..badf531b 100755
--- a/CPP/7zip/UI/FileManager/PanelMenu.cpp
+++ b/CPP/7zip/UI/FileManager/PanelMenu.cpp
@@ -564,6 +564,7 @@ bool CPanel::InvokePluginCommand(int id,
CMINVOKECOMMANDINFOEX
#endif
commandInfo;
+ memset(&commandInfo, 0, sizeof(commandInfo));
commandInfo.cbSize = sizeof(commandInfo);
commandInfo.fMask = 0
#ifndef UNDER_CE
@@ -576,8 +577,8 @@ bool CPanel::InvokePluginCommand(int id,
CSysString currentFolderSys = GetSystemString(_currentFolderPrefix);
commandInfo.lpDirectory = (LPCSTR)(LPCTSTR)(currentFolderSys);
commandInfo.nShow = SW_SHOW;
- commandInfo.lpParameters = NULL;
#ifndef UNDER_CE
+ commandInfo.lpParametersW = NULL;
commandInfo.lpTitle = "";
commandInfo.lpVerbW = (LPCWSTR)(MAKEINTRESOURCEW(offset));
UString currentFolderUnicode = _currentFolderPrefix;
diff --git a/CPP/7zip/UI/FileManager/PanelOperations.cpp b/CPP/7zip/UI/FileManager/PanelOperations.cpp
index 0c6d3122..9c109d0d 100755
--- a/CPP/7zip/UI/FileManager/PanelOperations.cpp
+++ b/CPP/7zip/UI/FileManager/PanelOperations.cpp
@@ -284,6 +284,24 @@ BOOL CPanel::OnBeginLabelEdit(LV_DISPINFOW * lpnmh)
return FALSE;
}
+static UString GetLastPart(const UString name)
+{
+ int slashPos = name.ReverseFind(L'/');
+ #ifdef _WIN32
+ int slash1Pos = name.ReverseFind(L'\\');
+ slashPos = MyMax(slashPos, slash1Pos);
+ #endif
+ return name.Mid(slashPos + 1);
+}
+
+bool IsCorrectFsName(const UString name)
+{
+ const UString lastPart = GetLastPart(name);
+ return
+ lastPart != L"." &&
+ lastPart != L"..";
+}
+
BOOL CPanel::OnEndLabelEdit(LV_DISPINFOW * lpnmh)
{
if (lpnmh->item.pszText == NULL)
@@ -295,6 +313,11 @@ BOOL CPanel::OnEndLabelEdit(LV_DISPINFOW * lpnmh)
return FALSE;
}
const UString newName = lpnmh->item.pszText;
+ if (!IsCorrectFsName(newName))
+ {
+ MessageBoxError(E_INVALIDARG);
+ return FALSE;
+ }
CPanel::CDisableTimerProcessing disableTimerProcessing2(*this);
SaveSelectedState(_selectedState);
@@ -353,6 +376,11 @@ void CPanel::CreateFolder()
return;
UString newName = comboDialog.Value;
+ if (!IsCorrectFsName(newName))
+ {
+ MessageBoxError(E_INVALIDARG);
+ return;
+ }
{
CThreadFolderOperations op(FOLDER_TYPE_CREATE_FOLDER);
diff --git a/CPP/7zip/UI/FileManager/PanelSelect.cpp b/CPP/7zip/UI/FileManager/PanelSelect.cpp
index 29cf576b..b31c2e9d 100755
--- a/CPP/7zip/UI/FileManager/PanelSelect.cpp
+++ b/CPP/7zip/UI/FileManager/PanelSelect.cpp
@@ -78,7 +78,7 @@ void CPanel::OnInsert()
UINT state = (_listView.GetItemState(focusedItem, LVIS_CUT) == 0) ?
LVIS_CUT : 0;
_listView.SetItemState(focusedItem, state, LVIS_CUT);
- // _listView.SetItemState(focusedItem, LVIS_SELECTED, LVIS_SELECTED);
+ // _listView.SetItemState_Selected(focusedItem);
*/
int focusedItem = _listView.GetFocusedItem();
@@ -90,7 +90,7 @@ void CPanel::OnInsert()
_selectedStatusVector[realIndex] = isSelected;
if (!_mySelectMode)
- _listView.SetItemState(focusedItem, isSelected ? LVIS_SELECTED: 0, LVIS_SELECTED);
+ _listView.SetItemState_Selected(focusedItem, isSelected);
_listView.RedrawItem(focusedItem);
@@ -135,11 +135,7 @@ void CPanel::UpdateSelection()
{
int realIndex = GetRealItemIndex(i);
if (realIndex != kParentIndex)
- {
- UINT value = 0;
- value = _selectedStatusVector[realIndex] ? LVIS_SELECTED: 0;
- _listView.SetItemState(i, value, LVIS_SELECTED);
- }
+ _listView.SetItemState_Selected(i, _selectedStatusVector[realIndex]);
}
_enableItemChangeNotify = enableTemp;
}
@@ -174,7 +170,7 @@ void CPanel::SelectByType(bool selectMode)
bool isItemFolder = IsItemFolder(realIndex);
/*
- UINT32 numItems;
+ UInt32 numItems;
_folder->GetNumberOfItems(&numItems);
if ((UInt32)_selectedStatusVector.Size() != numItems)
throw 11111;
@@ -251,7 +247,7 @@ void CPanel::KillSelection()
int realIndex = GetRealItemIndex(focused);
if (realIndex != kParentIndex)
_selectedStatusVector[realIndex] = true;
- _listView.SetItemState(focused, LVIS_SELECTED, LVIS_SELECTED);
+ _listView.SetItemState_Selected(focused);
}
}
}
diff --git a/CPP/7zip/UI/FileManager/PanelSort.cpp b/CPP/7zip/UI/FileManager/PanelSort.cpp
index 186315b3..5ac04800 100755
--- a/CPP/7zip/UI/FileManager/PanelSort.cpp
+++ b/CPP/7zip/UI/FileManager/PanelSort.cpp
@@ -63,8 +63,8 @@ int CALLBACK CompareItems2(LPARAM lParam1, LPARAM lParam2, LPARAM lpData)
NCOM::CPropVariant prop1, prop2;
// Name must be first property
- panel->_folder->GetProperty((UINT32)lParam1, propID, &prop1);
- panel->_folder->GetProperty((UINT32)lParam2, propID, &prop2);
+ panel->_folder->GetProperty((UInt32)lParam1, propID, &prop1);
+ panel->_folder->GetProperty((UInt32)lParam2, propID, &prop2);
if (prop1.vt != prop2.vt)
{
return MyCompare(prop1.vt, prop2.vt);
diff --git a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
index 213c2d48..ba0bedf8 100755
--- a/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
+++ b/CPP/7zip/UI/FileManager/PanelSplitFile.cpp
@@ -7,6 +7,7 @@
#include "Windows/Error.h"
#include "Windows/FileIO.h"
#include "Windows/FileFind.h"
+#include "Windows/FileName.h"
#include "../GUI/ExtractRes.h"
@@ -89,8 +90,8 @@ class CThreadSplit: public CProgressThreadVirt
{
HRESULT ProcessVirt();
public:
- UString FilePath;
- UString VolBasePath;
+ FString FilePath;
+ FString VolBasePath;
UInt64 NumVolumes;
CRecordVector<UInt64> VolumeSizes;
};
@@ -136,15 +137,15 @@ HRESULT CThreadSplit::ProcessVirt()
needSize = processedSize;
if (curVolSize == 0)
{
- UString name = VolBasePath;
- name += L'.';
- name += seqName.GetNextName();
- sync.SetCurrentFileName(name);
+ FString name = VolBasePath;
+ name += FTEXT('.');
+ name += us2fs(seqName.GetNextName());
+ sync.SetCurrentFileName(fs2us(name));
sync.SetNumFilesCur(numFiles++);
if (!outFile.Create(name, false))
{
HRESULT res = GetLastError();
- ErrorPath1 = name;
+ SetErrorPath1(name);
return res;
}
}
@@ -206,8 +207,8 @@ void CApp::Split()
if (splitDialog.Create(srcPanel.GetParent()) == IDCANCEL)
return;
- NFile::NFind::CFileInfoW fileInfo;
- if (!fileInfo.Find(srcPath + itemName))
+ NFile::NFind::CFileInfo fileInfo;
+ if (!fileInfo.Find(us2fs(srcPath + itemName)))
{
srcPanel.MessageBoxMyError(L"Can not find file");
return;
@@ -230,7 +231,7 @@ void CApp::Split()
path = splitDialog.Path;
NFile::NName::NormalizeDirPathPrefix(path);
- if (!NFile::NDirectory::CreateComplexDirectory(path))
+ if (!NFile::NDirectory::CreateComplexDirectory(us2fs(path)))
{
srcPanel.MessageBoxMyError(MyFormatNew(IDS_CANNOT_CREATE_FOLDER, 0x02000603, path));
return;
@@ -253,8 +254,8 @@ void CApp::Split()
progressDialog.Sync.SetTitleFileName(itemName);
- spliter.FilePath = srcPath + itemName;
- spliter.VolBasePath = path + itemName;
+ spliter.FilePath = us2fs(srcPath + itemName);
+ spliter.VolBasePath = us2fs(path + itemName);
spliter.VolumeSizes = splitDialog.VolumeSizes;
// if (splitDialog.VolumeSizes.Size() == 0) return;
@@ -279,9 +280,9 @@ class CThreadCombine: public CProgressThreadVirt
{
HRESULT ProcessVirt();
public:
- UString InputDirPrefix;
- UStringVector Names;
- UString OutputPath;
+ FString InputDirPrefix;
+ FStringVector Names;
+ FString OutputPath;
UInt64 TotalSize;
};
@@ -291,7 +292,7 @@ HRESULT CThreadCombine::ProcessVirt()
if (!outFile.Create(OutputPath, false))
{
HRESULT res = GetLastError();
- ErrorPath1 = OutputPath;
+ SetErrorPath1(OutputPath);
return res;
}
@@ -306,21 +307,21 @@ HRESULT CThreadCombine::ProcessVirt()
for (int i = 0; i < Names.Size(); i++)
{
NFile::NIO::CInFile inFile;
- const UString nextName = InputDirPrefix + Names[i];
+ const FString nextName = InputDirPrefix + Names[i];
if (!inFile.Open(nextName))
{
HRESULT res = GetLastError();
- ErrorPath1 = nextName;
+ SetErrorPath1(nextName);
return res;
}
- sync.SetCurrentFileName(nextName);
+ sync.SetCurrentFileName(fs2us(nextName));
for (;;)
{
UInt32 processedSize;
if (!inFile.Read(buffer, kBufSize, processedSize))
{
HRESULT res = GetLastError();
- ErrorPath1 = nextName;
+ SetErrorPath1(nextName);
return res;
}
if (processedSize == 0)
@@ -329,7 +330,7 @@ HRESULT CThreadCombine::ProcessVirt()
if (!outFile.Write(buffer, needSize, processedSize))
{
HRESULT res = GetLastError();
- ErrorPath1 = OutputPath;
+ SetErrorPath1(OutputPath);
return res;
}
if (needSize != processedSize)
@@ -392,10 +393,10 @@ void CApp::Combine()
combiner.TotalSize = 0;
for (;;)
{
- NFile::NFind::CFileInfoW fileInfo;
- if (!fileInfo.Find(srcPath + nextName) || fileInfo.IsDir())
+ NFile::NFind::CFileInfo fileInfo;
+ if (!fileInfo.Find(us2fs(srcPath + nextName)) || fileInfo.IsDir())
break;
- combiner.Names.Add(nextName);
+ combiner.Names.Add(us2fs(nextName));
combiner.TotalSize += fileInfo.Size;
nextName = volSeqName.GetNextName();
}
@@ -419,12 +420,12 @@ void CApp::Combine()
int i;
for (i = 0; i < combiner.Names.Size() && i < 2; i++)
- AddInfoFileName(combiner.Names[i], info);
+ AddInfoFileName(fs2us(combiner.Names[i]), info);
if (i != combiner.Names.Size())
{
if (i + 1 != combiner.Names.Size())
AddInfoFileName(L"...", info);
- AddInfoFileName(combiner.Names.Back(), info);
+ AddInfoFileName(fs2us(combiner.Names.Back()), info);
}
{
@@ -441,7 +442,7 @@ void CApp::Combine()
}
NFile::NName::NormalizeDirPathPrefix(path);
- if (!NFile::NDirectory::CreateComplexDirectory(path))
+ if (!NFile::NDirectory::CreateComplexDirectory(us2fs(path)))
{
srcPanel.MessageBoxMyError(MyFormatNew(IDS_CANNOT_CREATE_FOLDER, 0x02000603, path));
return;
@@ -450,18 +451,17 @@ void CApp::Combine()
UString outName = volSeqName.UnchangedPart;
while (!outName.IsEmpty())
{
- int lastIndex = outName.Length() - 1;
- if (outName[lastIndex] != L'.')
+ if (outName.Back() != L'.')
break;
- outName.Delete(lastIndex);
+ outName.DeleteBack();
}
if (outName.IsEmpty())
outName = L"file";
- NFile::NFind::CFileInfoW fileInfo;
+ NFile::NFind::CFileInfo fileInfo;
UString destFilePath = path + outName;
- combiner.OutputPath = destFilePath;
- if (fileInfo.Find(destFilePath))
+ combiner.OutputPath = us2fs(destFilePath);
+ if (fileInfo.Find(combiner.OutputPath))
{
srcPanel.MessageBoxMyError(MyFormatNew(IDS_FILE_EXIST, 0x03020A04, destFilePath));
return;
@@ -477,7 +477,7 @@ void CApp::Combine()
progressDialog.MainTitle = progressWindowTitle;
progressDialog.MainAddTitle = title + UString(L" ");
- combiner.InputDirPrefix = srcPath;
+ combiner.InputDirPrefix = us2fs(srcPath);
// CPanel::CDisableTimerProcessing disableTimerProcessing1(srcPanel);
// CPanel::CDisableTimerProcessing disableTimerProcessing2(destPanel);
diff --git a/CPP/7zip/UI/FileManager/PasswordDialog.cpp b/CPP/7zip/UI/FileManager/PasswordDialog.cpp
index eaf90a24..92826a1f 100755
--- a/CPP/7zip/UI/FileManager/PasswordDialog.cpp
+++ b/CPP/7zip/UI/FileManager/PasswordDialog.cpp
@@ -18,6 +18,17 @@ static CIDLangPair kIDLangPairs[] =
};
#endif
+void CPasswordDialog::ReadControls()
+{
+ _passwordControl.GetText(Password);
+ ShowPassword = IsButtonCheckedBool(IDC_CHECK_PASSWORD_SHOW);
+}
+
+void CPasswordDialog::SetTextSpec()
+{
+ _passwordControl.SetPasswordChar(ShowPassword ? 0: TEXT('*'));
+ _passwordControl.SetText(Password);
+}
bool CPasswordDialog::OnInit()
{
@@ -26,8 +37,8 @@ bool CPasswordDialog::OnInit()
LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
#endif
_passwordControl.Attach(GetItem(IDC_EDIT_PASSWORD));
- _passwordControl.SetText(Password);
- _passwordControl.SetPasswordChar(TEXT('*'));
+ CheckButton(IDC_CHECK_PASSWORD_SHOW, ShowPassword);
+ SetTextSpec();
return CModalDialog::OnInit();
}
@@ -35,10 +46,8 @@ bool CPasswordDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
{
if (buttonID == IDC_CHECK_PASSWORD_SHOW)
{
- _passwordControl.SetPasswordChar(IsButtonCheckedBool(IDC_CHECK_PASSWORD_SHOW) ? 0: TEXT('*'));
- UString password;
- _passwordControl.GetText(password);
- _passwordControl.SetText(password);
+ ReadControls();
+ SetTextSpec();
return true;
}
return CDialog::OnButtonClicked(buttonID, buttonHWND);
@@ -46,6 +55,6 @@ bool CPasswordDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
void CPasswordDialog::OnOK()
{
- _passwordControl.GetText(Password);
+ ReadControls();
CModalDialog::OnOK();
}
diff --git a/CPP/7zip/UI/FileManager/PasswordDialog.h b/CPP/7zip/UI/FileManager/PasswordDialog.h
index e5a96073..1d903249 100755
--- a/CPP/7zip/UI/FileManager/PasswordDialog.h
+++ b/CPP/7zip/UI/FileManager/PasswordDialog.h
@@ -1,7 +1,7 @@
// PasswordDialog.h
-#ifndef __PASSWORDDIALOG_H
-#define __PASSWORDDIALOG_H
+#ifndef __PASSWORD_DIALOG_H
+#define __PASSWORD_DIALOG_H
#include "Windows/Control/Dialog.h"
#include "Windows/Control/Edit.h"
@@ -13,8 +13,12 @@ class CPasswordDialog: public NWindows::NControl::CModalDialog
virtual void OnOK();
virtual bool OnInit();
virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
+ void SetTextSpec();
+ void ReadControls();
public:
UString Password;
+ bool ShowPassword;
+ CPasswordDialog(): ShowPassword(false) {}
INT_PTR Create(HWND parentWindow = 0) { return CModalDialog::Create(IDD_DIALOG_PASSWORD, parentWindow); }
};
diff --git a/CPP/7zip/UI/FileManager/PluginLoader.h b/CPP/7zip/UI/FileManager/PluginLoader.h
index 3cf15aa5..cb7d4d7c 100755
--- a/CPP/7zip/UI/FileManager/PluginLoader.h
+++ b/CPP/7zip/UI/FileManager/PluginLoader.h
@@ -5,6 +5,8 @@
#include "Windows/DLL.h"
+#include "IFolder.h"
+
typedef UINT32 (WINAPI * CreateObjectPointer)(const GUID *clsID, const GUID *interfaceID, void **outObject);
class CPluginLibrary: public NWindows::NDLL::CLibrary
@@ -17,7 +19,7 @@ public:
return GetLastError();
return createObject(&clsID, &IID_IFolderManager, (void **)manager);
}
- HRESULT LoadAndCreateManager(LPCWSTR filePath, REFGUID clsID, IFolderManager **manager)
+ HRESULT LoadAndCreateManager(CFSTR filePath, REFGUID clsID, IFolderManager **manager)
{
if (!Load(filePath))
return GetLastError();
diff --git a/CPP/7zip/UI/FileManager/ProgramLocation.cpp b/CPP/7zip/UI/FileManager/ProgramLocation.cpp
index ce2d178e..50ca5ca5 100755
--- a/CPP/7zip/UI/FileManager/ProgramLocation.cpp
+++ b/CPP/7zip/UI/FileManager/ProgramLocation.cpp
@@ -1,24 +1,3 @@
// ProgramLocation.cpp
#include "StdAfx.h"
-
-#include "../../../../C/Types.h"
-
-#include "ProgramLocation.h"
-
-#include "Windows/DLL.h"
-
-using namespace NWindows;
-
-extern HINSTANCE g_hInstance;
-
-bool GetProgramFolderPath(UString &folder)
-{
- if (!NDLL::MyGetModuleFileName(g_hInstance, folder))
- return false;
- int pos = folder.ReverseFind(WCHAR_PATH_SEPARATOR);
- if (pos < 0)
- return false;
- folder = folder.Left(pos + 1);
- return true;
-}
diff --git a/CPP/7zip/UI/FileManager/ProgramLocation.h b/CPP/7zip/UI/FileManager/ProgramLocation.h
index 55c56144..6bfb711e 100755
--- a/CPP/7zip/UI/FileManager/ProgramLocation.h
+++ b/CPP/7zip/UI/FileManager/ProgramLocation.h
@@ -3,8 +3,4 @@
#ifndef __PROGRAM_LOCATION_H
#define __PROGRAM_LOCATION_H
-#include "Common/MyString.h"
-
-bool GetProgramFolderPath(UString &folder); // normalized
-
#endif
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
index 3d878a61..bd77d20d 100755
--- a/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
+++ b/CPP/7zip/UI/FileManager/ProgressDialog2.cpp
@@ -146,6 +146,7 @@ bool CProgressDialog::OnInit()
m_ProgressBar.Attach(GetItem(IDC_PROGRESS1));
_messageList.Attach(GetItem(IDC_PROGRESS_LIST));
+ _messageList.SetUnicodeFormat();
_wasCreated = true;
_dialogCreatedEvent.Set();
@@ -154,7 +155,6 @@ bool CProgressDialog::OnInit()
LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
#endif
-
CWindow window(GetItem(IDC_BUTTON_PROGRESS_PRIORITY));
window.GetText(backgroundString);
backgroundedString = backgroundString;
@@ -171,11 +171,6 @@ bool CProgressDialog::OnInit()
SetPauseText();
SetPriorityText();
-
- #ifndef UNDER_CE
- _messageList.SetUnicodeFormat(true);
- #endif
-
_messageList.InsertColumn(0, L"", 30);
const UString s = LangStringSpec(IDS_MESSAGES_DIALOG_MESSAGE_COLUMN, 0x02000A80);
@@ -957,10 +952,8 @@ UString HResultToMessage(HRESULT errorCode)
UString message;
if (errorCode == E_OUTOFMEMORY)
message = LangStringSpec(IDS_MEM_ERROR, 0x0200060B);
- else if (!NError::MyFormatMessage(errorCode, message))
- message.Empty();
- if (message.IsEmpty())
- message = L"Error";
+ else
+ message = NError::MyFormatMessageW(errorCode);
return message;
}
@@ -989,8 +982,8 @@ void CProgressThreadVirt::Process()
m = HResultToMessage(Result);
}
AddMessageToString(m, ErrorMessage);
- AddMessageToString(m, ErrorPath1);
- AddMessageToString(m, ErrorPath2);
+ AddMessageToString(m, fs2us(ErrorPath1));
+ AddMessageToString(m, fs2us(ErrorPath2));
if (m.IsEmpty())
{
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2.h b/CPP/7zip/UI/FileManager/ProgressDialog2.h
index ed096f06..81a64e32 100755
--- a/CPP/7zip/UI/FileManager/ProgressDialog2.h
+++ b/CPP/7zip/UI/FileManager/ProgressDialog2.h
@@ -323,10 +323,10 @@ public:
class CProgressThreadVirt
{
+ FString ErrorPath1;
+ FString ErrorPath2;
protected:
UString ErrorMessage;
- UString ErrorPath1;
- UString ErrorPath2;
UString OkMessage;
UString OkMessageTitle;
@@ -350,6 +350,9 @@ public:
return 0;
}
+ void SetErrorPath1(const FString &path) { ErrorPath1 = path; }
+ void SetErrorPath2(const FString &path) { ErrorPath2 = path; }
+
HRESULT Create(const UString &title, HWND parentWindow = 0);
CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {}
};
diff --git a/CPP/7zip/UI/FileManager/ProgressDialog2Res.h b/CPP/7zip/UI/FileManager/ProgressDialog2Res.h
index 21ac03c2..be5af607 100755
--- a/CPP/7zip/UI/FileManager/ProgressDialog2Res.h
+++ b/CPP/7zip/UI/FileManager/ProgressDialog2Res.h
@@ -35,7 +35,11 @@
#define IDC_PROGRESS_ERRORS_VALUE 1031
#define IDC_PROGRESS_LIST 1032
+#ifdef UNDER_CE
#define MY_PROGRESS_VALUE_UNITS 44
+#else
+#define MY_PROGRESS_VALUE_UNITS 76
+#endif
#define MY_PROGRESS_LABEL_UNITS_MIN 60
#define MY_PROGRESS_LABEL_UNITS_START 90
#define MY_PROGRESS_PAD_UNITS 4
diff --git a/CPP/7zip/UI/FileManager/RegistryAssociations.cpp b/CPP/7zip/UI/FileManager/RegistryAssociations.cpp
index f7edbb4b..487b6060 100755
--- a/CPP/7zip/UI/FileManager/RegistryAssociations.cpp
+++ b/CPP/7zip/UI/FileManager/RegistryAssociations.cpp
@@ -2,234 +2,151 @@
#include "StdAfx.h"
-#include "RegistryAssociations.h"
-
#include "Common/IntToString.h"
#include "Common/StringConvert.h"
#include "Common/StringToInt.h"
#include "Windows/Registry.h"
-#include "Windows/Synchronization.h"
-#include "StringUtils.h"
+#include "RegistryAssociations.h"
using namespace NWindows;
using namespace NRegistry;
-namespace NRegistryAssociations {
+namespace NRegistryAssoc {
-static NSynchronization::CCriticalSection g_CriticalSection;
-
-#define REG_PATH_FM TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-Zip") TEXT(STRING_PATH_SEPARATOR) TEXT("FM")
-
-/*
-
-static const TCHAR *kCUKeyPath = REG_PATH_FM;
-static const WCHAR *kExtPlugins = L"Plugins";
-static const TCHAR *kExtEnabled = TEXT("Enabled");
-
-#define kAssociations TEXT("Associations")
-#define kAssociationsPath REG_PATH_FM TEXT(STRING_PATH_SEPARATOR) kAssociations
-
-bool ReadInternalAssociation(const wchar_t *ext, CExtInfo &extInfo)
-{
- NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
- CKey key;
- if (key.Open(HKEY_CURRENT_USER,
- CSysString(kAssociationsPath TEXT(STRING_PATH_SEPARATOR)) +
- GetSystemString(ext), KEY_READ) != ERROR_SUCCESS)
- return false;
- UString pluginsString;
- key.QueryValue(kExtPlugins, pluginsString);
- SplitString(pluginsString, extInfo.Plugins);
- return true;
-}
-
-void ReadInternalAssociations(CObjectVector<CExtInfo> &items)
-{
- items.Clear();
- NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
- CKey associationsKey;
- if (associationsKey.Open(HKEY_CURRENT_USER, kAssociationsPath, KEY_READ) != ERROR_SUCCESS)
- return;
- CSysStringVector extNames;
- associationsKey.EnumKeys(extNames);
- for(int i = 0; i < extNames.Size(); i++)
- {
- const CSysString extName = extNames[i];
- CExtInfo extInfo;
- // extInfo.Enabled = false;
- extInfo.Ext = GetUnicodeString(extName);
- CKey key;
- if (key.Open(associationsKey, extName, KEY_READ) != ERROR_SUCCESS)
- return;
- UString pluginsString;
- key.QueryValue(kExtPlugins, pluginsString);
- SplitString(pluginsString, extInfo.Plugins);
- // if (key.QueryValue(kExtEnabled, extInfo.Enabled) != ERROR_SUCCESS)
- // extInfo.Enabled = false;
- items.Add(extInfo);
- }
-}
-
-void WriteInternalAssociations(const CObjectVector<CExtInfo> &items)
-{
- NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
- CKey mainKey;
- mainKey.Create(HKEY_CURRENT_USER, kCUKeyPath);
- mainKey.RecurseDeleteKey(kAssociations);
- CKey associationsKey;
- associationsKey.Create(mainKey, kAssociations);
- for(int i = 0; i < items.Size(); i++)
- {
- const CExtInfo &extInfo = items[i];
- CKey key;
- key.Create(associationsKey, GetSystemString(extInfo.Ext));
- key.SetValue(kExtPlugins, JoinStrings(extInfo.Plugins));
- // key.SetValue(kExtEnabled, extInfo.Enabled);
- }
-}
-*/
-
-///////////////////////////////////
-// External
+// static NSynchronization::CCriticalSection g_CriticalSection;
-static const TCHAR *kShellNewKeyName = TEXT("ShellNew");
-static const TCHAR *kShellNewDataValueName = TEXT("Data");
-
+static const TCHAR *kClasses = TEXT("Software\\Classes\\");
+// static const TCHAR *kShellNewKeyName = TEXT("ShellNew");
+// static const TCHAR *kShellNewDataValueName = TEXT("Data");
static const TCHAR *kDefaultIconKeyName = TEXT("DefaultIcon");
static const TCHAR *kShellKeyName = TEXT("shell");
static const TCHAR *kOpenKeyName = TEXT("open");
static const TCHAR *kCommandKeyName = TEXT("command");
static const TCHAR *k7zipPrefix = TEXT("7-Zip.");
-static CSysString GetExtensionKeyName(const CSysString &extension)
+static CSysString GetExtProgramKeyName(const CSysString &ext)
{
- return CSysString(TEXT(".")) + extension;
+ return CSysString(k7zipPrefix) + ext;
}
-static CSysString GetExtProgramKeyName(const CSysString &extension)
+static CSysString GetFullKeyPath(HKEY hkey, const CSysString &name)
{
- return CSysString(k7zipPrefix) + extension;
+ CSysString s;
+ if (hkey != HKEY_CLASSES_ROOT)
+ s = kClasses;
+ return s + name;
}
-static bool CheckShellExtensionInfo2(const CSysString &extension,
- CSysString programKeyName, UString &iconPath, int &iconIndex)
+static CSysString GetExtKeyPath(HKEY hkey, const CSysString &ext)
{
- iconIndex = -1;
- iconPath.Empty();
- NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
- CKey extKey;
- if (extKey.Open(HKEY_CLASSES_ROOT, GetExtensionKeyName(extension), KEY_READ) != ERROR_SUCCESS)
- return false;
- if (extKey.QueryValue(NULL, programKeyName) != ERROR_SUCCESS)
- return false;
- UString s = GetUnicodeString(k7zipPrefix);
- if (s.CompareNoCase(GetUnicodeString(programKeyName.Left(s.Length()))) != 0)
- return false;
- CKey iconKey;
- if (extKey.Open(HKEY_CLASSES_ROOT, programKeyName + CSysString(TEXT(CHAR_PATH_SEPARATOR)) + kDefaultIconKeyName, KEY_READ) != ERROR_SUCCESS)
- return false;
- UString value;
- if (extKey.QueryValue(NULL, value) == ERROR_SUCCESS)
+ return GetFullKeyPath(hkey, (TEXT(".")) + ext);
+}
+
+bool CShellExtInfo::ReadFromRegistry(HKEY hkey, const CSysString &ext)
+{
+ ProgramKey.Empty();
+ IconPath.Empty();
+ IconIndex = -1;
+ // NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+ {
+ CKey extKey;
+ if (extKey.Open(hkey, GetExtKeyPath(hkey, ext), KEY_READ) != ERROR_SUCCESS)
+ return false;
+ if (extKey.QueryValue(NULL, ProgramKey) != ERROR_SUCCESS)
+ return false;
+ }
{
- int pos = value.ReverseFind(L',');
- iconPath = value;
- if (pos >= 0)
+ CKey iconKey;
+ if (iconKey.Open(hkey, GetFullKeyPath(hkey, ProgramKey + CSysString(TEXT(CHAR_PATH_SEPARATOR)) + kDefaultIconKeyName), KEY_READ) == ERROR_SUCCESS)
{
- const wchar_t *end;
- UInt64 index = ConvertStringToUInt64((const wchar_t *)value + pos + 1, &end);
- if (*end == 0)
+ UString value;
+ if (iconKey.QueryValue(NULL, value) == ERROR_SUCCESS)
{
- iconIndex = (int)index;
- iconPath = value.Left(pos);
+ int pos = value.ReverseFind(L',');
+ IconPath = value;
+ if (pos >= 0)
+ {
+ const wchar_t *end;
+ Int64 index = ConvertStringToInt64((const wchar_t *)value + pos + 1, &end);
+ if (*end == 0)
+ {
+ IconIndex = (int)index;
+ IconPath = value.Left(pos);
+ }
+ }
}
}
}
return true;
}
-bool CheckShellExtensionInfo(const CSysString &extension, UString &iconPath, int &iconIndex)
-{
- NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
- CSysString programKeyName;
- if (!CheckShellExtensionInfo2(extension, programKeyName, iconPath, iconIndex))
- return false;
- CKey extProgKey;
- return (extProgKey.Open(HKEY_CLASSES_ROOT, programKeyName, KEY_READ) == ERROR_SUCCESS);
-}
-
-static void DeleteShellExtensionKey(const CSysString &extension)
+bool CShellExtInfo::IsIt7Zip() const
{
- NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
- CKey rootKey;
- rootKey.Attach(HKEY_CLASSES_ROOT);
- rootKey.RecurseDeleteKey(GetExtensionKeyName(extension));
- rootKey.Detach();
+ UString s = GetUnicodeString(k7zipPrefix);
+ return (s.CompareNoCase(GetUnicodeString(ProgramKey.Left(s.Length()))) == 0);
}
-static void DeleteShellExtensionProgramKey(const CSysString &extension)
+LONG DeleteShellExtensionInfo(HKEY hkey, const CSysString &ext)
{
- NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+ // NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
CKey rootKey;
- rootKey.Attach(HKEY_CLASSES_ROOT);
- rootKey.RecurseDeleteKey(GetExtProgramKeyName(extension));
+ rootKey.Attach(hkey);
+ LONG res = rootKey.RecurseDeleteKey(GetExtKeyPath(hkey, ext));
+ // then we delete only 7-Zip.* key.
+ rootKey.RecurseDeleteKey(GetFullKeyPath(hkey, GetExtProgramKeyName(ext)));
rootKey.Detach();
+ return res;
}
-void DeleteShellExtensionInfo(const CSysString &extension)
-{
- CSysString programKeyName;
- UString iconPath;
- int iconIndex;
- if (CheckShellExtensionInfo2(extension, programKeyName, iconPath, iconIndex))
- DeleteShellExtensionKey(extension);
- DeleteShellExtensionProgramKey(extension);
-}
-
-void AddShellExtensionInfo(const CSysString &extension,
+LONG AddShellExtensionInfo(HKEY hkey,
+ const CSysString &ext,
const UString &programTitle,
const UString &programOpenCommand,
- const UString &iconPath, int iconIndex,
- const void *shellNewData, int shellNewDataSize)
+ const UString &iconPath, int iconIndex
+ // , const void *shellNewData, int shellNewDataSize
+ )
{
- DeleteShellExtensionKey(extension);
- DeleteShellExtensionProgramKey(extension);
- NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
+ LONG res = 0;
+ DeleteShellExtensionInfo(hkey, ext);
+ // NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
CSysString programKeyName;
{
- CSysString ext = extension;
+ CSysString ext2 = ext;
if (iconIndex < 0)
- ext = TEXT("*");
- programKeyName = GetExtProgramKeyName(ext);
+ ext2 = TEXT("*");
+ programKeyName = GetExtProgramKeyName(ext2);
}
{
CKey extKey;
- extKey.Create(HKEY_CLASSES_ROOT, GetExtensionKeyName(extension));
+ res = extKey.Create(hkey, GetExtKeyPath(hkey, ext));
extKey.SetValue(NULL, programKeyName);
+ /*
if (shellNewData != NULL)
{
CKey shellNewKey;
shellNewKey.Create(extKey, kShellNewKeyName);
shellNewKey.SetValue(kShellNewDataValueName, shellNewData, shellNewDataSize);
}
+ */
}
CKey programKey;
- programKey.Create(HKEY_CLASSES_ROOT, programKeyName);
+ programKey.Create(hkey, GetFullKeyPath(hkey, programKeyName));
programKey.SetValue(NULL, programTitle);
{
CKey iconKey;
- iconKey.Create(programKey, kDefaultIconKeyName);
UString iconPathFull = iconPath;
if (iconIndex < 0)
iconIndex = 0;
// if (iconIndex >= 0)
{
- iconPathFull += L",";
+ iconPathFull += L',';
wchar_t s[16];
- ConvertUInt32ToString(iconIndex, s);
+ ConvertInt64ToString(iconIndex, s);
iconPathFull += s;
}
+ iconKey.Create(programKey, kDefaultIconKeyName);
iconKey.SetValue(NULL, iconPathFull);
}
@@ -243,70 +160,8 @@ void AddShellExtensionInfo(const CSysString &extension,
CKey commandKey;
commandKey.Create(openKey, kCommandKeyName);
-
commandKey.SetValue(NULL, programOpenCommand);
+ return res;
}
-///////////////////////////
-// ContextMenu
-/*
-
-static const TCHAR *kContextMenuKeyName = TEXT("\\shellex\\ContextMenuHandlers\\7-Zip");
-static const TCHAR *kContextMenuHandlerCLASSIDValue =
- TEXT("{23170F69-40C1-278A-1000-000100020000}");
-static const TCHAR *kRootKeyNameForFile = TEXT("*");
-static const TCHAR *kRootKeyNameForFolder = TEXT("Folder");
-
-static CSysString GetFullContextMenuKeyName(const CSysString &aKeyName)
- { return (aKeyName + kContextMenuKeyName); }
-
-static bool CheckContextMenuHandlerCommon(const CSysString &aKeyName)
-{
- NSynchronization::CCriticalSectionLock lock(&g_CriticalSection, true);
- CKey aKey;
- if (aKey.Open(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(aKeyName), KEY_READ)
- != ERROR_SUCCESS)
- return false;
- CSysString aValue;
- if (aKey.QueryValue(NULL, aValue) != ERROR_SUCCESS)
- return false;
- return (aValue.CompareNoCase(kContextMenuHandlerCLASSIDValue) == 0);
-}
-
-bool CheckContextMenuHandler()
-{
- return CheckContextMenuHandlerCommon(kRootKeyNameForFile) &&
- CheckContextMenuHandlerCommon(kRootKeyNameForFolder);
-}
-
-static void DeleteContextMenuHandlerCommon(const CSysString &aKeyName)
-{
- CKey rootKey;
- rootKey.Attach(HKEY_CLASSES_ROOT);
- rootKey.RecurseDeleteKey(GetFullContextMenuKeyName(aKeyName));
- rootKey.Detach();
-}
-
-void DeleteContextMenuHandler()
-{
- DeleteContextMenuHandlerCommon(kRootKeyNameForFile);
- DeleteContextMenuHandlerCommon(kRootKeyNameForFolder);
-}
-
-static void AddContextMenuHandlerCommon(const CSysString &aKeyName)
-{
- DeleteContextMenuHandlerCommon(aKeyName);
- NSynchronization::CCriticalSectionLock lock(&g_CriticalSection, true);
- CKey aKey;
- aKey.Create(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(aKeyName));
- aKey.SetValue(NULL, kContextMenuHandlerCLASSIDValue);
-}
-
-void AddContextMenuHandler()
-{
- AddContextMenuHandlerCommon(kRootKeyNameForFile);
- AddContextMenuHandlerCommon(kRootKeyNameForFolder);
-}
-*/
-
}
diff --git a/CPP/7zip/UI/FileManager/RegistryAssociations.h b/CPP/7zip/UI/FileManager/RegistryAssociations.h
index 5390b9db..0be8244e 100755
--- a/CPP/7zip/UI/FileManager/RegistryAssociations.h
+++ b/CPP/7zip/UI/FileManager/RegistryAssociations.h
@@ -1,46 +1,31 @@
// RegistryAssociations.h
-#ifndef __REGISTRYASSOCIATIONS_H
-#define __REGISTRYASSOCIATIONS_H
+#ifndef __REGISTRY_ASSOCIATIONS_H
+#define __REGISTRY_ASSOCIATIONS_H
#include "Common/MyString.h"
-namespace NRegistryAssociations {
+namespace NRegistryAssoc {
- /*
- struct CExtInfo
+ struct CShellExtInfo
{
- UString Ext;
- UStringVector Plugins;
- // bool Enabled;
- };
- bool ReadInternalAssociation(const wchar_t *ext, CExtInfo &extInfo);
- void ReadInternalAssociations(CObjectVector<CExtInfo> &items);
- void WriteInternalAssociations(const CObjectVector<CExtInfo> &items);
- */
+ CSysString ProgramKey;
+ UString IconPath;
+ int IconIndex;
- bool CheckShellExtensionInfo(const CSysString &extension, UString &iconPath, int &iconIndex);
+ bool ReadFromRegistry(HKEY hkey, const CSysString &ext);
+ bool IsIt7Zip() const;
+ };
- // void ReadCompressionInfo(NZipSettings::NCompression::CInfo &anInfo,
- void DeleteShellExtensionInfo(const CSysString &extension);
+ LONG DeleteShellExtensionInfo(HKEY hkey, const CSysString &ext);
- void AddShellExtensionInfo(const CSysString &extension,
+ LONG AddShellExtensionInfo(HKEY hkey,
+ const CSysString &ext,
const UString &programTitle,
const UString &programOpenCommand,
- const UString &iconPath, int iconIndex,
- const void *shellNewData, int shellNewDataSize);
-
-
- ///////////////////////////
- // ContextMenu
- /*
- bool CheckContextMenuHandler();
- void AddContextMenuHandler();
- void DeleteContextMenuHandler();
- */
-
+ const UString &iconPath, int iconIndex
+ // , const void *shellNewData, int shellNewDataSize
+ );
}
-// bool GetProgramDirPrefix(CSysString &aFolder);
-
#endif
diff --git a/CPP/7zip/UI/FileManager/RegistryPlugins.cpp b/CPP/7zip/UI/FileManager/RegistryPlugins.cpp
index d49eaa6e..54254f1f 100755
--- a/CPP/7zip/UI/FileManager/RegistryPlugins.cpp
+++ b/CPP/7zip/UI/FileManager/RegistryPlugins.cpp
@@ -3,12 +3,11 @@
#include "StdAfx.h"
#include "Windows/DLL.h"
-#include "Windows/PropVariant.h"
#include "Windows/FileFind.h"
+#include "Windows/PropVariant.h"
-#include "ProgramLocation.h"
-#include "RegistryPlugins.h"
#include "IFolder.h"
+#include "RegistryPlugins.h"
using namespace NWindows;
using namespace NFile;
@@ -91,23 +90,20 @@ static bool ReadPluginInfo(CPluginInfo &pluginInfo, bool needCheckDll)
return true;
}
-UString GetProgramFolderPrefix();
-
void ReadPluginInfoList(CObjectVector<CPluginInfo> &plugins)
{
plugins.Clear();
- UString baseFolderPrefix;
- GetProgramFolderPath(baseFolderPrefix);
+ FString baseFolderPrefix = NDLL::GetModuleDirPrefix();
{
CPluginInfo pluginInfo;
- pluginInfo.FilePath = baseFolderPrefix + L"7-zip.dll";
+ pluginInfo.FilePath = baseFolderPrefix + FTEXT("7-zip.dll");
if (::ReadPluginInfo(pluginInfo, false))
plugins.Add(pluginInfo);
}
- UString folderPath = baseFolderPrefix + L"Plugins" WSTRING_PATH_SEPARATOR;
- NFind::CEnumeratorW enumerator(folderPath + L"*");
- NFind::CFileInfoW fileInfo;
+ FString folderPath = baseFolderPrefix + FTEXT("Plugins") FSTRING_PATH_SEPARATOR;
+ NFind::CEnumerator enumerator(folderPath + FCHAR_ANY_MASK);
+ NFind::CFileInfo fileInfo;
while (enumerator.Next(fileInfo))
{
if (fileInfo.IsDir())
diff --git a/CPP/7zip/UI/FileManager/RegistryPlugins.h b/CPP/7zip/UI/FileManager/RegistryPlugins.h
index 77055ac7..20f2ec34 100755
--- a/CPP/7zip/UI/FileManager/RegistryPlugins.h
+++ b/CPP/7zip/UI/FileManager/RegistryPlugins.h
@@ -1,7 +1,7 @@
// RegistryPlugins.h
-#ifndef __REGISTRYPLUGINS_H
-#define __REGISTRYPLUGINS_H
+#ifndef __REGISTRY_PLUGINS_H
+#define __REGISTRY_PLUGINS_H
#include "Common/MyString.h"
@@ -12,7 +12,7 @@ enum EPluginType
struct CPluginInfo
{
- UString FilePath;
+ FString FilePath;
EPluginType Type;
UString Name;
CLSID ClassID;
diff --git a/CPP/7zip/UI/FileManager/RootFolder.cpp b/CPP/7zip/UI/FileManager/RootFolder.cpp
index 0715a8be..a81f94c1 100755
--- a/CPP/7zip/UI/FileManager/RootFolder.cpp
+++ b/CPP/7zip/UI/FileManager/RootFolder.cpp
@@ -30,7 +30,7 @@ static const STATPROPSTG kProps[] =
UString RootFolder_GetName_Computer(int &iconIndex)
{
#ifdef UNDER_CE
- GetRealIconIndex(L"\\", FILE_ATTRIBUTE_DIRECTORY, iconIndex);
+ GetRealIconIndex(FTEXT("\\"), FILE_ATTRIBUTE_DIRECTORY, iconIndex);
#else
iconIndex = GetIconIndexForCSIDL(CSIDL_DRIVES);
#endif
@@ -123,7 +123,7 @@ UString GetMyDocsPath()
us = GetUnicodeString(s2);
}
#endif
- if (us.Length() > 0 && us[us.Length() - 1] != WCHAR_PATH_SEPARATOR)
+ if (us.Length() > 0 && us.Back() != WCHAR_PATH_SEPARATOR)
us += WCHAR_PATH_SEPARATOR;
return us;
}
@@ -159,7 +159,7 @@ STDMETHODIMP CRootFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolde
{
NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder;
subFolder = fsFolderSpec;
- RINOK(fsFolderSpec->Init(s, NULL));
+ RINOK(fsFolderSpec->Init(us2fs(s), NULL));
}
}
#endif
@@ -227,7 +227,7 @@ STDMETHODIMP CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resu
name2 += WCHAR_PATH_SEPARATOR;
NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder;
subFolder = fsFolderSpec;
- if (fsFolderSpec->Init(name2, 0) != S_OK)
+ if (fsFolderSpec->Init(us2fs(name2), 0) != S_OK)
{
#ifndef UNDER_CE
if (name2[0] == WCHAR_PATH_SEPARATOR)
diff --git a/CPP/7zip/UI/FileManager/SettingsPage.cpp b/CPP/7zip/UI/FileManager/SettingsPage.cpp
index 10d063f7..866b0b2d 100755
--- a/CPP/7zip/UI/FileManager/SettingsPage.cpp
+++ b/CPP/7zip/UI/FileManager/SettingsPage.cpp
@@ -10,7 +10,6 @@
#include "HelpUtils.h"
#include "LangUtils.h"
-#include "ProgramLocation.h"
#include "RegistryUtils.h"
#include "SettingsPage.h"
diff --git a/CPP/7zip/UI/FileManager/SysIconUtils.cpp b/CPP/7zip/UI/FileManager/SysIconUtils.cpp
index e359ed2b..e537621e 100755
--- a/CPP/7zip/UI/FileManager/SysIconUtils.cpp
+++ b/CPP/7zip/UI/FileManager/SysIconUtils.cpp
@@ -24,7 +24,7 @@ int GetIconIndexForCSIDL(int csidl)
SHGFI_PIDL | SHGFI_SYSICONINDEX);
IMalloc *pMalloc;
SHGetMalloc(&pMalloc);
- if(pMalloc)
+ if (pMalloc)
{
pMalloc->Free(pidl);
pMalloc->Release();
@@ -34,16 +34,6 @@ int GetIconIndexForCSIDL(int csidl)
return 0;
}
-DWORD_PTR GetRealIconIndex(LPCTSTR path, DWORD attrib, int &iconIndex)
-{
- SHFILEINFO shellInfo;
- DWORD_PTR res = ::SHGetFileInfo(path, FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo,
- sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);
- iconIndex = shellInfo.iIcon;
- return res;
-}
-
-
#ifndef _UNICODE
typedef int (WINAPI * SHGetFileInfoWP)(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags);
@@ -70,28 +60,32 @@ static DWORD_PTR MySHGetFileInfoW(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *ps
pszPath, attrib, psfi, cbFileInfo, uFlags);
}
-#ifndef _UNICODE
-// static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
-DWORD_PTR GetRealIconIndex(LPCWSTR path, DWORD attrib, int &iconIndex)
+DWORD_PTR GetRealIconIndex(CFSTR path, DWORD attrib, int &iconIndex)
{
- if(g_IsNT)
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- SHFILEINFOW shellInfo;
- DWORD_PTR res = ::MySHGetFileInfoW(path, FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo,
+ SHFILEINFO shellInfo;
+ DWORD_PTR res = ::SHGetFileInfo(fs2fas(path), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo,
sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);
iconIndex = shellInfo.iIcon;
return res;
}
else
- return GetRealIconIndex(UnicodeStringToMultiByte(path), attrib, iconIndex);
+ #endif
+ {
+ SHFILEINFOW shellInfo;
+ DWORD_PTR res = ::MySHGetFileInfoW(fs2us(path), FILE_ATTRIBUTE_NORMAL | attrib, &shellInfo,
+ sizeof(shellInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);
+ iconIndex = shellInfo.iIcon;
+ return res;
+ }
}
-#endif
-DWORD_PTR GetRealIconIndex(const UString &fileName, DWORD attrib,
- int &iconIndex, UString &typeName)
+DWORD_PTR GetRealIconIndex(const UString &fileName, DWORD attrib, int &iconIndex, UString &typeName)
{
#ifndef _UNICODE
- if(!g_IsNT)
+ if (!g_IsNT)
{
SHFILEINFO shellInfo;
shellInfo.szTypeName[0] = 0;
diff --git a/CPP/7zip/UI/FileManager/SysIconUtils.h b/CPP/7zip/UI/FileManager/SysIconUtils.h
index 5ba9c57f..129de781 100755
--- a/CPP/7zip/UI/FileManager/SysIconUtils.h
+++ b/CPP/7zip/UI/FileManager/SysIconUtils.h
@@ -39,10 +39,7 @@ public:
int GetIconIndex(DWORD attrib, const UString &fileName);
};
-DWORD_PTR GetRealIconIndex(LPCTSTR path, DWORD attrib, int &iconIndex);
-#ifndef _UNICODE
-DWORD_PTR GetRealIconIndex(LPCWSTR path, DWORD attrib, int &iconIndex);
-#endif
+DWORD_PTR GetRealIconIndex(CFSTR path, DWORD attrib, int &iconIndex);
int GetIconIndexForCSIDL(int csidl);
inline HIMAGELIST GetSysImageList(bool smallIcons)
diff --git a/CPP/7zip/UI/FileManager/SystemPage.cpp b/CPP/7zip/UI/FileManager/SystemPage.cpp
index 3681992d..359656ea 100755
--- a/CPP/7zip/UI/FileManager/SystemPage.cpp
+++ b/CPP/7zip/UI/FileManager/SystemPage.cpp
@@ -1,172 +1,266 @@
// SystemPage.cpp
#include "StdAfx.h"
-#include "SystemPageRes.h"
-#include "SystemPage.h"
#include "Common/StringConvert.h"
-#include "Common/MyCom.h"
-#include "Windows/Defs.h"
-#include "Windows/Control/ListView.h"
-#include "Windows/FileFind.h"
+#include "Windows/DLL.h"
+#include "Windows/Error.h"
-#include "IFolder.h"
#include "HelpUtils.h"
+#include "IFolder.h"
#include "LangUtils.h"
-#include "PluginLoader.h"
-#include "ProgramLocation.h"
-#include "StringUtils.h"
-
#include "PropertyNameRes.h"
-#include "../Agent/Agent.h"
+#include "SystemPage.h"
+#include "SystemPageRes.h"
-using namespace NRegistryAssociations;
+static const CIDLangPair kIDLangPairs[] =
+{
+ { IDC_SYSTEM_STATIC_ASSOCIATE, 0x03010302}
+ // { IDC_SYSTEM_SELECT_ALL, 0x03000330}
+};
-const int kRefreshpluginsListMessage = WM_USER + 1;
-const int kUpdateDatabase = kRefreshpluginsListMessage + 1;
+static LPCWSTR kSystemTopic = L"FM/options.htm#system";
-static CIDLangPair kIDLangPairs[] =
+CSysString CModifiedExtInfo::GetString() const
{
- { IDC_SYSTEM_STATIC_ASSOCIATE, 0x03010302},
- { IDC_SYSTEM_SELECT_ALL, 0x03000330}
+ if (State == kExtState_7Zip)
+ return TEXT("7-Zip");
+ if (State == kExtState_Clear)
+ return TEXT("");
+ if (Other7Zip)
+ return TEXT("[7-Zip]");
+ return ProgramKey;
};
-static LPCWSTR kSystemTopic = L"FM/options.htm#system";
+int CSystemPage::AddIcon(const UString &iconPath, int iconIndex)
+{
+ if (iconPath.IsEmpty())
+ return -1;
+ if (iconIndex == -1)
+ iconIndex = 0;
+ HICON hicon;
+ #ifdef UNDER_CE
+ ExtractIconExW(iconPath, iconIndex, NULL, &hicon, 1);
+ if (!hicon)
+ #else
+ // we expand path from REG_EXPAND_SZ registry item.
+ UString path;
+ DWORD size = MAX_PATH + 10;
+ DWORD needLen = ::ExpandEnvironmentStringsW(iconPath, path.GetBuffer((int)size + 1), size);
+ path.ReleaseBuffer();
+ if (needLen == 0 || needLen >= size)
+ path = iconPath;
+ int num = ExtractIconExW(path, iconIndex, NULL, &hicon, 1);
+ if (num != 1 || !hicon)
+ #endif
+ return -1;
+ _imageList.AddIcon(hicon);
+ DestroyIcon(hicon);
+ return _numIcons++;
+}
+void CSystemPage::RefreshListItem(int group, int listIndex)
+{
+ const CAssoc &assoc = _items[GetRealIndex(listIndex)];
+ _listView.SetSubItem(listIndex, group + 1, assoc.Pair[group].GetString());
+ LVITEMW newItem;
+ memset(&newItem, 0, sizeof(newItem));
+ newItem.iItem = listIndex;
+ newItem.mask = LVIF_IMAGE;
+ newItem.iImage = assoc.GetIconIndex();
+ _listView.SetItem(&newItem);
+}
+
+void CSystemPage::ChangeState(int group, const CIntVector &indices)
+{
+ if (indices.IsEmpty())
+ return;
+
+ bool thereAreClearItems = false;
+ int counters[3] = { 0, 0, 0 };
+
+ int i;
+ for (i = 0; i < indices.Size(); i++)
+ {
+ const CModifiedExtInfo &mi = _items[GetRealIndex(indices[i])].Pair[group];
+ int state = kExtState_7Zip;
+ if (mi.State == kExtState_7Zip)
+ state = kExtState_Clear;
+ else if (mi.State == kExtState_Clear)
+ {
+ thereAreClearItems = true;
+ if (mi.Other)
+ state = kExtState_Other;
+ }
+ counters[state]++;
+ }
+
+ int state = kExtState_Clear;
+ if (counters[kExtState_Other] != 0)
+ state = kExtState_Other;
+ else if (counters[kExtState_7Zip] != 0)
+ state = kExtState_7Zip;
+
+ for (i = 0; i < indices.Size(); i++)
+ {
+ int listIndex = indices[i];
+ CAssoc &assoc = _items[GetRealIndex(listIndex)];
+ CModifiedExtInfo &mi = assoc.Pair[group];
+ bool change = false;
+ switch (state)
+ {
+ case kExtState_Clear: change = true; break;
+ case kExtState_Other: change = mi.Other; break;
+ default: change = !(mi.Other && thereAreClearItems); break;
+ }
+ if (change)
+ {
+ mi.State = state;
+ RefreshListItem(group, listIndex);
+ }
+ }
+ Changed();
+}
bool CSystemPage::OnInit()
{
- _initMode = true;
- LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+ LangSetDlgItemsText((HWND)*this, kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));
+
+ _listView.Attach(GetItem(IDC_SYSTEM_LIST_ASSOCIATE));
+ _listView.SetUnicodeFormat();
+ DWORD newFlags = LVS_EX_FULLROWSELECT;
+ _listView.SetExtendedListViewStyle(newFlags, newFlags);
- _listViewExt.Attach(GetItem(IDC_SYSTEM_LIST_ASSOCIATE));
- _listViewPlugins.Attach(GetItem(IDC_SYSTEM_LIST_PLUGINS));
+ _numIcons = 0;
+ _imageList.Create(16, 16, ILC_MASK | ILC_COLOR32, 0, 0);
- /*
- CheckButton(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU,
- NRegistryAssociations::CheckContextMenuHandler());
- */
+ _listView.SetImageList(_imageList, LVSIL_SMALL);
- UINT32 newFlags = LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT;
- _listViewExt.SetExtendedListViewStyle(newFlags, newFlags);
- _listViewPlugins.SetExtendedListViewStyle(newFlags, newFlags);
+ _listView.InsertColumn(0, LangString(IDS_PROP_FILE_TYPE, 0x02000214), 72);
- _listViewExt.InsertColumn(0, LangString(IDS_PROP_EXTENSION, 0x02000205), 40);
- const UString s = LangString(IDS_PLUGIN, 0x03010310);
- _listViewExt.InsertColumn(1, s, 40);
+ CSysString s;
- _listViewPlugins.InsertColumn(0, s, 40);
+ #if NUM_EXT_GROUPS == 1
+ s = TEXT("Program");
+ #else
+ #ifndef UNDER_CE
+ DWORD size = 256;
+ BOOL res = GetUserName(s.GetBuffer(size), &size);
+ s.ReleaseBuffer();
+ if (!res)
+ #endif
+ s = TEXT("Current User");
+ #endif
- _extDatabase.Read();
+ LVCOLUMN ci;
+ ci.mask = LVCF_TEXT | LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
+ ci.cx = 100;
+ ci.pszText = (TCHAR *)(const TCHAR *)s;
+ ci.iSubItem = 1;
+ ci.fmt = LVCFMT_CENTER;
+ _listView.InsertColumn(1, &ci);
- for (int i = 0; i < _extDatabase.ExtBigItems.Size(); i++)
+ #if NUM_EXT_GROUPS > 1
{
- CExtInfoBig &extInfo = _extDatabase.ExtBigItems[i];
-
- int itemIndex = _listViewExt.InsertItem(i, (LPCWSTR)extInfo.Ext);
+ ci.iSubItem = 2;
+ ci.pszText = TEXT("All Users");
+ _listView.InsertColumn(2, &ci);
+ }
+ #endif
- UString iconPath;
- int iconIndex;
- extInfo.Associated = NRegistryAssociations::CheckShellExtensionInfo(GetSystemString(extInfo.Ext), iconPath, iconIndex);
- if (extInfo.Associated && !NWindows::NFile::NFind::DoesFileExist(iconPath))
- extInfo.Associated = false;
- _listViewExt.SetCheckState(itemIndex, extInfo.Associated);
+ _extDB.Read();
+ _items.Clear();
- SetMainPluginText(itemIndex, i);
+ for (int i = 0; i < _extDB.Exts.Size(); i++)
+ {
+ const CExtPlugins &extInfo = _extDB.Exts[i];
+
+ LVITEMW item;
+ item.iItem = i;
+ item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
+ item.lParam = i;
+ item.iSubItem = 0;
+ // ListView always uses internal iImage that is 0 by default?
+ // so we always use LVIF_IMAGE.
+ item.iImage = -1;
+ item.pszText = (wchar_t *)(const wchar_t *)(LPCWSTR)extInfo.Ext;
+
+ CAssoc assoc;
+ const CPluginToIcon &plug = extInfo.Plugins[0];
+ assoc.SevenZipImageIndex = AddIcon(plug.IconPath, plug.IconIndex);
+
+ CSysString texts[NUM_EXT_GROUPS];
+ int g;
+ for (g = 0; g < NUM_EXT_GROUPS; g++)
+ {
+ CModifiedExtInfo &mi = assoc.Pair[g];
+ mi.ReadFromRegistry(GetHKey(g), GetSystemString(extInfo.Ext));
+ mi.SetState(plug.IconPath);
+ mi.ImageIndex = AddIcon(mi.IconPath, mi.IconIndex);
+ texts[g] = mi.GetString();
+ }
+ item.iImage = assoc.GetIconIndex();
+ int itemIndex = _listView.InsertItem(&item);
+ for (g = 0; g < NUM_EXT_GROUPS; g++)
+ _listView.SetSubItem(itemIndex, 1 + g, texts[g]);
+ _items.Add(assoc);
}
- // _listViewExt.SortItems();
- if (_listViewExt.GetItemCount() > 0)
- _listViewExt.SetItemState_FocusedSelected(0);
- RefreshPluginsList(-1);
- _initMode = false;
+ if (_listView.GetItemCount() > 0)
+ _listView.SetItemState(0, LVIS_FOCUSED, LVIS_FOCUSED);
return CPropertyPage::OnInit();
}
-void CSystemPage::SetMainPluginText(int itemIndex, int indexInDatabase)
-{
- _listViewExt.SetSubItem(itemIndex, 1, _extDatabase.GetMainPluginNameForExtItem(indexInDatabase));
-}
-
static UString GetProgramCommand()
{
- UString path = L"\"";
- UString folder;
- if (GetProgramFolderPath(folder))
- path += folder;
- path += L"7zFM.exe\" \"%1\"";
- return path;
-}
-
-static UString GetIconPath(const UString &filePath,
- const CLSID &clsID, const UString &extension, Int32 &iconIndex)
-{
- CPluginLibrary library;
- CMyComPtr<IFolderManager> folderManager;
- CMyComPtr<IFolderFolder> folder;
- if (filePath.IsEmpty())
- folderManager = new CArchiveFolderManager;
- else if (library.LoadAndCreateManager(filePath, clsID, &folderManager) != S_OK)
- return UString();
- CMyComBSTR extBSTR;
- if (folderManager->GetExtensions(&extBSTR) != S_OK)
- return UString();
- const UString ext2 = (const wchar_t *)extBSTR;
- UStringVector exts;
- SplitString(ext2, exts);
- for (int i = 0; i < exts.Size(); i++)
- {
- const UString &plugExt = exts[i];
- if (extension.CompareNoCase((const wchar_t *)plugExt) == 0)
- {
- CMyComBSTR iconPathTemp;
- if (folderManager->GetIconPath(plugExt, &iconPathTemp, &iconIndex) != S_OK)
- break;
- if (iconPathTemp != 0)
- return (const wchar_t *)iconPathTemp;
- }
- }
- return UString();
+ return L"\"" + fs2us(NWindows::NDLL::GetModuleDirPrefix()) + L"7zFM.exe\" \"%1\"";
}
LONG CSystemPage::OnApply()
{
- UpdateDatabase();
- _extDatabase.Save();
- UString command = GetProgramCommand();
+ const UString command = GetProgramCommand();
- for (int i = 0; i < _extDatabase.ExtBigItems.Size(); i++)
+ LONG res = 0;
+
+ for (int listIndex = 0; listIndex < _extDB.Exts.Size(); listIndex++)
{
- const CExtInfoBig &extInfo = _extDatabase.ExtBigItems[i];
- if (extInfo.Associated)
+ int realIndex = GetRealIndex(listIndex);
+ const CExtPlugins &extInfo = _extDB.Exts[realIndex];
+ CAssoc &assoc = _items[realIndex];
+
+ for (int g = 0; g < NUM_EXT_GROUPS; g++)
{
- UString title = extInfo.Ext + UString(L" Archive");
- UString command = GetProgramCommand();
- UString iconPath;
- Int32 iconIndex = -1;
- if (!extInfo.PluginsPairs.IsEmpty())
+ CModifiedExtInfo &mi = assoc.Pair[g];
+ HKEY key = GetHKey(g);
+ if (mi.OldState != mi.State)
{
- const CPluginInfo &plugin = _extDatabase.Plugins[extInfo.PluginsPairs[0].Index];
- iconPath = GetIconPath(plugin.FilePath, plugin.ClassID, extInfo.Ext, iconIndex);
+ LONG res2 = 0;
+ if (mi.State == kExtState_7Zip)
+ {
+ UString title = extInfo.Ext + UString(L" Archive");
+ const CPluginToIcon &plug = extInfo.Plugins[0];
+ res2 = NRegistryAssoc::AddShellExtensionInfo(key, GetSystemString(extInfo.Ext),
+ title, command, plug.IconPath, plug.IconIndex);
+ }
+ else if (mi.State == kExtState_Clear)
+ res2 = NRegistryAssoc::DeleteShellExtensionInfo(key, GetSystemString(extInfo.Ext));
+ if (res == 0)
+ res = res2;
+ if (res2 == 0)
+ mi.OldState = mi.State;
+ mi.State = mi.OldState;
+ RefreshListItem(g, listIndex);
}
- NRegistryAssociations::AddShellExtensionInfo(GetSystemString(extInfo.Ext),
- title, command, iconPath, iconIndex, NULL, 0);
}
- else
- NRegistryAssociations::DeleteShellExtensionInfo(GetSystemString(extInfo.Ext));
}
- /*
- if (IsButtonCheckedBool(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU))
- NRegistryAssociations::AddContextMenuHandler();
- else
- NRegistryAssociations::DeleteContextMenuHandler();
- */
#ifndef UNDER_CE
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
WasChanged = true;
#endif
+ if (res != 0)
+ MessageBoxW(*this, NWindows::NError::MyFormatMessageW(res), L"7-Zip", MB_ICONERROR);
return PSNRET_NOERROR;
}
@@ -175,228 +269,119 @@ void CSystemPage::OnNotifyHelp()
ShowHelpWindow(NULL, kSystemTopic);
}
-void CSystemPage::SelectAll()
-{
- int count = _listViewExt.GetItemCount();
- for (int i = 0; i < count; i++)
- _listViewExt.SetCheckState(i, true);
- UpdateDatabase();
-}
-
bool CSystemPage::OnButtonClicked(int buttonID, HWND buttonHWND)
{
- switch(buttonID)
+ switch (buttonID)
{
+ /*
case IDC_SYSTEM_SELECT_ALL:
- {
- SelectAll();
- Changed();
+ _listView.SelectAll();
+ return true;
+ */
+ case IDC_SYSTEM_BUTTON_CURRENT:
+ case IDC_SYSTEM_BUTTON_ALL:
+ ChangeState(buttonID == IDC_SYSTEM_BUTTON_CURRENT ? 0 : 1);
return true;
- }
}
return CPropertyPage::OnButtonClicked(buttonID, buttonHWND);
}
bool CSystemPage::OnNotify(UINT controlID, LPNMHDR lParam)
{
- if (lParam->hwndFrom == HWND(_listViewExt))
+ if (lParam->hwndFrom == HWND(_listView))
{
- switch(lParam->code)
+ switch (lParam->code)
{
- case (LVN_ITEMCHANGED):
- return OnItemChanged((const NMLISTVIEW *)lParam);
- case NM_RCLICK:
- case NM_DBLCLK:
- case LVN_KEYDOWN:
- case NM_CLICK:
- case LVN_BEGINRDRAG:
- PostMessage(kRefreshpluginsListMessage, 0);
- PostMessage(kUpdateDatabase, 0);
- break;
- }
- }
- else if (lParam->hwndFrom == HWND(_listViewPlugins))
- {
- switch(lParam->code)
- {
- case NM_RCLICK:
- case NM_DBLCLK:
- // case LVN_KEYDOWN:
+ case NM_RETURN:
+ {
+ ChangeState(0);
+ return true;
+ }
+ break;
case NM_CLICK:
- case LVN_BEGINRDRAG:
- PostMessage(kUpdateDatabase, 0);
- break;
-
- case (LVN_ITEMCHANGED):
{
- OnItemChanged((const NMLISTVIEW *)lParam);
- PostMessage(kUpdateDatabase, 0);
+ #ifdef UNDER_CE
+ NMLISTVIEW *item = (NMLISTVIEW *)lParam;
+ #else
+ NMITEMACTIVATE *item = (NMITEMACTIVATE *)lParam;
+ if (item->uKeyFlags == 0)
+ #endif
+ {
+ int realIndex = GetRealIndex(item->iItem);
+ if (realIndex >= 0)
+ {
+ if (item->iSubItem >= 1 && item->iSubItem <= 2)
+ {
+ CIntVector indices;
+ indices.Add(item->iItem);
+ ChangeState(item->iSubItem < 2 ? 0 : 1, indices);
+ }
+ }
+ }
break;
}
case LVN_KEYDOWN:
{
- OnPluginsKeyDown((LPNMLVKEYDOWN)lParam);
- PostMessage(kUpdateDatabase, 0);
+ if (OnListKeyDown(LPNMLVKEYDOWN(lParam)))
+ return true;
break;
}
+ /*
+ case NM_RCLICK:
+ case NM_DBLCLK:
+ case LVN_BEGINRDRAG:
+ // PostMessage(kRefreshpluginsListMessage, 0);
+ PostMessage(kUpdateDatabase, 0);
+ break;
+ */
}
}
return CPropertyPage::OnNotify(controlID, lParam);
}
-bool CSystemPage::OnPluginsKeyDown(LPNMLVKEYDOWN keyDownInfo)
+void CSystemPage::ChangeState(int group)
{
- bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
- // bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
- switch(keyDownInfo->wVKey)
- {
- case VK_UP:
- {
- if (alt)
- MovePlugin(true);
- return true;
- }
- case VK_DOWN:
- {
- if (alt)
- MovePlugin(false);
- return true;
- }
- }
- return false;
+ CIntVector indices;
+ int itemIndex = -1;
+ while ((itemIndex = _listView.GetNextSelectedItem(itemIndex)) != -1)
+ indices.Add(itemIndex);
+ if (indices.IsEmpty())
+ for (int i = 0; i < _items.Size(); i++)
+ indices.Add(i);
+ ChangeState(group, indices);
}
-void CSystemPage::MovePlugin(bool upDirection)
+bool CSystemPage::OnListKeyDown(LPNMLVKEYDOWN keyDownInfo)
{
- int selectedPlugin = _listViewPlugins.GetSelectionMark();
- if (selectedPlugin < 0)
- return;
- int newIndex = selectedPlugin + (upDirection ? -1: 1);
- if (newIndex < 0 || newIndex >= _listViewPlugins.GetItemCount())
- return;
- int selectedExtIndex = GetSelectedExtIndex();
- if (selectedExtIndex < 0)
- return;
- CExtInfoBig &extInfo = _extDatabase.ExtBigItems[selectedExtIndex];
- CPluginEnabledPair pluginPairTemp = extInfo.PluginsPairs[newIndex];
- extInfo.PluginsPairs[newIndex] = extInfo.PluginsPairs[selectedPlugin];
- extInfo.PluginsPairs[selectedPlugin] = pluginPairTemp;
-
- SetMainPluginText(_listViewExt.GetSelectionMark(), selectedExtIndex);
- RefreshPluginsList(newIndex);
-
- Changed();
-}
-
-bool CSystemPage::OnItemChanged(const NMLISTVIEW *info)
-{
- if (_initMode)
- return true;
- if ((info->uChanged & LVIF_STATE) != 0)
- {
- UINT oldState = info->uOldState & LVIS_STATEIMAGEMASK;
- UINT newState = info->uNewState & LVIS_STATEIMAGEMASK;
- if (oldState != newState)
- Changed();
- }
- // PostMessage(kRefreshpluginsListMessage, 0);
- // RefreshPluginsList();
- return true;
-}
-
-bool CSystemPage::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
-{
- switch(message)
- {
- case kRefreshpluginsListMessage:
- RefreshPluginsList(-1);
- return true;
- case kUpdateDatabase:
- UpdateDatabase();
- return true;
- }
- return CPropertyPage::OnMessage(message, wParam, lParam);
-}
+ bool ctrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0;
+ bool alt = (::GetKeyState(VK_MENU) & 0x8000) != 0;
-void CSystemPage::UpdateDatabase()
-{
- int i;
- for (i = 0; i < _listViewExt.GetItemCount(); i++)
- {
- LPARAM param;
- if (!_listViewExt.GetItemParam(i, param))
- return;
- CExtInfoBig &extInfo = _extDatabase.ExtBigItems[(int)param];
- extInfo.Associated = _listViewExt.GetCheckState(i);
- }
+ if (alt)
+ return false;
- int selectedExtIndex = GetSelectedExtIndex();
- if (selectedExtIndex < 0)
- return;
-
- CExtInfoBig &extInfo = _extDatabase.ExtBigItems[selectedExtIndex];
- for (i = 0; i < _listViewPlugins.GetItemCount(); i++)
+ if ((ctrl && keyDownInfo->wVKey == 'A') ||
+ (!ctrl && keyDownInfo->wVKey == VK_MULTIPLY))
{
- extInfo.PluginsPairs[i].Enabled = _listViewPlugins.GetCheckState(i);
+ _listView.SelectAll();
+ return true;
}
-}
-
-
-
-int CSystemPage::GetSelectedExtIndex()
-{
- int selectedIndex = _listViewExt.GetSelectionMark();
- if (selectedIndex < 0)
- return -1;
- LPARAM param;
- if (!_listViewExt.GetItemParam(selectedIndex, param))
- return -1;
- return (int)param;
-}
-
-
-void CSystemPage::RefreshPluginsList(int selectIndex)
-{
- _listViewPlugins.DeleteAllItems();
- int selectedExtIndex = GetSelectedExtIndex();
- if (selectedExtIndex < 0)
- return;
- const CExtInfoBig &extInfo = _extDatabase.ExtBigItems[selectedExtIndex];
- _initMode = true;
- for (int i = 0; i < extInfo.PluginsPairs.Size(); i++)
+ switch (keyDownInfo->wVKey)
{
- CPluginEnabledPair pluginPair = extInfo.PluginsPairs[i];
- int itemIndex = _listViewPlugins.InsertItem(i, _extDatabase.Plugins[pluginPair.Index].Name);
- _listViewPlugins.SetCheckState(itemIndex, pluginPair.Enabled);
- }
- if (_listViewPlugins.GetItemCount() > 0)
- {
- if (selectIndex < 0)
- selectIndex = 0;
- _listViewPlugins.SetItemState_FocusedSelected(selectIndex);
+ case VK_SPACE:
+ case VK_ADD:
+ case VK_SUBTRACT:
+ case VK_SEPARATOR:
+ case VK_DIVIDE:
+ #ifndef UNDER_CE
+ case VK_OEM_PLUS:
+ case VK_OEM_MINUS:
+ #endif
+ if (!ctrl)
+ {
+ ChangeState(keyDownInfo->wVKey == VK_SPACE ? 0 : 1);
+ return true;
+ }
}
- _initMode = false;
+ return false;
}
-
-
-
-/*
-static BYTE kZipShellNewData[] =
- { 0x50-1, 0x4B, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0 };
-
-static BYTE kRarShellNewData[] =
- { 0x52-1, 0x61, 0x72, 0x21, 0x1A, 7, 0, 0xCF, 0x90, 0x73, 0, 0, 0x0D, 0, 0, 0, 0, 0, 0, 0};
-
-class CSignatureMaker
-{
-public:
- CSignatureMaker()
- {
- kZipShellNewData[0]++;
- kRarShellNewData[0]++;
- };
-};
-
-static CSignatureMaker g_SignatureMaker;
-*/
diff --git a/CPP/7zip/UI/FileManager/SystemPage.h b/CPP/7zip/UI/FileManager/SystemPage.h
index 967731fd..a4b4ab92 100755
--- a/CPP/7zip/UI/FileManager/SystemPage.h
+++ b/CPP/7zip/UI/FileManager/SystemPage.h
@@ -3,39 +3,117 @@
#ifndef __SYSTEM_PAGE_H
#define __SYSTEM_PAGE_H
-#include "Windows/Control/PropertyPage.h"
+#include "Windows/Control/ImageList.h"
#include "Windows/Control/ListView.h"
+#include "Windows/Control/PropertyPage.h"
#include "FilePlugins.h"
+#include "RegistryAssociations.h"
+
+enum EExtState
+{
+ kExtState_Clear = 0,
+ kExtState_Other,
+ kExtState_7Zip
+};
+
+struct CModifiedExtInfo: public NRegistryAssoc::CShellExtInfo
+{
+ int OldState;
+ int State;
+ int ImageIndex;
+ bool Other;
+ bool Other7Zip;
+
+ CModifiedExtInfo(): ImageIndex(-1) {}
+
+ CSysString GetString() const;
+
+ void SetState(const UString &iconPath)
+ {
+ State = kExtState_Clear;
+ Other = false;
+ Other7Zip = false;
+ if (!ProgramKey.IsEmpty())
+ {
+ State = kExtState_Other;
+ Other = true;
+ if (IsIt7Zip())
+ {
+ Other7Zip = (iconPath.CompareNoCase(IconPath) != 0);
+ if (!Other7Zip)
+ {
+ State = kExtState_7Zip;
+ Other = false;
+ }
+ }
+ }
+ OldState = State;
+ };
+};
+
+struct CAssoc
+{
+ CModifiedExtInfo Pair[2];
+ int SevenZipImageIndex;
+
+ int GetIconIndex() const
+ {
+ for (int i = 0; i < 2; i++)
+ {
+ const CModifiedExtInfo &pair = Pair[i];
+ if (pair.State == kExtState_Clear)
+ continue;
+ if (pair.State == kExtState_7Zip)
+ return SevenZipImageIndex;
+ if (pair.ImageIndex != -1)
+ return pair.ImageIndex;
+ }
+ return -1;
+ }
+};
+
+#ifdef UNDER_CE
+ #define NUM_EXT_GROUPS 1
+#else
+ #define NUM_EXT_GROUPS 2
+#endif
class CSystemPage: public NWindows::NControl::CPropertyPage
{
- bool _initMode;
- CExtDatabase _extDatabase;
+ CExtDatabase _extDB;
+ CObjectVector<CAssoc> _items;
- NWindows::NControl::CListView _listViewExt;
- NWindows::NControl::CListView _listViewPlugins;
+ int _numIcons;
+ NWindows::NControl::CImageList _imageList;
+ NWindows::NControl::CListView _listView;
- void SetMainPluginText(int itemIndex, int indexInDatabase);
+ const HKEY GetHKey(int group) const
+ {
+ #if NUM_EXT_GROUPS == 1
+ return HKEY_CLASSES_ROOT;
+ #else
+ return group == 0 ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
+ #endif
+ }
- int GetSelectedExtIndex();
- void RefreshPluginsList(int selectIndex);
- void MovePlugin(bool upDirection);
- void UpdateDatabase();
- void SelectAll();
+ int AddIcon(const UString &path, int iconIndex);
+ int GetRealIndex(int listIndex) const { return listIndex; }
+ void RefreshListItem(int group, int listIndex);
+ void ChangeState(int group, const CIntVector &indices);
+ void ChangeState(int group);
+ bool OnListKeyDown(LPNMLVKEYDOWN keyDownInfo);
+
public:
bool WasChanged;
CSystemPage(): WasChanged(false) {}
- virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+
virtual bool OnInit();
virtual void OnNotifyHelp();
virtual bool OnNotify(UINT controlID, LPNMHDR lParam);
- virtual bool OnItemChanged(const NMLISTVIEW *info);
-
virtual LONG OnApply();
virtual bool OnButtonClicked(int buttonID, HWND buttonHWND);
- bool OnPluginsKeyDown(LPNMLVKEYDOWN keyDownInfo);
};
#endif
diff --git a/CPP/7zip/UI/FileManager/SystemPage.rc b/CPP/7zip/UI/FileManager/SystemPage.rc
index 52e60d19..49581c9b 100755
--- a/CPP/7zip/UI/FileManager/SystemPage.rc
+++ b/CPP/7zip/UI/FileManager/SystemPage.rc
@@ -2,16 +2,18 @@
#include "../../GuiCommon.rc"
#define xc 200
-#define yc 200
+#define yc 250
IDD_SYSTEM MY_PAGE
CAPTION "System"
BEGIN
LTEXT "Associate 7-Zip with:", IDC_SYSTEM_STATIC_ASSOCIATE, m, m, xc, 8
+ PUSHBUTTON "+", IDC_SYSTEM_BUTTON_CURRENT, 72, m + 12, 40, bys
+ PUSHBUTTON "+", IDC_SYSTEM_BUTTON_ALL, 140, m + 12, 40, bys
CONTROL "List1", IDC_SYSTEM_LIST_ASSOCIATE, "SysListView32",
- LVS_LIST | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP,
- m, m + 12, xc, (yc - m - 12 - 1 - bys)
- PUSHBUTTON "Select all", IDC_SYSTEM_SELECT_ALL, m, (ys - m - bys), 90, bys
+ LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,
+ m, m + 32, xc, (yc - m - 32 - 1)
+; PUSHBUTTON "Select all", IDC_SYSTEM_SELECT_ALL, m, m + 12, 60, bys
END
#ifdef UNDER_CE
@@ -28,10 +30,11 @@ IDD_SYSTEM_2 MY_PAGE
CAPTION "System"
BEGIN
LTEXT "Associate 7-Zip with:", IDC_SYSTEM_STATIC_ASSOCIATE, m, m, xc, 8
+ PUSHBUTTON "+", IDC_SYSTEM_BUTTON_CURRENT, 60, m + 12, 40, bys
CONTROL "List1", IDC_SYSTEM_LIST_ASSOCIATE, "SysListView32",
- LVS_LIST | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP,
- m, m + 12, xc, (yc - m - 12 - 1 - bys - 8)
- PUSHBUTTON "Select all", IDC_SYSTEM_SELECT_ALL, m, (ys - m - bys - 8), 90, bys
+ LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,
+ m, m + 32, xc, (yc - m - 32 - 1 - 8)
+; PUSHBUTTON "Select all", IDC_SYSTEM_SELECT_ALL, m, m + 12, 60, bys
END
#endif
diff --git a/CPP/7zip/UI/FileManager/SystemPageRes.h b/CPP/7zip/UI/FileManager/SystemPageRes.h
index b60b4533..133996e7 100755
--- a/CPP/7zip/UI/FileManager/SystemPageRes.h
+++ b/CPP/7zip/UI/FileManager/SystemPageRes.h
@@ -4,5 +4,7 @@
// #define IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU 1010
#define IDC_SYSTEM_STATIC_ASSOCIATE 1020
#define IDC_SYSTEM_LIST_ASSOCIATE 1021
-#define IDC_SYSTEM_LIST_PLUGINS 1022
-#define IDC_SYSTEM_SELECT_ALL 1023
+// #define IDC_SYSTEM_LIST_PLUGINS 1022
+// #define IDC_SYSTEM_SELECT_ALL 1023
+#define IDC_SYSTEM_BUTTON_CURRENT 1024
+#define IDC_SYSTEM_BUTTON_ALL 1025
diff --git a/CPP/7zip/UI/FileManager/resource.h b/CPP/7zip/UI/FileManager/resource.h
index 13c8e0e7..cdb77edf 100755
--- a/CPP/7zip/UI/FileManager/resource.h
+++ b/CPP/7zip/UI/FileManager/resource.h
@@ -52,6 +52,7 @@
#define IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT 463
#define IDM_OPTIONS 510
#define IDM_BENCHMARK 511
+#define IDM_BENCHMARK2 512
#define IDM_HELP_CONTENTS 610
#define IDM_ABOUT 620
#define IDS_BOOKMARK 720
diff --git a/CPP/7zip/UI/FileManager/resource.rc b/CPP/7zip/UI/FileManager/resource.rc
index 833cb374..2952ce5a 100755
--- a/CPP/7zip/UI/FileManager/resource.rc
+++ b/CPP/7zip/UI/FileManager/resource.rc
@@ -95,6 +95,9 @@ BEGIN
BEGIN
MENUITEM "&Options...", IDM_OPTIONS
MENUITEM "&Benchmark", IDM_BENCHMARK
+ #ifdef UNDER_CE
+ MENUITEM "&Benchmark2", IDM_BENCHMARK2
+ #endif
#ifndef UNDER_CE
END
POPUP "&Help"
diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.cpp b/CPP/7zip/UI/GUI/BenchmarkDialog.cpp
index e4d6c019..8ca87f8f 100755
--- a/CPP/7zip/UI/GUI/BenchmarkDialog.cpp
+++ b/CPP/7zip/UI/GUI/BenchmarkDialog.cpp
@@ -4,6 +4,7 @@
#include "Common/IntToString.h"
#include "Common/MyException.h"
+#include "Common/StringConvert.h"
#include "Windows/Error.h"
#include "Windows/System.h"
@@ -85,6 +86,25 @@ bool CBenchmarkDialog::OnInit()
Sync.Init();
+ if (TotalMode)
+ {
+ _consoleEdit.Attach(GetItem(IDC_BENCHMARK2_EDIT));
+ LOGFONT f;
+ memset(&f, 0, sizeof(f));
+ f.lfHeight = 14;
+ f.lfWidth = 0;
+ f.lfWeight = FW_DONTCARE;
+ f.lfCharSet = DEFAULT_CHARSET;
+ f.lfOutPrecision = OUT_DEFAULT_PRECIS;
+ f.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ f.lfQuality = DEFAULT_QUALITY;
+
+ f.lfPitchAndFamily = FIXED_PITCH;
+ MyStringCopy(f.lfFaceName, TEXT(""));
+ _font.Create(&f);
+ if (_font._font)
+ _consoleEdit.SendMessage(WM_SETFONT, (WPARAM)_font._font, TRUE);
+ }
UInt32 numCPUs = NSystem::GetNumberOfProcessors();
if (numCPUs < 1)
@@ -101,8 +121,8 @@ bool CBenchmarkDialog::OnInit()
int cur = 0;
for (UInt32 num = 1; num <= numCPUs * 2;)
{
- TCHAR s[40];
- ConvertUInt64ToString(num, s);
+ TCHAR s[16];
+ ConvertUInt32ToString(num, s);
int index = (int)m_NumThreads.AddString(s);
m_NumThreads.SetItemData(index, num);
if (num <= Sync.NumThreads)
@@ -143,8 +163,8 @@ bool CBenchmarkDialog::OnInit()
UInt32 dictionary = (1 << i) + (j << (i - 1));
if (dictionary > kMaxDicSize)
continue;
- TCHAR s[40];
- ConvertUInt64ToString((dictionary >> 20), s);
+ TCHAR s[16];
+ ConvertUInt32ToString((dictionary >> 20), s);
lstrcat(s, kMB);
int index = (int)m_Dictionary.AddString(s);
m_Dictionary.SetItemData(index, dictionary);
@@ -158,10 +178,47 @@ bool CBenchmarkDialog::OnInit()
Sync._startEvent.Set();
_timer = SetTimer(kTimerID, kTimerElapse);
- NormalizePosition();
+ if (TotalMode)
+ NormalizeSize(true);
+ else
+ NormalizePosition();
return CModalDialog::OnInit();
}
+bool CBenchmarkDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize)
+{
+ if (!TotalMode)
+ return false;
+ int mx, my;
+ GetMargins(8, mx, my);
+ int bx1, bx2, by;
+ GetItemSizes(IDCANCEL, bx1, by);
+ GetItemSizes(IDHELP, bx2, by);
+ int y = ySize - my - by;
+ int x = xSize - mx - bx1;
+
+ InvalidateRect(NULL);
+
+ MoveItem(IDCANCEL, x, y, bx1, by);
+ MoveItem(IDHELP, x - mx - bx2, y, bx2, by);
+ if (_consoleEdit)
+ {
+ int yPos = ySize - my - by;
+ RECT rect;
+ GetClientRectOfItem(IDC_BENCHMARK2_EDIT, rect);
+ int y = rect.top;
+ int ySize2 = yPos - my - y;
+ const int kMinYSize = 20;
+ int xx = xSize - mx * 2;
+ if (ySize2 < kMinYSize)
+ {
+ ySize2 = kMinYSize;
+ }
+ _consoleEdit.Move(mx, y, xx, ySize2);
+ }
+ return false;
+}
+
UInt32 CBenchmarkDialog::GetNumberOfThreads()
{
return (UInt32)m_NumThreads.GetItemData(m_NumThreads.GetCurSel());
@@ -209,7 +266,7 @@ void CBenchmarkDialog::OnChangeSettings()
EnableItem(IDC_BUTTON_STOP, true);
UInt32 dictionary = OnChangeDictionary();
TCHAR s[40] = { TEXT('/'), TEXT(' '), 0 };
- ConvertUInt64ToString(NSystem::GetNumberOfProcessors(), s + 2);
+ ConvertUInt32ToString(NSystem::GetNumberOfProcessors(), s + 2);
SetItemText(IDC_BENCHMARK_HARDWARE_THREADS, s);
for (int i = 0; i < sizeof(g_IDs) / sizeof(g_IDs[0]); i++)
SetItemText(g_IDs[i], kProcessingString);
@@ -305,15 +362,32 @@ void CBenchmarkDialog::PrintResults(
rating = GetCompressRating(dictionarySize, info.GlobalTime, info.GlobalFreq, size * info.NumIterations);
PrintRating(rating, ratingID);
- PrintRating(GetRatingPerUsage(info, rating), rpuID);
- PrintUsage(GetUsage(info), usageID);
+ PrintRating(info.GetRatingPerUsage(rating), rpuID);
+ PrintUsage(info.GetUsage(), usageID);
}
bool CBenchmarkDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */)
{
- PrintTime();
+ bool printTime = true;
+ if (TotalMode)
+ {
+ if (Sync.WasStopped())
+ printTime = false;
+ }
+ if (printTime)
+ PrintTime();
NWindows::NSynchronization::CCriticalSectionLock lock(Sync.CS);
+ if (TotalMode)
+ {
+ if (Sync.TextWasChanged)
+ {
+ _consoleEdit.SetText(GetSystemString(Sync.Text));
+ Sync.TextWasChanged = false;
+ }
+ return true;
+ }
+
TCHAR s[40];
ConvertUInt64ToString((Sync.ProcessedSize >> 20), s);
lstrcat(s, kMB);
@@ -377,9 +451,11 @@ bool CBenchmarkDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */)
Sync.DecompressingInfo.PackSize, 1);
PrintRating((comprRating + decomprRating) / 2, IDC_BENCHMARK_TOTAL_RATING_VALUE);
PrintRating((
- GetRatingPerUsage(Sync.CompressingInfo, comprRating) +
- GetRatingPerUsage(Sync.DecompressingInfo, decomprRating)) / 2, IDC_BENCHMARK_TOTAL_RPU_VALUE);
- PrintUsage((GetUsage(Sync.CompressingInfo) + GetUsage(Sync.DecompressingInfo)) / 2, IDC_BENCHMARK_TOTAL_USAGE_VALUE);
+ Sync.CompressingInfo.GetRatingPerUsage(comprRating) +
+ Sync.DecompressingInfo.GetRatingPerUsage(decomprRating)) / 2, IDC_BENCHMARK_TOTAL_RPU_VALUE);
+ PrintUsage(
+ (Sync.CompressingInfo.GetUsage() +
+ Sync.DecompressingInfo.GetUsage()) / 2, IDC_BENCHMARK_TOTAL_USAGE_VALUE);
}
}
return true;
@@ -414,7 +490,6 @@ bool CBenchmarkDialog::OnButtonClicked(int buttonID, HWND buttonHWND)
struct CThreadBenchmark
{
CBenchmarkDialog *BenchmarkDialog;
- UInt64 _startTime;
DECL_EXTERNAL_CODECS_VARS
// UInt32 dictionarySize;
// UInt32 numThreads;
@@ -478,6 +553,35 @@ HRESULT CBenchCallback::SetDecodeResult(const CBenchInfo &info, bool final)
return S_OK;
}
+struct CBenchCallback2: public IBenchPrintCallback
+{
+ CProgressSyncInfo *Sync;
+
+ void Print(const char *s);
+ void NewLine();
+ HRESULT CheckBreak();
+};
+
+void CBenchCallback2::Print(const char *s)
+{
+ NSynchronization::CCriticalSectionLock lock(Sync->CS);
+ Sync->Text += s;
+ Sync->TextWasChanged = true;
+}
+
+void CBenchCallback2::NewLine()
+{
+ Print("\xD\n");
+}
+
+HRESULT CBenchCallback2::CheckBreak()
+{
+ if (Sync->Changed || Sync->Paused || Sync->Stopped)
+ return E_ABORT;
+ return S_OK;
+}
+
+
HRESULT CThreadBenchmark::Process()
{
CProgressSyncInfo &sync = BenchmarkDialog->Sync;
@@ -508,12 +612,44 @@ HRESULT CThreadBenchmark::Process()
CBenchCallback callback;
callback.dictionarySize = dictionarySize;
callback.Sync = &sync;
+ CBenchCallback2 callback2;
+ callback2.Sync = &sync;
HRESULT result;
try
{
- result = LzmaBench(
- EXTERNAL_CODECS_VARS
- numThreads, dictionarySize, &callback);
+ CObjectVector<CProperty> props;
+ if (BenchmarkDialog->TotalMode)
+ {
+ props = BenchmarkDialog->Props;
+ }
+ else
+ {
+ {
+ CProperty prop;
+ prop.Name = L"mt";
+ wchar_t s[16];
+ ConvertUInt32ToString(numThreads, s);
+ prop.Value = s;
+ props.Add(prop);
+ }
+ {
+ CProperty prop;
+ prop.Name = L"d";
+ wchar_t s[16];
+ ConvertUInt32ToString(dictionarySize, s);
+ prop.Name += s;
+ prop.Name += 'b';
+ props.Add(prop);
+ }
+ }
+ result = Bench(EXTERNAL_CODECS_VARS
+ BenchmarkDialog->TotalMode ? &callback2 : NULL,
+ BenchmarkDialog->TotalMode ? NULL : &callback,
+ props, 1, false);
+ if (BenchmarkDialog->TotalMode)
+ {
+ sync.Stop();
+ }
}
catch(...)
{
@@ -561,7 +697,7 @@ HRESULT CThreadBenchmark::Process()
HRESULT Benchmark(
DECL_EXTERNAL_CODECS_LOC_VARS
- UInt32 numThreads, UInt32 dictionarySize, HWND hwndParent)
+ const CObjectVector<CProperty> props, HWND hwndParent)
{
CThreadBenchmark benchmarker;
#ifdef EXTERNAL_CODECS
@@ -569,13 +705,21 @@ HRESULT Benchmark(
benchmarker._externalCodecs = *externalCodecs;
#endif
- CBenchmarkDialog benchmarkDialog;
- benchmarkDialog.Sync.DictionarySize = dictionarySize;
- benchmarkDialog.Sync.NumThreads = numThreads;
+ CBenchmarkDialog bd;
+ bd.Props = props;
+ bd.TotalMode = false;
+ for (int i = 0; i < props.Size(); i++)
+ {
+ const CProperty &prop = props[i];
+ if (prop.Name.CompareNoCase(L"m") == 0 && prop.Value == L"*")
+ bd.TotalMode = true;
+ }
+ bd.Sync.DictionarySize = (UInt32)-1;
+ bd.Sync.NumThreads = (UInt32)-1;
+ benchmarker.BenchmarkDialog = &bd;
- benchmarker.BenchmarkDialog = &benchmarkDialog;
NWindows::CThread thread;
RINOK(thread.Create(CThreadBenchmark::MyThreadFunction, &benchmarker));
- benchmarkDialog.Create(hwndParent);
+ bd.Create(hwndParent);
return thread.Wait();
}
diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.h b/CPP/7zip/UI/GUI/BenchmarkDialog.h
index 2b6216fd..b3ab9dcb 100755
--- a/CPP/7zip/UI/GUI/BenchmarkDialog.h
+++ b/CPP/7zip/UI/GUI/BenchmarkDialog.h
@@ -5,6 +5,7 @@
#include "Windows/Synchronization.h"
#include "Windows/Control/ComboBox.h"
+#include "Windows/Control/Edit.h"
#include "../Common/Bench.h"
@@ -37,6 +38,9 @@ public:
CBenchInfo2 DecompressingInfoTemp;
CBenchInfo2 DecompressingInfo;
+ AString Text;
+ bool TextWasChanged;
+
CProgressSyncInfo()
{
if (_startEvent.Create() != S_OK)
@@ -56,6 +60,9 @@ public:
NumPasses = 0;
// NumErrors = 0;
+
+ Text.Empty();
+ TextWasChanged = true;
}
void Stop()
{
@@ -85,14 +92,33 @@ public:
void WaitCreating() { _startEvent.Lock(); }
};
+struct CMyFont
+{
+ HFONT _font;
+ CMyFont(): _font(NULL) {}
+ ~CMyFont()
+ {
+ if (_font)
+ DeleteObject(_font);
+ }
+ void Create(const LOGFONT *lplf)
+ {
+ _font = CreateFontIndirect(lplf);
+ }
+};
+
+
class CBenchmarkDialog:
public NWindows::NControl::CModalDialog
{
NWindows::NControl::CComboBox m_Dictionary;
NWindows::NControl::CComboBox m_NumThreads;
+ NWindows::NControl::CEdit _consoleEdit;
UINT_PTR _timer;
UINT32 _startTime;
+ CMyFont _font;
+ bool OnSize(WPARAM /* wParam */, int xSize, int ySize);
bool OnTimer(WPARAM timerID, LPARAM callback);
virtual bool OnInit();
void OnRestartButton();
@@ -115,12 +141,14 @@ class CBenchmarkDialog:
void OnChangeSettings();
public:
CProgressSyncInfo Sync;
+ bool TotalMode;
+ CObjectVector<CProperty> Props;
- CBenchmarkDialog(): _timer(0) {}
+ CBenchmarkDialog(): _timer(0), TotalMode(false) {}
INT_PTR Create(HWND wndParent = 0)
{
BIG_DIALOG_SIZE(332, 228);
- return CModalDialog::Create(SIZED_DIALOG(IDD_DIALOG_BENCHMARK), wndParent);
+ return CModalDialog::Create(TotalMode ? IDD_DIALOG_BENCHMARK_TOTAL : SIZED_DIALOG(IDD_DIALOG_BENCHMARK), wndParent);
}
void MessageBoxError(LPCWSTR message)
{
@@ -130,6 +158,6 @@ public:
HRESULT Benchmark(
DECL_EXTERNAL_CODECS_LOC_VARS
- UInt32 numThreads, UInt32 dictionarySize, HWND hwndParent = NULL);
+ const CObjectVector<CProperty> props, HWND hwndParent = NULL);
#endif
diff --git a/CPP/7zip/UI/GUI/BenchmarkDialog.rc b/CPP/7zip/UI/GUI/BenchmarkDialog.rc
index b77bac5f..6b17a12a 100755
--- a/CPP/7zip/UI/GUI/BenchmarkDialog.rc
+++ b/CPP/7zip/UI/GUI/BenchmarkDialog.rc
@@ -41,6 +41,12 @@
#define g3xs 36
#define g3x (m + g2xs)
+#undef GROUP_Y_SIZE
+#ifdef UNDER_CE
+#define GROUP_Y_SIZE 8
+#else
+#define GROUP_Y_SIZE 40
+#endif
IDD_DIALOG_BENCHMARK DIALOG 0, 0, xs, ys MY_MODAL_DIALOG_STYLE | WS_MINIMIZEBOX
CAPTION "Benchmark"
@@ -66,7 +72,7 @@ BEGIN
RTEXT "Rating / Usage", IDC_BENCHMARK_RPU_LABEL, xRpu, 54, sRpu, 8
RTEXT "Rating", IDC_BENCHMARK_RATING_LABEL, xRating, 54, sRating, 8
- GROUPBOX "Compressing", IDC_BENCHMARK_COMPRESSING, m, 64, xc, 40
+ GROUPBOX "Compressing", IDC_BENCHMARK_COMPRESSING, m, 64, xc, GROUP_Y_SIZE
LTEXT "Current", IDC_BENCHMARK_CURRENT, g4x, 76, sLabel, 8
RTEXT "100%", IDC_BENCHMARK_COMPRESSING_USAGE, xUsage, 76, sUsage, 8
@@ -80,7 +86,7 @@ BEGIN
RTEXT "0", IDC_BENCHMARK_COMPRESSING_RPU2, xRpu, 89, sRpu, 8
RTEXT "0", IDC_BENCHMARK_COMPRESSING_RATING2, xRating, 89, sRating, 8
- GROUPBOX "Decompressing", IDC_BENCHMARK_DECOMPRESSING, m, 111, xc, 40
+ GROUPBOX "Decompressing", IDC_BENCHMARK_DECOMPRESSING, m, 111, xc, GROUP_Y_SIZE
LTEXT "Current", IDC_BENCHMARK_CURRENT2, g4x, 123, sLabel, 8
RTEXT "100%", IDC_BENCHMARK_DECOMPRESSING_USAGE, xUsage, 123, sUsage, 8
@@ -94,7 +100,7 @@ BEGIN
RTEXT "0", IDC_BENCHMARK_DECOMPRESSING_RPU2, xRpu, 136, sRpu, 8
RTEXT "0", IDC_BENCHMARK_DECOMPRESSING_RATING2, xRating, 136, sRating, 8
- GROUPBOX "Total Rating", IDC_BENCHMARK_TOTAL_RATING, xTotalRating, 163, sTotalRating, 38
+ GROUPBOX "Total Rating", IDC_BENCHMARK_TOTAL_RATING, xTotalRating, 163, sTotalRating, GROUP_Y_SIZE
RTEXT "0", IDC_BENCHMARK_TOTAL_USAGE_VALUE, xUsage, 181, sUsage, 8
RTEXT "0", IDC_BENCHMARK_TOTAL_RPU_VALUE, xRpu, 181, sRpu, 8
RTEXT "0", IDC_BENCHMARK_TOTAL_RATING_VALUE, xRating, 181, sRating, 8
@@ -225,3 +231,18 @@ BEGIN
END
#endif
+
+#include "../../GuiCommon.rc"
+
+#define xc 360
+#define yc 260
+
+IDD_DIALOG_BENCHMARK_TOTAL MY_RESIZE_DIALOG
+CAPTION "Benchmark"
+{
+ LTEXT "Elapsed time:", IDC_BENCHMARK_ELAPSED, m, m, 58, 8
+ RTEXT "00:00:00", IDC_BENCHMARK_ELAPSED_VALUE, m + 58, m, 38, 8
+ EDITTEXT IDC_BENCHMARK2_EDIT, m, m + 14, xc, yc - bys - m - 14, ES_MULTILINE | ES_READONLY | ES_AUTOVSCROLL | WS_VSCROLL | WS_HSCROLL
+ PUSHBUTTON "&Help", IDHELP, bx2, by, bxs, bys
+ PUSHBUTTON "Cancel", IDCANCEL, bx1, by, bxs, bys
+}
diff --git a/CPP/7zip/UI/GUI/BenchmarkDialogRes.h b/CPP/7zip/UI/GUI/BenchmarkDialogRes.h
index 2488bd1c..cf009df3 100755
--- a/CPP/7zip/UI/GUI/BenchmarkDialogRes.h
+++ b/CPP/7zip/UI/GUI/BenchmarkDialogRes.h
@@ -1,5 +1,7 @@
#define IDD_DIALOG_BENCHMARK 550
#define IDD_DIALOG_BENCHMARK_2 650
+#define IDD_DIALOG_BENCHMARK_TOTAL 750
+#define IDD_DIALOG_BENCHMARK_TOTAL_2 750
#define IDC_BUTTON_STOP 1001
#define IDC_BUTTON_RESTART 1002
#define IDC_BENCHMARK_DICTIONARY 1010
@@ -53,3 +55,5 @@
#define IDC_BENCHMARK_SIZE_VALUE 1063
#define IDC_BENCHMARK_PASSES 1066
#define IDC_BENCHMARK_PASSES_VALUE 1067
+
+#define IDC_BENCHMARK2_EDIT 1090
diff --git a/CPP/7zip/UI/GUI/CompressDialog.cpp b/CPP/7zip/UI/GUI/CompressDialog.cpp
index da2b7924..2723f515 100755
--- a/CPP/7zip/UI/GUI/CompressDialog.cpp
+++ b/CPP/7zip/UI/GUI/CompressDialog.cpp
@@ -351,7 +351,10 @@ namespace NCompressDialog
#ifndef UNDER_CE
NDirectory::MySetCurrentDirectory(CurrentDirPrefix);
#endif
- return MyGetFullPathName(ArchiveName, result);
+ FString resultF;
+ bool res = MyGetFullPathName(us2fs(ArchiveName), resultF);
+ result = fs2us(resultF);
+ return res;
}
}
@@ -1236,6 +1239,7 @@ bool CCompressDialog::GetOrderMode()
switch (GetMethodID())
{
case kPPMd:
+ case kPPMdZip:
return true;
}
return false;
diff --git a/CPP/7zip/UI/GUI/CompressDialog.h b/CPP/7zip/UI/GUI/CompressDialog.h
index 86f7b173..7b0067fa 100755
--- a/CPP/7zip/UI/GUI/CompressDialog.h
+++ b/CPP/7zip/UI/GUI/CompressDialog.h
@@ -49,7 +49,7 @@ namespace NCompressDialog
UString ArchiveName; // in: Relative for ; out: abs
- UString CurrentDirPrefix;
+ FString CurrentDirPrefix;
bool KeepName;
bool GetFullPathName(UString &result) const;
diff --git a/CPP/7zip/UI/GUI/CompressDialog.rc b/CPP/7zip/UI/GUI/CompressDialog.rc
index 5f622c76..5a71b043 100755
--- a/CPP/7zip/UI/GUI/CompressDialog.rc
+++ b/CPP/7zip/UI/GUI/CompressDialog.rc
@@ -36,6 +36,16 @@
#define yOpt 72
#define yPsw 128
+#undef GROUP_Y_SIZE
+#undef GROUP_Y_SIZE_ENCRYPT
+#ifdef UNDER_CE
+#define GROUP_Y_SIZE 8
+#define GROUP_Y_SIZE_ENCRYPT 8
+#else
+#define GROUP_Y_SIZE 48
+#define GROUP_Y_SIZE_ENCRYPT 128
+#endif
+
IDD_DIALOG_COMPRESS MY_DIALOG
CAPTION "Add to Archive"
BEGIN
@@ -82,13 +92,13 @@ BEGIN
LTEXT "&Update mode:",IDC_STATIC_COMPRESS_UPDATE_MODE, g4x, 39, g4xs, 8
COMBOBOX IDC_COMPRESS_COMBO_UPDATE_MODE, g4x, 51, g4xs, 80, MY_COMBO
- GROUPBOX "Options",IDC_STATIC_COMPRESS_OPTIONS, g4x, yOpt, g4xs, 48
+ GROUPBOX "Options",IDC_STATIC_COMPRESS_OPTIONS, g4x, yOpt, g4xs, GROUP_Y_SIZE
CONTROL "Create SF&X archive",IDC_COMPRESS_SFX, MY_CHECKBOX,
g4x2, yOpt + 14, g4xs2, 10
CONTROL "Compress shared files",IDC_COMPRESS_SHARED, MY_CHECKBOX,
g4x2, yOpt + 30, g4xs2, 10
- GROUPBOX "Encryption",IDC_COMPRESS_ENCRYPTION, g4x, yPsw, g4xs, 127
+ GROUPBOX "Encryption", IDC_COMPRESS_ENCRYPTION, g4x, yPsw, g4xs, GROUP_Y_SIZE_ENCRYPT
LTEXT "Enter password:",IDC_STATIC_COMPRESS_PASSWORD1, g4x2, yPsw + 14, g4xs2, 8
EDITTEXT IDC_COMPRESS_EDIT_PASSWORD1, g4x2, yPsw + 26, g4xs2, 14, ES_PASSWORD | ES_AUTOHSCROLL
diff --git a/CPP/7zip/UI/GUI/ExtractDialog.cpp b/CPP/7zip/UI/GUI/ExtractDialog.cpp
index 94556639..64ae445e 100755
--- a/CPP/7zip/UI/GUI/ExtractDialog.cpp
+++ b/CPP/7zip/UI/GUI/ExtractDialog.cpp
@@ -352,4 +352,3 @@ void CExtractDialog::OnHelp()
CModalDialog::OnHelp();
}
#endif
-
diff --git a/CPP/7zip/UI/GUI/ExtractDialog.rc b/CPP/7zip/UI/GUI/ExtractDialog.rc
index db8a5b24..ec4c20c2 100755
--- a/CPP/7zip/UI/GUI/ExtractDialog.rc
+++ b/CPP/7zip/UI/GUI/ExtractDialog.rc
@@ -18,6 +18,13 @@
#define g2xs (xc - g1xs - gSpace)
#define g2xs2 (g2xs - m - m)
+#undef GROUP_Y_SIZE
+#ifdef UNDER_CE
+#define GROUP_Y_SIZE 8
+#else
+#define GROUP_Y_SIZE 56
+#endif
+
IDD_DIALOG_EXTRACT MY_DIALOG
CAPTION "Extract"
BEGIN
@@ -31,11 +38,7 @@ BEGIN
LTEXT "Overwrite mode:", IDC_EXTRACT_OVERWRITE_MODE, m, m + 68, g1xs, 8
COMBOBOX IDC_EXTRACT_COMBO_OVERWRITE_MODE, m, m + 80, g1xs, 140, MY_COMBO
- #ifdef UNDER_CE
- LTEXT "Password", IDC_EXTRACT_PASSWORD, g2x, m + 36, g2xs, 8
- #else
- GROUPBOX "Password", IDC_EXTRACT_PASSWORD, g2x, m + 36, g2xs, 56
- #endif
+ GROUPBOX "Password", IDC_EXTRACT_PASSWORD, g2x, m + 36, g2xs, GROUP_Y_SIZE
EDITTEXT IDC_EXTRACT_EDIT_PASSWORD, g2x2, m + 50, g2xs2, 14, ES_PASSWORD | ES_AUTOHSCROLL
CONTROL "Show Password", IDC_EXTRACT_CHECK_SHOW_PASSWORD, MY_CHECKBOX, g2x2, m + 72, g2xs2, 10
diff --git a/CPP/7zip/UI/GUI/ExtractGUI.cpp b/CPP/7zip/UI/GUI/ExtractGUI.cpp
index a976833c..9d39bffd 100755
--- a/CPP/7zip/UI/GUI/ExtractGUI.cpp
+++ b/CPP/7zip/UI/GUI/ExtractGUI.cpp
@@ -8,6 +8,7 @@
#include "Windows/Error.h"
#include "Windows/FileDir.h"
#include "Windows/FileFind.h"
+#include "Windows/FileName.h"
#include "Windows/Thread.h"
#include "../FileManager/ExtractCallback.h"
@@ -128,7 +129,7 @@ HRESULT ExtractGUI(
if (!options.TestMode)
{
- UString outputDir = options.OutputDir;
+ FString outputDir = options.OutputDir;
#ifndef UNDER_CE
if (outputDir.IsEmpty())
NFile::NDirectory::MyGetCurrentDirectory(outputDir);
@@ -136,20 +137,22 @@ HRESULT ExtractGUI(
if (showDialog)
{
CExtractDialog dialog;
- if (!NFile::NDirectory::MyGetFullPathName(outputDir, dialog.DirectoryPath))
+ FString outputDirFull;
+ if (!NFile::NDirectory::MyGetFullPathName(outputDir, outputDirFull))
{
ShowErrorMessage(kIncorrectOutDir);
messageWasDisplayed = true;
return E_FAIL;
}
- NFile::NName::NormalizeDirPathPrefix(dialog.DirectoryPath);
+ NFile::NName::NormalizeDirPathPrefix(outputDirFull);
+ dialog.DirectoryPath = fs2us(outputDirFull);
// dialog.OverwriteMode = options.OverwriteMode;
// dialog.PathMode = options.PathMode;
if (dialog.Create(hwndParent) != IDOK)
return E_ABORT;
- outputDir = dialog.DirectoryPath;
+ outputDir = us2fs(dialog.DirectoryPath);
options.OverwriteMode = dialog.OverwriteMode;
options.PathMode = dialog.PathMode;
#ifndef _SFX
diff --git a/CPP/7zip/UI/GUI/GUI.cpp b/CPP/7zip/UI/GUI/GUI.cpp
index 377c7841..0a40b58e 100755
--- a/CPP/7zip/UI/GUI/GUI.cpp
+++ b/CPP/7zip/UI/GUI/GUI.cpp
@@ -121,7 +121,7 @@ static int Main2()
#ifdef EXTERNAL_CODECS
codecs, &externalCodecs,
#endif
- options.NumThreads, options.DictionarySize);
+ options.Properties);
if (res != S_OK)
throw CSystemException(res);
}
@@ -146,7 +146,7 @@ static int Main2()
eo.TestMode = options.Command.IsTestMode();
eo.CalcCrc = options.CalcCrc;
#if !defined(_7ZIP_ST) && !defined(_SFX)
- eo.Properties = options.ExtractProperties;
+ eo.Properties = options.Properties;
#endif
bool messageWasDisplayed = false;
@@ -280,4 +280,3 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
return NExitCode::kFatalError;
}
}
-
diff --git a/CPP/7zip/UI/GUI/GUI.dsp b/CPP/7zip/UI/GUI/GUI.dsp
index d54e944f..382f592e 100755
--- a/CPP/7zip/UI/GUI/GUI.dsp
+++ b/CPP/7zip/UI/GUI/GUI.dsp
@@ -585,6 +585,14 @@ SOURCE=..\..\Common\FilterCoder.h
# End Source File
# Begin Source File
+SOURCE=..\..\Common\MethodProps.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\Common\MethodProps.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Common\ProgressUtils.cpp
# End Source File
# Begin Source File
diff --git a/CPP/7zip/UI/GUI/UpdateGUI.cpp b/CPP/7zip/UI/GUI/UpdateGUI.cpp
index 7ee74fc8..ec56492f 100755
--- a/CPP/7zip/UI/GUI/UpdateGUI.cpp
+++ b/CPP/7zip/UI/GUI/UpdateGUI.cpp
@@ -10,6 +10,7 @@
#include "Windows/Error.h"
#include "Windows/FileDir.h"
+#include "Windows/FileName.h"
#include "Windows/Thread.h"
#include "../Common/WorkDir.h"
@@ -17,7 +18,6 @@
#include "../Explorer/MyMessages.h"
#include "../FileManager/LangUtils.h"
-#include "../FileManager/ProgramLocation.h"
#include "../FileManager/StringUtils.h"
#include "../FileManager/resourceGui.h"
@@ -29,7 +29,7 @@
using namespace NWindows;
using namespace NFile;
-static const wchar_t *kDefaultSfxModule = L"7z.sfx";
+static CFSTR kDefaultSfxModule = FTEXT("7z.sfx");
static const wchar_t *kSFXExtension = L"exe";
extern void AddMessageToString(UString &dest, const UString &src);
@@ -52,8 +52,8 @@ HRESULT CThreadUpdating::ProcessVirt()
HRESULT res = UpdateArchive(codecs, *WildcardCensor, *Options,
ei, UpdateCallbackGUI, UpdateCallbackGUI);
ErrorMessage = ei.Message;
- ErrorPath1 = ei.FileName;
- ErrorPath2 = ei.FileName2;
+ SetErrorPath1(ei.FileName);
+ SetErrorPath2(ei.FileName2);
if (ei.SystemError != S_OK && ei.SystemError != E_FAIL && ei.SystemError != E_ABORT)
return ei.SystemError;
return res;
@@ -197,7 +197,7 @@ static HRESULT ShowDialog(
{
if (options.Commands.Size() != 1)
throw "It must be one command";
- UString currentDirPrefix;
+ FString currentDirPrefix;
#ifndef UNDER_CE
{
if (!NDirectory::MyGetCurrentDirectory(currentDirPrefix))
@@ -207,7 +207,7 @@ static HRESULT ShowDialog(
#endif
bool oneFile = false;
- NFind::CFileInfoW fileInfo;
+ NFind::CFileInfo fileInfo;
UString name;
if (censor.Pairs.Size() > 0)
{
@@ -224,7 +224,7 @@ static HRESULT ShowDialog(
name += WCHAR_PATH_SEPARATOR;
name += item.PathParts[i];
}
- if (fileInfo.Find(name))
+ if (fileInfo.Find(us2fs(name)))
{
if (censor.Pairs.Size() == 1 && pair.Head.IncludeItems.Size() == 1)
oneFile = !fileInfo.IsDir();
@@ -253,7 +253,7 @@ static HRESULT ShowDialog(
// di.ArchiveName = options.ArchivePath.GetFinalPath();
di.ArchiveName = options.ArchivePath.GetPathWithoutExt();
- dialog.OriginalFileName = options.ArchivePath.Prefix + fileInfo.Name;
+ dialog.OriginalFileName = options.ArchivePath.Prefix + fs2us(fileInfo.Name);
di.CurrentDirPrefix = currentDirPrefix;
di.SFXMode = options.SfxMode;
@@ -338,9 +338,10 @@ static HRESULT ShowDialog(
options.WorkingDir.Empty();
if (workDirInfo.Mode != NWorkDir::NMode::kCurrent)
{
- UString fullPath;
- NDirectory::MyGetFullPathName(di.ArchiveName, fullPath);
- options.WorkingDir = GetWorkDir(workDirInfo, fullPath);
+ FString fullPath;
+ NDirectory::MyGetFullPathName(us2fs(di.ArchiveName), fullPath);
+ FString namePart;
+ options.WorkingDir = GetWorkDir(workDirInfo, fullPath, namePart);
NDirectory::CreateComplexDirectory(options.WorkingDir);
}
return S_OK;
@@ -362,9 +363,7 @@ HRESULT UpdateGUI(
}
if (options.SfxMode && options.SfxModule.IsEmpty())
{
- UString folder;
- if (!GetProgramFolderPath(folder))
- folder.Empty();
+ FString folder = NWindows::NDLL::GetModuleDirPrefix();
options.SfxModule = folder + kDefaultSfxModule;
}
diff --git a/CPP/7zip/UI/GUI/makefile b/CPP/7zip/UI/GUI/makefile
index fdedb44a..cd2c2f55 100755
--- a/CPP/7zip/UI/GUI/makefile
+++ b/CPP/7zip/UI/GUI/makefile
@@ -6,7 +6,7 @@ CFLAGS = $(CFLAGS) -I ../../../ \
!IFDEF UNDER_CE
LIBS = $(LIBS) ceshell.lib Commctrl.lib
!ELSE
-LIBS = $(LIBS) comctl32.lib htmlhelp.lib comdlg32.lib
+LIBS = $(LIBS) comctl32.lib htmlhelp.lib comdlg32.lib gdi32.lib
CFLAGS = $(CFLAGS) -DWIN_LONG_PATH -DSUPPORT_DEVICE_FILE -D_7ZIP_LARGE_PAGES
!ENDIF
@@ -63,6 +63,7 @@ WIN_CTRL_OBJS = \
$O\FilePathAutoRename.obj \
$O\FileStreams.obj \
$O\FilterCoder.obj \
+ $O\MethodProps.obj \
$O\ProgressUtils.obj \
$O\StreamUtils.obj \
diff --git a/CPP/Build.mak b/CPP/Build.mak
index 9209a32e..b3465d44 100755
--- a/CPP/Build.mak
+++ b/CPP/Build.mak
@@ -64,6 +64,10 @@ CFLAGS_O2 = $(CFLAGS) -O2
LFLAGS = $(LFLAGS) -nologo -OPT:REF -OPT:ICF
+!IFNDEF UNDER_CE
+LFLAGS = $(LFLAGS) /LARGEADDRESSAWARE
+!ENDIF
+
!IFDEF DEF_FILE
LFLAGS = $(LFLAGS) -DLL -DEF:$(DEF_FILE)
!ENDIF
diff --git a/CPP/Common/C_FileIO.cpp b/CPP/Common/C_FileIO.cpp
index b4893d65..7c629390 100755
--- a/CPP/Common/C_FileIO.cpp
+++ b/CPP/Common/C_FileIO.cpp
@@ -1,9 +1,13 @@
-// Common/C_FileIO.h
+// Common/C_FileIO.cpp
#include "C_FileIO.h"
#include <fcntl.h>
+#ifdef _WIN32
+#include <io.h>
+#else
#include <unistd.h>
+#endif
namespace NC {
namespace NFile {
diff --git a/CPP/Common/C_FileIO.h b/CPP/Common/C_FileIO.h
index 27aa5686..ff7a1a11 100755
--- a/CPP/Common/C_FileIO.h
+++ b/CPP/Common/C_FileIO.h
@@ -9,6 +9,10 @@
#include "Types.h"
#include "MyWindows.h"
+#ifdef _WIN32
+typedef size_t ssize_t;
+#endif
+
namespace NC {
namespace NFile {
namespace NIO {
diff --git a/CPP/Common/Lang.cpp b/CPP/Common/Lang.cpp
index 75dfed42..df4bbac0 100755
--- a/CPP/Common/Lang.cpp
+++ b/CPP/Common/Lang.cpp
@@ -48,7 +48,7 @@ static int CompareLangItems(void *const *elem1, void *const *elem2, void *)
return MyCompare(langPair1.Value, langPair2.Value);
}
-bool CLang::Open(LPCWSTR fileName)
+bool CLang::Open(CFSTR fileName)
{
_langPairs.Clear();
NWindows::NFile::NIO::CInFile file;
diff --git a/CPP/Common/Lang.h b/CPP/Common/Lang.h
index cf978758..2ce53a0d 100755
--- a/CPP/Common/Lang.h
+++ b/CPP/Common/Lang.h
@@ -3,7 +3,6 @@
#ifndef __COMMON_LANG_H
#define __COMMON_LANG_H
-#include "MyVector.h"
#include "MyString.h"
#include "Types.h"
@@ -17,7 +16,7 @@ class CLang
{
CObjectVector<CLangPair> _langPairs;
public:
- bool Open(LPCWSTR fileName);
+ bool Open(CFSTR fileName);
void Clear() { _langPairs.Clear(); }
int FindItem(UInt32 value) const;
bool GetMessage(UInt32 value, UString &message) const;
diff --git a/CPP/Common/ListFileUtils.cpp b/CPP/Common/ListFileUtils.cpp
index c1c682a2..f9bd18ed 100755
--- a/CPP/Common/ListFileUtils.cpp
+++ b/CPP/Common/ListFileUtils.cpp
@@ -9,15 +9,16 @@
#include "StringConvert.h"
#include "UTFConvert.h"
-static const char kQuoteChar = '\"';
+static const char kQuoteChar = '\"';
+
static void RemoveQuote(UString &s)
{
if (s.Length() >= 2)
- if (s[0] == kQuoteChar && s[s.Length() - 1] == kQuoteChar)
+ if (s[0] == kQuoteChar && s.Back() == kQuoteChar)
s = s.Mid(1, s.Length() - 2);
}
-bool ReadNamesFromListFile(LPCWSTR fileName, UStringVector &resultStrings, UINT codePage)
+bool ReadNamesFromListFile(CFSTR fileName, UStringVector &resultStrings, UINT codePage)
{
NWindows::NFile::NIO::CInFile file;
if (!file.Open(fileName))
diff --git a/CPP/Common/ListFileUtils.h b/CPP/Common/ListFileUtils.h
index c58a8bd4..d43bfdfc 100755
--- a/CPP/Common/ListFileUtils.h
+++ b/CPP/Common/ListFileUtils.h
@@ -1,11 +1,11 @@
// Common/ListFileUtils.h
-#ifndef __COMMON_LISTFILEUTILS_H
-#define __COMMON_LISTFILEUTILS_H
+#ifndef __COMMON_LIST_FILE_UTILS_H
+#define __COMMON_LIST_FILE_UTILS_H
#include "MyString.h"
#include "Types.h"
-bool ReadNamesFromListFile(LPCWSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP);
+bool ReadNamesFromListFile(CFSTR fileName, UStringVector &strings, UINT codePage = CP_OEMCP);
#endif
diff --git a/CPP/Common/MyString.cpp b/CPP/Common/MyString.cpp
index 3d1ce2b8..dc254eaf 100755
--- a/CPP/Common/MyString.cpp
+++ b/CPP/Common/MyString.cpp
@@ -2,7 +2,9 @@
#include "StdAfx.h"
-#ifndef _WIN32
+#ifdef _WIN32
+#include <windows.h>
+#else
#include <ctype.h>
#endif
@@ -12,10 +14,75 @@
#include "MyString.h"
+const char* MyStringGetNextCharPointer(const char *p)
+{
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ return CharNextA(p);
+ #else
+ return p + 1;
+ #endif
+}
+
+int FindCharPosInString(const char *s, char c)
+{
+ for (const char *p = s;;)
+ {
+ if (*p == c)
+ return (int)(p - s);
+ if (*p == 0)
+ return -1;
+ p = MyStringGetNextCharPointer(p);
+ }
+}
+
+int FindCharPosInString(const wchar_t *s, wchar_t c)
+{
+ for (const wchar_t *p = s;; p++)
+ {
+ if (*p == c)
+ return (int)(p - s);
+ if (*p == 0)
+ return -1;
+ }
+}
#ifdef _WIN32
-#ifndef _UNICODE
+#ifdef _UNICODE
+
+wchar_t MyCharUpper(wchar_t c)
+{
+ return (wchar_t)(unsigned int)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c);
+}
+
+/*
+wchar_t MyCharLower(wchar_t c)
+{
+ return (wchar_t)(unsigned int)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c);
+}
+
+char MyCharLower(char c)
+#ifdef UNDER_CE
+ { return (char)MyCharLower((wchar_t)c); }
+#else
+ { return (char)(unsigned int)(UINT_PTR)CharLowerA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }
+#endif
+*/
+
+wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }
+wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }
+
+// for WinCE - FString - char
+const char *MyStringGetPrevCharPointer(const char * /* base */, const char *p)
+{
+ return p - 1;
+}
+
+#else
+
+const char * MyStringGetPrevCharPointer(const char *base, const char *p) { return CharPrevA(base, p); }
+char * MyStringUpper(char *s) { return CharUpperA(s); }
+char * MyStringLower(char *s) { return CharLowerA(s); }
wchar_t MyCharUpper(wchar_t c)
{
@@ -62,7 +129,8 @@ wchar_t * MyStringUpper(wchar_t *s)
return res;
AString a = UnicodeStringToMultiByte(s);
a.MakeUpper();
- return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+ MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+ return s;
}
wchar_t * MyStringLower(wchar_t *s)
@@ -74,57 +142,12 @@ wchar_t * MyStringLower(wchar_t *s)
return res;
AString a = UnicodeStringToMultiByte(s);
a.MakeLower();
- return MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+ MyStringCopy(s, (const wchar_t *)MultiByteToUnicodeString(a));
+ return s;
}
#endif
-/*
-inline int ConvertCompareResult(int r) { return r - 2; }
-
-int MyStringCollate(const wchar_t *s1, const wchar_t *s2)
-{
- int res = CompareStringW(
- LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1);
- #ifdef _UNICODE
- return ConvertCompareResult(res);
- #else
- if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
- return ConvertCompareResult(res);
- return MyStringCollate(UnicodeStringToMultiByte(s1),
- UnicodeStringToMultiByte(s2));
- #endif
-}
-
-#ifndef UNDER_CE
-int MyStringCollate(const char *s1, const char *s2)
-{
- return ConvertCompareResult(CompareStringA(
- LOCALE_USER_DEFAULT, SORT_STRINGSORT, s1, -1, s2, -1));
-}
-
-int MyStringCollateNoCase(const char *s1, const char *s2)
-{
- return ConvertCompareResult(CompareStringA(
- LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1));
-}
-#endif
-
-int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
-{
- int res = CompareStringW(
- LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT, s1, -1, s2, -1);
- #ifdef _UNICODE
- return ConvertCompareResult(res);
- #else
- if (res != 0 || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
- return ConvertCompareResult(res);
- return MyStringCollateNoCase(UnicodeStringToMultiByte(s1),
- UnicodeStringToMultiByte(s2));
- #endif
-}
-*/
-
#else
wchar_t MyCharUpper(wchar_t c)
@@ -132,6 +155,15 @@ wchar_t MyCharUpper(wchar_t c)
return toupper(c);
}
+wchar_t * MyStringUpper(wchar_t *s)
+{
+ if (s == 0)
+ return 0;
+ for (wchar_t *p = s; *p != 0; p++)
+ *p = MyCharUpper(*p);
+ return s;
+}
+
/*
int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2)
{
@@ -192,9 +224,45 @@ int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2)
}
}
-/*
+UString MultiByteToUnicodeString(const AString &srcString, UINT codePage);
+AString UnicodeStringToMultiByte(const UString &srcString, UINT codePage);
+
int MyStringCompareNoCase(const char *s1, const char *s2)
{
- return MyStringCompareNoCase(MultiByteToUnicodeString(s1), MultiByteToUnicodeString(s2));
+ return MyStringCompareNoCase(MultiByteToUnicodeString(s1, CP_ACP), MultiByteToUnicodeString(s2, CP_ACP));
}
-*/
+
+static inline UINT GetCurrentCodePage()
+{
+ #if defined(UNDER_CE) || !defined(defined)
+ return CP_ACP;
+ #else
+ return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+ #endif
+}
+
+#ifdef USE_UNICODE_FSTRING
+
+AString fs2fas(CFSTR s)
+{
+ return UnicodeStringToMultiByte(s, GetCurrentCodePage());
+}
+
+FString fas2fs(const AString &s)
+{
+ return MultiByteToUnicodeString(s, GetCurrentCodePage());
+}
+
+#else
+
+UString fs2us(const FString &s)
+{
+ return MultiByteToUnicodeString((AString)s, GetCurrentCodePage());
+}
+
+FString us2fs(const wchar_t *s)
+{
+ return UnicodeStringToMultiByte(s, GetCurrentCodePage());
+}
+
+#endif
diff --git a/CPP/Common/MyString.h b/CPP/Common/MyString.h
index eb3c52dc..0312bac6 100755
--- a/CPP/Common/MyString.h
+++ b/CPP/Common/MyString.h
@@ -5,6 +5,7 @@
#include <string.h>
+#include "Types.h"
#include "MyVector.h"
template <class T>
@@ -16,13 +17,14 @@ inline int MyStringLen(const T *s)
}
template <class T>
-inline T * MyStringCopy(T *dest, const T *src)
+inline void MyStringCopy(T *dest, const T *src)
{
- T *destStart = dest;
while ((*dest++ = *src++) != 0);
- return destStart;
}
+int FindCharPosInString(const char *s, char c);
+int FindCharPosInString(const wchar_t *s, wchar_t c);
+
inline wchar_t* MyStringGetNextCharPointer(wchar_t *p)
{ return (p + 1); }
inline const wchar_t* MyStringGetNextCharPointer(const wchar_t *p)
@@ -32,77 +34,25 @@ inline wchar_t* MyStringGetPrevCharPointer(const wchar_t *, wchar_t *p)
inline const wchar_t* MyStringGetPrevCharPointer(const wchar_t *, const wchar_t *p)
{ return (p - 1); }
-#ifdef _WIN32
-
-inline const char* MyStringGetNextCharPointer(const char *p)
-{
- #ifdef UNDER_CE
- return p + 1;
- #else
- return CharNextA(p);
- #endif
-}
-
-inline const char* MyStringGetPrevCharPointer(const char *base, const char *p)
- { return CharPrevA(base, p); }
-
-inline char MyCharUpper(char c)
- { return (char)(unsigned int)(UINT_PTR)CharUpperA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }
-#ifdef _UNICODE
-inline wchar_t MyCharUpper(wchar_t c)
- { return (wchar_t)(unsigned int)(UINT_PTR)CharUpperW((LPWSTR)(UINT_PTR)(unsigned int)c); }
-#else
wchar_t MyCharUpper(wchar_t c);
-#endif
+// wchar_t MyCharLower(wchar_t c);
-#ifdef _UNICODE
-inline wchar_t MyCharLower(wchar_t c)
- { return (wchar_t)(unsigned int)(UINT_PTR)CharLowerW((LPWSTR)(UINT_PTR)(unsigned int)c); }
-#else
-wchar_t MyCharLower(wchar_t c);
-#endif
+char *MyStringUpper(char *s);
+char *MyStringLower(char *s);
-inline char MyCharLower(char c)
-#ifdef UNDER_CE
- { return (char)MyCharLower((wchar_t)c); }
-#else
- { return (char)(unsigned int)(UINT_PTR)CharLowerA((LPSTR)(UINT_PTR)(unsigned int)(unsigned char)c); }
-#endif
+wchar_t *MyStringUpper(wchar_t *s);
+wchar_t *MyStringLower(wchar_t *s);
-inline char * MyStringUpper(char *s) { return CharUpperA(s); }
-#ifdef _UNICODE
-inline wchar_t * MyStringUpper(wchar_t *s) { return CharUpperW(s); }
-#else
-wchar_t * MyStringUpper(wchar_t *s);
-#endif
-
-inline char * MyStringLower(char *s) { return CharLowerA(s); }
-#ifdef _UNICODE
-inline wchar_t * MyStringLower(wchar_t *s) { return CharLowerW(s); }
-#else
-wchar_t * MyStringLower(wchar_t *s);
-#endif
-
-#else // Standard-C
-wchar_t MyCharUpper(wchar_t c);
-#endif
+const char* MyStringGetNextCharPointer(const char *p);
+const char* MyStringGetPrevCharPointer(const char *base, const char *p);
//////////////////////////////////////
// Compare
-/*
-#ifndef UNDER_CE
-int MyStringCollate(const char *s1, const char *s2);
-int MyStringCollateNoCase(const char *s1, const char *s2);
-#endif
-int MyStringCollate(const wchar_t *s1, const wchar_t *s2);
-int MyStringCollateNoCase(const wchar_t *s1, const wchar_t *s2);
-*/
-
int MyStringCompare(const char *s1, const char *s2);
int MyStringCompare(const wchar_t *s1, const wchar_t *s2);
-// int MyStringCompareNoCase(const char *s1, const char *s2);
+int MyStringCompareNoCase(const char *s1, const char *s2);
int MyStringCompareNoCase(const wchar_t *s1, const wchar_t *s2);
template <class T>
@@ -338,10 +288,8 @@ public:
return Mid(_length - count, count);
}
- void MakeUpper()
- { MyStringUpper(_chars); }
- void MakeLower()
- { MyStringLower(_chars); }
+ void MakeUpper() { MyStringUpper(_chars); }
+ void MakeLower() { MyStringLower(_chars); }
int Compare(const CStringBase& s) const
{ return MyStringCompare(_chars, s._chars); }
@@ -362,18 +310,11 @@ public:
{ return MyStringCollateNoCase(_chars, s._chars); }
*/
- int Find(T c) const { return Find(c, 0); }
+ int Find(T c) const { return FindCharPosInString(_chars, c); }
int Find(T c, int startIndex) const
{
- const T *p = _chars + startIndex;
- for (;;)
- {
- if (*p == c)
- return (int)(p - _chars);
- if (*p == 0)
- return -1;
- p = GetNextCharPointer(p);
- }
+ int pos = FindCharPosInString(_chars + startIndex, c);
+ return pos < 0 ? -1 : pos + startIndex;
}
int Find(const CStringBase &s) const { return Find(s, 0); }
int Find(const CStringBase &s, int startIndex) const
@@ -622,4 +563,47 @@ typedef CObjectVector<UString> UStringVector;
typedef CObjectVector<CSysString> CSysStringVector;
+
+// ---------- FString ----------
+
+#ifdef _WIN32
+ #define USE_UNICODE_FSTRING
+#endif
+
+#ifdef USE_UNICODE_FSTRING
+
+ #define __FTEXT(quote) L##quote
+
+ typedef wchar_t FChar;
+ typedef UString FString;
+
+ #define fs2us(_x_) (_x_)
+ #define us2fs(_x_) (_x_)
+ FString fas2fs(const AString &s);
+ AString fs2fas(const FChar *s);
+
+#else
+
+ #define __FTEXT(quote) quote
+
+ typedef char FChar;
+ typedef AString FString;
+
+ UString fs2us(const FString &s);
+ FString us2fs(const wchar_t *s);
+ #define fas2fs(_x_) (_x_)
+ #define fs2fas(_x_) (_x_)
+
+#endif
+
+#define FTEXT(quote) __FTEXT(quote)
+
+#define FCHAR_PATH_SEPARATOR FTEXT(CHAR_PATH_SEPARATOR)
+#define FSTRING_PATH_SEPARATOR FTEXT(STRING_PATH_SEPARATOR)
+#define FCHAR_ANY_MASK FTEXT('*')
+#define FSTRING_ANY_MASK FTEXT("*")
+typedef const FChar *CFSTR;
+
+typedef CObjectVector<FString> FStringVector;
+
#endif
diff --git a/CPP/Common/MyWindows.cpp b/CPP/Common/MyWindows.cpp
index 1283946c..f940fc8a 100755
--- a/CPP/Common/MyWindows.cpp
+++ b/CPP/Common/MyWindows.cpp
@@ -26,10 +26,13 @@ BSTR SysAllocStringByteLen(LPCSTR psz, UINT len)
return 0;
*(UINT *)p = len;
BSTR bstr = (BSTR)((UINT *)p + 1);
- memmove(bstr, psz, len);
- Byte *pb = ((Byte *)bstr) + len;
- for (int i = 0; i < sizeof(OLECHAR) * 2; i++)
- pb[i] = 0;
+ if (psz)
+ {
+ memmove(bstr, psz, len);
+ Byte *pb = ((Byte *)bstr) + len;
+ for (unsigned i = 0; i < sizeof(OLECHAR) * 2; i++)
+ pb[i] = 0;
+ }
return bstr;
}
diff --git a/CPP/Common/MyWindows.h b/CPP/Common/MyWindows.h
index 8b0e5c06..780e1f5d 100755
--- a/CPP/Common/MyWindows.h
+++ b/CPP/Common/MyWindows.h
@@ -1,7 +1,7 @@
// MyWindows.h
-#ifndef __MYWINDOWS_H
-#define __MYWINDOWS_H
+#ifndef __MY_WINDOWS_H
+#define __MY_WINDOWS_H
#ifdef _WIN32
@@ -40,8 +40,8 @@ typedef UINT32 DWORD;
typedef Int64 LONGLONG;
typedef UInt64 ULONGLONG;
-typedef struct LARGE_INTEGER { LONGLONG QuadPart; }LARGE_INTEGER;
-typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart;} ULARGE_INTEGER;
+typedef struct _LARGE_INTEGER { LONGLONG QuadPart; } LARGE_INTEGER;
+typedef struct _ULARGE_INTEGER { ULONGLONG QuadPart; } ULARGE_INTEGER;
typedef const CHAR *LPCSTR;
typedef CHAR TCHAR;
@@ -57,7 +57,7 @@ typedef struct _FILETIME
{
DWORD dwLowDateTime;
DWORD dwHighDateTime;
-}FILETIME;
+} FILETIME;
#define HRESULT LONG
#define FAILED(Status) ((HRESULT)(Status)<0)
@@ -179,6 +179,13 @@ typedef VARIANT VARIANTARG;
MY_EXTERN_C HRESULT VariantClear(VARIANTARG *prop);
MY_EXTERN_C HRESULT VariantCopy(VARIANTARG *dest, VARIANTARG *src);
+typedef struct tagSTATPROPSTG
+{
+ LPOLESTR lpwstrName;
+ PROPID propid;
+ VARTYPE vt;
+} STATPROPSTG;
+
#endif
MY_EXTERN_C BSTR SysAllocStringByteLen(LPCSTR psz, UINT len);
diff --git a/CPP/Common/StringToInt.cpp b/CPP/Common/StringToInt.cpp
index 9473766b..15474a42 100755
--- a/CPP/Common/StringToInt.cpp
+++ b/CPP/Common/StringToInt.cpp
@@ -88,3 +88,10 @@ Int64 ConvertStringToInt64(const char *s, const char **end)
return -(Int64)ConvertStringToUInt64(s + 1, end);
return ConvertStringToUInt64(s, end);
}
+
+Int64 ConvertStringToInt64(const wchar_t *s, const wchar_t **end)
+{
+ if (*s == L'-')
+ return -(Int64)ConvertStringToUInt64(s + 1, end);
+ return ConvertStringToUInt64(s, end);
+}
diff --git a/CPP/Common/StringToInt.h b/CPP/Common/StringToInt.h
index c0d860ef..cd99f17e 100755
--- a/CPP/Common/StringToInt.h
+++ b/CPP/Common/StringToInt.h
@@ -1,9 +1,8 @@
// Common/StringToInt.h
-#ifndef __COMMON_STRINGTOINT_H
-#define __COMMON_STRINGTOINT_H
+#ifndef __COMMON_STRING_TO_INT_H
+#define __COMMON_STRING_TO_INT_H
-#include <string.h>
#include "Types.h"
UInt64 ConvertStringToUInt64(const char *s, const char **end);
@@ -12,7 +11,6 @@ UInt64 ConvertHexStringToUInt64(const char *s, const char **end);
UInt64 ConvertStringToUInt64(const wchar_t *s, const wchar_t **end);
Int64 ConvertStringToInt64(const char *s, const char **end);
+Int64 ConvertStringToInt64(const wchar_t *s, const wchar_t **end);
#endif
-
-
diff --git a/CPP/Common/Wildcard.cpp b/CPP/Common/Wildcard.cpp
index 476ddebd..87d44971 100755
--- a/CPP/Common/Wildcard.cpp
+++ b/CPP/Common/Wildcard.cpp
@@ -342,9 +342,9 @@ void CCensorNode::AddItem2(bool include, const UString &path, bool recursive)
bool forFile = true;
bool forFolder = true;
UString path2 = path;
- if (IsCharDirLimiter(path[path.Length() - 1]))
+ if (IsCharDirLimiter(path.Back()))
{
- path2.Delete(path.Length() - 1);
+ path2.DeleteBack();
forFile = false;
}
AddItem(include, path2, recursive, forFile, forFolder);
diff --git a/CPP/Windows/Control/Dialog.cpp b/CPP/Windows/Control/Dialog.cpp
index 3cfa517a..2695ca54 100755
--- a/CPP/Windows/Control/Dialog.cpp
+++ b/CPP/Windows/Control/Dialog.cpp
@@ -2,10 +2,10 @@
#include "StdAfx.h"
+#include "Windows/Control/Dialog.h"
#ifndef _UNICODE
-#include "Common/StringConvert.h"
+#include "../../Common/StringConvert.h"
#endif
-#include "Windows/Control/Dialog.h"
extern HINSTANCE g_hInstance;
#ifndef _UNICODE
@@ -17,17 +17,16 @@ namespace NControl {
static INT_PTR APIENTRY DialogProcedure(HWND dialogHWND, UINT message, WPARAM wParam, LPARAM lParam)
{
- CWindow dialogTmp(dialogHWND);
+ CWindow tempDialog(dialogHWND);
if (message == WM_INITDIALOG)
- dialogTmp.SetUserDataLongPtr(lParam);
- CDialog *dialog = (CDialog *)(dialogTmp.GetUserDataLongPtr());
+ tempDialog.SetUserDataLongPtr(lParam);
+ CDialog *dialog = (CDialog *)(tempDialog.GetUserDataLongPtr());
if (dialog == NULL)
return FALSE;
if (message == WM_INITDIALOG)
dialog->Attach(dialogHWND);
-
try { return BoolToBOOL(dialog->OnMessage(message, wParam, lParam)); }
- catch(...) { return true; }
+ catch(...) { return TRUE; }
}
bool CDialog::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
@@ -68,7 +67,7 @@ bool CDialog::OnCommand(int code, int itemID, LPARAM lParam)
bool CDialog::OnButtonClicked(int buttonID, HWND /* buttonHWND */)
{
- switch(buttonID)
+ switch (buttonID)
{
case IDOK: OnOK(); break;
case IDCANCEL: OnCancel(); break;
diff --git a/CPP/Windows/Control/ListView.cpp b/CPP/Windows/Control/ListView.cpp
index 53777bdb..255a17c5 100755
--- a/CPP/Windows/Control/ListView.cpp
+++ b/CPP/Windows/Control/ListView.cpp
@@ -4,6 +4,10 @@
#include "Windows/Control/ListView.h"
+#ifndef _UNICODE
+extern bool g_IsNT;
+#endif
+
namespace NWindows {
namespace NControl {
@@ -93,4 +97,59 @@ int CListView::SetSubItem(int index, int subIndex, LPCWSTR text)
#endif
+static LRESULT APIENTRY ListViewSubclassProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ CWindow window(hwnd);
+ CListView2 *w = (CListView2 *)(window.GetUserDataLongPtr());
+ if (w == NULL)
+ return 0;
+ return w->OnMessage(message, wParam, lParam);
+}
+
+LRESULT CListView2::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ #ifndef _UNICODE
+ if (g_IsNT)
+ return CallWindowProcW(_origWindowProc, *this, message, wParam, lParam);
+ else
+ #endif
+ return CallWindowProc(_origWindowProc, *this, message, wParam, lParam);
+}
+
+void CListView2::SetWindowProc()
+{
+ SetUserDataLongPtr((LONG_PTR)this);
+ #ifndef _UNICODE
+ if (g_IsNT)
+ _origWindowProc = (WNDPROC)SetLongPtrW(GWLP_WNDPROC, (LONG_PTR)ListViewSubclassProc);
+ else
+ #endif
+ _origWindowProc = (WNDPROC)SetLongPtr(GWLP_WNDPROC, (LONG_PTR)ListViewSubclassProc);
+}
+
+/*
+LRESULT CListView3::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ LRESULT res = CListView2::OnMessage(message, wParam, lParam);
+ if (message == WM_GETDLGCODE)
+ {
+ // when user presses RETURN, windows sends default (first) button command to parent dialog.
+ // we disable this:
+ MSG *msg = (MSG *)lParam;
+ WPARAM key = wParam;
+ bool change = false;
+ if (msg)
+ {
+ if (msg->message == WM_KEYDOWN && msg->wParam == VK_RETURN)
+ change = true;
+ }
+ else if (wParam == VK_RETURN)
+ change = true;
+ if (change)
+ res |= DLGC_WANTALLKEYS;
+ }
+ return res;
+}
+*/
+
}}
diff --git a/CPP/Windows/Control/ListView.h b/CPP/Windows/Control/ListView.h
index 1258ec93..bebcd9e2 100755
--- a/CPP/Windows/Control/ListView.h
+++ b/CPP/Windows/Control/ListView.h
@@ -18,9 +18,12 @@ public:
HWND parentWindow, HMENU idOrHMenu,
HINSTANCE instance, LPVOID createParam);
- #ifndef UNDER_CE
- bool SetUnicodeFormat(bool fUnicode) { return BOOLToBool(ListView_SetUnicodeFormat(_window, BOOLToBool(fUnicode))); }
- #endif
+ void SetUnicodeFormat()
+ {
+ #ifndef UNDER_CE
+ ListView_SetUnicodeFormat(_window, TRUE);
+ #endif
+ }
bool DeleteAllItems() { return BOOLToBool(ListView_DeleteAllItems(_window)); }
bool DeleteColumn(int columnIndex) { return BOOLToBool(ListView_DeleteColumn(_window, columnIndex)); }
@@ -65,8 +68,12 @@ public:
{ return BOOLToBool(ListView_SortItems(_window, compareFunction, dataParam)); }
void SetItemState(int index, UINT state, UINT mask) { ListView_SetItemState(_window, index, state, mask); }
+ void SetItemState_Selected(int index, bool select) { SetItemState(index, select ? LVIS_SELECTED : 0, LVIS_SELECTED); }
+ void SetItemState_Selected(int index) { SetItemState(index, LVIS_SELECTED, LVIS_SELECTED); }
+ void SelectAll() { SetItemState_Selected(-1); }
void SetItemState_FocusedSelected(int index) { SetItemState(index, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED); }
UINT GetItemState(int index, UINT mask) const { return ListView_GetItemState(_window, index, mask); }
+ bool IsItemSelected(int index) const { return GetItemState(index, LVIS_SELECTED) == LVIS_SELECTED; }
bool GetColumn(int columnIndex, LVCOLUMN* columnInfo) const
{ return BOOLToBool(ListView_GetColumn(_window, columnIndex, columnInfo)); }
@@ -104,6 +111,22 @@ public:
bool SetColumnWidthAuto(int iCol) { return SetColumnWidth(iCol, LVSCW_AUTOSIZE); }
};
+class CListView2: public CListView
+{
+ WNDPROC _origWindowProc;
+public:
+ void SetWindowProc();
+ virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+};
+
+/*
+class CListView3: public CListView2
+{
+public:
+ virtual LRESULT OnMessage(UINT message, WPARAM wParam, LPARAM lParam);
+};
+*/
+
}}
#endif
diff --git a/CPP/Windows/Control/PropertyPage.cpp b/CPP/Windows/Control/PropertyPage.cpp
index 01724797..d7eaab17 100755
--- a/CPP/Windows/Control/PropertyPage.cpp
+++ b/CPP/Windows/Control/PropertyPage.cpp
@@ -15,50 +15,30 @@ extern bool g_IsNT;
namespace NWindows {
namespace NControl {
-INT_PTR APIENTRY ProperyPageProcedure(HWND dialogHWND, UINT message,
- WPARAM wParam, LPARAM lParam)
+static INT_PTR APIENTRY MyProperyPageProcedure(HWND dialogHWND, UINT message, WPARAM wParam, LPARAM lParam)
{
- CDialog tempDialog(dialogHWND);
+ CWindow tempDialog(dialogHWND);
if (message == WM_INITDIALOG)
tempDialog.SetUserDataLongPtr(((PROPSHEETPAGE *)lParam)->lParam);
CDialog *dialog = (CDialog *)(tempDialog.GetUserDataLongPtr());
+ if (dialog == NULL)
+ return FALSE;
if (message == WM_INITDIALOG)
dialog->Attach(dialogHWND);
- switch (message)
- {
- case WM_INITDIALOG:
- return dialog->OnInit();
- case WM_COMMAND:
- return dialog->OnCommand(wParam, lParam);
- case WM_NOTIFY:
- return dialog->OnNotify((UINT)wParam, (LPNMHDR) lParam);
- }
- if (dialog == NULL)
- return false;
- return dialog->OnMessage(message, wParam, lParam);
+ try { return BoolToBOOL(dialog->OnMessage(message, wParam, lParam)); }
+ catch(...) { return TRUE; }
}
bool CPropertyPage::OnNotify(UINT /* controlID */, LPNMHDR lParam)
{
- switch(lParam->code)
+ switch (lParam->code)
{
- case PSN_APPLY:
- SetMsgResult(OnApply(LPPSHNOTIFY(lParam)));
- break;
- case PSN_KILLACTIVE:
- SetMsgResult(BoolToBOOL(OnKillActive(LPPSHNOTIFY(lParam))));
- break;
- case PSN_SETACTIVE:
- SetMsgResult(OnSetActive(LPPSHNOTIFY(lParam)));
- break;
- case PSN_RESET:
- OnReset(LPPSHNOTIFY(lParam));
- break;
- case PSN_HELP:
- OnNotifyHelp(LPPSHNOTIFY(lParam));
- break;
- default:
- return false;
+ case PSN_APPLY: SetMsgResult(OnApply(LPPSHNOTIFY(lParam))); break;
+ case PSN_KILLACTIVE: SetMsgResult(BoolToBOOL(OnKillActive(LPPSHNOTIFY(lParam)))); break;
+ case PSN_SETACTIVE: SetMsgResult(OnSetActive(LPPSHNOTIFY(lParam))); break;
+ case PSN_RESET: OnReset(LPPSHNOTIFY(lParam)); break;
+ case PSN_HELP: OnNotifyHelp(LPPSHNOTIFY(lParam)); break;
+ default: return false;
}
return true;
}
@@ -90,7 +70,7 @@ INT_PTR MyPropertySheet(const CObjectVector<CPageInfo> &pagesInfo, HWND hwndPare
page.hInstance = g_hInstance;
page.pszTemplate = MAKEINTRESOURCE(pageInfo.ID);
page.pszIcon = NULL;
- page.pfnDlgProc = NWindows::NControl::ProperyPageProcedure;
+ page.pfnDlgProc = NWindows::NControl::MyProperyPageProcedure;
if (titles[i].IsEmpty())
page.pszTitle = NULL;
@@ -111,7 +91,7 @@ INT_PTR MyPropertySheet(const CObjectVector<CPageInfo> &pagesInfo, HWND hwndPare
page.hInstance = g_hInstance;
page.pszTemplate = MAKEINTRESOURCEW(pageInfo.ID);
page.pszIcon = NULL;
- page.pfnDlgProc = NWindows::NControl::ProperyPageProcedure;
+ page.pfnDlgProc = NWindows::NControl::MyProperyPageProcedure;
if (pageInfo.Title.IsEmpty())
page.pszTitle = NULL;
diff --git a/CPP/Windows/DLL.cpp b/CPP/Windows/DLL.cpp
index 5afd72d9..81eec692 100755
--- a/CPP/Windows/DLL.cpp
+++ b/CPP/Windows/DLL.cpp
@@ -2,16 +2,14 @@
#include "StdAfx.h"
-#ifndef _UNICODE
-#include "../Common/StringConvert.h"
-#endif
-
#include "DLL.h"
#ifndef _UNICODE
extern bool g_IsNT;
#endif
+extern HINSTANCE g_hInstance;
+
namespace NWindows {
namespace NDLL {
@@ -19,92 +17,91 @@ bool CLibrary::Free()
{
if (_module == 0)
return true;
- // MessageBox(0, TEXT(""), TEXT("Free"), 0);
- // Sleep(5000);
if (!::FreeLibrary(_module))
return false;
_module = 0;
return true;
}
-bool CLibrary::LoadOperations(HMODULE newModule)
+bool CLibrary::LoadEx(CFSTR path, DWORD flags)
{
- if (newModule == NULL)
- return false;
if (!Free())
return false;
- _module = newModule;
- return true;
-}
-
-bool CLibrary::LoadEx(LPCTSTR fileName, DWORD flags)
-{
- // MessageBox(0, fileName, TEXT("LoadEx"), 0);
- return LoadOperations(::LoadLibraryEx(fileName, NULL, flags));
-}
-
-bool CLibrary::Load(LPCTSTR fileName)
-{
- // MessageBox(0, fileName, TEXT("Load"), 0);
- // Sleep(5000);
- // OutputDebugString(fileName);
- // OutputDebugString(TEXT("\n"));
- return LoadOperations(::LoadLibrary(fileName));
-}
-
-#ifndef _UNICODE
-static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
-CSysString GetSysPath(LPCWSTR sysPath)
- { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
-
-bool CLibrary::LoadEx(LPCWSTR fileName, DWORD flags)
-{
- if (g_IsNT)
- return LoadOperations(::LoadLibraryExW(fileName, NULL, flags));
- return LoadEx(GetSysPath(fileName), flags);
-}
-bool CLibrary::Load(LPCWSTR fileName)
-{
- if (g_IsNT)
- return LoadOperations(::LoadLibraryW(fileName));
- return Load(GetSysPath(fileName));
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ _module = ::LoadLibraryEx(fs2fas(path), NULL, flags);
+ }
+ else
+ #endif
+ {
+ _module = ::LoadLibraryExW(fs2us(path), NULL, flags);
+ }
+ return (_module != NULL);
}
-#endif
-bool MyGetModuleFileName(HMODULE hModule, CSysString &result)
+bool CLibrary::Load(CFSTR path)
{
- result.Empty();
- TCHAR fullPath[MAX_PATH + 2];
- DWORD size = ::GetModuleFileName(hModule, fullPath, MAX_PATH + 1);
- if (size <= MAX_PATH && size != 0)
+ if (!Free())
+ return false;
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- result = fullPath;
- return true;
+ _module = ::LoadLibrary(fs2fas(path));
}
- return false;
+ else
+ #endif
+ {
+ _module = ::LoadLibraryW(fs2us(path));
+ }
+ return (_module != NULL);
}
-#ifndef _UNICODE
-bool MyGetModuleFileName(HMODULE hModule, UString &result)
+bool MyGetModuleFileName(FString &path)
{
- result.Empty();
- if (g_IsNT)
+ HMODULE hModule = g_hInstance;
+ path.Empty();
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- wchar_t fullPath[MAX_PATH + 2];
- DWORD size = ::GetModuleFileNameW(hModule, fullPath, MAX_PATH + 1);
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ DWORD size = ::GetModuleFileName(hModule, s, MAX_PATH + 1);
if (size <= MAX_PATH && size != 0)
{
- result = fullPath;
+ path = fas2fs(s);
return true;
}
- return false;
}
- CSysString resultSys;
- if (!MyGetModuleFileName(hModule, resultSys))
- return false;
- result = MultiByteToUnicodeString(resultSys, GetCurrentCodePage());
- return true;
+ else
+ #endif
+ {
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ DWORD size = ::GetModuleFileNameW(hModule, s, MAX_PATH + 1);
+ if (size <= MAX_PATH && size != 0)
+ {
+ path = us2fs(s);
+ return true;
+ }
+ }
+ return false;
+}
+
+#ifndef _SFX
+
+FString GetModuleDirPrefix()
+{
+ FString s;
+ if (NDLL::MyGetModuleFileName(s))
+ {
+ int pos = s.ReverseFind(FCHAR_PATH_SEPARATOR);
+ if (pos >= 0)
+ return s.Left(pos + 1);
+ }
+ return FTEXT(".") FSTRING_PATH_SEPARATOR;
}
+
#endif
}}
diff --git a/CPP/Windows/DLL.h b/CPP/Windows/DLL.h
index 4a253b32..9f0f5cd7 100755
--- a/CPP/Windows/DLL.h
+++ b/CPP/Windows/DLL.h
@@ -9,15 +9,13 @@ namespace NWindows {
namespace NDLL {
#ifdef UNDER_CE
-#define My_GetProcAddress(module, proceName) GetProcAddressA(module, proceName)
+#define My_GetProcAddress(module, procName) ::GetProcAddressA(module, procName)
#else
-#define My_GetProcAddress(module, proceName) ::GetProcAddress(module, proceName)
+#define My_GetProcAddress(module, procName) ::GetProcAddress(module, procName)
#endif
class CLibrary
{
- bool LoadOperations(HMODULE newModule);
-protected:
HMODULE _module;
public:
CLibrary(): _module(NULL) {};
@@ -40,19 +38,14 @@ public:
}
bool Free();
- bool LoadEx(LPCTSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
- bool Load(LPCTSTR fileName);
- #ifndef _UNICODE
- bool LoadEx(LPCWSTR fileName, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
- bool Load(LPCWSTR fileName);
- #endif
+ bool LoadEx(CFSTR path, DWORD flags = LOAD_LIBRARY_AS_DATAFILE);
+ bool Load(CFSTR path);
FARPROC GetProc(LPCSTR procName) const { return My_GetProcAddress(_module, procName); }
};
-bool MyGetModuleFileName(HMODULE hModule, CSysString &result);
-#ifndef _UNICODE
-bool MyGetModuleFileName(HMODULE hModule, UString &result);
-#endif
+bool MyGetModuleFileName(FString &path);
+
+FString GetModuleDirPrefix();
}}
diff --git a/CPP/Windows/Error.cpp b/CPP/Windows/Error.cpp
index 7b18c29c..c02e3b9e 100755
--- a/CPP/Windows/Error.cpp
+++ b/CPP/Windows/Error.cpp
@@ -14,37 +14,47 @@ extern bool g_IsNT;
namespace NWindows {
namespace NError {
-bool MyFormatMessage(DWORD messageID, CSysString &message)
+static bool MyFormatMessage(DWORD errorCode, UString &message)
{
LPVOID msgBuf;
- if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,messageID, 0, (LPTSTR) &msgBuf,0, NULL) == 0)
- return false;
- message = (LPCTSTR)msgBuf;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, errorCode, 0, (LPTSTR) &msgBuf, 0, NULL) == 0)
+ return false;
+ message = GetUnicodeString((LPCTSTR)msgBuf);
+ }
+ else
+ #endif
+ {
+ if (::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, errorCode, 0, (LPWSTR) &msgBuf, 0, NULL) == 0)
+ return false;
+ message = (LPCWSTR)msgBuf;
+ }
::LocalFree(msgBuf);
return true;
}
-#ifndef _UNICODE
-bool MyFormatMessage(DWORD messageID, UString &message)
+UString MyFormatMessageW(DWORD errorCode)
{
- if (g_IsNT)
+ UString message;
+ if (!MyFormatMessage(errorCode, message))
{
- LPVOID msgBuf;
- if (::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, messageID, 0, (LPWSTR) &msgBuf, 0, NULL) == 0)
- return false;
- message = (LPCWSTR)msgBuf;
- ::LocalFree(msgBuf);
- return true;
+ wchar_t s[16];
+ for (int i = 0; i < 8; i++)
+ {
+ int t = errorCode & 0xF;
+ errorCode >>= 4;
+ s[7 - i] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ }
+ s[8] = '\0';
+ message = (UString)L"Error #" + s;
}
- CSysString messageSys;
- bool result = MyFormatMessage(messageID, messageSys);
- message = GetUnicodeString(messageSys);
- return result;
+ return message;
}
-#endif
}}
diff --git a/CPP/Windows/Error.h b/CPP/Windows/Error.h
index 05b5cd0e..b7da3ca5 100755
--- a/CPP/Windows/Error.h
+++ b/CPP/Windows/Error.h
@@ -8,25 +8,7 @@
namespace NWindows {
namespace NError {
-bool MyFormatMessage(DWORD messageID, CSysString &message);
-inline CSysString MyFormatMessage(DWORD messageID)
-{
- CSysString message;
- MyFormatMessage(messageID, message);
- return message;
-}
-#ifdef _UNICODE
-inline UString MyFormatMessageW(DWORD messageID)
- { return MyFormatMessage(messageID); }
-#else
-bool MyFormatMessage(DWORD messageID, UString &message);
-inline UString MyFormatMessageW(DWORD messageID)
-{
- UString message;
- MyFormatMessage(messageID, message);
- return message;
-}
-#endif
+UString MyFormatMessageW(DWORD errorCode);
}}
diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp
index 85794603..88215faa 100755
--- a/CPP/Windows/FileDir.cpp
+++ b/CPP/Windows/FileDir.cpp
@@ -17,78 +17,64 @@ extern bool g_IsNT;
namespace NWindows {
namespace NFile {
-#if defined(WIN_LONG_PATH) && defined(_UNICODE)
-#define WIN_LONG_PATH2
-#endif
-
// SetCurrentDirectory doesn't support \\?\ prefix
#ifdef WIN_LONG_PATH
-bool GetLongPathBase(LPCWSTR fileName, UString &res);
-bool GetLongPath(LPCWSTR fileName, UString &res);
+bool GetLongPathBase(CFSTR fileName, UString &res);
+bool GetLongPath(CFSTR fileName, UString &res);
#endif
namespace NDirectory {
-#ifndef _UNICODE
-static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
-static UString GetUnicodePath(const CSysString &sysPath)
- { return MultiByteToUnicodeString(sysPath, GetCurrentCodePage()); }
-static CSysString GetSysPath(LPCWSTR sysPath)
- { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
-#endif
-
#ifndef UNDER_CE
-bool MyGetWindowsDirectory(CSysString &path)
+bool MyGetWindowsDirectory(FString &path)
{
- UINT needLength = ::GetWindowsDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
-}
-
-bool MyGetSystemDirectory(CSysString &path)
-{
- UINT needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
- path.ReleaseBuffer();
+ UINT needLength;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetWindowsDirectory(s, MAX_PATH + 1);
+ path = fas2fs(s);
+ }
+ else
+ #endif
+ {
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetWindowsDirectoryW(s, MAX_PATH + 1);
+ path = us2fs(s);
+ }
return (needLength > 0 && needLength <= MAX_PATH);
}
-#endif
-#ifndef _UNICODE
-bool MyGetWindowsDirectory(UString &path)
+bool MyGetSystemDirectory(FString &path)
{
- if (g_IsNT)
+ UINT needLength;
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- UINT needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetSystemDirectory(s, MAX_PATH + 1);
+ path = fas2fs(s);
}
- CSysString sysPath;
- if (!MyGetWindowsDirectory(sysPath))
- return false;
- path = GetUnicodePath(sysPath);
- return true;
-}
-
-bool MyGetSystemDirectory(UString &path)
-{
- if (g_IsNT)
+ else
+ #endif
{
- UINT needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetSystemDirectoryW(s, MAX_PATH + 1);
+ path = us2fs(s);
}
- CSysString sysPath;
- if (!MyGetSystemDirectory(sysPath))
- return false;
- path = GetUnicodePath(sysPath);
- return true;
+ return (needLength > 0 && needLength <= MAX_PATH);
}
#endif
-bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
+bool SetDirTime(CFSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
{
#ifndef _UNICODE
if (!g_IsNT)
@@ -97,17 +83,15 @@ bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime,
return false;
}
#endif
- HANDLE hDir = ::CreateFileW(fileName, GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
+ HANDLE hDir = ::CreateFileW(fs2us(fileName), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
#ifdef WIN_LONG_PATH
if (hDir == INVALID_HANDLE_VALUE)
{
UString longPath;
if (GetLongPath(fileName, longPath))
- hDir = ::CreateFileW(longPath, GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ hDir = ::CreateFileW(longPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
}
#endif
@@ -120,219 +104,122 @@ bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime,
return res;
}
-bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
-{
- if (::SetFileAttributes(fileName, fileAttributes))
- return true;
- #ifdef WIN_LONG_PATH2
- UString longPath;
- if (GetLongPath(fileName, longPath))
- return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));
- #endif
- return false;
-}
-
-bool MyRemoveDirectory(LPCTSTR pathName)
-{
- if (::RemoveDirectory(pathName))
- return true;
- #ifdef WIN_LONG_PATH2
- UString longPath;
- if (GetLongPath(pathName, longPath))
- return BOOLToBool(::RemoveDirectoryW(longPath));
- #endif
- return false;
-}
-
#ifdef WIN_LONG_PATH
-bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2)
+bool GetLongPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2)
{
- if (!GetLongPathBase(s1, d1) || !GetLongPathBase(s2, d2))
+ if (!GetLongPathBase(s1, d1) ||
+ !GetLongPathBase(s2, d2))
return false;
- if (d1.IsEmpty() && d2.IsEmpty()) return false;
- if (d1.IsEmpty()) d1 = s1;
- if (d2.IsEmpty()) d2 = s2;
+ if (d1.IsEmpty() && d2.IsEmpty())
+ return false;
+ if (d1.IsEmpty()) d1 = fs2us(s1);
+ if (d2.IsEmpty()) d2 = fs2us(s2);
return true;
}
#endif
-bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName)
-{
- if (::MoveFile(existFileName, newFileName))
- return true;
- #ifdef WIN_LONG_PATH2
- UString d1, d2;
- if (GetLongPaths(existFileName, newFileName, d1, d2))
- return BOOLToBool(::MoveFileW(d1, d2));
- #endif
- return false;
-}
-
-#ifndef _UNICODE
-bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes)
-{
- if (!g_IsNT)
- return MySetFileAttributes(GetSysPath(fileName), fileAttributes);
- if (::SetFileAttributesW(fileName, fileAttributes))
- return true;
- #ifdef WIN_LONG_PATH
- UString longPath;
- if (GetLongPath(fileName, longPath))
- return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));
- #endif
- return false;
-}
-
-
-bool MyRemoveDirectory(LPCWSTR pathName)
+bool MySetFileAttributes(CFSTR fileName, DWORD fileAttributes)
{
+ #ifndef _UNICODE
if (!g_IsNT)
- return MyRemoveDirectory(GetSysPath(pathName));
- if (::RemoveDirectoryW(pathName))
- return true;
- #ifdef WIN_LONG_PATH
- UString longPath;
- if (GetLongPath(pathName, longPath))
- return BOOLToBool(::RemoveDirectoryW(longPath));
+ {
+ if (::SetFileAttributes(fs2fas(fileName), fileAttributes))
+ return true;
+ }
+ else
#endif
+ {
+ if (::SetFileAttributesW(fs2us(fileName), fileAttributes))
+ return true;
+ #ifdef WIN_LONG_PATH
+ UString longPath;
+ if (GetLongPath(fileName, longPath))
+ return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));
+ #endif
+ }
return false;
}
-bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName)
+bool MyRemoveDirectory(CFSTR path)
{
+ #ifndef _UNICODE
if (!g_IsNT)
- return MyMoveFile(GetSysPath(existFileName), GetSysPath(newFileName));
- if (::MoveFileW(existFileName, newFileName))
- return true;
- #ifdef WIN_LONG_PATH
- UString d1, d2;
- if (GetLongPaths(existFileName, newFileName, d1, d2))
- return BOOLToBool(::MoveFileW(d1, d2));
+ {
+ if (::RemoveDirectory(fs2fas(path)))
+ return true;
+ }
+ else
#endif
- return false;
-}
-#endif
-
-bool MyCreateDirectory(LPCTSTR pathName)
-{
- if (::CreateDirectory(pathName, NULL))
- return true;
- #ifdef WIN_LONG_PATH2
- if (::GetLastError() != ERROR_ALREADY_EXISTS)
{
+ if (::RemoveDirectoryW(fs2us(path)))
+ return true;
+ #ifdef WIN_LONG_PATH
UString longPath;
- if (GetLongPath(pathName, longPath))
- return BOOLToBool(::CreateDirectoryW(longPath, NULL));
+ if (GetLongPath(path, longPath))
+ return BOOLToBool(::RemoveDirectoryW(longPath));
+ #endif
}
- #endif
return false;
}
-#ifndef _UNICODE
-bool MyCreateDirectory(LPCWSTR pathName)
+bool MyMoveFile(CFSTR existFileName, CFSTR newFileName)
{
+ #ifndef _UNICODE
if (!g_IsNT)
- return MyCreateDirectory(GetSysPath(pathName));
- if (::CreateDirectoryW(pathName, NULL))
- return true;
- #ifdef WIN_LONG_PATH
- if (::GetLastError() != ERROR_ALREADY_EXISTS)
{
- UString longPath;
- if (GetLongPath(pathName, longPath))
- return BOOLToBool(::CreateDirectoryW(longPath, NULL));
+ if (::MoveFile(fs2fas(existFileName), fs2fas(newFileName)))
+ return true;
}
+ else
#endif
- return false;
-}
-#endif
-
-/*
-bool CreateComplexDirectory(LPCTSTR pathName)
-{
- NName::CParsedPath path;
- path.ParsePath(pathName);
- CSysString fullPath = path.Prefix;
- DWORD errorCode = ERROR_SUCCESS;
- for (int i = 0; i < path.PathParts.Size(); i++)
- {
- const CSysString &string = path.PathParts[i];
- if (string.IsEmpty())
- {
- if (i != path.PathParts.Size() - 1)
- return false;
+ {
+ if (::MoveFileW(fs2us(existFileName), fs2us(newFileName)))
return true;
- }
- fullPath += path.PathParts[i];
- if (!MyCreateDirectory(fullPath))
- {
- DWORD errorCode = GetLastError();
- if (errorCode != ERROR_ALREADY_EXISTS)
- return false;
- }
- fullPath += NName::kDirDelimiter;
+ #ifdef WIN_LONG_PATH
+ UString d1, d2;
+ if (GetLongPaths(existFileName, newFileName, d1, d2))
+ return BOOLToBool(::MoveFileW(d1, d2));
+ #endif
}
- return true;
+ return false;
}
-*/
-bool CreateComplexDirectory(LPCTSTR _aPathName)
+bool MyCreateDirectory(CFSTR path)
{
- CSysString pathName = _aPathName;
- int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
- if (pos > 0 && pos == pathName.Length() - 1)
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- if (pathName.Length() == 3 && pathName[1] == ':')
- return true; // Disk folder;
- pathName.Delete(pos);
+ if (::CreateDirectory(fs2fas(path), NULL))
+ return true;
}
- CSysString pathName2 = pathName;
- pos = pathName.Length();
- for (;;)
+ else
+ #endif
{
- if (MyCreateDirectory(pathName))
- break;
- if (::GetLastError() == ERROR_ALREADY_EXISTS)
+ if (::CreateDirectoryW(fs2us(path), NULL))
+ return true;
+ #ifdef WIN_LONG_PATH
+ if (::GetLastError() != ERROR_ALREADY_EXISTS)
{
- NFind::CFileInfo fileInfo;
- if (!fileInfo.Find(pathName)) // For network folders
- return true;
- if (!fileInfo.IsDir())
- return false;
- break;
+ UString longPath;
+ if (GetLongPath(path, longPath))
+ return BOOLToBool(::CreateDirectoryW(longPath, NULL));
}
- pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
- if (pos < 0 || pos == 0)
- return false;
- if (pathName[pos - 1] == ':')
- return false;
- pathName = pathName.Left(pos);
- }
- pathName = pathName2;
- while (pos < pathName.Length())
- {
- pos = pathName.Find(TEXT(CHAR_PATH_SEPARATOR), pos + 1);
- if (pos < 0)
- pos = pathName.Length();
- if (!MyCreateDirectory(pathName.Left(pos)))
- return false;
+ #endif
}
- return true;
+ return false;
}
-#ifndef _UNICODE
-
-bool CreateComplexDirectory(LPCWSTR _aPathName)
+bool CreateComplexDirectory(CFSTR _aPathName)
{
- UString pathName = _aPathName;
- int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
+ FString pathName = _aPathName;
+ int pos = pathName.ReverseFind(FCHAR_PATH_SEPARATOR);
if (pos > 0 && pos == pathName.Length() - 1)
{
if (pathName.Length() == 3 && pathName[1] == L':')
return true; // Disk folder;
pathName.Delete(pos);
}
- UString pathName2 = pathName;
+ FString pathName2 = pathName;
pos = pathName.Length();
for (;;)
{
@@ -340,14 +227,14 @@ bool CreateComplexDirectory(LPCWSTR _aPathName)
break;
if (::GetLastError() == ERROR_ALREADY_EXISTS)
{
- NFind::CFileInfoW fileInfo;
+ NFind::CFileInfo fileInfo;
if (!fileInfo.Find(pathName)) // For network folders
return true;
if (!fileInfo.IsDir())
return false;
break;
}
- pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
+ pos = pathName.ReverseFind(FCHAR_PATH_SEPARATOR);
if (pos < 0 || pos == 0)
return false;
if (pathName[pos - 1] == L':')
@@ -357,7 +244,7 @@ bool CreateComplexDirectory(LPCWSTR _aPathName)
pathName = pathName2;
while (pos < pathName.Length())
{
- pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1);
+ pos = pathName.Find(FCHAR_PATH_SEPARATOR, pos + 1);
if (pos < 0)
pos = pathName.Length();
if (!MyCreateDirectory(pathName.Left(pos)))
@@ -366,75 +253,42 @@ bool CreateComplexDirectory(LPCWSTR _aPathName)
return true;
}
-#endif
-
-bool DeleteFileAlways(LPCTSTR name)
+bool DeleteFileAlways(CFSTR name)
{
if (!MySetFileAttributes(name, 0))
return false;
- if (::DeleteFile(name))
- return true;
- #ifdef WIN_LONG_PATH2
- UString longPath;
- if (GetLongPath(name, longPath))
- return BOOLToBool(::DeleteFileW(longPath));
- #endif
- return false;
-}
-
-#ifndef _UNICODE
-bool DeleteFileAlways(LPCWSTR name)
-{
+ #ifndef _UNICODE
if (!g_IsNT)
- return DeleteFileAlways(GetSysPath(name));
- if (!MySetFileAttributes(name, 0))
- return false;
- if (::DeleteFileW(name))
- return true;
- #ifdef WIN_LONG_PATH
- UString longPath;
- if (GetLongPath(name, longPath))
- return BOOLToBool(::DeleteFileW(longPath));
+ {
+ if (::DeleteFile(fs2fas(name)))
+ return true;
+ }
+ else
#endif
- return false;
-}
-#endif
-
-static bool RemoveDirectorySubItems2(const CSysString pathPrefix, const NFind::CFileInfo &fileInfo)
-{
- if (fileInfo.IsDir())
- return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
- return DeleteFileAlways(pathPrefix + fileInfo.Name);
-}
-
-bool RemoveDirectoryWithSubItems(const CSysString &path)
-{
- NFind::CFileInfo fileInfo;
- CSysString pathPrefix = path + NName::kDirDelimiter;
{
- NFind::CEnumerator enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard));
- while (enumerator.Next(fileInfo))
- if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
- return false;
+ if (::DeleteFileW(fs2us(name)))
+ return true;
+ #ifdef WIN_LONG_PATH
+ UString longPath;
+ if (GetLongPath(name, longPath))
+ return BOOLToBool(::DeleteFileW(longPath));
+ #endif
}
- if (!MySetFileAttributes(path, 0))
- return false;
- return MyRemoveDirectory(path);
+ return false;
}
-#ifndef _UNICODE
-static bool RemoveDirectorySubItems2(const UString pathPrefix, const NFind::CFileInfoW &fileInfo)
+static bool RemoveDirectorySubItems2(const FString pathPrefix, const NFind::CFileInfo &fileInfo)
{
if (fileInfo.IsDir())
return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
return DeleteFileAlways(pathPrefix + fileInfo.Name);
}
-bool RemoveDirectoryWithSubItems(const UString &path)
+bool RemoveDirectoryWithSubItems(const FString &path)
{
- NFind::CFileInfoW fileInfo;
- UString pathPrefix = path + UString(NName::kDirDelimiter);
+ NFind::CFileInfo fileInfo;
+ FString pathPrefix = path + FCHAR_PATH_SEPARATOR;
{
- NFind::CEnumeratorW enumerator(pathPrefix + UString(NName::kAnyStringWildcard));
+ NFind::CEnumerator enumerator(pathPrefix + FCHAR_ANY_MASK);
while (enumerator.Next(fileInfo))
if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
return false;
@@ -443,74 +297,40 @@ bool RemoveDirectoryWithSubItems(const UString &path)
return false;
return MyRemoveDirectory(path);
}
-#endif
-
-bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName)
-{
- int index;
- if (!MyGetFullPathName(fileName, resultName, index))
- return false;
- resultName = resultName.Left(index);
- return true;
-}
-
-bool GetOnlyName(LPCTSTR fileName, CSysString &resultName)
-{
- int index;
- if (!MyGetFullPathName(fileName, resultName, index))
- return false;
- resultName = resultName.Mid(index);
- return true;
-}
#ifdef UNDER_CE
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath)
-{
- resultPath = fileName;
- return true;
-}
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)
+bool MyGetFullPathName(CFSTR fileName, FString &resFullPath)
{
- resultPath = fileName;
- // change it
- fileNamePartStartIndex = resultPath.ReverseFind(WCHAR_PATH_SEPARATOR);
- fileNamePartStartIndex++;
+ resFullPath = fileName;
return true;
}
#else
-bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath)
-{
- DWORD needLength = ::GetShortPathName(longPath, shortPath.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
- shortPath.ReleaseBuffer();
- return (needLength > 0 && needLength < MAX_PATH);
-}
-
#ifdef WIN_LONG_PATH
-static UString GetLastPart(LPCWSTR path)
+static FString GetLastPart(CFSTR path)
{
- int i = (int)wcslen(path);
+ int i = MyStringLen(path);
for (; i > 0; i--)
{
- WCHAR c = path[i - 1];
- if (c == WCHAR_PATH_SEPARATOR || c == '/')
+ FChar c = path[i - 1];
+ if (c == FCHAR_PATH_SEPARATOR || c == '/')
break;
}
return path + i;
}
-static void AddTrailingDots(LPCWSTR oldPath, UString &newPath)
+static void AddTrailingDots(CFSTR oldPath, FString &newPath)
{
- int len = (int)wcslen(oldPath);
+ int len = MyStringLen(oldPath);
int i;
for (i = len; i > 0 && oldPath[i - 1] == '.'; i--);
if (i == 0 || i == len)
return;
- UString oldName = GetLastPart(oldPath);
- UString newName = GetLastPart(newPath);
+ FString oldName = GetLastPart(oldPath);
+ FString newName = GetLastPart(newPath);
int nonDotsLen = oldName.Length() - (len - i);
if (nonDotsLen == 0 || newName.CompareNoCase(oldName.Left(nonDotsLen)) != 0)
return;
@@ -520,390 +340,248 @@ static void AddTrailingDots(LPCWSTR oldPath, UString &newPath)
#endif
-bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex)
+bool MyGetFullPathName(CFSTR fileName, FString &resFullPath)
{
- resultPath.Empty();
- LPTSTR fileNamePointer = 0;
- LPTSTR buffer = resultPath.GetBuffer(MAX_PATH);
- DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
- resultPath.ReleaseBuffer();
- if (needLength == 0)
- return false;
- if (needLength >= MAX_PATH)
+ resFullPath.Empty();
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- #ifdef WIN_LONG_PATH2
- needLength++;
- buffer = resultPath.GetBuffer(needLength + 1);
- DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer);
- resultPath.ReleaseBuffer();
- if (needLength2 == 0 || needLength2 > needLength)
- #endif
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ LPTSTR fileNamePointer = 0;
+ DWORD needLength = ::GetFullPathName(fs2fas(fileName), MAX_PATH + 1, s, &fileNamePointer);
+ if (needLength == 0 || needLength > MAX_PATH)
return false;
+ resFullPath = fas2fs(s);
+ return true;
}
- if (fileNamePointer == 0)
- fileNamePartStartIndex = lstrlen(fileName);
else
- fileNamePartStartIndex = (int)(fileNamePointer - buffer);
- #ifdef _UNICODE
- #ifdef WIN_LONG_PATH
- AddTrailingDots(fileName, resultPath);
#endif
- #endif
- return true;
-}
-
-#ifndef _UNICODE
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)
-{
- resultPath.Empty();
- if (g_IsNT)
{
LPWSTR fileNamePointer = 0;
- LPWSTR buffer = resultPath.GetBuffer(MAX_PATH);
- DWORD needLength = ::GetFullPathNameW(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
- resultPath.ReleaseBuffer();
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ DWORD needLength = ::GetFullPathNameW(fs2us(fileName), MAX_PATH + 1, s, &fileNamePointer);
if (needLength == 0)
return false;
- if (needLength >= MAX_PATH)
+ if (needLength <= MAX_PATH)
{
- #ifdef WIN_LONG_PATH
- needLength++;
- buffer = resultPath.GetBuffer(needLength + 1);
- DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer);
- resultPath.ReleaseBuffer();
- if (needLength2 == 0 || needLength2 > needLength)
- #endif
- return false;
+ resFullPath = us2fs(s);
+ return true;
}
- if (fileNamePointer == 0)
- fileNamePartStartIndex = MyStringLen(fileName);
- else
- fileNamePartStartIndex = (int)(fileNamePointer - buffer);
#ifdef WIN_LONG_PATH
- AddTrailingDots(fileName, resultPath);
+ needLength++;
+ UString temp;
+ LPWSTR buffer = temp.GetBuffer(needLength + 1);
+ buffer[0] = 0;
+ DWORD needLength2 = ::GetFullPathNameW(fs2us(fileName), needLength, buffer, &fileNamePointer);
+ temp.ReleaseBuffer();
+ if (needLength2 > 0 && needLength2 <= needLength)
+ {
+ resFullPath = us2fs(temp);
+ AddTrailingDots(fileName, resFullPath);
+ return true;
+ }
#endif
+ return false;
+ }
+}
+
+bool MySetCurrentDirectory(CFSTR path)
+{
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ return BOOLToBool(::SetCurrentDirectory(fs2fas(path)));
}
else
+ #endif
{
- CSysString sysPath;
- if (!MyGetFullPathName(GetSysPath(fileName), sysPath, fileNamePartStartIndex))
- return false;
- UString resultPath1 = GetUnicodePath(sysPath.Left(fileNamePartStartIndex));
- UString resultPath2 = GetUnicodePath(sysPath.Mid(fileNamePartStartIndex));
- fileNamePartStartIndex = resultPath1.Length();
- resultPath = resultPath1 + resultPath2;
+ return BOOLToBool(::SetCurrentDirectoryW(fs2us(path)));
}
- return true;
}
-#endif
-
-bool MyGetFullPathName(LPCTSTR fileName, CSysString &path)
+bool MyGetCurrentDirectory(FString &path)
{
- int index;
- return MyGetFullPathName(fileName, path, index);
+ path.Empty();
+ DWORD needLength;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetCurrentDirectory(MAX_PATH + 1, s);
+ path = fas2fs(s);
+ }
+ else
+ #endif
+ {
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, s);
+ path = us2fs(s);
+ }
+ return (needLength > 0 && needLength <= MAX_PATH);
}
-#ifndef _UNICODE
-bool MyGetFullPathName(LPCWSTR fileName, UString &path)
-{
- int index;
- return MyGetFullPathName(fileName, path, index);
-}
#endif
-#ifndef _UNICODE
-bool GetOnlyName(LPCWSTR fileName, UString &resultName)
+bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName)
{
- int index;
- if (!MyGetFullPathName(fileName, resultName, index))
- return false;
- resultName = resultName.Mid(index);
- return true;
+ bool res = MyGetFullPathName(path, resFileName);
+ if (!res)
+ resFileName = path;
+ int pos = resFileName.ReverseFind(FCHAR_PATH_SEPARATOR);
+ if (pos >= 0)
+ {
+ resDirPrefix = resFileName.Left(pos + 1);
+ resFileName = resFileName.Mid(pos + 1);
+ }
+ return res;
}
-#endif
-#ifndef _UNICODE
-bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName)
+bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix)
{
- int index;
- if (!MyGetFullPathName(fileName, resultName, index))
- return false;
- resultName = resultName.Left(index);
- return true;
+ FString resFileName;
+ return GetFullPathAndSplit(path, resDirPrefix, resFileName);
}
-#endif
-bool MyGetCurrentDirectory(CSysString &path)
+bool MyGetTempPath(FString &path)
{
- DWORD needLength = ::GetCurrentDirectory(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
- path.ReleaseBuffer();
+ path.Empty();
+ DWORD needLength;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ TCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetTempPath(MAX_PATH + 1, s);
+ path = fas2fs(s);
+ }
+ else
+ #endif
+ {
+ WCHAR s[MAX_PATH + 2];
+ s[0] = 0;
+ needLength = ::GetTempPathW(MAX_PATH + 1, s);;
+ path = us2fs(s);
+ }
return (needLength > 0 && needLength <= MAX_PATH);
}
-#ifndef _UNICODE
-bool MySetCurrentDirectory(LPCWSTR path)
+static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COutFile *outFile)
{
- if (g_IsNT)
- return BOOLToBool(::SetCurrentDirectoryW(path));
- return MySetCurrentDirectory(GetSysPath(path));
-}
-bool MyGetCurrentDirectory(UString &path)
-{
- if (g_IsNT)
+ UInt32 d = (GetTickCount() << 12) ^ (GetCurrentThreadId() << 14) ^ GetCurrentProcessId();
+ for (unsigned i = 0; i < 100; i++)
{
- DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
+ path = prefix;
+ if (addRandom)
+ {
+ FChar s[16];
+ UInt32 value = d;
+ unsigned k;
+ for (k = 0; k < 8; k++)
+ {
+ unsigned t = value & 0xF;
+ value >>= 4;
+ s[k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
+ }
+ s[k] = '\0';
+ if (outFile)
+ path += FChar('.');
+ path += s;
+ UInt32 step = GetTickCount() + 2;
+ if (step == 0)
+ step = 1;
+ d += step;
+ }
+ addRandom = true;
+ if (outFile)
+ path += FTEXT(".tmp");
+ if (NFind::DoesFileOrDirExist(path))
+ {
+ SetLastError(ERROR_ALREADY_EXISTS);
+ continue;
+ }
+ if (outFile)
+ {
+ if (outFile->Create(path, false))
+ return true;
+ }
+ else
+ {
+ if (MyCreateDirectory(path))
+ return true;
+ }
+ DWORD error = GetLastError();
+ if (error != ERROR_FILE_EXISTS &&
+ error != ERROR_ALREADY_EXISTS)
+ break;
}
- CSysString sysPath;
- if (!MyGetCurrentDirectory(sysPath))
- return false;
- path = GetUnicodePath(sysPath);
- return true;
-}
-#endif
-
-bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
- CSysString &resultPath, UINT32 &filePart)
-{
- LPTSTR filePartPointer;
- DWORD value = ::SearchPath(path, fileName, extension,
- MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
- filePart = (UINT32)(filePartPointer - (LPCTSTR)resultPath);
- resultPath.ReleaseBuffer();
- return (value > 0 && value <= MAX_PATH);
+ path.Empty();
+ return false;
}
-#endif
-#ifndef _UNICODE
-bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
- UString &resultPath, UINT32 &filePart)
+bool CTempFile::Create(CFSTR prefix, NIO::COutFile *outFile)
{
- if (g_IsNT)
- {
- LPWSTR filePartPointer = 0;
- DWORD value = ::SearchPathW(path, fileName, extension,
- MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
- filePart = (UINT32)(filePartPointer - (LPCWSTR)resultPath);
- resultPath.ReleaseBuffer();
- return (value > 0 && value <= MAX_PATH);
- }
-
- CSysString sysPath;
- if (!MySearchPath(
- path != 0 ? (LPCTSTR)GetSysPath(path): 0,
- fileName != 0 ? (LPCTSTR)GetSysPath(fileName): 0,
- extension != 0 ? (LPCTSTR)GetSysPath(extension): 0,
- sysPath, filePart))
+ if (!Remove())
return false;
- UString resultPath1 = GetUnicodePath(sysPath.Left(filePart));
- UString resultPath2 = GetUnicodePath(sysPath.Mid(filePart));
- filePart = resultPath1.Length();
- resultPath = resultPath1 + resultPath2;
- return true;
-}
-#endif
-
-bool MyGetTempPath(CSysString &path)
-{
- DWORD needLength = ::GetTempPath(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
-}
-
-#ifndef _UNICODE
-bool MyGetTempPath(UString &path)
-{
- path.Empty();
- if (g_IsNT)
- {
- DWORD needLength = ::GetTempPathW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
- path.ReleaseBuffer();
- return (needLength > 0 && needLength <= MAX_PATH);
- }
- CSysString sysPath;
- if (!MyGetTempPath(sysPath))
+ if (!CreateTempFile(prefix, false, _path, outFile))
return false;
- path = GetUnicodePath(sysPath);
+ _mustBeDeleted = true;
return true;
}
-#endif
-
-UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &path)
-{
- UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH + 1));
- path.ReleaseBuffer();
- return number;
-}
-
-#ifndef _UNICODE
-UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &path)
-{
- if (g_IsNT)
- {
- UINT number = ::GetTempFileNameW(dirPath, prefix, 0, path.GetBuffer(MAX_PATH));
- path.ReleaseBuffer();
- return number;
- }
- CSysString sysPath;
- UINT number = MyGetTempFileName(
- dirPath ? (LPCTSTR)GetSysPath(dirPath): 0,
- prefix ? (LPCTSTR)GetSysPath(prefix): 0,
- sysPath);
- path = GetUnicodePath(sysPath);
- return number;
-}
-#endif
-
-UINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath)
-{
- Remove();
- UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
- if (number != 0)
- {
- _fileName = resultPath;
- _mustBeDeleted = true;
- }
- return number;
-}
-bool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath)
+bool CTempFile::CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFile)
{
- CSysString tempPath;
+ if (!Remove())
+ return false;
+ FString tempPath;
if (!MyGetTempPath(tempPath))
return false;
- if (Create(tempPath, prefix, resultPath) != 0)
- return true;
- #ifdef UNDER_CE
- return false;
- #else
- if (!MyGetWindowsDirectory(tempPath))
+ if (!CreateTempFile(tempPath + namePrefix, true, _path, outFile))
return false;
- return (Create(tempPath, prefix, resultPath) != 0);
- #endif
+ _mustBeDeleted = true;
+ return true;
}
bool CTempFile::Remove()
{
if (!_mustBeDeleted)
return true;
- _mustBeDeleted = !DeleteFileAlways(_fileName);
+ _mustBeDeleted = !DeleteFileAlways(_path);
return !_mustBeDeleted;
}
-#ifndef _UNICODE
-
-UINT CTempFileW::Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath)
+bool CTempFile::MoveTo(CFSTR name, bool deleteDestBefore)
{
- Remove();
- UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
- if (number != 0)
- {
- _fileName = resultPath;
- _mustBeDeleted = true;
- }
- return number;
+ if (deleteDestBefore)
+ if (NFind::DoesFileExist(name))
+ if (!DeleteFileAlways(name))
+ return false;
+ DisableDeleting();
+ return MyMoveFile(_path, name);
}
-bool CTempFileW::Create(LPCWSTR prefix, UString &resultPath)
+bool CTempDir::Create(CFSTR prefix)
{
- UString tempPath;
+ if (!Remove())
+ return false;
+ FString tempPath;
if (!MyGetTempPath(tempPath))
return false;
- if (Create(tempPath, prefix, resultPath) != 0)
- return true;
- if (!MyGetWindowsDirectory(tempPath))
+ if (!CreateTempFile(tempPath + prefix, true, _path, NULL))
return false;
- return (Create(tempPath, prefix, resultPath) != 0);
+ _mustBeDeleted = true;
+ return true;
}
-bool CTempFileW::Remove()
+bool CTempDir::Remove()
{
if (!_mustBeDeleted)
return true;
- _mustBeDeleted = !DeleteFileAlways(_fileName);
+ _mustBeDeleted = !RemoveDirectoryWithSubItems(_path);
return !_mustBeDeleted;
}
-#endif
-
-bool CreateTempDirectory(LPCTSTR prefix, CSysString &dirName)
-{
- /*
- CSysString prefix = tempPath + prefixChars;
- CRandom random;
- random.Init();
- */
- for (;;)
- {
- {
- CTempFile tempFile;
- if (!tempFile.Create(prefix, dirName))
- return false;
- if (!tempFile.Remove())
- return false;
- }
- /*
- UINT32 randomNumber = random.Generate();
- TCHAR randomNumberString[32];
- _stprintf(randomNumberString, _T("%04X"), randomNumber);
- dirName = prefix + randomNumberString;
- */
- if (NFind::DoesFileOrDirExist(dirName))
- continue;
- if (MyCreateDirectory(dirName))
- return true;
- if (::GetLastError() != ERROR_ALREADY_EXISTS)
- return false;
- }
-}
-
-bool CTempDirectory::Create(LPCTSTR prefix)
-{
- Remove();
- return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
-}
-
-#ifndef _UNICODE
-
-bool CreateTempDirectory(LPCWSTR prefix, UString &dirName)
-{
- /*
- CSysString prefix = tempPath + prefixChars;
- CRandom random;
- random.Init();
- */
- for (;;)
- {
- {
- CTempFileW tempFile;
- if (!tempFile.Create(prefix, dirName))
- return false;
- if (!tempFile.Remove())
- return false;
- }
- /*
- UINT32 randomNumber = random.Generate();
- TCHAR randomNumberString[32];
- _stprintf(randomNumberString, _T("%04X"), randomNumber);
- dirName = prefix + randomNumberString;
- */
- if (NFind::DoesFileOrDirExist(dirName))
- continue;
- if (MyCreateDirectory(dirName))
- return true;
- if (::GetLastError() != ERROR_ALREADY_EXISTS)
- return false;
- }
-}
-
-bool CTempDirectoryW::Create(LPCWSTR prefix)
-{
- Remove();
- return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
-}
-
-#endif
-
}}}
diff --git a/CPP/Windows/FileDir.h b/CPP/Windows/FileDir.h
index 04542d87..e43c19bd 100755
--- a/CPP/Windows/FileDir.h
+++ b/CPP/Windows/FileDir.h
@@ -1,176 +1,71 @@
// Windows/FileDir.h
-#ifndef __WINDOWS_FILEDIR_H
-#define __WINDOWS_FILEDIR_H
+#ifndef __WINDOWS_FILE_DIR_H
+#define __WINDOWS_FILE_DIR_H
#include "../Common/MyString.h"
-#include "Defs.h"
+#include "FileIO.h"
namespace NWindows {
namespace NFile {
namespace NDirectory {
#ifdef WIN_LONG_PATH
-bool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2);
+bool GetLongPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2);
#endif
-bool MyGetWindowsDirectory(CSysString &path);
-bool MyGetSystemDirectory(CSysString &path);
-#ifndef _UNICODE
-bool MyGetWindowsDirectory(UString &path);
-bool MyGetSystemDirectory(UString &path);
-#endif
+bool MyGetWindowsDirectory(FString &path);
+bool MyGetSystemDirectory(FString &path);
-bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
+bool SetDirTime(CFSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
+bool MySetFileAttributes(CFSTR fileName, DWORD fileAttributes);
+bool MyMoveFile(CFSTR existFileName, CFSTR newFileName);
+bool MyRemoveDirectory(CFSTR path);
+bool MyCreateDirectory(CFSTR path);
+bool CreateComplexDirectory(CFSTR path);
+bool DeleteFileAlways(CFSTR name);
+bool RemoveDirectoryWithSubItems(const FString &path);
-bool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes);
-bool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName);
-bool MyRemoveDirectory(LPCTSTR pathName);
-bool MyCreateDirectory(LPCTSTR pathName);
-bool CreateComplexDirectory(LPCTSTR pathName);
-bool DeleteFileAlways(LPCTSTR name);
-bool RemoveDirectoryWithSubItems(const CSysString &path);
+bool MyGetFullPathName(CFSTR path, FString &resFullPath);
+bool GetFullPathAndSplit(CFSTR path, FString &resDirPrefix, FString &resFileName);
+bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix);
-#ifndef _UNICODE
-bool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes);
-bool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName);
-bool MyRemoveDirectory(LPCWSTR pathName);
-bool MyCreateDirectory(LPCWSTR pathName);
-bool CreateComplexDirectory(LPCWSTR pathName);
-bool DeleteFileAlways(LPCWSTR name);
-bool RemoveDirectoryWithSubItems(const UString &path);
-#endif
+#ifndef UNDER_CE
-bool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName);
-bool GetOnlyName(LPCTSTR fileName, CSysString &resultName);
-#ifdef UNDER_CE
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath);
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex);
-#else
-bool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath);
+bool MySetCurrentDirectory(CFSTR path);
+bool MyGetCurrentDirectory(FString &resultPath);
-bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex);
-bool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath);
-#ifndef _UNICODE
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath,
- int &fileNamePartStartIndex);
-bool MyGetFullPathName(LPCWSTR fileName, UString &resultPath);
-bool GetOnlyName(LPCWSTR fileName, UString &resultName);
-bool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName);
#endif
-inline bool MySetCurrentDirectory(LPCTSTR path)
- { return BOOLToBool(::SetCurrentDirectory(path)); }
-bool MyGetCurrentDirectory(CSysString &resultPath);
-#ifndef _UNICODE
-bool MySetCurrentDirectory(LPCWSTR path);
-bool MyGetCurrentDirectory(UString &resultPath);
-#endif
-
-bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension, CSysString &resultPath, UINT32 &filePart);
-#ifndef _UNICODE
-bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, UString &resultPath, UINT32 &filePart);
-#endif
-
-inline bool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension, CSysString &resultPath)
-{
- UINT32 value;
- return MySearchPath(path, fileName, extension, resultPath, value);
-}
-
-#ifndef _UNICODE
-inline bool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension, UString &resultPath)
-{
- UINT32 value;
- return MySearchPath(path, fileName, extension, resultPath, value);
-}
-#endif
-
-#endif
-
-bool MyGetTempPath(CSysString &resultPath);
-#ifndef _UNICODE
-bool MyGetTempPath(UString &resultPath);
-#endif
-
-UINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);
-#ifndef _UNICODE
-UINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);
-#endif
+bool MyGetTempPath(FString &resultPath);
class CTempFile
{
bool _mustBeDeleted;
- CSysString _fileName;
+ FString _path;
+ void DisableDeleting() { _mustBeDeleted = false; }
public:
CTempFile(): _mustBeDeleted(false) {}
~CTempFile() { Remove(); }
- void DisableDeleting() { _mustBeDeleted = false; }
- UINT Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath);
- bool Create(LPCTSTR prefix, CSysString &resultPath);
+ const FString &GetPath() const { return _path; }
+ bool Create(CFSTR pathPrefix, NIO::COutFile *outFile); // pathPrefix is not folder prefix
+ bool CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFile);
bool Remove();
+ bool MoveTo(CFSTR name, bool deleteDestBefore);
};
-#ifdef _UNICODE
-typedef CTempFile CTempFileW;
-#else
-class CTempFileW
+class CTempDir
{
bool _mustBeDeleted;
- UString _fileName;
+ FString _path;
public:
- CTempFileW(): _mustBeDeleted(false) {}
- ~CTempFileW() { Remove(); }
+ CTempDir(): _mustBeDeleted(false) {}
+ ~CTempDir() { Remove(); }
+ const FString &GetPath() const { return _path; }
void DisableDeleting() { _mustBeDeleted = false; }
- UINT Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath);
- bool Create(LPCWSTR prefix, UString &resultPath);
+ bool Create(CFSTR namePrefix) ;
bool Remove();
};
-#endif
-
-bool CreateTempDirectory(LPCTSTR prefixChars, CSysString &dirName);
-
-class CTempDirectory
-{
- bool _mustBeDeleted;
- CSysString _tempDir;
-public:
- const CSysString &GetPath() const { return _tempDir; }
- CTempDirectory(): _mustBeDeleted(false) {}
- ~CTempDirectory() { Remove(); }
- bool Create(LPCTSTR prefix) ;
- bool Remove()
- {
- if (!_mustBeDeleted)
- return true;
- _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
- return (!_mustBeDeleted);
- }
- void DisableDeleting() { _mustBeDeleted = false; }
-};
-
-#ifdef _UNICODE
-typedef CTempDirectory CTempDirectoryW;
-#else
-class CTempDirectoryW
-{
- bool _mustBeDeleted;
- UString _tempDir;
-public:
- const UString &GetPath() const { return _tempDir; }
- CTempDirectoryW(): _mustBeDeleted(false) {}
- ~CTempDirectoryW() { Remove(); }
- bool Create(LPCWSTR prefix) ;
- bool Remove()
- {
- if (!_mustBeDeleted)
- return true;
- _mustBeDeleted = !RemoveDirectoryWithSubItems(_tempDir);
- return (!_mustBeDeleted);
- }
- void DisableDeleting() { _mustBeDeleted = false; }
-};
-#endif
}}}
diff --git a/CPP/Windows/FileFind.cpp b/CPP/Windows/FileFind.cpp
index e3358f90..081bd9bc 100755
--- a/CPP/Windows/FileFind.cpp
+++ b/CPP/Windows/FileFind.cpp
@@ -16,41 +16,23 @@ namespace NWindows {
namespace NFile {
#ifdef SUPPORT_DEVICE_FILE
-bool IsDeviceName(LPCTSTR n);
-#ifndef _UNICODE
-bool IsDeviceName(LPCWSTR n);
-#endif
+bool IsDeviceName(CFSTR n);
#endif
-#if defined(WIN_LONG_PATH) && defined(_UNICODE)
-#define WIN_LONG_PATH2
+#if defined(WIN_LONG_PATH)
+bool GetLongPath(CFSTR fileName, UString &res);
#endif
-bool GetLongPath(LPCWSTR fileName, UString &res);
-
namespace NFind {
-static const TCHAR kDot = TEXT('.');
-
bool CFileInfo::IsDots() const
{
if (!IsDir() || Name.IsEmpty())
return false;
- if (Name[0] != kDot)
- return false;
- return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
-}
-
-#ifndef _UNICODE
-bool CFileInfoW::IsDots() const
-{
- if (!IsDir() || Name.IsEmpty())
- return false;
- if (Name[0] != kDot)
+ if (Name[0] != FTEXT('.'))
return false;
- return Name.Length() == 1 || (Name[1] == kDot && Name.Length() == 2);
+ return Name.Length() == 1 || (Name.Length() == 2 && Name[1] == FTEXT('.'));
}
-#endif
#define WIN_FD_TO_MY_FI(fi, fd) \
fi.Attrib = fd.dwFileAttributes; \
@@ -68,26 +50,20 @@ bool CFileInfoW::IsDots() const
#endif
*/
-static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi)
+static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATAW &fd, CFileInfo &fi)
{
WIN_FD_TO_MY_FI(fi, fd);
- fi.Name = fd.cFileName;
+ fi.Name = us2fs(fd.cFileName);
}
#ifndef _UNICODE
static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
-static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATAW &fd, CFileInfoW &fi)
-{
- WIN_FD_TO_MY_FI(fi, fd);
- fi.Name = fd.cFileName;
-}
-
-static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfoW &fi)
+static void ConvertWIN32_FIND_DATA_To_FileInfo(const WIN32_FIND_DATA &fd, CFileInfo &fi)
{
WIN_FD_TO_MY_FI(fi, fd);
- fi.Name = GetUnicodeString(fd.cFileName, GetCurrentCodePage());
+ fi.Name = fas2fs(fd.cFileName);
}
#endif
@@ -104,36 +80,24 @@ bool CFindFile::Close()
return true;
}
-
-bool CFindFile::FindFirst(LPCTSTR wildcard, CFileInfo &fi)
+bool CFindFile::FindFirst(CFSTR wildcard, CFileInfo &fi)
{
if (!Close())
return false;
- WIN32_FIND_DATA fd;
- _handle = ::FindFirstFile(wildcard, &fd);
- #ifdef WIN_LONG_PATH2
- if (_handle == INVALID_HANDLE_VALUE)
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- UString longPath;
- if (GetLongPath(wildcard, longPath))
- _handle = ::FindFirstFileW(longPath, &fd);
+ WIN32_FIND_DATAA fd;
+ _handle = ::FindFirstFileA(fs2fas(wildcard), &fd);
+ if (_handle == INVALID_HANDLE_VALUE)
+ return false;
+ ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
}
+ else
#endif
- if (_handle == INVALID_HANDLE_VALUE)
- return false;
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
- return true;
-}
-
-#ifndef _UNICODE
-bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fi)
-{
- if (!Close())
- return false;
- if (g_IsNT)
{
WIN32_FIND_DATAW fd;
- _handle = ::FindFirstFileW(wildcard, &fd);
+ _handle = ::FindFirstFileW(fs2us(wildcard), &fd);
#ifdef WIN_LONG_PATH
if (_handle == INVALID_HANDLE_VALUE)
{
@@ -142,50 +106,33 @@ bool CFindFile::FindFirst(LPCWSTR wildcard, CFileInfoW &fi)
_handle = ::FindFirstFileW(longPath, &fd);
}
#endif
- if (_handle != INVALID_HANDLE_VALUE)
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
- }
- else
- {
- WIN32_FIND_DATAA fd;
- _handle = ::FindFirstFileA(UnicodeStringToMultiByte(wildcard,
- GetCurrentCodePage()), &fd);
- if (_handle != INVALID_HANDLE_VALUE)
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
+ if (_handle == INVALID_HANDLE_VALUE)
+ return false;
+ ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
}
- return (_handle != INVALID_HANDLE_VALUE);
+ return true;
}
-#endif
bool CFindFile::FindNext(CFileInfo &fi)
{
- WIN32_FIND_DATA fd;
- bool result = BOOLToBool(::FindNextFile(_handle, &fd));
- if (result)
- ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
- return result;
-}
-
-#ifndef _UNICODE
-bool CFindFile::FindNext(CFileInfoW &fi)
-{
- if (g_IsNT)
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- WIN32_FIND_DATAW fd;
- if (!::FindNextFileW(_handle, &fd))
+ WIN32_FIND_DATAA fd;
+ if (!::FindNextFileA(_handle, &fd))
return false;
ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
}
else
+ #endif
{
- WIN32_FIND_DATAA fd;
- if (!::FindNextFileA(_handle, &fd))
+ WIN32_FIND_DATAW fd;
+ if (!::FindNextFileW(_handle, &fd))
return false;
ConvertWIN32_FIND_DATA_To_FileInfo(fd, fi);
}
return true;
}
-#endif
#define MY_CLEAR_FILETIME(ft) ft.dwLowDateTime = ft.dwHighDateTime = 0;
@@ -198,7 +145,7 @@ void CFileInfoBase::Clear()
Attrib = 0;
}
-bool CFileInfo::Find(LPCTSTR wildcard)
+bool CFileInfo::Find(CFSTR wildcard)
{
#ifdef SUPPORT_DEVICE_FILE
if (IsDeviceName(wildcard))
@@ -215,72 +162,66 @@ bool CFileInfo::Find(LPCTSTR wildcard)
}
#endif
CFindFile finder;
- return finder.FindFirst(wildcard, *this);
-}
-
-
-#ifndef _UNICODE
-bool CFileInfoW::Find(LPCWSTR wildcard)
-{
- #ifdef SUPPORT_DEVICE_FILE
- if (IsDeviceName(wildcard))
- {
- Clear();
- IsDevice = true;
- NIO::CInFile inFile;
- if (!inFile.Open(wildcard))
- return false;
- Name = wildcard + 4;
- if (inFile.LengthDefined)
- Size = inFile.Length;
+ if (finder.FindFirst(wildcard, *this))
return true;
+ #ifdef _WIN32
+ {
+ DWORD lastError = GetLastError();
+ if (lastError == ERROR_BAD_NETPATH || lastError == ERROR_FILE_NOT_FOUND)
+ {
+ int len = MyStringLen(wildcard);
+ if (len > 2 && wildcard[0] == '\\' && wildcard[1] == '\\')
+ {
+ int pos = FindCharPosInString(wildcard + 2, FTEXT('\\'));
+ if (pos >= 0)
+ {
+ pos += 2 + 1;
+ len -= pos;
+ CFSTR remString = wildcard + pos;
+ int pos2 = FindCharPosInString(remString, FTEXT('\\'));
+ FString s = wildcard;
+ if (pos2 < 0 || pos2 == len - 1)
+ {
+ FString s = wildcard;
+ if (pos2 < 0)
+ {
+ pos2 = len;
+ s += FTEXT('\\');
+ }
+ s += FCHAR_ANY_MASK;
+ if (finder.FindFirst(s, *this))
+ if (Name == FTEXT("."))
+ {
+ Name = s.Mid(pos, pos2);
+ return true;
+ }
+ ::SetLastError(lastError);
+ }
+ }
+ }
+ }
}
#endif
- CFindFile finder;
- return finder.FindFirst(wildcard, *this);
+ return false;
}
-#endif
-bool DoesFileExist(LPCTSTR name)
+bool DoesFileExist(CFSTR name)
{
CFileInfo fi;
return fi.Find(name) && !fi.IsDir();
}
-bool DoesDirExist(LPCTSTR name)
+bool DoesDirExist(CFSTR name)
{
CFileInfo fi;
return fi.Find(name) && fi.IsDir();
}
-
-bool DoesFileOrDirExist(LPCTSTR name)
+bool DoesFileOrDirExist(CFSTR name)
{
CFileInfo fi;
return fi.Find(name);
}
-#ifndef _UNICODE
-bool DoesFileExist(LPCWSTR name)
-{
- CFileInfoW fi;
- return fi.Find(name) && !fi.IsDir();
-}
-
-bool DoesDirExist(LPCWSTR name)
-{
- CFileInfoW fi;
- return fi.Find(name) && fi.IsDir();
-}
-bool DoesFileOrDirExist(LPCWSTR name)
-{
- CFileInfoW fi;
- return fi.Find(name);
-}
-#endif
-
-/////////////////////////////////////
-// CEnumerator
-
bool CEnumerator::NextAny(CFileInfo &fi)
{
if (_findFile.IsHandleAllocated())
@@ -311,39 +252,6 @@ bool CEnumerator::Next(CFileInfo &fi, bool &found)
return (::GetLastError() == ERROR_NO_MORE_FILES);
}
-#ifndef _UNICODE
-bool CEnumeratorW::NextAny(CFileInfoW &fi)
-{
- if (_findFile.IsHandleAllocated())
- return _findFile.FindNext(fi);
- else
- return _findFile.FindFirst(_wildcard, fi);
-}
-
-bool CEnumeratorW::Next(CFileInfoW &fi)
-{
- for (;;)
- {
- if (!NextAny(fi))
- return false;
- if (!fi.IsDots())
- return true;
- }
-}
-
-bool CEnumeratorW::Next(CFileInfoW &fi, bool &found)
-{
- if (Next(fi))
- {
- found = true;
- return true;
- }
- found = false;
- return (::GetLastError() == ERROR_NO_MORE_FILES);
-}
-
-#endif
-
////////////////////////////////
// CFindChangeNotification
// FindFirstChangeNotification can return 0. MSDN doesn't tell about it.
@@ -358,104 +266,82 @@ bool CFindChangeNotification::Close()
return true;
}
-HANDLE CFindChangeNotification::FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter)
-{
- _handle = ::FindFirstChangeNotification(pathName, BoolToBOOL(watchSubtree), notifyFilter);
- #ifdef WIN_LONG_PATH2
- if (!IsHandleAllocated())
- {
- UString longPath;
- if (GetLongPath(pathName, longPath))
- _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
- }
- #endif
- return _handle;
-}
-
-#ifndef _UNICODE
-HANDLE CFindChangeNotification::FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter)
+HANDLE CFindChangeNotification::FindFirst(CFSTR pathName, bool watchSubtree, DWORD notifyFilter)
{
+ #ifndef _UNICODE
if (!g_IsNT)
- return FindFirst(UnicodeStringToMultiByte(pathName, GetCurrentCodePage()), watchSubtree, notifyFilter);
- _handle = ::FindFirstChangeNotificationW(pathName, BoolToBOOL(watchSubtree), notifyFilter);
- #ifdef WIN_LONG_PATH
- if (!IsHandleAllocated())
+ _handle = ::FindFirstChangeNotification(fs2fas(pathName), BoolToBOOL(watchSubtree), notifyFilter);
+ else
+ #endif
{
- UString longPath;
- if (GetLongPath(pathName, longPath))
- _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
+ _handle = ::FindFirstChangeNotificationW(fs2us(pathName), BoolToBOOL(watchSubtree), notifyFilter);
+ #ifdef WIN_LONG_PATH
+ if (!IsHandleAllocated())
+ {
+ UString longPath;
+ if (GetLongPath(pathName, longPath))
+ _handle = ::FindFirstChangeNotificationW(longPath, BoolToBOOL(watchSubtree), notifyFilter);
+ }
+ #endif
}
- #endif
return _handle;
}
-#endif
#ifndef UNDER_CE
-bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings)
+
+bool MyGetLogicalDriveStrings(CObjectVector<FString> &driveStrings)
{
driveStrings.Clear();
- UINT32 size = GetLogicalDriveStrings(0, NULL);
- if (size == 0)
- return false;
- CSysString buffer;
- UINT32 newSize = GetLogicalDriveStrings(size, buffer.GetBuffer(size));
- if (newSize == 0)
- return false;
- if (newSize > size)
- return false;
- CSysString string;
- for (UINT32 i = 0; i < newSize; i++)
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- TCHAR c = buffer[i];
- if (c == TEXT('\0'))
+ driveStrings.Clear();
+ UINT32 size = GetLogicalDriveStrings(0, NULL);
+ if (size == 0)
+ return false;
+ AString buf;
+ UINT32 newSize = GetLogicalDriveStrings(size, buf.GetBuffer(size));
+ if (newSize == 0 || newSize > size)
+ return false;
+ AString s;
+ for (UINT32 i = 0; i < newSize; i++)
{
- driveStrings.Add(string);
- string.Empty();
+ char c = buf[i];
+ if (c == '\0')
+ {
+ driveStrings.Add(fas2fs(s));
+ s.Empty();
+ }
+ else
+ s += c;
}
- else
- string += c;
+ return s.IsEmpty();
}
- if (!string.IsEmpty())
- return false;
- return true;
-}
-
-#ifndef _UNICODE
-bool MyGetLogicalDriveStrings(UStringVector &driveStrings)
-{
- driveStrings.Clear();
- if (g_IsNT)
+ else
+ #endif
{
UINT32 size = GetLogicalDriveStringsW(0, NULL);
if (size == 0)
return false;
- UString buffer;
- UINT32 newSize = GetLogicalDriveStringsW(size, buffer.GetBuffer(size));
- if (newSize == 0)
+ UString buf;
+ UINT32 newSize = GetLogicalDriveStringsW(size, buf.GetBuffer(size));
+ if (newSize == 0 || newSize > size)
return false;
- if (newSize > size)
- return false;
- UString string;
+ UString s;
for (UINT32 i = 0; i < newSize; i++)
{
- WCHAR c = buffer[i];
+ WCHAR c = buf[i];
if (c == L'\0')
{
- driveStrings.Add(string);
- string.Empty();
+ driveStrings.Add(us2fs(s));
+ s.Empty();
}
else
- string += c;
+ s += c;
}
- return string.IsEmpty();
+ return s.IsEmpty();
}
- CSysStringVector driveStringsA;
- bool res = MyGetLogicalDriveStrings(driveStringsA);
- for (int i = 0; i < driveStringsA.Size(); i++)
- driveStrings.Add(GetUnicodeString(driveStringsA[i]));
- return res;
}
-#endif
#endif
diff --git a/CPP/Windows/FileFind.h b/CPP/Windows/FileFind.h
index 63631f66..97a3b7c2 100755
--- a/CPP/Windows/FileFind.h
+++ b/CPP/Windows/FileFind.h
@@ -1,12 +1,11 @@
// Windows/FileFind.h
-#ifndef __WINDOWS_FILEFIND_H
-#define __WINDOWS_FILEFIND_H
+#ifndef __WINDOWS_FILE_FIND_H
+#define __WINDOWS_FILE_FIND_H
#include "../Common/MyString.h"
#include "../Common/Types.h"
#include "Defs.h"
-#include "FileName.h"
namespace NWindows {
namespace NFile {
@@ -60,24 +59,12 @@ public:
struct CFileInfo: public CFileInfoBase
{
- CSysString Name;
+ FString Name;
bool IsDots() const;
- bool Find(LPCTSTR wildcard);
+ bool Find(CFSTR wildcard);
};
-#ifdef _UNICODE
-typedef CFileInfo CFileInfoW;
-#else
-struct CFileInfoW: public CFileInfoBase
-{
- UString Name;
-
- bool IsDots() const;
- bool Find(LPCWSTR wildcard);
-};
-#endif
-
class CFindFile
{
friend class CEnumerator;
@@ -85,53 +72,28 @@ class CFindFile
public:
bool IsHandleAllocated() const { return _handle != INVALID_HANDLE_VALUE; }
CFindFile(): _handle(INVALID_HANDLE_VALUE) {}
- ~CFindFile() { Close(); }
- bool FindFirst(LPCTSTR wildcard, CFileInfo &fileInfo);
+ ~CFindFile() { Close(); }
+ bool FindFirst(CFSTR wildcard, CFileInfo &fileInfo);
bool FindNext(CFileInfo &fileInfo);
- #ifndef _UNICODE
- bool FindFirst(LPCWSTR wildcard, CFileInfoW &fileInfo);
- bool FindNext(CFileInfoW &fileInfo);
- #endif
bool Close();
};
-bool DoesFileExist(LPCTSTR name);
-bool DoesDirExist(LPCTSTR name);
-bool DoesFileOrDirExist(LPCTSTR name);
-#ifndef _UNICODE
-bool DoesFileExist(LPCWSTR name);
-bool DoesDirExist(LPCWSTR name);
-bool DoesFileOrDirExist(LPCWSTR name);
-#endif
+bool DoesFileExist(CFSTR name);
+bool DoesDirExist(CFSTR name);
+bool DoesFileOrDirExist(CFSTR name);
class CEnumerator
{
CFindFile _findFile;
- CSysString _wildcard;
+ FString _wildcard;
+
bool NextAny(CFileInfo &fileInfo);
public:
- CEnumerator(): _wildcard(NName::kAnyStringWildcard) {}
- CEnumerator(const CSysString &wildcard): _wildcard(wildcard) {}
+ CEnumerator(const FString &wildcard): _wildcard(wildcard) {}
bool Next(CFileInfo &fileInfo);
bool Next(CFileInfo &fileInfo, bool &found);
};
-#ifdef _UNICODE
-typedef CEnumerator CEnumeratorW;
-#else
-class CEnumeratorW
-{
- CFindFile _findFile;
- UString _wildcard;
- bool NextAny(CFileInfoW &fileInfo);
-public:
- CEnumeratorW(): _wildcard(NName::kAnyStringWildcard) {}
- CEnumeratorW(const UString &wildcard): _wildcard(wildcard) {}
- bool Next(CFileInfoW &fileInfo);
- bool Next(CFileInfoW &fileInfo, bool &found);
-};
-#endif
-
class CFindChangeNotification
{
HANDLE _handle;
@@ -141,21 +103,14 @@ public:
CFindChangeNotification(): _handle(INVALID_HANDLE_VALUE) {}
~CFindChangeNotification() { Close(); }
bool Close();
- HANDLE FindFirst(LPCTSTR pathName, bool watchSubtree, DWORD notifyFilter);
- #ifndef _UNICODE
- HANDLE FindFirst(LPCWSTR pathName, bool watchSubtree, DWORD notifyFilter);
- #endif
+ HANDLE FindFirst(CFSTR pathName, bool watchSubtree, DWORD notifyFilter);
bool FindNext() { return BOOLToBool(::FindNextChangeNotification(_handle)); }
};
#ifndef UNDER_CE
-bool MyGetLogicalDriveStrings(CSysStringVector &driveStrings);
-#ifndef _UNICODE
-bool MyGetLogicalDriveStrings(UStringVector &driveStrings);
-#endif
+bool MyGetLogicalDriveStrings(CObjectVector<FString> &driveStrings);
#endif
}}}
#endif
-
diff --git a/CPP/Windows/FileIO.cpp b/CPP/Windows/FileIO.cpp
index 938e6c70..e8f98747 100755
--- a/CPP/Windows/FileIO.cpp
+++ b/CPP/Windows/FileIO.cpp
@@ -4,13 +4,6 @@
#include "FileIO.h"
-#if defined(WIN_LONG_PATH) || defined(SUPPORT_DEVICE_FILE)
-#include "../Common/MyString.h"
-#endif
-#ifndef _UNICODE
-#include "../Common/StringConvert.h"
-#endif
-
#ifndef _UNICODE
extern bool g_IsNT;
#endif
@@ -19,11 +12,12 @@ namespace NWindows {
namespace NFile {
#ifdef SUPPORT_DEVICE_FILE
-bool IsDeviceName(LPCTSTR n)
+
+bool IsDeviceName(CFSTR n)
{
#ifdef UNDER_CE
int len = (int)MyStringLen(n);
- if (len < 5 || len > 5 || memcmp(n, TEXT("DSK"), 3 * sizeof(TCHAR)) != 0)
+ if (len < 5 || len > 5 || memcmp(n, FTEXT("DSK"), 3 * sizeof(FCHAR)) != 0)
return false;
if (n[4] != ':')
return false;
@@ -34,7 +28,7 @@ bool IsDeviceName(LPCTSTR n)
int len = (int)MyStringLen(n);
if (len == 6 && n[5] == ':')
return true;
- if (len < 18 || len > 22 || memcmp(n + 4, TEXT("PhysicalDrive"), 13 * sizeof(TCHAR)) != 0)
+ if (len < 18 || len > 22 || memcmp(n + 4, FTEXT("PhysicalDrive"), 13 * sizeof(FCHAR)) != 0)
return false;
for (int i = 17; i < len; i++)
if (n[i] < '0' || n[i] > '9')
@@ -43,22 +37,6 @@ bool IsDeviceName(LPCTSTR n)
return true;
}
-#ifndef _UNICODE
-bool IsDeviceName(LPCWSTR n)
-{
- if (n[0] != '\\' || n[1] != '\\' || n[2] != '.' || n[3] != '\\')
- return false;
- int len = (int)wcslen(n);
- if (len == 6 && n[5] == ':')
- return true;
- if (len < 18 || len > 22 || wcsncmp(n + 4, L"PhysicalDrive", 13) != 0)
- return false;
- for (int i = 17; i < len; i++)
- if (n[i] < '0' || n[i] > '9')
- return false;
- return true;
-}
-#endif
#endif
#if defined(WIN_LONG_PATH) && defined(_UNICODE)
@@ -66,32 +44,34 @@ bool IsDeviceName(LPCWSTR n)
#endif
#ifdef WIN_LONG_PATH
-bool GetLongPathBase(LPCWSTR s, UString &res)
+bool GetLongPathBase(CFSTR s, UString &res)
{
res.Empty();
int len = MyStringLen(s);
- wchar_t c = s[0];
- if (len < 1 || c == L'\\' || c == L'.' && (len == 1 || len == 2 && s[1] == L'.'))
+ FChar c = s[0];
+ if (len < 1 || c == '\\' || c == '.' && (len == 1 || len == 2 && s[1] == '.'))
return true;
UString curDir;
bool isAbs = false;
if (len > 3)
- isAbs = (s[1] == L':' && s[2] == L'\\' && (c >= L'a' && c <= L'z' || c >= L'A' && c <= L'Z'));
+ isAbs = (s[1] == ':' && s[2] == '\\' && (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'));
if (!isAbs)
- {
- DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, curDir.GetBuffer(MAX_PATH + 1));
- curDir.ReleaseBuffer();
- if (needLength == 0 || needLength > MAX_PATH)
- return false;
- if (curDir[curDir.Length() - 1] != L'\\')
- curDir += L'\\';
- }
- res = UString(L"\\\\?\\") + curDir + s;
+ {
+ WCHAR temp[MAX_PATH + 2];
+ temp[0] = 0;
+ DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, temp);
+ if (needLength == 0 || needLength > MAX_PATH)
+ return false;
+ curDir = temp;
+ if (curDir.Back() != L'\\')
+ curDir += L'\\';
+ }
+ res = UString(L"\\\\?\\") + curDir + fs2us(s);
return true;
}
-bool GetLongPath(LPCWSTR path, UString &longPath)
+bool GetLongPath(CFSTR path, UString &longPath)
{
if (GetLongPathBase(path, longPath))
return !longPath.IsEmpty();
@@ -103,58 +83,39 @@ namespace NIO {
CFileBase::~CFileBase() { Close(); }
-bool CFileBase::Create(LPCTSTR fileName, DWORD desiredAccess,
+bool CFileBase::Create(CFSTR fileName, DWORD desiredAccess,
DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
{
if (!Close())
return false;
- _handle = ::CreateFile(fileName, desiredAccess, shareMode,
- (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
- flagsAndAttributes, (HANDLE)NULL);
- #ifdef WIN_LONG_PATH2
- if (_handle == INVALID_HANDLE_VALUE)
- {
- UString longPath;
- if (GetLongPath(fileName, longPath))
- _handle = ::CreateFileW(longPath, desiredAccess, shareMode,
- (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
- flagsAndAttributes, (HANDLE)NULL);
- }
- #endif
+
#ifdef SUPPORT_DEVICE_FILE
IsDeviceFile = false;
#endif
- return (_handle != INVALID_HANDLE_VALUE);
-}
-#ifndef _UNICODE
-bool CFileBase::Create(LPCWSTR fileName, DWORD desiredAccess,
- DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
-{
+ #ifndef _UNICODE
if (!g_IsNT)
- return Create(UnicodeStringToMultiByte(fileName, ::AreFileApisANSI() ? CP_ACP : CP_OEMCP),
- desiredAccess, shareMode, creationDisposition, flagsAndAttributes);
- if (!Close())
- return false;
- _handle = ::CreateFileW(fileName, desiredAccess, shareMode,
- (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
- flagsAndAttributes, (HANDLE)NULL);
- #ifdef WIN_LONG_PATH
- if (_handle == INVALID_HANDLE_VALUE)
{
- UString longPath;
- if (GetLongPath(fileName, longPath))
- _handle = ::CreateFileW(longPath, desiredAccess, shareMode,
- (LPSECURITY_ATTRIBUTES)NULL, creationDisposition,
- flagsAndAttributes, (HANDLE)NULL);
+ _handle = ::CreateFile(fs2fas(fileName), desiredAccess, shareMode,
+ (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL);
}
+ else
#endif
- #ifdef SUPPORT_DEVICE_FILE
- IsDeviceFile = false;
- #endif
+ {
+ _handle = ::CreateFileW(fs2us(fileName), desiredAccess, shareMode,
+ (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL);
+ #ifdef WIN_LONG_PATH
+ if (_handle == INVALID_HANDLE_VALUE)
+ {
+ UString longPath;
+ if (GetLongPath(fileName, longPath))
+ _handle = ::CreateFileW(longPath, desiredAccess, shareMode,
+ (LPSECURITY_ATTRIBUTES)NULL, creationDisposition, flagsAndAttributes, (HANDLE)NULL);
+ }
+ #endif
+ }
return (_handle != INVALID_HANDLE_VALUE);
}
-#endif
bool CFileBase::Close()
{
@@ -226,21 +187,23 @@ bool CFileBase::SeekToEnd(UInt64 &newPosition)
return Seek(0, FILE_END, newPosition);
}
-bool CFileBase::GetFileInformation(CByHandleFileInfo &fileInfo) const
+/*
+bool CFileBase::GetFileInformation(CByHandleFileInfo &fi) const
{
- BY_HANDLE_FILE_INFORMATION winFileInfo;
- if (!::GetFileInformationByHandle(_handle, &winFileInfo))
+ BY_HANDLE_FILE_INFORMATION wfi;
+ if (!::GetFileInformationByHandle(_handle, &wfi))
return false;
- fileInfo.Attrib = winFileInfo.dwFileAttributes;
- fileInfo.CTime = winFileInfo.ftCreationTime;
- fileInfo.ATime = winFileInfo.ftLastAccessTime;
- fileInfo.MTime = winFileInfo.ftLastWriteTime;
- fileInfo.VolumeSerialNumber = winFileInfo.dwFileAttributes;
- fileInfo.Size = (((UInt64)winFileInfo.nFileSizeHigh) << 32) + winFileInfo.nFileSizeLow;
- fileInfo.NumberOfLinks = winFileInfo.nNumberOfLinks;
- fileInfo.FileIndex = (((UInt64)winFileInfo.nFileIndexHigh) << 32) + winFileInfo.nFileIndexLow;
+ fi.Attrib = wfi.dwFileAttributes;
+ fi.CTime = wfi.ftCreationTime;
+ fi.ATime = wfi.ftLastAccessTime;
+ fi.MTime = wfi.ftLastWriteTime;
+ fi.Size = (((UInt64)wfi.nFileSizeHigh) << 32) + wfi.nFileSizeLow;
+ fi.VolumeSerialNumber = wfi.dwVolumeSerialNumber;
+ fi.NumLinks = wfi.nNumberOfLinks;
+ fi.FileIndex = (((UInt64)wfi.nFileIndexHigh) << 32) + wfi.nFileIndexLow;
return true;
}
+*/
/////////////////////////
// CInFile
@@ -284,34 +247,19 @@ void CInFile::GetDeviceLength()
#define MY_DEVICE_EXTRA_CODE
#endif
-bool CInFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+bool CInFile::Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
{
bool res = Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes);
MY_DEVICE_EXTRA_CODE
return res;
}
-bool CInFile::OpenShared(LPCTSTR fileName, bool shareForWrite)
+bool CInFile::OpenShared(CFSTR fileName, bool shareForWrite)
{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
-bool CInFile::Open(LPCTSTR fileName)
+bool CInFile::Open(CFSTR fileName)
{ return OpenShared(fileName, false); }
-#ifndef _UNICODE
-bool CInFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
-{
- bool res = Create(fileName, GENERIC_READ, shareMode, creationDisposition, flagsAndAttributes);
- MY_DEVICE_EXTRA_CODE
- return res;
-}
-
-bool CInFile::OpenShared(LPCWSTR fileName, bool shareForWrite)
-{ return Open(fileName, FILE_SHARE_READ | (shareForWrite ? FILE_SHARE_WRITE : 0), OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL); }
-
-bool CInFile::Open(LPCWSTR fileName)
- { return OpenShared(fileName, false); }
-#endif
-
// ReadFile and WriteFile functions in Windows have BUG:
// If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1)
// from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES
@@ -360,31 +308,18 @@ bool CInFile::Read(void *data, UInt32 size, UInt32 &processedSize)
/////////////////////////
// COutFile
-bool COutFile::Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
- { return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
-
static inline DWORD GetCreationDisposition(bool createAlways)
{ return createAlways? CREATE_ALWAYS: CREATE_NEW; }
-bool COutFile::Open(LPCTSTR fileName, DWORD creationDisposition)
- { return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
-
-bool COutFile::Create(LPCTSTR fileName, bool createAlways)
- { return Open(fileName, GetCreationDisposition(createAlways)); }
-
-#ifndef _UNICODE
-
-bool COutFile::Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
+bool COutFile::Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes)
{ return CFileBase::Create(fileName, GENERIC_WRITE, shareMode, creationDisposition, flagsAndAttributes); }
-bool COutFile::Open(LPCWSTR fileName, DWORD creationDisposition)
+bool COutFile::Open(CFSTR fileName, DWORD creationDisposition)
{ return Open(fileName, FILE_SHARE_READ, creationDisposition, FILE_ATTRIBUTE_NORMAL); }
-bool COutFile::Create(LPCWSTR fileName, bool createAlways)
+bool COutFile::Create(CFSTR fileName, bool createAlways)
{ return Open(fileName, GetCreationDisposition(createAlways)); }
-#endif
-
bool COutFile::SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
{ return BOOLToBool(::SetFileTime(_handle, cTime, aTime, mTime)); }
diff --git a/CPP/Windows/FileIO.h b/CPP/Windows/FileIO.h
index dce692fe..ecd7af96 100755
--- a/CPP/Windows/FileIO.h
+++ b/CPP/Windows/FileIO.h
@@ -1,9 +1,10 @@
// Windows/FileIO.h
-#ifndef __WINDOWS_FILEIO_H
-#define __WINDOWS_FILEIO_H
+#ifndef __WINDOWS_FILE_IO_H
+#define __WINDOWS_FILE_IO_H
#include "../Common/Types.h"
+#include "../Common/MyString.h"
#include "Defs.h"
@@ -11,29 +12,27 @@ namespace NWindows {
namespace NFile {
namespace NIO {
+/*
struct CByHandleFileInfo
{
- DWORD Attrib;
+ UInt64 Size;
FILETIME CTime;
FILETIME ATime;
FILETIME MTime;
+ DWORD Attrib;
DWORD VolumeSerialNumber;
- UInt64 Size;
- DWORD NumberOfLinks;
+ DWORD NumLinks;
UInt64 FileIndex;
};
+*/
class CFileBase
{
protected:
HANDLE _handle;
- bool Create(LPCTSTR fileName, DWORD desiredAccess,
- DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- #ifndef _UNICODE
- bool Create(LPCWSTR fileName, DWORD desiredAccess,
+ bool Create(CFSTR fileName, DWORD desiredAccess,
DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- #endif
public:
#ifdef SUPPORT_DEVICE_FILE
@@ -55,7 +54,7 @@ public:
bool SeekToBegin();
bool SeekToEnd(UInt64 &newPosition);
- bool GetFileInformation(CByHandleFileInfo &fileInfo) const;
+ // bool GetFileInformation(CByHandleFileInfo &fileInfo) const;
};
#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM
@@ -97,14 +96,10 @@ class CInFile: public CFileBase
#endif
public:
- bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- bool OpenShared(LPCTSTR fileName, bool shareForWrite);
- bool Open(LPCTSTR fileName);
- #ifndef _UNICODE
- bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- bool OpenShared(LPCWSTR fileName, bool shareForWrite);
- bool Open(LPCWSTR fileName);
- #endif
+ bool Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool OpenShared(CFSTR fileName, bool shareForWrite);
+ bool Open(CFSTR fileName);
+
bool Read1(void *data, UInt32 size, UInt32 &processedSize);
bool ReadPart(void *data, UInt32 size, UInt32 &processedSize);
bool Read(void *data, UInt32 size, UInt32 &processedSize);
@@ -113,15 +108,9 @@ public:
class COutFile: public CFileBase
{
public:
- bool Open(LPCTSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- bool Open(LPCTSTR fileName, DWORD creationDisposition);
- bool Create(LPCTSTR fileName, bool createAlways);
-
- #ifndef _UNICODE
- bool Open(LPCWSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
- bool Open(LPCWSTR fileName, DWORD creationDisposition);
- bool Create(LPCWSTR fileName, bool createAlways);
- #endif
+ bool Open(CFSTR fileName, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes);
+ bool Open(CFSTR fileName, DWORD creationDisposition);
+ bool Create(CFSTR fileName, bool createAlways);
bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime);
bool SetMTime(const FILETIME *mTime);
diff --git a/CPP/Windows/FileName.cpp b/CPP/Windows/FileName.cpp
index 8443a4af..8f464aa8 100755
--- a/CPP/Windows/FileName.cpp
+++ b/CPP/Windows/FileName.cpp
@@ -2,49 +2,28 @@
#include "StdAfx.h"
-#include "Windows/FileName.h"
-#include "Common/Wildcard.h"
+#include "FileName.h"
namespace NWindows {
namespace NFile {
namespace NName {
-void NormalizeDirPathPrefix(CSysString &dirPath)
+void NormalizeDirPathPrefix(FString &dirPath)
{
if (dirPath.IsEmpty())
return;
- if (dirPath.ReverseFind(kDirDelimiter) != dirPath.Length() - 1)
- dirPath += kDirDelimiter;
+ if (dirPath.ReverseFind(FCHAR_PATH_SEPARATOR) != dirPath.Length() - 1)
+ dirPath += FCHAR_PATH_SEPARATOR;
}
-#ifndef _UNICODE
+#ifndef USE_UNICODE_FSTRING
void NormalizeDirPathPrefix(UString &dirPath)
{
if (dirPath.IsEmpty())
return;
- if (dirPath.ReverseFind(wchar_t(kDirDelimiter)) != dirPath.Length() - 1)
- dirPath += wchar_t(kDirDelimiter);
+ if (dirPath.ReverseFind(WCHAR_PATH_SEPARATOR) != dirPath.Length() - 1)
+ dirPath += WCHAR_PATH_SEPARATOR;
}
#endif
-const wchar_t kExtensionDelimiter = L'.';
-
-void SplitNameToPureNameAndExtension(const UString &fullName,
- UString &pureName, UString &extensionDelimiter, UString &extension)
-{
- int index = fullName.ReverseFind(kExtensionDelimiter);
- if (index < 0)
- {
- pureName = fullName;
- extensionDelimiter.Empty();
- extension.Empty();
- }
- else
- {
- pureName = fullName.Left(index);
- extensionDelimiter = kExtensionDelimiter;
- extension = fullName.Mid(index + 1);
- }
-}
-
}}}
diff --git a/CPP/Windows/FileName.h b/CPP/Windows/FileName.h
index d9807902..9ee57f9d 100755
--- a/CPP/Windows/FileName.h
+++ b/CPP/Windows/FileName.h
@@ -1,9 +1,7 @@
// Windows/FileName.h
-#ifndef __WINDOWS_FILENAME_H
-#define __WINDOWS_FILENAME_H
-
-#include "../../C/Types.h"
+#ifndef __WINDOWS_FILE_NAME_H
+#define __WINDOWS_FILE_NAME_H
#include "../Common/MyString.h"
@@ -11,16 +9,8 @@ namespace NWindows {
namespace NFile {
namespace NName {
-const TCHAR kDirDelimiter = CHAR_PATH_SEPARATOR;
-const TCHAR kAnyStringWildcard = '*';
-
-void NormalizeDirPathPrefix(CSysString &dirPath); // ensures that it ended with '\\'
-#ifndef _UNICODE
-void NormalizeDirPathPrefix(UString &dirPath); // ensures that it ended with '\\'
-#endif
-
-void SplitNameToPureNameAndExtension(const UString &fullName,
- UString &pureName, UString &extensionDelimiter, UString &extension);
+void NormalizeDirPathPrefix(FString &dirPath); // ensures that it ended with '\\', if dirPath is not epmty
+void NormalizeDirPathPrefix(UString &dirPath);
}}}
diff --git a/CPP/Windows/FileSystem.cpp b/CPP/Windows/FileSystem.cpp
index 3ebfb752..8bf595b2 100755
--- a/CPP/Windows/FileSystem.cpp
+++ b/CPP/Windows/FileSystem.cpp
@@ -2,6 +2,10 @@
#include "StdAfx.h"
+#ifndef _UNICODE
+#include "Common/StringConvert.h"
+#endif
+
#include "FileSystem.h"
#include "Defs.h"
@@ -14,113 +18,94 @@ namespace NFile {
namespace NSystem {
bool MyGetVolumeInformation(
- LPCTSTR rootPathName,
- CSysString &volumeName,
+ CFSTR rootPath,
+ UString &volumeName,
LPDWORD volumeSerialNumber,
LPDWORD maximumComponentLength,
LPDWORD fileSystemFlags,
- CSysString &fileSystemName)
+ UString &fileSystemName)
{
- bool result = BOOLToBool(GetVolumeInformation(
- rootPathName,
- volumeName.GetBuffer(MAX_PATH), MAX_PATH,
- volumeSerialNumber,
- maximumComponentLength,
- fileSystemFlags,
- fileSystemName.GetBuffer(MAX_PATH), MAX_PATH));
- volumeName.ReleaseBuffer();
- fileSystemName.ReleaseBuffer();
- return result;
+ BOOL res;
+ #ifndef _UNICODE
+ if (!g_IsNT)
+ {
+ TCHAR v[MAX_PATH + 2]; v[0] = 0;
+ TCHAR f[MAX_PATH + 2]; f[0] = 0;
+ res = GetVolumeInformation(fs2fas(rootPath),
+ v, MAX_PATH,
+ volumeSerialNumber, maximumComponentLength, fileSystemFlags,
+ f, MAX_PATH);
+ volumeName = MultiByteToUnicodeString(v);
+ fileSystemName = MultiByteToUnicodeString(f);
+ }
+ else
+ #endif
+ {
+ WCHAR v[MAX_PATH + 2]; v[0] = 0;
+ WCHAR f[MAX_PATH + 2]; f[0] = 0;
+ res = GetVolumeInformationW(fs2us(rootPath),
+ v, MAX_PATH,
+ volumeSerialNumber, maximumComponentLength, fileSystemFlags,
+ f, MAX_PATH);
+ volumeName = v;
+ fileSystemName = f;
+ }
+ return BOOLToBool(res);
}
-
-#ifndef _UNICODE
-bool MyGetVolumeInformation(
- LPCWSTR rootPathName,
- UString &volumeName,
- LPDWORD volumeSerialNumber,
- LPDWORD maximumComponentLength,
- LPDWORD fileSystemFlags,
- UString &fileSystemName)
+UINT MyGetDriveType(CFSTR pathName)
{
- if (g_IsNT)
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- bool result = BOOLToBool(GetVolumeInformationW(
- rootPathName,
- volumeName.GetBuffer(MAX_PATH), MAX_PATH,
- volumeSerialNumber,
- maximumComponentLength,
- fileSystemFlags,
- fileSystemName.GetBuffer(MAX_PATH), MAX_PATH));
- volumeName.ReleaseBuffer();
- fileSystemName.ReleaseBuffer();
- return result;
+ return GetDriveType(fs2fas(pathName));
}
- AString volumeNameA, fileSystemNameA;
- bool result = MyGetVolumeInformation(GetSystemString(rootPathName), volumeNameA,
- volumeSerialNumber, maximumComponentLength, fileSystemFlags,fileSystemNameA);
- if (result)
+ else
+ #endif
{
- volumeName = GetUnicodeString(volumeNameA);
- fileSystemName = GetUnicodeString(fileSystemNameA);
+ return GetDriveTypeW(fs2us(pathName));
}
- return result;
}
-#endif
-typedef BOOL (WINAPI * GetDiskFreeSpaceExPointer)(
- LPCTSTR lpDirectoryName, // directory name
+typedef BOOL (WINAPI * GetDiskFreeSpaceExW_Pointer)(
+ LPCWSTR lpDirectoryName, // directory name
PULARGE_INTEGER lpFreeBytesAvailable, // bytes available to caller
PULARGE_INTEGER lpTotalNumberOfBytes, // bytes on disk
PULARGE_INTEGER lpTotalNumberOfFreeBytes // free bytes on disk
);
-bool MyGetDiskFreeSpace(LPCTSTR rootPathName,
- UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize)
+bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize)
{
- GetDiskFreeSpaceExPointer pGetDiskFreeSpaceEx =
- (GetDiskFreeSpaceExPointer)GetProcAddress(
- GetModuleHandle(TEXT("kernel32.dll")), "GetDiskFreeSpaceExA");
-
+ DWORD numSectorsPerCluster, bytesPerSector, numFreeClusters, numClusters;
bool sizeIsDetected = false;
- if (pGetDiskFreeSpaceEx)
+ #ifndef _UNICODE
+ if (!g_IsNT)
{
- ULARGE_INTEGER i64FreeBytesToCaller, totalSize2, freeSize2;
- sizeIsDetected = BOOLToBool(pGetDiskFreeSpaceEx(rootPathName,
- &i64FreeBytesToCaller,
- &totalSize2,
- &freeSize2));
- totalSize = totalSize2.QuadPart;
- freeSize = freeSize2.QuadPart;
+ if (!::GetDiskFreeSpace(fs2fas(rootPath), &numSectorsPerCluster, &bytesPerSector, &numFreeClusters, &numClusters))
+ return false;
+ }
+ else
+ #endif
+ {
+ GetDiskFreeSpaceExW_Pointer pGetDiskFreeSpaceEx = (GetDiskFreeSpaceExW_Pointer)GetProcAddress(
+ GetModuleHandle(TEXT("kernel32.dll")), "GetDiskFreeSpaceExW");
+ if (pGetDiskFreeSpaceEx)
+ {
+ ULARGE_INTEGER freeBytesToCaller2, totalSize2, freeSize2;
+ sizeIsDetected = BOOLToBool(pGetDiskFreeSpaceEx(fs2us(rootPath), &freeBytesToCaller2, &totalSize2, &freeSize2));
+ totalSize = totalSize2.QuadPart;
+ freeSize = freeSize2.QuadPart;
+ }
+ if (!::GetDiskFreeSpaceW(fs2us(rootPath), &numSectorsPerCluster, &bytesPerSector, &numFreeClusters, &numClusters))
+ return false;
}
-
- DWORD numSectorsPerCluster;
- DWORD bytesPerSector;
- DWORD numberOfFreeClusters;
- DWORD totalNumberOfClusters;
-
- if (!::GetDiskFreeSpace(rootPathName,
- &numSectorsPerCluster,
- &bytesPerSector,
- &numberOfFreeClusters,
- &totalNumberOfClusters))
- return false;
-
clusterSize = (UInt64)bytesPerSector * (UInt64)numSectorsPerCluster;
if (!sizeIsDetected)
{
- totalSize = clusterSize * (UInt64)totalNumberOfClusters;
- freeSize = clusterSize * (UInt64)numberOfFreeClusters;
+ totalSize = clusterSize * (UInt64)numClusters;
+ freeSize = clusterSize * (UInt64)numFreeClusters;
}
return true;
}
-#ifndef _UNICODE
-bool MyGetDiskFreeSpace(LPCWSTR rootPathName,
- UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize)
-{
- return MyGetDiskFreeSpace(GetSystemString(rootPathName), clusterSize, totalSize, freeSize);
-}
-#endif
-
}}}
diff --git a/CPP/Windows/FileSystem.h b/CPP/Windows/FileSystem.h
index 727497bb..a7a8d1a9 100755
--- a/CPP/Windows/FileSystem.h
+++ b/CPP/Windows/FileSystem.h
@@ -1,51 +1,27 @@
// Windows/FileSystem.h
-#ifndef __WINDOWS_FILESYSTEM_H
-#define __WINDOWS_FILESYSTEM_H
+#ifndef __WINDOWS_FILE_SYSTEM_H
+#define __WINDOWS_FILE_SYSTEM_H
#include "../Common/MyString.h"
#include "../Common/Types.h"
-#ifndef _UNICODE
-#include "../Common/StringConvert.h"
-#endif
-
namespace NWindows {
namespace NFile {
namespace NSystem {
bool MyGetVolumeInformation(
- LPCTSTR rootPathName,
- CSysString &volumeName,
- LPDWORD volumeSerialNumber,
- LPDWORD maximumComponentLength,
- LPDWORD fileSystemFlags,
- CSysString &fileSystemName);
-
-#ifndef _UNICODE
-bool MyGetVolumeInformation(
- LPCWSTR rootPathName,
+ CFSTR rootPath ,
UString &volumeName,
LPDWORD volumeSerialNumber,
LPDWORD maximumComponentLength,
LPDWORD fileSystemFlags,
UString &fileSystemName);
-#endif
-
-inline UINT MyGetDriveType(LPCTSTR pathName) { return GetDriveType(pathName); }
-#ifndef _UNICODE
-inline UINT MyGetDriveType(LPCWSTR pathName) { return GetDriveType(GetSystemString(pathName)); }
-#endif
-bool MyGetDiskFreeSpace(LPCTSTR rootPathName,
- UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
+UINT MyGetDriveType(CFSTR pathName);
-#ifndef _UNICODE
-bool MyGetDiskFreeSpace(LPCWSTR rootPathName,
- UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
-#endif
+bool MyGetDiskFreeSpace(CFSTR rootPath, UInt64 &clusterSize, UInt64 &totalSize, UInt64 &freeSize);
}}}
#endif
-
diff --git a/CPP/Windows/PropVariantUtils.cpp b/CPP/Windows/PropVariantUtils.cpp
index 0a9cfab7..f10b4ef2 100755
--- a/CPP/Windows/PropVariantUtils.cpp
+++ b/CPP/Windows/PropVariantUtils.cpp
@@ -20,7 +20,7 @@ void StringToProp(const AString &s, NCOM::CPropVariant &prop)
prop = MultiByteToUnicodeString(s);
}
-void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NCOM::CPropVariant &prop)
+AString TypePairToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 value)
{
AString s;
for (unsigned i = 0; i < num; i++)
@@ -31,7 +31,13 @@ void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NCOM:
}
if (s.IsEmpty())
s = GetHex(value);
- StringToProp(s, prop);
+ return s;
+}
+
+
+void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NCOM::CPropVariant &prop)
+{
+ StringToProp(TypePairToString(pairs, num, value), prop);
}
AString TypeToString(const char *table[], unsigned num, UInt32 value)
@@ -56,9 +62,12 @@ AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags)
UInt32 flag = (UInt32)1 << (unsigned)p.Value;
if ((flags & flag) != 0)
{
- if (!s.IsEmpty())
- s += ' ';
- s += p.Name;
+ if (p.Name[0] != 0)
+ {
+ if (!s.IsEmpty())
+ s += ' ';
+ s += p.Name;
+ }
}
flags &= ~flag;
}
@@ -75,4 +84,3 @@ void FlagsToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags, NCOM
{
StringToProp(FlagsToString(pairs, num, flags), prop);
}
-
diff --git a/CPP/Windows/PropVariantUtils.h b/CPP/Windows/PropVariantUtils.h
index 5aaf65cb..5582aaff 100755
--- a/CPP/Windows/PropVariantUtils.h
+++ b/CPP/Windows/PropVariantUtils.h
@@ -13,6 +13,7 @@ struct CUInt32PCharPair
};
void StringToProp(const AString &s, NWindows::NCOM::CPropVariant &prop);
+AString TypePairToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 value);
void PairToProp(const CUInt32PCharPair *pairs, unsigned num, UInt32 value, NWindows::NCOM::CPropVariant &prop);
AString FlagsToString(const CUInt32PCharPair *pairs, unsigned num, UInt32 flags);
diff --git a/CPP/Windows/Time.cpp b/CPP/Windows/Time.cpp
index ec9ca47d..2cb028f9 100755
--- a/CPP/Windows/Time.cpp
+++ b/CPP/Windows/Time.cpp
@@ -13,8 +13,9 @@ static const UInt32 kNumTimeQuantumsInSecond = 10000000;
static const UInt32 kFileTimeStartYear = 1601;
static const UInt32 kDosTimeStartYear = 1980;
static const UInt32 kUnixTimeStartYear = 1970;
-static const UInt64 kUnixTimeStartValue = ((UInt64)kNumTimeQuantumsInSecond) *
- 60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear));
+static const UInt64 kUnixTimeOffset =
+ (UInt64)60 * 60 * 24 * (89 + 365 * (kUnixTimeStartYear - kFileTimeStartYear));
+static const UInt64 kNumSecondsInFileTime = (UInt64)(Int64)-1 / kNumTimeQuantumsInSecond;
bool DosTimeToFileTime(UInt32 dosTime, FILETIME &ft)
{
@@ -117,20 +118,52 @@ bool FileTimeToDosTime(const FILETIME &ft, UInt32 &dosTime)
void UnixTimeToFileTime(UInt32 unixTime, FILETIME &ft)
{
- UInt64 v = kUnixTimeStartValue + ((UInt64)unixTime) * kNumTimeQuantumsInSecond;
+ UInt64 v = (kUnixTimeOffset + (UInt64)unixTime) * kNumTimeQuantumsInSecond;
ft.dwLowDateTime = (DWORD)v;
ft.dwHighDateTime = (DWORD)(v >> 32);
}
+bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &ft)
+{
+ Int64 v = (Int64)kUnixTimeOffset + unixTime;
+ if (unixTime < 0)
+ {
+ if (v < 0)
+ {
+ ft.dwLowDateTime = ft.dwHighDateTime = 0;
+ return false;
+ }
+ }
+ else
+ {
+ if (v < unixTime || v > kNumSecondsInFileTime)
+ {
+ ft.dwLowDateTime = ft.dwHighDateTime = (UInt32)(Int32)-1;
+ return false;
+ }
+ }
+ UInt64 v2 = (UInt64)v * kNumTimeQuantumsInSecond;
+ ft.dwLowDateTime = (DWORD)v2;
+ ft.dwHighDateTime = (DWORD)(v2 >> 32);
+ return true;
+}
+
+Int64 FileTimeToUnixTime64(const FILETIME &ft)
+{
+ UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
+ return (Int64)(winTime / kNumTimeQuantumsInSecond) - kUnixTimeOffset;
+}
+
bool FileTimeToUnixTime(const FILETIME &ft, UInt32 &unixTime)
{
UInt64 winTime = (((UInt64)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
- if (winTime < kUnixTimeStartValue)
+ winTime /= kNumTimeQuantumsInSecond;
+ if (winTime < kUnixTimeOffset)
{
unixTime = 0;
return false;
}
- winTime = (winTime - kUnixTimeStartValue) / kNumTimeQuantumsInSecond;
+ winTime -= kUnixTimeOffset;
if (winTime > 0xFFFFFFFF)
{
unixTime = 0xFFFFFFFF;
diff --git a/CPP/Windows/Time.h b/CPP/Windows/Time.h
index 6f510b22..537b80e6 100755
--- a/CPP/Windows/Time.h
+++ b/CPP/Windows/Time.h
@@ -11,7 +11,9 @@ namespace NTime {
bool DosTimeToFileTime(UInt32 dosTime, FILETIME &fileTime);
bool FileTimeToDosTime(const FILETIME &fileTime, UInt32 &dosTime);
void UnixTimeToFileTime(UInt32 unixTime, FILETIME &fileTime);
+bool UnixTime64ToFileTime(Int64 unixTime, FILETIME &fileTime);
bool FileTimeToUnixTime(const FILETIME &fileTime, UInt32 &unixTime);
+Int64 FileTimeToUnixTime64(const FILETIME &ft);
bool GetSecondsSince1601(unsigned year, unsigned month, unsigned day,
unsigned hour, unsigned min, unsigned sec, UInt64 &resSeconds);
void GetCurUtcFileTime(FILETIME &ft);
diff --git a/DOC/7zip.inf b/DOC/7zip.inf
index ff235405..b78a834f 100755
--- a/DOC/7zip.inf
+++ b/DOC/7zip.inf
@@ -10,8 +10,8 @@ AppName = "7-Zip"
InstallDir = %CE1%\%AppName%
[Strings]
-AppVer = "9.20"
-AppDate = "2010-11-18"
+AppVer = "9.21"
+AppDate = "2011-04-11"
[CEDevice]
; ProcessorType = 2577 ; ARM
diff --git a/DOC/7zip.nsi b/DOC/7zip.nsi
index 06af769c..977f27e8 100755
--- a/DOC/7zip.nsi
+++ b/DOC/7zip.nsi
@@ -2,8 +2,8 @@
;Defines
!define VERSION_MAJOR 9
-!define VERSION_MINOR 20
-!define VERSION_POSTFIX_FULL ""
+!define VERSION_MINOR 21
+!define VERSION_POSTFIX_FULL "beta"
!ifdef WIN64
!ifdef IA64
!define VERSION_SYS_POSTFIX_FULL " for Windows IA-64"
@@ -49,7 +49,7 @@
InstallDir "$PROGRAMFILES\7-Zip"
;Get install folder from registry if available
- InstallDirRegKey HKLM "Software\7-Zip" "Path"
+ InstallDirRegKey HKCU "Software\7-Zip" "Path32"
;Compressor
!ifndef NO_COMPRESSION
@@ -190,6 +190,7 @@ Section
File bn.txt
File br.txt
File ca.txt
+ File co.txt
File cs.txt
File cy.txt
File da.txt
@@ -222,6 +223,8 @@ Section
File ko.txt
File ku.txt
File ku-ckb.txt
+ File ky.txt
+ File lij.txt
File lt.txt
File lv.txt
File mk.txt
@@ -293,8 +296,10 @@ Section
noScErrors:
# store install folder
- WriteRegStr HKLM "Software\7-Zip" "Path" $INSTDIR
- WriteRegStr HKCU "Software\7-Zip" "Path" $INSTDIR
+ WriteRegStr HKLM "Software\7-Zip" "Path32" $INSTDIR
+ WriteRegStr HKLM "Software\7-Zip" "Path" $INSTDIR
+ WriteRegStr HKCU "Software\7-Zip" "Path32" $INSTDIR
+ WriteRegStr HKCU "Software\7-Zip" "Path" $INSTDIR
# write reg entries
WriteRegStr HKCR "CLSID\${CLSID_CONTEXT_MENU}" "" "7-Zip Shell Extension"
@@ -384,6 +389,7 @@ Section "Uninstall"
Delete $INSTDIR\Lang\bn.txt
Delete $INSTDIR\Lang\br.txt
Delete $INSTDIR\Lang\ca.txt
+ Delete $INSTDIR\Lang\co.txt
Delete $INSTDIR\Lang\cs.txt
Delete $INSTDIR\Lang\cy.txt
Delete $INSTDIR\Lang\da.txt
@@ -416,6 +422,8 @@ Section "Uninstall"
Delete $INSTDIR\Lang\ko.txt
Delete $INSTDIR\Lang\ku.txt
Delete $INSTDIR\Lang\ku-ckb.txt
+ Delete $INSTDIR\Lang\ky.txt
+ Delete $INSTDIR\Lang\lij.txt
Delete $INSTDIR\Lang\lt.txt
Delete $INSTDIR\Lang\lv.txt
Delete $INSTDIR\Lang\mk.txt
@@ -496,6 +504,7 @@ Section "Uninstall"
DeleteRegKey HKCR "Directory\shellex\ContextMenuHandlers\7-Zip"
DeleteRegKey HKCR "Folder\shellex\ContextMenuHandlers\7-Zip"
+ DeleteRegKey HKCR "Drive\shellex\DragDropHandlers\7-Zip"
DeleteRegKey HKCR "Directory\shellex\DragDropHandlers\7-Zip"
DeleteRegKey HKCR "Folder\shellex\DragDropHandlers\7-Zip"
@@ -512,6 +521,7 @@ Section "Uninstall"
DeleteRegKey HKCR "7-Zip.cpio"
DeleteRegKey HKCR "7-Zip.deb"
DeleteRegKey HKCR "7-Zip.dmg"
+ DeleteRegKey HKCR "7-Zip.fat"
DeleteRegKey HKCR "7-Zip.gz"
DeleteRegKey HKCR "7-Zip.gzip"
DeleteRegKey HKCR "7-Zip.hfs"
@@ -519,16 +529,21 @@ Section "Uninstall"
DeleteRegKey HKCR "7-Zip.lha"
DeleteRegKey HKCR "7-Zip.lzh"
DeleteRegKey HKCR "7-Zip.lzma"
+ DeleteRegKey HKCR "7-Zip.ntfs"
DeleteRegKey HKCR "7-Zip.rar"
DeleteRegKey HKCR "7-Zip.rpm"
DeleteRegKey HKCR "7-Zip.split"
+ DeleteRegKey HKCR "7-Zip.squashfs"
DeleteRegKey HKCR "7-Zip.swm"
DeleteRegKey HKCR "7-Zip.tar"
DeleteRegKey HKCR "7-Zip.taz"
DeleteRegKey HKCR "7-Zip.tgz"
DeleteRegKey HKCR "7-Zip.tpz"
+ DeleteRegKey HKCR "7-Zip.txz"
+ DeleteRegKey HKCR "7-Zip.vhd"
DeleteRegKey HKCR "7-Zip.wim"
DeleteRegKey HKCR "7-Zip.xar"
+ DeleteRegKey HKCR "7-Zip.xz"
DeleteRegKey HKCR "7-Zip.z"
DeleteRegKey HKCR "7-Zip.zip"
diff --git a/DOC/7zip.wxs b/DOC/7zip.wxs
index 984e6687..1d266498 100755
--- a/DOC/7zip.wxs
+++ b/DOC/7zip.wxs
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<?define VerMajor = "9" ?>
-<?define VerMinor = "20" ?>
+<?define VerMinor = "21" ?>
<?define VerBuild = "00" ?>
<?define MmVer = "$(var.VerMajor).$(var.VerMinor)" ?>
<?define MmHex = "0$(var.VerMajor)$(var.VerMinor)" ?>
@@ -20,18 +20,21 @@
<?define Platforms = "x64" ?>
<?define CpuPostfix = " (x64 edition)" ?>
<?define Is64 = "yes" ?>
+ <?define NumBits = "64" ?>
<?elseif $(var.MyCPU) = "ia64" ?>
<?define CpuId = "3" ?>
<?define PFilesFolder = "ProgramFiles64Folder" ?>
<?define Platforms = "Intel64" ?>
<?define CpuPostfix = " (ia64 edition)" ?>
<?define Is64 = "yes" ?>
+ <?define NumBits = "64" ?>
<?else ?>
<?define CpuId = "1" ?>
<?define PFilesFolder = "ProgramFilesFolder" ?>
<?define Platforms = "Intel" ?>
<?define CpuPostfix = "" ?>
<?define Is64 = "no" ?>
+ <?define NumBits = "32" ?>
<?endif ?>
@@ -100,7 +103,10 @@
<Media Id="1" Cabinet="product.cab" EmbedCab="yes" CompressionLevel="high" />
<Property Id="INSTALLDIR">
- <RegistrySearch Id="My7zipPath" Type="raw" Root="HKCU" Key="Software\7-Zip" Name="Path" />
+ <RegistrySearch Id="My7zipPathLM" Type="raw" Root="HKLM" Key="Software\7-Zip" Name="Path" />
+ <RegistrySearch Id="My7zipPathLM2" Type="raw" Root="HKLM" Key="Software\7-Zip" Name="Path$(var.NumBits)" />
+ <RegistrySearch Id="My7zipPath" Type="raw" Root="HKCU" Key="Software\7-Zip" Name="Path" />
+ <RegistrySearch Id="My7zipPath2" Type="raw" Root="HKCU" Key="Software\7-Zip" Name="Path$(var.NumBits)" />
</Property>
<Property Id="ALLUSERS">2</Property>
@@ -116,13 +122,13 @@
<Directory Id="INSTALLDIR" Name="7-Zip">
<Component Id="InstallRegCU" Guid="$(var.CompInstallRegCU)" DiskId="1" Win64="$(var.Is64)">
- <Registry Id="MyInstallRegCU" Root="HKCU" Key="Software\7-Zip" Name="Path"
- Action="write" Type="string" Value="[INSTALLDIR]" />
+ <Registry Id="MyInstallRegCU" Root="HKCU" Key="Software\7-Zip" Name="Path" Action="write" Type="string" Value="[INSTALLDIR]" />
+ <Registry Id="MyInstallRegCU2" Root="HKCU" Key="Software\7-Zip" Name="Path$(var.NumBits)" Action="write" Type="string" Value="[INSTALLDIR]" />
</Component>
<Component Id="InstallRegLM" Guid="$(var.CompInstallRegLM)" DiskId="1" Win64="$(var.Is64)">
<Condition>Privileged</Condition>
- <Registry Id="MyInstallRegLM" Root="HKLM" Key="Software\7-Zip" Name="Path"
- Action="write" Type="string" Value="[INSTALLDIR]" />
+ <Registry Id="MyInstallRegLM" Root="HKLM" Key="Software\7-Zip" Name="Path" Action="write" Type="string" Value="[INSTALLDIR]" />
+ <Registry Id="MyInstallRegLM2" Root="HKLM" Key="Software\7-Zip" Name="Path$(var.NumBits)" Action="write" Type="string" Value="[INSTALLDIR]" />
</Component>
@@ -174,6 +180,21 @@
</File>
</Component>
+ <?if $(var.MyCPU) = "x64" ?>
+
+ <Component Id="ShellExt32" Guid="$(var.CompShellExt)" DiskId="1" Win64="no">
+ <File Id="_7zip32.dll" Name="7-zip32.dll" />
+ <Registry Id="shellReg0_32" Action="write" Type="string" Root="HKCR"
+ Key="CLSID\$(var.ShellExtId)\InprocServer32"
+ Value="[INSTALLDIR]7-zip32.dll" />
+ <Registry Id="shellReg1_32" Action="write" Type="string" Root="HKCR"
+ Key="CLSID\$(var.ShellExtId)\InprocServer32"
+ Name="ThreadingModel"
+ Value="Apartment" />
+ </Component>
+
+ <?endif ?>
+
<Component Id="ShellExt" Guid="$(var.CompShellExt)" DiskId="1" Win64="$(var.Is64)">
<File Id="_7zip.dll" Name="7-zip.dll" />
<Registry Id="shellReg0" Action="write" Type="string" Root="HKCR"
@@ -232,6 +253,7 @@
<File Id="bn.txt" Name="bn.txt" />
<File Id="br.txt" Name="br.txt" />
<File Id="ca.txt" Name="ca.txt" />
+ <File Id="co.txt" Name="co.txt" />
<File Id="cs.txt" Name="cs.txt" />
<File Id="cy.txt" Name="cy.txt" />
<File Id="da.txt" Name="da.txt" />
@@ -264,6 +286,8 @@
<File Id="ko.txt" Name="ko.txt" />
<File Id="ku.txt" Name="ku.txt" />
<File Id="ku_ckb.txt" Name="ku-ckb.txt" />
+ <File Id="ky.txt" Name="ky.txt" />
+ <File Id="lij.txt" Name="lij.txt" />
<File Id="lt.txt" Name="lt.txt" />
<File Id="lv.txt" Name="lv.txt" />
<File Id="mk.txt" Name="mk.txt" />
@@ -319,6 +343,9 @@
Absent="disallow" AllowAdvertise="no">
<ComponentRef Id="Fm" />
<ComponentRef Id="ShellExt" />
+ <?if $(var.MyCPU) = "x64" ?>
+ <ComponentRef Id="ShellExt32" />
+ <?endif ?>
<ComponentRef Id="CmdLine" />
<ComponentRef Id="Gui" />
<ComponentRef Id="GuiSfx" />
diff --git a/DOC/history.txt b/DOC/history.txt
index 05a9a216..64ce04ae 100755
--- a/DOC/history.txt
+++ b/DOC/history.txt
@@ -1,6 +1,12 @@
Sources history of the 7-Zip
----------------------------
+9.21 2011-04-11
+-------------------------
+- New class FString for file names at file systems.
+- Speed optimization in CRC code for big-endian CPUs.
+
+
9.18 2010-11-02
-------------------------
- New small SFX module for installers (C/Util/SfxSetup).
diff --git a/DOC/lzma.txt b/DOC/lzma.txt
index 65932323..ce1af3a2 100755
--- a/DOC/lzma.txt
+++ b/DOC/lzma.txt
@@ -1,4 +1,4 @@
-LZMA SDK 9.20
+LZMA SDK 9.21
-------------
LZMA SDK provides the documentation, samples, header files, libraries,
@@ -24,6 +24,12 @@ Some code in LZMA SDK is based on public domain code from another developers:
1) PPMd var.H (2001): Dmitry Shkarin
2) SHA-256: Wei Dai (Crypto++ library)
+You can copy, modify, distribute and perform LZMA SDK code, even for commercial purposes,
+all without asking permission.
+
+LZMA SDK code is compatible with open source licenses, for example, you can
+include it to GNU GPL or GNU LGPL code.
+
LZMA SDK Contents
-----------------
diff --git a/DOC/readme.txt b/DOC/readme.txt
index aad46264..96e6b485 100755
--- a/DOC/readme.txt
+++ b/DOC/readme.txt
@@ -1,4 +1,4 @@
-7-Zip 9.20 Sources
+7-Zip 9.21 Sources
------------------
7-Zip is a file archiver for Windows.