From d9666cf046a8453b33b3e2fbf4d82295a9f87df3 Mon Sep 17 00:00:00 2001 From: Igor Pavlov Date: Sat, 20 Jan 2007 00:00:00 +0000 Subject: 4.44 beta --- CPP/7zip/UI/Agent/Agent.cpp | 578 +++++++++ CPP/7zip/UI/Agent/Agent.h | 314 +++++ CPP/7zip/UI/Agent/AgentOut.cpp | 518 ++++++++ CPP/7zip/UI/Agent/AgentProxy.cpp | 203 ++++ CPP/7zip/UI/Agent/AgentProxy.h | 56 + CPP/7zip/UI/Agent/ArchiveFolder.cpp | 72 ++ CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp | 98 ++ CPP/7zip/UI/Agent/ArchiveFolderOut.cpp | 215 ++++ CPP/7zip/UI/Agent/IFolderArchive.h | 90 ++ CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp | 80 ++ CPP/7zip/UI/Agent/UpdateCallbackAgent.h | 24 + CPP/7zip/UI/Client7z/Client7z.cpp | 850 ++++++++++++++ CPP/7zip/UI/Client7z/Client7z.dsp | 226 ++++ CPP/7zip/UI/Client7z/Client7z.dsw | 29 + CPP/7zip/UI/Client7z/StdAfx.cpp | 3 + CPP/7zip/UI/Client7z/StdAfx.h | 9 + CPP/7zip/UI/Client7z/makefile | 45 + CPP/7zip/UI/Common/ArchiveCommandLine.cpp | 985 ++++++++++++++++ CPP/7zip/UI/Common/ArchiveCommandLine.h | 95 ++ CPP/7zip/UI/Common/ArchiveExtractCallback.cpp | 448 +++++++ CPP/7zip/UI/Common/ArchiveExtractCallback.h | 111 ++ CPP/7zip/UI/Common/ArchiveName.cpp | 46 + CPP/7zip/UI/Common/ArchiveName.h | 10 + CPP/7zip/UI/Common/ArchiveOpenCallback.cpp | 127 ++ CPP/7zip/UI/Common/ArchiveOpenCallback.h | 89 ++ CPP/7zip/UI/Common/ArchiverInfo.cpp | 372 ++++++ CPP/7zip/UI/Common/ArchiverInfo.h | 66 ++ CPP/7zip/UI/Common/CompressCall.cpp | 367 ++++++ CPP/7zip/UI/Common/CompressCall.h | 28 + CPP/7zip/UI/Common/DefaultName.cpp | 26 + CPP/7zip/UI/Common/DefaultName.h | 11 + CPP/7zip/UI/Common/DirItem.h | 34 + CPP/7zip/UI/Common/EnumDirItems.cpp | 281 +++++ CPP/7zip/UI/Common/EnumDirItems.h | 39 + CPP/7zip/UI/Common/ExitCode.h | 27 + CPP/7zip/UI/Common/Extract.cpp | 152 +++ CPP/7zip/UI/Common/Extract.h | 59 + CPP/7zip/UI/Common/ExtractMode.h | 31 + CPP/7zip/UI/Common/ExtractingFilePath.cpp | 75 ++ CPP/7zip/UI/Common/ExtractingFilePath.h | 12 + CPP/7zip/UI/Common/HandlerLoader.h | 38 + CPP/7zip/UI/Common/IFileExtractCallback.h | 46 + CPP/7zip/UI/Common/OpenArchive.cpp | 531 +++++++++ CPP/7zip/UI/Common/OpenArchive.h | 134 +++ CPP/7zip/UI/Common/PropIDUtils.cpp | 90 ++ CPP/7zip/UI/Common/PropIDUtils.h | 11 + CPP/7zip/UI/Common/Property.h | 14 + CPP/7zip/UI/Common/SetProperties.cpp | 65 + CPP/7zip/UI/Common/SetProperties.h | 10 + CPP/7zip/UI/Common/SortUtils.cpp | 78 ++ CPP/7zip/UI/Common/SortUtils.h | 11 + CPP/7zip/UI/Common/StdAfx.h | 9 + CPP/7zip/UI/Common/TempFiles.cpp | 22 + CPP/7zip/UI/Common/TempFiles.h | 16 + CPP/7zip/UI/Common/Update.cpp | 818 +++++++++++++ CPP/7zip/UI/Common/Update.h | 158 +++ CPP/7zip/UI/Common/UpdateAction.cpp | 64 + CPP/7zip/UI/Common/UpdateAction.h | 57 + CPP/7zip/UI/Common/UpdateCallback.cpp | 258 ++++ CPP/7zip/UI/Common/UpdateCallback.h | 70 ++ CPP/7zip/UI/Common/UpdatePair.cpp | 175 +++ CPP/7zip/UI/Common/UpdatePair.h | 24 + CPP/7zip/UI/Common/UpdateProduce.cpp | 63 + CPP/7zip/UI/Common/UpdateProduce.h | 31 + CPP/7zip/UI/Common/WorkDir.cpp | 64 + CPP/7zip/UI/Common/WorkDir.h | 10 + CPP/7zip/UI/Common/ZipRegistry.cpp | 420 +++++++ CPP/7zip/UI/Common/ZipRegistry.h | 99 ++ CPP/7zip/UI/Console/Console.dsp | 667 +++++++++++ CPP/7zip/UI/Console/Console.dsw | 29 + CPP/7zip/UI/Console/ConsoleClose.cpp | 65 + CPP/7zip/UI/Console/ConsoleClose.h | 24 + CPP/7zip/UI/Console/ExtractCallbackConsole.cpp | 235 ++++ CPP/7zip/UI/Console/ExtractCallbackConsole.h | 65 + CPP/7zip/UI/Console/List.cpp | 532 +++++++++ CPP/7zip/UI/Console/List.h | 13 + CPP/7zip/UI/Console/Main.cpp | 382 ++++++ CPP/7zip/UI/Console/MainAr.cpp | 169 +++ CPP/7zip/UI/Console/OpenCallbackConsole.cpp | 58 + CPP/7zip/UI/Console/OpenCallbackConsole.h | 27 + CPP/7zip/UI/Console/PercentPrinter.cpp | 90 ++ CPP/7zip/UI/Console/PercentPrinter.h | 31 + CPP/7zip/UI/Console/StdAfx.cpp | 3 + CPP/7zip/UI/Console/StdAfx.h | 9 + CPP/7zip/UI/Console/UpdateCallbackConsole.cpp | 196 +++ CPP/7zip/UI/Console/UpdateCallbackConsole.h | 75 ++ CPP/7zip/UI/Console/UserInputUtils.cpp | 58 + CPP/7zip/UI/Console/UserInputUtils.h | 24 + CPP/7zip/UI/Console/afxres.h | 1 + CPP/7zip/UI/Console/makefile | 93 ++ CPP/7zip/UI/Console/resource.rc | 3 + CPP/7zip/UI/Explorer/7-zip.dll.manifest | 1 + CPP/7zip/UI/Explorer/ContextMenu.cpp | 682 +++++++++++ CPP/7zip/UI/Explorer/ContextMenu.h | 86 ++ CPP/7zip/UI/Explorer/ContextMenuFlags.h | 34 + CPP/7zip/UI/Explorer/DllExports.cpp | 315 +++++ CPP/7zip/UI/Explorer/Explorer.def | 12 + CPP/7zip/UI/Explorer/Explorer.dsp | 818 +++++++++++++ CPP/7zip/UI/Explorer/Explorer.dsw | 29 + CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.cpp | 157 +++ CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.h | 30 + CPP/7zip/UI/Explorer/FoldersPage/resource.h | 12 + CPP/7zip/UI/Explorer/FoldersPage/resource.rc | 36 + CPP/7zip/UI/Explorer/MyMessages.cpp | 58 + CPP/7zip/UI/Explorer/MyMessages.h | 30 + CPP/7zip/UI/Explorer/OptionsDialog.cpp | 71 ++ CPP/7zip/UI/Explorer/OptionsDialog.h | 23 + CPP/7zip/UI/Explorer/RegistryContextMenu.cpp | 128 ++ CPP/7zip/UI/Explorer/RegistryContextMenu.h | 13 + CPP/7zip/UI/Explorer/StdAfx.cpp | 3 + CPP/7zip/UI/Explorer/StdAfx.h | 26 + CPP/7zip/UI/Explorer/SystemPage/SystemPage.cpp | 212 ++++ CPP/7zip/UI/Explorer/SystemPage/SystemPage.h | 25 + CPP/7zip/UI/Explorer/SystemPage/resource.h | 6 + CPP/7zip/UI/Explorer/SystemPage/resource.rc | 24 + CPP/7zip/UI/Explorer/makefile | 137 +++ CPP/7zip/UI/Explorer/resource.h | 31 + CPP/7zip/UI/Explorer/resource.rc | 38 + CPP/7zip/UI/Far/CLSIDConst.cpp | 8 + CPP/7zip/UI/Far/ExtractEngine.cpp | 168 +++ CPP/7zip/UI/Far/ExtractEngine.h | 68 ++ CPP/7zip/UI/Far/Far.def | 20 + CPP/7zip/UI/Far/Far.dsp | 561 +++++++++ CPP/7zip/UI/Far/Far.dsw | 29 + CPP/7zip/UI/Far/FarPlugin.h | 577 +++++++++ CPP/7zip/UI/Far/FarUtils.cpp | 416 +++++++ CPP/7zip/UI/Far/FarUtils.h | 185 +++ CPP/7zip/UI/Far/Main.cpp | 622 ++++++++++ CPP/7zip/UI/Far/Messages.h | 152 +++ CPP/7zip/UI/Far/OverwriteDialog.cpp | 109 ++ CPP/7zip/UI/Far/OverwriteDialog.h | 33 + CPP/7zip/UI/Far/Plugin.cpp | 693 +++++++++++ CPP/7zip/UI/Far/Plugin.h | 99 ++ CPP/7zip/UI/Far/PluginCommon.cpp | 50 + CPP/7zip/UI/Far/PluginDelete.cpp | 169 +++ CPP/7zip/UI/Far/PluginRead.cpp | 278 +++++ CPP/7zip/UI/Far/PluginWrite.cpp | 696 +++++++++++ CPP/7zip/UI/Far/ProgressBox.cpp | 103 ++ CPP/7zip/UI/Far/ProgressBox.h | 35 + CPP/7zip/UI/Far/StdAfx.cpp | 3 + CPP/7zip/UI/Far/StdAfx.h | 12 + CPP/7zip/UI/Far/UpdateCallback100.cpp | 54 + CPP/7zip/UI/Far/UpdateCallback100.h | 45 + CPP/7zip/UI/Far/makefile | 102 ++ CPP/7zip/UI/Far/resource.rc | 3 + CPP/7zip/UI/GUI/7zG.exe.manifest | 1 + CPP/7zip/UI/GUI/CompressDialog.cpp | 1373 ++++++++++++++++++++++ CPP/7zip/UI/GUI/CompressDialog.h | 171 +++ CPP/7zip/UI/GUI/ExtractDialog.cpp | 371 ++++++ CPP/7zip/UI/GUI/ExtractDialog.h | 77 ++ CPP/7zip/UI/GUI/ExtractGUI.cpp | 172 +++ CPP/7zip/UI/GUI/ExtractGUI.h | 20 + CPP/7zip/UI/GUI/FM.ico | Bin 0 -> 4846 bytes CPP/7zip/UI/GUI/GUI.cpp | 260 ++++ CPP/7zip/UI/GUI/GUI.dsp | 904 ++++++++++++++ CPP/7zip/UI/GUI/GUI.dsw | 29 + CPP/7zip/UI/GUI/OpenCallbackGUI.cpp | 65 + CPP/7zip/UI/GUI/OpenCallbackGUI.h | 35 + CPP/7zip/UI/GUI/StdAfx.cpp | 3 + CPP/7zip/UI/GUI/StdAfx.h | 13 + CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp | 167 +++ CPP/7zip/UI/GUI/UpdateCallbackGUI.h | 63 + CPP/7zip/UI/GUI/UpdateGUI.cpp | 397 +++++++ CPP/7zip/UI/GUI/UpdateGUI.h | 20 + CPP/7zip/UI/GUI/makefile | 135 +++ CPP/7zip/UI/GUI/resource.h | 45 + CPP/7zip/UI/GUI/resource.rc | 57 + CPP/7zip/UI/Resource/CompressDialog/resource.h | 40 + CPP/7zip/UI/Resource/CompressDialog/resource.rc | 117 ++ CPP/7zip/UI/Resource/Extract/resource.h | 15 + CPP/7zip/UI/Resource/Extract/resource.rc | 19 + CPP/7zip/UI/Resource/ExtractDialog/resource.h | 26 + CPP/7zip/UI/Resource/ExtractDialog/resource.rc | 80 ++ CPP/7zip/UI/makefile | 10 + 174 files changed, 26148 insertions(+) create mode 100755 CPP/7zip/UI/Agent/Agent.cpp create mode 100755 CPP/7zip/UI/Agent/Agent.h create mode 100755 CPP/7zip/UI/Agent/AgentOut.cpp create mode 100755 CPP/7zip/UI/Agent/AgentProxy.cpp create mode 100755 CPP/7zip/UI/Agent/AgentProxy.h create mode 100755 CPP/7zip/UI/Agent/ArchiveFolder.cpp create mode 100755 CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp create mode 100755 CPP/7zip/UI/Agent/ArchiveFolderOut.cpp create mode 100755 CPP/7zip/UI/Agent/IFolderArchive.h create mode 100755 CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp create mode 100755 CPP/7zip/UI/Agent/UpdateCallbackAgent.h create mode 100755 CPP/7zip/UI/Client7z/Client7z.cpp create mode 100755 CPP/7zip/UI/Client7z/Client7z.dsp create mode 100755 CPP/7zip/UI/Client7z/Client7z.dsw create mode 100755 CPP/7zip/UI/Client7z/StdAfx.cpp create mode 100755 CPP/7zip/UI/Client7z/StdAfx.h create mode 100755 CPP/7zip/UI/Client7z/makefile create mode 100755 CPP/7zip/UI/Common/ArchiveCommandLine.cpp create mode 100755 CPP/7zip/UI/Common/ArchiveCommandLine.h create mode 100755 CPP/7zip/UI/Common/ArchiveExtractCallback.cpp create mode 100755 CPP/7zip/UI/Common/ArchiveExtractCallback.h create mode 100755 CPP/7zip/UI/Common/ArchiveName.cpp create mode 100755 CPP/7zip/UI/Common/ArchiveName.h create mode 100755 CPP/7zip/UI/Common/ArchiveOpenCallback.cpp create mode 100755 CPP/7zip/UI/Common/ArchiveOpenCallback.h create mode 100755 CPP/7zip/UI/Common/ArchiverInfo.cpp create mode 100755 CPP/7zip/UI/Common/ArchiverInfo.h create mode 100755 CPP/7zip/UI/Common/CompressCall.cpp create mode 100755 CPP/7zip/UI/Common/CompressCall.h create mode 100755 CPP/7zip/UI/Common/DefaultName.cpp create mode 100755 CPP/7zip/UI/Common/DefaultName.h create mode 100755 CPP/7zip/UI/Common/DirItem.h create mode 100755 CPP/7zip/UI/Common/EnumDirItems.cpp create mode 100755 CPP/7zip/UI/Common/EnumDirItems.h create mode 100755 CPP/7zip/UI/Common/ExitCode.h create mode 100755 CPP/7zip/UI/Common/Extract.cpp create mode 100755 CPP/7zip/UI/Common/Extract.h create mode 100755 CPP/7zip/UI/Common/ExtractMode.h create mode 100755 CPP/7zip/UI/Common/ExtractingFilePath.cpp create mode 100755 CPP/7zip/UI/Common/ExtractingFilePath.h create mode 100755 CPP/7zip/UI/Common/HandlerLoader.h create mode 100755 CPP/7zip/UI/Common/IFileExtractCallback.h create mode 100755 CPP/7zip/UI/Common/OpenArchive.cpp create mode 100755 CPP/7zip/UI/Common/OpenArchive.h create mode 100755 CPP/7zip/UI/Common/PropIDUtils.cpp create mode 100755 CPP/7zip/UI/Common/PropIDUtils.h create mode 100755 CPP/7zip/UI/Common/Property.h create mode 100755 CPP/7zip/UI/Common/SetProperties.cpp create mode 100755 CPP/7zip/UI/Common/SetProperties.h create mode 100755 CPP/7zip/UI/Common/SortUtils.cpp create mode 100755 CPP/7zip/UI/Common/SortUtils.h create mode 100755 CPP/7zip/UI/Common/StdAfx.h create mode 100755 CPP/7zip/UI/Common/TempFiles.cpp create mode 100755 CPP/7zip/UI/Common/TempFiles.h create mode 100755 CPP/7zip/UI/Common/Update.cpp create mode 100755 CPP/7zip/UI/Common/Update.h create mode 100755 CPP/7zip/UI/Common/UpdateAction.cpp create mode 100755 CPP/7zip/UI/Common/UpdateAction.h create mode 100755 CPP/7zip/UI/Common/UpdateCallback.cpp create mode 100755 CPP/7zip/UI/Common/UpdateCallback.h create mode 100755 CPP/7zip/UI/Common/UpdatePair.cpp create mode 100755 CPP/7zip/UI/Common/UpdatePair.h create mode 100755 CPP/7zip/UI/Common/UpdateProduce.cpp create mode 100755 CPP/7zip/UI/Common/UpdateProduce.h create mode 100755 CPP/7zip/UI/Common/WorkDir.cpp create mode 100755 CPP/7zip/UI/Common/WorkDir.h create mode 100755 CPP/7zip/UI/Common/ZipRegistry.cpp create mode 100755 CPP/7zip/UI/Common/ZipRegistry.h create mode 100755 CPP/7zip/UI/Console/Console.dsp create mode 100755 CPP/7zip/UI/Console/Console.dsw create mode 100755 CPP/7zip/UI/Console/ConsoleClose.cpp create mode 100755 CPP/7zip/UI/Console/ConsoleClose.h create mode 100755 CPP/7zip/UI/Console/ExtractCallbackConsole.cpp create mode 100755 CPP/7zip/UI/Console/ExtractCallbackConsole.h create mode 100755 CPP/7zip/UI/Console/List.cpp create mode 100755 CPP/7zip/UI/Console/List.h create mode 100755 CPP/7zip/UI/Console/Main.cpp create mode 100755 CPP/7zip/UI/Console/MainAr.cpp create mode 100755 CPP/7zip/UI/Console/OpenCallbackConsole.cpp create mode 100755 CPP/7zip/UI/Console/OpenCallbackConsole.h create mode 100755 CPP/7zip/UI/Console/PercentPrinter.cpp create mode 100755 CPP/7zip/UI/Console/PercentPrinter.h create mode 100755 CPP/7zip/UI/Console/StdAfx.cpp create mode 100755 CPP/7zip/UI/Console/StdAfx.h create mode 100755 CPP/7zip/UI/Console/UpdateCallbackConsole.cpp create mode 100755 CPP/7zip/UI/Console/UpdateCallbackConsole.h create mode 100755 CPP/7zip/UI/Console/UserInputUtils.cpp create mode 100755 CPP/7zip/UI/Console/UserInputUtils.h create mode 100755 CPP/7zip/UI/Console/afxres.h create mode 100755 CPP/7zip/UI/Console/makefile create mode 100755 CPP/7zip/UI/Console/resource.rc create mode 100755 CPP/7zip/UI/Explorer/7-zip.dll.manifest create mode 100755 CPP/7zip/UI/Explorer/ContextMenu.cpp create mode 100755 CPP/7zip/UI/Explorer/ContextMenu.h create mode 100755 CPP/7zip/UI/Explorer/ContextMenuFlags.h create mode 100755 CPP/7zip/UI/Explorer/DllExports.cpp create mode 100755 CPP/7zip/UI/Explorer/Explorer.def create mode 100755 CPP/7zip/UI/Explorer/Explorer.dsp create mode 100755 CPP/7zip/UI/Explorer/Explorer.dsw create mode 100755 CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.cpp create mode 100755 CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.h create mode 100755 CPP/7zip/UI/Explorer/FoldersPage/resource.h create mode 100755 CPP/7zip/UI/Explorer/FoldersPage/resource.rc create mode 100755 CPP/7zip/UI/Explorer/MyMessages.cpp create mode 100755 CPP/7zip/UI/Explorer/MyMessages.h create mode 100755 CPP/7zip/UI/Explorer/OptionsDialog.cpp create mode 100755 CPP/7zip/UI/Explorer/OptionsDialog.h create mode 100755 CPP/7zip/UI/Explorer/RegistryContextMenu.cpp create mode 100755 CPP/7zip/UI/Explorer/RegistryContextMenu.h create mode 100755 CPP/7zip/UI/Explorer/StdAfx.cpp create mode 100755 CPP/7zip/UI/Explorer/StdAfx.h create mode 100755 CPP/7zip/UI/Explorer/SystemPage/SystemPage.cpp create mode 100755 CPP/7zip/UI/Explorer/SystemPage/SystemPage.h create mode 100755 CPP/7zip/UI/Explorer/SystemPage/resource.h create mode 100755 CPP/7zip/UI/Explorer/SystemPage/resource.rc create mode 100755 CPP/7zip/UI/Explorer/makefile create mode 100755 CPP/7zip/UI/Explorer/resource.h create mode 100755 CPP/7zip/UI/Explorer/resource.rc create mode 100755 CPP/7zip/UI/Far/CLSIDConst.cpp create mode 100755 CPP/7zip/UI/Far/ExtractEngine.cpp create mode 100755 CPP/7zip/UI/Far/ExtractEngine.h create mode 100755 CPP/7zip/UI/Far/Far.def create mode 100755 CPP/7zip/UI/Far/Far.dsp create mode 100755 CPP/7zip/UI/Far/Far.dsw create mode 100755 CPP/7zip/UI/Far/FarPlugin.h create mode 100755 CPP/7zip/UI/Far/FarUtils.cpp create mode 100755 CPP/7zip/UI/Far/FarUtils.h create mode 100755 CPP/7zip/UI/Far/Main.cpp create mode 100755 CPP/7zip/UI/Far/Messages.h create mode 100755 CPP/7zip/UI/Far/OverwriteDialog.cpp create mode 100755 CPP/7zip/UI/Far/OverwriteDialog.h create mode 100755 CPP/7zip/UI/Far/Plugin.cpp create mode 100755 CPP/7zip/UI/Far/Plugin.h create mode 100755 CPP/7zip/UI/Far/PluginCommon.cpp create mode 100755 CPP/7zip/UI/Far/PluginDelete.cpp create mode 100755 CPP/7zip/UI/Far/PluginRead.cpp create mode 100755 CPP/7zip/UI/Far/PluginWrite.cpp create mode 100755 CPP/7zip/UI/Far/ProgressBox.cpp create mode 100755 CPP/7zip/UI/Far/ProgressBox.h create mode 100755 CPP/7zip/UI/Far/StdAfx.cpp create mode 100755 CPP/7zip/UI/Far/StdAfx.h create mode 100755 CPP/7zip/UI/Far/UpdateCallback100.cpp create mode 100755 CPP/7zip/UI/Far/UpdateCallback100.h create mode 100755 CPP/7zip/UI/Far/makefile create mode 100755 CPP/7zip/UI/Far/resource.rc create mode 100755 CPP/7zip/UI/GUI/7zG.exe.manifest create mode 100755 CPP/7zip/UI/GUI/CompressDialog.cpp create mode 100755 CPP/7zip/UI/GUI/CompressDialog.h create mode 100755 CPP/7zip/UI/GUI/ExtractDialog.cpp create mode 100755 CPP/7zip/UI/GUI/ExtractDialog.h create mode 100755 CPP/7zip/UI/GUI/ExtractGUI.cpp create mode 100755 CPP/7zip/UI/GUI/ExtractGUI.h create mode 100755 CPP/7zip/UI/GUI/FM.ico create mode 100755 CPP/7zip/UI/GUI/GUI.cpp create mode 100755 CPP/7zip/UI/GUI/GUI.dsp create mode 100755 CPP/7zip/UI/GUI/GUI.dsw create mode 100755 CPP/7zip/UI/GUI/OpenCallbackGUI.cpp create mode 100755 CPP/7zip/UI/GUI/OpenCallbackGUI.h create mode 100755 CPP/7zip/UI/GUI/StdAfx.cpp create mode 100755 CPP/7zip/UI/GUI/StdAfx.h create mode 100755 CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp create mode 100755 CPP/7zip/UI/GUI/UpdateCallbackGUI.h create mode 100755 CPP/7zip/UI/GUI/UpdateGUI.cpp create mode 100755 CPP/7zip/UI/GUI/UpdateGUI.h create mode 100755 CPP/7zip/UI/GUI/makefile create mode 100755 CPP/7zip/UI/GUI/resource.h create mode 100755 CPP/7zip/UI/GUI/resource.rc create mode 100755 CPP/7zip/UI/Resource/CompressDialog/resource.h create mode 100755 CPP/7zip/UI/Resource/CompressDialog/resource.rc create mode 100755 CPP/7zip/UI/Resource/Extract/resource.h create mode 100755 CPP/7zip/UI/Resource/Extract/resource.rc create mode 100755 CPP/7zip/UI/Resource/ExtractDialog/resource.h create mode 100755 CPP/7zip/UI/Resource/ExtractDialog/resource.rc create mode 100755 CPP/7zip/UI/makefile (limited to 'CPP/7zip/UI') diff --git a/CPP/7zip/UI/Agent/Agent.cpp b/CPP/7zip/UI/Agent/Agent.cpp new file mode 100755 index 00000000..f983e2f9 --- /dev/null +++ b/CPP/7zip/UI/Agent/Agent.cpp @@ -0,0 +1,578 @@ +// Agent.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/ComTry.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" +#include "Windows/FileFind.h" + +#include "../Common/DefaultName.h" +#include "../Common/ArchiveExtractCallback.h" + +#include "Agent.h" + +#ifdef FORMAT_7Z +#include "../../Archive/7z/7zHandler.h" +#endif + +extern "C" +{ + #include "../../../../C/Sort.h" +} + + +using namespace NWindows; + +STDMETHODIMP CAgentFolder::GetAgentFolder(CAgentFolder **agentFolder) +{ + *agentFolder = this; + return S_OK; +} + +void CAgentFolder::LoadFolder(CProxyFolder *folder) +{ + int i; + CProxyItem item; + item.Folder = folder; + for (i = 0; i < folder->Folders.Size(); i++) + { + item.Index = i; + _items.Add(item); + LoadFolder(&folder->Folders[i]); + } + int start = folder->Folders.Size(); + for (i = 0; i < folder->Files.Size(); i++) + { + item.Index = start + i; + _items.Add(item); + } +} + + +STDMETHODIMP CAgentFolder::LoadItems() +{ + _items.Clear(); + if (_flatMode) + LoadFolder(_proxyFolderItem); + return S_OK; +} + +STDMETHODIMP CAgentFolder::GetNumberOfItems(UINT32 *numItems) +{ + if (_flatMode) + *numItems = _items.Size(); + else + *numItems = _proxyFolderItem->Folders.Size() +_proxyFolderItem->Files.Size(); + return S_OK; +} + +/* +STDMETHODIMP CAgentFolder::GetNumberOfSubFolders(UINT32 *aNumSubFolders) +{ + *aNumSubFolders = _proxyFolderItem->Folders.Size(); + return S_OK; +} +*/ + +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; + } + + if (realIndex < (UINT32)folder->Folders.Size()) + return folder->Folders[realIndex].Name; + return folder->Files[realIndex - folder->Folders.Size()].Name; +} + +UString CAgentFolder::GetPrefix(UInt32 index) const +{ + if (!_flatMode) + return UString(); + const CProxyItem &item = _items[index]; + const CProxyFolder *folder = item.Folder; + UString path; + while(folder != _proxyFolderItem) + { + path = folder->Name + UString(L"\\") + path; + folder = folder->Parent; + } + return path; +} + +UString CAgentFolder::GetFullPathPrefixPlusPrefix(UInt32 index) const +{ + return _proxyFolderItem->GetFullPathPrefix() + GetPrefix(index); +} + +void CAgentFolder::GetPrefixIfAny(UInt32 index, NCOM::CPropVariant &propVariant) const +{ + if (!_flatMode) + return; + propVariant = GetPrefix(index); +} + + +STDMETHODIMP CAgentFolder::GetProperty(UINT32 itemIndex, PROPID propID, PROPVARIANT *value) +{ + NCOM::CPropVariant propVariant; + const CProxyFolder *folder; + UInt32 realIndex; + if (_flatMode) + { + const CProxyItem &item = _items[itemIndex]; + folder = item.Folder; + realIndex = item.Index; + } + else + { + folder = _proxyFolderItem; + realIndex = itemIndex; + } + + if (realIndex < (UINT32)folder->Folders.Size()) + { + const CProxyFolder &item = folder->Folders[realIndex]; + switch(propID) + { + case kpidIsFolder: + propVariant = true; + break; + case kpidName: + propVariant = item.Name; + break; + case kpidPrefix: + GetPrefixIfAny(itemIndex, propVariant); + break; + default: + if (item.IsLeaf) + return _agentSpec->GetArchive()->GetProperty(item.Index, propID, value); + } + } + else + { + realIndex -= folder->Folders.Size(); + const CProxyFile &item = folder->Files[realIndex]; + switch(propID) + { + case kpidIsFolder: + propVariant = false; + break; + case kpidName: + propVariant = item.Name; + break; + case kpidPrefix: + GetPrefixIfAny(itemIndex, propVariant); + break; + default: + return _agentSpec->GetArchive()->GetProperty(item.Index, propID, value); + } + } + propVariant.Detach(value); + return S_OK; +} + +HRESULT CAgentFolder::BindToFolder(CProxyFolder *folder, IFolderFolder **resultFolder) +{ + CMyComPtr parentFolder; + if (folder->Parent != _proxyFolderItem) + { + RINOK(BindToFolder(folder->Parent, &parentFolder)); + } + else + parentFolder = this; + CAgentFolder *folderSpec = new CAgentFolder; + CMyComPtr agentFolder = folderSpec; + folderSpec->Init(_proxyArchive, folder, parentFolder, _agentSpec); + *resultFolder = agentFolder.Detach(); + return S_OK; +} + +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; + } + if (realIndex >= (UINT32)folder->Folders.Size()) + return E_INVALIDARG; + return BindToFolder(&folder->Folders[realIndex], resultFolder); + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder) +{ + COM_TRY_BEGIN + int index = _proxyFolderItem->FindDirSubItemIndex(name); + if (index < 0) + return E_INVALIDARG; + return BindToFolder(index, resultFolder); + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::BindToParentFolder(IFolderFolder **resultFolder) +{ + COM_TRY_BEGIN + CMyComPtr parentFolder = _parentFolder; + *resultFolder = parentFolder.Detach(); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::GetName(BSTR *name) +{ + CMyComBSTR temp = _proxyFolderItem->Name; + *name = temp.Detach(); + return S_OK; +} + + +#ifdef NEW_FOLDER_INTERFACE + +struct CArchiveItemPropertyTemp +{ + UString Name; + PROPID ID; + VARTYPE Type; +}; + +STDMETHODIMP CAgentFolder::GetNumberOfProperties(UINT32 *numProperties) +{ + COM_TRY_BEGIN + RINOK(_agentSpec->GetArchive()->GetNumberOfProperties(numProperties)); + if (_flatMode) + (*numProperties)++; + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::GetPropertyInfo(UINT32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + COM_TRY_BEGIN + UINT32 numProperties; + _agentSpec->GetArchive()->GetNumberOfProperties(&numProperties); + if (index < numProperties) + { + RINOK(_agentSpec->GetArchive()->GetPropertyInfo(index, name, propID, varType)); + if (*propID == kpidPath) + *propID = kpidName; + } + else + { + *name = NULL; + *propID = kpidPrefix; + *varType = VT_BSTR; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::GetTypeID(BSTR *name) +{ + COM_TRY_BEGIN + UString temp = UString(L"7-Zip.") + _agentSpec->ArchiveType; + CMyComBSTR bstrTemp = temp; + *name = bstrTemp.Detach(); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::GetPath(BSTR *path) +{ + COM_TRY_BEGIN + UStringVector pathParts; + pathParts.Clear(); + CMyComPtr currentFolder = this; + for (;;) + { + CMyComPtr newFolder; + currentFolder->BindToParentFolder(&newFolder); + if (newFolder == NULL) + break; + CMyComBSTR aName; + currentFolder->GetName(&aName); + pathParts.Insert(0, (const wchar_t *)aName); + currentFolder = newFolder; + } + + UString prefix; + for(int i = 0; i < pathParts.Size(); i++) + { + prefix += pathParts[i]; + prefix += L'\\'; + } + + CMyComBSTR tempPath = prefix; + *path = tempPath.Detach(); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::SetFlatMode(Int32 flatMode) +{ + _flatMode = IntToBool(flatMode); + return S_OK; +} + +#endif + +void CAgentFolder::GetRealIndices(const UINT32 *indices, UINT32 numItems, CUIntVector &realIndices) const +{ + if (!_flatMode) + { + _proxyFolderItem->GetRealIndices(indices, numItems, realIndices); + return; + } + realIndices.Clear(); + for(UINT32 i = 0; i < numItems; i++) + { + const CProxyItem &item = _items[indices[i]]; + const CProxyFolder *folder = item.Folder; + UInt32 realIndex = item.Index; + if (realIndex < (UINT32)folder->Folders.Size()) + continue; + realIndices.Add(folder->Files[realIndex - folder->Folders.Size()].Index); + } + HeapSort(&realIndices.Front(), realIndices.Size()); +} + +STDMETHODIMP CAgentFolder::Extract(const UINT32 *indices, + UINT32 numItems, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const wchar_t *path, + INT32 testMode, + IFolderArchiveExtractCallback *extractCallback2) +{ + COM_TRY_BEGIN + CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; + CMyComPtr extractCallback = extractCallbackSpec; + UStringVector pathParts; + CProxyFolder *currentProxyFolder = _proxyFolderItem; + while (currentProxyFolder->Parent) + { + pathParts.Insert(0, currentProxyFolder->Name); + currentProxyFolder = currentProxyFolder->Parent; + } + + /* + if (_flatMode) + pathMode = NExtract::NPathMode::kNoPathnames; + */ + + extractCallbackSpec->Init(_agentSpec->GetArchive(), + extractCallback2, + false, + path, + pathMode, + overwriteMode, + pathParts, + _agentSpec->DefaultName, + _agentSpec->DefaultTime, + _agentSpec->DefaultAttributes + // ,_agentSpec->_srcDirectoryPrefix + ); + CUIntVector realIndices; + GetRealIndices(indices, numItems, realIndices); + return _agentSpec->GetArchive()->Extract(&realIndices.Front(), + realIndices.Size(), testMode, extractCallback); + COM_TRY_END +} + +///////////////////////////////////////// +// CAgent + +CAgent::CAgent(): + _proxyArchive(NULL) +{ +} + +CAgent::~CAgent() +{ + if (_proxyArchive != NULL) + delete _proxyArchive; +} + +STDMETHODIMP CAgent::Open( + const wchar_t *filePath, + BSTR *archiveType, + // CLSID *clsIDResult, + IArchiveOpenCallback *openArchiveCallback) +{ + COM_TRY_BEGIN + _archiveFilePath = filePath; + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(_archiveFilePath, fileInfo)) + return ::GetLastError(); + if (fileInfo.IsDirectory()) + return E_FAIL; + CArchiverInfo archiverInfo0, archiverInfo1; + HRESULT res = OpenArchive(_archiveFilePath, _archiveLink, openArchiveCallback); + // _archive = _archiveLink.GetArchive(); + DefaultName = _archiveLink.GetDefaultItemName(); + const CArchiverInfo &ai = _archiveLink.GetArchiverInfo(); + + RINOK(res); + DefaultTime = fileInfo.LastWriteTime; + DefaultAttributes = fileInfo.Attributes; + ArchiveType = ai.Name; + if (archiveType != 0) + { + CMyComBSTR name = ArchiveType; + *archiveType = name.Detach(); + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CAgent::ReOpen( + // const wchar_t *filePath, + IArchiveOpenCallback * /* openArchiveCallback */) +{ + COM_TRY_BEGIN + if (_proxyArchive != NULL) + { + delete _proxyArchive; + _proxyArchive = NULL; + } + RINOK(ReOpenArchive(_archiveLink, _archiveFilePath)); + return ReadItems(); + COM_TRY_END +} + +STDMETHODIMP CAgent::Close() +{ + COM_TRY_BEGIN + RINOK(_archiveLink.Close()); + if (_archiveLink.GetNumLevels() > 1) + { + // return S_OK; + } + // _archive->Close(); + return S_OK; + COM_TRY_END +} + +/* +STDMETHODIMP CAgent::EnumProperties(IEnumSTATPROPSTG **EnumProperties) +{ + return _archive->EnumProperties(EnumProperties); +} +*/ + +HRESULT CAgent::ReadItems() +{ + if (_proxyArchive != NULL) + return S_OK; + _proxyArchive = new CProxyArchive(); + return _proxyArchive->Load(GetArchive(), + DefaultName, + // _defaultTime, + // _defaultAttributes, + NULL); +} + +STDMETHODIMP CAgent::BindToRootFolder(IFolderFolder **resultFolder) +{ + COM_TRY_BEGIN + RINOK(ReadItems()); + CAgentFolder *folderSpec = new CAgentFolder; + CMyComPtr rootFolder = folderSpec; + folderSpec->Init(_proxyArchive, &_proxyArchive->RootFolder, NULL, this); + *resultFolder = rootFolder.Detach(); + return S_OK; + COM_TRY_END +} + + +STDMETHODIMP CAgent::Extract( + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const wchar_t *path, + INT32 testMode, + IFolderArchiveExtractCallback *extractCallback2) +{ + COM_TRY_BEGIN + CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; + CMyComPtr extractCallback = extractCallbackSpec; + extractCallbackSpec->Init(GetArchive(), + extractCallback2, + false, + path, + pathMode, + overwriteMode, + UStringVector(), + DefaultName, + DefaultTime, + DefaultAttributes + // ,_srcDirectoryPrefix + ); + return GetArchive()->Extract(0, (UInt32)(Int32)-1, testMode, extractCallback); + COM_TRY_END +} + +STDMETHODIMP CAgent::GetNumberOfProperties(UINT32 *numProperties) +{ + COM_TRY_BEGIN + return GetArchive()->GetNumberOfProperties(numProperties); + COM_TRY_END +} + +STDMETHODIMP CAgent::GetPropertyInfo(UINT32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + COM_TRY_BEGIN + RINOK(GetArchive()->GetPropertyInfo(index, name, propID, varType)); + if (*propID == kpidPath) + *propID = kpidName; + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CAgent::GetArchiveProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + return GetArchive()->GetArchiveProperty(propID, value); + COM_TRY_END +} + +STDMETHODIMP CAgent::GetNumberOfArchiveProperties(UINT32 *numProperties) +{ + COM_TRY_BEGIN + return GetArchive()->GetNumberOfArchiveProperties(numProperties); + COM_TRY_END +} + +STDMETHODIMP CAgent::GetArchivePropertyInfo(UINT32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) +{ + COM_TRY_BEGIN + return GetArchive()->GetArchivePropertyInfo(index, + name, propID, varType); + COM_TRY_END +} + diff --git a/CPP/7zip/UI/Agent/Agent.h b/CPP/7zip/UI/Agent/Agent.h new file mode 100755 index 00000000..41f80266 --- /dev/null +++ b/CPP/7zip/UI/Agent/Agent.h @@ -0,0 +1,314 @@ +// Agent/Agent.h + +#ifndef __AGENT_AGENT_H +#define __AGENT_AGENT_H + +#include "Common/MyCom.h" +#include "Windows/PropVariant.h" + +#include "../Common/UpdateAction.h" +#include "../Common/ArchiverInfo.h" +#include "../Common/OpenArchive.h" + +#include "IFolderArchive.h" +#include "AgentProxy.h" + +#ifndef EXCLUDE_COM +#include "Windows/DLL.h" +#endif +#ifdef NEW_FOLDER_INTERFACE +#include "../../FileManager/IFolder.h" +#endif + +class CAgentFolder; + +// {23170F69-40C1-278A-0000-000100050001} +DEFINE_GUID(IID_IArchiveFolderInternal, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000100050001") +IArchiveFolderInternal: public IUnknown +{ +public: + STDMETHOD(GetAgentFolder)(CAgentFolder **agentFolder) PURE; +}; + +struct CProxyItem +{ + CProxyFolder *Folder; + UInt32 Index; +}; + +class CAgent; + +class CAgentFolder: + public IFolderFolder, + public IArchiveFolder, + public IArchiveFolderInternal, +#ifdef NEW_FOLDER_INTERFACE + public IEnumProperties, + public IFolderGetTypeID, + public IFolderGetPath, + public IFolderOperations, + public IFolderSetFlatMode, +#endif + public CMyUnknownImp +{ +public: + + MY_QUERYINTERFACE_BEGIN + MY_QUERYINTERFACE_ENTRY(IFolderFolder) + MY_QUERYINTERFACE_ENTRY(IArchiveFolder) + MY_QUERYINTERFACE_ENTRY(IArchiveFolderInternal) + #ifdef NEW_FOLDER_INTERFACE + MY_QUERYINTERFACE_ENTRY(IEnumProperties) + MY_QUERYINTERFACE_ENTRY(IFolderGetTypeID) + MY_QUERYINTERFACE_ENTRY(IFolderGetPath) + MY_QUERYINTERFACE_ENTRY(IFolderOperations) + MY_QUERYINTERFACE_ENTRY(IFolderSetFlatMode) + #endif + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + // IFolderFolder + + void LoadFolder(CProxyFolder *folder); + HRESULT BindToFolder(CProxyFolder *folder, IFolderFolder **resultFolder); + void GetRealIndices(const UINT32 *indices, UINT32 numItems, CUIntVector &realIndices) const; + + STDMETHOD(LoadItems)(); + STDMETHOD(GetNumberOfItems)(UINT32 *numItems); + STDMETHOD(GetProperty)(UINT32 itemIndex, PROPID propID, PROPVARIANT *value); + STDMETHOD(BindToFolder)(UINT32 index, IFolderFolder **resultFolder); + STDMETHOD(BindToFolder)(const wchar_t *name, IFolderFolder **resultFolder); + STDMETHOD(BindToParentFolder)(IFolderFolder **resultFolder); + STDMETHOD(GetName)(BSTR *name); + + // IArchiveFolder + STDMETHOD(Extract)(const UINT32 *indices, UINT32 numItems, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const wchar_t *path, + INT32 testMode, + IFolderArchiveExtractCallback *extractCallback); + + STDMETHOD(GetAgentFolder)(CAgentFolder **agentFolder); + + #ifdef NEW_FOLDER_INTERFACE + STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); + STDMETHOD(GetPropertyInfo)(UINT32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + STDMETHOD(GetTypeID)(BSTR *name); + STDMETHOD(GetPath)(BSTR *path); + + + // IFolderOperations + STDMETHOD(CreateFolder)(const wchar_t *name, IProgress *progress); + STDMETHOD(CreateFile)(const wchar_t *name, IProgress *progress); + STDMETHOD(Rename)(UINT32 index, const wchar_t *newName, IProgress *progress); + STDMETHOD(Delete)(const UINT32 *indices, UINT32 numItems, IProgress *progress); + STDMETHOD(CopyTo)(const UINT32 *indices, UINT32 numItems, + const wchar_t *path, IFolderOperationsExtractCallback *callback); + STDMETHOD(MoveTo)(const UINT32 *indices, UINT32 numItems, + const wchar_t *path, IFolderOperationsExtractCallback *callback); + STDMETHOD(CopyFrom)(const wchar_t *fromFolderPath, + const wchar_t **itemsPaths, UINT32 numItems, IProgress *progress); + STDMETHOD(SetProperty)(UINT32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress); + + STDMETHOD(SetFlatMode)(Int32 flatMode); + #endif + + CAgentFolder(): _proxyFolderItem(NULL), _flatMode(0) {} + + void Init(CProxyArchive *proxyHandler, + CProxyFolder *proxyFolderItem, + IFolderFolder *parentFolder, + CAgent *agent) + { + _proxyArchive = proxyHandler; + _proxyFolderItem = proxyFolderItem; + _parentFolder = parentFolder; + _agent = (IInFolderArchive *)agent; + _agentSpec = agent; + } + + void GetPathParts(UStringVector &pathParts); + HRESULT CommonUpdateOperation( + bool deleteOperation, + bool createFolderOperation, + bool renameOperation, + const wchar_t *newItemName, + const NUpdateArchive::CActionSet *actionSet, + const UINT32 *indices, UINT32 numItems, + IFolderArchiveUpdateCallback *updateCallback100); + + + 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; + CMyComPtr _parentFolder; + CMyComPtr _agent; + CAgent *_agentSpec; + + CRecordVector _items; + bool _flatMode; +private: +}; + +// {23170F69-40C1-278A-1000-000100030000} +DEFINE_GUID(CLSID_CAgentArchiveHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00); + +class CAgent: + public IInFolderArchive, + #ifndef EXTRACT_ONLY + public IOutFolderArchive, + public ISetProperties, + #endif + public CMyUnknownImp +{ +public: + + MY_QUERYINTERFACE_BEGIN + MY_QUERYINTERFACE_ENTRY(IInFolderArchive) + #ifndef EXTRACT_ONLY + MY_QUERYINTERFACE_ENTRY(IOutFolderArchive) + MY_QUERYINTERFACE_ENTRY(ISetProperties) + #endif + MY_QUERYINTERFACE_END + MY_ADDREF_RELEASE + + STDMETHOD(Open)( + const wchar_t *filePath, + // CLSID *clsIDResult, + BSTR *archiveType, + IArchiveOpenCallback *openArchiveCallback); + + STDMETHOD(ReOpen)( + // const wchar_t *filePath, + IArchiveOpenCallback *openArchiveCallback); + /* + STDMETHOD(ReOpen)(IInStream *stream, + const wchar_t *defaultName, + const FILETIME *defaultTime, + UINT32 defaultAttributes, + const UINT64 *maxCheckStartPosition, + IArchiveOpenCallback *openArchiveCallback); + */ + STDMETHOD(Close)(); + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value); + STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties); + STDMETHOD(GetPropertyInfo)(UINT32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties); + STDMETHOD(GetArchivePropertyInfo)(UINT32 index, + BSTR *name, PROPID *propID, VARTYPE *varType); + STDMETHOD(BindToRootFolder)(IFolderFolder **resultFolder); + STDMETHOD(Extract)( + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const wchar_t *path, + INT32 testMode, + IFolderArchiveExtractCallback *extractCallback2); + + #ifndef EXTRACT_ONLY + STDMETHOD(SetFolder)(IFolderFolder *folder); + STDMETHOD(SetFiles)(const wchar_t *folderPrefix, const wchar_t **names, UINT32 numNames); + STDMETHOD(DeleteItems)(const wchar_t *newArchiveName, const UINT32 *indices, + UINT32 numItems, IFolderArchiveUpdateCallback *updateCallback); + STDMETHOD(DoOperation)( + const wchar_t *filePath, + const CLSID *clsID, + const wchar_t *newArchiveName, + const Byte *stateActions, + const wchar_t *sfxModule, + IFolderArchiveUpdateCallback *updateCallback); + + HRESULT CommonUpdate( + const wchar_t *newArchiveName, + int numUpdateItems, + IArchiveUpdateCallback *updateCallback); + + HRESULT CreateFolder( + const wchar_t *newArchiveName, + const wchar_t *folderName, + IFolderArchiveUpdateCallback *updateCallback100); + + HRESULT RenameItem( + const wchar_t *newArchiveName, + const UINT32 *indices, UINT32 numItems, + const wchar_t *newItemName, + IFolderArchiveUpdateCallback *updateCallback100); + + // ISetProperties + STDMETHOD(SetProperties)(const wchar_t **names, const PROPVARIANT *values, INT32 numProperties); + #endif + + CAgent(); + ~CAgent(); +private: + HRESULT ReadItems(); +public: + CProxyArchive *_proxyArchive; + + CArchiveLink _archiveLink; + // IInArchive *_archive2; + + // CLSID _CLSID; + // CMyComPtr m_RootFolder; + + UString DefaultName; + + FILETIME DefaultTime; + UINT32 DefaultAttributes; + + UString ArchiveType; + + UStringVector _names; + UString _folderPrefix; + + UString _archiveNamePrefix; + CAgentFolder *_agentFolder; + + UString _archiveFilePath; + + #ifndef EXTRACT_ONLY + CObjectVector m_PropNames; + CObjectVector m_PropValues; + #endif + + IInArchive *GetArchive() { return _archiveLink.GetArchive(); } + bool CanUpdate() const { return _archiveLink.GetNumLevels() <= 1; } +}; + +#ifdef NEW_FOLDER_INTERFACE +class CArchiveFolderManager: + public IFolderManager, + public IFolderManagerGetIconPath, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP2( + IFolderManager, + IFolderManagerGetIconPath + ) + // IFolderManager + STDMETHOD(OpenFolderFile)(const wchar_t *filePath, IFolderFolder **resultFolder, IProgress *progress); + STDMETHOD(GetTypes)(BSTR *types); + STDMETHOD(GetExtension)(const wchar_t *type, BSTR *extension); + STDMETHOD(CreateFolderFile)(const wchar_t *type, const wchar_t *filePath, IProgress *progress); + STDMETHOD(GetIconPath)(const wchar_t *type, BSTR *iconPath); + CArchiveFolderManager(): _formatsLoaded(false) {} +private: + void LoadFormats(); + int FindFormat(const UString &type); + bool _formatsLoaded; + CObjectVector _formats; +}; +#endif + +#endif diff --git a/CPP/7zip/UI/Agent/AgentOut.cpp b/CPP/7zip/UI/Agent/AgentOut.cpp new file mode 100755 index 00000000..25d65bb2 --- /dev/null +++ b/CPP/7zip/UI/Agent/AgentOut.cpp @@ -0,0 +1,518 @@ +// AgentOut.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/IntToString.h" + +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" +#include "Windows/PropVariantConversions.h" +#include "Windows/FileDir.h" + +#include "../../Compress/Copy/CopyCoder.h" +#include "../../Common/FileStreams.h" + +#include "../Common/UpdatePair.h" +#include "../Common/EnumDirItems.h" +#include "../Common/HandlerLoader.h" +#include "../Common/UpdateCallback.h" +#include "../Common/OpenArchive.h" + +#include "Agent.h" +#include "UpdateCallbackAgent.h" + +using namespace NWindows; +using namespace NCOM; + +static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream) +{ + CMyComPtr copyCoder = new NCompress::CCopyCoder; + return copyCoder->Code(inStream, outStream, NULL, NULL, NULL); +} + +STDMETHODIMP CAgent::SetFolder(IFolderFolder *folder) +{ + _archiveNamePrefix.Empty(); + if (folder == NULL) + { + _agentFolder = NULL; + return S_OK; + } + else + { + CMyComPtr archiveFolder = folder; + CMyComPtr archiveFolderInternal; + RINOK(archiveFolder.QueryInterface(IID_IArchiveFolderInternal, &archiveFolderInternal)); + RINOK(archiveFolderInternal->GetAgentFolder(&_agentFolder)); + } + + UStringVector pathParts; + pathParts.Clear(); + CMyComPtr folderItem = folder; + if (folderItem != NULL) + for (;;) + { + CMyComPtr newFolder; + folderItem->BindToParentFolder(&newFolder); + if (newFolder == NULL) + break; + CMyComBSTR name; + folderItem->GetName(&name); + pathParts.Insert(0, (const wchar_t *)name); + folderItem = newFolder; + } + + for(int i = 0; i < pathParts.Size(); i++) + { + _archiveNamePrefix += pathParts[i]; + _archiveNamePrefix += L'\\'; + } + return S_OK; +} + +STDMETHODIMP CAgent::SetFiles(const wchar_t *folderPrefix, + const wchar_t **names, UINT32 numNames) +{ + _folderPrefix = folderPrefix; + _names.Clear(); + _names.Reserve(numNames); + for (UINT32 i = 0; i < numNames; i++) + _names.Add(names[i]); + return S_OK; +} + + +static HRESULT GetFileTime(CAgent *agent, UINT32 itemIndex, FILETIME &fileTime) +{ + CPropVariant property; + RINOK(agent->GetArchive()->GetProperty(itemIndex, kpidLastWriteTime, &property)); + if (property.vt == VT_FILETIME) + fileTime = property.filetime; + else if (property.vt == VT_EMPTY) + fileTime = agent->DefaultTime; + else + throw 4190407; + return S_OK; +} + +static HRESULT EnumerateArchiveItems(CAgent *agent, + const CProxyFolder &item, + const UString &prefix, + CObjectVector &archiveItems) +{ + int i; + for(i = 0; i < item.Files.Size(); i++) + { + const CProxyFile &fileItem = item.Files[i]; + CArchiveItem archiveItem; + + RINOK(::GetFileTime(agent, fileItem.Index, archiveItem.LastWriteTime)); + + CPropVariant property; + agent->GetArchive()->GetProperty(fileItem.Index, kpidSize, &property); + archiveItem.SizeIsDefined = (property.vt != VT_EMPTY); + if (archiveItem.SizeIsDefined) + archiveItem.Size = ConvertPropVariantToUInt64(property); + archiveItem.IsDirectory = false; + archiveItem.Name = prefix + fileItem.Name; + archiveItem.Censored = true; // test it + archiveItem.IndexInServer = fileItem.Index; + archiveItems.Add(archiveItem); + } + for(i = 0; i < item.Folders.Size(); i++) + { + const CProxyFolder &dirItem = item.Folders[i]; + UString fullName = prefix + dirItem.Name; + if(dirItem.IsLeaf) + { + CArchiveItem archiveItem; + RINOK(::GetFileTime(agent, dirItem.Index, archiveItem.LastWriteTime)); + archiveItem.IsDirectory = true; + archiveItem.SizeIsDefined = false; + archiveItem.Name = fullName; + archiveItem.Censored = true; // test it + archiveItem.IndexInServer = dirItem.Index; + archiveItems.Add(archiveItem); + } + RINOK(EnumerateArchiveItems(agent, dirItem, fullName + UString(L'\\'), archiveItems)); + } + return S_OK; +} + +STDMETHODIMP CAgent::DoOperation( + const wchar_t *filePath, + const CLSID *clsID, + const wchar_t *newArchiveName, + const Byte *stateActions, + const wchar_t *sfxModule, + IFolderArchiveUpdateCallback *updateCallback100) +{ + if (!CanUpdate()) + return E_NOTIMPL; + NUpdateArchive::CActionSet actionSet; + int i; + for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) + actionSet.StateActions[i] = (NUpdateArchive::NPairAction::EEnum)stateActions[i]; + + CObjectVector dirItems; + + UString folderPrefix = _folderPrefix; + NFile::NName::NormalizeDirPathPrefix(folderPrefix); + UStringVector errorPaths; + CRecordVector errorCodes; + ::EnumerateDirItems(folderPrefix, _names, _archiveNamePrefix, dirItems, errorPaths, errorCodes); + if (errorCodes.Size() > 0) + { + return errorCodes.Front(); + } + + NWindows::NDLL::CLibrary library; + + CMyComPtr outArchive; + if (GetArchive()) + { + RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive)); + } + else + { + CHandlerLoader loader; + RINOK(loader.CreateHandler(filePath, *clsID, (void **)&outArchive, true)); + library.Attach(loader.Detach()); + } + + NFileTimeType::EEnum fileTimeType; + UINT32 value; + RINOK(outArchive->GetFileTimeType(&value)); + + switch(value) + { + case NFileTimeType::kWindows: + case NFileTimeType::kDOS: + case NFileTimeType::kUnix: + fileTimeType = NFileTimeType::EEnum(value); + break; + default: + return E_FAIL; + } + + CObjectVector updatePairs; + + CObjectVector archiveItems; + if (GetArchive()) + { + RINOK(ReadItems()); + EnumerateArchiveItems(this, _proxyArchive->RootFolder, L"", archiveItems); + } + + GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs); + + CObjectVector updatePairs2; + UpdateProduce(updatePairs, actionSet, updatePairs2); + + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.Callback = updateCallback100; + CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; + CMyComPtr updateCallback(updateCallbackSpec ); + + updateCallbackSpec->DirPrefix = folderPrefix; + updateCallbackSpec->DirItems = &dirItems; + updateCallbackSpec->ArchiveItems = &archiveItems; + updateCallbackSpec->UpdatePairs = &updatePairs2; + updateCallbackSpec->Archive = GetArchive(); + updateCallbackSpec->Callback = &updateCallbackAgent; + + COutFileStream *outStreamSpec = new COutFileStream; + CMyComPtr outStream(outStreamSpec); + UString archiveName = newArchiveName; + { + UString resultPath; + int pos; + if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos)) + throw 141716; + NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos)); + } + if (!outStreamSpec->Create(archiveName, true)) + { + // ShowLastErrorMessage(); + return E_FAIL; + } + + CMyComPtr setProperties; + if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK) + { + if (m_PropNames.Size() == 0) + { + RINOK(setProperties->SetProperties(0, 0, 0)); + } + else + { + CRecordVector names; + 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()]; + try + { + for (int i = 0; i < m_PropValues.Size(); i++) + propValues[i] = m_PropValues[i]; + RINOK(setProperties->SetProperties(&names.Front(), propValues, names.Size())); + } + catch(...) + { + delete []propValues; + throw; + } + delete []propValues; + } + } + m_PropNames.Clear(); + m_PropValues.Clear(); + + if (sfxModule != NULL) + { + CInFileStream *sfxStreamSpec = new CInFileStream; + CMyComPtr sfxStream(sfxStreamSpec); + if (!sfxStreamSpec->Open(sfxModule)) + throw "Can't open sfx module"; + RINOK(CopyBlock(sfxStream, outStream)); + } + + return outArchive->UpdateItems(outStream, updatePairs2.Size(),updateCallback); +} + + +HRESULT CAgent::CommonUpdate( + const wchar_t *newArchiveName, + int numUpdateItems, + IArchiveUpdateCallback *updateCallback) +{ + if (!CanUpdate()) + return E_NOTIMPL; + CMyComPtr outArchive; + RINOK(GetArchive()->QueryInterface(IID_IOutArchive, (void **)&outArchive)); + + COutFileStream *outStreamSpec = new COutFileStream; + CMyComPtr 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[32]; + ConvertUInt64ToString(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; + } + + return outArchive->UpdateItems(outStream, numUpdateItems, updateCallback); +} + + +STDMETHODIMP CAgent::DeleteItems( + const wchar_t *newArchiveName, + const UINT32 *indices, UINT32 numItems, + IFolderArchiveUpdateCallback *updateCallback100) +{ + if (!CanUpdate()) + return E_NOTIMPL; + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.Callback = updateCallback100; + CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; + CMyComPtr updateCallback(updateCallbackSpec); + + CUIntVector realIndices; + _agentFolder->GetRealIndices(indices, numItems, realIndices); + CObjectVector updatePairs; + int curIndex = 0; + UInt32 numItemsInArchive; + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); + for (UInt32 i = 0; i < numItemsInArchive; i++) + { + if (curIndex < realIndices.Size()) + if (realIndices[curIndex] == i) + { + curIndex++; + continue; + } + CUpdatePair2 updatePair; + updatePair.NewData = updatePair.NewProperties = false; + updatePair.ExistInArchive = true; + updatePair.ExistOnDisk = false; + updatePair.IsAnti = false; // check it. Maybe it can be undefined + updatePair.ArchiveItemIndex = i; + updatePairs.Add(updatePair); + } + updateCallbackSpec->UpdatePairs = &updatePairs; + updateCallbackSpec->Archive = GetArchive(); + updateCallbackSpec->Callback = &updateCallbackAgent; + return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback); +} + +HRESULT CAgent::CreateFolder( + const wchar_t *newArchiveName, + const wchar_t *folderName, + IFolderArchiveUpdateCallback *updateCallback100) +{ + if (!CanUpdate()) + return E_NOTIMPL; + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.Callback = updateCallback100; + CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; + CMyComPtr updateCallback(updateCallbackSpec); + + CObjectVector updatePairs; + UINT32 numItemsInArchive; + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); + for (UInt32 i = 0; i < numItemsInArchive; i++) + { + CUpdatePair2 updatePair; + updatePair.NewData = updatePair.NewProperties = false; + updatePair.ExistInArchive = true; + updatePair.ExistOnDisk = false; + updatePair.IsAnti = false; // check it. + updatePair.ArchiveItemIndex = i; + updatePairs.Add(updatePair); + } + CUpdatePair2 updatePair; + updatePair.NewData = updatePair.NewProperties = true; + updatePair.ExistInArchive = false; + updatePair.ExistOnDisk = true; + updatePair.IsAnti = false; + updatePair.ArchiveItemIndex = -1; + updatePair.DirItemIndex = 0; + + updatePairs.Add(updatePair); + + CObjectVector dirItems; + CDirItem dirItem; + + dirItem.Attributes = FILE_ATTRIBUTE_DIRECTORY; + dirItem.Size = 0; + dirItem.Name = _agentFolder->_proxyFolderItem->GetFullPathPrefix() + folderName; + + SYSTEMTIME systemTime; + FILETIME fileTime; + ::GetSystemTime(&systemTime); + ::SystemTimeToFileTime(&systemTime, &fileTime); + dirItem.LastAccessTime = dirItem.LastWriteTime = + dirItem.CreationTime = fileTime; + + dirItems.Add(dirItem); + + updateCallbackSpec->Callback = &updateCallbackAgent; + updateCallbackSpec->DirItems = &dirItems; + updateCallbackSpec->UpdatePairs = &updatePairs; + updateCallbackSpec->Archive = GetArchive(); + return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback); +} + + +HRESULT CAgent::RenameItem( + const wchar_t *newArchiveName, + const UINT32 *indices, UINT32 numItems, + const wchar_t *newItemName, + IFolderArchiveUpdateCallback *updateCallback100) +{ + if (!CanUpdate()) + return E_NOTIMPL; + if (numItems != 1) + return E_INVALIDARG; + CUpdateCallbackAgent updateCallbackAgent; + updateCallbackAgent.Callback = updateCallback100; + CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; + CMyComPtr updateCallback(updateCallbackSpec); + + CUIntVector realIndices; + _agentFolder->GetRealIndices(indices, numItems, realIndices); + + UString fullPrefix = _agentFolder->GetFullPathPrefixPlusPrefix(indices[0]); + UString oldItemPath = fullPrefix + _agentFolder->GetName(indices[0]); + UString newItemPath = fullPrefix + newItemName; + + CObjectVector updatePairs; + int curIndex = 0; + UINT32 numItemsInArchive; + RINOK(GetArchive()->GetNumberOfItems(&numItemsInArchive)); + for (UInt32 i = 0; i < numItemsInArchive; i++) + { + if (curIndex < realIndices.Size()) + if (realIndices[curIndex] == i) + { + CUpdatePair2 updatePair; + updatePair.NewData = false; + updatePair.NewProperties = true; + updatePair.ExistInArchive = true; + updatePair.ExistOnDisk = false; + RINOK(IsArchiveItemAnti(GetArchive(), i, updatePair.IsAnti)); + updatePair.ArchiveItemIndex = i; + updatePair.NewNameIsDefined = true; + + updatePair.NewName = newItemName; + + UString oldFullPath; + RINOK(GetArchiveItemPath(GetArchive(), i, DefaultName, oldFullPath)); + + if (oldItemPath.CompareNoCase(oldFullPath.Left(oldItemPath.Length())) != 0) + return E_INVALIDARG; + + updatePair.NewName = newItemPath + oldFullPath.Mid(oldItemPath.Length()); + updatePairs.Add(updatePair); + curIndex++; + continue; + } + CUpdatePair2 updatePair; + updatePair.NewData = updatePair.NewProperties = false; + updatePair.ExistInArchive = true; + updatePair.ExistOnDisk = false; + updatePair.IsAnti = false; + updatePair.ArchiveItemIndex = i; + updatePairs.Add(updatePair); + } + updateCallbackSpec->Callback = &updateCallbackAgent; + updateCallbackSpec->UpdatePairs = &updatePairs; + updateCallbackSpec->Archive = GetArchive(); + return CommonUpdate(newArchiveName, updatePairs.Size(), updateCallback); +} + +STDMETHODIMP CAgent::SetProperties(const wchar_t **names, + const PROPVARIANT *values, INT32 numProperties) +{ + m_PropNames.Clear(); + m_PropValues.Clear(); + for (int i = 0; i < numProperties; i++) + { + m_PropNames.Add(names[i]); + m_PropValues.Add(values[i]); + } + return S_OK; +} + + diff --git a/CPP/7zip/UI/Agent/AgentProxy.cpp b/CPP/7zip/UI/Agent/AgentProxy.cpp new file mode 100755 index 00000000..42063e67 --- /dev/null +++ b/CPP/7zip/UI/Agent/AgentProxy.cpp @@ -0,0 +1,203 @@ +// AgentProxy.cpp + +#include "StdAfx.h" + +#include "AgentProxy.h" + +#include "Common/MyCom.h" +#include "Windows/PropVariant.h" +#include "Windows/Defs.h" +#include "../Common/OpenArchive.h" + +extern "C" +{ + #include "../../../../C/Sort.h" +} + +using namespace NWindows; + +int CProxyFolder::FindDirSubItemIndex(const UString &name, int &insertPos) const +{ + int left = 0, right = Folders.Size(); + for (;;) + { + if (left == right) + { + insertPos = left; + return -1; + } + int mid = (left + right) / 2; + int compare = name.CompareNoCase(Folders[mid].Name); + if (compare == 0) + return mid; + if (compare < 0) + right = mid; + else + left = mid + 1; + } +} + +int CProxyFolder::FindDirSubItemIndex(const UString &name) const +{ + int insertPos; + return FindDirSubItemIndex(name, insertPos); +} + +void CProxyFolder::AddFileSubItem(UINT32 index, const UString &name) +{ + Files.Add(CProxyFile()); + Files.Back().Name = name; + Files.Back().Index = index; +} + +CProxyFolder* CProxyFolder::AddDirSubItem(UINT32 index, bool leaf, + const UString &name) +{ + int insertPos; + int folderIndex = FindDirSubItemIndex(name, insertPos); + if (folderIndex >= 0) + { + CProxyFolder *item = &Folders[folderIndex]; + if(leaf) + { + item->Index = index; + item->IsLeaf = true; + } + return item; + } + Folders.Insert(insertPos, CProxyFolder()); + CProxyFolder *item = &Folders[insertPos]; + item->Name = name; + item->Index = index; + item->Parent = this; + item->IsLeaf = leaf; + return item; +} + +void CProxyFolder::Clear() +{ + Folders.Clear(); + Files.Clear(); +} + +UString CProxyFolder::GetFullPathPrefix() const +{ + UString result; + const CProxyFolder *current = this; + while (current->Parent != NULL) + { + result = current->Name + UString(L'\\') + result; + current = current->Parent; + } + 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) + realIndices.Add(Index); + int i; + for(i = 0; i < Folders.Size(); i++) + Folders[i].AddRealIndices(realIndices); + for(i = 0; i < Files.Size(); i++) + realIndices.Add(Files[i].Index); +} + +void CProxyFolder::GetRealIndices(const UINT32 *indices, + UINT32 numItems, CUIntVector &realIndices) const +{ + realIndices.Clear(); + for(UINT32 i = 0; i < numItems; i++) + { + int index = indices[i]; + int numDirItems = Folders.Size(); + if (index < numDirItems) + Folders[index].AddRealIndices(realIndices); + else + realIndices.Add(Files[index - numDirItems].Index); + } + HeapSort(&realIndices.Front(), realIndices.Size()); +} + +/////////////////////////////////////////////// +// CProxyArchive + +HRESULT CProxyArchive::Reload(IInArchive *archive, IProgress *progress) +{ + RootFolder.Clear(); + return ReadObjects(archive, progress); +} + +HRESULT CProxyArchive::Load(IInArchive *archive, + const UString &defaultName, + // const FILETIME &defaultTime, + // UINT32 defaultAttributes, + IProgress *progress) +{ + DefaultName = defaultName; + // DefaultTime = defaultTime; + // DefaultAttributes = defaultAttributes; + return Reload(archive, progress); +} + + +HRESULT CProxyArchive::ReadObjects(IInArchive *archiveHandler, IProgress *progress) +{ + UINT32 numItems; + RINOK(archiveHandler->GetNumberOfItems(&numItems)); + if (progress != NULL) + { + UINT64 totalItems = numItems; + RINOK(progress->SetTotal(totalItems)); + } + for(UINT32 i = 0; i < numItems; i++) + { + if (progress != NULL) + { + UINT64 currentItemIndex = i; + RINOK(progress->SetCompleted(¤tItemIndex)); + } + NCOM::CPropVariant propVariantPath; + RINOK(archiveHandler->GetProperty(i, kpidPath, &propVariantPath)); + CProxyFolder *currentItem = &RootFolder; + UString fileName; + if(propVariantPath.vt == VT_EMPTY) + fileName = DefaultName; + else + { + if(propVariantPath.vt != VT_BSTR) + return E_FAIL; + UString filePath = propVariantPath.bstrVal; + + int len = filePath.Length(); + for (int i = 0; i < len; i++) + { + wchar_t c = filePath[i]; + if (c == '\\' || c == '/') + { + currentItem = currentItem->AddDirSubItem((UInt32)(Int32)-1, false, fileName); + fileName.Empty(); + } + else + fileName += c; + } + } + + NCOM::CPropVariant propVariantIsFolder; + bool isFolder; + RINOK(IsArchiveItemFolder(archiveHandler, i, isFolder)); + if(isFolder) + currentItem->AddDirSubItem(i, true, fileName); + else + currentItem->AddFileSubItem(i, fileName); + } + return S_OK; +} + diff --git a/CPP/7zip/UI/Agent/AgentProxy.h b/CPP/7zip/UI/Agent/AgentProxy.h new file mode 100755 index 00000000..9402cfdd --- /dev/null +++ b/CPP/7zip/UI/Agent/AgentProxy.h @@ -0,0 +1,56 @@ +// AgentProxy.h + +#ifndef __AGENT_PROXY_H +#define __AGENT_PROXY_H + +#include "Common/String.h" + +#include "../../Archive/IArchive.h" + +class CProxyFile +{ +public: + UINT32 Index; + UString Name; +}; + +class CProxyFolder: public CProxyFile +{ +public: + CProxyFolder *Parent; + CObjectVector Folders; + CObjectVector Files; + bool IsLeaf; + + 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); + void Clear(); + + UString GetFullPathPrefix() const; + UString GetItemName(UINT32 index) const; + void AddRealIndices(CUIntVector &realIndices) const; + void GetRealIndices(const UINT32 *indices, UINT32 numItems, + CUIntVector &realIndices) const; +}; + +class CProxyArchive +{ + HRESULT ReadObjects(IInArchive *inArchive, IProgress *progress); +public: + UString DefaultName; + // FILETIME DefaultTime; + // UINT32 DefaultAttributes; + CProxyFolder RootFolder; + HRESULT Reload(IInArchive *archive, IProgress *progress); + HRESULT Load(IInArchive *archive, + const UString &defaultName, + // const FILETIME &defaultTime, + // UINT32 defaultAttributes, + IProgress *progress); +}; + +#endif \ No newline at end of file diff --git a/CPP/7zip/UI/Agent/ArchiveFolder.cpp b/CPP/7zip/UI/Agent/ArchiveFolder.cpp new file mode 100755 index 00000000..0ce553dc --- /dev/null +++ b/CPP/7zip/UI/Agent/ArchiveFolder.cpp @@ -0,0 +1,72 @@ +// Zip/ArchiveFolder.cpp + +#include "StdAfx.h" + +#include "Common/ComTry.h" +#include "Common/StringConvert.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" +#include "Windows/PropVariantConversions.h" +#include "Windows/FileDir.h" + +#include "../../Common/FileStreams.h" + +#include "../Common/UpdatePair.h" +#include "../Common/ArchiveExtractCallback.h" + +#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 extractCallback = extractCallbackSpec; + UStringVector pathParts; + CProxyFolder *currentProxyFolder = _proxyFolderItem; + while (currentProxyFolder->Parent) + { + pathParts.Insert(0, currentProxyFolder->Name); + currentProxyFolder = currentProxyFolder->Parent; + } + + CMyComPtr extractCallback2; + { + CMyComPtr callbackWrap = callback; + RINOK(callbackWrap.QueryInterface( + IID_IFolderArchiveExtractCallback, &extractCallback2)); + } + + NExtract::NPathMode::EEnum pathMode = _flatMode ? + NExtract::NPathMode::kNoPathnames : + NExtract::NPathMode::kCurrentPathnames; + + extractCallbackSpec->Init(_agentSpec->GetArchive(), + extractCallback2, + false, + path, + pathMode, + NExtract::NOverwriteMode::kAskBefore, + pathParts, + _agentSpec->DefaultName, + _agentSpec->DefaultTime, + _agentSpec->DefaultAttributes + // ,_agentSpec->_srcDirectoryPrefix + ); + CUIntVector realIndices; + GetRealIndices(indices, numItems, realIndices); + return _agentSpec->GetArchive()->Extract(&realIndices.Front(), + realIndices.Size(), BoolToInt(false), extractCallback); + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::MoveTo(const UINT32 * /* indices */, UINT32 /* numItems */, + const wchar_t * /* path */, IFolderOperationsExtractCallback * /* callback */) +{ + return E_NOTIMPL; +} + diff --git a/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp b/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp new file mode 100755 index 00000000..ce423941 --- /dev/null +++ b/CPP/7zip/UI/Agent/ArchiveFolderOpen.cpp @@ -0,0 +1,98 @@ +// Zip/ArchiveFolder.cpp + +#include "StdAfx.h" + +#include "Agent.h" + +#include "Common/StringConvert.h" + +#include "../Common/OpenArchive.h" + +static const UInt64 kMaxCheckStartPosition = 1 << 20; + +static inline UINT GetCurrentFileCodePage() + { return AreFileApisANSI() ? CP_ACP : CP_OEMCP; } + +void CArchiveFolderManager::LoadFormats() +{ + if (!_formatsLoaded) + ReadArchiverInfoList(_formats); +} + +int CArchiveFolderManager::FindFormat(const UString &type) +{ + // LoadFormats(); + for (int i = 0; i < _formats.Size(); i++) + if (type.CompareNoCase(_formats[i].Name) == 0) + return i; + return -1; +} + +STDMETHODIMP CArchiveFolderManager::OpenFolderFile(const wchar_t *filePath, + IFolderFolder **resultFolder, IProgress *progress) +{ + CMyComPtr openArchiveCallback; + if (progress != 0) + { + CMyComPtr progressWrapper = progress; + progressWrapper.QueryInterface(IID_IArchiveOpenCallback, &openArchiveCallback); + } + CAgent *agent = new CAgent(); + CMyComPtr archive = agent; + RINOK(agent->Open(filePath, NULL, openArchiveCallback)); + return agent->BindToRootFolder(resultFolder); +} + +/* +HRESULT CAgent::FolderReOpen( + IArchiveOpenCallback *openArchiveCallback) +{ + return ReOpenArchive(_archive, _archiveFilePath); +} +*/ + +STDMETHODIMP CArchiveFolderManager::GetTypes(BSTR *types) +{ + LoadFormats(); + UString typesStrings; + for(int i = 0; i < _formats.Size(); i++) + { + const CArchiverInfo &ai = _formats[i]; + if (!ai.Associate) + continue; + if (i != 0) + typesStrings += L' '; + typesStrings += ai.Name; + } + CMyComBSTR valueTemp = typesStrings; + *types = valueTemp.Detach(); + return S_OK; +} + +STDMETHODIMP CArchiveFolderManager::GetExtension(const wchar_t *type, BSTR *extension) +{ + *extension = 0; + int formatIndex = FindFormat(type); + if (formatIndex < 0) + return E_INVALIDARG; + CMyComBSTR valueTemp = _formats[formatIndex].Extensions[0].Ext; + *extension = valueTemp.Detach(); + return S_OK; +} + +STDMETHODIMP CArchiveFolderManager::GetIconPath(const wchar_t *type, BSTR *iconPath) +{ + *iconPath = 0; + int formatIndex = FindFormat(type); + if (formatIndex < 0) + return E_INVALIDARG; + CMyComBSTR iconPathTemp = _formats[formatIndex].FilePath; + *iconPath = iconPathTemp.Detach(); + return S_OK; +} + +STDMETHODIMP CArchiveFolderManager::CreateFolderFile(const wchar_t * /* type */, + const wchar_t * /* filePath */, IProgress * /* progress */) +{ + return E_NOTIMPL; +} diff --git a/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp b/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp new file mode 100755 index 00000000..4d66d86d --- /dev/null +++ b/CPP/7zip/UI/Agent/ArchiveFolderOut.cpp @@ -0,0 +1,215 @@ +// FolderOut.cpp + +#include "StdAfx.h" +#include "Agent.h" + +#include "Common/StringConvert.h" +#include "Common/ComTry.h" +#include "Windows/FileDir.h" + +// #include "../Common/CompressEngineCommon.h" +#include "../Common/ZipRegistry.h" +#include "../Common/UpdateAction.h" +#include "../Common/WorkDir.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDirectory; + +static LPCWSTR kTempArcivePrefix = L"7zA"; + +void CAgentFolder::GetPathParts(UStringVector &pathParts) +{ + pathParts.Clear(); + CMyComPtr folder = this; + for (;;) + { + CMyComPtr newFolder; + folder->BindToParentFolder(&newFolder); + if (newFolder == NULL) + break; + CMyComBSTR name; + folder->GetName(&name); + pathParts.Insert(0, (const wchar_t *)name); + folder = newFolder; + } +} + +HRESULT CAgentFolder::CommonUpdateOperation( + bool deleteOperation, + bool createFolderOperation, + bool renameOperation, + const wchar_t *newItemName, + const NUpdateArchive::CActionSet *actionSet, + const UINT32 *indices, UINT32 numItems, + IFolderArchiveUpdateCallback *updateCallback100) +{ + NWorkDir::CInfo workDirInfo; + ReadWorkDirInfo(workDirInfo); + 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; + + /* + if (SetOutProperties(anOutArchive, aCompressionInfo.Method) != S_OK) + return NFileOperationReturnCode::kError; + */ + + //////////////////////////// + // Save FolderItem; + + UStringVector pathParts; + GetPathParts(pathParts); + + HRESULT result; + if (deleteOperation) + result = _agentSpec->DeleteItems(tempFileName, + indices, numItems, updateCallback100); + else if (createFolderOperation) + { + 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->DoOperation(NULL, NULL, + tempFileName, actionSetByte, NULL, updateCallback100); + } + + if (result != S_OK) + return result; + + _agentSpec->Close(); + + // m_FolderItem = NULL; + + if (!DeleteFileAlways(archiveFilePath )) + return GetLastError(); + + tempFile.DisableDeleting(); + if (!MyMoveFile(tempFileName, archiveFilePath )) + return GetLastError(); + + RINOK(_agentSpec->ReOpen(NULL)); + + //////////////////////////// + // Restore FolderItem; + + CMyComPtr archiveFolder; + RINOK(_agentSpec->BindToRootFolder(&archiveFolder)); + for (int i = 0; i < pathParts.Size(); i++) + { + CMyComPtr newFolder; + archiveFolder->BindToFolder(pathParts[i], &newFolder); + if(!newFolder) + break; + archiveFolder = newFolder; + } + + CMyComPtr archiveFolderInternal; + RINOK(archiveFolder.QueryInterface(IID_IArchiveFolderInternal, &archiveFolderInternal)); + CAgentFolder *agentFolder; + RINOK(archiveFolderInternal->GetAgentFolder(&agentFolder)); + _proxyFolderItem = agentFolder->_proxyFolderItem; + _proxyArchive = agentFolder->_proxyArchive; + _parentFolder = agentFolder->_parentFolder; + + return S_OK; +} + +STDMETHODIMP CAgentFolder::CopyFrom( + const wchar_t *fromFolderPath, // test it + const wchar_t **itemsPaths, + UINT32 numItems, + IProgress *progress) +{ + COM_TRY_BEGIN + RINOK(_agentSpec->SetFiles(fromFolderPath, itemsPaths, numItems)); + RINOK(_agentSpec->SetFolder(this)); + CMyComPtr updateCallback100; + if (progress != 0) + { + CMyComPtr progressWrapper = progress; + RINOK(progressWrapper.QueryInterface( + IID_IFolderArchiveUpdateCallback, &updateCallback100)); + } + return CommonUpdateOperation(false, false, false, NULL, + &NUpdateArchive::kAddActionSet, 0, 0, updateCallback100); + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::Delete(const UINT32 *indices, UINT32 numItems, IProgress *progress) +{ + COM_TRY_BEGIN + RINOK(_agentSpec->SetFolder(this)); + CMyComPtr updateCallback100; + if (progress != 0) + { + CMyComPtr progressWrapper = progress; + RINOK(progressWrapper.QueryInterface( + IID_IFolderArchiveUpdateCallback, &updateCallback100)); + } + return CommonUpdateOperation(true, false, false, NULL, + &NUpdateArchive::kDeleteActionSet, indices, numItems, updateCallback100); + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::CreateFolder(const wchar_t *name, IProgress *progress) +{ + COM_TRY_BEGIN + if (_proxyFolderItem->FindDirSubItemIndex(name) >= 0) + return ERROR_ALREADY_EXISTS; + RINOK(_agentSpec->SetFolder(this)); + CMyComPtr updateCallback100; + if (progress != 0) + { + CMyComPtr progressWrapper = progress; + RINOK(progressWrapper.QueryInterface(IID_IFolderArchiveUpdateCallback, &updateCallback100)); + } + return CommonUpdateOperation(false, true, false, name, NULL, NULL, 0, updateCallback100); + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::Rename(UINT32 index, const wchar_t *newName, IProgress *progress) +{ + COM_TRY_BEGIN + CUIntVector indices; + indices.Add(index); + RINOK(_agentSpec->SetFolder(this)); + CMyComPtr updateCallback100; + if (progress != 0) + { + CMyComPtr progressWrapper = progress; + RINOK(progressWrapper.QueryInterface(IID_IFolderArchiveUpdateCallback, &updateCallback100)); + } + return CommonUpdateOperation(false, false, true, newName, NULL, &indices.Front(), + indices.Size(), updateCallback100); + COM_TRY_END +} + +STDMETHODIMP CAgentFolder::CreateFile(const wchar_t * /* name */, IProgress * /* progress */) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CAgentFolder::SetProperty(UINT32 /* index */, PROPID /* propID */, + const PROPVARIANT * /* value */, IProgress * /* progress */) +{ + return E_NOTIMPL; +} diff --git a/CPP/7zip/UI/Agent/IFolderArchive.h b/CPP/7zip/UI/Agent/IFolderArchive.h new file mode 100755 index 00000000..41d9eb22 --- /dev/null +++ b/CPP/7zip/UI/Agent/IFolderArchive.h @@ -0,0 +1,90 @@ +// IFolderArchive.h + +#ifndef __IFOLDER_ARCHIVE_H +#define __IFOLDER_ARCHIVE_H + +#include "../../Archive/IArchive.h" +// #include "../Format/Common/ArchiveInterface.h" +#include "../../FileManager/IFolder.h" +#include "../Common/IFileExtractCallback.h" +#include "../Common/ExtractMode.h" + +// {23170F69-40C1-278A-0000-000100050000} +DEFINE_GUID(IID_IArchiveFolder, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000100050000") +IArchiveFolder: public IUnknown +{ +public: + STDMETHOD(Extract)(const UINT32 *indices, UINT32 numItems, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const wchar_t *path, + INT32 testMode, + IFolderArchiveExtractCallback *extractCallback2) PURE; +}; + +// {23170F69-40C1-278A-0000-000100060000} +DEFINE_GUID(IID_IInFolderArchive, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000100060000") +IInFolderArchive: public IUnknown +{ +public: + STDMETHOD(Open)(const wchar_t *filePath, + // CLSID *clsIDResult, + BSTR *archiveType, + IArchiveOpenCallback *openArchiveCallback) PURE; + STDMETHOD(ReOpen)( + // const wchar_t *filePath, + IArchiveOpenCallback *openArchiveCallback) PURE; + STDMETHOD(Close)() PURE; + STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value) PURE; + STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties) PURE; + STDMETHOD(GetPropertyInfo)(UINT32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) PURE; + STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties) PURE; + STDMETHOD(GetArchivePropertyInfo)(UINT32 index, + BSTR *name, PROPID *propID, VARTYPE *varType) PURE; + STDMETHOD(BindToRootFolder)(IFolderFolder **resultFolder) PURE; + STDMETHOD(Extract)( + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const wchar_t *path, + INT32 testMode, + IFolderArchiveExtractCallback *extractCallback2) PURE; +}; + +// {23170F69-40C1-278A-0000-0001000B0000} +DEFINE_GUID(IID_IFolderArchiveUpdateCallback, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0B, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-0001000B0000") +IFolderArchiveUpdateCallback: public IProgress +{ +public: + STDMETHOD(CompressOperation)(const wchar_t *name) PURE; + STDMETHOD(DeleteOperation)(const wchar_t *name) PURE; + STDMETHOD(OperationResult)(INT32 operationResult) PURE; + STDMETHOD(UpdateErrorMessage)(const wchar_t *message) PURE; +}; + +// {23170F69-40C1-278A-0000-0001000A0000} +DEFINE_GUID(IID_IOutFolderArchive, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-0001000A0000") +IOutFolderArchive: public IUnknown +{ + STDMETHOD(SetFolder)(IFolderFolder *folder) PURE; + STDMETHOD(SetFiles)(const wchar_t *folderPrefix, const wchar_t **names, UINT32 numNames) PURE; + STDMETHOD(DeleteItems)(const wchar_t *newArchiveName, + const UINT32 *indices, UINT32 numItems, IFolderArchiveUpdateCallback *updateCallback) PURE; + STDMETHOD(DoOperation)( + const wchar_t *filePath, + const CLSID *clsID, + const wchar_t *newArchiveName, + const Byte *stateActions, + const wchar_t *sfxModule, + IFolderArchiveUpdateCallback *updateCallback) PURE; +}; + +#endif diff --git a/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp b/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp new file mode 100755 index 00000000..0d57307c --- /dev/null +++ b/CPP/7zip/UI/Agent/UpdateCallbackAgent.cpp @@ -0,0 +1,80 @@ +// UpdateCallbackAgent.h + +#include "StdAfx.h" + +#include "Windows/Error.h" + +#include "UpdateCallbackAgent.h" + +using namespace NWindows; + +HRESULT CUpdateCallbackAgent::SetTotal(UINT64 size) +{ + if (Callback) + return Callback->SetTotal(size); + return S_OK; +} + +HRESULT CUpdateCallbackAgent::SetCompleted(const UINT64 *completeValue) +{ + if (Callback) + return Callback->SetCompleted(completeValue); + return S_OK; +} + +HRESULT CUpdateCallbackAgent::CheckBreak() +{ + return S_OK; +} + +HRESULT CUpdateCallbackAgent::Finilize() +{ + return S_OK; +} + +HRESULT CUpdateCallbackAgent::OpenFileError(const wchar_t *name, DWORD systemError) +{ + // if (systemError == ERROR_SHARING_VIOLATION) + { + if (Callback) + { + RINOK(Callback->UpdateErrorMessage( + UString(L"WARNING: ") + + NError::MyFormatMessageW(systemError) + + UString(L": ") + + UString(name))); + return S_FALSE; + } + } + // FailedFiles.Add(name); + return systemError; +} + +HRESULT CUpdateCallbackAgent::GetStream(const wchar_t *name, bool /* isAnti */) +{ + if (Callback) + return Callback->CompressOperation(name); + return S_OK; +} + +HRESULT CUpdateCallbackAgent::SetOperationResult(INT32 operationResult) +{ + if (Callback) + return Callback->OperationResult(operationResult); + return S_OK; +} + +HRESULT CUpdateCallbackAgent::CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password) +{ + *passwordIsDefined = BoolToInt(false); + if (!_cryptoGetTextPassword) + { + if (!Callback) + return S_OK; + HRESULT result = Callback.QueryInterface( + IID_ICryptoGetTextPassword2, &_cryptoGetTextPassword); + if (result != S_OK) + return S_OK; + } + return _cryptoGetTextPassword->CryptoGetTextPassword2(passwordIsDefined, password); +} diff --git a/CPP/7zip/UI/Agent/UpdateCallbackAgent.h b/CPP/7zip/UI/Agent/UpdateCallbackAgent.h new file mode 100755 index 00000000..1cff501a --- /dev/null +++ b/CPP/7zip/UI/Agent/UpdateCallbackAgent.h @@ -0,0 +1,24 @@ +// UpdateCallbackAgent.h + +#ifndef __UPDATECALLBACKAGENT_H +#define __UPDATECALLBACKAGENT_H + +#include "../Common/UpdateCallback.h" +#include "IFolderArchive.h" + +class CUpdateCallbackAgent: public IUpdateCallbackUI +{ + virtual HRESULT SetTotal(UINT64 size); + virtual HRESULT SetCompleted(const UINT64 *completeValue); + virtual HRESULT CheckBreak(); + virtual HRESULT Finilize(); + virtual HRESULT GetStream(const wchar_t *name, bool isAnti); + virtual HRESULT OpenFileError(const wchar_t *name, DWORD systemError); + virtual HRESULT SetOperationResult(INT32 operationResult); + virtual HRESULT CryptoGetTextPassword2(INT32 *passwordIsDefined, BSTR *password); + CMyComPtr _cryptoGetTextPassword; +public: + CMyComPtr Callback; +}; + +#endif diff --git a/CPP/7zip/UI/Client7z/Client7z.cpp b/CPP/7zip/UI/Client7z/Client7z.cpp new file mode 100755 index 00000000..46bdb727 --- /dev/null +++ b/CPP/7zip/UI/Client7z/Client7z.cpp @@ -0,0 +1,850 @@ +// Client7z.cpp + +#include "StdAfx.h" + +#include + +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "../../Common/FileStreams.h" +#include "../../Archive/IArchive.h" +#include "../../IPassword.h" + +#include "Windows/PropVariant.h" +#include "Windows/PropVariantConversions.h" +#include "Windows/DLL.h" +#include "Windows/FileDir.h" +#include "Windows/FileName.h" +#include "Windows/FileFind.h" + +// {23170F69-40C1-278A-1000-000110070000} +DEFINE_GUID(CLSID_CFormat7z, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00); + +using namespace NWindows; + +static const char *kCopyrightString = "7-Zip 4.43 (7za.DLL client example) (c) 1999-2006 Igor Pavlov 2006-08-10\n"; +static const char *kHelpString = +"Usage: Client7z.exe [a | l | x ] archive.7z [fileName ...]\n" +"Examples:\n" +" Client7z.exe a archive.7z f1.txt f2.txt : compress two files to archive.7z\n" +" Client7z.exe l archive.7z : List contents of archive.7z\n" +" Client7z.exe x archive.7z : eXtract files from archive.7z\n"; + + +typedef UINT32 (WINAPI * CreateObjectFunc)( + const GUID *clsID, + const GUID *interfaceID, + void **outObject); + +#ifndef _UNICODE +bool g_IsNT = false; +static inline bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + +void PrintString(const UString &s) +{ + printf("%s", (LPCSTR)GetOemString(s)); +} + +void PrintString(const AString &s) +{ + printf("%s", s); +} + +void PrintNewLine() +{ + PrintString("\n"); +} + +void PrintStringLn(const AString &s) +{ + PrintString(s); + PrintNewLine(); +} + +static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result) +{ + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, propID, &prop)); + if(prop.vt == VT_BOOL) + result = VARIANT_BOOLToBool(prop.boolVal); + else if (prop.vt == VT_EMPTY) + result = false; + else + return E_FAIL; + return S_OK; +} + +static HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result) +{ + return IsArchiveItemProp(archive, index, kpidIsFolder, result); +} + + +static const wchar_t *kEmptyFileAlias = L"[Content]"; + + +////////////////////////////////////////////////////////////// +// Archive Open callback class + + +class CArchiveOpenCallback: + public IArchiveOpenCallback, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(ICryptoGetTextPassword) + + STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes); + STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes); + + STDMETHOD(CryptoGetTextPassword)(BSTR *password); + + bool PasswordIsDefined; + UString Password; + + CArchiveOpenCallback() : PasswordIsDefined(false) {} +}; + +STDMETHODIMP CArchiveOpenCallback::SetTotal(const UInt64 *files, const UInt64 *bytes) +{ + return S_OK; +} + +STDMETHODIMP CArchiveOpenCallback::SetCompleted(const UInt64 *files, const UInt64 *bytes) +{ + return S_OK; +} + +STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password) +{ + if (!PasswordIsDefined) + { + // You can ask real password here from user + // Password = GetPassword(OutStream); + // PasswordIsDefined = true; + PrintStringLn("Password is not defined"); + return E_ABORT; + } + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} + + +////////////////////////////////////////////////////////////// +// 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 "; + +static const char *kUnsupportedMethod = "Unsupported Method"; +static const char *kCRCFailed = "CRC Failed"; +static const char *kDataError = "Data Error"; +static const char *kUnknownError = "Unknown Error"; + +class CArchiveExtractCallback: + public IArchiveExtractCallback, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(ICryptoGetTextPassword) + + // IProgress + STDMETHOD(SetTotal)(UInt64 size); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); + + // IArchiveExtractCallback + STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode); + STDMETHOD(PrepareOperation)(Int32 askExtractMode); + STDMETHOD(SetOperationResult)(Int32 resultEOperationResult); + + // ICryptoGetTextPassword + STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword); + +private: + CMyComPtr _archiveHandler; + UString _directoryPath; // Output directory + UString _filePath; // name inside arcvhive + UString _diskFilePath; // full path to file on disk + bool _extractMode; + struct CProcessedFileInfo + { + FILETIME UTCLastWriteTime; + UInt32 Attributes; + bool IsDirectory; + bool AttributesAreDefined; + bool UTCLastWriteTimeIsDefined; + } _processedFileInfo; + + COutFileStream *_outFileStreamSpec; + CMyComPtr _outFileStream; + +public: + void Init(IInArchive *archiveHandler, const UString &directoryPath); + + UInt64 NumErrors; + bool PasswordIsDefined; + UString Password; + + CArchiveExtractCallback() : PasswordIsDefined(false) {} +}; + +void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const UString &directoryPath) +{ + NumErrors = 0; + _archiveHandler = archiveHandler; + _directoryPath = directoryPath; + NFile::NName::NormalizeDirPathPrefix(_directoryPath); +} + +STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size) +{ + return S_OK; +} + +STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue) +{ + return S_OK; +} + +STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, + ISequentialOutStream **outStream, Int32 askExtractMode) +{ + *outStream = 0; + _outFileStream.Release(); + + { + // Get Name + NCOM::CPropVariant propVariant; + RINOK(_archiveHandler->GetProperty(index, kpidPath, &propVariant)); + + UString fullPath; + if(propVariant.vt == VT_EMPTY) + fullPath = kEmptyFileAlias; + else + { + if(propVariant.vt != VT_BSTR) + return E_FAIL; + fullPath = propVariant.bstrVal; + } + _filePath = fullPath; + } + + { + // Get Attributes + NCOM::CPropVariant propVariant; + RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &propVariant)); + if (propVariant.vt == VT_EMPTY) + { + _processedFileInfo.Attributes = 0; + _processedFileInfo.AttributesAreDefined = false; + } + else + { + if (propVariant.vt != VT_UI4) + throw "incorrect item"; + _processedFileInfo.Attributes = propVariant.ulVal; + _processedFileInfo.AttributesAreDefined = true; + } + } + + RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.IsDirectory)); + + { + // Get Modified Time + NCOM::CPropVariant propVariant; + RINOK(_archiveHandler->GetProperty(index, kpidLastWriteTime, &propVariant)); + _processedFileInfo.UTCLastWriteTimeIsDefined = false; + switch(propVariant.vt) + { + case VT_EMPTY: + // _processedFileInfo.UTCLastWriteTime = _utcLastWriteTimeDefault; + break; + case VT_FILETIME: + _processedFileInfo.UTCLastWriteTime = propVariant.filetime; + _processedFileInfo.UTCLastWriteTimeIsDefined = true; + break; + default: + return E_FAIL; + } + + } + { + // Get Size + NCOM::CPropVariant propVariant; + RINOK(_archiveHandler->GetProperty(index, kpidSize, &propVariant)); + bool newFileSizeDefined = (propVariant.vt != VT_EMPTY); + UInt64 newFileSize; + if (newFileSizeDefined) + newFileSize = ConvertPropVariantToUInt64(propVariant); + } + + + { + // Create folders for file + int slashPos = _filePath.ReverseFind(WCHAR_PATH_SEPARATOR); + if (slashPos >= 0) + NFile::NDirectory::CreateComplexDirectory(_directoryPath + _filePath.Left(slashPos)); + } + + UString fullProcessedPath = _directoryPath + _filePath; + _diskFilePath = fullProcessedPath; + + if (_processedFileInfo.IsDirectory) + { + NFile::NDirectory::CreateComplexDirectory(fullProcessedPath); + } + else + { + NFile::NFind::CFileInfoW fileInfo; + if(NFile::NFind::FindFile(fullProcessedPath, fileInfo)) + { + if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath)) + { + PrintString(UString(kCantDeleteOutputFile) + fullProcessedPath); + return E_ABORT; + } + } + + _outFileStreamSpec = new COutFileStream; + CMyComPtr outStreamLoc(_outFileStreamSpec); + if (!_outFileStreamSpec->File.Open(fullProcessedPath, CREATE_ALWAYS)) + { + PrintString((UString)L"can not open output file " + fullProcessedPath); + return E_ABORT; + } + _outFileStream = outStreamLoc; + *outStream = outStreamLoc.Detach(); + } + return S_OK; +} + +STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode) +{ + _extractMode = false; + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: + _extractMode = true; + }; + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: + PrintString(kExtractingString); + break; + case NArchive::NExtract::NAskMode::kTest: + PrintString(kTestingString); + break; + case NArchive::NExtract::NAskMode::kSkip: + PrintString(kSkippingString); + break; + }; + PrintString(_filePath); + return S_OK; +} + +STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult) +{ + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kOK: + break; + default: + { + NumErrors++; + PrintString(" "); + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kUnSupportedMethod: + PrintString(kUnsupportedMethod); + break; + case NArchive::NExtract::NOperationResult::kCRCError: + PrintString(kCRCFailed); + break; + case NArchive::NExtract::NOperationResult::kDataError: + PrintString(kDataError); + break; + default: + PrintString(kUnknownError); + } + } + } + + if(_outFileStream != NULL && _processedFileInfo.UTCLastWriteTimeIsDefined) + _outFileStreamSpec->File.SetLastWriteTime(&_processedFileInfo.UTCLastWriteTime); + _outFileStream.Release(); + if (_extractMode && _processedFileInfo.AttributesAreDefined) + NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes); + PrintNewLine(); + return S_OK; +} + + +STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password) +{ + if (!PasswordIsDefined) + { + // You can ask real password here from user + // Password = GetPassword(OutStream); + // PasswordIsDefined = true; + PrintStringLn("Password is not defined"); + return E_ABORT; + } + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} + + + +////////////////////////////////////////////////////////////// +// Archive Creating callback class + +struct CDirItem +{ + UInt32 Attributes; + FILETIME CreationTime; + FILETIME LastAccessTime; + FILETIME LastWriteTime; + UInt64 Size; + UString Name; + UString FullPath; + bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ; } +}; + +class CArchiveUpdateCallback: + public IArchiveUpdateCallback2, + public ICryptoGetTextPassword2, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2) + + // IProgress + STDMETHOD(SetTotal)(UInt64 size); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); + + // IUpdateCallback2 + STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator); + STDMETHOD(GetUpdateItemInfo)(UInt32 index, + Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream); + STDMETHOD(SetOperationResult)(Int32 operationResult); + STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size); + STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream); + + STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password); + +public: + CRecordVector VolumesSizes; + UString VolName; + UString VolExt; + + UString DirPrefix; + const CObjectVector *DirItems; + + bool PasswordIsDefined; + UString Password; + bool AskPassword; + + bool m_NeedBeClosed; + + UStringVector FailedFiles; + CRecordVector FailedCodes; + + CArchiveUpdateCallback(): PasswordIsDefined(false), AskPassword(false), DirItems(0) {}; + + ~CArchiveUpdateCallback() { Finilize(); } + HRESULT Finilize(); + + void Init(const CObjectVector *dirItems) + { + DirItems = dirItems; + m_NeedBeClosed = false; + FailedFiles.Clear(); + FailedCodes.Clear(); + } +}; + +STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size) +{ + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue) +{ + return S_OK; +} + + +STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **enumerator) +{ + return E_NOTIMPL; +} + +STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index, + Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive) +{ + if(newData != NULL) + *newData = BoolToInt(true); + if(newProperties != NULL) + *newProperties = BoolToInt(true); + if(indexInArchive != NULL) + *indexInArchive = UInt32(-1); + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + + if (propID == kpidIsAnti) + { + propVariant = false; + propVariant.Detach(value); + return S_OK; + } + + { + const CDirItem &dirItem = (*DirItems)[index]; + switch(propID) + { + case kpidPath: + propVariant = dirItem.Name; + break; + case kpidIsFolder: + propVariant = dirItem.IsDirectory(); + break; + case kpidSize: + propVariant = dirItem.Size; + break; + case kpidAttributes: + propVariant = dirItem.Attributes; + break; + case kpidLastAccessTime: + propVariant = dirItem.LastAccessTime; + break; + case kpidCreationTime: + propVariant = dirItem.CreationTime; + break; + case kpidLastWriteTime: + propVariant = dirItem.LastWriteTime; + break; + } + } + propVariant.Detach(value); + return S_OK; +} + +HRESULT CArchiveUpdateCallback::Finilize() +{ + if (m_NeedBeClosed) + { + PrintNewLine(); + m_NeedBeClosed = false; + } + return S_OK; +} + +static void GetStream2(const wchar_t *name) +{ + PrintString("Compressing "); + if (name[0] == 0) + name = kEmptyFileAlias; + PrintString(name); +} + +STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream) +{ + RINOK(Finilize()); + + const CDirItem &dirItem = (*DirItems)[index]; + GetStream2(dirItem.Name); + + if(dirItem.IsDirectory()) + return S_OK; + + { + CInFileStream *inStreamSpec = new CInFileStream; + CMyComPtr inStreamLoc(inStreamSpec); + UString path = DirPrefix + dirItem.FullPath; + if(!inStreamSpec->Open(path)) + { + DWORD sysError = ::GetLastError(); + FailedCodes.Add(sysError); + FailedFiles.Add(path); + // if (systemError == ERROR_SHARING_VIOLATION) + { + PrintNewLine(); + PrintStringLn("WARNING: can't open file"); + // PrintString(NError::MyFormatMessageW(systemError)); + return S_FALSE; + } + // return sysError; + } + *inStream = inStreamLoc.Detach(); + } + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult) +{ + m_NeedBeClosed = true; + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size) +{ + if (VolumesSizes.Size() == 0) + return S_FALSE; + if (index >= (UInt32)VolumesSizes.Size()) + index = VolumesSizes.Size() - 1; + *size = VolumesSizes[index]; + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream) +{ + wchar_t temp[32]; + ConvertUInt64ToString(index + 1, temp); + UString res = temp; + while (res.Length() < 2) + res = UString(L'0') + res; + UString fileName = VolName; + fileName += L'.'; + fileName += res; + fileName += VolExt; + COutFileStream *streamSpec = new COutFileStream; + CMyComPtr streamLoc(streamSpec); + if(!streamSpec->Create(fileName, false)) + return ::GetLastError(); + *volumeStream = streamLoc.Detach(); + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +{ + if (!PasswordIsDefined) + { + if (AskPassword) + { + // You can ask real password here from user + // Password = GetPassword(OutStream); + // PasswordIsDefined = true; + PrintStringLn("Password is not defined"); + return E_ABORT; + } + } + *passwordIsDefined = BoolToInt(PasswordIsDefined); + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} + + + +////////////////////////////////////////////////////////////////////////// +// Main function + +int +#ifdef _MSC_VER +__cdecl +#endif +main(int argc, char* argv[]) +{ + #ifndef _UNICODE + g_IsNT = IsItWindowsNT(); + #endif + + PrintStringLn(kCopyrightString); + + if (argc < 3) + { + PrintStringLn(kHelpString); + return 1; + } + NWindows::NDLL::CLibrary library; + if (!library.Load(TEXT("7za.dll"))) + { + PrintStringLn("Can not load library"); + return 1; + } + CreateObjectFunc createObjectFunc = (CreateObjectFunc)library.GetProcAddress("CreateObject"); + if (createObjectFunc == 0) + { + PrintStringLn("Can not get CreateObject"); + return 1; + } + + AString command = argv[1]; + UString archiveName = GetUnicodeString(argv[2], CP_OEMCP); + if (command.CompareNoCase("a") == 0) + { + // create archive command + if (argc < 4) + { + PrintStringLn(kHelpString); + return 1; + } + CObjectVector dirItems; + int i; + for (i = 3; i < argc; i++) + { + CDirItem item; + UString name = GetUnicodeString(argv[i], CP_OEMCP); + + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(name, fileInfo)) + { + PrintString(UString(L"Can't find file") + name); + return 1; + } + + item.Attributes = fileInfo.Attributes; + item.Size = fileInfo.Size; + item.CreationTime = fileInfo.CreationTime; + item.LastAccessTime = fileInfo.LastAccessTime; + item.LastWriteTime = fileInfo.LastWriteTime; + item.Name = name; + item.FullPath = name; + dirItems.Add(item); + } + COutFileStream *outFileStreamSpec = new COutFileStream; + CMyComPtr outFileStream = outFileStreamSpec; + if (!outFileStreamSpec->Create(archiveName, false)) + { + PrintStringLn("can't create archive file"); + return 1; + } + + CMyComPtr outArchive; + if (createObjectFunc(&CLSID_CFormat7z, &IID_IOutArchive, (void **)&outArchive) != S_OK) + { + PrintStringLn("Can not get class object"); + return 1; + } + + CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; + CMyComPtr updateCallback(updateCallbackSpec); + updateCallbackSpec->Init(&dirItems); + // updateCallbackSpec->PasswordIsDefined = true; + // updateCallbackSpec->Password = L"1"; + + HRESULT result = outArchive->UpdateItems(outFileStream, dirItems.Size(), updateCallback); + updateCallbackSpec->Finilize(); + if (result != S_OK) + { + PrintStringLn("Update Error"); + return 1; + } + for (i = 0; i < updateCallbackSpec->FailedFiles.Size(); i++) + { + PrintNewLine(); + PrintString((UString)L"Error for file: " + updateCallbackSpec->FailedFiles[i]); + } + if (updateCallbackSpec->FailedFiles.Size() != 0) + return 1; + } + else + { + if (argc != 3) + { + PrintStringLn(kHelpString); + return 1; + } + + bool listCommand; + if (command.CompareNoCase("l") == 0) + listCommand = true; + else if (command.CompareNoCase("x") == 0) + listCommand = false; + else + { + PrintStringLn("incorrect command"); + return 1; + } + + CMyComPtr archive; + if (createObjectFunc(&CLSID_CFormat7z, &IID_IInArchive, (void **)&archive) != S_OK) + { + PrintStringLn("Can not get class object"); + return 1; + } + + CInFileStream *fileSpec = new CInFileStream; + CMyComPtr file = fileSpec; + + if (!fileSpec->Open(archiveName)) + { + PrintStringLn("Can not open archive file"); + return 1; + } + + { + CArchiveOpenCallback *openCallbackSpec = new CArchiveOpenCallback; + CMyComPtr openCallback(openCallbackSpec); + openCallbackSpec->PasswordIsDefined = false; + // openCallbackSpec->PasswordIsDefined = true; + // openCallbackSpec->Password = L"1"; + + if (archive->Open(file, 0, openCallback) != S_OK) + { + PrintStringLn("Can not open archive"); + return 1; + } + } + + if (listCommand) + { + // List command + UInt32 numItems = 0; + archive->GetNumberOfItems(&numItems); + for (UInt32 i = 0; i < numItems; i++) + { + { + // Get uncompressed size of file + NWindows::NCOM::CPropVariant propVariant; + archive->GetProperty(i, kpidSize, &propVariant); + UString s = ConvertPropVariantToString(propVariant); + PrintString(s); + PrintString(" "); + } + { + // Get name of file + NWindows::NCOM::CPropVariant propVariant; + archive->GetProperty(i, kpidPath, &propVariant); + UString s = ConvertPropVariantToString(propVariant); + PrintString(s); + } + PrintString("\n"); + } + } + else + { + // Extract command + CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; + CMyComPtr extractCallback(extractCallbackSpec); + extractCallbackSpec->Init(archive, L""); // second parameter is output folder path + extractCallbackSpec->PasswordIsDefined = false; + // extractCallbackSpec->PasswordIsDefined = true; + // extractCallbackSpec->Password = L"1"; + archive->Extract(0, (UInt32)(Int32)(-1), false, extractCallback); + } + } + return 0; +} diff --git a/CPP/7zip/UI/Client7z/Client7z.dsp b/CPP/7zip/UI/Client7z/Client7z.dsp new file mode 100755 index 00000000..b574bdb7 --- /dev/null +++ b/CPP/7zip/UI/Client7z/Client7z.dsp @@ -0,0 +1,226 @@ +# Microsoft Developer Studio Project File - Name="Client7z" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Client7z - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Client7z.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Client7z.mak" CFG="Client7z - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Client7z - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Client7z - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Client7z - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "Client7z - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Client7z - Win32 Release" +# Name "Client7z - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.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\PropVariantConversions.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "7zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\Client7z.cpp +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/UI/Client7z/Client7z.dsw b/CPP/7zip/UI/Client7z/Client7z.dsw new file mode 100755 index 00000000..598a6d3f --- /dev/null +++ b/CPP/7zip/UI/Client7z/Client7z.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Client7z"=.\Client7z.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/UI/Client7z/StdAfx.cpp b/CPP/7zip/UI/Client7z/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/UI/Client7z/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/UI/Client7z/StdAfx.h b/CPP/7zip/UI/Client7z/StdAfx.h new file mode 100755 index 00000000..b23436e9 --- /dev/null +++ b/CPP/7zip/UI/Client7z/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include +#include + +#endif diff --git a/CPP/7zip/UI/Client7z/makefile b/CPP/7zip/UI/Client7z/makefile new file mode 100755 index 00000000..c4ae0aaf --- /dev/null +++ b/CPP/7zip/UI/Client7z/makefile @@ -0,0 +1,45 @@ +PROG = 7z.exe +LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib +CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT + +CONSOLE_OBJS = \ + $O\Client7z.obj \ + +COMMON_OBJS = \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\PropVariant.obj \ + $O\PropVariantConversions.obj \ + +7ZIP_COMMON_OBJS = \ + $O\FileStreams.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(CONSOLE_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + +!include "../../../Build.mak" + +$(CONSOLE_OBJS): $(*B).cpp + $(COMPL_O1_W3) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.cpp b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp new file mode 100755 index 00000000..6f951a27 --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiveCommandLine.cpp @@ -0,0 +1,985 @@ +// ArchiveCommandLine.cpp + +#include "StdAfx.h" + +#include +#include + +#include "Common/ListFileUtils.h" +#include "Common/StringConvert.h" +#include "Common/StringToInt.h" + +#include "Windows/FileName.h" +#include "Windows/FileDir.h" +#ifdef _WIN32 +#include "Windows/FileMapping.h" +#include "Windows/Synchronization.h" +#endif + +#include "ArchiveCommandLine.h" +#include "UpdateAction.h" +#include "Update.h" +#include "ArchiverInfo.h" +#include "SortUtils.h" +#include "EnumDirItems.h" + +using namespace NCommandLineParser; +using namespace NWindows; +using namespace NFile; + +static const int kNumSwitches = 28; + +namespace NKey { +enum Enum +{ + kHelp1 = 0, + kHelp2, + kHelp3, + kDisableHeaders, + kDisablePercents, + kArchiveType, + kYes, + kPassword, + kProperty, + kOutputDir, + kWorkingDir, + kInclude, + kExclude, + kArInclude, + kArExclude, + kNoArName, + kUpdate, + kVolume, + kRecursed, + kSfx, + kStdIn, + kStdOut, + kOverwrite, + kEmail, + kShowDialog, + kLargePages, + kCharSet, + kTechMode +}; + +} + + +static const wchar_t kRecursedIDChar = 'R'; +static const wchar_t *kRecursedPostCharSet = L"0-"; + +static const wchar_t *kDefaultArchiveType = L"7z"; +static const wchar_t *kSFXExtension = + #ifdef _WIN32 + L"exe"; + #else + L""; + #endif + +namespace NRecursedPostCharIndex { + enum EEnum + { + kWildCardRecursionOnly = 0, + kNoRecursion = 1 + }; +} + +static const char kImmediateNameID = '!'; +static const char kMapNameID = '#'; +static const char kFileListID = '@'; + +static const char kSomeCludePostStringMinSize = 2; // at least <@|!>ame must be +static const char kSomeCludeAfterRecursedPostStringMinSize = 2; // at least <@|!>ame must be + +static const wchar_t *kOverwritePostCharSet = L"asut"; + +NExtract::NOverwriteMode::EEnum k_OverwriteModes[] = +{ + NExtract::NOverwriteMode::kWithoutPrompt, + NExtract::NOverwriteMode::kSkipExisting, + NExtract::NOverwriteMode::kAutoRename, + NExtract::NOverwriteMode::kAutoRenameExisting +}; + +static const CSwitchForm kSwitchForms[kNumSwitches] = + { + { L"?", NSwitchType::kSimple, false }, + { L"H", NSwitchType::kSimple, false }, + { L"-HELP", NSwitchType::kSimple, false }, + { L"BA", NSwitchType::kSimple, false }, + { L"BD", NSwitchType::kSimple, false }, + { L"T", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"Y", NSwitchType::kSimple, false }, + { L"P", NSwitchType::kUnLimitedPostString, false, 0 }, + { L"M", NSwitchType::kUnLimitedPostString, true, 1 }, + { L"O", NSwitchType::kUnLimitedPostString, false, 1 }, + { L"W", NSwitchType::kUnLimitedPostString, false, 0 }, + { L"I", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize}, + { L"X", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize}, + { L"AI", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize}, + { L"AX", NSwitchType::kUnLimitedPostString, true, kSomeCludePostStringMinSize}, + { L"AN", NSwitchType::kSimple, false }, + { L"U", NSwitchType::kUnLimitedPostString, true, 1}, + { L"V", NSwitchType::kUnLimitedPostString, true, 1}, + { L"R", NSwitchType::kPostChar, false, 0, 0, kRecursedPostCharSet }, + { L"SFX", NSwitchType::kUnLimitedPostString, false, 0 }, + { L"SI", NSwitchType::kUnLimitedPostString, false, 0 }, + { L"SO", NSwitchType::kSimple, false, 0 }, + { L"AO", NSwitchType::kPostChar, false, 1, 1, kOverwritePostCharSet}, + { L"SEML", NSwitchType::kUnLimitedPostString, false, 0}, + { L"AD", NSwitchType::kSimple, false }, + { L"SLP", NSwitchType::kUnLimitedPostString, false, 0}, + { L"SCS", NSwitchType::kUnLimitedPostString, false, 0}, + { L"SLT", NSwitchType::kSimple, false } + }; + +static const int kNumCommandForms = 7; + +static const CCommandForm g_CommandForms[kNumCommandForms] = +{ + { L"A", false }, + { L"U", false }, + { L"D", false }, + { L"T", false }, + { L"E", false }, + { L"X", false }, + { L"L", false } +}; + +static const int kMaxCmdLineSize = 1000; +static const wchar_t *kUniversalWildcard = L"*"; +static const int kMinNonSwitchWords = 1; +static const int kCommandIndex = 0; + +// --------------------------- +// exception messages + +static const char *kUserErrorMessage = "Incorrect command line"; +static const char *kIncorrectListFile = "Incorrect wildcard in listfile"; +static const char *kIncorrectWildCardInListFile = "Incorrect wildcard in listfile"; +static const char *kIncorrectWildCardInCommandLine = "Incorrect wildcard in command line"; +static const char *kTerminalOutError = "I won't write compressed data to a terminal"; +static const char *kSameTerminalError = "I won't write data and program's messages to same terminal"; + +static void ThrowException(const char *errorMessage) +{ + throw CArchiveCommandLineException(errorMessage); +}; + +static void ThrowUserErrorException() +{ + ThrowException(kUserErrorMessage); +}; + +// --------------------------- + +bool CArchiveCommand::IsFromExtractGroup() const +{ + switch(CommandType) + { + case NCommandType::kTest: + case NCommandType::kExtract: + case NCommandType::kFullExtract: + return true; + default: + return false; + } +} + +NExtract::NPathMode::EEnum CArchiveCommand::GetPathMode() const +{ + switch(CommandType) + { + case NCommandType::kTest: + case NCommandType::kFullExtract: + return NExtract::NPathMode::kFullPathnames; + default: + return NExtract::NPathMode::kNoPathnames; + } +} + +bool CArchiveCommand::IsFromUpdateGroup() const +{ + return (CommandType == NCommandType::kAdd || + CommandType == NCommandType::kUpdate || + CommandType == NCommandType::kDelete); +} + +static NRecursedType::EEnum GetRecursedTypeFromIndex(int index) +{ + switch (index) + { + case NRecursedPostCharIndex::kWildCardRecursionOnly: + return NRecursedType::kWildCardOnlyRecursed; + case NRecursedPostCharIndex::kNoRecursion: + return NRecursedType::kNonRecursed; + default: + return NRecursedType::kRecursed; + } +} + +static bool ParseArchiveCommand(const UString &commandString, CArchiveCommand &command) +{ + UString commandStringUpper = commandString; + commandStringUpper.MakeUpper(); + UString postString; + int commandIndex = ParseCommand(kNumCommandForms, g_CommandForms, commandStringUpper, + postString) ; + if (commandIndex < 0) + return false; + command.CommandType = (NCommandType::EEnum)commandIndex; + return true; +} + +// ------------------------------------------------------------------ +// filenames functions + +static bool AddNameToCensor(NWildcard::CCensor &wildcardCensor, + const UString &name, bool include, NRecursedType::EEnum type) +{ + bool isWildCard = DoesNameContainWildCard(name); + bool recursed = false; + + switch (type) + { + case NRecursedType::kWildCardOnlyRecursed: + recursed = isWildCard; + break; + case NRecursedType::kRecursed: + recursed = true; + break; + case NRecursedType::kNonRecursed: + recursed = false; + break; + } + wildcardCensor.AddItem(include, name, recursed); + return true; +} + +static inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } + +static void AddToCensorFromListFile(NWildcard::CCensor &wildcardCensor, + LPCWSTR fileName, bool include, NRecursedType::EEnum type, UINT codePage) +{ + UStringVector names; + if (!ReadNamesFromListFile(GetSystemString(fileName, GetCurrentCodePage()), names, codePage)) + throw kIncorrectListFile; + for (int i = 0; i < names.Size(); i++) + if (!AddNameToCensor(wildcardCensor, names[i], include, type)) + throw kIncorrectWildCardInListFile; +} + +static void AddCommandLineWildCardToCensr(NWildcard::CCensor &wildcardCensor, + const UString &name, bool include, NRecursedType::EEnum recursedType) +{ + if (!AddNameToCensor(wildcardCensor, name, include, recursedType)) + throw kIncorrectWildCardInCommandLine; +} + +static void AddToCensorFromNonSwitchesStrings( + int startIndex, + NWildcard::CCensor &wildcardCensor, + const UStringVector &nonSwitchStrings, NRecursedType::EEnum type, + bool thereAreSwitchIncludes, UINT codePage) +{ + if(nonSwitchStrings.Size() == startIndex && (!thereAreSwitchIncludes)) + AddCommandLineWildCardToCensr(wildcardCensor, kUniversalWildcard, true, type); + for(int i = startIndex; i < nonSwitchStrings.Size(); i++) + { + const UString &s = nonSwitchStrings[i]; + if (s[0] == kFileListID) + AddToCensorFromListFile(wildcardCensor, s.Mid(1), true, type, codePage); + else + AddCommandLineWildCardToCensr(wildcardCensor, s, true, type); + } +} + +#ifdef _WIN32 +static void ParseMapWithPaths(NWildcard::CCensor &wildcardCensor, + const UString &switchParam, bool include, + NRecursedType::EEnum commonRecursedType) +{ + int splitPos = switchParam.Find(L':'); + if (splitPos < 0) + ThrowUserErrorException(); + UString mappingName = switchParam.Left(splitPos); + + UString switchParam2 = switchParam.Mid(splitPos + 1); + splitPos = switchParam2.Find(L':'); + if (splitPos < 0) + ThrowUserErrorException(); + + UString mappingSize = switchParam2.Left(splitPos); + UString eventName = switchParam2.Mid(splitPos + 1); + + UInt64 dataSize64 = ConvertStringToUInt64(mappingSize, NULL); + UInt32 dataSize = (UInt32)dataSize64; + { + CFileMapping fileMapping; + if (!fileMapping.Open(FILE_MAP_READ, false, GetSystemString(mappingName))) + ThrowException("Can not open mapping"); + LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_READ, 0, dataSize); + if (data == NULL) + ThrowException("MapViewOfFile error"); + try + { + const wchar_t *curData = (const wchar_t *)data; + if (*curData != 0) + ThrowException("Incorrect mapping data"); + UInt32 numChars = dataSize / sizeof(wchar_t); + UString name; + for (UInt32 i = 1; i < numChars; i++) + { + wchar_t c = curData[i]; + if (c == L'\0') + { + AddCommandLineWildCardToCensr(wildcardCensor, + name, include, commonRecursedType); + name.Empty(); + } + else + name += c; + } + if (!name.IsEmpty()) + ThrowException("data error"); + } + catch(...) + { + UnmapViewOfFile(data); + throw; + } + UnmapViewOfFile(data); + } + + { + NSynchronization::CEvent event; + event.Open(EVENT_MODIFY_STATE, false, GetSystemString(eventName)); + event.Set(); + } +} +#endif + +static void AddSwitchWildCardsToCensor(NWildcard::CCensor &wildcardCensor, + const UStringVector &strings, bool include, + NRecursedType::EEnum commonRecursedType, UINT codePage) +{ + for(int i = 0; i < strings.Size(); i++) + { + const UString &name = strings[i]; + NRecursedType::EEnum recursedType; + int pos = 0; + if (name.Length() < kSomeCludePostStringMinSize) + ThrowUserErrorException(); + if (::MyCharUpper(name[pos]) == kRecursedIDChar) + { + pos++; + int index = UString(kRecursedPostCharSet).Find(name[pos]); + recursedType = GetRecursedTypeFromIndex(index); + if (index >= 0) + pos++; + } + else + recursedType = commonRecursedType; + if (name.Length() < pos + kSomeCludeAfterRecursedPostStringMinSize) + ThrowUserErrorException(); + UString tail = name.Mid(pos + 1); + if (name[pos] == kImmediateNameID) + AddCommandLineWildCardToCensr(wildcardCensor, tail, include, recursedType); + else if (name[pos] == kFileListID) + AddToCensorFromListFile(wildcardCensor, tail, include, recursedType, codePage); + #ifdef _WIN32 + else if (name[pos] == kMapNameID) + ParseMapWithPaths(wildcardCensor, tail, include, recursedType); + #endif + else + ThrowUserErrorException(); + } +} + +#ifdef _WIN32 + +// This code converts all short file names to long file names. + +static void ConvertToLongName(const UString &prefix, UString &name) +{ + if (name.IsEmpty() || DoesNameContainWildCard(name)) + return; + NFind::CFileInfoW fileInfo; + if (NFind::FindFile(prefix + name, fileInfo)) + name = fileInfo.Name; +} + +static void ConvertToLongNames(const UString &prefix, CObjectVector &items) +{ + for (int i = 0; i < items.Size(); i++) + { + NWildcard::CItem &item = items[i]; + if (item.Recursive || item.PathParts.Size() != 1) + continue; + ConvertToLongName(prefix, item.PathParts.Front()); + } +} + +static void ConvertToLongNames(const UString &prefix, NWildcard::CCensorNode &node) +{ + ConvertToLongNames(prefix, node.IncludeItems); + ConvertToLongNames(prefix, node.ExcludeItems); + int i; + for (i = 0; i < node.SubNodes.Size(); i++) + ConvertToLongName(prefix, node.SubNodes[i].Name); + // mix folders with same name + for (i = 0; i < node.SubNodes.Size(); i++) + { + NWildcard::CCensorNode &nextNode1 = node.SubNodes[i]; + for (int j = i + 1; j < node.SubNodes.Size();) + { + const NWildcard::CCensorNode &nextNode2 = node.SubNodes[j]; + if (nextNode1.Name.CompareNoCase(nextNode2.Name) == 0) + { + nextNode1.IncludeItems += nextNode2.IncludeItems; + nextNode1.ExcludeItems += nextNode2.ExcludeItems; + node.SubNodes.Delete(j); + } + else + j++; + } + } + for (i = 0; i < node.SubNodes.Size(); i++) + { + NWildcard::CCensorNode &nextNode = node.SubNodes[i]; + ConvertToLongNames(prefix + nextNode.Name + wchar_t(NFile::NName::kDirDelimiter), nextNode); + } +} + +static void ConvertToLongNames(NWildcard::CCensor &censor) +{ + for (int i = 0; i < censor.Pairs.Size(); i++) + { + NWildcard::CPair &pair = censor.Pairs[i]; + ConvertToLongNames(pair.Prefix, pair.Head); + } +} + +#endif + +static NUpdateArchive::NPairAction::EEnum GetUpdatePairActionType(int i) +{ + switch(i) + { + case NUpdateArchive::NPairAction::kIgnore: return NUpdateArchive::NPairAction::kIgnore; + case NUpdateArchive::NPairAction::kCopy: return NUpdateArchive::NPairAction::kCopy; + case NUpdateArchive::NPairAction::kCompress: return NUpdateArchive::NPairAction::kCompress; + case NUpdateArchive::NPairAction::kCompressAsAnti: return NUpdateArchive::NPairAction::kCompressAsAnti; + } + throw 98111603; +} + +const UString kUpdatePairStateIDSet = L"PQRXYZW"; +const int kUpdatePairStateNotSupportedActions[] = {2, 2, 1, -1, -1, -1, -1}; + +const UString kUpdatePairActionIDSet = L"0123"; //Ignore, Copy, Compress, Create Anti + +const wchar_t *kUpdateIgnoreItselfPostStringID = L"-"; +const wchar_t kUpdateNewArchivePostCharID = '!'; + + +static bool ParseUpdateCommandString2(const UString &command, + NUpdateArchive::CActionSet &actionSet, UString &postString) +{ + for(int i = 0; i < command.Length();) + { + wchar_t c = MyCharUpper(command[i]); + int statePos = kUpdatePairStateIDSet.Find(c); + if (statePos < 0) + { + postString = command.Mid(i); + return true; + } + i++; + if (i >= command.Length()) + return false; + int actionPos = kUpdatePairActionIDSet.Find(::MyCharUpper(command[i])); + if (actionPos < 0) + return false; + actionSet.StateActions[statePos] = GetUpdatePairActionType(actionPos); + if (kUpdatePairStateNotSupportedActions[statePos] == actionPos) + return false; + i++; + } + postString.Empty(); + return true; +} + +static void ParseUpdateCommandString(CUpdateOptions &options, + const UStringVector &updatePostStrings, + const NUpdateArchive::CActionSet &defaultActionSet) +{ + for(int i = 0; i < updatePostStrings.Size(); i++) + { + const UString &updateString = updatePostStrings[i]; + if(updateString.CompareNoCase(kUpdateIgnoreItselfPostStringID) == 0) + { + if(options.UpdateArchiveItself) + { + options.UpdateArchiveItself = false; + options.Commands.Delete(0); + } + } + else + { + NUpdateArchive::CActionSet actionSet = defaultActionSet; + + UString postString; + if (!ParseUpdateCommandString2(updateString, actionSet, postString)) + ThrowUserErrorException(); + if(postString.IsEmpty()) + { + if(options.UpdateArchiveItself) + options.Commands[0].ActionSet = actionSet; + } + else + { + if(MyCharUpper(postString[0]) != kUpdateNewArchivePostCharID) + ThrowUserErrorException(); + CUpdateArchiveCommand uc; + UString archivePath = postString.Mid(1); + if (archivePath.IsEmpty()) + ThrowUserErrorException(); + uc.ArchivePath.BaseExtension = options.ArchivePath.BaseExtension; + uc.ArchivePath.VolExtension = options.ArchivePath.VolExtension; + uc.ArchivePath.ParseFromPath(archivePath); + uc.ActionSet = actionSet; + options.Commands.Add(uc); + } + } + } +} + +static const char kByteSymbol = 'B'; +static const char kKiloSymbol = 'K'; +static const char kMegaSymbol = 'M'; +static const char kGigaSymbol = 'G'; + +static bool ParseComplexSize(const UString &src, UInt64 &result) +{ + UString s = src; + s.MakeUpper(); + + const wchar_t *start = s; + const wchar_t *end; + UInt64 number = ConvertStringToUInt64(start, &end); + int numDigits = (int)(end - start); + if (numDigits == 0 || s.Length() > numDigits + 1) + return false; + if (s.Length() == numDigits) + { + result = number; + return true; + } + int numBits; + switch (s[numDigits]) + { + case kByteSymbol: + result = number; + return true; + case kKiloSymbol: + numBits = 10; + break; + case kMegaSymbol: + numBits = 20; + break; + case kGigaSymbol: + numBits = 30; + break; + default: + return false; + } + if (number >= ((UInt64)1 << (64 - numBits))) + return false; + result = number << numBits; + return true; +} + +static void SetAddCommandOptions( + NCommandType::EEnum commandType, + const CParser &parser, + CUpdateOptions &options) +{ + NUpdateArchive::CActionSet defaultActionSet; + switch(commandType) + { + case NCommandType::kAdd: + defaultActionSet = NUpdateArchive::kAddActionSet; + break; + case NCommandType::kDelete: + defaultActionSet = NUpdateArchive::kDeleteActionSet; + break; + default: + defaultActionSet = NUpdateArchive::kUpdateActionSet; + } + + options.UpdateArchiveItself = true; + + options.Commands.Clear(); + CUpdateArchiveCommand updateMainCommand; + updateMainCommand.ActionSet = defaultActionSet; + options.Commands.Add(updateMainCommand); + if(parser[NKey::kUpdate].ThereIs) + ParseUpdateCommandString(options, parser[NKey::kUpdate].PostStrings, + defaultActionSet); + if(parser[NKey::kWorkingDir].ThereIs) + { + const UString &postString = parser[NKey::kWorkingDir].PostStrings[0]; + if (postString.IsEmpty()) + NDirectory::MyGetTempPath(options.WorkingDir); + else + options.WorkingDir = postString; + } + options.SfxMode = parser[NKey::kSfx].ThereIs; + if (options.SfxMode) + options.SfxModule = parser[NKey::kSfx].PostStrings[0]; + + if (parser[NKey::kVolume].ThereIs) + { + const UStringVector &sv = parser[NKey::kVolume].PostStrings; + for (int i = 0; i < sv.Size(); i++) + { + UInt64 size; + if (!ParseComplexSize(sv[i], size)) + ThrowException("Incorrect volume size"); + options.VolumesSizes.Add(size); + } + } +} + +static void SetMethodOptions(const CParser &parser, CObjectVector &properties) +{ + if (parser[NKey::kProperty].ThereIs) + { + // options.MethodMode.Properties.Clear(); + for(int i = 0; i < parser[NKey::kProperty].PostStrings.Size(); i++) + { + CProperty property; + const UString &postString = parser[NKey::kProperty].PostStrings[i]; + int index = postString.Find(L'='); + if (index < 0) + property.Name = postString; + else + { + property.Name = postString.Left(index); + property.Value = postString.Mid(index + 1); + } + properties.Add(property); + } + } +} + + +static void SetArchiveType(const UString &archiveType, +#ifndef EXCLUDE_COM + UString &filePath, CLSID &classID, +#else + UString &formatName, +#endif + UString &archiveExtension) +{ + CObjectVector archiverInfoVector; + ReadArchiverInfoList(archiverInfoVector); + if (archiverInfoVector.Size() == 0) + ThrowException("There are no installed archive handlers"); + if (archiveType.IsEmpty()) + ThrowException("Incorrect archive type was assigned"); + for (int i = 0; i < archiverInfoVector.Size(); i++) + { + const CArchiverInfo &archiverInfo = archiverInfoVector[i]; + if (archiverInfo.Name.CompareNoCase(archiveType) == 0) + { + #ifndef EXCLUDE_COM + classID = archiverInfo.ClassID; + filePath = archiverInfo.FilePath; + #else + formatName = archiverInfo.Name; + + #endif + + archiveExtension = archiverInfo.GetMainExtension(); + return; + } + } + ThrowException("Incorrect archive type was assigned"); +} + + +CArchiveCommandLineParser::CArchiveCommandLineParser(): parser(kNumSwitches) {} + +void CArchiveCommandLineParser::Parse1(const UStringVector &commandStrings, + CArchiveCommandLineOptions &options) +{ + try + { + parser.ParseStrings(kSwitchForms, commandStrings); + } + catch(...) + { + ThrowUserErrorException(); + } + + options.IsInTerminal = (_isatty(_fileno(stdin)) != 0); + options.IsStdOutTerminal = (_isatty(_fileno(stdout)) != 0); + options.IsStdErrTerminal = (_isatty(_fileno(stderr)) != 0); + options.StdOutMode = parser[NKey::kStdOut].ThereIs; + options.EnableHeaders = !parser[NKey::kDisableHeaders].ThereIs; + options.HelpMode = parser[NKey::kHelp1].ThereIs || parser[NKey::kHelp2].ThereIs || parser[NKey::kHelp3].ThereIs; + + #ifdef _WIN32 + options.LargePages = false; + if (parser[NKey::kLargePages].ThereIs) + { + const UString &postString = parser[NKey::kLargePages].PostStrings.Front(); + if (postString.IsEmpty()) + options.LargePages = true; + } + #endif +} + +struct CCodePagePair +{ + const wchar_t *Name; + UINT CodePage; +}; + +static CCodePagePair g_CodePagePairs[] = +{ + { L"UTF-8", CP_UTF8 }, + { L"WIN", CP_ACP }, + { L"DOS", CP_OEMCP } +}; + +static const int kNumCodePages = sizeof(g_CodePagePairs) / sizeof(g_CodePagePairs[0]); + +void CArchiveCommandLineParser::Parse2(CArchiveCommandLineOptions &options) +{ + const UStringVector &nonSwitchStrings = parser.NonSwitchStrings; + int numNonSwitchStrings = nonSwitchStrings.Size(); + if(numNonSwitchStrings < kMinNonSwitchWords) + ThrowUserErrorException(); + + if (!ParseArchiveCommand(nonSwitchStrings[kCommandIndex], options.Command)) + ThrowUserErrorException(); + + options.TechMode = parser[NKey::kTechMode].ThereIs; + + NRecursedType::EEnum recursedType; + if (parser[NKey::kRecursed].ThereIs) + recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex); + else + recursedType = NRecursedType::kNonRecursed; + + UINT codePage = CP_UTF8; + if (parser[NKey::kCharSet].ThereIs) + { + UString name = parser[NKey::kCharSet].PostStrings.Front(); + name.MakeUpper(); + int i; + for (i = 0; i < kNumCodePages; i++) + { + const CCodePagePair &pair = g_CodePagePairs[i]; + if (name.Compare(pair.Name) == 0) + { + codePage = pair.CodePage; + break; + } + } + if (i >= kNumCodePages) + ThrowUserErrorException(); + } + + bool thereAreSwitchIncludes = false; + if (parser[NKey::kInclude].ThereIs) + { + thereAreSwitchIncludes = true; + AddSwitchWildCardsToCensor(options.WildcardCensor, + parser[NKey::kInclude].PostStrings, true, recursedType, codePage); + } + if (parser[NKey::kExclude].ThereIs) + AddSwitchWildCardsToCensor(options.WildcardCensor, + parser[NKey::kExclude].PostStrings, false, recursedType, codePage); + + int curCommandIndex = kCommandIndex + 1; + bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs; + if (thereIsArchiveName) + { + if(curCommandIndex >= numNonSwitchStrings) + ThrowUserErrorException(); + options.ArchiveName = nonSwitchStrings[curCommandIndex++]; + } + + AddToCensorFromNonSwitchesStrings( + curCommandIndex, options.WildcardCensor, + nonSwitchStrings, recursedType, thereAreSwitchIncludes, codePage); + + options.YesToAll = parser[NKey::kYes].ThereIs; + + bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); + + options.PasswordEnabled = parser[NKey::kPassword].ThereIs; + + if(options.PasswordEnabled) + options.Password = parser[NKey::kPassword].PostStrings[0]; + + options.StdInMode = parser[NKey::kStdIn].ThereIs; + options.ShowDialog = parser[NKey::kShowDialog].ThereIs; + + if(isExtractGroupCommand || options.Command.CommandType == NCommandType::kList) + { + if (options.StdInMode) + ThrowException("Reading archives from stdin is not implemented"); + if (!options.WildcardCensor.AllAreRelative()) + ThrowException("Cannot use absolute pathnames for this command"); + + NWildcard::CCensor archiveWildcardCensor; + + if (parser[NKey::kArInclude].ThereIs) + { + AddSwitchWildCardsToCensor(archiveWildcardCensor, + parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed, codePage); + } + if (parser[NKey::kArExclude].ThereIs) + AddSwitchWildCardsToCensor(archiveWildcardCensor, + parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, codePage); + + if (thereIsArchiveName) + AddCommandLineWildCardToCensr(archiveWildcardCensor, options.ArchiveName, true, NRecursedType::kNonRecursed); + + #ifdef _WIN32 + ConvertToLongNames(archiveWildcardCensor); + #endif + + archiveWildcardCensor.ExtendExclude(); + + CObjectVector dirItems; + { + UStringVector errorPaths; + CRecordVector errorCodes; + HRESULT res = EnumerateItems(archiveWildcardCensor, dirItems, NULL, errorPaths, errorCodes); + if (res != S_OK || errorPaths.Size() > 0) + throw "cannot find archive"; + } + UStringVector archivePaths; + int i; + for (i = 0; i < dirItems.Size(); i++) + { + const CDirItem &dirItem = dirItems[i]; + if (!dirItem.IsDirectory()) + archivePaths.Add(dirItem.FullPath); + } + + if (archivePaths.Size() == 0) + throw "there is no such archive"; + + UStringVector archivePathsFull; + + for (i = 0; i < archivePaths.Size(); i++) + { + UString fullPath; + NFile::NDirectory::MyGetFullPathName(archivePaths[i], fullPath); + archivePathsFull.Add(fullPath); + } + CIntVector indices; + SortStringsToIndices(archivePathsFull, indices); + options.ArchivePathsSorted.Reserve(indices.Size()); + options.ArchivePathsFullSorted.Reserve(indices.Size()); + for (i = 0; i < indices.Size(); i++) + { + options.ArchivePathsSorted.Add(archivePaths[indices[i]]); + options.ArchivePathsFullSorted.Add(archivePathsFull[indices[i]]); + } + + 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]; + NFile::NName::NormalizeDirPathPrefix(options.OutputDir); + } + + options.OverwriteMode = NExtract::NOverwriteMode::kAskBefore; + if(parser[NKey::kOverwrite].ThereIs) + options.OverwriteMode = + k_OverwriteModes[parser[NKey::kOverwrite].PostCharIndex]; + else if (options.YesToAll) + options.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; + } + } + else if(options.Command.IsFromUpdateGroup()) + { + CUpdateOptions &updateOptions = options.UpdateOptions; + + UString archiveType; + if(parser[NKey::kArchiveType].ThereIs) + archiveType = parser[NKey::kArchiveType].PostStrings[0]; + else + archiveType = kDefaultArchiveType; + + UString typeExtension; + if (!archiveType.IsEmpty()) + { + #ifndef EXCLUDE_COM + SetArchiveType(archiveType, updateOptions.MethodMode.FilePath, + updateOptions.MethodMode.ClassID, typeExtension); + #else + SetArchiveType(archiveType, updateOptions.MethodMode.Name, typeExtension); + #endif + } + UString extension = typeExtension; + if(parser[NKey::kSfx].ThereIs) + extension = kSFXExtension; + updateOptions.ArchivePath.BaseExtension = extension; + updateOptions.ArchivePath.VolExtension = typeExtension; + updateOptions.ArchivePath.ParseFromPath(options.ArchiveName); + SetAddCommandOptions(options.Command.CommandType, parser, updateOptions); + + SetMethodOptions(parser, updateOptions.MethodMode.Properties); + + options.EnablePercents = !parser[NKey::kDisablePercents].ThereIs; + + if (options.EnablePercents) + { + if ((options.StdOutMode && !options.IsStdErrTerminal) || + (!options.StdOutMode && !options.IsStdOutTerminal)) + options.EnablePercents = false; + } + + updateOptions.EMailMode = parser[NKey::kEmail].ThereIs; + if (updateOptions.EMailMode) + { + updateOptions.EMailAddress = parser[NKey::kEmail].PostStrings.Front(); + if (updateOptions.EMailAddress.Length() > 0) + if (updateOptions.EMailAddress[0] == L'.') + { + updateOptions.EMailRemoveAfter = true; + updateOptions.EMailAddress.Delete(0); + } + } + + updateOptions.StdOutMode = options.StdOutMode; + updateOptions.StdInMode = options.StdInMode; + + if (updateOptions.StdOutMode && updateOptions.EMailMode) + throw "stdout mode and email mode cannot be combined"; + if (updateOptions.StdOutMode && options.IsStdOutTerminal) + throw kTerminalOutError; + if(updateOptions.StdInMode) + updateOptions.StdInFileName = parser[NKey::kStdIn].PostStrings.Front(); + + #ifdef _WIN32 + ConvertToLongNames(options.WildcardCensor); + #endif + } + else + ThrowUserErrorException(); + options.WildcardCensor.ExtendExclude(); +} diff --git a/CPP/7zip/UI/Common/ArchiveCommandLine.h b/CPP/7zip/UI/Common/ArchiveCommandLine.h new file mode 100755 index 00000000..daa66fb6 --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiveCommandLine.h @@ -0,0 +1,95 @@ +// ArchiveCommandLine.h + +#ifndef __ARCHIVECOMMANDLINE_H +#define __ARCHIVECOMMANDLINE_H + +#include "Common/Wildcard.h" +#include "Common/CommandLineParser.h" + +#include "Extract.h" +#include "Update.h" + +struct CArchiveCommandLineException: public AString +{ + CArchiveCommandLineException(const char *errorMessage): AString(errorMessage) {} +}; + +namespace NCommandType { enum EEnum +{ + kAdd = 0, + kUpdate, + kDelete, + kTest, + kExtract, + kFullExtract, + kList +};} + +namespace NRecursedType { enum EEnum +{ + kRecursed, + kWildCardOnlyRecursed, + kNonRecursed, +};} + +struct CArchiveCommand +{ + NCommandType::EEnum CommandType; + bool IsFromExtractGroup() const; + bool IsFromUpdateGroup() const; + bool IsTestMode() const { return CommandType == NCommandType::kTest; } + NExtract::NPathMode::EEnum GetPathMode() const; +}; + +struct CArchiveCommandLineOptions +{ + bool HelpMode; + + #ifdef _WIN32 + bool LargePages; + #endif + + bool IsInTerminal; + bool IsStdOutTerminal; + bool IsStdErrTerminal; + bool StdInMode; + bool StdOutMode; + bool EnableHeaders; + + bool YesToAll; + bool ShowDialog; + // NWildcard::CCensor ArchiveWildcardCensor; + NWildcard::CCensor WildcardCensor; + + CArchiveCommand Command; + UString ArchiveName; + + bool PasswordEnabled; + UString Password; + + bool TechMode; + // Extract + bool AppendName; + UString OutputDir; + NExtract::NOverwriteMode::EEnum OverwriteMode; + UStringVector ArchivePathsSorted; + UStringVector ArchivePathsFullSorted; + CObjectVector ExtractProperties; + + CUpdateOptions UpdateOptions; + bool EnablePercents; + + CArchiveCommandLineOptions(): StdInMode(false), StdOutMode(false) {}; + +}; + +class CArchiveCommandLineParser +{ + NCommandLineParser::CParser parser; +public: + CArchiveCommandLineParser(); + void Parse1(const UStringVector &commandStrings, CArchiveCommandLineOptions &options); + void Parse2(CArchiveCommandLineOptions &options); +}; + +#endif diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp new file mode 100755 index 00000000..05520fed --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp @@ -0,0 +1,448 @@ +// ArchiveExtractCallback.cpp + +#include "StdAfx.h" + +#include "ArchiveExtractCallback.h" + +#include "Common/Wildcard.h" +#include "Common/StringConvert.h" +#include "Common/ComTry.h" + +#include "Windows/FileDir.h" +#include "Windows/FileFind.h" +#include "Windows/Time.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" + +#include "Windows/PropVariantConversions.h" + +#include "../../Common/FilePathAutoRename.h" + +#include "../Common/ExtractingFilePath.h" +#include "OpenArchive.h" + +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 "; + + +void CArchiveExtractCallback::Init( + IInArchive *archiveHandler, + IFolderArchiveExtractCallback *extractCallback2, + bool stdOutMode, + const UString &directoryPath, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const UStringVector &removePathParts, + const UString &itemDefaultName, + const FILETIME &utcLastWriteTimeDefault, + UInt32 attributesDefault) +{ + _stdOutMode = stdOutMode; + _numErrors = 0; + _extractCallback2 = extractCallback2; + _itemDefaultName = itemDefaultName; + _utcLastWriteTimeDefault = utcLastWriteTimeDefault; + _attributesDefault = attributesDefault; + _removePathParts = removePathParts; + _pathMode = pathMode; + _overwriteMode = overwriteMode; + _archiveHandler = archiveHandler; + _directoryPath = directoryPath; + NFile::NName::NormalizeDirPathPrefix(_directoryPath); +} + +STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size) +{ + COM_TRY_BEGIN + return _extractCallback2->SetTotal(size); + COM_TRY_END +} + +STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *completeValue) +{ + COM_TRY_BEGIN + return _extractCallback2->SetCompleted(completeValue); + COM_TRY_END +} + +void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath) +{ + fullPath = _directoryPath; + for(int i = 0; i < dirPathParts.Size(); i++) + { + if (i > 0) + fullPath += wchar_t(NFile::NName::kDirDelimiter); + fullPath += dirPathParts[i]; + NFile::NDirectory::MyCreateDirectory(fullPath); + } +} + +static UString MakePathNameFromParts(const UStringVector &parts) +{ + UString result; + for(int i = 0; i < parts.Size(); i++) + { + if(i != 0) + result += wchar_t(NFile::NName::kDirDelimiter); + result += parts[i]; + } + return result; +} + + +HRESULT CArchiveExtractCallback::GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined) +{ + filetimeIsDefined = false; + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, propID, &prop)); + if (prop.vt == VT_FILETIME) + { + filetime = prop.filetime; + filetimeIsDefined = true; + } + else if (prop.vt != VT_EMPTY) + return E_FAIL; + return S_OK; +} + +STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) +{ + COM_TRY_BEGIN + *outStream = 0; + _outFileStream.Release(); + + _encrypted = false; + _isSplit = false; + + UString fullPath; + { + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop)); + + if(prop.vt == VT_EMPTY) + fullPath = _itemDefaultName; + else + { + if(prop.vt != VT_BSTR) + return E_FAIL; + fullPath = prop.bstrVal; + } + } + + // UString fullPathCorrect = GetCorrectPath(fullPath); + _filePath = fullPath; + + { + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, kpidPosition, &prop)); + if (prop.vt != VT_EMPTY) + { + if (prop.vt != VT_UI8) + return E_FAIL; + _position = prop.uhVal.QuadPart; + _isSplit = true; + } + } + + { + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, kpidEncrypted, &prop)); + if (prop.vt == VT_BOOL) + _encrypted = VARIANT_BOOLToBool(prop.boolVal); + else if (prop.vt != VT_EMPTY) + return E_FAIL; + } + + if(askExtractMode == NArchive::NExtract::NAskMode::kExtract) + { + if (_stdOutMode) + { + CMyComPtr outStreamLoc = new CStdOutFileStream; + *outStream = outStreamLoc.Detach(); + return S_OK; + } + + { + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &prop)); + if (prop.vt == VT_EMPTY) + { + _processedFileInfo.Attributes = _attributesDefault; + _processedFileInfo.AttributesAreDefined = false; + } + else + { + if (prop.vt != VT_UI4) + throw "incorrect item"; + _processedFileInfo.Attributes = prop.ulVal; + _processedFileInfo.AttributesAreDefined = true; + } + } + + RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.IsDirectory)); + + RINOK(GetTime(index, kpidCreationTime, _processedFileInfo.CreationTime, + _processedFileInfo.IsCreationTimeDefined)); + RINOK(GetTime(index, kpidLastWriteTime, _processedFileInfo.LastWriteTime, + _processedFileInfo.IsLastWriteTimeDefined)); + RINOK(GetTime(index, kpidLastAccessTime, _processedFileInfo.LastAccessTime, + _processedFileInfo.IsLastAccessTimeDefined)); + + bool newFileSizeDefined; + UInt64 newFileSize; + { + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop)); + newFileSizeDefined = (prop.vt != VT_EMPTY); + if (newFileSizeDefined) + newFileSize = ConvertPropVariantToUInt64(prop); + } + + bool isAnti = false; + { + NCOM::CPropVariant prop; + RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, &prop)); + if (prop.vt == VT_BOOL) + isAnti = VARIANT_BOOLToBool(prop.boolVal); + } + + UStringVector pathParts; + SplitPathToParts(fullPath, pathParts); + + if(pathParts.IsEmpty()) + return E_FAIL; + UString processedPath; + switch(_pathMode) + { + case NExtract::NPathMode::kFullPathnames: + { + processedPath = fullPath; + break; + } + case NExtract::NPathMode::kCurrentPathnames: + { + // for incorrect paths: "/dir1/dir2/file" + int numRemovePathParts = _removePathParts.Size(); + if(pathParts.Size() <= numRemovePathParts) + return E_FAIL; + for(int i = 0; i < numRemovePathParts; i++) + if(_removePathParts[i].CompareNoCase(pathParts[i]) != 0) + return E_FAIL; + pathParts.Delete(0, numRemovePathParts); + processedPath = MakePathNameFromParts(pathParts); + break; + } + case NExtract::NPathMode::kNoPathnames: + { + processedPath = pathParts.Back(); + pathParts.Delete(0, pathParts.Size() - 1); // Test it!! + break; + } + } + processedPath = GetCorrectPath(processedPath); + if(!_processedFileInfo.IsDirectory) + pathParts.DeleteBack(); + + MakeCorrectPath(pathParts); + + if (!isAnti) + { + if (!pathParts.IsEmpty()) + { + UString fullPathNew; + CreateComplexDirectory(pathParts, fullPathNew); + if (_processedFileInfo.IsDirectory) + NFile::NDirectory::SetDirTime(fullPathNew, + (WriteCreated && _processedFileInfo.IsCreationTimeDefined) ? &_processedFileInfo.CreationTime : NULL, + (WriteAccessed && _processedFileInfo.IsLastAccessTimeDefined) ? &_processedFileInfo.LastAccessTime : NULL, + (WriteModified && _processedFileInfo.IsLastWriteTimeDefined) ? &_processedFileInfo.LastWriteTime : &_utcLastWriteTimeDefault); + } + } + + + UString fullProcessedPath = _directoryPath + processedPath; + + if(_processedFileInfo.IsDirectory) + { + _diskFilePath = fullProcessedPath; + if (isAnti) + NFile::NDirectory::MyRemoveDirectory(_diskFilePath); + return S_OK; + } + + if (!_isSplit) + { + NFile::NFind::CFileInfoW fileInfo; + if(NFile::NFind::FindFile(fullProcessedPath, fileInfo)) + { + switch(_overwriteMode) + { + case NExtract::NOverwriteMode::kSkipExisting: + return S_OK; + case NExtract::NOverwriteMode::kAskBefore: + { + Int32 overwiteResult; + RINOK(_extractCallback2->AskOverwrite( + fullProcessedPath, &fileInfo.LastWriteTime, &fileInfo.Size, fullPath, + _processedFileInfo.IsLastWriteTimeDefined ? &_processedFileInfo.LastWriteTime : NULL, + newFileSizeDefined ? &newFileSize : NULL, + &overwiteResult)) + + switch(overwiteResult) + { + case NOverwriteAnswer::kCancel: + return E_ABORT; + case NOverwriteAnswer::kNo: + return S_OK; + case NOverwriteAnswer::kNoToAll: + _overwriteMode = NExtract::NOverwriteMode::kSkipExisting; + return S_OK; + case NOverwriteAnswer::kYesToAll: + _overwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; + break; + case NOverwriteAnswer::kYes: + break; + case NOverwriteAnswer::kAutoRename: + _overwriteMode = NExtract::NOverwriteMode::kAutoRename; + break; + default: + throw 20413; + } + } + } + if (_overwriteMode == NExtract::NOverwriteMode::kAutoRename) + { + if (!AutoRenamePath(fullProcessedPath)) + { + UString message = UString(kCantAutoRename) + fullProcessedPath; + RINOK(_extractCallback2->MessageError(message)); + return E_FAIL; + } + } + else if (_overwriteMode == NExtract::NOverwriteMode::kAutoRenameExisting) + { + UString existPath = fullProcessedPath; + if (!AutoRenamePath(existPath)) + { + UString message = kCantAutoRename + fullProcessedPath; + RINOK(_extractCallback2->MessageError(message)); + return E_FAIL; + } + if(!NFile::NDirectory::MyMoveFile(fullProcessedPath, existPath)) + { + UString message = UString(kCantRenameFile) + fullProcessedPath; + RINOK(_extractCallback2->MessageError(message)); + return E_FAIL; + } + } + else + if (!NFile::NDirectory::DeleteFileAlways(fullProcessedPath)) + { + UString message = UString(kCantDeleteOutputFile) + + fullProcessedPath; + RINOK(_extractCallback2->MessageError(message)); + return E_FAIL; + } + } + } + if (!isAnti) + { + _outFileStreamSpec = new COutFileStream; + CMyComPtr outStreamLoc(_outFileStreamSpec); + if (!_outFileStreamSpec->File.Open(fullProcessedPath, + _isSplit ? OPEN_ALWAYS: CREATE_ALWAYS)) + { + // if (::GetLastError() != ERROR_FILE_EXISTS || !isSplit) + { + UString message = L"can not open output file " + fullProcessedPath; + RINOK(_extractCallback2->MessageError(message)); + return S_OK; + } + } + if (_isSplit) + { + RINOK(_outFileStreamSpec->Seek(_position, STREAM_SEEK_SET, NULL)); + } + _outFileStream = outStreamLoc; + *outStream = outStreamLoc.Detach(); + } + _diskFilePath = fullProcessedPath; + } + else + { + *outStream = NULL; + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode) +{ + COM_TRY_BEGIN + _extractMode = false; + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: + _extractMode = true; + }; + return _extractCallback2->PrepareOperation(_filePath, askExtractMode, _isSplit ? &_position: 0); + COM_TRY_END +} + +STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult) +{ + COM_TRY_BEGIN + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kOK: + case NArchive::NExtract::NOperationResult::kUnSupportedMethod: + case NArchive::NExtract::NOperationResult::kCRCError: + case NArchive::NExtract::NOperationResult::kDataError: + break; + default: + _outFileStream.Release(); + return E_FAIL; + } + if(_outFileStream != NULL) + _outFileStreamSpec->File.SetTime( + (WriteCreated && _processedFileInfo.IsCreationTimeDefined) ? &_processedFileInfo.CreationTime : NULL, + (WriteAccessed && _processedFileInfo.IsLastAccessTimeDefined) ? &_processedFileInfo.LastAccessTime : NULL, + (WriteModified && _processedFileInfo.IsLastWriteTimeDefined) ? &_processedFileInfo.LastWriteTime : &_utcLastWriteTimeDefault); + _outFileStream.Release(); + if (_extractMode && _processedFileInfo.AttributesAreDefined) + NFile::NDirectory::MySetFileAttributes(_diskFilePath, _processedFileInfo.Attributes); + RINOK(_extractCallback2->SetOperationResult(operationResult, _encrypted)); + return S_OK; + COM_TRY_END +} + +/* +STDMETHODIMP CArchiveExtractCallback::GetInStream( + const wchar_t *name, ISequentialInStream **inStream) +{ + COM_TRY_BEGIN + CInFileStream *inFile = new CInFileStream; + CMyComPtr inStreamTemp = inFile; + if (!inFile->Open(_srcDirectoryPrefix + name)) + return ::GetLastError(); + *inStream = inStreamTemp.Detach(); + return S_OK; + COM_TRY_END +} +*/ + +STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password) +{ + COM_TRY_BEGIN + if (!_cryptoGetTextPassword) + { + RINOK(_extractCallback2.QueryInterface(IID_ICryptoGetTextPassword, + &_cryptoGetTextPassword)); + } + return _cryptoGetTextPassword->CryptoGetTextPassword(password); + COM_TRY_END +} + diff --git a/CPP/7zip/UI/Common/ArchiveExtractCallback.h b/CPP/7zip/UI/Common/ArchiveExtractCallback.h new file mode 100755 index 00000000..4fd63a53 --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.h @@ -0,0 +1,111 @@ +// ArchiveExtractCallback.h + +#ifndef __ARCHIVEEXTRACTCALLBACK_H +#define __ARCHIVEEXTRACTCALLBACK_H + +#include "../../Archive/IArchive.h" +#include "IFileExtractCallback.h" + +#include "Common/String.h" +#include "Common/MyCom.h" + +#include "../../Common/FileStreams.h" +#include "../../IPassword.h" + +#include "ExtractMode.h" + +class CArchiveExtractCallback: + public IArchiveExtractCallback, + // public IArchiveVolumeExtractCallback, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(ICryptoGetTextPassword) + // COM_INTERFACE_ENTRY(IArchiveVolumeExtractCallback) + + // IProgress + STDMETHOD(SetTotal)(UInt64 size); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); + + // IExtractCallBack + STDMETHOD(GetStream)(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode); + STDMETHOD(PrepareOperation)(Int32 askExtractMode); + STDMETHOD(SetOperationResult)(Int32 resultEOperationResult); + + // IArchiveVolumeExtractCallback + // STDMETHOD(GetInStream)(const wchar_t *name, ISequentialInStream **inStream); + + // ICryptoGetTextPassword + STDMETHOD(CryptoGetTextPassword)(BSTR *aPassword); + +private: + CMyComPtr _archiveHandler; + CMyComPtr _extractCallback2; + CMyComPtr _cryptoGetTextPassword; + UString _directoryPath; + NExtract::NPathMode::EEnum _pathMode; + NExtract::NOverwriteMode::EEnum _overwriteMode; + + UString _filePath; + UInt64 _position; + bool _isSplit; + + UString _diskFilePath; + + bool _extractMode; + + bool WriteModified; + bool WriteCreated; + bool WriteAccessed; + + bool _encrypted; + + struct CProcessedFileInfo + { + FILETIME CreationTime; + FILETIME LastWriteTime; + FILETIME LastAccessTime; + UInt32 Attributes; + + bool IsCreationTimeDefined; + bool IsLastWriteTimeDefined; + bool IsLastAccessTimeDefined; + + bool IsDirectory; + bool AttributesAreDefined; + } _processedFileInfo; + + COutFileStream *_outFileStreamSpec; + CMyComPtr _outFileStream; + UStringVector _removePathParts; + + UString _itemDefaultName; + FILETIME _utcLastWriteTimeDefault; + UInt32 _attributesDefault; + bool _stdOutMode; + + void CreateComplexDirectory(const UStringVector &dirPathParts, UString &fullPath); + HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined); +public: + CArchiveExtractCallback(): + WriteModified(true), + WriteCreated(false), + WriteAccessed(false) + {} + void Init( + IInArchive *archiveHandler, + IFolderArchiveExtractCallback *extractCallback2, + bool stdOutMode, + const UString &directoryPath, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const UStringVector &removePathParts, + const UString &itemDefaultName, + const FILETIME &utcLastWriteTimeDefault, + UInt32 attributesDefault); + + UInt64 _numErrors; +}; + +#endif diff --git a/CPP/7zip/UI/Common/ArchiveName.cpp b/CPP/7zip/UI/Common/ArchiveName.cpp new file mode 100755 index 00000000..2d50ede1 --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiveName.cpp @@ -0,0 +1,46 @@ +// ArchiveName.cpp + +#include "StdAfx.h" + +#include "Windows/FileFind.h" +#include "Windows/FileDir.h" + +using namespace NWindows; + +UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName) +{ + UString resultName = L"Archive"; + if (fromPrev) + { + UString dirPrefix; + if (NFile::NDirectory::GetOnlyDirPrefix(srcName, dirPrefix)) + { + if (dirPrefix.Length() > 0) + if (dirPrefix[dirPrefix.Length() - 1] == '\\') + { + dirPrefix.Delete(dirPrefix.Length() - 1); + NFile::NFind::CFileInfoW fileInfo; + if (NFile::NFind::FindFile(dirPrefix, fileInfo)) + resultName = fileInfo.Name; + } + } + } + else + { + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(srcName, fileInfo)) + return resultName; + resultName = fileInfo.Name; + if (!fileInfo.IsDirectory() && !keepName) + { + int dotPos = resultName.ReverseFind('.'); + if (dotPos > 0) + { + UString archiveName2 = resultName.Left(dotPos); + if (archiveName2.ReverseFind('.') < 0) + resultName = archiveName2; + } + } + } + return resultName; +} diff --git a/CPP/7zip/UI/Common/ArchiveName.h b/CPP/7zip/UI/Common/ArchiveName.h new file mode 100755 index 00000000..6b001a5a --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiveName.h @@ -0,0 +1,10 @@ +// ArchiveName.h + +#ifndef __ARCHIVENAME_H +#define __ARCHIVENAME_H + +#include "Common/String.h" + +UString CreateArchiveName(const UString &srcName, bool fromPrev, bool keepName); + +#endif diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp new file mode 100755 index 00000000..1d2944d8 --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiveOpenCallback.cpp @@ -0,0 +1,127 @@ +// ArchiveOpenCallback.cpp + +#include "StdAfx.h" + +#include "ArchiveOpenCallback.h" + +#include "Common/StringConvert.h" +#include "Common/ComTry.h" +#include "Windows/PropVariant.h" + +#include "../../Common/FileStreams.h" + +using namespace NWindows; + +STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes) +{ + COM_TRY_BEGIN + return Callback->SetTotal(files, bytes); + COM_TRY_END +} + +STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes) +{ + COM_TRY_BEGIN + return Callback->SetTotal(files, bytes); + COM_TRY_END +} + +STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + NCOM::CPropVariant propVariant; + if (_subArchiveMode) + { + switch(propID) + { + case kpidName: + propVariant = _subArchiveName; + break; + } + propVariant.Detach(value); + return S_OK; + } + switch(propID) + { + case kpidName: + propVariant = _fileInfo.Name; + break; + case kpidIsFolder: + propVariant = _fileInfo.IsDirectory(); + break; + case kpidSize: + propVariant = _fileInfo.Size; + break; + case kpidAttributes: + propVariant = (UInt32)_fileInfo.Attributes; + break; + case kpidLastAccessTime: + propVariant = _fileInfo.LastAccessTime; + break; + case kpidCreationTime: + propVariant = _fileInfo.CreationTime; + break; + case kpidLastWriteTime: + propVariant = _fileInfo.LastWriteTime; + break; + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +int COpenCallbackImp::FindName(const UString &name) +{ + for (int i = 0; i < FileNames.Size(); i++) + if (name.CompareNoCase(FileNames[i]) == 0) + return i; + return -1; +} + +struct CInFileStreamVol: public CInFileStream +{ + UString Name; + COpenCallbackImp *OpenCallbackImp; + CMyComPtr OpenCallbackRef; + ~CInFileStreamVol() + { + int index = OpenCallbackImp->FindName(Name); + if (index >= 0) + OpenCallbackImp->FileNames.Delete(index); + } +}; + +STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream) +{ + COM_TRY_BEGIN + if (_subArchiveMode) + return S_FALSE; + RINOK(Callback->CheckBreak()); + *inStream = NULL; + UString fullPath = _folderPrefix + name; + if (!NFile::NFind::FindFile(fullPath, _fileInfo)) + return S_FALSE; + if (_fileInfo.IsDirectory()) + return S_FALSE; + CInFileStreamVol *inFile = new CInFileStreamVol; + CMyComPtr inStreamTemp = inFile; + if (!inFile->Open(fullPath)) + return ::GetLastError(); + *inStream = inStreamTemp.Detach(); + inFile->Name = name; + inFile->OpenCallbackImp = this; + inFile->OpenCallbackRef = this; + FileNames.Add(name); + return S_OK; + COM_TRY_END +} + +#ifndef _NO_CRYPTO +STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password) +{ + COM_TRY_BEGIN + return Callback->CryptoGetTextPassword(password); + COM_TRY_END +} +#endif + diff --git a/CPP/7zip/UI/Common/ArchiveOpenCallback.h b/CPP/7zip/UI/Common/ArchiveOpenCallback.h new file mode 100755 index 00000000..454873ad --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiveOpenCallback.h @@ -0,0 +1,89 @@ +// ArchiveOpenCallback.h + +#ifndef __ARCHIVE_OPEN_CALLBACK_H +#define __ARCHIVE_OPEN_CALLBACK_H + +#include "Common/String.h" +#include "Common/MyCom.h" +#include "Windows/FileFind.h" + +#ifndef _NO_CRYPTO +#include "../../IPassword.h" +#endif +#include "../../Archive/IArchive.h" + +struct IOpenCallbackUI +{ + virtual HRESULT CheckBreak() = 0; + virtual HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes) = 0; + virtual HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes) = 0; + #ifndef _NO_CRYPTO + virtual HRESULT CryptoGetTextPassword(BSTR *password) = 0; + virtual HRESULT GetPasswordIfAny(UString &password) = 0; + virtual bool WasPasswordAsked() = 0; + virtual void ClearPasswordWasAskedFlag() = 0; + #endif +}; + +class COpenCallbackImp: + public IArchiveOpenCallback, + public IArchiveOpenVolumeCallback, + public IArchiveOpenSetSubArchiveName, + #ifndef _NO_CRYPTO + public ICryptoGetTextPassword, + #endif + public CMyUnknownImp +{ +public: + #ifndef _NO_CRYPTO + MY_UNKNOWN_IMP3( + IArchiveOpenVolumeCallback, + ICryptoGetTextPassword, + IArchiveOpenSetSubArchiveName + ) + #else + MY_UNKNOWN_IMP2( + IArchiveOpenVolumeCallback, + IArchiveOpenSetSubArchiveName + ) + #endif + + STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes); + STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes); + + // IArchiveOpenVolumeCallback + STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value); + STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream); + + #ifndef _NO_CRYPTO + // ICryptoGetTextPassword + STDMETHOD(CryptoGetTextPassword)(BSTR *password); + #endif + + STDMETHOD(SetSubArchiveName(const wchar_t *name)) + { + _subArchiveMode = true; + _subArchiveName = name; + return S_OK; + } + +private: + UString _folderPrefix; + NWindows::NFile::NFind::CFileInfoW _fileInfo; + bool _subArchiveMode; + UString _subArchiveName; +public: + UStringVector FileNames; + IOpenCallbackUI *Callback; + void Init(const UString &folderPrefix, const UString &fileName) + { + _folderPrefix = folderPrefix; + if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo)) + throw 1; + FileNames.Clear(); + _subArchiveMode = false; + } + int FindName(const UString &name); +}; + +#endif diff --git a/CPP/7zip/UI/Common/ArchiverInfo.cpp b/CPP/7zip/UI/Common/ArchiverInfo.cpp new file mode 100755 index 00000000..7833ed3c --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiverInfo.cpp @@ -0,0 +1,372 @@ +// ArchiverInfo.cpp + +#include "StdAfx.h" + +#include "ArchiverInfo.h" + +#ifndef EXCLUDE_COM + +#include "Common/StringConvert.h" +#include "Windows/FileFind.h" +#include "Windows/FileName.h" +#include "Windows/DLL.h" +#ifdef _WIN32 +#include "Windows/Registry.h" +#endif +#include "Windows/PropVariant.h" +#include "../../Archive/IArchive.h" + +using namespace NWindows; +using namespace NFile; + +#endif + +extern HINSTANCE g_hInstance; + +#ifndef EXCLUDE_COM + +static void SplitString(const UString &srcString, UStringVector &destStrings) +{ + destStrings.Clear(); + UString string; + int len = srcString.Length(); + if (len == 0) + return; + for (int i = 0; i < len; i++) + { + wchar_t c = srcString[i]; + if (c == L' ') + { + if (!string.IsEmpty()) + { + destStrings.Add(string); + string.Empty(); + } + } + else + string += c; + } + if (!string.IsEmpty()) + destStrings.Add(string); +} + +typedef UInt32 (WINAPI * GetHandlerPropertyFunc)( + PROPID propID, PROPVARIANT *value); + +static UString GetModuleFolderPrefix() +{ + UString path; + NDLL::MyGetModuleFileName(g_hInstance, path); + int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR); + return path.Left(pos + 1); +} + +static wchar_t *kFormatFolderName = L"Formats"; + +#ifdef _WIN32 +static LPCTSTR kRegistryPath = TEXT("Software\\7-zip"); +static LPCWSTR kProgramPathValue = L"Path"; +static bool ReadPathFromRegistry(HKEY baseKey, UString &path) +{ + NRegistry::CKey key; + if(key.Open(baseKey, kRegistryPath, KEY_READ) == ERROR_SUCCESS) + if (key.QueryValue(kProgramPathValue, path) == ERROR_SUCCESS) + { + NName::NormalizeDirPathPrefix(path); + return true; + } + return false; +} +#endif + +static UString GetBaseFolderPrefixFromRegistry() +{ + UString moduleFolderPrefix = GetModuleFolderPrefix(); + NFind::CFileInfoW fileInfo; + if (NFind::FindFile(moduleFolderPrefix + kFormatFolderName, fileInfo)) + if (fileInfo.IsDirectory()) + return moduleFolderPrefix; + UString path; + #ifdef _WIN32 + if(ReadPathFromRegistry(HKEY_CURRENT_USER, path)) + return path; + if(ReadPathFromRegistry(HKEY_LOCAL_MACHINE, path)) + return path; + #endif + return moduleFolderPrefix; +} + +typedef UInt32 (WINAPI *CreateObjectPointer)( + const GUID *clsID, + const GUID *interfaceID, + void **outObject); + +#endif + +#ifndef _SFX +static inline void SetBuffer(CByteBuffer &bb, const Byte *data, int size) +{ + bb.SetCapacity(size); + memmove((Byte *)bb, data, size); +} +#endif + +void ReadArchiverInfoList(CObjectVector &archivers) +{ + archivers.Clear(); + + #ifdef EXCLUDE_COM + + #ifdef FORMAT_7Z + { + CArchiverInfo item; + item.UpdateEnabled = true; + item.Name = L"7z"; + item.Extensions.Add(CArchiverExtInfo(L"7z")); + #ifndef _SFX + const unsigned char kSig[] = {'7' , 'z', 0xBC, 0xAF, 0x27, 0x1C}; + SetBuffer(item.StartSignature, kSig, 6); + #endif + archivers.Add(item); + } + #endif + + #ifdef FORMAT_BZIP2 + { + CArchiverInfo item; + item.UpdateEnabled = true; + item.KeepName = true; + item.Name = L"BZip2"; + item.Extensions.Add(CArchiverExtInfo(L"bz2")); + item.Extensions.Add(CArchiverExtInfo(L"tbz2", L".tar")); + #ifndef _SFX + const unsigned char sig[] = {'B' , 'Z', 'h' }; + SetBuffer(item.StartSignature, sig, 3); + #endif + archivers.Add(item); + } + #endif + + #ifdef FORMAT_CAB + { + CArchiverInfo item; + item.Name = L"Cab"; + item.Extensions.Add(CArchiverExtInfo(L"cab")); + #ifndef _SFX + const unsigned char sig[] = { 0x4D, 0x53, 0x43, 0x46 }; + SetBuffer(item.StartSignature, sig, 4); + #endif + archivers.Add(item); + } + #endif + + #ifdef FORMAT_GZIP + { + CArchiverInfo item; + item.UpdateEnabled = true; + item.Name = L"GZip"; + item.Extensions.Add(CArchiverExtInfo(L"gz")); + item.Extensions.Add(CArchiverExtInfo(L"tgz", L".tar")); + #ifndef _SFX + const unsigned char sig[] = { 0x1F, 0x8B }; + SetBuffer(item.StartSignature, sig, 2); + #endif + archivers.Add(item); + } + #endif + + #ifdef FORMAT_SPLIT + { + CArchiverInfo item; + item.UpdateEnabled = false; + item.KeepName = true; + item.Name = L"Split"; + item.Extensions.Add(CArchiverExtInfo(L"001")); + archivers.Add(item); + } + #endif + + #ifdef FORMAT_TAR + { + CArchiverInfo item; + item.UpdateEnabled = true; + item.Name = L"Tar"; + item.Extensions.Add(CArchiverExtInfo(L"tar")); + archivers.Add(item); + } + #endif + + #ifdef FORMAT_ZIP + { + CArchiverInfo item; + item.UpdateEnabled = true; + item.Name = L"Zip"; + item.Extensions.Add(CArchiverExtInfo(L"zip")); + #ifndef _SFX + const unsigned char sig[] = { 0x50, 0x4B, 0x03, 0x04 }; + SetBuffer(item.StartSignature, sig, 4); + #endif + archivers.Add(item); + } + #endif + + #ifdef FORMAT_CPIO + { + CArchiverInfo item; + item.Name = L"Cpio"; + item.Extensions.Add(CArchiverExtInfo(L"cpio")); + archivers.Add(item); + } + #endif + + #ifdef FORMAT_RPM + { + CArchiverInfo item; + item.Name = L"Rpm"; + item.Extensions.Add(CArchiverExtInfo(L"rpm", L".cpio.gz")); + archivers.Add(item); + } + #endif + + #ifdef FORMAT_ARJ + { + CArchiverInfo item; + item.Name = L"Arj"; + item.Extensions.Add(CArchiverExtInfo(L"arj")); + #ifndef _SFX + const unsigned char sig[] = { 0x60, 0xEA }; + SetBuffer(item.StartSignature, sig, 2); + #endif + archivers.Add(item); + } + #endif + + #ifdef FORMAT_Z + { + CArchiverInfo item; + item.Name = L"Z"; + item.Extensions.Add(CArchiverExtInfo(L"Z")); + #ifndef _SFX + const unsigned char sig[] = { 0x1F, 0x9D }; + SetBuffer(item.StartSignature, sig, 2); + #endif + archivers.Add(item); + } + #endif + + #else + + UString folderPath = GetBaseFolderPrefixFromRegistry() + + (UString)kFormatFolderName + (UString)WSTRING_PATH_SEPARATOR; + NFind::CEnumeratorW enumerator(folderPath + L"*"); + NFind::CFileInfoW fileInfo; + while (enumerator.Next(fileInfo)) + { + if (fileInfo.IsDirectory()) + continue; + UString filePath = folderPath + fileInfo.Name; + { + NDLL::CLibrary library; + if (!library.LoadEx(filePath, LOAD_LIBRARY_AS_DATAFILE)) + continue; + } + + NDLL::CLibrary library; + if (!library.Load(filePath)) + continue; + GetHandlerPropertyFunc getHandlerProperty = (GetHandlerPropertyFunc) + library.GetProcAddress("GetHandlerProperty"); + if (getHandlerProperty == NULL) + continue; + + CArchiverInfo item; + item.FilePath = filePath; + + NWindows::NCOM::CPropVariant prop; + if (getHandlerProperty(NArchive::kName, &prop) != S_OK) + continue; + if (prop.vt != VT_BSTR) + continue; + item.Name = prop.bstrVal; + prop.Clear(); + + if (getHandlerProperty(NArchive::kClassID, &prop) != S_OK) + continue; + if (prop.vt != VT_BSTR) + continue; + item.ClassID = *(const GUID *)prop.bstrVal; + prop.Clear(); + + if (getHandlerProperty(NArchive::kExtension, &prop) != S_OK) + continue; + if (prop.vt != VT_BSTR) + continue; + + UString ext = prop.bstrVal; + UString addExt; + + prop.Clear(); + + if (getHandlerProperty(NArchive::kAddExtension, &prop) != S_OK) + continue; + if (prop.vt == VT_BSTR) + { + addExt = prop.bstrVal; + } + else if (prop.vt != VT_EMPTY) + continue; + prop.Clear(); + + UStringVector exts, addExts; + SplitString(ext, exts); + SplitString(addExt, addExts); + + prop.Clear(); + for (int i = 0; i < exts.Size(); i++) + { + CArchiverExtInfo extInfo; + extInfo.Ext = exts[i]; + if (addExts.Size() > 0) + extInfo.AddExt = addExts[i]; + if (extInfo.AddExt == L"*") + extInfo.AddExt.Empty(); + item.Extensions.Add(extInfo); + } + + if (getHandlerProperty(NArchive::kUpdate, &prop) == S_OK) + if (prop.vt == VT_BOOL) + item.UpdateEnabled = VARIANT_BOOLToBool(prop.boolVal); + prop.Clear(); + + if (item.UpdateEnabled) + { + if (getHandlerProperty(NArchive::kKeepName, &prop) == S_OK) + if (prop.vt == VT_BOOL) + item.KeepName = VARIANT_BOOLToBool(prop.boolVal); + prop.Clear(); + } + + if (getHandlerProperty(NArchive::kStartSignature, &prop) == S_OK) + { + if (prop.vt == VT_BSTR) + { + UINT len = ::SysStringByteLen(prop.bstrVal); + item.StartSignature.SetCapacity(len); + memmove(item.StartSignature, prop.bstrVal, len); + } + } + prop.Clear(); + + if (getHandlerProperty(NArchive::kAssociate, &prop) == S_OK) + if (prop.vt == VT_BOOL) + item.Associate = VARIANT_BOOLToBool(prop.boolVal); + prop.Clear(); + + + archivers.Add(item); + } + + #endif +} + + diff --git a/CPP/7zip/UI/Common/ArchiverInfo.h b/CPP/7zip/UI/Common/ArchiverInfo.h new file mode 100755 index 00000000..3b829518 --- /dev/null +++ b/CPP/7zip/UI/Common/ArchiverInfo.h @@ -0,0 +1,66 @@ +// ArchiverInfo.h + +#ifndef __ARCHIVERINFO_H +#define __ARCHIVERINFO_H + +#include "Common/String.h" +#include "Common/Types.h" +#include "Common/Buffer.h" + +struct CArchiverExtInfo +{ + UString Ext; + UString AddExt; + CArchiverExtInfo() {} + CArchiverExtInfo(const UString &ext): Ext(ext) {} + CArchiverExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {} +}; + +struct CArchiverInfo +{ + #ifndef EXCLUDE_COM + UString FilePath; + CLSID ClassID; + #endif + UString Name; + CObjectVector Extensions; + #ifndef _SFX + CByteBuffer StartSignature; + CByteBuffer FinishSignature; + bool Associate; + #endif + int FindExtension(const UString &ext) const + { + for (int i = 0; i < Extensions.Size(); i++) + if (ext.CompareNoCase(Extensions[i].Ext) == 0) + return i; + return -1; + } + UString GetAllExtensions() const + { + UString s; + for (int i = 0; i < Extensions.Size(); i++) + { + if (i > 0) + s += ' '; + s += Extensions[i].Ext; + } + return s; + } + const UString &GetMainExtension() const + { + return Extensions[0].Ext; + } + bool UpdateEnabled; + bool KeepName; + + CArchiverInfo(): UpdateEnabled(false), KeepName(false) + #ifndef _SFX + ,Associate(true) + #endif + {} +}; + +void ReadArchiverInfoList(CObjectVector &archivers); + +#endif diff --git a/CPP/7zip/UI/Common/CompressCall.cpp b/CPP/7zip/UI/Common/CompressCall.cpp new file mode 100755 index 00000000..86bdd297 --- /dev/null +++ b/CPP/7zip/UI/Common/CompressCall.cpp @@ -0,0 +1,367 @@ +// CompressCall.cpp + +#include "StdAfx.h" + +#include "CompressCall.h" + +#include "Common/Random.h" +#include "Common/IntToString.h" +#include "Common/MyCom.h" +#include "Common/StringConvert.h" + +#include "Windows/Synchronization.h" +#include "Windows/FileMapping.h" +#include "Windows/FileDir.h" + +#include "../../FileManager/ProgramLocation.h" +#include "../../FileManager/RegistryUtils.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif _UNICODE + +using namespace NWindows; + +static LPCWSTR kShowDialogSwitch = L" -ad"; +static LPCWSTR kEmailSwitch = L" -seml."; +static LPCWSTR kMapSwitch = L" -i#"; +static LPCWSTR kArchiveNoNameSwitch = L" -an"; +static LPCWSTR kArchiveTypeSwitch = L" -t"; +static LPCWSTR kArchiveMapSwitch = L" -ai#"; +static LPCWSTR kStopSwitchParsing = L" --"; +static LPCWSTR kLargePagesDisable = L" -slp-"; + +static void AddLagePagesSwitch(UString ¶ms) +{ + if (!ReadLockMemoryEnable()) + params += kLargePagesDisable; +} + +HRESULT MyCreateProcess(const UString ¶ms, + LPCWSTR curDir, bool waitFinish, + NWindows::NSynchronization::CEvent *event) +{ + const UString params2 = params; + PROCESS_INFORMATION processInformation; + BOOL result; + #ifndef _UNICODE + if (!g_IsNT) + { + STARTUPINFOA startupInfo; + startupInfo.cb = sizeof(startupInfo); + startupInfo.lpReserved = 0; + startupInfo.lpDesktop = 0; + startupInfo.lpTitle = 0; + startupInfo.dwFlags = 0; + startupInfo.cbReserved2 = 0; + startupInfo.lpReserved2 = 0; + + CSysString curDirA; + if (curDir != 0) + curDirA = GetSystemString(curDir); + result = ::CreateProcessA(NULL, (LPSTR)(LPCSTR)GetSystemString(params), + NULL, NULL, FALSE, 0, NULL, + ((curDir != 0) ? (LPCSTR)curDirA: 0), + &startupInfo, &processInformation); + } + else + #endif + { + STARTUPINFOW startupInfo; + startupInfo.cb = sizeof(startupInfo); + startupInfo.lpReserved = 0; + startupInfo.lpDesktop = 0; + startupInfo.lpTitle = 0; + startupInfo.dwFlags = 0; + startupInfo.cbReserved2 = 0; + startupInfo.lpReserved2 = 0; + + result = ::CreateProcessW(NULL, (LPWSTR)(LPCWSTR)params, + NULL, NULL, FALSE, 0, NULL, + curDir, + &startupInfo, &processInformation); + } + if (result == 0) + return ::GetLastError(); + else + { + ::CloseHandle(processInformation.hThread); + if (waitFinish) + WaitForSingleObject(processInformation.hProcess, INFINITE); + else if (event != NULL) + { + HANDLE handles[] = {processInformation.hProcess, *event }; + ::WaitForMultipleObjects(sizeof(handles) / sizeof(handles[0]), + handles, FALSE, INFINITE); + } + ::CloseHandle(processInformation.hProcess); + } + return S_OK; +} + +static UString GetQuotedString(const UString &s) +{ + return UString(L"\"") + s + UString(L"\""); +} + +static UString Get7zGuiPath() +{ + UString path; + UString folder; + if (GetProgramFolderPath(folder)) + path += folder; + path += L"7zG.exe"; + return GetQuotedString(path); +} + +static HRESULT CreateMap(const UStringVector &names, + const UString &id, + CFileMapping &fileMapping, NSynchronization::CEvent &event, + UString ¶ms) +{ + UInt32 extraSize = 2; + UInt32 dataSize = 0; + for (int i = 0; i < names.Size(); i++) + dataSize += (names[i].Length() + 1) * sizeof(wchar_t); + UInt32 totalSize = extraSize + dataSize; + + UString mappingName; + UString eventName; + + CRandom random; + random.Init(GetTickCount()); + for (;;) + { + int number = random.Generate(); + wchar_t temp[32]; + ConvertUInt64ToString(UInt32(number), temp); + mappingName = id; + mappingName += L"Mapping"; + mappingName += temp; + if (!fileMapping.Create(INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE, totalSize, GetSystemString(mappingName))) + return E_FAIL; + if (::GetLastError() != ERROR_ALREADY_EXISTS) + break; + fileMapping.Close(); + } + + for (;;) + { + int number = random.Generate(); + wchar_t temp[32]; + ConvertUInt64ToString(UInt32(number), temp); + eventName = id; + eventName += L"MappingEndEvent"; + eventName += temp; + if (!event.Create(true, false, GetSystemString(eventName))) + return E_FAIL; + if (::GetLastError() != ERROR_ALREADY_EXISTS) + break; + event.Close(); + } + + params += mappingName; + params += L":"; + wchar_t string[10]; + ConvertUInt64ToString(totalSize, string); + params += string; + + params += L":"; + params += eventName; + + LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_WRITE, 0, totalSize); + if (data == NULL) + return E_FAIL; + { + wchar_t *curData = (wchar_t *)data; + *curData = 0; + curData++; + for (int i = 0; i < names.Size(); i++) + { + const UString &s = names[i]; + memcpy(curData, (const wchar_t *)s, s.Length() * sizeof(wchar_t)); + curData += s.Length(); + *curData++ = L'\0'; + } + } + return S_OK; +} + +HRESULT CompressFiles( + const UString &curDir, + const UString &archiveName, + const UString &archiveType, + const UStringVector &names, + // const UString &outFolder, + bool email, + bool showDialog, + bool waitFinish) +{ + /* + UString curDir; + if (names.Size() > 0) + { + NFile::NDirectory::GetOnlyDirPrefix(names[0], curDir); + } + */ + UString params; + params = Get7zGuiPath(); + params += L" a"; + params += kMapSwitch; + // params += _fileNames[0]; + + UInt32 extraSize = 2; + UInt32 dataSize = 0; + for (int i = 0; i < names.Size(); i++) + dataSize += (names[i].Length() + 1) * sizeof(wchar_t); + UInt32 totalSize = extraSize + dataSize; + + UString mappingName; + UString eventName; + + CFileMapping fileMapping; + CRandom random; + random.Init(GetTickCount()); + for (;;) + { + int number = random.Generate(); + wchar_t temp[32]; + ConvertUInt64ToString(UInt32(number), temp); + mappingName = L"7zCompressMapping"; + mappingName += temp; + if (!fileMapping.Create(INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE, totalSize, GetSystemString(mappingName))) + { + // MyMessageBox(IDS_ERROR, 0x02000605); + return E_FAIL; + } + if (::GetLastError() != ERROR_ALREADY_EXISTS) + break; + fileMapping.Close(); + } + + NSynchronization::CEvent event; + for (;;) + { + int number = random.Generate(); + wchar_t temp[32]; + ConvertUInt64ToString(UInt32(number), temp); + eventName = L"7zCompressMappingEndEvent"; + eventName += temp; + if (!event.Create(true, false, GetSystemString(eventName))) + { + // MyMessageBox(IDS_ERROR, 0x02000605); + return E_FAIL; + } + if (::GetLastError() != ERROR_ALREADY_EXISTS) + break; + event.Close(); + } + + params += mappingName; + params += L":"; + wchar_t string[10]; + ConvertUInt64ToString(totalSize, string); + params += string; + + params += L":"; + params += eventName; + + if (!archiveType.IsEmpty()) + { + params += kArchiveTypeSwitch; + params += archiveType; + } + + if (email) + params += kEmailSwitch; + + if (showDialog) + params += kShowDialogSwitch; + + AddLagePagesSwitch(params); + + params += kStopSwitchParsing; + params += L" "; + + params += GetQuotedString(archiveName); + + LPVOID data = fileMapping.MapViewOfFile(FILE_MAP_WRITE, 0, totalSize); + if (data == NULL) + { + // MyMessageBox(IDS_ERROR, 0x02000605); + return E_FAIL; + } + try + { + wchar_t *curData = (wchar_t *)data; + *curData = 0; + curData++; + for (int i = 0; i < names.Size(); i++) + { + const UString &unicodeString = names[i]; + memcpy(curData, (const wchar_t *)unicodeString , + unicodeString .Length() * sizeof(wchar_t)); + curData += unicodeString.Length(); + *curData++ = L'\0'; + } + // MessageBox(0, params, 0, 0); + RINOK(MyCreateProcess(params, + (curDir.IsEmpty()? 0: (LPCWSTR)curDir), + waitFinish, &event)); + } + catch(...) + { + UnmapViewOfFile(data); + throw; + } + UnmapViewOfFile(data); + + + /* + CThreadCompressMain *compressor = new CThreadCompressMain();; + compressor->FileNames = _fileNames; + CThread thread; + if (!thread.Create(CThreadCompressMain::MyThreadFunction, compressor)) + throw 271824; + */ + return S_OK; +} + +static HRESULT ExtractGroupCommand(const UStringVector &archivePaths, + const UString ¶ms) +{ + UString params2 = params; + AddLagePagesSwitch(params2); + params2 += kArchiveNoNameSwitch; + params2 += kArchiveMapSwitch; + CFileMapping fileMapping; + NSynchronization::CEvent event; + RINOK(CreateMap(archivePaths, L"7zExtract", fileMapping, event, params2)); + return MyCreateProcess(params2, 0, false, &event); +} + +HRESULT ExtractArchives(const UStringVector &archivePaths, + const UString &outFolder, bool showDialog) +{ + UString params; + params = Get7zGuiPath(); + params += L" x"; + if (!outFolder.IsEmpty()) + { + params += L" -o"; + params += GetQuotedString(outFolder); + } + if (showDialog) + params += kShowDialogSwitch; + return ExtractGroupCommand(archivePaths, params); +} + +HRESULT TestArchives(const UStringVector &archivePaths) +{ + UString params; + params = Get7zGuiPath(); + params += L" t"; + return ExtractGroupCommand(archivePaths, params); +} diff --git a/CPP/7zip/UI/Common/CompressCall.h b/CPP/7zip/UI/Common/CompressCall.h new file mode 100755 index 00000000..95be95c3 --- /dev/null +++ b/CPP/7zip/UI/Common/CompressCall.h @@ -0,0 +1,28 @@ +// CompressCall.h + +#ifndef __COMPRESSCALL_H +#define __COMPRESSCALL_H + +#include "Common/String.h" +#include "Windows/Synchronization.h" + +HRESULT MyCreateProcess(const UString ¶ms, + LPCWSTR lpCurrentDirectory, bool waitFinish, + NWindows::NSynchronization::CEvent *event); + +HRESULT CompressFiles( + const UString &curDir, + const UString &archiveName, + const UString &archiveType, + const UStringVector &names, + // const UString &outFolder, + bool email, bool showDialog, bool waitFinish); + +HRESULT ExtractArchives( + const UStringVector &archivePaths, + const UString &outFolder, bool showDialog); + +HRESULT TestArchives(const UStringVector &archivePaths); + +#endif + diff --git a/CPP/7zip/UI/Common/DefaultName.cpp b/CPP/7zip/UI/Common/DefaultName.cpp new file mode 100755 index 00000000..8ee7c048 --- /dev/null +++ b/CPP/7zip/UI/Common/DefaultName.cpp @@ -0,0 +1,26 @@ +// DefaultName.cpp + +#include "StdAfx.h" + +#include "DefaultName.h" + +static const wchar_t *kEmptyFileAlias = L"[Content]"; + +UString GetDefaultName2(const UString &fileName, + const UString &extension, const UString &addSubExtension) +{ + int extLength = extension.Length(); + int fileNameLength = fileName.Length(); + if (fileNameLength > extLength + 1) + { + int dotPos = fileNameLength - (extLength + 1); + if (fileName[dotPos] == '.') + if (extension.CompareNoCase(fileName.Mid(dotPos + 1)) == 0) + return fileName.Left(dotPos) + addSubExtension; + } + int dotPos = fileName.ReverseFind(L'.'); + if (dotPos > 0) + return fileName.Left(dotPos) + addSubExtension; + return kEmptyFileAlias; +} + diff --git a/CPP/7zip/UI/Common/DefaultName.h b/CPP/7zip/UI/Common/DefaultName.h new file mode 100755 index 00000000..ff6330fa --- /dev/null +++ b/CPP/7zip/UI/Common/DefaultName.h @@ -0,0 +1,11 @@ +// DefaultName.h + +#ifndef __DEFAULTNAME_H +#define __DEFAULTNAME_H + +#include "Common/String.h" + +UString GetDefaultName2(const UString &fileName, + const UString &extension, const UString &addSubExtension); + +#endif diff --git a/CPP/7zip/UI/Common/DirItem.h b/CPP/7zip/UI/Common/DirItem.h new file mode 100755 index 00000000..9537071c --- /dev/null +++ b/CPP/7zip/UI/Common/DirItem.h @@ -0,0 +1,34 @@ +// DirItem.h + +#ifndef __DIR_ITEM_H +#define __DIR_ITEM_H + +#include "Common/String.h" +#include "Common/Types.h" + +struct CDirItem +{ + UInt32 Attributes; + FILETIME CreationTime; + FILETIME LastAccessTime; + FILETIME LastWriteTime; + UInt64 Size; + UString Name; + UString FullPath; + bool IsDirectory() const { return (Attributes & FILE_ATTRIBUTE_DIRECTORY) != 0 ; } +}; + +struct CArchiveItem +{ + bool IsDirectory; + // DWORD Attributes; + // NWindows::NCOM::CPropVariant LastWriteTime; + FILETIME LastWriteTime; + bool SizeIsDefined; + UInt64 Size; + UString Name; + bool Censored; + int IndexInServer; +}; + +#endif diff --git a/CPP/7zip/UI/Common/EnumDirItems.cpp b/CPP/7zip/UI/Common/EnumDirItems.cpp new file mode 100755 index 00000000..454092ec --- /dev/null +++ b/CPP/7zip/UI/Common/EnumDirItems.cpp @@ -0,0 +1,281 @@ +// EnumDirItems.cpp + +#include "StdAfx.h" + +#include "Common/StringConvert.h" +#include "Common/Wildcard.h" +#include "Common/MyCom.h" + +#include "EnumDirItems.h" + +using namespace NWindows; +using namespace NFile; +using namespace NName; + +void AddDirFileInfo( + const UString &prefix, // prefix for logical path + const UString &fullPathName, // path on disk: can be relative to some basePrefix + const NFind::CFileInfoW &fileInfo, + CObjectVector &dirItems) +{ + CDirItem item; + item.Attributes = fileInfo.Attributes; + item.Size = fileInfo.Size; + item.CreationTime = fileInfo.CreationTime; + item.LastAccessTime = fileInfo.LastAccessTime; + item.LastWriteTime = fileInfo.LastWriteTime; + item.Name = prefix + fileInfo.Name; + item.FullPath = fullPathName; + dirItems.Add(item); +} + +static void EnumerateDirectory( + const UString &baseFolderPrefix, // base (disk) prefix for scanning + const UString &directory, // additional disk prefix starting from baseFolderPrefix + const UString &prefix, // logical prefix + CObjectVector &dirItems, + UStringVector &errorPaths, + CRecordVector &errorCodes) +{ + NFind::CEnumeratorW enumerator(baseFolderPrefix + directory + wchar_t(kAnyStringWildcard)); + for (;;) + { + NFind::CFileInfoW fileInfo; + bool found; + if (!enumerator.Next(fileInfo, found)) + { + errorCodes.Add(::GetLastError()); + errorPaths.Add(baseFolderPrefix + directory); + return; + } + if (!found) + break; + AddDirFileInfo(prefix, directory + fileInfo.Name, fileInfo, dirItems); + if (fileInfo.IsDirectory()) + { + EnumerateDirectory(baseFolderPrefix, directory + fileInfo.Name + wchar_t(kDirDelimiter), + prefix + fileInfo.Name + wchar_t(kDirDelimiter), dirItems, errorPaths, errorCodes); + } + } +} + +void EnumerateDirItems( + const UString &baseFolderPrefix, // base (disk) prefix for scanning + const UStringVector &fileNames, // names relative to baseFolderPrefix + const UString &archiveNamePrefix, + CObjectVector &dirItems, + UStringVector &errorPaths, + CRecordVector &errorCodes) +{ + for(int i = 0; i < fileNames.Size(); i++) + { + const UString &fileName = fileNames[i]; + NFind::CFileInfoW fileInfo; + if (!NFind::FindFile(baseFolderPrefix + fileName, fileInfo)) + { + errorCodes.Add(::GetLastError()); + errorPaths.Add(baseFolderPrefix + fileName); + continue; + } + AddDirFileInfo(archiveNamePrefix, fileName, fileInfo, dirItems); + if (fileInfo.IsDirectory()) + { + EnumerateDirectory(baseFolderPrefix, fileName + wchar_t(kDirDelimiter), + archiveNamePrefix + fileInfo.Name + wchar_t(kDirDelimiter), + dirItems, errorPaths, errorCodes); + } + } +} + +static HRESULT EnumerateDirItems( + const NWildcard::CCensorNode &curNode, + const UString &diskPrefix, // full disk path prefix + const UString &archivePrefix, // prefix from root + const UStringVector &addArchivePrefix, // prefix from curNode + CObjectVector &dirItems, + bool enterToSubFolders, + IEnumDirItemCallback *callback, + UStringVector &errorPaths, + CRecordVector &errorCodes) +{ + if (!enterToSubFolders) + if (curNode.NeedCheckSubDirs()) + enterToSubFolders = true; + if (callback) + RINOK(callback->CheckBreak()); + + // try direct_names case at first + if (addArchivePrefix.IsEmpty() && !enterToSubFolders) + { + // check that all names are direct + int i; + for (i = 0; i < curNode.IncludeItems.Size(); i++) + { + const NWildcard::CItem &item = curNode.IncludeItems[i]; + if (item.Recursive || item.PathParts.Size() != 1) + break; + const UString &name = item.PathParts.Front(); + if (name.IsEmpty() || DoesNameContainWildCard(name)) + break; + } + if (i == curNode.IncludeItems.Size()) + { + // all names are direct (no wildcards) + // so we don't need file_system's dir enumerator + CRecordVector needEnterVector; + for (i = 0; i < curNode.IncludeItems.Size(); i++) + { + const NWildcard::CItem &item = curNode.IncludeItems[i]; + const UString &name = item.PathParts.Front(); + const UString fullPath = diskPrefix + name; + NFind::CFileInfoW fileInfo; + if (!NFind::FindFile(fullPath, fileInfo)) + { + errorCodes.Add(::GetLastError()); + errorPaths.Add(fullPath); + continue; + } + bool isDir = fileInfo.IsDirectory(); + if (isDir && !item.ForDir || !isDir && !item.ForFile) + { + errorCodes.Add((DWORD)E_FAIL); + errorPaths.Add(fullPath); + continue; + } + const UString realName = fileInfo.Name; + const UString realDiskPath = diskPrefix + realName; + { + UStringVector pathParts; + pathParts.Add(fileInfo.Name); + if (curNode.CheckPathToRoot(false, pathParts, !isDir)) + continue; + } + AddDirFileInfo(archivePrefix, realDiskPath, fileInfo, dirItems); + if (!isDir) + continue; + + UStringVector addArchivePrefixNew; + const NWildcard::CCensorNode *nextNode = 0; + int index = curNode.FindSubNode(name); + if (index >= 0) + { + for (int t = needEnterVector.Size(); t <= index; t++) + needEnterVector.Add(true); + needEnterVector[index] = false; + nextNode = &curNode.SubNodes[index]; + } + else + { + nextNode = &curNode; + addArchivePrefixNew.Add(name); // don't change it to realName. It's for shortnames support + } + RINOK(EnumerateDirItems(*nextNode, + realDiskPath + wchar_t(kDirDelimiter), + archivePrefix + realName + wchar_t(kDirDelimiter), + addArchivePrefixNew, dirItems, true, callback, errorPaths, errorCodes)); + } + for (i = 0; i < curNode.SubNodes.Size(); i++) + { + if (i < needEnterVector.Size()) + if (!needEnterVector[i]) + continue; + const NWildcard::CCensorNode &nextNode = curNode.SubNodes[i]; + const UString fullPath = diskPrefix + nextNode.Name; + NFind::CFileInfoW fileInfo; + if (!NFind::FindFile(fullPath, fileInfo)) + { + if (!nextNode.AreThereIncludeItems()) + continue; + errorCodes.Add(::GetLastError()); + errorPaths.Add(fullPath); + continue; + } + if (!fileInfo.IsDirectory()) + { + errorCodes.Add((DWORD)E_FAIL); + errorPaths.Add(fullPath); + continue; + } + RINOK(EnumerateDirItems(nextNode, + diskPrefix + fileInfo.Name + wchar_t(kDirDelimiter), + archivePrefix + fileInfo.Name + wchar_t(kDirDelimiter), + UStringVector(), dirItems, false, callback, errorPaths, errorCodes)); + } + return S_OK; + } + } + + + NFind::CEnumeratorW enumerator(diskPrefix + wchar_t(kAnyStringWildcard)); + for (;;) + { + NFind::CFileInfoW fileInfo; + bool found; + if (!enumerator.Next(fileInfo, found)) + { + errorCodes.Add(::GetLastError()); + errorPaths.Add(diskPrefix); + break; + } + if (!found) + break; + + if (callback) + RINOK(callback->CheckBreak()); + const UString &name = fileInfo.Name; + bool enterToSubFolders2 = enterToSubFolders; + UStringVector addArchivePrefixNew = addArchivePrefix; + addArchivePrefixNew.Add(name); + { + UStringVector addArchivePrefixNewTemp(addArchivePrefixNew); + if (curNode.CheckPathToRoot(false, addArchivePrefixNewTemp, !fileInfo.IsDirectory())) + continue; + } + if (curNode.CheckPathToRoot(true, addArchivePrefixNew, !fileInfo.IsDirectory())) + { + AddDirFileInfo(archivePrefix, diskPrefix + name, fileInfo, dirItems); + if (fileInfo.IsDirectory()) + enterToSubFolders2 = true; + } + if (!fileInfo.IsDirectory()) + continue; + + const NWildcard::CCensorNode *nextNode = 0; + if (addArchivePrefix.IsEmpty()) + { + int index = curNode.FindSubNode(name); + if (index >= 0) + nextNode = &curNode.SubNodes[index]; + } + if (!enterToSubFolders2 && nextNode == 0) + continue; + + addArchivePrefixNew = addArchivePrefix; + if (nextNode == 0) + { + nextNode = &curNode; + addArchivePrefixNew.Add(name); + } + RINOK(EnumerateDirItems(*nextNode, + diskPrefix + name + wchar_t(kDirDelimiter), + archivePrefix + name + wchar_t(kDirDelimiter), + addArchivePrefixNew, dirItems, enterToSubFolders2, callback, errorPaths, errorCodes)); + } + return S_OK; +} + +HRESULT EnumerateItems( + const NWildcard::CCensor &censor, + CObjectVector &dirItems, + IEnumDirItemCallback *callback, + UStringVector &errorPaths, + CRecordVector &errorCodes) +{ + for (int i = 0; i < censor.Pairs.Size(); i++) + { + const NWildcard::CPair &pair = censor.Pairs[i]; + RINOK(EnumerateDirItems(pair.Head, pair.Prefix, L"", UStringVector(), dirItems, false, + callback, errorPaths, errorCodes)); + } + return S_OK; +} diff --git a/CPP/7zip/UI/Common/EnumDirItems.h b/CPP/7zip/UI/Common/EnumDirItems.h new file mode 100755 index 00000000..8d5495a8 --- /dev/null +++ b/CPP/7zip/UI/Common/EnumDirItems.h @@ -0,0 +1,39 @@ +// EnumDirItems.h + +#ifndef __ENUM_DIR_ITEMS_H +#define __ENUM_DIR_ITEMS_H + +#include "Common/Wildcard.h" +#include "DirItem.h" + +#include "Windows/FileFind.h" + +void AddDirFileInfo( + const UString &prefix, + const UString &fullPathName, + const NWindows::NFile::NFind::CFileInfoW &fileInfo, + CObjectVector &dirItems); + + +void EnumerateDirItems( + const UString &baseFolderPrefix, + const UStringVector &fileNames, + const UString &archiveNamePrefix, + CObjectVector &dirItems, + UStringVector &errorPaths, + CRecordVector &errorCodes); + +struct IEnumDirItemCallback +{ + virtual HRESULT CheckBreak() { return S_OK; } +}; + + +HRESULT EnumerateItems( + const NWildcard::CCensor &censor, + CObjectVector &dirItems, + IEnumDirItemCallback *callback, + UStringVector &errorPaths, + CRecordVector &errorCodes); + +#endif diff --git a/CPP/7zip/UI/Common/ExitCode.h b/CPP/7zip/UI/Common/ExitCode.h new file mode 100755 index 00000000..0aac3695 --- /dev/null +++ b/CPP/7zip/UI/Common/ExitCode.h @@ -0,0 +1,27 @@ +// ExitCode.h + +#ifndef __EXIT_CODE_H +#define __EXIT_CODE_H + +namespace NExitCode { + +enum EEnum { + + kSuccess = 0, // Successful operation + kWarning = 1, // Non fatal error(s) occurred + kFatalError = 2, // A fatal error occurred + // kCRCError = 3, // A CRC error occurred when unpacking + // kLockedArchive = 4, // Attempt to modify an archive previously locked + // kWriteError = 5, // Write to disk error + // kOpenError = 6, // Open file error + kUserError = 7, // Command line option error + kMemoryError = 8, // Not enough memory for operation + // kCreateFileError = 9, // Create file error + + kUserBreak = 255 // User stopped the process + +}; + +} + +#endif diff --git a/CPP/7zip/UI/Common/Extract.cpp b/CPP/7zip/UI/Common/Extract.cpp new file mode 100755 index 00000000..34fb383b --- /dev/null +++ b/CPP/7zip/UI/Common/Extract.cpp @@ -0,0 +1,152 @@ +// Extract.cpp + +#include "StdAfx.h" + +#include "Extract.h" + +#include "Windows/Defs.h" +#include "Windows/FileDir.h" + +#include "OpenArchive.h" +#include "SetProperties.h" + +#ifndef EXCLUDE_COM +#include "Windows/DLL.h" +#endif + +using namespace NWindows; + +HRESULT DecompressArchive( + IInArchive *archive, + const UString &defaultName, + const NWildcard::CCensorNode &wildcardCensor, + const CExtractOptions &options, + IExtractCallbackUI *callback, + UString &errorMessage) +{ + CRecordVector realIndices; + UInt32 numItems; + RINOK(archive->GetNumberOfItems(&numItems)); + + for(UInt32 i = 0; i < numItems; i++) + { + UString filePath; + RINOK(GetArchiveItemPath(archive, i, options.DefaultItemName, filePath)); + bool isFolder; + RINOK(IsArchiveItemFolder(archive, i, isFolder)); + if (!wildcardCensor.CheckPath(filePath, !isFolder)) + continue; + realIndices.Add(i); + } + if (realIndices.Size() == 0) + { + callback->ThereAreNoFiles(); + return S_OK; + } + + CArchiveExtractCallback *extractCallbackSpec = new CArchiveExtractCallback; + CMyComPtr extractCallback(extractCallbackSpec); + + UStringVector removePathParts; + + UString outDir = options.OutputDir; + outDir.Replace(L"*", defaultName); + if(!outDir.IsEmpty()) + if(!NFile::NDirectory::CreateComplexDirectory(outDir)) + { + HRESULT res = ::GetLastError(); + if (res == S_OK) + res = E_FAIL; + errorMessage = ((UString)L"Can not create output directory ") + outDir; + return res; + } + + extractCallbackSpec->Init( + archive, + callback, + options.StdOutMode, + outDir, + options.PathMode, + options.OverwriteMode, + removePathParts, + options.DefaultItemName, + options.ArchiveFileInfo.LastWriteTime, + options.ArchiveFileInfo.Attributes); + + #ifdef COMPRESS_MT + RINOK(SetProperties(archive, options.Properties)); + #endif + + HRESULT result = archive->Extract(&realIndices.Front(), + realIndices.Size(), options.TestMode? 1: 0, + extractCallback); + + return callback->ExtractResult(result); +} + +HRESULT DecompressArchives( + UStringVector &archivePaths, UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + const CExtractOptions &optionsSpec, + IOpenCallbackUI *openCallback, + IExtractCallbackUI *extractCallback, + UString &errorMessage) +{ + CExtractOptions options = optionsSpec; + for (int i = 0; i < archivePaths.Size(); i++) + { + const UString &archivePath = archivePaths[i]; + NFile::NFind::CFileInfoW archiveFileInfo; + if (!NFile::NFind::FindFile(archivePath, archiveFileInfo)) + throw "there is no such archive"; + + if (archiveFileInfo.IsDirectory()) + throw "there is no such archive"; + + options.ArchiveFileInfo = archiveFileInfo; + + #ifndef _NO_CRYPTO + openCallback->ClearPasswordWasAskedFlag(); + #endif + + RINOK(extractCallback->BeforeOpen(archivePath)); + CArchiveLink archiveLink; + HRESULT result = MyOpenArchive(archivePath, archiveLink, openCallback); + + bool crypted = false; + #ifndef _NO_CRYPTO + crypted = openCallback->WasPasswordAsked(); + #endif + + RINOK(extractCallback->OpenResult(archivePath, result, crypted)); + if (result != S_OK) + continue; + + for (int v = 0; v < archiveLink.VolumePaths.Size(); v++) + { + int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]); + if (index >= 0 && index > i) + { + archivePaths.Delete(index); + archivePathsFull.Delete(index); + } + } + + #ifndef _NO_CRYPTO + UString password; + RINOK(openCallback->GetPasswordIfAny(password)); + if (!password.IsEmpty()) + { + RINOK(extractCallback->SetPassword(password)); + } + #endif + + options.DefaultItemName = archiveLink.GetDefaultItemName(); + RINOK(DecompressArchive( + archiveLink.GetArchive(), archiveLink.GetDefaultItemName(), + wildcardCensor, options, extractCallback, errorMessage)); + if (!errorMessage.IsEmpty()) + return E_FAIL; + } + return S_OK; +} diff --git a/CPP/7zip/UI/Common/Extract.h b/CPP/7zip/UI/Common/Extract.h new file mode 100755 index 00000000..c7b47c84 --- /dev/null +++ b/CPP/7zip/UI/Common/Extract.h @@ -0,0 +1,59 @@ +// Extract.h + +#ifndef __EXTRACT_H +#define __EXTRACT_H + +#include "Common/Wildcard.h" +#include "Windows/FileFind.h" + +#include "../../Archive/IArchive.h" + +#include "ArchiveExtractCallback.h" +#include "ArchiveOpenCallback.h" +#include "ExtractMode.h" +#include "Property.h" + +class CExtractOptions +{ +public: + bool StdOutMode; + bool TestMode; + NExtract::NPathMode::EEnum PathMode; + + UString OutputDir; + bool YesToAll; + UString DefaultItemName; + NWindows::NFile::NFind::CFileInfoW ArchiveFileInfo; + + // bool ShowDialog; + // bool PasswordEnabled; + // UString Password; + #ifdef COMPRESS_MT + CObjectVector Properties; + #endif + + NExtract::NOverwriteMode::EEnum OverwriteMode; + + CExtractOptions(): + StdOutMode(false), + YesToAll(false), + TestMode(false), + PathMode(NExtract::NPathMode::kFullPathnames), + OverwriteMode(NExtract::NOverwriteMode::kAskBefore) + {} + + /* + bool FullPathMode() const { return (ExtractMode == NExtractMode::kTest) || + (ExtractMode == NExtractMode::kFullPath); } + */ +}; + +HRESULT DecompressArchives( + UStringVector &archivePaths, UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + const CExtractOptions &options, + IOpenCallbackUI *openCallback, + IExtractCallbackUI *extractCallback, + UString &errorMessage); + +#endif diff --git a/CPP/7zip/UI/Common/ExtractMode.h b/CPP/7zip/UI/Common/ExtractMode.h new file mode 100755 index 00000000..96b5a8cd --- /dev/null +++ b/CPP/7zip/UI/Common/ExtractMode.h @@ -0,0 +1,31 @@ +// ExtractMode.h + +#ifndef __EXTRACT_MODE_H +#define __EXTRACT_MODE_H + +namespace NExtract { + + namespace NPathMode + { + enum EEnum + { + kFullPathnames, + kCurrentPathnames, + kNoPathnames + }; + } + + namespace NOverwriteMode + { + enum EEnum + { + kAskBefore, + kWithoutPrompt, + kSkipExisting, + kAutoRename, + kAutoRenameExisting + }; + } +} + +#endif diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.cpp b/CPP/7zip/UI/Common/ExtractingFilePath.cpp new file mode 100755 index 00000000..a0b17282 --- /dev/null +++ b/CPP/7zip/UI/Common/ExtractingFilePath.cpp @@ -0,0 +1,75 @@ +// ExtractingFilePath.cpp + +#include "StdAfx.h" +#include "ExtractingFilePath.h" + +static void ReplaceDisk(UString &s) +{ + int i; + for (i = 0; i < s.Length(); i++) + if (s[i] != ' ') + break; + if (s.Length() > i + 1) + { + if (s[i + 1] == L':') + { + s.Delete(i + 1); + // s.Insert(i + 1, L'_'); + } + } +} + +UString GetCorrectFileName(const UString &path) +{ + UString result = path; + { + UString test = path; + test.Trim(); + if (test == L"..") + result.Replace(L"..", L""); + } + ReplaceDisk(result); + return result; +} + +UString GetCorrectPath(const UString &path) +{ + UString result = path; + int first; + for (first = 0; first < result.Length(); first++) + if (result[first] != ' ') + break; + while(result.Length() > first) + { + if ( + #ifdef _WIN32 + result[first] == L'\\' || + #endif + result[first] == L'/') + { + result.Delete(first); + continue; + } + break; + } + #ifdef _WIN32 + result.Replace(L"..\\", L""); + #endif + result.Replace(L"../", L""); + + ReplaceDisk(result); + return result; +} + +void MakeCorrectPath(UStringVector &pathParts) +{ + for (int i = 0; i < pathParts.Size();) + { + UString &s = pathParts[i]; + s = GetCorrectFileName(s); + if (s.IsEmpty()) + pathParts.Delete(i); + else + i++; + } +} diff --git a/CPP/7zip/UI/Common/ExtractingFilePath.h b/CPP/7zip/UI/Common/ExtractingFilePath.h new file mode 100755 index 00000000..0ae9e9b8 --- /dev/null +++ b/CPP/7zip/UI/Common/ExtractingFilePath.h @@ -0,0 +1,12 @@ +// ExtractingFilePath.h + +#ifndef __EXTRACTINGFILEPATH_H +#define __EXTRACTINGFILEPATH_H + +#include "Common/String.h" + +UString GetCorrectFileName(const UString &path); +UString GetCorrectPath(const UString &path); +void MakeCorrectPath(UStringVector &pathParts); + +#endif diff --git a/CPP/7zip/UI/Common/HandlerLoader.h b/CPP/7zip/UI/Common/HandlerLoader.h new file mode 100755 index 00000000..2a878019 --- /dev/null +++ b/CPP/7zip/UI/Common/HandlerLoader.h @@ -0,0 +1,38 @@ +// HandlerLoader.h + +#ifndef __HANDLERLOADER_H +#define __HANDLERLOADER_H + +#include "../../ICoder.h" +#include "Windows/DLL.h" + +typedef UInt32 (WINAPI * CreateObjectFunc)( + const GUID *clsID, + const GUID *interfaceID, + void **outObject); + +class CHandlerLoader: public NWindows::NDLL::CLibrary +{ +public: + HRESULT CreateHandler(LPCWSTR filepath, REFGUID clsID, + void **archive, bool outHandler) + { + if (!Load(filepath)) + return GetLastError(); + CreateObjectFunc createObject = (CreateObjectFunc) + GetProcAddress("CreateObject"); + if (createObject == NULL) + { + HRESULT res = ::GetLastError(); + Free(); + return res; + } + HRESULT res = createObject(&clsID, + outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive); + if (res != 0) + Free(); + return res; + } +}; + +#endif diff --git a/CPP/7zip/UI/Common/IFileExtractCallback.h b/CPP/7zip/UI/Common/IFileExtractCallback.h new file mode 100755 index 00000000..c70d7021 --- /dev/null +++ b/CPP/7zip/UI/Common/IFileExtractCallback.h @@ -0,0 +1,46 @@ +// IFileExtractCallback.h + +#ifndef __IFILEEXTRACTCALLBACK_H +#define __IFILEEXTRACTCALLBACK_H + +#include "Common/String.h" + +namespace NOverwriteAnswer +{ + enum EEnum + { + kYes, + kYesToAll, + kNo, + kNoToAll, + kAutoRename, + kCancel, + }; +} + +// {23170F69-40C1-278A-0000-000100070000} +DEFINE_GUID(IID_IFolderArchiveExtractCallback, +0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00); +MIDL_INTERFACE("23170F69-40C1-278A-0000-000100070000") +IFolderArchiveExtractCallback: public IProgress +{ +public: + STDMETHOD(AskOverwrite)( + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, + Int32 *answer) PURE; + STDMETHOD(PrepareOperation)(const wchar_t *name, Int32 askExtractMode, const UInt64 *position) PURE; + STDMETHOD(MessageError)(const wchar_t *message) PURE; + STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted) PURE; +}; + +struct IExtractCallbackUI: IFolderArchiveExtractCallback +{ + virtual HRESULT BeforeOpen(const wchar_t *name) = 0; + virtual HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted) = 0; + virtual HRESULT ThereAreNoFiles() = 0; + virtual HRESULT ExtractResult(HRESULT result) = 0; + virtual HRESULT SetPassword(const UString &password) = 0; +}; + +#endif diff --git a/CPP/7zip/UI/Common/OpenArchive.cpp b/CPP/7zip/UI/Common/OpenArchive.cpp new file mode 100755 index 00000000..ce1a6de3 --- /dev/null +++ b/CPP/7zip/UI/Common/OpenArchive.cpp @@ -0,0 +1,531 @@ +// OpenArchive.cpp + +#include "StdAfx.h" + +#include "OpenArchive.h" + +#include "Common/Wildcard.h" + +#include "Windows/FileName.h" +#include "Windows/FileDir.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" + +#include "../../Common/FileStreams.h" +#include "../../Common/StreamUtils.h" + +#include "Common/StringConvert.h" + +#ifdef FORMAT_7Z +#include "../../Archive/7z/7zHandler.h" +#endif + +#ifdef FORMAT_BZIP2 +#include "../../Archive/BZip2/BZip2Handler.h" +#endif + +#ifdef FORMAT_CAB +#include "../../Archive/Cab/CabHandler.h" +#endif + +#ifdef FORMAT_GZIP +#include "../../Archive/GZip/GZipHandler.h" +#endif + +#ifdef FORMAT_SPLIT +#include "../../Archive/Split/SplitHandler.h" +#endif + +#ifdef FORMAT_TAR +#include "../../Archive/Tar/TarHandler.h" +#endif + +#ifdef FORMAT_ZIP +#include "../../Archive/Zip/ZipHandler.h" +#endif + +#ifdef FORMAT_Z +#include "../../Archive/Z/ZHandler.h" +#endif + +#ifndef EXCLUDE_COM +#include "HandlerLoader.h" +#endif + +#include "DefaultName.h" + +using namespace NWindows; + +HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result) +{ + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidPath, &prop)); + if(prop.vt == VT_BSTR) + result = prop.bstrVal; + else if (prop.vt == VT_EMPTY) + result.Empty(); + else + return E_FAIL; + return S_OK; +} + +HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result) +{ + RINOK(GetArchiveItemPath(archive, index, result)); + if (result.IsEmpty()) + result = defaultName; + return S_OK; +} + +HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index, + const FILETIME &defaultFileTime, FILETIME &fileTime) +{ + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, kpidLastWriteTime, &prop)); + if (prop.vt == VT_FILETIME) + fileTime = prop.filetime; + else if (prop.vt == VT_EMPTY) + fileTime = defaultFileTime; + else + return E_FAIL; + return S_OK; +} + +static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result) +{ + NCOM::CPropVariant prop; + RINOK(archive->GetProperty(index, propID, &prop)); + if(prop.vt == VT_BOOL) + result = VARIANT_BOOLToBool(prop.boolVal); + else if (prop.vt == VT_EMPTY) + result = false; + else + return E_FAIL; + return S_OK; +} + +HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result) +{ + return IsArchiveItemProp(archive, index, kpidIsFolder, result); +} + +HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result) +{ + return IsArchiveItemProp(archive, index, kpidIsAnti, result); +} + +// Static-SFX (for Linux) can be big. +const UInt64 kMaxCheckStartPosition = 1 << 22; + +HRESULT ReOpenArchive(IInArchive *archive, const UString &fileName) +{ + CInFileStream *inStreamSpec = new CInFileStream; + CMyComPtr inStream(inStreamSpec); + inStreamSpec->Open(fileName); + return archive->Open(inStream, &kMaxCheckStartPosition, NULL); +} + +#ifndef _SFX +static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size) +{ + for (size_t i = 0; i < size; i++) + if (p1[i] != p2[i]) + return false; + return true; +} +#endif + +HRESULT OpenArchive( + IInStream *inStream, + const UString &fileName, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archiveResult, + CArchiverInfo &archiverInfoResult, + UString &defaultItemName, + IArchiveOpenCallback *openArchiveCallback) +{ + *archiveResult = NULL; + CObjectVector archiverInfoList; + ReadArchiverInfoList(archiverInfoList); + UString extension; + { + int dotPos = fileName.ReverseFind(L'.'); + if (dotPos >= 0) + extension = fileName.Mid(dotPos + 1); + } + CIntVector orderIndices; + int i; + bool finded = false; + for(i = 0; i < archiverInfoList.Size(); i++) + { + if (archiverInfoList[i].FindExtension(extension) >= 0) + { + orderIndices.Insert(0, i); + finded = true; + } + else + orderIndices.Add(i); + } + + #ifndef _SFX + if (!finded) + { + CByteBuffer byteBuffer; + const UInt32 kBufferSize = (200 << 10); + byteBuffer.SetCapacity(kBufferSize); + Byte *buffer = byteBuffer; + RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); + UInt32 processedSize; + RINOK(ReadStream(inStream, buffer, kBufferSize, &processedSize)); + int numFinded = 0; + for (int pos = (int)processedSize; pos >= 0 ; pos--) + { + for(int i = numFinded; i < orderIndices.Size(); i++) + { + int index = orderIndices[i]; + const CArchiverInfo &ai = archiverInfoList[index]; + const CByteBuffer &sig = ai.StartSignature; + if (sig.GetCapacity() == 0) + continue; + if (pos + sig.GetCapacity() > processedSize) + continue; + if (TestSignature(buffer + pos, sig, sig.GetCapacity())) + { + orderIndices.Delete(i); + orderIndices.Insert(0, index); + numFinded++; + } + } + } + } + #endif + + HRESULT badResult = S_OK; + for(i = 0; i < orderIndices.Size(); i++) + { + inStream->Seek(0, STREAM_SEEK_SET, NULL); + const CArchiverInfo &archiverInfo = archiverInfoList[orderIndices[i]]; + #ifndef EXCLUDE_COM + CHandlerLoader loader; + #endif + CMyComPtr archive; + + #ifdef FORMAT_7Z + if (archiverInfo.Name.CompareNoCase(L"7z") == 0) + archive = new NArchive::N7z::CHandler; + #endif + + #ifdef FORMAT_BZIP2 + if (archiverInfo.Name.CompareNoCase(L"BZip2") == 0) + archive = new NArchive::NBZip2::CHandler; + #endif + + #ifdef FORMAT_CAB + if (archiverInfo.Name.CompareNoCase(L"Cab") == 0) + archive = new NArchive::NCab::CHandler; + #endif + + #ifdef FORMAT_GZIP + if (archiverInfo.Name.CompareNoCase(L"GZip") == 0) + archive = new NArchive::NGZip::CHandler; + #endif + + #ifdef FORMAT_SPLIT + if (archiverInfo.Name.CompareNoCase(L"Split") == 0) + archive = new NArchive::NSplit::CHandler; + #endif + + #ifdef FORMAT_TAR + if (archiverInfo.Name.CompareNoCase(L"Tar") == 0) + archive = new NArchive::NTar::CHandler; + #endif + + #ifdef FORMAT_ZIP + if (archiverInfo.Name.CompareNoCase(L"Zip") == 0) + archive = new NArchive::NZip::CHandler; + #endif + + #ifdef FORMAT_Z + if (archiverInfo.Name.CompareNoCase(L"Z") == 0) + archive = new NArchive::NZ::CHandler; + #endif + + + #ifndef EXCLUDE_COM + if (!archive) + { + HRESULT result = loader.CreateHandler(archiverInfo.FilePath, + archiverInfo.ClassID, (void **)&archive, false); + if (result != S_OK) + continue; + } + #endif + + if (!archive) + return E_FAIL; + + HRESULT result = archive->Open(inStream, &kMaxCheckStartPosition, openArchiveCallback); + if(result == S_FALSE) + continue; + if(result != S_OK) + { + badResult = result; + if(result == E_ABORT) + break; + continue; + } + *archiveResult = archive.Detach(); + #ifndef EXCLUDE_COM + *module = loader.Detach(); + #endif + archiverInfoResult = archiverInfo; + int subExtIndex = archiverInfo.FindExtension(extension); + if (subExtIndex < 0) + subExtIndex = 0; + defaultItemName = GetDefaultName2(fileName, + archiverInfo.Extensions[subExtIndex].Ext, + archiverInfo.Extensions[subExtIndex].AddExt); + + return S_OK; + } + if (badResult != S_OK) + return badResult; + return S_FALSE; +} + +HRESULT OpenArchive(const UString &filePath, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archiveResult, + CArchiverInfo &archiverInfo, + UString &defaultItemName, + IArchiveOpenCallback *openArchiveCallback) +{ + CInFileStream *inStreamSpec = new CInFileStream; + CMyComPtr inStream(inStreamSpec); + if (!inStreamSpec->Open(filePath)) + return GetLastError(); + return OpenArchive(inStream, ExtractFileNameFromPath(filePath), + #ifndef EXCLUDE_COM + module, + #endif + archiveResult, archiverInfo, + defaultItemName, openArchiveCallback); +} + +static void MakeDefaultName(UString &name) +{ + int dotPos = name.ReverseFind(L'.'); + if (dotPos < 0) + return; + UString ext = name.Mid(dotPos + 1); + if (ext.IsEmpty()) + return; + for (int pos = 0; pos < ext.Length(); pos++) + if (ext[pos] < L'0' || ext[pos] > L'9') + return; + name = name.Left(dotPos); +} + +HRESULT OpenArchive(const UString &fileName, + #ifndef EXCLUDE_COM + HMODULE *module0, + HMODULE *module1, + #endif + IInArchive **archive0, + IInArchive **archive1, + CArchiverInfo &archiverInfo0, + CArchiverInfo &archiverInfo1, + UString &defaultItemName0, + UString &defaultItemName1, + IArchiveOpenCallback *openArchiveCallback) +{ + HRESULT result = OpenArchive(fileName, + #ifndef EXCLUDE_COM + module0, + #endif + archive0, archiverInfo0, defaultItemName0, openArchiveCallback); + RINOK(result); + CMyComPtr getStream; + result = (*archive0)->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream); + if (result != S_OK || getStream == 0) + return S_OK; + + CMyComPtr subSeqStream; + result = getStream->GetStream(0, &subSeqStream); + if (result != S_OK) + return S_OK; + + CMyComPtr subStream; + if (subSeqStream.QueryInterface(IID_IInStream, &subStream) != S_OK) + return S_OK; + if (!subStream) + return S_OK; + + UInt32 numItems; + RINOK((*archive0)->GetNumberOfItems(&numItems)); + if (numItems < 1) + return S_OK; + + UString subPath; + RINOK(GetArchiveItemPath(*archive0, 0, subPath)) + if (subPath.IsEmpty()) + { + MakeDefaultName(defaultItemName0); + subPath = defaultItemName0; + if (archiverInfo0.Name.CompareNoCase(L"7z") == 0) + { + if (subPath.Right(3).CompareNoCase(L".7z") != 0) + subPath += L".7z"; + } + } + else + subPath = ExtractFileNameFromPath(subPath); + + CMyComPtr setSubArchiveName; + openArchiveCallback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName); + if (setSubArchiveName) + setSubArchiveName->SetSubArchiveName(subPath); + + result = OpenArchive(subStream, subPath, + #ifndef EXCLUDE_COM + module1, + #endif + archive1, archiverInfo1, defaultItemName1, openArchiveCallback); + return S_OK; +} + +HRESULT MyOpenArchive(const UString &archiveName, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archive, + UString &defaultItemName, + IOpenCallbackUI *openCallbackUI) +{ + COpenCallbackImp *openCallbackSpec = new COpenCallbackImp; + CMyComPtr openCallback = openCallbackSpec; + openCallbackSpec->Callback = openCallbackUI; + + UString fullName; + int fileNamePartStartIndex; + NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex); + openCallbackSpec->Init( + fullName.Left(fileNamePartStartIndex), + fullName.Mid(fileNamePartStartIndex)); + + CArchiverInfo archiverInfo; + return OpenArchive(archiveName, + #ifndef EXCLUDE_COM + module, + #endif + archive, + archiverInfo, + defaultItemName, + openCallback); +} + +HRESULT MyOpenArchive(const UString &archiveName, + #ifndef EXCLUDE_COM + HMODULE *module0, + HMODULE *module1, + #endif + IInArchive **archive0, + IInArchive **archive1, + UString &defaultItemName0, + UString &defaultItemName1, + UStringVector &volumePaths, + IOpenCallbackUI *openCallbackUI) +{ + COpenCallbackImp *openCallbackSpec = new COpenCallbackImp; + CMyComPtr openCallback = openCallbackSpec; + openCallbackSpec->Callback = openCallbackUI; + + UString fullName; + int fileNamePartStartIndex; + NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartIndex); + UString prefix = fullName.Left(fileNamePartStartIndex); + UString name = fullName.Mid(fileNamePartStartIndex); + openCallbackSpec->Init(prefix, name); + + CArchiverInfo archiverInfo0, archiverInfo1; + HRESULT result = OpenArchive(archiveName, + #ifndef EXCLUDE_COM + module0, + module1, + #endif + archive0, + archive1, + archiverInfo0, + archiverInfo1, + defaultItemName0, + defaultItemName1, + openCallback); + RINOK(result); + volumePaths.Add(prefix + name); + for (int i = 0; i < openCallbackSpec->FileNames.Size(); i++) + volumePaths.Add(prefix + openCallbackSpec->FileNames[i]); + return S_OK; +} + +HRESULT CArchiveLink::Close() +{ + if (Archive1 != 0) + RINOK(Archive1->Close()); + if (Archive0 != 0) + RINOK(Archive0->Close()); + return S_OK; +} + +void CArchiveLink::Release() +{ + if (Archive1 != 0) + Archive1.Release(); + if (Archive0 != 0) + Archive0.Release(); + #ifndef EXCLUDE_COM + Library1.Free(); + Library0.Free(); + #endif +} + +HRESULT OpenArchive(const UString &archiveName, + CArchiveLink &archiveLink, + IArchiveOpenCallback *openCallback) +{ + return OpenArchive(archiveName, + #ifndef EXCLUDE_COM + &archiveLink.Library0, &archiveLink.Library1, + #endif + &archiveLink.Archive0, &archiveLink.Archive1, + archiveLink.ArchiverInfo0, archiveLink.ArchiverInfo1, + archiveLink.DefaultItemName0, archiveLink.DefaultItemName1, + openCallback); +} + +HRESULT MyOpenArchive(const UString &archiveName, + CArchiveLink &archiveLink, + IOpenCallbackUI *openCallbackUI) +{ + return MyOpenArchive(archiveName, + #ifndef EXCLUDE_COM + &archiveLink.Library0, &archiveLink.Library1, + #endif + &archiveLink.Archive0, &archiveLink.Archive1, + archiveLink.DefaultItemName0, archiveLink.DefaultItemName1, + archiveLink.VolumePaths, + openCallbackUI); +} + +HRESULT ReOpenArchive(CArchiveLink &archiveLink, + const UString &fileName) +{ + if (archiveLink.GetNumLevels() > 1) + return E_NOTIMPL; + if (archiveLink.GetNumLevels() == 0) + return MyOpenArchive(fileName, archiveLink, 0); + return ReOpenArchive(archiveLink.GetArchive(), fileName); +} diff --git a/CPP/7zip/UI/Common/OpenArchive.h b/CPP/7zip/UI/Common/OpenArchive.h new file mode 100755 index 00000000..f96b1ebf --- /dev/null +++ b/CPP/7zip/UI/Common/OpenArchive.h @@ -0,0 +1,134 @@ +// OpenArchive.h + +#ifndef __OPENARCHIVE_H +#define __OPENARCHIVE_H + +#include "Common/String.h" +#include "Windows/FileFind.h" + +#include "../../Archive/IArchive.h" +#include "ArchiverInfo.h" +#include "ArchiveOpenCallback.h" + +#ifndef EXCLUDE_COM +#include "Windows/DLL.h" +#endif + +HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result); +HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &defaultName, UString &result); +HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index, + const FILETIME &defaultFileTime, FILETIME &fileTime); +HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result); +HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result); + +struct ISetSubArchiveName +{ + virtual void SetSubArchiveName(const wchar_t *name) = 0; +}; + +HRESULT OpenArchive( + IInStream *inStream, + const UString &fileName, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archiveResult, + CArchiverInfo &archiverInfoResult, + UString &defaultItemName, + IArchiveOpenCallback *openArchiveCallback); + +HRESULT OpenArchive(const UString &filePath, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archive, + CArchiverInfo &archiverInfo, + UString &defaultItemName, + IArchiveOpenCallback *openArchiveCallback); + +HRESULT OpenArchive(const UString &filePath, + #ifndef EXCLUDE_COM + HMODULE *module0, + HMODULE *module1, + #endif + IInArchive **archive0, + IInArchive **archive1, + CArchiverInfo &archiverInfo0, + CArchiverInfo &archiverInfo1, + UString &defaultItemName0, + UString &defaultItemName1, + IArchiveOpenCallback *openArchiveCallback); + + +HRESULT ReOpenArchive(IInArchive *archive, + const UString &fileName); + +HRESULT MyOpenArchive(const UString &archiveName, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archive, + UString &defaultItemName, + IOpenCallbackUI *openCallbackUI); + +HRESULT MyOpenArchive(const UString &archiveName, + #ifndef EXCLUDE_COM + HMODULE *module0, + HMODULE *module1, + #endif + IInArchive **archive0, + IInArchive **archive1, + UString &defaultItemName0, + UString &defaultItemName1, + UStringVector &volumePaths, + IOpenCallbackUI *openCallbackUI); + +struct CArchiveLink +{ + #ifndef EXCLUDE_COM + NWindows::NDLL::CLibrary Library0; + NWindows::NDLL::CLibrary Library1; + #endif + CMyComPtr Archive0; + CMyComPtr Archive1; + UString DefaultItemName0; + UString DefaultItemName1; + + CArchiverInfo ArchiverInfo0; + CArchiverInfo ArchiverInfo1; + + UStringVector VolumePaths; + + int GetNumLevels() const + { + int result = 0; + if (Archive0) + { + result++; + if (Archive1) + result++; + } + return result; + } + + + IInArchive *GetArchive() { return Archive1 != 0 ? Archive1: Archive0; } + UString GetDefaultItemName() { return Archive1 != 0 ? DefaultItemName1: DefaultItemName0; } + const CArchiverInfo &GetArchiverInfo() { return Archive1 != 0 ? ArchiverInfo1: ArchiverInfo0; } + HRESULT Close(); + void Release(); +}; + +HRESULT OpenArchive(const UString &archiveName, + CArchiveLink &archiveLink, + IArchiveOpenCallback *openCallback); + +HRESULT MyOpenArchive(const UString &archiveName, + CArchiveLink &archiveLink, + IOpenCallbackUI *openCallbackUI); + +HRESULT ReOpenArchive(CArchiveLink &archiveLink, + const UString &fileName); + +#endif + diff --git a/CPP/7zip/UI/Common/PropIDUtils.cpp b/CPP/7zip/UI/Common/PropIDUtils.cpp new file mode 100755 index 00000000..8869e565 --- /dev/null +++ b/CPP/7zip/UI/Common/PropIDUtils.cpp @@ -0,0 +1,90 @@ +// PropIDUtils.cpp + +#include "StdAfx.h" + +#include "PropIDUtils.h" + +#include "Common/IntToString.h" +#include "Common/StringConvert.h" + +#include "Windows/FileFind.h" +#include "Windows/PropVariantConversions.h" + +#include "../../PropID.h" + +using namespace NWindows; + +static UString ConvertUInt32ToString(UInt32 value) +{ + wchar_t buffer[32]; + ConvertUInt64ToString(value, buffer); + return buffer; +} + +static void ConvertUInt32ToHex(UInt32 value, wchar_t *s) +{ + for (int i = 0; i < 8; i++) + { + int t = value & 0xF; + value >>= 4; + s[7 - i] = (wchar_t)((t < 10) ? (L'0' + t) : (L'A' + (t - 10))); + } + s[8] = L'\0'; +} + +UString ConvertPropertyToString(const PROPVARIANT &propVariant, + PROPID propID, bool full) +{ + switch(propID) + { + case kpidCreationTime: + case kpidLastWriteTime: + case kpidLastAccessTime: + { + if (propVariant.vt != VT_FILETIME) + return UString(); // It is error; + FILETIME localFileTime; + if (propVariant.filetime.dwHighDateTime == 0 && + propVariant.filetime.dwLowDateTime == 0) + return UString(); + if (!::FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime)) + return UString(); // It is error; + return ConvertFileTimeToString(localFileTime, true, full); + } + case kpidCRC: + { + if(propVariant.vt != VT_UI4) + break; + wchar_t temp[12]; + ConvertUInt32ToHex(propVariant.ulVal, temp); + return temp; + } + case kpidAttributes: + { + if(propVariant.vt != VT_UI4) + break; + UString result; + UInt32 attributes = propVariant.ulVal; + if (NFile::NFind::NAttributes::IsReadOnly(attributes)) result += L'R'; + if (NFile::NFind::NAttributes::IsHidden(attributes)) result += L'H'; + if (NFile::NFind::NAttributes::IsSystem(attributes)) result += L'S'; + if (NFile::NFind::NAttributes::IsDirectory(attributes)) result += L'D'; + if (NFile::NFind::NAttributes::IsArchived(attributes)) result += L'A'; + if (NFile::NFind::NAttributes::IsCompressed(attributes)) result += L'C'; + if (NFile::NFind::NAttributes::IsEncrypted(attributes)) result += L'E'; + return result; + } + case kpidDictionarySize: + { + if(propVariant.vt != VT_UI4) + break; + UInt32 size = propVariant.ulVal; + if (size % (1 << 20) == 0) + return ConvertUInt32ToString(size >> 20) + L"MB"; + if (size % (1 << 10) == 0) + return ConvertUInt32ToString(size >> 10) + L"KB"; + return ConvertUInt32ToString(size); + } + } + return ConvertPropVariantToString(propVariant); +} diff --git a/CPP/7zip/UI/Common/PropIDUtils.h b/CPP/7zip/UI/Common/PropIDUtils.h new file mode 100755 index 00000000..aa540885 --- /dev/null +++ b/CPP/7zip/UI/Common/PropIDUtils.h @@ -0,0 +1,11 @@ +// PropIDUtils.h + +#ifndef __PROPIDUTILS_H +#define __PROPIDUTILS_H + +#include "Common/String.h" + +UString ConvertPropertyToString(const PROPVARIANT &aPropVariant, + PROPID aPropID, bool aFull = true); + +#endif diff --git a/CPP/7zip/UI/Common/Property.h b/CPP/7zip/UI/Common/Property.h new file mode 100755 index 00000000..57e7b452 --- /dev/null +++ b/CPP/7zip/UI/Common/Property.h @@ -0,0 +1,14 @@ +// Property.h + +#ifndef __PROPERTY_H +#define __PROPERTY_H + +#include "Common/String.h" + +struct CProperty +{ + UString Name; + UString Value; +}; + +#endif diff --git a/CPP/7zip/UI/Common/SetProperties.cpp b/CPP/7zip/UI/Common/SetProperties.cpp new file mode 100755 index 00000000..6c92a847 --- /dev/null +++ b/CPP/7zip/UI/Common/SetProperties.cpp @@ -0,0 +1,65 @@ +// SetProperties.cpp + +#include "StdAfx.h" + +#include "SetProperties.h" + +#include "Windows/PropVariant.h" +#include "Common/String.h" +#include "Common/StringToInt.h" +#include "Common/MyCom.h" + +#include "../../Archive/IArchive.h" + +using namespace NWindows; +using namespace NCOM; + +static void ParseNumberString(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 SetProperties(IUnknown *unknown, const CObjectVector &properties) +{ + if (properties.IsEmpty()) + return S_OK; + CMyComPtr setProperties; + unknown->QueryInterface(IID_ISetProperties, (void **)&setProperties); + if (!setProperties) + return S_OK; + + UStringVector realNames; + CPropVariant *values = new CPropVariant[properties.Size()]; + try + { + int i; + for(i = 0; i < properties.Size(); i++) + { + const CProperty &property = properties[i]; + NCOM::CPropVariant propVariant; + if (!property.Value.IsEmpty()) + ParseNumberString(property.Value, propVariant); + realNames.Add(property.Name); + values[i] = propVariant; + } + CRecordVector names; + for(i = 0; i < realNames.Size(); i++) + names.Add((const wchar_t *)realNames[i]); + + RINOK(setProperties->SetProperties(&names.Front(), values, names.Size())); + } + catch(...) + { + delete []values; + throw; + } + delete []values; + return S_OK; +} diff --git a/CPP/7zip/UI/Common/SetProperties.h b/CPP/7zip/UI/Common/SetProperties.h new file mode 100755 index 00000000..892f1a21 --- /dev/null +++ b/CPP/7zip/UI/Common/SetProperties.h @@ -0,0 +1,10 @@ +// SetProperties.h + +#ifndef __SETPROPERTIES_H +#define __SETPROPERTIES_H + +#include "Property.h" + +HRESULT SetProperties(IUnknown *unknown, const CObjectVector &properties); + +#endif diff --git a/CPP/7zip/UI/Common/SortUtils.cpp b/CPP/7zip/UI/Common/SortUtils.cpp new file mode 100755 index 00000000..c0111581 --- /dev/null +++ b/CPP/7zip/UI/Common/SortUtils.cpp @@ -0,0 +1,78 @@ +// SortUtils.cpp + +#include "StdAfx.h" + +#include "SortUtils.h" +#include "Common/Types.h" + +/* +template +void TSortRefDown(T *p, UInt32 k, UInt32 size, int (*compare)(const T*, const T*, void *), void *param) +{ + T temp = p[k]; + for (;;) + { + UInt32 s = (k << 1); + if (s > size) + break; + if (s < size && compare(p + s + 1, p + s, param) > 0) + s++; + if (compare(&temp, p + s, param) >= 0) + break; + p[k] = p[s]; + k = s; + } + p[k] = temp; +} + +template +void TSort(T* p, UInt32 size, int (*compare)(const T*, const T*, void *), void *param) +{ + if (size <= 1) + return; + p--; + { + UInt32 i = size / 2; + do + TSortRefDown(p, i, size, compare, param); + while(--i != 0); + } + do + { + T temp = p[size]; + p[size--] = p[1]; + p[1] = temp; + TSortRefDown(p, 1, size, compare, param); + } + while (size > 1); +} +*/ + +static int CompareStrings(const int *p1, const int *p2, void *param) +{ + const UStringVector &strings = *(const UStringVector *)param; + const UString &s1 = strings[*p1]; + const UString &s2 = strings[*p2]; + return s1.CompareNoCase(s2); +} + +void SortStringsToIndices(const UStringVector &strings, CIntVector &indices) +{ + indices.Clear(); + int numItems = strings.Size(); + indices.Reserve(numItems); + for(int i = 0; i < numItems; i++) + indices.Add(i); + indices.Sort(CompareStrings, (void *)&strings); + // TSort(&indices.Front(), indices.Size(), CompareStrings, (void *)&strings); +} + +void SortStrings(const UStringVector &src, UStringVector &dest) +{ + CIntVector indices; + SortStringsToIndices(src, indices); + dest.Clear(); + dest.Reserve(indices.Size()); + for (int i = 0; i < indices.Size(); i++) + dest.Add(src[indices[i]]); +} diff --git a/CPP/7zip/UI/Common/SortUtils.h b/CPP/7zip/UI/Common/SortUtils.h new file mode 100755 index 00000000..5b9af264 --- /dev/null +++ b/CPP/7zip/UI/Common/SortUtils.h @@ -0,0 +1,11 @@ +// SortUtils.h + +#ifndef __SORTUTLS_H +#define __SORTUTLS_H + +#include "Common/String.h" + +void SortStringsToIndices(const UStringVector &strings, CIntVector &indices); +void SortStrings(const UStringVector &src, UStringVector &dest); + +#endif diff --git a/CPP/7zip/UI/Common/StdAfx.h b/CPP/7zip/UI/Common/StdAfx.h new file mode 100755 index 00000000..100f4344 --- /dev/null +++ b/CPP/7zip/UI/Common/StdAfx.h @@ -0,0 +1,9 @@ +// stdafx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/UI/Common/TempFiles.cpp b/CPP/7zip/UI/Common/TempFiles.cpp new file mode 100755 index 00000000..3e604aea --- /dev/null +++ b/CPP/7zip/UI/Common/TempFiles.cpp @@ -0,0 +1,22 @@ +// TempFiles.cpp + +#include "StdAfx.h" + +#include "TempFiles.h" + +#include "Windows/FileDir.h" +#include "Windows/FileIO.h" + +using namespace NWindows; +using namespace NFile; + +void CTempFiles::Clear() +{ + while(!Paths.IsEmpty()) + { + NDirectory::DeleteFileAlways(Paths.Back()); + Paths.DeleteBack(); + } +} + + diff --git a/CPP/7zip/UI/Common/TempFiles.h b/CPP/7zip/UI/Common/TempFiles.h new file mode 100755 index 00000000..173713a0 --- /dev/null +++ b/CPP/7zip/UI/Common/TempFiles.h @@ -0,0 +1,16 @@ +// TempFiles.h + +#ifndef __TEMPFILES_H +#define __TEMPFILES_H + +#include "Common/String.h" + +class CTempFiles +{ + void Clear(); +public: + UStringVector Paths; + ~CTempFiles() { Clear(); } +}; + +#endif diff --git a/CPP/7zip/UI/Common/Update.cpp b/CPP/7zip/UI/Common/Update.cpp new file mode 100755 index 00000000..cd7975d0 --- /dev/null +++ b/CPP/7zip/UI/Common/Update.cpp @@ -0,0 +1,818 @@ +// Update.cpp + +#include "StdAfx.h" + +#ifdef _WIN32 +#include +#endif + +#include "Update.h" + +#include "Common/IntToString.h" +#include "Common/StringConvert.h" +#include "Common/CommandLineParser.h" + +#ifdef _WIN32 +#include "Windows/DLL.h" +#endif + +#include "Windows/Defs.h" +#include "Windows/FileDir.h" +#include "Windows/FileFind.h" +#include "Windows/FileName.h" +#include "Windows/PropVariant.h" +#include "Windows/PropVariantConversions.h" +// #include "Windows/Synchronization.h" + +#include "../../Common/FileStreams.h" +#include "../../Compress/Copy/CopyCoder.h" + +#include "../Common/DirItem.h" +#include "../Common/EnumDirItems.h" +#include "../Common/UpdateProduce.h" +#include "../Common/OpenArchive.h" + +#include "TempFiles.h" +#include "UpdateCallback.h" +#include "EnumDirItems.h" +#include "SetProperties.h" + +#ifdef FORMAT_7Z +#include "../../Archive/7z/7zHandler.h" +#endif + +#ifdef FORMAT_BZIP2 +#include "../../Archive/BZip2/BZip2Handler.h" +#endif + +#ifdef FORMAT_GZIP +#include "../../Archive/GZip/GZipHandler.h" +#endif + +#ifdef FORMAT_TAR +#include "../../Archive/Tar/TarHandler.h" +#endif + +#ifdef FORMAT_ZIP +#include "../../Archive/Zip/ZipHandler.h" +#endif + +#ifndef EXCLUDE_COM +#include "../Common/HandlerLoader.h" +#endif + +static const char *kUpdateIsNotSupoorted = + "update operations are not supported for this archive"; + +using namespace NCommandLineParser; +using namespace NWindows; +using namespace NCOM; +using namespace NFile; +using namespace NName; + +static const wchar_t *kTempArchiveFilePrefixString = L"7zi"; +static const wchar_t *kTempFolderPrefix = L"7zE"; + +static const char *kIllegalFileNameMessage = "Illegal file name for temp archive"; + +using namespace NUpdateArchive; + +static HRESULT CopyBlock(ISequentialInStream *inStream, ISequentialOutStream *outStream) +{ + CMyComPtr copyCoder = new NCompress::CCopyCoder; + return copyCoder->Code(inStream, outStream, NULL, NULL, NULL); +} + +class COutMultiVolStream: + public IOutStream, + public CMyUnknownImp +{ + int _streamIndex; // required stream + UInt64 _offsetPos; // offset from start of _streamIndex index + UInt64 _absPos; + UInt64 _length; + + struct CSubStreamInfo + { + CMyComPtr Stream; + UString Name; + UInt64 Pos; + UInt64 RealSize; + }; + CObjectVector Streams; +public: + // CMyComPtr VolumeCallback; + CRecordVector Sizes; + UString Prefix; + CTempFiles *TempFiles; + + void Init() + { + _streamIndex = 0; + _offsetPos = 0; + _absPos = 0; + _length = 0; + } + + MY_UNKNOWN_IMP1(IOutStream) + + STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); + STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); + STDMETHOD(SetSize)(Int64 newSize); +}; + +// static NSynchronization::CCriticalSection g_TempPathsCS; + +STDMETHODIMP COutMultiVolStream::Write(const void *data, UInt32 size, UInt32 *processedSize) +{ + if(processedSize != NULL) + *processedSize = 0; + while(size > 0) + { + if (_streamIndex >= Streams.Size()) + { + CSubStreamInfo subStream; + + wchar_t temp[32]; + ConvertUInt64ToString(_streamIndex + 1, temp); + UString res = temp; + while (res.Length() < 3) + res = UString(L'0') + res; + UString name = Prefix + res; + COutFileStream *streamSpec = new COutFileStream; + subStream.Stream = streamSpec; + if(!streamSpec->Create(name, false)) + return ::GetLastError(); + { + // NSynchronization::CCriticalSectionLock lock(g_TempPathsCS); + TempFiles->Paths.Add(name); + } + + subStream.Pos = 0; + subStream.RealSize = 0; + subStream.Name = name; + Streams.Add(subStream); + continue; + } + CSubStreamInfo &subStream = Streams[_streamIndex]; + + int index = _streamIndex; + if (index >= Sizes.Size()) + index = Sizes.Size() - 1; + UInt64 volSize = Sizes[index]; + + if (_offsetPos >= volSize) + { + _offsetPos -= volSize; + _streamIndex++; + continue; + } + if (_offsetPos != subStream.Pos) + { + // CMyComPtr outStream; + // RINOK(subStream.Stream.QueryInterface(IID_IOutStream, &outStream)); + RINOK(subStream.Stream->Seek(_offsetPos, STREAM_SEEK_SET, NULL)); + subStream.Pos = _offsetPos; + } + + UInt32 curSize = (UInt32)MyMin((UInt64)size, volSize - subStream.Pos); + UInt32 realProcessed; + RINOK(subStream.Stream->Write(data, curSize, &realProcessed)); + data = (void *)((Byte *)data + realProcessed); + size -= realProcessed; + subStream.Pos += realProcessed; + _offsetPos += realProcessed; + _absPos += realProcessed; + if (_absPos > _length) + _length = _absPos; + if (_offsetPos > subStream.RealSize) + subStream.RealSize = _offsetPos; + if(processedSize != NULL) + *processedSize += realProcessed; + if (subStream.Pos == volSize) + { + _streamIndex++; + _offsetPos = 0; + } + if (realProcessed == 0 && curSize != 0) + return E_FAIL; + break; + } + return S_OK; +} + +STDMETHODIMP COutMultiVolStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) +{ + if(seekOrigin >= 3) + return STG_E_INVALIDFUNCTION; + switch(seekOrigin) + { + case STREAM_SEEK_SET: + _absPos = offset; + break; + case STREAM_SEEK_CUR: + _absPos += offset; + break; + case STREAM_SEEK_END: + _absPos = _length + offset; + break; + } + _offsetPos = _absPos; + if (newPosition != NULL) + *newPosition = _absPos; + _streamIndex = 0; + return S_OK; +} + +STDMETHODIMP COutMultiVolStream::SetSize(Int64 newSize) +{ + if (newSize < 0) + return E_INVALIDARG; + int i = 0; + while (i < Streams.Size()) + { + CSubStreamInfo &subStream = Streams[i++]; + if ((UInt64)newSize < subStream.RealSize) + { + RINOK(subStream.Stream->SetSize(newSize)); + subStream.RealSize = newSize; + break; + } + newSize -= subStream.RealSize; + } + while (i < Streams.Size()) + { + { + CSubStreamInfo &subStream = Streams.Back(); + subStream.Stream.Release(); + NDirectory::DeleteFileAlways(subStream.Name); + } + Streams.DeleteBack(); + } + _offsetPos = _absPos; + _streamIndex = 0; + _length = newSize; + return S_OK; +} + + +static HRESULT Compress( + const CActionSet &actionSet, + IInArchive *archive, + const CCompressionMethodMode &compressionMethod, + CArchivePath &archivePath, + const CObjectVector &archiveItems, + bool stdInMode, + /* const UString & stdInFileName, */ + bool stdOutMode, + const CObjectVector &dirItems, + bool sfxMode, + const UString &sfxModule, + const CRecordVector &volumesSizes, + CTempFiles &tempFiles, + CUpdateErrorInfo &errorInfo, + IUpdateCallbackUI *callback) +{ + #ifndef EXCLUDE_COM + CHandlerLoader loader; + #endif + + CMyComPtr outArchive; + if(archive != NULL) + { + CMyComPtr archive2 = archive; + HRESULT result = archive2.QueryInterface(IID_IOutArchive, &outArchive); + if(result != S_OK) + throw kUpdateIsNotSupoorted; + } + else + { + #ifndef EXCLUDE_COM + + if (loader.CreateHandler(compressionMethod.FilePath, + compressionMethod.ClassID, (void **)&outArchive, true) != S_OK) + throw kUpdateIsNotSupoorted; + #endif + + #ifdef FORMAT_7Z + if (compressionMethod.Name.CompareNoCase(L"7z") == 0) + outArchive = new NArchive::N7z::CHandler; + #endif + + #ifdef FORMAT_BZIP2 + if (compressionMethod.Name.CompareNoCase(L"BZip2") == 0) + outArchive = new NArchive::NBZip2::CHandler; + #endif + + #ifdef FORMAT_GZIP + if (compressionMethod.Name.CompareNoCase(L"GZip") == 0) + outArchive = new NArchive::NGZip::CHandler; + #endif + + #ifdef FORMAT_TAR + if (compressionMethod.Name.CompareNoCase(L"Tar") == 0) + outArchive = new NArchive::NTar::CHandler; + #endif + + #ifdef FORMAT_ZIP + if (compressionMethod.Name.CompareNoCase(L"Zip") == 0) + outArchive = new NArchive::NZip::CHandler; + #endif + + } + if (outArchive == 0) + throw kUpdateIsNotSupoorted; + + NFileTimeType::EEnum fileTimeType; + UInt32 value; + RINOK(outArchive->GetFileTimeType(&value)); + + switch(value) + { + case NFileTimeType::kWindows: + case NFileTimeType::kDOS: + case NFileTimeType::kUnix: + fileTimeType = NFileTimeType::EEnum(value); + break; + default: + return E_FAIL; + } + + CObjectVector updatePairs; + GetUpdatePairInfoList(dirItems, archiveItems, fileTimeType, updatePairs); // must be done only once!!! + + CObjectVector updatePairs2; + UpdateProduce(updatePairs, actionSet, updatePairs2); + + CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback; + CMyComPtr updateCallback(updateCallbackSpec ); + + updateCallbackSpec->StdInMode = stdInMode; + updateCallbackSpec->Callback = callback; + updateCallbackSpec->DirItems = &dirItems; + updateCallbackSpec->ArchiveItems = &archiveItems; + updateCallbackSpec->UpdatePairs = &updatePairs2; + + CMyComPtr outStream; + + const UString &archiveName = archivePath.GetFinalPath(); + if (!stdOutMode) + { + UString resultPath; + int pos; + if(!NFile::NDirectory::MyGetFullPathName(archiveName, resultPath, pos)) + throw 1417161; + NFile::NDirectory::CreateComplexDirectory(resultPath.Left(pos)); + } + if (volumesSizes.Size() == 0) + { + if (stdOutMode) + outStream = new CStdOutFileStream; + else + { + COutFileStream *outStreamSpec = new COutFileStream; + outStream = outStreamSpec; + bool isOK = false; + UString realPath; + for (int i = 0; i < (1 << 16); i++) + { + if (archivePath.Temp) + { + if (i > 0) + { + wchar_t s[32]; + ConvertUInt64ToString(i, s); + archivePath.TempPostfix = s; + } + realPath = archivePath.GetTempPath(); + } + else + realPath = archivePath.GetFinalPath(); + if (outStreamSpec->Create(realPath, false)) + { + tempFiles.Paths.Add(realPath); + isOK = true; + break; + } + if (::GetLastError() != ERROR_FILE_EXISTS) + break; + if (!archivePath.Temp) + break; + } + if (!isOK) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.FileName = realPath; + errorInfo.Message = L"Can not open file"; + return E_FAIL; + } + } + } + else + { + if (stdOutMode) + return E_FAIL; + COutMultiVolStream *volStreamSpec = new COutMultiVolStream; + outStream = volStreamSpec; + volStreamSpec->Sizes = volumesSizes; + volStreamSpec->Prefix = archivePath.GetFinalPath() + UString(L"."); + volStreamSpec->TempFiles = &tempFiles; + volStreamSpec->Init(); + + /* + updateCallbackSpec->VolumesSizes = volumesSizes; + updateCallbackSpec->VolName = archivePath.Prefix + archivePath.Name; + if (!archivePath.VolExtension.IsEmpty()) + updateCallbackSpec->VolExt = UString(L'.') + archivePath.VolExtension; + */ + } + + RINOK(SetProperties(outArchive, compressionMethod.Properties)); + + if (sfxMode) + { + CInFileStream *sfxStreamSpec = new CInFileStream; + CMyComPtr sfxStream(sfxStreamSpec); + if (!sfxStreamSpec->Open(sfxModule)) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.Message = L"Can't open sfx module"; + errorInfo.FileName = sfxModule; + return E_FAIL; + } + + CMyComPtr sfxOutStream; + if (volumesSizes.Size() == 0) + sfxOutStream = outStream; + else + { + COutFileStream *outStreamSpec = new COutFileStream; + sfxOutStream = outStreamSpec; + UString realPath = archivePath.GetFinalPath(); + if (!outStreamSpec->Create(realPath, false)) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.FileName = realPath; + errorInfo.Message = L"Can not open file"; + return E_FAIL; + } + } + RINOK(CopyBlock(sfxStream, sfxOutStream)); + } + + HRESULT result = outArchive->UpdateItems(outStream, updatePairs2.Size(), + updateCallback); + callback->Finilize(); + return result; +} + + + +HRESULT EnumerateInArchiveItems(const NWildcard::CCensor &censor, + IInArchive *archive, + const UString &defaultItemName, + const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo, + CObjectVector &archiveItems) +{ + archiveItems.Clear(); + UInt32 numItems; + RINOK(archive->GetNumberOfItems(&numItems)); + archiveItems.Reserve(numItems); + for(UInt32 i = 0; i < numItems; i++) + { + CArchiveItem ai; + + RINOK(GetArchiveItemPath(archive, i, ai.Name)); + RINOK(IsArchiveItemFolder(archive, i, ai.IsDirectory)); + ai.Censored = censor.CheckPath(ai.Name.IsEmpty() ? defaultItemName : ai.Name, !ai.IsDirectory); + RINOK(GetArchiveItemFileTime(archive, i, + archiveFileInfo.LastWriteTime, ai.LastWriteTime)); + + CPropVariant propertySize; + RINOK(archive->GetProperty(i, kpidSize, &propertySize)); + ai.SizeIsDefined = (propertySize.vt != VT_EMPTY); + if (ai.SizeIsDefined) + ai.Size = ConvertPropVariantToUInt64(propertySize); + + ai.IndexInServer = i; + archiveItems.Add(ai); + } + return S_OK; +} + + +static HRESULT UpdateWithItemLists( + CUpdateOptions &options, + IInArchive *archive, + const CObjectVector &archiveItems, + const CObjectVector &dirItems, + CTempFiles &tempFiles, + CUpdateErrorInfo &errorInfo, + IUpdateCallbackUI2 *callback) +{ + for(int i = 0; i < options.Commands.Size(); i++) + { + CUpdateArchiveCommand &command = options.Commands[i]; + if (options.StdOutMode) + { + RINOK(callback->StartArchive(0, archive != 0)); + } + else + { + RINOK(callback->StartArchive(command.ArchivePath.GetFinalPath(), + i == 0 && options.UpdateArchiveItself && archive != 0)); + } + + RINOK(Compress(command.ActionSet, archive, + options.MethodMode, + command.ArchivePath, + archiveItems, + options.StdInMode, + /* options.StdInFileName, */ + options.StdOutMode, + dirItems, + options.SfxMode, options.SfxModule, + options.VolumesSizes, + tempFiles, + errorInfo, callback)); + + RINOK(callback->FinishArchive()); + } + return S_OK; +} + +#ifdef _WIN32 +class CCurrentDirRestorer +{ + UString m_CurrentDirectory; +public: + CCurrentDirRestorer() + { NFile::NDirectory::MyGetCurrentDirectory(m_CurrentDirectory); } + ~CCurrentDirRestorer() + { RestoreDirectory();} + bool RestoreDirectory() + { return BOOLToBool(NFile::NDirectory::MySetCurrentDirectory(m_CurrentDirectory)); } +}; +#endif + +struct CEnumDirItemUpdateCallback: public IEnumDirItemCallback +{ + IUpdateCallbackUI2 *Callback; + HRESULT CheckBreak() { return Callback->CheckBreak(); } +}; + +HRESULT UpdateArchive(const NWildcard::CCensor &censor, + CUpdateOptions &options, + CUpdateErrorInfo &errorInfo, + IOpenCallbackUI *openCallback, + IUpdateCallbackUI2 *callback) +{ + if (options.StdOutMode && options.EMailMode) + return E_FAIL; + + if (options.VolumesSizes.Size() > 0 && (options.EMailMode || options.SfxMode)) + return E_NOTIMPL; + + if (options.SfxMode) + { + CProperty property; + property.Name = L"rsfx"; + property.Value = L"on"; + options.MethodMode.Properties.Add(property); + if (options.SfxModule.IsEmpty()) + { + errorInfo.Message = L"sfx file is not specified"; + return E_FAIL; + } + UString name = options.SfxModule; + if (!NDirectory::MySearchPath(NULL, name, NULL, options.SfxModule)) + { + errorInfo.Message = L"can't find specified sfx module"; + return E_FAIL; + } + } + + const UString archiveName = options.ArchivePath.GetFinalPath(); + + UString defaultItemName; + NFind::CFileInfoW archiveFileInfo; + + CArchiveLink archiveLink; + IInArchive *archive = 0; + if (NFind::FindFile(archiveName, archiveFileInfo)) + { + if (archiveFileInfo.IsDirectory()) + throw "there is no such archive"; + if (options.VolumesSizes.Size() > 0) + return E_NOTIMPL; + HRESULT result = MyOpenArchive(archiveName, archiveLink, openCallback); + RINOK(callback->OpenResult(archiveName, result)); + RINOK(result); + if (archiveLink.VolumePaths.Size() > 1) + { + errorInfo.SystemError = (DWORD)E_NOTIMPL; + errorInfo.Message = L"Updating for multivolume archives is not implemented"; + return E_NOTIMPL; + } + archive = archiveLink.GetArchive(); + defaultItemName = archiveLink.GetDefaultItemName(); + } + else + { + /* + if (archiveType.IsEmpty()) + throw "type of archive is not specified"; + */ + } + + CObjectVector dirItems; + if (options.StdInMode) + { + CDirItem item; + item.FullPath = item.Name = options.StdInFileName; + item.Size = (UInt64)(Int64)-1; + item.Attributes = 0; + SYSTEMTIME st; + FILETIME ft; + GetSystemTime(&st); + SystemTimeToFileTime(&st, &ft); + item.CreationTime = item.LastAccessTime = item.LastWriteTime = ft; + dirItems.Add(item); + } + else + { + bool needScanning = false; + for(int i = 0; i < options.Commands.Size(); i++) + if (options.Commands[i].ActionSet.NeedScanning()) + needScanning = true; + if (needScanning) + { + CEnumDirItemUpdateCallback enumCallback; + enumCallback.Callback = callback; + RINOK(callback->StartScanning()); + UStringVector errorPaths; + CRecordVector errorCodes; + HRESULT res = EnumerateItems(censor, dirItems, &enumCallback, errorPaths, errorCodes); + for (int i = 0; i < errorPaths.Size(); i++) + { + RINOK(callback->CanNotFindError(errorPaths[i], errorCodes[i])); + } + if(res != S_OK) + { + errorInfo.Message = L"Scanning error"; + // errorInfo.FileName = errorPath; + return res; + } + RINOK(callback->FinishScanning()); + } + } + + UString tempDirPrefix; + bool usesTempDir = false; + + #ifdef _WIN32 + NDirectory::CTempDirectoryW tempDirectory; + if (options.EMailMode && options.EMailRemoveAfter) + { + tempDirectory.Create(kTempFolderPrefix); + tempDirPrefix = tempDirectory.GetPath(); + NormalizeDirPathPrefix(tempDirPrefix); + usesTempDir = true; + } + #endif + + CTempFiles tempFiles; + + bool createTempFile = false; + if(!options.StdOutMode && options.UpdateArchiveItself) + { + CArchivePath &ap = options.Commands[0].ArchivePath; + ap = options.ArchivePath; + // if ((archive != 0 && !usesTempDir) || !options.WorkingDir.IsEmpty()) + if ((archive != 0 || !options.WorkingDir.IsEmpty()) && !usesTempDir && options.VolumesSizes.Size() == 0) + { + createTempFile = true; + ap.Temp = true; + if (!options.WorkingDir.IsEmpty()) + { + ap.TempPrefix = options.WorkingDir; + NormalizeDirPathPrefix(ap.TempPrefix); + } + } + } + + for(int i = 0; i < options.Commands.Size(); i++) + { + CArchivePath &ap = options.Commands[i].ArchivePath; + if (usesTempDir) + { + // Check it + ap.Prefix = tempDirPrefix; + // ap.Temp = true; + // ap.TempPrefix = tempDirPrefix; + } + if (i > 0 || !createTempFile) + { + const UString &path = ap.GetFinalPath(); + if (NFind::DoesFileExist(path)) + { + errorInfo.SystemError = 0; + errorInfo.Message = L"File already exists"; + errorInfo.FileName = path; + return E_FAIL; + } + } + } + + CObjectVector archiveItems; + if (archive != NULL) + { + RINOK(EnumerateInArchiveItems(censor, + archive, defaultItemName, archiveFileInfo, archiveItems)); + } + + RINOK(UpdateWithItemLists(options, archive, archiveItems, dirItems, + tempFiles, errorInfo, callback)); + + if (archive != NULL) + { + RINOK(archiveLink.Close()); + archiveLink.Release(); + } + + tempFiles.Paths.Clear(); + if(createTempFile) + { + try + { + CArchivePath &ap = options.Commands[0].ArchivePath; + const UString &tempPath = ap.GetTempPath(); + if (archive != NULL) + if (!NDirectory::DeleteFileAlways(archiveName)) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.Message = L"delete file error"; + errorInfo.FileName = archiveName; + return E_FAIL; + } + if (!NDirectory::MyMoveFile(tempPath, archiveName)) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.Message = L"move file error"; + errorInfo.FileName = tempPath; + errorInfo.FileName2 = archiveName; + return E_FAIL; + } + } + catch(...) + { + throw; + } + } + + #ifdef _WIN32 + if (options.EMailMode) + { + NDLL::CLibrary mapiLib; + if (!mapiLib.Load(TEXT("Mapi32.dll"))) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.Message = L"can not load Mapi32.dll"; + return E_FAIL; + } + LPMAPISENDDOCUMENTS fnSend = (LPMAPISENDDOCUMENTS) + mapiLib.GetProcAddress("MAPISendDocuments"); + if (fnSend == 0) + { + errorInfo.SystemError = ::GetLastError(); + errorInfo.Message = L"can not find MAPISendDocuments function"; + return E_FAIL; + } + UStringVector fullPaths; + int i; + for(i = 0; i < options.Commands.Size(); i++) + { + CArchivePath &ap = options.Commands[i].ArchivePath; + UString arcPath; + if(!NFile::NDirectory::MyGetFullPathName(ap.GetFinalPath(), arcPath)) + { + errorInfo.SystemError = ::GetLastError(); + return E_FAIL; + } + fullPaths.Add(arcPath); + } + CCurrentDirRestorer curDirRestorer; + for(i = 0; i < fullPaths.Size(); i++) + { + UString arcPath = fullPaths[i]; + UString fileName = ExtractFileNameFromPath(arcPath); + AString path = GetAnsiString(arcPath); + AString name = GetAnsiString(fileName); + // Warning!!! MAPISendDocuments function changes Current directory + fnSend(0, ";", (LPSTR)(LPCSTR)path, (LPSTR)(LPCSTR)name, 0); + } + } + #endif + return S_OK; +} + diff --git a/CPP/7zip/UI/Common/Update.h b/CPP/7zip/UI/Common/Update.h new file mode 100755 index 00000000..465acc24 --- /dev/null +++ b/CPP/7zip/UI/Common/Update.h @@ -0,0 +1,158 @@ +// Update.h + +#ifndef __UPDATE_H +#define __UPDATE_H + +#include "Common/Wildcard.h" +#include "Windows/FileFind.h" +#include "../../Archive/IArchive.h" + +#include "UpdateAction.h" +#include "ArchiveOpenCallback.h" +#include "UpdateCallback.h" +#include "Property.h" + +struct CArchivePath +{ + UString Prefix; // path(folder) prefix including slash + UString Name; // base name + UString BaseExtension; // archive type extension or "exe" extension + UString VolExtension; // archive type extension for volumes + + bool Temp; + UString TempPrefix; // path(folder) for temp location + UString TempPostfix; + + CArchivePath(): Temp(false) {}; + + void ParseFromPath(const UString &path) + { + SplitPathToParts(path, Prefix, Name); + if (Name.IsEmpty()) + return; + int dotPos = Name.ReverseFind(L'.'); + if (dotPos <= 0) + return; + if (dotPos == Name.Length() - 1) + { + Name = Name.Left(dotPos); + BaseExtension.Empty(); + return; + } + if (BaseExtension.CompareNoCase(Name.Mid(dotPos + 1)) == 0) + { + BaseExtension = Name.Mid(dotPos + 1); + Name = Name.Left(dotPos); + } + else + BaseExtension.Empty(); + } + + UString GetPathWithoutExt() const + { + return Prefix + Name; + } + + UString GetFinalPath() const + { + UString path = GetPathWithoutExt(); + if (!BaseExtension.IsEmpty()) + path += UString(L'.') + BaseExtension; + return path; + } + + + UString GetTempPath() const + { + UString path = TempPrefix + Name; + if (!BaseExtension.IsEmpty()) + path += UString(L'.') + BaseExtension; + path += L".tmp"; + path += TempPostfix; + return path; + } +}; + +struct CUpdateArchiveCommand +{ + CArchivePath ArchivePath; + NUpdateArchive::CActionSet ActionSet; +}; + +struct CCompressionMethodMode +{ + #ifndef EXCLUDE_COM + UString FilePath; + CLSID ClassID; + #else + UString Name; + #endif + CObjectVector Properties; +}; + +struct CUpdateOptions +{ + CCompressionMethodMode MethodMode; + + CObjectVector Commands; + bool UpdateArchiveItself; + CArchivePath ArchivePath; + + bool SfxMode; + UString SfxModule; + + bool StdInMode; + UString StdInFileName; + bool StdOutMode; + + bool EMailMode; + bool EMailRemoveAfter; + UString EMailAddress; + + UString WorkingDir; + + CUpdateOptions(): + UpdateArchiveItself(true), + SfxMode(false), + StdInMode(false), + StdOutMode(false), + EMailMode(false), + EMailRemoveAfter(false) + {}; + CRecordVector VolumesSizes; +}; + +struct CErrorInfo +{ + DWORD SystemError; + UString FileName; + UString FileName2; + UString Message; + // UStringVector ErrorPaths; + // CRecordVector ErrorCodes; + CErrorInfo(): SystemError(0) {}; +}; + +struct CUpdateErrorInfo: public CErrorInfo +{ +}; + +struct IUpdateCallbackUI2: public IUpdateCallbackUI +{ + virtual HRESULT OpenResult(const wchar_t *name, HRESULT result) = 0; + + virtual HRESULT StartScanning() = 0; + virtual HRESULT CanNotFindError(const wchar_t *name, DWORD systemError) = 0; + virtual HRESULT FinishScanning() = 0; + + virtual HRESULT StartArchive(const wchar_t *name, bool updating) = 0; + virtual HRESULT FinishArchive() = 0; +}; + +HRESULT UpdateArchive(const NWildcard::CCensor &censor, + CUpdateOptions &options, + CUpdateErrorInfo &errorInfo, + IOpenCallbackUI *openCallback, + IUpdateCallbackUI2 *callback); + +#endif diff --git a/CPP/7zip/UI/Common/UpdateAction.cpp b/CPP/7zip/UI/Common/UpdateAction.cpp new file mode 100755 index 00000000..5e3b5a10 --- /dev/null +++ b/CPP/7zip/UI/Common/UpdateAction.cpp @@ -0,0 +1,64 @@ +// UpdateAction.cpp + +#include "StdAfx.h" + +#include "UpdateAction.h" + +namespace NUpdateArchive { + +const CActionSet kAddActionSet = +{ + NPairAction::kCopy, + NPairAction::kCopy, + NPairAction::kCompress, + NPairAction::kCompress, + NPairAction::kCompress, + NPairAction::kCompress, + NPairAction::kCompress +}; + +const CActionSet kUpdateActionSet = +{ + NPairAction::kCopy, + NPairAction::kCopy, + NPairAction::kCompress, + NPairAction::kCopy, + NPairAction::kCompress, + NPairAction::kCopy, + NPairAction::kCompress +}; + +const CActionSet kFreshActionSet = +{ + NPairAction::kCopy, + NPairAction::kCopy, + NPairAction::kIgnore, + NPairAction::kCopy, + NPairAction::kCompress, + NPairAction::kCopy, + NPairAction::kCompress +}; + +const CActionSet kSynchronizeActionSet = +{ + NPairAction::kCopy, + NPairAction::kIgnore, + NPairAction::kCompress, + NPairAction::kCopy, + NPairAction::kCompress, + NPairAction::kCopy, + NPairAction::kCompress, +}; + +const CActionSet kDeleteActionSet = +{ + NPairAction::kCopy, + NPairAction::kIgnore, + NPairAction::kIgnore, + NPairAction::kIgnore, + NPairAction::kIgnore, + NPairAction::kIgnore, + NPairAction::kIgnore +}; + +} diff --git a/CPP/7zip/UI/Common/UpdateAction.h b/CPP/7zip/UI/Common/UpdateAction.h new file mode 100755 index 00000000..aa050975 --- /dev/null +++ b/CPP/7zip/UI/Common/UpdateAction.h @@ -0,0 +1,57 @@ +// UpdateAction.h + +#ifndef __UPDATE_ACTION_H +#define __UPDATE_ACTION_H + +namespace NUpdateArchive { + + namespace NPairState + { + const int kNumValues = 7; + enum EEnum + { + kNotMasked = 0, + kOnlyInArchive, + kOnlyOnDisk, + kNewInArchive, + kOldInArchive, + kSameFiles, + kUnknowNewerFiles + }; + } + namespace NPairAction + { + enum EEnum + { + kIgnore = 0, + kCopy, + kCompress, + kCompressAsAnti + }; + } + struct CActionSet + { + NPairAction::EEnum StateActions[NPairState::kNumValues]; + bool NeedScanning() const + { + int i; + for (i = 0; i < NPairState::kNumValues; i++) + if (StateActions[i] == NPairAction::kCompress) + return true; + for (i = 1; i < NPairState::kNumValues; i++) + if (StateActions[i] != NPairAction::kIgnore) + return true; + return false; + } + }; + extern const CActionSet kAddActionSet; + extern const CActionSet kUpdateActionSet; + extern const CActionSet kFreshActionSet; + extern const CActionSet kSynchronizeActionSet; + extern const CActionSet kDeleteActionSet; +}; + + +#endif + + diff --git a/CPP/7zip/UI/Common/UpdateCallback.cpp b/CPP/7zip/UI/Common/UpdateCallback.cpp new file mode 100755 index 00000000..db3bf805 --- /dev/null +++ b/CPP/7zip/UI/Common/UpdateCallback.cpp @@ -0,0 +1,258 @@ +// UpdateCallback.cpp + +#include "StdAfx.h" + +#include "UpdateCallback.h" + +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "Common/Defs.h" +#include "Common/ComTry.h" + +#include "Windows/PropVariant.h" + +#include "../../Common/FileStreams.h" + +using namespace NWindows; + +CArchiveUpdateCallback::CArchiveUpdateCallback(): + Callback(0), + StdInMode(false), + DirItems(0), + ArchiveItems(0), + UpdatePairs(0) + {} + + +STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size) +{ + COM_TRY_BEGIN + return Callback->SetTotal(size); + COM_TRY_END +} + +STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue) +{ + COM_TRY_BEGIN + return Callback->SetCompleted(completeValue); + COM_TRY_END +} + +/* +STATPROPSTG kProperties[] = +{ + { NULL, kpidPath, VT_BSTR}, + { NULL, kpidIsFolder, VT_BOOL}, + { NULL, kpidSize, VT_UI8}, + { NULL, kpidLastAccessTime, VT_FILETIME}, + { NULL, kpidCreationTime, VT_FILETIME}, + { NULL, kpidLastWriteTime, VT_FILETIME}, + { NULL, kpidAttributes, VT_UI4}, + { NULL, kpidIsAnti, VT_BOOL} +}; +*/ + +STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **) +{ + return E_NOTIMPL; + /* + return CStatPropEnumerator::CreateEnumerator(kProperties, + sizeof(kProperties) / sizeof(kProperties[0]), enumerator); + */ +} + +STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index, + Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive) +{ + COM_TRY_BEGIN + RINOK(Callback->CheckBreak()); + const CUpdatePair2 &updatePair = (*UpdatePairs)[index]; + if(newData != NULL) + *newData = BoolToInt(updatePair.NewData); + if(newProperties != NULL) + *newProperties = BoolToInt(updatePair.NewProperties); + if(indexInArchive != NULL) + { + if (updatePair.ExistInArchive) + { + if (ArchiveItems == 0) + *indexInArchive = updatePair.ArchiveItemIndex; + else + *indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer; + } + else + *indexInArchive = UInt32(-1); + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) +{ + COM_TRY_BEGIN + const CUpdatePair2 &updatePair = (*UpdatePairs)[index]; + NWindows::NCOM::CPropVariant propVariant; + + if (propID == kpidIsAnti) + { + propVariant = updatePair.IsAnti; + propVariant.Detach(value); + return S_OK; + } + + if (updatePair.IsAnti) + { + switch(propID) + { + case kpidIsFolder: + case kpidPath: + break; + case kpidSize: + propVariant = (UInt64)0; + propVariant.Detach(value); + return S_OK; + default: + propVariant.Detach(value); + return S_OK; + } + } + + if(updatePair.ExistOnDisk) + { + const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex]; + switch(propID) + { + case kpidPath: + propVariant = dirItem.Name; + break; + case kpidIsFolder: + propVariant = dirItem.IsDirectory(); + break; + case kpidSize: + propVariant = dirItem.Size; + break; + case kpidAttributes: + propVariant = dirItem.Attributes; + break; + case kpidLastAccessTime: + propVariant = dirItem.LastAccessTime; + break; + case kpidCreationTime: + propVariant = dirItem.CreationTime; + break; + case kpidLastWriteTime: + propVariant = dirItem.LastWriteTime; + break; + } + } + else + { + if (propID == kpidPath) + { + if (updatePair.NewNameIsDefined) + { + propVariant = updatePair.NewName; + propVariant.Detach(value); + return S_OK; + } + } + if (updatePair.ExistInArchive && Archive) + { + UInt32 indexInArchive; + if (ArchiveItems == 0) + indexInArchive = updatePair.ArchiveItemIndex; + else + indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer; + return Archive->GetProperty(indexInArchive, propID, value); + } + } + propVariant.Detach(value); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream) +{ + COM_TRY_BEGIN + const CUpdatePair2 &updatePair = (*UpdatePairs)[index]; + if(!updatePair.NewData) + return E_FAIL; + + RINOK(Callback->CheckBreak()); + RINOK(Callback->Finilize()); + + if(updatePair.IsAnti) + { + return Callback->GetStream((*ArchiveItems)[updatePair.ArchiveItemIndex].Name, true); + } + const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex]; + RINOK(Callback->GetStream(dirItem.Name, false)); + + if(dirItem.IsDirectory()) + return S_OK; + + if (StdInMode) + { + CStdInFileStream *inStreamSpec = new CStdInFileStream; + CMyComPtr inStreamLoc(inStreamSpec); + *inStream = inStreamLoc.Detach(); + } + else + { + CInFileStream *inStreamSpec = new CInFileStream; + CMyComPtr inStreamLoc(inStreamSpec); + UString path = DirPrefix + dirItem.FullPath; + if(!inStreamSpec->Open(path)) + { + return Callback->OpenFileError(path, ::GetLastError()); + } + *inStream = inStreamLoc.Detach(); + } + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult) +{ + COM_TRY_BEGIN + return Callback->SetOperationResult(operationResult); + COM_TRY_END +} + +STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size) +{ + if (VolumesSizes.Size() == 0) + return S_FALSE; + if (index >= (UInt32)VolumesSizes.Size()) + index = VolumesSizes.Size() - 1; + *size = VolumesSizes[index]; + return S_OK; +} + +STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream) +{ + COM_TRY_BEGIN + wchar_t temp[32]; + ConvertUInt64ToString(index + 1, temp); + UString res = temp; + while (res.Length() < 2) + res = UString(L'0') + res; + UString fileName = VolName; + fileName += L'.'; + fileName += res; + fileName += VolExt; + COutFileStream *streamSpec = new COutFileStream; + CMyComPtr streamLoc(streamSpec); + if(!streamSpec->Create(fileName, false)) + return ::GetLastError(); + *volumeStream = streamLoc.Detach(); + return S_OK; + COM_TRY_END +} + +STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +{ + COM_TRY_BEGIN + return Callback->CryptoGetTextPassword2(passwordIsDefined, password); + COM_TRY_END +} diff --git a/CPP/7zip/UI/Common/UpdateCallback.h b/CPP/7zip/UI/Common/UpdateCallback.h new file mode 100755 index 00000000..8b14a9dc --- /dev/null +++ b/CPP/7zip/UI/Common/UpdateCallback.h @@ -0,0 +1,70 @@ +// UpdateCallback.h + +#ifndef __UPDATECALLBACK_H +#define __UPDATECALLBACK_H + +#include "Common/MyCom.h" +#include "Common/String.h" + +#include "../../IPassword.h" + +#include "../Common/UpdatePair.h" +#include "../Common/UpdateProduce.h" + +struct IUpdateCallbackUI +{ + virtual HRESULT SetTotal(UInt64 size) = 0; + virtual HRESULT SetCompleted(const UInt64 *completeValue) = 0; + virtual HRESULT CheckBreak() = 0; + virtual HRESULT Finilize() = 0; + virtual HRESULT GetStream(const wchar_t *name, bool isAnti) = 0; + virtual HRESULT OpenFileError(const wchar_t *name, DWORD systemError) = 0; + virtual HRESULT SetOperationResult(Int32 operationResult) = 0; + virtual HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) = 0; + virtual HRESULT CloseProgress() { return S_OK; }; +}; + +class CArchiveUpdateCallback: + public IArchiveUpdateCallback2, + public ICryptoGetTextPassword2, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, + ICryptoGetTextPassword2) + + // IProgress + STDMETHOD(SetTotal)(UInt64 size); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); + + // IUpdateCallback + STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator); + STDMETHOD(GetUpdateItemInfo)(UInt32 index, + Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive); + STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value); + STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream); + STDMETHOD(SetOperationResult)(Int32 operationResult); + + STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size); + STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream); + + STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password); + +public: + CRecordVector VolumesSizes; + UString VolName; + UString VolExt; + + IUpdateCallbackUI *Callback; + + UString DirPrefix; + bool StdInMode; + const CObjectVector *DirItems; + const CObjectVector *ArchiveItems; + const CObjectVector *UpdatePairs; + CMyComPtr Archive; + + CArchiveUpdateCallback(); +}; + +#endif diff --git a/CPP/7zip/UI/Common/UpdatePair.cpp b/CPP/7zip/UI/Common/UpdatePair.cpp new file mode 100755 index 00000000..dd51646f --- /dev/null +++ b/CPP/7zip/UI/Common/UpdatePair.cpp @@ -0,0 +1,175 @@ +// UpdatePair.cpp + +#include "StdAfx.h" + +#include + +#include "Common/Defs.h" +#include "Windows/Time.h" + +#include "UpdatePair.h" +#include "SortUtils.h" + +using namespace NWindows; +using namespace NTime; + +static int MyCompareTime(NFileTimeType::EEnum fileTimeType, + const FILETIME &time1, const FILETIME &time2) +{ + switch(fileTimeType) + { + case NFileTimeType::kWindows: + return ::CompareFileTime(&time1, &time2); + case NFileTimeType::kUnix: + { + UInt32 unixTime1, unixTime2; + if (!FileTimeToUnixTime(time1, unixTime1)) + { + unixTime1 = 0; + // throw 4191614; + } + if (!FileTimeToUnixTime(time2, unixTime2)) + { + unixTime2 = 0; + // throw 4191615; + } + return MyCompare(unixTime1, unixTime2); + } + case NFileTimeType::kDOS: + { + UInt32 dosTime1, dosTime2; + FileTimeToDosTime(time1, dosTime1); + FileTimeToDosTime(time2, dosTime2); + /* + if (!FileTimeToDosTime(time1, dosTime1)) + throw 4191616; + if (!FileTimeToDosTime(time2, dosTime2)) + throw 4191617; + */ + return MyCompare(dosTime1, dosTime2); + } + } + throw 4191618; +} + +static const wchar_t *kDuplicateFileNameMessage = L"Duplicate filename:"; + +/* +static const char *kNotCensoredCollisionMessaged = "Internal file name collision:\n"; +static const char *kSameTimeChangedSizeCollisionMessaged = + "Collision between files with same date/time and different sizes:\n"; +*/ + +static inline int MyFileNameCompare(const UString &s1, const UString &s2) +{ + return + #ifdef _WIN32 + s1.CompareNoCase(s2); + #else + s1.Compare(s2); + #endif +} + +static void TestDuplicateString(const UStringVector &strings, const CIntVector &indices) +{ + for(int i = 0; i + 1 < indices.Size(); i++) + if (MyFileNameCompare(strings[indices[i]], strings[indices[i + 1]]) == 0) + { + UString message = kDuplicateFileNameMessage; + message += L"\n"; + message += strings[indices[i]]; + message += L"\n"; + message += strings[indices[i + 1]]; + throw message; + } +} + +void GetUpdatePairInfoList( + const CObjectVector &dirItems, + const CObjectVector &archiveItems, + NFileTimeType::EEnum fileTimeType, + CObjectVector &updatePairs) +{ + CIntVector dirIndices, archiveIndices; + UStringVector dirNames, archiveNames; + + int numDirItems = dirItems.Size(); + int i; + for(i = 0; i < numDirItems; i++) + dirNames.Add(dirItems[i].Name); + SortStringsToIndices(dirNames, dirIndices); + TestDuplicateString(dirNames, dirIndices); + + int numArchiveItems = archiveItems.Size(); + for(i = 0; i < numArchiveItems; i++) + archiveNames.Add(archiveItems[i].Name); + SortStringsToIndices(archiveNames, archiveIndices); + TestDuplicateString(archiveNames, archiveIndices); + + int dirItemIndex = 0, archiveItemIndex = 0; + CUpdatePair pair; + while(dirItemIndex < numDirItems && archiveItemIndex < numArchiveItems) + { + int dirItemIndex2 = dirIndices[dirItemIndex], + archiveItemIndex2 = archiveIndices[archiveItemIndex]; + const CDirItem &dirItem = dirItems[dirItemIndex2]; + const CArchiveItem &archiveItem = archiveItems[archiveItemIndex2]; + int compareResult = MyFileNameCompare(dirItem.Name, archiveItem.Name); + if (compareResult < 0) + { + pair.State = NUpdateArchive::NPairState::kOnlyOnDisk; + pair.DirItemIndex = dirItemIndex2; + dirItemIndex++; + } + else if (compareResult > 0) + { + pair.State = archiveItem.Censored ? + NUpdateArchive::NPairState::kOnlyInArchive: NUpdateArchive::NPairState::kNotMasked; + pair.ArchiveItemIndex = archiveItemIndex2; + archiveItemIndex++; + } + else + { + if (!archiveItem.Censored) + throw 1082022;; // TTString(kNotCensoredCollisionMessaged + dirItem.Name); + pair.DirItemIndex = dirItemIndex2; + pair.ArchiveItemIndex = archiveItemIndex2; + switch (MyCompareTime(fileTimeType, dirItem.LastWriteTime, archiveItem.LastWriteTime)) + { + case -1: + pair.State = NUpdateArchive::NPairState::kNewInArchive; + break; + case 1: + pair.State = NUpdateArchive::NPairState::kOldInArchive; + break; + default: + if (archiveItem.SizeIsDefined) + if (dirItem.Size != archiveItem.Size) + // throw 1082034; // kSameTimeChangedSizeCollisionMessaged; + pair.State = NUpdateArchive::NPairState::kUnknowNewerFiles; + else + pair.State = NUpdateArchive::NPairState::kSameFiles; + else + pair.State = NUpdateArchive::NPairState::kUnknowNewerFiles; + } + dirItemIndex++; + archiveItemIndex++; + } + updatePairs.Add(pair); + } + for(;dirItemIndex < numDirItems; dirItemIndex++) + { + pair.State = NUpdateArchive::NPairState::kOnlyOnDisk; + pair.DirItemIndex = dirIndices[dirItemIndex]; + updatePairs.Add(pair); + } + for(;archiveItemIndex < numArchiveItems; archiveItemIndex++) + { + int archiveItemIndex2 = archiveIndices[archiveItemIndex]; + const CArchiveItem &archiveItem = archiveItems[archiveItemIndex2]; + pair.State = archiveItem.Censored ? + NUpdateArchive::NPairState::kOnlyInArchive: NUpdateArchive::NPairState::kNotMasked; + pair.ArchiveItemIndex = archiveItemIndex2; + updatePairs.Add(pair); + } +} diff --git a/CPP/7zip/UI/Common/UpdatePair.h b/CPP/7zip/UI/Common/UpdatePair.h new file mode 100755 index 00000000..f50a23f8 --- /dev/null +++ b/CPP/7zip/UI/Common/UpdatePair.h @@ -0,0 +1,24 @@ +// UpdatePair.h + +#ifndef __UPDATE_PAIR_H +#define __UPDATE_PAIR_H + +#include "DirItem.h" +#include "UpdateAction.h" + +#include "../../Archive/IArchive.h" + +struct CUpdatePair +{ + NUpdateArchive::NPairState::EEnum State; + int ArchiveItemIndex; + int DirItemIndex; +}; + +void GetUpdatePairInfoList( + const CObjectVector &dirItems, + const CObjectVector &archiveItems, + NFileTimeType::EEnum fileTimeType, + CObjectVector &updatePairs); + +#endif diff --git a/CPP/7zip/UI/Common/UpdateProduce.cpp b/CPP/7zip/UI/Common/UpdateProduce.cpp new file mode 100755 index 00000000..992bbeec --- /dev/null +++ b/CPP/7zip/UI/Common/UpdateProduce.cpp @@ -0,0 +1,63 @@ +// UpdateProduce.cpp + +#include "StdAfx.h" + +#include "UpdateProduce.h" + +using namespace NUpdateArchive; + +static const char *kUpdateActionSetCollision = + "Internal collision in update action set"; + +void UpdateProduce( + const CObjectVector &updatePairs, + const NUpdateArchive::CActionSet &actionSet, + CObjectVector &operationChain) +{ + for(int i = 0; i < updatePairs.Size(); i++) + { + // CUpdateArchiveRange aRange; + const CUpdatePair &pair = updatePairs[i]; + + CUpdatePair2 pair2; + pair2.IsAnti = false; + pair2.ArchiveItemIndex = pair.ArchiveItemIndex; + pair2.DirItemIndex = pair.DirItemIndex; + pair2.ExistInArchive = (pair.State != NPairState::kOnlyOnDisk); + pair2.ExistOnDisk = (pair.State != NPairState::kOnlyInArchive); + switch(actionSet.StateActions[pair.State]) + { + case NPairAction::kIgnore: + /* + if (pair.State != NPairState::kOnlyOnDisk) + IgnoreArchiveItem(m_ArchiveItems[pair.ArchiveItemIndex]); + // cout << "deleting"; + */ + break; + case NPairAction::kCopy: + { + if (pair.State == NPairState::kOnlyOnDisk) + throw kUpdateActionSetCollision; + pair2.NewData = pair2.NewProperties = false; + operationChain.Add(pair2); + break; + } + case NPairAction::kCompress: + { + if (pair.State == NPairState::kOnlyInArchive || + pair.State == NPairState::kNotMasked) + throw kUpdateActionSetCollision; + pair2.NewData = pair2.NewProperties = true; + operationChain.Add(pair2); + break; + } + case NPairAction::kCompressAsAnti: + { + pair2.IsAnti = true; + pair2.NewData = pair2.NewProperties = true; + operationChain.Add(pair2); + break; + } + } + } +} diff --git a/CPP/7zip/UI/Common/UpdateProduce.h b/CPP/7zip/UI/Common/UpdateProduce.h new file mode 100755 index 00000000..8f58dab9 --- /dev/null +++ b/CPP/7zip/UI/Common/UpdateProduce.h @@ -0,0 +1,31 @@ +// UpdateProduce.h + +#ifndef __UPDATE_PRODUCE_H +#define __UPDATE_PRODUCE_H + +#include "UpdatePair.h" + +struct CUpdatePair2 +{ + // bool OperationIsCompress; + bool NewData; + bool NewProperties; + + bool ExistInArchive; + bool ExistOnDisk; + bool IsAnti; + int ArchiveItemIndex; + int DirItemIndex; + + bool NewNameIsDefined; + UString NewName; + + CUpdatePair2(): NewNameIsDefined(false) {} +}; + +void UpdateProduce( + const CObjectVector &updatePairs, + const NUpdateArchive::CActionSet &actionSet, + CObjectVector &operationChain); + +#endif diff --git a/CPP/7zip/UI/Common/WorkDir.cpp b/CPP/7zip/UI/Common/WorkDir.cpp new file mode 100755 index 00000000..8db6f4f1 --- /dev/null +++ b/CPP/7zip/UI/Common/WorkDir.cpp @@ -0,0 +1,64 @@ +// WorkDir.cpp + +#include "StdAfx.h" + +#include "WorkDir.h" + +#include "Common/StringConvert.h" +#include "Common/Wildcard.h" + +#include "Windows/FileName.h" +#include "Windows/FileDir.h" + +static inline UINT GetCurrentCodePage() + { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; } + +using namespace NWindows; +using namespace NFile; +using namespace NName; + +UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path) +{ + NWorkDir::NMode::EEnum mode = workDirInfo.Mode; + if (workDirInfo.ForRemovableOnly) + { + mode = NWorkDir::NMode::kCurrent; + UString prefix = path.Left(3); + if (prefix[1] == L':' && prefix[2] == L'\\') + { + UINT driveType = GetDriveType(GetSystemString(prefix, GetCurrentCodePage())); + if (driveType == DRIVE_CDROM || driveType == DRIVE_REMOVABLE) + mode = workDirInfo.Mode; + } + /* + CParsedPath parsedPath; + parsedPath.ParsePath(archiveName); + UINT driveType = GetDriveType(parsedPath.Prefix); + if ((driveType != DRIVE_CDROM) && (driveType != DRIVE_REMOVABLE)) + mode = NZipSettings::NWorkDir::NMode::kCurrent; + */ + } + switch(mode) + { + case NWorkDir::NMode::kCurrent: + { + return ExtractDirPrefixFromPath(path); + } + case NWorkDir::NMode::kSpecified: + { + UString tempDir = workDirInfo.Path; + NormalizeDirPathPrefix(tempDir); + return tempDir; + } + default: + { + UString tempDir; + if(!NFile::NDirectory::MyGetTempPath(tempDir)) + throw 141717; + return tempDir; + } + } +} + + + diff --git a/CPP/7zip/UI/Common/WorkDir.h b/CPP/7zip/UI/Common/WorkDir.h new file mode 100755 index 00000000..0643d67a --- /dev/null +++ b/CPP/7zip/UI/Common/WorkDir.h @@ -0,0 +1,10 @@ +// WorkDir.h + +#ifndef __WORKDIR_H +#define __WORKDIR_H + +#include "ZipRegistry.h" + +UString GetWorkDir(const NWorkDir::CInfo &workDirInfo, const UString &path); + +#endif diff --git a/CPP/7zip/UI/Common/ZipRegistry.cpp b/CPP/7zip/UI/Common/ZipRegistry.cpp new file mode 100755 index 00000000..e449d6b4 --- /dev/null +++ b/CPP/7zip/UI/Common/ZipRegistry.cpp @@ -0,0 +1,420 @@ +// ZipRegistry.cpp + +#include "StdAfx.h" + +#include "ZipRegistry.h" + +#include "Common/IntToString.h" +#include "Common/StringConvert.h" + +#include "Windows/Synchronization.h" +#include "Windows/Registry.h" + +#include "Windows/FileDir.h" + +using namespace NWindows; +using namespace NRegistry; + +static const TCHAR *kCUBasePath = TEXT("Software\\7-ZIP"); + +// static const TCHAR *kArchiversKeyName = TEXT("Archivers"); + +static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection; + +////////////////////// +// ExtractionInfo + +static const TCHAR *kExtractionKeyName = TEXT("Extraction"); + +static const TCHAR *kExtractionPathHistoryKeyName = TEXT("PathHistory"); +static const TCHAR *kExtractionExtractModeValueName = TEXT("ExtarctMode"); +static const TCHAR *kExtractionOverwriteModeValueName = TEXT("OverwriteMode"); +static const TCHAR *kExtractionShowPasswordValueName = TEXT("ShowPassword"); + +static CSysString GetKeyPath(const CSysString &path) +{ + return CSysString(kCUBasePath) + CSysString('\\') + CSysString(path); +} + +void SaveExtractionInfo(const NExtract::CInfo &info) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey extractionKey; + extractionKey.Create(HKEY_CURRENT_USER, GetKeyPath(kExtractionKeyName)); + extractionKey.RecurseDeleteKey(kExtractionPathHistoryKeyName); + { + CKey pathHistoryKey; + pathHistoryKey.Create(extractionKey, kExtractionPathHistoryKeyName); + for(int i = 0; i < info.Paths.Size(); i++) + { + wchar_t numberString[16]; + ConvertUInt64ToString(i, numberString); + pathHistoryKey.SetValue(numberString, info.Paths[i]); + } + } + extractionKey.SetValue(kExtractionExtractModeValueName, UInt32(info.PathMode)); + extractionKey.SetValue(kExtractionOverwriteModeValueName, UInt32(info.OverwriteMode)); + extractionKey.SetValue(kExtractionShowPasswordValueName, info.ShowPassword); +} + +void ReadExtractionInfo(NExtract::CInfo &info) +{ + info.Paths.Clear(); + info.PathMode = NExtract::NPathMode::kCurrentPathnames; + info.OverwriteMode = NExtract::NOverwriteMode::kAskBefore; + info.ShowPassword = false; + + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey extractionKey; + if(extractionKey.Open(HKEY_CURRENT_USER, GetKeyPath(kExtractionKeyName), KEY_READ) != ERROR_SUCCESS) + return; + + { + CKey pathHistoryKey; + if(pathHistoryKey.Open(extractionKey, kExtractionPathHistoryKeyName, KEY_READ) == + ERROR_SUCCESS) + { + for (;;) + { + wchar_t numberString[16]; + ConvertUInt64ToString(info.Paths.Size(), numberString); + UString path; + if (pathHistoryKey.QueryValue(numberString, path) != ERROR_SUCCESS) + break; + info.Paths.Add(path); + } + } + } + UInt32 extractModeIndex; + if (extractionKey.QueryValue(kExtractionExtractModeValueName, extractModeIndex) == ERROR_SUCCESS) + { + switch (extractModeIndex) + { + case NExtract::NPathMode::kFullPathnames: + case NExtract::NPathMode::kCurrentPathnames: + case NExtract::NPathMode::kNoPathnames: + info.PathMode = NExtract::NPathMode::EEnum(extractModeIndex); + break; + } + } + UInt32 overwriteModeIndex; + if (extractionKey.QueryValue(kExtractionOverwriteModeValueName, overwriteModeIndex) == ERROR_SUCCESS) + { + switch (overwriteModeIndex) + { + case NExtract::NOverwriteMode::kAskBefore: + case NExtract::NOverwriteMode::kWithoutPrompt: + case NExtract::NOverwriteMode::kSkipExisting: + case NExtract::NOverwriteMode::kAutoRename: + case NExtract::NOverwriteMode::kAutoRenameExisting: + info.OverwriteMode = NExtract::NOverwriteMode::EEnum(overwriteModeIndex); + break; + } + } + if (extractionKey.QueryValue(kExtractionShowPasswordValueName, + info.ShowPassword) != ERROR_SUCCESS) + info.ShowPassword = false; +} + +/////////////////////////////////// +// CompressionInfo + +static const TCHAR *kCompressionKeyName = TEXT("Compression"); + +static const TCHAR *kCompressionHistoryArchivesKeyName = TEXT("ArcHistory"); +static const TCHAR *kCompressionLevelValueName = TEXT("Level"); +static const TCHAR *kCompressionLastFormatValueName = TEXT("Archiver"); +static const TCHAR *kCompressionShowPasswordValueName = TEXT("ShowPassword"); +static const TCHAR *kCompressionEncryptHeadersValueName = TEXT("EncryptHeaders"); +// static const TCHAR *kCompressionMaximizeValueName = TEXT("Maximize"); + +static const TCHAR *kCompressionOptionsKeyName = TEXT("Options"); +static const TCHAR *kSolid = TEXT("Solid"); +static const TCHAR *kMultiThread = TEXT("Multithread"); + +static const WCHAR *kCompressionOptions = L"Options"; +static const TCHAR *kCompressionLevel = TEXT("Level"); +static const WCHAR *kCompressionMethod = L"Method"; +static const WCHAR *kEncryptionMethod = L"EncryptionMethod"; +static const TCHAR *kCompressionDictionary = TEXT("Dictionary"); +static const TCHAR *kCompressionOrder = TEXT("Order"); + + +static void SetRegString(CKey &key, const WCHAR *name, const UString &value) +{ + if (value.IsEmpty()) + key.DeleteValue(name); + else + key.SetValue(name, value); +} + +static void SetRegUInt32(CKey &key, const TCHAR *name, UInt32 value) +{ + if (value == (UInt32)-1) + key.DeleteValue(name); + else + key.SetValue(name, value); +} + +static void GetRegString(CKey &key, const WCHAR *name, UString &value) +{ + if (key.QueryValue(name, value) != ERROR_SUCCESS) + value.Empty(); +} + +static void GetRegUInt32(CKey &key, const TCHAR *name, UInt32 &value) +{ + if (key.QueryValue(name, value) != ERROR_SUCCESS) + value = UInt32(-1); +} + +void SaveCompressionInfo(const NCompression::CInfo &info) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + + CKey compressionKey; + compressionKey.Create(HKEY_CURRENT_USER, GetKeyPath(kCompressionKeyName)); + compressionKey.RecurseDeleteKey(kCompressionHistoryArchivesKeyName); + { + CKey historyArchivesKey; + historyArchivesKey.Create(compressionKey, kCompressionHistoryArchivesKeyName); + for(int i = 0; i < info.HistoryArchives.Size(); i++) + { + wchar_t numberString[16]; + ConvertUInt64ToString(i, numberString); + historyArchivesKey.SetValue(numberString, info.HistoryArchives[i]); + } + } + + compressionKey.SetValue(kSolid, info.Solid); + compressionKey.SetValue(kMultiThread, info.MultiThread); + compressionKey.RecurseDeleteKey(kCompressionOptionsKeyName); + { + CKey optionsKey; + optionsKey.Create(compressionKey, kCompressionOptionsKeyName); + for(int i = 0; i < info.FormatOptionsVector.Size(); i++) + { + const NCompression::CFormatOptions &fo = info.FormatOptionsVector[i]; + CKey formatKey; + formatKey.Create(optionsKey, fo.FormatID); + + SetRegString(formatKey, kCompressionOptions, fo.Options); + SetRegString(formatKey, kCompressionMethod, fo.Method); + SetRegString(formatKey, kEncryptionMethod, fo.EncryptionMethod); + + SetRegUInt32(formatKey, kCompressionLevel, fo.Level); + SetRegUInt32(formatKey, kCompressionDictionary, fo.Dictionary); + SetRegUInt32(formatKey, kCompressionOrder, fo.Order); + } + } + + compressionKey.SetValue(kCompressionLevelValueName, UInt32(info.Level)); + compressionKey.SetValue(kCompressionLastFormatValueName, + GetSystemString(info.ArchiveType)); + + compressionKey.SetValue(kCompressionShowPasswordValueName, info.ShowPassword); + compressionKey.SetValue(kCompressionEncryptHeadersValueName, info.EncryptHeaders); + // compressionKey.SetValue(kCompressionMaximizeValueName, info.Maximize); +} + +static bool IsMultiProcessor() +{ + SYSTEM_INFO systemInfo; + GetSystemInfo(&systemInfo); + return systemInfo.dwNumberOfProcessors > 1; +} + +void ReadCompressionInfo(NCompression::CInfo &info) +{ + info.HistoryArchives.Clear(); + + info.Solid = true; + info.MultiThread = IsMultiProcessor(); + info.FormatOptionsVector.Clear(); + + info.Level = 5; + info.ArchiveType = L"7z"; + // definedStatus.Maximize = false; + info.ShowPassword = false; + info.EncryptHeaders = false; + + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey compressionKey; + + if(compressionKey.Open(HKEY_CURRENT_USER, + GetKeyPath(kCompressionKeyName), KEY_READ) != ERROR_SUCCESS) + return; + + { + CKey historyArchivesKey; + if(historyArchivesKey.Open(compressionKey, kCompressionHistoryArchivesKeyName, KEY_READ) == + ERROR_SUCCESS) + { + for (;;) + { + wchar_t numberString[16]; + ConvertUInt64ToString(info.HistoryArchives.Size(), numberString); + UString path; + if (historyArchivesKey.QueryValue(numberString, path) != ERROR_SUCCESS) + break; + info.HistoryArchives.Add(path); + } + } + } + + + bool solid = false; + if (compressionKey.QueryValue(kSolid, solid) == ERROR_SUCCESS) + info.Solid = solid; + bool multiThread = false; + if (compressionKey.QueryValue(kMultiThread, multiThread) == ERROR_SUCCESS) + info.MultiThread = multiThread; + + { + CKey optionsKey; + if(optionsKey.Open(compressionKey, kCompressionOptionsKeyName, KEY_READ) == + ERROR_SUCCESS) + { + CSysStringVector formatIDs; + optionsKey.EnumKeys(formatIDs); + for(int i = 0; i < formatIDs.Size(); i++) + { + CKey formatKey; + NCompression::CFormatOptions fo; + fo.FormatID = formatIDs[i]; + if(formatKey.Open(optionsKey, fo.FormatID, KEY_READ) == ERROR_SUCCESS) + { + GetRegString(formatKey, kCompressionOptions, fo.Options); + GetRegString(formatKey, kCompressionMethod, fo.Method); + GetRegString(formatKey, kEncryptionMethod, fo.EncryptionMethod); + + GetRegUInt32(formatKey, kCompressionLevel, fo.Level); + GetRegUInt32(formatKey, kCompressionDictionary, fo.Dictionary); + GetRegUInt32(formatKey, kCompressionOrder, fo.Order); + + info.FormatOptionsVector.Add(fo); + } + + } + } + } + + UInt32 level; + if (compressionKey.QueryValue(kCompressionLevelValueName, level) == ERROR_SUCCESS) + info.Level = level; + CSysString archiveType; + if (compressionKey.QueryValue(kCompressionLastFormatValueName, archiveType) == ERROR_SUCCESS) + info.ArchiveType = GetUnicodeString(archiveType); + if (compressionKey.QueryValue(kCompressionShowPasswordValueName, + info.ShowPassword) != ERROR_SUCCESS) + info.ShowPassword = false; + if (compressionKey.QueryValue(kCompressionEncryptHeadersValueName, + info.EncryptHeaders) != ERROR_SUCCESS) + info.EncryptHeaders = false; + /* + if (compressionKey.QueryValue(kCompressionLevelValueName, info.Maximize) == ERROR_SUCCESS) + definedStatus.Maximize = true; + */ +} + + +/////////////////////////////////// +// WorkDirInfo + +static const TCHAR *kOptionsInfoKeyName = TEXT("Options"); + +static const TCHAR *kWorkDirTypeValueName = TEXT("WorkDirType"); +static const WCHAR *kWorkDirPathValueName = L"WorkDirPath"; +static const TCHAR *kTempRemovableOnlyValueName = TEXT("TempRemovableOnly"); +static const TCHAR *kCascadedMenuValueName = TEXT("CascadedMenu"); +static const TCHAR *kContextMenuValueName = TEXT("ContextMenu"); + +void SaveWorkDirInfo(const NWorkDir::CInfo &info) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey optionsKey; + optionsKey.Create(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName)); + optionsKey.SetValue(kWorkDirTypeValueName, UInt32(info.Mode)); + optionsKey.SetValue(kWorkDirPathValueName, info.Path); + optionsKey.SetValue(kTempRemovableOnlyValueName, info.ForRemovableOnly); +} + +void ReadWorkDirInfo(NWorkDir::CInfo &info) +{ + info.SetDefault(); + + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey optionsKey; + if(optionsKey.Open(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName), KEY_READ) != ERROR_SUCCESS) + return; + + UInt32 dirType; + if (optionsKey.QueryValue(kWorkDirTypeValueName, dirType) != ERROR_SUCCESS) + return; + switch (dirType) + { + case NWorkDir::NMode::kSystem: + case NWorkDir::NMode::kCurrent: + case NWorkDir::NMode::kSpecified: + info.Mode = NWorkDir::NMode::EEnum(dirType); + } + UString sysWorkDir; + if (optionsKey.QueryValue(kWorkDirPathValueName, sysWorkDir) != ERROR_SUCCESS) + { + info.Path.Empty(); + if (info.Mode == NWorkDir::NMode::kSpecified) + info.Mode = NWorkDir::NMode::kSystem; + } + info.Path = GetUnicodeString(sysWorkDir); + if (optionsKey.QueryValue(kTempRemovableOnlyValueName, info.ForRemovableOnly) != ERROR_SUCCESS) + info.SetForRemovableOnlyDefault(); +} + +static void SaveOption(const TCHAR *value, bool enabled) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey optionsKey; + optionsKey.Create(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName)); + optionsKey.SetValue(value, enabled); +} + +static bool ReadOption(const TCHAR *value, bool defaultValue) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey optionsKey; + if(optionsKey.Open(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName), KEY_READ) != ERROR_SUCCESS) + return defaultValue; + bool enabled; + if (optionsKey.QueryValue(value, enabled) != ERROR_SUCCESS) + return defaultValue; + return enabled; +} + +void SaveCascadedMenu(bool show) + { SaveOption(kCascadedMenuValueName, show); } +bool ReadCascadedMenu() + { return ReadOption(kCascadedMenuValueName, true); } + + +static void SaveValue(const TCHAR *value, UInt32 valueToWrite) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey optionsKey; + optionsKey.Create(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName)); + optionsKey.SetValue(value, valueToWrite); +} + +static bool ReadValue(const TCHAR *value, UInt32 &result) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey optionsKey; + if(optionsKey.Open(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName), KEY_READ) != ERROR_SUCCESS) + return false; + return (optionsKey.QueryValue(value, result) == ERROR_SUCCESS); +} + +void SaveContextMenuStatus(UInt32 value) + { SaveValue(kContextMenuValueName, value); } + +bool ReadContextMenuStatus(UInt32 &value) + { return ReadValue(kContextMenuValueName, value); } diff --git a/CPP/7zip/UI/Common/ZipRegistry.h b/CPP/7zip/UI/Common/ZipRegistry.h new file mode 100755 index 00000000..30e7ee44 --- /dev/null +++ b/CPP/7zip/UI/Common/ZipRegistry.h @@ -0,0 +1,99 @@ +// ZipRegistry.h + +#ifndef __ZIPREGISTRY_H +#define __ZIPREGISTRY_H + +#include "Common/String.h" +#include "Common/Types.h" +#include "ExtractMode.h" + +namespace NExtract +{ + struct CInfo + { + NPathMode::EEnum PathMode; + NOverwriteMode::EEnum OverwriteMode; + UStringVector Paths; + bool ShowPassword; + }; +} + +namespace NCompression { + + struct CFormatOptions + { + CSysString FormatID; + UString Options; + UString Method; + UString EncryptionMethod; + UInt32 Level; + UInt32 Dictionary; + UInt32 Order; + void ResetForLevelChange() + { + Level = Dictionary = Order = UInt32(-1); + Method.Empty(); + // EncryptionMethod.Empty(); + // Options.Empty(); + } + CFormatOptions() { ResetForLevelChange(); } + }; + + struct CInfo + { + UStringVector HistoryArchives; + // bool LevelIsDefined; + UInt32 Level; + UString ArchiveType; + + bool Solid; + bool MultiThread; + CObjectVector FormatOptionsVector; + + bool ShowPassword; + bool EncryptHeaders; + }; +} + +namespace NWorkDir{ + + namespace NMode + { + enum EEnum + { + kSystem, + kCurrent, + kSpecified + }; + } + struct CInfo + { + NMode::EEnum Mode; + UString Path; + bool ForRemovableOnly; + void SetForRemovableOnlyDefault() { ForRemovableOnly = true; } + void SetDefault() + { + Mode = NMode::kSystem; + Path.Empty(); + SetForRemovableOnlyDefault(); + } + }; +} + +void SaveExtractionInfo(const NExtract::CInfo &info); +void ReadExtractionInfo(NExtract::CInfo &info); + +void SaveCompressionInfo(const NCompression::CInfo &info); +void ReadCompressionInfo(NCompression::CInfo &info); + +void SaveWorkDirInfo(const NWorkDir::CInfo &info); +void ReadWorkDirInfo(NWorkDir::CInfo &info); + +void SaveCascadedMenu(bool enabled); +bool ReadCascadedMenu(); + +void SaveContextMenuStatus(UInt32 value); +bool ReadContextMenuStatus(UInt32 &value); + +#endif diff --git a/CPP/7zip/UI/Console/Console.dsp b/CPP/7zip/UI/Console/Console.dsp new file mode 100755 index 00000000..e457008c --- /dev/null +++ b/CPP/7zip/UI/Console/Console.dsp @@ -0,0 +1,667 @@ +# Microsoft Developer Studio Project File - Name="Console" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=Console - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Console.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Console.mak" CFG="Console - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Console - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "Console - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "Console - Win32 ReleaseU" (based on "Win32 (x86) Console Application") +!MESSAGE "Console - Win32 DebugU" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Console - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7z.exe" /OPT:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Console - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "../../../" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\UTIL\7z.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "Console - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Console___Win32_ReleaseU" +# PROP BASE Intermediate_Dir "Console___Win32_ReleaseU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "../../../" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /c +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7z.exe" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"C:\UTIL\7zn.exe" /OPT:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Console - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Console___Win32_DebugU" +# PROP BASE Intermediate_Dir "Console___Win32_DebugU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "../../../" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /W3 /Gm /GX /ZI /Od /I "../../../" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_CONSOLE" /D "COMPRESS_MT" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\UTIL\7z.exe" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"C:\UTIL\7z.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Console - Win32 Release" +# Name "Console - Win32 Debug" +# Name "Console - Win32 ReleaseU" +# Name "Console - Win32 DebugU" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Console" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ConsoleClose.cpp +# End Source File +# Begin Source File + +SOURCE=.\ConsoleClose.h +# End Source File +# Begin Source File + +SOURCE=.\ExtractCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=.\List.cpp +# End Source File +# Begin Source File + +SOURCE=.\List.h +# End Source File +# Begin Source File + +SOURCE=.\Main.cpp +# End Source File +# Begin Source File + +SOURCE=.\MainAr.cpp +# End Source File +# Begin Source File + +SOURCE=.\OpenCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=.\OpenCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=.\PercentPrinter.cpp +# End Source File +# Begin Source File + +SOURCE=.\PercentPrinter.h +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallbackConsole.cpp +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallbackConsole.h +# End Source File +# Begin Source File + +SOURCE=.\UserInputUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\UserInputUtils.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.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\PropVariantConversions.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Time.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Buffer.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ComTry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Exception.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdOutStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ArchiveCommandLine.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveCommandLine.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiverInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiverInfo.h +# End Source File +# Begin Source File + +SOURCE=..\Common\CompressionMode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DirItem.h +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExitCode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Extract.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\HandlerLoader.h +# End Source File +# Begin Source File + +SOURCE=..\Common\IFileExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Property.h +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SetProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SetProperties.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\TempFiles.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\TempFiles.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Update.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Update.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +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 +# Begin Group "7-zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/UI/Console/Console.dsw b/CPP/7zip/UI/Console/Console.dsw new file mode 100755 index 00000000..0d93da2f --- /dev/null +++ b/CPP/7zip/UI/Console/Console.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Console"=".\Console.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/UI/Console/ConsoleClose.cpp b/CPP/7zip/UI/Console/ConsoleClose.cpp new file mode 100755 index 00000000..a514c12a --- /dev/null +++ b/CPP/7zip/UI/Console/ConsoleClose.cpp @@ -0,0 +1,65 @@ +// ConsoleClose.cpp + +#include "StdAfx.h" + +#include + +#include "ConsoleClose.h" + +static int g_BreakCounter = 0; +static const int kBreakAbortThreshold = 2; + +namespace NConsoleClose { + +static BOOL WINAPI HandlerRoutine(DWORD ctrlType) +{ + if (ctrlType == CTRL_LOGOFF_EVENT) + { + // printf("\nCTRL_LOGOFF_EVENT\n"); + return TRUE; + } + + g_BreakCounter++; + if (g_BreakCounter < kBreakAbortThreshold) + return TRUE; + return FALSE; + /* + switch(ctrlType) + { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: + if (g_BreakCounter < kBreakAbortThreshold) + return TRUE; + } + return FALSE; + */ +} + +bool TestBreakSignal() +{ + /* + if (g_BreakCounter > 0) + return true; + */ + return (g_BreakCounter > 0); +} + +void CheckCtrlBreak() +{ + if (TestBreakSignal()) + throw CCtrlBreakException(); +} + +CCtrlHandlerSetter::CCtrlHandlerSetter() +{ + if(!SetConsoleCtrlHandler(HandlerRoutine, TRUE)) + throw "SetConsoleCtrlHandler fails"; +} + +CCtrlHandlerSetter::~CCtrlHandlerSetter() +{ + if(!SetConsoleCtrlHandler(HandlerRoutine, FALSE)) + throw "SetConsoleCtrlHandler fails"; +} + +} diff --git a/CPP/7zip/UI/Console/ConsoleClose.h b/CPP/7zip/UI/Console/ConsoleClose.h new file mode 100755 index 00000000..3c5fd55d --- /dev/null +++ b/CPP/7zip/UI/Console/ConsoleClose.h @@ -0,0 +1,24 @@ +// ConsoleCloseUtils.h + +#ifndef __CONSOLECLOSEUTILS_H +#define __CONSOLECLOSEUTILS_H + +namespace NConsoleClose { + +bool TestBreakSignal(); + +class CCtrlHandlerSetter +{ +public: + CCtrlHandlerSetter(); + virtual ~CCtrlHandlerSetter(); +}; + +class CCtrlBreakException +{}; + +void CheckCtrlBreak(); + +} + +#endif diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp new file mode 100755 index 00000000..9bd605ec --- /dev/null +++ b/CPP/7zip/UI/Console/ExtractCallbackConsole.cpp @@ -0,0 +1,235 @@ +// ExtractCallbackConsole.h + +#include "StdAfx.h" + +#include "ExtractCallbackConsole.h" +#include "UserInputUtils.h" +#include "ConsoleClose.h" + +#include "Common/Wildcard.h" + +#include "Windows/FileDir.h" +#include "Windows/FileFind.h" +#include "Windows/Time.h" +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" +#include "Windows/Error.h" +#include "Windows/PropVariantConversions.h" + +#include "../../Common/FilePathAutoRename.h" + +#include "../Common/ExtractingFilePath.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDirectory; + +static const char *kTestingString = "Testing "; +static const char *kExtractingString = "Extracting "; +static const char *kSkippingString = "Skipping "; + +static const char *kCantAutoRename = "can not create file with auto name\n"; +static const char *kCantRenameFile = "can not rename existing file\n"; +static const char *kCantDeleteOutputFile = "can not delete output file "; +static const char *kError = "ERROR: "; +static const char *kMemoryExceptionMessage = "Can't allocate required memory!"; + +static const char *kProcessing = "Processing archive: "; +static const char *kEverythingIsOk = "Everything is Ok"; +static const char *kNoFiles = "No files to process"; + +static const char *kUnsupportedMethod = "Unsupported Method"; +static const char *kCrcFailed = "CRC Failed"; +static const char *kCrcFailedEncrypted = "CRC Failed in encrypted file. Wrong password?"; +static const char *kDataError = "Data Error"; +static const char *kDataErrorEncrypted = "Data Error in encrypted file. Wrong password?"; +static const char *kUnknownError = "Unknown Error"; + +STDMETHODIMP CExtractCallbackConsole::SetTotal(UInt64) +{ + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::SetCompleted(const UInt64 *) +{ + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::AskOverwrite( + const wchar_t *existName, const FILETIME *, const UInt64 *, + const wchar_t *newName, const FILETIME *, const UInt64 *, + Int32 *answer) +{ + (*OutStream) << "file " << existName << + "\nalready exists. Overwrite with " << endl; + (*OutStream) << newName; + + NUserAnswerMode::EEnum overwriteAnswer = ScanUserYesNoAllQuit(OutStream); + + switch(overwriteAnswer) + { + case NUserAnswerMode::kQuit: + return E_ABORT; + case NUserAnswerMode::kNo: + *answer = NOverwriteAnswer::kNo; + break; + case NUserAnswerMode::kNoAll: + *answer = NOverwriteAnswer::kNoToAll; + break; + case NUserAnswerMode::kYesAll: + *answer = NOverwriteAnswer::kYesToAll; + break; + case NUserAnswerMode::kYes: + *answer = NOverwriteAnswer::kYes; + break; + case NUserAnswerMode::kAutoRename: + *answer = NOverwriteAnswer::kAutoRename; + break; + default: + return E_FAIL; + } + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int32 askExtractMode, const UInt64 *position) +{ + switch (askExtractMode) + { + case NArchive::NExtract::NAskMode::kExtract: + (*OutStream) << kExtractingString; + break; + case NArchive::NExtract::NAskMode::kTest: + (*OutStream) << kTestingString; + break; + case NArchive::NExtract::NAskMode::kSkip: + (*OutStream) << kSkippingString; + break; + }; + (*OutStream) << name; + if (position != 0) + (*OutStream) << " <" << *position << ">"; + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::MessageError(const wchar_t *message) +{ + (*OutStream) << message << endl; + NumFileErrorsInCurrentArchive++; + NumFileErrors++; + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::SetOperationResult(Int32 operationResult, bool encrypted) +{ + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kOK: + break; + default: + { + NumFileErrorsInCurrentArchive++; + NumFileErrors++; + (*OutStream) << " "; + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kUnSupportedMethod: + (*OutStream) << kUnsupportedMethod; + break; + case NArchive::NExtract::NOperationResult::kCRCError: + (*OutStream) << (encrypted ? kCrcFailedEncrypted: kCrcFailed); + break; + case NArchive::NExtract::NOperationResult::kDataError: + (*OutStream) << (encrypted ? kDataErrorEncrypted : kDataError); + break; + default: + (*OutStream) << kUnknownError; + } + } + } + (*OutStream) << endl; + return S_OK; +} + +STDMETHODIMP CExtractCallbackConsole::CryptoGetTextPassword(BSTR *password) +{ + if (!PasswordIsDefined) + { + Password = GetPassword(OutStream); + PasswordIsDefined = true; + } + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} + +HRESULT CExtractCallbackConsole::BeforeOpen(const wchar_t *name) +{ + NumArchives++; + NumFileErrorsInCurrentArchive = 0; + (*OutStream) << endl << kProcessing << name << endl; + return S_OK; +} + +HRESULT CExtractCallbackConsole::OpenResult(const wchar_t * /* name */, HRESULT result, bool encrypted) +{ + (*OutStream) << endl; + if (result != S_OK) + { + (*OutStream) << "Error: "; + if (encrypted) + (*OutStream) << "Can not open encrypted archive. Wrong password?"; + else + (*OutStream) << "Can not open file as archive"; + (*OutStream) << endl; + NumArchiveErrors++; + } + return S_OK; +} + +HRESULT CExtractCallbackConsole::ThereAreNoFiles() +{ + (*OutStream) << endl << kNoFiles << endl; + return S_OK; +} + +HRESULT CExtractCallbackConsole::ExtractResult(HRESULT result) +{ + if (result == S_OK) + { + (*OutStream) << endl; + if (NumFileErrorsInCurrentArchive == 0) + (*OutStream) << kEverythingIsOk << endl; + else + { + NumArchiveErrors++; + (*OutStream) << "Sub items Errors: " << NumFileErrorsInCurrentArchive << endl; + } + } + if (result == S_OK) + return result; + NumArchiveErrors++; + if (result == E_ABORT || result == ERROR_DISK_FULL) + return result; + (*OutStream) << endl << kError; + if (result == E_OUTOFMEMORY) + (*OutStream) << kMemoryExceptionMessage; + else + { + UString message; + NError::MyFormatMessage(result, message); + (*OutStream) << message; + } + (*OutStream) << endl; + return S_OK; +} + +HRESULT CExtractCallbackConsole::SetPassword(const UString &password) +{ + PasswordIsDefined = true; + Password = password; + return S_OK; +} diff --git a/CPP/7zip/UI/Console/ExtractCallbackConsole.h b/CPP/7zip/UI/Console/ExtractCallbackConsole.h new file mode 100755 index 00000000..5b45106a --- /dev/null +++ b/CPP/7zip/UI/Console/ExtractCallbackConsole.h @@ -0,0 +1,65 @@ +// ExtractCallbackConsole.h + +#ifndef __EXTRACTCALLBACKCONSOLE_H +#define __EXTRACTCALLBACKCONSOLE_H + +#include "Common/String.h" +#include "Common/StdOutStream.h" +#include "../../Common/FileStreams.h" +#include "../../IPassword.h" +#include "../../Archive/IArchive.h" +#include "../Common/ArchiveExtractCallback.h" + +class CExtractCallbackConsole: + public IExtractCallbackUI, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP2(IFolderArchiveExtractCallback, ICryptoGetTextPassword) + + STDMETHOD(SetTotal)(UInt64 total); + STDMETHOD(SetCompleted)(const UInt64 *completeValue); + + // IFolderArchiveExtractCallback + STDMETHOD(AskOverwrite)( + const wchar_t *existName, const FILETIME *existTime, const UInt64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UInt64 *newSize, + Int32 *answer); + STDMETHOD (PrepareOperation)(const wchar_t *name, Int32 askExtractMode, const UInt64 *position); + + STDMETHOD(MessageError)(const wchar_t *message); + STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted); + + // ICryptoGetTextPassword + STDMETHOD(CryptoGetTextPassword)(BSTR *password); + + HRESULT BeforeOpen(const wchar_t *name); + HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted); + HRESULT ThereAreNoFiles(); + HRESULT ExtractResult(HRESULT result); + + HRESULT SetPassword(const UString &password); + +public: + bool PasswordIsDefined; + UString Password; + + UInt64 NumArchives; + UInt64 NumArchiveErrors; + UInt64 NumFileErrors; + UInt64 NumFileErrorsInCurrentArchive; + + CStdOutStream *OutStream; + + void Init() + { + NumArchives = 0; + NumArchiveErrors = 0; + NumFileErrors = 0; + NumFileErrorsInCurrentArchive = 0; + } + +}; + +#endif diff --git a/CPP/7zip/UI/Console/List.cpp b/CPP/7zip/UI/Console/List.cpp new file mode 100755 index 00000000..6001e114 --- /dev/null +++ b/CPP/7zip/UI/Console/List.cpp @@ -0,0 +1,532 @@ +// List.cpp + +#include "StdAfx.h" + +#include "List.h" +#include "ConsoleClose.h" + +#include "Common/StringConvert.h" +#include "Common/StdOutStream.h" +#include "Common/IntToString.h" +#include "Common/MyCom.h" + +#include "Windows/PropVariant.h" +#include "Windows/Defs.h" +#include "Windows/PropVariantConversions.h" +#include "Windows/FileDir.h" + +#include "../../Archive/IArchive.h" + +#include "../Common/PropIDUtils.h" +#include "../Common/OpenArchive.h" + +#include "OpenCallbackConsole.h" + +using namespace NWindows; + +struct CPropIdToName +{ + PROPID PropID; + const wchar_t *Name; +}; + +static CPropIdToName kPropIdToName[] = +{ + { kpidPath, L"Path" }, + { kpidName, L"Name" }, + { kpidIsFolder, L"Folder" }, + { kpidSize, L"Size" }, + { kpidPackedSize, L"Packed Size" }, + { kpidAttributes, L"Attributes" }, + { kpidCreationTime, L"Created" }, + { kpidLastAccessTime, L"Accessed" }, + { kpidLastWriteTime, L"Modified" }, + { kpidSolid, L"Solid" }, + { kpidCommented, L"Commented" }, + { kpidEncrypted, L"Encrypted" }, + { kpidSplitBefore, L"Split Before" }, + { kpidSplitAfter, L"Split After" }, + { kpidDictionarySize, L"Dictionary Size" }, + { kpidCRC, L"CRC" }, + { kpidType, L"Type" }, + { kpidIsAnti, L"Anti" }, + { kpidMethod, L"Method" }, + { kpidHostOS, L"Host OS" }, + { kpidFileSystem, L"File System" }, + { kpidUser, L"User" }, + { kpidGroup, L"Group" }, + { kpidBlock, L"Block" }, + { kpidComment, L"Comment" }, + { kpidPosition, L"Position" } +}; + +static const char kEmptyAttributeChar = '.'; +static const char kDirectoryAttributeChar = 'D'; +static const char kReadonlyAttributeChar = 'R'; +static const char kHiddenAttributeChar = 'H'; +static const char kSystemAttributeChar = 'S'; +static const char kArchiveAttributeChar = 'A'; + +static const char *kListing = "Listing archive: "; +static const wchar_t *kFilesMessage = L"files"; + +static void GetAttributesString(DWORD wa, bool directory, char *s) +{ + s[0] = ((wa & FILE_ATTRIBUTE_DIRECTORY) != 0 || directory) ? + kDirectoryAttributeChar: kEmptyAttributeChar; + s[1] = ((wa & FILE_ATTRIBUTE_READONLY) != 0)? + kReadonlyAttributeChar: kEmptyAttributeChar; + s[2] = ((wa & FILE_ATTRIBUTE_HIDDEN) != 0) ? + kHiddenAttributeChar: kEmptyAttributeChar; + s[3] = ((wa & FILE_ATTRIBUTE_SYSTEM) != 0) ? + kSystemAttributeChar: kEmptyAttributeChar; + s[4] = ((wa & FILE_ATTRIBUTE_ARCHIVE) != 0) ? + kArchiveAttributeChar: kEmptyAttributeChar; + s[5] = '\0'; +} + +enum EAdjustment +{ + kLeft, + kCenter, + kRight +}; + +struct CFieldInfo +{ + PROPID PropID; + UString Name; + EAdjustment TitleAdjustment; + EAdjustment TextAdjustment; + int PrefixSpacesWidth; + int Width; +}; + +struct CFieldInfoInit +{ + PROPID PropID; + const wchar_t *Name; + EAdjustment TitleAdjustment; + EAdjustment TextAdjustment; + int PrefixSpacesWidth; + int Width; +}; + +CFieldInfoInit kStandardFieldTable[] = +{ + { kpidLastWriteTime, L" Date Time", kLeft, kLeft, 0, 19 }, + { kpidAttributes, L"Attr", kRight, kCenter, 1, 5 }, + { kpidSize, L"Size", kRight, kRight, 1, 12 }, + { kpidPackedSize, L"Compressed", kRight, kRight, 1, 12 }, + { kpidPath, L"Name", kLeft, kLeft, 2, 12 } +}; + +void PrintSpaces(int numSpaces) +{ + for (int i = 0; i < numSpaces; i++) + g_StdOut << ' '; +} + +void PrintString(EAdjustment adjustment, int width, const UString &textString) +{ + const int numSpaces = width - textString.Length(); + int numLeftSpaces = 0; + switch (adjustment) + { + case kLeft: + numLeftSpaces = 0; + break; + case kCenter: + numLeftSpaces = numSpaces / 2; + break; + case kRight: + numLeftSpaces = numSpaces; + break; + } + PrintSpaces(numLeftSpaces); + g_StdOut << textString; + PrintSpaces(numSpaces - numLeftSpaces); +} + +class CFieldPrinter +{ + CObjectVector _fields; +public: + void Clear() { _fields.Clear(); } + void Init(const CFieldInfoInit *standardFieldTable, int numItems); + HRESULT Init(IInArchive *archive); + void PrintTitle(); + void PrintTitleLines(); + HRESULT PrintItemInfo(IInArchive *archive, + const UString &defaultItemName, + const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo, + UInt32 index, + bool techMode); + HRESULT PrintSummaryInfo(UInt64 numFiles, const UInt64 *size, + const UInt64 *compressedSize); +}; + +void CFieldPrinter::Init(const CFieldInfoInit *standardFieldTable, int numItems) +{ + Clear(); + for (int i = 0; i < numItems; i++) + { + CFieldInfo fieldInfo; + const CFieldInfoInit &fieldInfoInit = standardFieldTable[i]; + fieldInfo.PropID = fieldInfoInit.PropID; + fieldInfo.Name = fieldInfoInit.Name; + fieldInfo.TitleAdjustment = fieldInfoInit.TitleAdjustment; + fieldInfo.TextAdjustment = fieldInfoInit.TextAdjustment; + fieldInfo.PrefixSpacesWidth = fieldInfoInit.PrefixSpacesWidth; + fieldInfo.Width = fieldInfoInit.Width; + _fields.Add(fieldInfo); + } +} + +HRESULT CFieldPrinter::Init(IInArchive *archive) +{ + Clear(); + UInt32 numProps; + RINOK(archive->GetNumberOfProperties(&numProps)); + for (UInt32 i = 0; i < numProps; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + RINOK(archive->GetPropertyInfo(i, &name, &propID, &vt)); + CFieldInfo fieldInfo; + fieldInfo.PropID = propID; + if (name != NULL) + fieldInfo.Name = name; + else + { + fieldInfo.Name = L"Unknown"; + for (int i = 0; i < sizeof(kPropIdToName) / sizeof(kPropIdToName[0]); i++) + { + const CPropIdToName &propIdToName = kPropIdToName[i]; + if (propIdToName.PropID == propID) + { + fieldInfo.Name = propIdToName.Name; + break; + } + } + } + _fields.Add(fieldInfo); + } + return S_OK; +} + +void CFieldPrinter::PrintTitle() +{ + for (int i = 0; i < _fields.Size(); i++) + { + const CFieldInfo &fieldInfo = _fields[i]; + PrintSpaces(fieldInfo.PrefixSpacesWidth); + PrintString(fieldInfo.TitleAdjustment, + ((fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width), fieldInfo.Name); + } +} + +void CFieldPrinter::PrintTitleLines() +{ + for (int i = 0; i < _fields.Size(); i++) + { + const CFieldInfo &fieldInfo = _fields[i]; + PrintSpaces(fieldInfo.PrefixSpacesWidth); + for (int i = 0; i < fieldInfo.Width; i++) + g_StdOut << '-'; + } +} + + +BOOL IsFileTimeZero(CONST FILETIME *lpFileTime) +{ + return (lpFileTime->dwLowDateTime == 0) && (lpFileTime->dwHighDateTime == 0); +} + +static const char *kEmptyTimeString = " "; +void PrintTime(const NCOM::CPropVariant &propVariant) +{ + if (propVariant.vt != VT_FILETIME) + throw "incorrect item"; + if (IsFileTimeZero(&propVariant.filetime)) + g_StdOut << kEmptyTimeString; + else + { + FILETIME localFileTime; + if (!FileTimeToLocalFileTime(&propVariant.filetime, &localFileTime)) + throw "FileTimeToLocalFileTime error"; + char s[32]; + if (ConvertFileTimeToString(localFileTime, s, true, true)) + g_StdOut << s; + else + g_StdOut << kEmptyTimeString; + } +} + +HRESULT CFieldPrinter::PrintItemInfo(IInArchive *archive, + const UString &defaultItemName, + const NWindows::NFile::NFind::CFileInfoW &archiveFileInfo, + UInt32 index, + bool techMode) +{ + /* + if (techMode) + { + g_StdOut << "Index = "; + g_StdOut << (UInt64)index; + g_StdOut << endl; + } + */ + for (int i = 0; i < _fields.Size(); i++) + { + const CFieldInfo &fieldInfo = _fields[i]; + if (!techMode) + PrintSpaces(fieldInfo.PrefixSpacesWidth); + + NCOM::CPropVariant propVariant; + RINOK(archive->GetProperty(index, fieldInfo.PropID, &propVariant)); + if (techMode) + { + g_StdOut << fieldInfo.Name << " = "; + } + int width = (fieldInfo.PropID == kpidPath) ? 0: fieldInfo.Width; + if (propVariant.vt == VT_EMPTY) + { + switch(fieldInfo.PropID) + { + case kpidPath: + propVariant = defaultItemName; + break; + case kpidLastWriteTime: + propVariant = archiveFileInfo.LastWriteTime; + break; + default: + if (techMode) + g_StdOut << endl; + else + PrintSpaces(width); + continue; + } + } + if (fieldInfo.PropID == kpidLastWriteTime) + { + PrintTime(propVariant); + } + else if (fieldInfo.PropID == kpidAttributes) + { + if (propVariant.vt != VT_UI4) + throw "incorrect item"; + UInt32 attributes = propVariant.ulVal; + bool isFolder; + RINOK(IsArchiveItemFolder(archive, index, isFolder)); + char s[8]; + GetAttributesString(attributes, isFolder, s); + g_StdOut << s; + } + else if (propVariant.vt == VT_BSTR) + { + if (techMode) + g_StdOut << propVariant.bstrVal; + else + PrintString(fieldInfo.TextAdjustment, width, propVariant.bstrVal); + } + else + { + UString s = ConvertPropertyToString(propVariant, fieldInfo.PropID); + if (techMode) + g_StdOut << s; + else + PrintString(fieldInfo.TextAdjustment, width, s); + } + if (techMode) + g_StdOut << endl; + } + return S_OK; +} + +void PrintNumberString(EAdjustment adjustment, int width, const UInt64 *value) +{ + wchar_t textString[32] = { 0 }; + if (value != NULL) + ConvertUInt64ToString(*value, textString); + PrintString(adjustment, width, textString); +} + + +HRESULT CFieldPrinter::PrintSummaryInfo(UInt64 numFiles, + const UInt64 *size, const UInt64 *compressedSize) +{ + for (int i = 0; i < _fields.Size(); i++) + { + const CFieldInfo &fieldInfo = _fields[i]; + PrintSpaces(fieldInfo.PrefixSpacesWidth); + NCOM::CPropVariant propVariant; + if (fieldInfo.PropID == kpidSize) + PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, size); + else if (fieldInfo.PropID == kpidPackedSize) + PrintNumberString(fieldInfo.TextAdjustment, fieldInfo.Width, compressedSize); + else if (fieldInfo.PropID == kpidPath) + { + wchar_t textString[32]; + ConvertUInt64ToString(numFiles, textString); + UString temp = textString; + temp += L" "; + temp += kFilesMessage; + PrintString(fieldInfo.TextAdjustment, 0, temp); + } + else + PrintString(fieldInfo.TextAdjustment, fieldInfo.Width, L""); + } + return S_OK; +} + +bool GetUInt64Value(IInArchive *archive, UInt32 index, PROPID propID, UInt64 &value) +{ + NCOM::CPropVariant propVariant; + if (archive->GetProperty(index, propID, &propVariant) != S_OK) + throw "GetPropertyValue error"; + if (propVariant.vt == VT_EMPTY) + return false; + value = ConvertPropVariantToUInt64(propVariant); + return true; +} + +HRESULT ListArchives(UStringVector &archivePaths, UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + bool enableHeaders, bool techMode, bool &passwordEnabled, UString &password) +{ + CFieldPrinter fieldPrinter; + if (!techMode) + fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0])); + + UInt64 numFiles2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0; + UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0; + int numErrors = 0; + for (int i = 0; i < archivePaths.Size(); i++) + { + const UString &archiveName = archivePaths[i]; + NFile::NFind::CFileInfoW archiveFileInfo; + if (!NFile::NFind::FindFile(archiveName, archiveFileInfo) || archiveFileInfo.IsDirectory()) + { + g_StdOut << endl << "Error: " << archiveName << " is not archive" << endl; + numErrors++; + continue; + } + if (archiveFileInfo.IsDirectory()) + { + g_StdOut << endl << "Error: " << archiveName << " is not file" << endl; + numErrors++; + continue; + } + + CArchiveLink archiveLink; + + COpenCallbackConsole openCallback; + openCallback.OutStream = &g_StdOut; + openCallback.PasswordIsDefined = passwordEnabled; + openCallback.Password = password; + + HRESULT result = MyOpenArchive(archiveName, archiveLink, &openCallback); + if (result != S_OK) + { + g_StdOut << endl << "Error: " << archiveName << " is not supported archive" << endl; + numErrors++; + continue; + } + + for (int v = 0; v < archiveLink.VolumePaths.Size(); v++) + { + int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]); + if (index >= 0 && index > i) + { + archivePaths.Delete(index); + archivePathsFull.Delete(index); + } + } + + IInArchive *archive = archiveLink.GetArchive(); + const UString defaultItemName = archiveLink.GetDefaultItemName(); + + if (enableHeaders) + g_StdOut << endl << kListing << archiveName << endl << endl; + + if (enableHeaders && !techMode) + { + fieldPrinter.PrintTitle(); + g_StdOut << endl; + fieldPrinter.PrintTitleLines(); + g_StdOut << endl; + } + + if (techMode) + { + RINOK(fieldPrinter.Init(archive)); + } + UInt64 numFiles = 0, totalPackSize = 0, totalUnPackSize = 0; + UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0; + UInt32 numItems; + RINOK(archive->GetNumberOfItems(&numItems)); + for(UInt32 i = 0; i < numItems; i++) + { + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + + UString filePath; + RINOK(GetArchiveItemPath(archive, i, defaultItemName, filePath)); + + bool isFolder; + RINOK(IsArchiveItemFolder(archive, i, isFolder)); + if (!wildcardCensor.CheckPath(filePath, !isFolder)) + continue; + + fieldPrinter.PrintItemInfo(archive, defaultItemName, archiveFileInfo, i, techMode); + + UInt64 packSize, unpackSize; + if (!GetUInt64Value(archive, i, kpidSize, unpackSize)) + unpackSize = 0; + else + totalUnPackSizePointer = &totalUnPackSize; + if (!GetUInt64Value(archive, i, kpidPackedSize, packSize)) + packSize = 0; + else + totalPackSizePointer = &totalPackSize; + + g_StdOut << endl; + + numFiles++; + totalPackSize += packSize; + totalUnPackSize += unpackSize; + } + if (enableHeaders && !techMode) + { + fieldPrinter.PrintTitleLines(); + g_StdOut << endl; + fieldPrinter.PrintSummaryInfo(numFiles, totalUnPackSizePointer, totalPackSizePointer); + g_StdOut << endl; + } + if (totalPackSizePointer != 0) + { + totalPackSizePointer2 = &totalPackSize2; + totalPackSize2 += totalPackSize; + } + if (totalUnPackSizePointer != 0) + { + totalUnPackSizePointer2 = &totalUnPackSize2; + totalUnPackSize2 += totalUnPackSize; + } + numFiles2 += numFiles; + } + if (enableHeaders && !techMode && archivePaths.Size() > 1) + { + g_StdOut << endl; + fieldPrinter.PrintTitleLines(); + g_StdOut << endl; + fieldPrinter.PrintSummaryInfo(numFiles2, totalUnPackSizePointer2, totalPackSizePointer2); + g_StdOut << endl; + g_StdOut << "Archives: " << archivePaths.Size() << endl; + } + if (numErrors > 0) + g_StdOut << endl << "Errors: " << numErrors; + return S_OK; +} diff --git a/CPP/7zip/UI/Console/List.h b/CPP/7zip/UI/Console/List.h new file mode 100755 index 00000000..201a4128 --- /dev/null +++ b/CPP/7zip/UI/Console/List.h @@ -0,0 +1,13 @@ +// List.h + +#ifndef __LIST_H +#define __LIST_H + +#include "Common/Wildcard.h" + +HRESULT ListArchives(UStringVector &archivePaths, UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + bool enableHeaders, bool techMode, bool &passwordEnabled, UString &password); + +#endif + diff --git a/CPP/7zip/UI/Console/Main.cpp b/CPP/7zip/UI/Console/Main.cpp new file mode 100755 index 00000000..387b8c2a --- /dev/null +++ b/CPP/7zip/UI/Console/Main.cpp @@ -0,0 +1,382 @@ +// Main.cpp + +#include "StdAfx.h" + +#include + +#include "Common/MyInitGuid.h" +#include "Common/CommandLineParser.h" +#include "Common/StdOutStream.h" +#include "Common/Wildcard.h" +#include "Common/ListFileUtils.h" +#include "Common/StringConvert.h" +#include "Common/StdInStream.h" +#include "Common/StringToInt.h" +#include "Common/Exception.h" + +#include "Windows/FileDir.h" +#include "Windows/FileName.h" +#include "Windows/Defs.h" +#include "Windows/Error.h" +// #include "Windows/System.h" +#ifdef _WIN32 +#include "Windows/MemoryLock.h" +#endif + +#include "../../IPassword.h" +#include "../../ICoder.h" +#include "../Common/ArchiverInfo.h" +#include "../Common/UpdateAction.h" +#include "../Common/Update.h" +#include "../Common/Extract.h" +#include "../Common/ArchiveCommandLine.h" +#include "../Common/ExitCode.h" + +#include "List.h" +#include "OpenCallbackConsole.h" +#include "ExtractCallbackConsole.h" +#include "UpdateCallbackConsole.h" + +#include "../../MyVersion.h" + +#ifndef EXCLUDE_COM +#include "Windows/DLL.h" +#endif + +using namespace NWindows; +using namespace NFile; +using namespace NCommandLineParser; + +HINSTANCE g_hInstance = 0; +extern CStdOutStream *g_StdStream; + +static const char *kCopyrightString = "\n7-Zip" +#ifdef EXCLUDE_COM +" (A)" +#endif + +#ifdef UNICODE +" [NT]" +#endif + +" " MY_VERSION_COPYRIGHT_DATE "\n"; + +static const char *kHelpString = + "\nUsage: 7z" +#ifdef _NO_CRYPTO + "r" +#elif EXCLUDE_COM + "a" +#endif + " [...] [...]\n" + " [<@listfiles...>]\n" + "\n" + "\n" + " a: Add files to archive\n" + " d: Delete files from archive\n" + " e: Extract files from archive (without using directory names)\n" + " l: List contents of archive\n" +// " l[a|t][f]: List contents of archive\n" +// " a - with Additional fields\n" +// " t - with all fields\n" +// " f - with Full pathnames\n" + " t: Test integrity of archive\n" + " u: Update files to archive\n" + " x: eXtract files with full paths\n" + "\n" + " -ai[r[-|0]]{@listfile|!wildcard}: Include archives\n" + " -ax[r[-|0]]{@listfile|!wildcard}: eXclude archives\n" + " -bd: Disable percentage indicator\n" + " -i[r[-|0]]{@listfile|!wildcard}: Include filenames\n" + " -m{Parameters}: set compression Method\n" + " -o{Directory}: set Output directory\n" + " -p{Password}: set Password\n" + " -r[-|0]: Recurse subdirectories\n" + " -scs{UTF-8 | WIN | DOS}: set charset for list files\n" + " -sfx[{name}]: Create SFX archive\n" + " -si[{name}]: read data from stdin\n" + " -slt: show technical information for l (List) command\n" + " -so: write data to stdout\n" + " -t{Type}: Set type of archive\n" + " -v{Size}[b|k|m|g]: Create volumes\n" + " -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName]: Update options\n" + " -w[{path}]: assign Work directory. Empty path means a temporary directory\n" + " -x[r[-|0]]]{@listfile|!wildcard}: eXclude filenames\n" + " -y: assume Yes on all queries\n"; + +// --------------------------- +// exception messages + +static const char *kProcessArchiveMessage = " archive: "; +static const char *kEverythingIsOk = "Everything is Ok"; +static const char *kUserErrorMessage = "Incorrect command line"; // NExitCode::kUserError + +static const wchar_t *kDefaultSfxModule = L"7zCon.sfx"; + +static void ShowMessageAndThrowException(CStdOutStream &s, LPCSTR message, NExitCode::EEnum code) +{ + s << message << endl; + throw code; +} + +static void PrintHelpAndExit(CStdOutStream &s) // yyy +{ + s << kHelpString; + ShowMessageAndThrowException(s, kUserErrorMessage, NExitCode::kUserError); +} + +#ifndef _WIN32 +static void GetArguments(int numArguments, const char *arguments[], UStringVector &parts) +{ + parts.Clear(); + for(int i = 0; i < numArguments; i++) + { + UString s = MultiByteToUnicodeString(arguments[i]); + parts.Add(s); + } +} +#endif + +static void ShowCopyrightAndHelp(CStdOutStream &s, bool needHelp) +{ + s << kCopyrightString; + /* + UInt32 numCPUs = NWindows::NSystem::GetNumberOfProcessors(); + s << "System configuration: " << (UInt64)numCPUs << " CPU"; + if (numCPUs > 1) + s << "s"; + s << "\n"; + */ + if (needHelp) + s << kHelpString; +} + +int Main2( + #ifndef _WIN32 + int numArguments, const char *arguments[] + #endif +) +{ + #ifdef _WIN32 + SetFileApisToOEM(); + #endif + + UStringVector commandStrings; + #ifdef _WIN32 + NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); + #else + GetArguments(numArguments, arguments, commandStrings); + #endif + + if(commandStrings.Size() == 1) + { + ShowCopyrightAndHelp(g_StdOut, true); + return 0; + } + commandStrings.Delete(0); + + CArchiveCommandLineOptions options; + + CArchiveCommandLineParser parser; + + parser.Parse1(commandStrings, options); + + if(options.HelpMode) + { + ShowCopyrightAndHelp(g_StdOut, true); + return 0; + } + + #ifdef _WIN32 + if (options.LargePages) + NSecurity::EnableLockMemoryPrivilege(); + #endif + + CStdOutStream &stdStream = options.StdOutMode ? g_StdErr : g_StdOut; + g_StdStream = &stdStream; + + if (options.EnableHeaders) + ShowCopyrightAndHelp(stdStream, false); + + parser.Parse2(options); + + bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); + if(isExtractGroupCommand || + options.Command.CommandType == NCommandType::kList) + { + if(isExtractGroupCommand) + { + CExtractCallbackConsole *ecs = new CExtractCallbackConsole; + CMyComPtr extractCallback = ecs; + + ecs->OutStream = &stdStream; + ecs->PasswordIsDefined = options.PasswordEnabled; + ecs->Password = options.Password; + ecs->Init(); + + COpenCallbackConsole openCallback; + openCallback.OutStream = &stdStream; + openCallback.PasswordIsDefined = options.PasswordEnabled; + openCallback.Password = options.Password; + + CExtractOptions eo; + eo.StdOutMode = options.StdOutMode; + eo.PathMode = options.Command.GetPathMode(); + eo.TestMode = options.Command.IsTestMode(); + eo.OverwriteMode = options.OverwriteMode; + eo.OutputDir = options.OutputDir; + eo.YesToAll = options.YesToAll; + #ifdef COMPRESS_MT + eo.Properties = options.ExtractProperties; + #endif + UString errorMessage; + HRESULT result = DecompressArchives( + options.ArchivePathsSorted, + options.ArchivePathsFullSorted, + options.WildcardCensor.Pairs.Front().Head, + eo, &openCallback, ecs, errorMessage); + if (!errorMessage.IsEmpty()) + { + stdStream << endl << "Error: " << errorMessage; + if (result == S_OK) + result = E_FAIL; + } + + if (ecs->NumArchives > 1) + { + stdStream << endl << endl << "Total:" << endl; + stdStream << "Archives: " << ecs->NumArchives << endl; + } + if (ecs->NumArchiveErrors != 0 || ecs->NumFileErrors != 0) + { + if (ecs->NumArchives > 1) + { + if (ecs->NumArchiveErrors != 0) + stdStream << "Archive Errors: " << ecs->NumArchiveErrors << endl; + if (ecs->NumFileErrors != 0) + stdStream << "Sub items Errors: " << ecs->NumFileErrors << endl; + } + if (result != S_OK) + throw CSystemException(result); + return NExitCode::kFatalError; + } + if (result != S_OK) + throw CSystemException(result); + } + else + { + HRESULT result = ListArchives( + options.ArchivePathsSorted, + options.ArchivePathsFullSorted, + options.WildcardCensor.Pairs.Front().Head, + options.EnableHeaders, + options.TechMode, + options.PasswordEnabled, + options.Password); + if (result != S_OK) + throw CSystemException(result); + } + } + else if(options.Command.IsFromUpdateGroup()) + { + UString workingDir; + + CUpdateOptions &uo = options.UpdateOptions; + if (uo.SfxMode && uo.SfxModule.IsEmpty()) + uo.SfxModule = kDefaultSfxModule; + + bool passwordIsDefined = + options.PasswordEnabled && !options.Password.IsEmpty(); + + COpenCallbackConsole openCallback; + openCallback.OutStream = &stdStream; + openCallback.PasswordIsDefined = passwordIsDefined; + openCallback.Password = options.Password; + + CUpdateCallbackConsole callback; + callback.EnablePercents = options.EnablePercents; + callback.PasswordIsDefined = passwordIsDefined; + callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty(); + callback.Password = options.Password; + callback.StdOutMode = uo.StdOutMode; + callback.Init(&stdStream); + + CUpdateErrorInfo errorInfo; + + HRESULT result = UpdateArchive(options.WildcardCensor, uo, + errorInfo, &openCallback, &callback); + + int exitCode = NExitCode::kSuccess; + if (callback.CantFindFiles.Size() > 0) + { + stdStream << endl; + stdStream << "WARNINGS for files:" << endl << endl; + int numErrors = callback.CantFindFiles.Size(); + for (int i = 0; i < numErrors; i++) + { + stdStream << callback.CantFindFiles[i] << " : "; + stdStream << NError::MyFormatMessageW(callback.CantFindCodes[i]) << endl; + } + stdStream << "----------------" << endl; + stdStream << "WARNING: Cannot find " << numErrors << " file"; + if (numErrors > 1) + stdStream << "s"; + stdStream << endl; + exitCode = NExitCode::kWarning; + } + + if (result != S_OK) + { + UString message; + if (!errorInfo.Message.IsEmpty()) + { + message += errorInfo.Message; + message += L"\n"; + } + if (!errorInfo.FileName.IsEmpty()) + { + message += errorInfo.FileName; + message += L"\n"; + } + if (!errorInfo.FileName2.IsEmpty()) + { + message += errorInfo.FileName2; + message += L"\n"; + } + if (errorInfo.SystemError != 0) + { + message += NError::MyFormatMessageW(errorInfo.SystemError); + message += L"\n"; + } + if (!message.IsEmpty()) + stdStream << L"\nError:\n" << message; + throw CSystemException(result); + } + int numErrors = callback.FailedFiles.Size(); + if (numErrors == 0) + { + if (callback.CantFindFiles.Size() == 0) + stdStream << kEverythingIsOk << endl; + } + else + { + stdStream << endl; + stdStream << "WARNINGS for files:" << endl << endl; + for (int i = 0; i < numErrors; i++) + { + stdStream << callback.FailedFiles[i] << " : "; + stdStream << NError::MyFormatMessageW(callback.FailedCodes[i]) << endl; + } + stdStream << "----------------" << endl; + stdStream << "WARNING: Cannot open " << numErrors << " file"; + if (numErrors > 1) + stdStream << "s"; + stdStream << endl; + exitCode = NExitCode::kWarning; + } + return exitCode; + } + else + PrintHelpAndExit(stdStream); + return 0; +} diff --git a/CPP/7zip/UI/Console/MainAr.cpp b/CPP/7zip/UI/Console/MainAr.cpp new file mode 100755 index 00000000..4bdf813a --- /dev/null +++ b/CPP/7zip/UI/Console/MainAr.cpp @@ -0,0 +1,169 @@ +// MainAr.cpp + +#include "StdAfx.h" + +// #include + +#include "Windows/Error.h" + +#include "Common/StdOutStream.h" +#include "Common/NewHandler.h" +#include "Common/Exception.h" +#include "Common/StringConvert.h" +#ifdef _WIN32 +#include "Common/Alloc.h" +#endif + +#include "../Common/ExitCode.h" +#include "../Common/ArchiveCommandLine.h" +#include "ConsoleClose.h" + +#ifdef CRC_GENERATE_TABLE +extern "C" +{ + #include "../../../../C/7zCrc.h" +} +#endif + +using namespace NWindows; + +CStdOutStream *g_StdStream = 0; + +#ifndef _UNICODE +bool g_IsNT = false; +#endif + +extern int Main2( + #ifndef _WIN32 + int numArguments, const char *arguments[] + #endif +); + +static const char *kExceptionErrorMessage = "\n\nError:\n"; +static const char *kUserBreak = "\nBreak signaled\n"; + +static const char *kMemoryExceptionMessage = "\n\nERROR: Can't allocate required memory!\n"; +static const char *kUnknownExceptionMessage = "\n\nUnknown Error\n"; +static const char *kInternalExceptionMessage = "\n\nInternal Error #"; + +static inline bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} + +int +#ifdef _MSC_VER +__cdecl +#endif +main +( +#ifndef _WIN32 +int numArguments, const char *arguments[] +#endif +) +{ + #ifdef CRC_GENERATE_TABLE + CrcGenerateTable(); + #endif + g_StdStream = &g_StdOut; + #ifdef _UNICODE + if (!IsItWindowsNT()) + { + (*g_StdStream) << "This program requires Windows NT/2000/XP/2003"; + return NExitCode::kFatalError; + } + #else + g_IsNT = IsItWindowsNT(); + #endif + + #ifdef _WIN32 + SetLargePageSize(); + #endif + + // setlocale(LC_COLLATE, ".OCP"); + NConsoleClose::CCtrlHandlerSetter ctrlHandlerSetter; + int res = 0; + try + { + res = Main2( +#ifndef _WIN32 + numArguments, arguments +#endif + ); + } + catch(const CNewException &) + { + (*g_StdStream) << kMemoryExceptionMessage; + return (NExitCode::kMemoryError); + } + catch(const NConsoleClose::CCtrlBreakException &) + { + (*g_StdStream) << endl << kUserBreak; + return (NExitCode::kUserBreak); + } + catch(const CArchiveCommandLineException &e) + { + (*g_StdStream) << kExceptionErrorMessage << e << endl; + return (NExitCode::kUserError); + } + catch(const CSystemException &systemError) + { + if (systemError.ErrorCode == E_OUTOFMEMORY) + { + (*g_StdStream) << kMemoryExceptionMessage; + return (NExitCode::kMemoryError); + } + if (systemError.ErrorCode == E_ABORT) + { + (*g_StdStream) << endl << kUserBreak; + return (NExitCode::kUserBreak); + } + UString message; + NError::MyFormatMessage(systemError.ErrorCode, message); + (*g_StdStream) << endl << endl << "System error:" << endl << + message << endl; + return (NExitCode::kFatalError); + } + catch(NExitCode::EEnum &exitCode) + { + (*g_StdStream) << kInternalExceptionMessage << exitCode << endl; + return (exitCode); + } + /* + catch(const NExitCode::CMultipleErrors &multipleErrors) + { + (*g_StdStream) << endl << multipleErrors.NumErrors << " errors" << endl; + return (NExitCode::kFatalError); + } + */ + catch(const UString &s) + { + (*g_StdStream) << kExceptionErrorMessage << s << endl; + return (NExitCode::kFatalError); + } + catch(const AString &s) + { + (*g_StdStream) << kExceptionErrorMessage << s << endl; + return (NExitCode::kFatalError); + } + catch(const char *s) + { + (*g_StdStream) << kExceptionErrorMessage << s << endl; + return (NExitCode::kFatalError); + } + catch(int t) + { + (*g_StdStream) << kInternalExceptionMessage << t << endl; + return (NExitCode::kFatalError); + } + catch(...) + { + (*g_StdStream) << kUnknownExceptionMessage; + return (NExitCode::kFatalError); + } + return res; +} diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.cpp b/CPP/7zip/UI/Console/OpenCallbackConsole.cpp new file mode 100755 index 00000000..06ff165f --- /dev/null +++ b/CPP/7zip/UI/Console/OpenCallbackConsole.cpp @@ -0,0 +1,58 @@ +// OpenCallbackConsole.cpp + +#include "StdAfx.h" + +#include "OpenCallbackConsole.h" + +#include "ConsoleClose.h" +#include "UserInputUtils.h" + +HRESULT COpenCallbackConsole::CheckBreak() +{ + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + return S_OK; +} + +HRESULT COpenCallbackConsole::SetTotal(const UInt64 *, const UInt64 *) +{ + return CheckBreak(); +} + +HRESULT COpenCallbackConsole::SetCompleted(const UInt64 *, const UInt64 *) +{ + return CheckBreak(); +} + +HRESULT COpenCallbackConsole::CryptoGetTextPassword(BSTR *password) +{ + PasswordWasAsked = true; + RINOK(CheckBreak()); + if (!PasswordIsDefined) + { + Password = GetPassword(OutStream); + PasswordIsDefined = true; + } + CMyComBSTR temp(Password); + *password = temp.Detach(); + return S_OK; +} + +HRESULT COpenCallbackConsole::GetPasswordIfAny(UString &password) +{ + if (PasswordIsDefined) + password = Password; + return S_OK; +} + +bool COpenCallbackConsole::WasPasswordAsked() +{ + return PasswordWasAsked; +} + +void COpenCallbackConsole::ClearPasswordWasAskedFlag() +{ + PasswordWasAsked = false; +} + + diff --git a/CPP/7zip/UI/Console/OpenCallbackConsole.h b/CPP/7zip/UI/Console/OpenCallbackConsole.h new file mode 100755 index 00000000..db0e9bd8 --- /dev/null +++ b/CPP/7zip/UI/Console/OpenCallbackConsole.h @@ -0,0 +1,27 @@ +// OpenCallbackConsole.h + +#ifndef __OPENCALLBACKCONSOLE_H +#define __OPENCALLBACKCONSOLE_H + +#include "Common/StdOutStream.h" +#include "../Common/ArchiveOpenCallback.h" + +class COpenCallbackConsole: public IOpenCallbackUI +{ +public: + HRESULT CheckBreak(); + HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes); + HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes); + HRESULT CryptoGetTextPassword(BSTR *password); + HRESULT GetPasswordIfAny(UString &password); + bool WasPasswordAsked(); + void ClearPasswordWasAskedFlag(); + + CStdOutStream *OutStream; + bool PasswordIsDefined; + UString Password; + bool PasswordWasAsked; + COpenCallbackConsole(): PasswordIsDefined(false), PasswordWasAsked(false) {} +}; + +#endif diff --git a/CPP/7zip/UI/Console/PercentPrinter.cpp b/CPP/7zip/UI/Console/PercentPrinter.cpp new file mode 100755 index 00000000..ec87b5d4 --- /dev/null +++ b/CPP/7zip/UI/Console/PercentPrinter.cpp @@ -0,0 +1,90 @@ +// PercentPrinter.cpp + +#include "StdAfx.h" + +#include "Common/IntToString.h" +#include "Common/String.h" + +#include "PercentPrinter.h" + +const int kPaddingSize = 2; +const int kPercentsSize = 4; +const int kMaxExtraSize = kPaddingSize + 32 + kPercentsSize; + +static void ClearPrev(char *p, int num) +{ + int i; + for (i = 0; i < num; i++) *p++ = '\b'; + for (i = 0; i < num; i++) *p++ = ' '; + for (i = 0; i < num; i++) *p++ = '\b'; + *p = '\0'; +} + +void CPercentPrinter::ClosePrint() +{ + if (m_NumExtraChars == 0) + return; + char s[kMaxExtraSize * 3 + 1]; + ClearPrev(s, m_NumExtraChars); + (*OutStream) << s; + m_NumExtraChars = 0; +} + +void CPercentPrinter::PrintString(const char *s) +{ + ClosePrint(); + (*OutStream) << s; +} + +void CPercentPrinter::PrintString(const wchar_t *s) +{ + ClosePrint(); + (*OutStream) << s; +} + +void CPercentPrinter::PrintNewLine() +{ + ClosePrint(); + (*OutStream) << "\n"; +} + +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'; + + int extraSize = kPaddingSize + MyMax(size, kPercentsSize); + if (extraSize < m_NumExtraChars) + extraSize = m_NumExtraChars; + + char fullString[kMaxExtraSize * 3]; + char *p = fullString; + int i; + if (m_NumExtraChars == 0) + { + for (i = 0; i < extraSize; i++) + *p++ = ' '; + m_NumExtraChars = extraSize; + } + + for (i = 0; i < m_NumExtraChars; i++) + *p++ = '\b'; + m_NumExtraChars = extraSize; + for (; size < m_NumExtraChars; size++) + *p++ = ' '; + strcpy(p, s); + (*OutStream) << fullString; + OutStream->Flush(); + m_PrevValue = m_CurValue; +} + +void CPercentPrinter::PrintRatio() +{ + if (m_CurValue < m_PrevValue + m_MinStepSize && + m_CurValue + m_MinStepSize > m_PrevValue && m_NumExtraChars != 0) + return; + RePrintRatio(); +} diff --git a/CPP/7zip/UI/Console/PercentPrinter.h b/CPP/7zip/UI/Console/PercentPrinter.h new file mode 100755 index 00000000..e8b40916 --- /dev/null +++ b/CPP/7zip/UI/Console/PercentPrinter.h @@ -0,0 +1,31 @@ +// PercentPrinter.h + +#ifndef __PERCENTPRINTER_H +#define __PERCENTPRINTER_H + +#include "Common/Types.h" +#include "Common/StdOutStream.h" + +class CPercentPrinter +{ + UInt64 m_MinStepSize; + UInt64 m_PrevValue; + UInt64 m_CurValue; + UInt64 m_Total; + int m_NumExtraChars; +public: + CStdOutStream *OutStream; + + CPercentPrinter(UInt64 minStepSize = 1): m_MinStepSize(minStepSize), + m_PrevValue(0), m_CurValue(0), m_Total(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); + void PrintString(const wchar_t *s); + void PrintNewLine(); + void ClosePrint(); + void RePrintRatio(); + void PrintRatio(); +}; + +#endif diff --git a/CPP/7zip/UI/Console/StdAfx.cpp b/CPP/7zip/UI/Console/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/UI/Console/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/UI/Console/StdAfx.h b/CPP/7zip/UI/Console/StdAfx.h new file mode 100755 index 00000000..8531cc9c --- /dev/null +++ b/CPP/7zip/UI/Console/StdAfx.h @@ -0,0 +1,9 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include "../../../Common/MyWindows.h" +#include "../../../Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp new file mode 100755 index 00000000..5cbc11c0 --- /dev/null +++ b/CPP/7zip/UI/Console/UpdateCallbackConsole.cpp @@ -0,0 +1,196 @@ +// UpdateCallbackConsole.cpp + +#include "StdAfx.h" + +#include "UpdateCallbackConsole.h" + +#include "Windows/Error.h" +#ifdef COMPRESS_MT +#include "Windows/Synchronization.h" +#endif + +#include "ConsoleClose.h" +#include "UserInputUtils.h" + +using namespace NWindows; + +#ifdef COMPRESS_MT +static NSynchronization::CCriticalSection g_CriticalSection; +#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection); +#else +#define MT_LOCK +#endif + +static const wchar_t *kEmptyFileAlias = L"[Content]"; + +static const char *kCreatingArchiveMessage = "Creating archive "; +static const char *kUpdatingArchiveMessage = "Updating archive "; +static const char *kScanningMessage = "Scanning"; +static const char *kNoFilesScannedMessage = "No files scanned"; +static const char *kTotalFilesAddedMessage = "Total files added to archive: "; + + +HRESULT CUpdateCallbackConsole::OpenResult(const wchar_t *name, HRESULT result) +{ + (*OutStream) << endl; + if (result != S_OK) + (*OutStream) << "Error: " << name << " is not supported archive" << endl; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::StartScanning() +{ + (*OutStream) << kScanningMessage; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::CanNotFindError(const wchar_t *name, DWORD systemError) +{ + CantFindFiles.Add(name); + CantFindCodes.Add(systemError); + // m_PercentPrinter.ClosePrint(); + if (!m_WarningsMode) + { + (*OutStream) << endl << endl; + m_PercentPrinter.PrintNewLine(); + m_WarningsMode = true; + } + m_PercentPrinter.PrintString(name); + m_PercentPrinter.PrintString(": WARNING: "); + m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError)); + m_PercentPrinter.PrintNewLine(); + return S_OK; +} + +HRESULT CUpdateCallbackConsole::FinishScanning() +{ + (*OutStream) << endl << endl; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating) +{ + if(updating) + (*OutStream) << kUpdatingArchiveMessage; + else + (*OutStream) << kCreatingArchiveMessage; + if (name != 0) + (*OutStream) << name; + else + (*OutStream) << "StdOut"; + (*OutStream) << endl << endl; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::FinishArchive() +{ + (*OutStream) << endl; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::CheckBreak() +{ + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::Finilize() +{ + MT_LOCK + if (m_NeedBeClosed) + { + if (EnablePercents) + { + m_PercentPrinter.ClosePrint(); + } + if (!StdOutMode && m_NeedNewLine) + { + m_PercentPrinter.PrintNewLine(); + m_NeedNewLine = false; + } + m_NeedBeClosed = false; + } + return S_OK; +} + +HRESULT CUpdateCallbackConsole::SetTotal(UInt64 size) +{ + MT_LOCK + if (EnablePercents) + m_PercentPrinter.SetTotal(size); + return S_OK; +} + +HRESULT CUpdateCallbackConsole::SetCompleted(const UInt64 *completeValue) +{ + MT_LOCK + if (completeValue != NULL) + { + if (EnablePercents) + { + m_PercentPrinter.SetRatio(*completeValue); + m_PercentPrinter.PrintRatio(); + m_NeedBeClosed = true; + } + } + if (NConsoleClose::TestBreakSignal()) + return E_ABORT; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isAnti) +{ + MT_LOCK + if (StdOutMode) + return S_OK; + if(isAnti) + m_PercentPrinter.PrintString("Anti item "); + else + m_PercentPrinter.PrintString("Compressing "); + if (name[0] == 0) + name = kEmptyFileAlias; + m_PercentPrinter.PrintString(name); + if (EnablePercents) + m_PercentPrinter.RePrintRatio(); + return S_OK; +} + +HRESULT CUpdateCallbackConsole::OpenFileError(const wchar_t *name, DWORD systemError) +{ + MT_LOCK + FailedCodes.Add(systemError); + FailedFiles.Add(name); + // if (systemError == ERROR_SHARING_VIOLATION) + { + m_PercentPrinter.ClosePrint(); + m_PercentPrinter.PrintNewLine(); + m_PercentPrinter.PrintString("WARNING: "); + m_PercentPrinter.PrintString(NError::MyFormatMessageW(systemError)); + return S_FALSE; + } + // return systemError; +} + +HRESULT CUpdateCallbackConsole::SetOperationResult(Int32 ) +{ + m_NeedBeClosed = true; + m_NeedNewLine = true; + return S_OK; +} + +HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +{ + if (!PasswordIsDefined) + { + if (AskPassword) + { + Password = GetPassword(OutStream); + PasswordIsDefined = true; + } + } + *passwordIsDefined = BoolToInt(PasswordIsDefined); + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} diff --git a/CPP/7zip/UI/Console/UpdateCallbackConsole.h b/CPP/7zip/UI/Console/UpdateCallbackConsole.h new file mode 100755 index 00000000..2fcb891b --- /dev/null +++ b/CPP/7zip/UI/Console/UpdateCallbackConsole.h @@ -0,0 +1,75 @@ +// UpdateCallbackConsole.h + +#ifndef __UPDATECALLBACKCONSOLE_H +#define __UPDATECALLBACKCONSOLE_H + +#include "Common/String.h" +#include "Common/StdOutStream.h" +#include "PercentPrinter.h" +#include "../Common/Update.h" + +class CUpdateCallbackConsole: public IUpdateCallbackUI2 +{ + CPercentPrinter m_PercentPrinter; + bool m_NeedBeClosed; + bool m_NeedNewLine; + + bool m_WarningsMode; + + CStdOutStream *OutStream; +public: + bool EnablePercents; + bool StdOutMode; + + bool PasswordIsDefined; + UString Password; + bool AskPassword; + + + CUpdateCallbackConsole(): + m_PercentPrinter(1 << 16), + PasswordIsDefined(false), + AskPassword(false), + StdOutMode(false), + EnablePercents(true), + m_WarningsMode(false) + {} + + ~CUpdateCallbackConsole() { Finilize(); } + void Init(CStdOutStream *outStream) + { + m_NeedBeClosed = false; + m_NeedNewLine = false; + FailedFiles.Clear(); + FailedCodes.Clear(); + OutStream = outStream; + m_PercentPrinter.OutStream = outStream; + } + + HRESULT OpenResult(const wchar_t *name, HRESULT result); + + HRESULT StartScanning(); + HRESULT CanNotFindError(const wchar_t *name, DWORD systemError); + HRESULT FinishScanning(); + + HRESULT StartArchive(const wchar_t *name, bool updating); + HRESULT FinishArchive(); + + HRESULT CheckBreak(); + HRESULT Finilize(); + HRESULT SetTotal(UInt64 size); + HRESULT SetCompleted(const UInt64 *completeValue); + + HRESULT GetStream(const wchar_t *name, bool isAnti); + HRESULT OpenFileError(const wchar_t *name, DWORD systemError); + HRESULT SetOperationResult(Int32 operationResult); + HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password); + + UStringVector FailedFiles; + CRecordVector FailedCodes; + + UStringVector CantFindFiles; + CRecordVector CantFindCodes; +}; + +#endif diff --git a/CPP/7zip/UI/Console/UserInputUtils.cpp b/CPP/7zip/UI/Console/UserInputUtils.cpp new file mode 100755 index 00000000..164af99c --- /dev/null +++ b/CPP/7zip/UI/Console/UserInputUtils.cpp @@ -0,0 +1,58 @@ +// UserInputUtils.cpp + +#include "StdAfx.h" + +#include "Common/StdInStream.h" +#include "Common/StringConvert.h" + +#include "UserInputUtils.h" + +static const char kYes = 'Y'; +static const char kNo = 'N'; +static const char kYesAll = 'A'; +static const char kNoAll = 'S'; +static const char kAutoRename = 'U'; +static const char kQuit = 'Q'; + +static const char *kFirstQuestionMessage = "?\n"; +static const char *kHelpQuestionMessage = + "(Y)es / (N)o / (A)lways / (S)kip all / A(u)to rename / (Q)uit? "; + +// return true if pressed Quite; +// in: anAll +// out: anAll, anYes; + +NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream) +{ + (*outStream) << kFirstQuestionMessage; + for(;;) + { + (*outStream) << kHelpQuestionMessage; + AString scannedString = g_StdIn.ScanStringUntilNewLine(); + scannedString.Trim(); + if(!scannedString.IsEmpty()) + switch(::MyCharUpper(scannedString[0])) + { + case kYes: + return NUserAnswerMode::kYes; + case kNo: + return NUserAnswerMode::kNo; + case kYesAll: + return NUserAnswerMode::kYesAll; + case kNoAll: + return NUserAnswerMode::kNoAll; + case kAutoRename: + return NUserAnswerMode::kAutoRename; + case kQuit: + return NUserAnswerMode::kQuit; + } + } +} + +UString GetPassword(CStdOutStream *outStream) +{ + (*outStream) << "\nEnter password:"; + outStream->Flush(); + AString oemPassword = g_StdIn.ScanStringUntilNewLine(); + return MultiByteToUnicodeString(oemPassword, CP_OEMCP); +} diff --git a/CPP/7zip/UI/Console/UserInputUtils.h b/CPP/7zip/UI/Console/UserInputUtils.h new file mode 100755 index 00000000..75c85ee6 --- /dev/null +++ b/CPP/7zip/UI/Console/UserInputUtils.h @@ -0,0 +1,24 @@ +// UserInputUtils.h + +#ifndef __USERINPUTUTILS_H +#define __USERINPUTUTILS_H + +#include "Common/StdOutStream.h" + +namespace NUserAnswerMode { + +enum EEnum +{ + kYes, + kNo, + kYesAll, + kNoAll, + kAutoRename, + kQuit, +}; +} + +NUserAnswerMode::EEnum ScanUserYesNoAllQuit(CStdOutStream *outStream); +UString GetPassword(CStdOutStream *outStream); + +#endif diff --git a/CPP/7zip/UI/Console/afxres.h b/CPP/7zip/UI/Console/afxres.h new file mode 100755 index 00000000..c2fadd4a --- /dev/null +++ b/CPP/7zip/UI/Console/afxres.h @@ -0,0 +1 @@ +#include diff --git a/CPP/7zip/UI/Console/makefile b/CPP/7zip/UI/Console/makefile new file mode 100755 index 00000000..54e83ea1 --- /dev/null +++ b/CPP/7zip/UI/Console/makefile @@ -0,0 +1,93 @@ +PROG = 7z.exe +LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib +CFLAGS = $(CFLAGS) -I ../../../ -DCOMPRESS_MT -DWIN_LONG_PATH + +CONSOLE_OBJS = \ + $O\ConsoleClose.obj \ + $O\ExtractCallbackConsole.obj \ + $O\List.obj \ + $O\Main.obj \ + $O\MainAr.obj \ + $O\OpenCallbackConsole.obj \ + $O\PercentPrinter.obj \ + $O\UpdateCallbackConsole.obj \ + $O\UserInputUtils.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CommandLineParser.obj \ + $O\IntToString.obj \ + $O\ListFileUtils.obj \ + $O\NewHandler.obj \ + $O\StdInStream.obj \ + $O\StdOutStream.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\UTFConvert.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\Error.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\MemoryLock.obj \ + $O\PropVariant.obj \ + $O\PropVariantConversions.obj \ + $O\Registry.obj \ + +7ZIP_COMMON_OBJS = \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\StreamUtils.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveCommandLine.obj \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveOpenCallback.obj \ + $O\ArchiverInfo.obj \ + $O\DefaultName.obj \ + $O\EnumDirItems.obj \ + $O\Extract.obj \ + $O\ExtractingFilePath.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + $O\SetProperties.obj \ + $O\SortUtils.obj \ + $O\TempFiles.obj \ + $O\Update.obj \ + $O\UpdateAction.obj \ + $O\UpdateCallback.obj \ + $O\UpdatePair.obj \ + $O\UpdateProduce.obj \ + $O\WorkDir.obj \ + + +OBJS = \ + $O\StdAfx.obj \ + $(CONSOLE_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(CONSOLE_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(UI_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/UI/Console/resource.rc b/CPP/7zip/UI/Console/resource.rc new file mode 100755 index 00000000..6e09bb96 --- /dev/null +++ b/CPP/7zip/UI/Console/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_APP("7-Zip Console", "7z") diff --git a/CPP/7zip/UI/Explorer/7-zip.dll.manifest b/CPP/7zip/UI/Explorer/7-zip.dll.manifest new file mode 100755 index 00000000..cba1c5df --- /dev/null +++ b/CPP/7zip/UI/Explorer/7-zip.dll.manifest @@ -0,0 +1 @@ +7-Zip Extension. diff --git a/CPP/7zip/UI/Explorer/ContextMenu.cpp b/CPP/7zip/UI/Explorer/ContextMenu.cpp new file mode 100755 index 00000000..fd40add5 --- /dev/null +++ b/CPP/7zip/UI/Explorer/ContextMenu.cpp @@ -0,0 +1,682 @@ +// ContextMenu.cpp + +#include "StdAfx.h" + +#include "ContextMenu.h" + +#include "Common/StringConvert.h" +#include "Common/MyCom.h" + +#include "Windows/Shell.h" +#include "Windows/Memory.h" +#include "Windows/COM.h" +#include "Windows/FileFind.h" +#include "Windows/FileDir.h" +#include "Windows/FileName.h" +#include "Windows/Thread.h" +#include "Windows/Window.h" + +#include "Windows/Menu.h" +#include "Windows/ResourceString.h" + +#include "../../FileManager/FormatUtils.h" +#include "../../FileManager/ProgramLocation.h" + +#include "../Common/ZipRegistry.h" +#include "../Common/ArchiveName.h" + +#ifdef LANG +#include "../../FileManager/LangUtils.h" +#endif + +#include "resource.h" +#include "ContextMenuFlags.h" + +// #include "ExtractEngine.h" +// #include "TestEngine.h" +// #include "CompressEngine.h" +#include "MyMessages.h" + +#include "../Resource/Extract/resource.h" +#include "../Common/CompressCall.h" + +using namespace NWindows; + +static LPCTSTR kFileClassIDString = TEXT("SevenZip"); + +/////////////////////////////// +// IShellExtInit + +extern LONG g_DllRefCount; + +CZipContextMenu::CZipContextMenu() { InterlockedIncrement(&g_DllRefCount); } +CZipContextMenu::~CZipContextMenu() { InterlockedDecrement(&g_DllRefCount); } + +HRESULT CZipContextMenu::GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames) +{ + fileNames.Clear(); + if(dataObject == NULL) + return E_FAIL; + FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + NCOM::CStgMedium stgMedium; + HRESULT result = dataObject->GetData(&fmte, &stgMedium); + if (result != S_OK) + return result; + stgMedium._mustBeReleased = true; + + NShell::CDrop drop(false); + NMemory::CGlobalLock globalLock(stgMedium->hGlobal); + drop.Attach((HDROP)globalLock.GetPointer()); + drop.QueryFileNames(fileNames); + + return S_OK; +} + +STDMETHODIMP CZipContextMenu::Initialize(LPCITEMIDLIST pidlFolder, + LPDATAOBJECT dataObject, HKEY /* hkeyProgID */) +{ + // OutputDebugString(TEXT("::Initialize\r\n")); + _dropMode = false; + _dropPath.Empty(); + if (pidlFolder != 0) + { + if (NShell::GetPathFromIDList(pidlFolder, _dropPath)) + { + // OutputDebugString(path); + // OutputDebugString(TEXT("\r\n")); + NFile::NName::NormalizeDirPathPrefix(_dropPath); + _dropMode = !_dropPath.IsEmpty(); + } + else + _dropPath.Empty(); + } + + /* + m_IsFolder = false; + if (pidlFolder == 0) + */ + // pidlFolder is NULL :( + return GetFileNames(dataObject, _fileNames); +} + +STDMETHODIMP CZipContextMenu::InitContextMenu(const wchar_t * /* folder */, + const wchar_t **names, UINT32 numFiles) +{ + _fileNames.Clear(); + for (UINT32 i = 0; i < numFiles; i++) + _fileNames.Add(names[i]); + _dropMode = false; + return S_OK; +} + + +///////////////////////////// +// IContextMenu + +static LPCWSTR kMainVerb = L"SevenZip"; + +/* +static LPCTSTR kOpenVerb = TEXT("SevenOpen"); +static LPCTSTR kExtractVerb = TEXT("SevenExtract"); +static LPCTSTR kExtractHereVerb = TEXT("SevenExtractHere"); +static LPCTSTR kExtractToVerb = TEXT("SevenExtractTo"); +static LPCTSTR kTestVerb = TEXT("SevenTest"); +static LPCTSTR kCompressVerb = TEXT("SevenCompress"); +static LPCTSTR kCompressToVerb = TEXT("SevenCompressTo"); +static LPCTSTR kCompressEmailVerb = TEXT("SevenCompressEmail"); +static LPCTSTR kCompressToEmailVerb = TEXT("SevenCompressToEmail"); +*/ + +struct CContextMenuCommand +{ + UINT32 flag; + CZipContextMenu::ECommandInternalID CommandInternalID; + LPCWSTR Verb; + UINT ResourceID; + UINT ResourceHelpID; + UINT32 LangID; +}; + +static CContextMenuCommand g_Commands[] = +{ + { + NContextMenuFlags::kOpen, + CZipContextMenu::kOpen, + L"Open", + IDS_CONTEXT_OPEN, + IDS_CONTEXT_OPEN_HELP, + 0x02000103 + }, + { + NContextMenuFlags::kExtract, + CZipContextMenu::kExtract, + L"Extract", + IDS_CONTEXT_EXTRACT, + IDS_CONTEXT_EXTRACT_HELP, + 0x02000105 + }, + { + NContextMenuFlags::kExtractHere, + CZipContextMenu::kExtractHere, + L"ExtractHere", + IDS_CONTEXT_EXTRACT_HERE, + IDS_CONTEXT_EXTRACT_HERE_HELP, + 0x0200010B + }, + { + NContextMenuFlags::kExtractTo, + CZipContextMenu::kExtractTo, + L"ExtractTo", + IDS_CONTEXT_EXTRACT_TO, + IDS_CONTEXT_EXTRACT_TO_HELP, + 0x0200010D + }, + { + NContextMenuFlags::kTest, + CZipContextMenu::kTest, + L"Test", + IDS_CONTEXT_TEST, + IDS_CONTEXT_TEST_HELP, + 0x02000109 + }, + { + NContextMenuFlags::kCompress, + CZipContextMenu::kCompress, + L"Compress", + IDS_CONTEXT_COMPRESS, + IDS_CONTEXT_COMPRESS_HELP, + 0x02000107, + }, + { + NContextMenuFlags::kCompressEmail, + CZipContextMenu::kCompressEmail, + L"CompressEmail", + IDS_CONTEXT_COMPRESS_EMAIL, + IDS_CONTEXT_COMPRESS_EMAIL_HELP, + 0x02000111 + }, + { + NContextMenuFlags::kCompressTo7z, + CZipContextMenu::kCompressTo7z, + L"CompressTo7z", + IDS_CONTEXT_COMPRESS_TO, + IDS_CONTEXT_COMPRESS_TO_HELP, + 0x0200010F + }, + { + NContextMenuFlags::kCompressTo7zEmail, + CZipContextMenu::kCompressTo7zEmail, + L"CompressTo7zEmail", + IDS_CONTEXT_COMPRESS_TO_EMAIL, + IDS_CONTEXT_COMPRESS_TO_EMAIL_HELP, + 0x02000113 + }, + { + NContextMenuFlags::kCompressToZip, + CZipContextMenu::kCompressToZip, + L"CompressToZip", + IDS_CONTEXT_COMPRESS_TO, + IDS_CONTEXT_COMPRESS_TO_HELP, + 0x0200010F + }, + { + NContextMenuFlags::kCompressToZipEmail, + CZipContextMenu::kCompressToZipEmail, + L"CompressToZipEmail", + IDS_CONTEXT_COMPRESS_TO_EMAIL, + IDS_CONTEXT_COMPRESS_TO_EMAIL_HELP, + 0x02000113 + } +}; + +int FindCommand(CZipContextMenu::ECommandInternalID &id) +{ + for (int i = 0; i < sizeof(g_Commands) / sizeof(g_Commands[0]); i++) + if (g_Commands[i].CommandInternalID == id) + return i; + return -1; +} + +void CZipContextMenu::FillCommand(ECommandInternalID id, + UString &mainString, CCommandMapItem &commandMapItem) +{ + int i = FindCommand(id); + if (i < 0) + return; + const CContextMenuCommand &command = g_Commands[i]; + commandMapItem.CommandInternalID = command.CommandInternalID; + commandMapItem.Verb = (UString)kMainVerb + (UString)command.Verb; + commandMapItem.HelpString = LangString(command.ResourceHelpID, command.LangID + 1); + mainString = LangString(command.ResourceID, command.LangID); +} + +static bool MyInsertMenu(CMenu &menu, int pos, UINT id, const UString &s) +{ + CMenuItem menuItem; + menuItem.fType = MFT_STRING; + menuItem.fMask = MIIM_TYPE | MIIM_ID; + menuItem.wID = id; + menuItem.StringValue = s; + return menu.InsertItem(pos, true, menuItem); +} + +static UString GetSubFolderNameForExtract(const UString &archiveName) +{ + int dotPos = archiveName.ReverseFind(L'.'); + if (dotPos < 0) + return archiveName + UString(L"~"); + UString res = archiveName.Left(dotPos); + res.TrimRight(); + return res; +} + +static UString GetReducedString(const UString &s) +{ + const int kMaxSize = 64; + if (s.Length() < kMaxSize) + return s; + const int kFirstPartSize = kMaxSize / 2; + return s.Left(kFirstPartSize) + UString(L" ... ") + s.Right(kMaxSize - kFirstPartSize); +} + +STDMETHODIMP CZipContextMenu::QueryContextMenu(HMENU hMenu, UINT indexMenu, + UINT commandIDFirst, UINT commandIDLast, UINT flags) +{ + LoadLangOneTime(); + if(_fileNames.Size() == 0) + return E_FAIL; + UINT currentCommandID = commandIDFirst; + if ((flags & 0x000F) != CMF_NORMAL && + (flags & CMF_VERBSONLY) == 0 && + (flags & CMF_EXPLORE) == 0) + return MAKE_HRESULT(SEVERITY_SUCCESS, 0, currentCommandID); + + _commandMap.Clear(); + + CMenu popupMenu; + CMenuDestroyer menuDestroyer; + + bool cascadedMenu = ReadCascadedMenu(); + MENUITEMINFO menuItem; + UINT subIndex = indexMenu; + if (cascadedMenu) + { + CCommandMapItem commandMapItem; + if(!popupMenu.CreatePopup()) + throw 210503; + menuDestroyer.Attach(popupMenu); + commandMapItem.CommandInternalID = kCommandNULL; + commandMapItem.Verb = kMainVerb; + commandMapItem.HelpString = LangString(IDS_CONTEXT_CAPTION_HELP, 0x02000102); + _commandMap.Add(commandMapItem); + + menuItem.wID = currentCommandID++; + subIndex = 0; + } + else + { + popupMenu.Attach(hMenu); + } + + UINT32 contextMenuFlags; + if (!ReadContextMenuStatus(contextMenuFlags)) + contextMenuFlags = NContextMenuFlags::GetDefaultFlags(); + + UString mainString; + if(_fileNames.Size() == 1 && currentCommandID + 6 <= commandIDLast) + { + const UString &fileName = _fileNames.Front(); + UString folderPrefix; + NFile::NDirectory::GetOnlyDirPrefix(fileName, folderPrefix); + + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(fileName, fileInfo)) + return E_FAIL; + if (!fileInfo.IsDirectory()) + { + // Open + if ((contextMenuFlags & NContextMenuFlags::kOpen) != 0) + { + CCommandMapItem commandMapItem; + FillCommand(kOpen, mainString, commandMapItem); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString); + _commandMap.Add(commandMapItem); + } + } + } + + if(_fileNames.Size() > 0 && currentCommandID + 10 <= commandIDLast) + { + bool thereAreFolders = false; + for(int i = 0; i < _fileNames.Size(); i++) + { + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(_fileNames[i], fileInfo)) + return E_FAIL; + if (fileInfo.IsDirectory()) + thereAreFolders = true; + } + const UString &fileName = _fileNames.Front(); + if (!thereAreFolders) + { + UString folderPrefix; + NFile::NDirectory::GetOnlyDirPrefix(fileName, folderPrefix); + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(fileName, fileInfo)) + return E_FAIL; + // Extract + if ((contextMenuFlags & NContextMenuFlags::kExtract) != 0) + { + CCommandMapItem commandMapItem; + FillCommand(kExtract, mainString, commandMapItem); + if (_dropMode) + commandMapItem.Folder = _dropPath; + else + commandMapItem.Folder = folderPrefix; + commandMapItem.Folder += GetSubFolderNameForExtract(fileInfo.Name) + UString(L'\\'); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString); + _commandMap.Add(commandMapItem); + } + + // Extract Here + if ((contextMenuFlags & NContextMenuFlags::kExtractHere) != 0) + { + CCommandMapItem commandMapItem; + FillCommand(kExtractHere, mainString, commandMapItem); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString); + if (_dropMode) + commandMapItem.Folder = _dropPath; + else + commandMapItem.Folder = folderPrefix; + _commandMap.Add(commandMapItem); + } + + // Extract To + if ((contextMenuFlags & NContextMenuFlags::kExtractTo) != 0) + { + CCommandMapItem commandMapItem; + UString s; + FillCommand(kExtractTo, s, commandMapItem); + UString folder; + if (_fileNames.Size() == 1) + folder = GetSubFolderNameForExtract(fileInfo.Name); + else + folder = L'*'; + if (_dropMode) + commandMapItem.Folder = _dropPath; + else + commandMapItem.Folder = folderPrefix; + commandMapItem.Folder += folder; + s = MyFormatNew(s, GetReducedString(UString(L"\"") + folder + UString(L"\\\""))); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s); + _commandMap.Add(commandMapItem); + } + // Test + if ((contextMenuFlags & NContextMenuFlags::kTest) != 0) + { + CCommandMapItem commandMapItem; + FillCommand(kTest, mainString, commandMapItem); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString); + _commandMap.Add(commandMapItem); + } + } + 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); + + // Compress + if ((contextMenuFlags & NContextMenuFlags::kCompress) != 0) + { + CCommandMapItem commandMapItem; + if (_dropMode) + commandMapItem.Folder = _dropPath; + else + commandMapItem.Folder = archivePathPrefix; + commandMapItem.Archive = archiveName; + FillCommand(kCompress, mainString, commandMapItem); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString); + _commandMap.Add(commandMapItem); + } + + + // CompressEmail + if ((contextMenuFlags & NContextMenuFlags::kCompressEmail) != 0 && !_dropMode) + { + CCommandMapItem commandMapItem; + commandMapItem.Archive = archiveName; + FillCommand(kCompressEmail, mainString, commandMapItem); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, mainString); + _commandMap.Add(commandMapItem); + } + + // CompressTo7z + if (contextMenuFlags & NContextMenuFlags::kCompressTo7z) + { + CCommandMapItem commandMapItem; + UString s; + FillCommand(kCompressTo7z, s, commandMapItem); + if (_dropMode) + commandMapItem.Folder = _dropPath; + else + commandMapItem.Folder = archivePathPrefix; + commandMapItem.Archive = archiveName7z; + commandMapItem.ArchiveType = L"7z"; + UString t = UString(L"\"") + GetReducedString(archiveName7z) + UString(L"\""); + s = MyFormatNew(s, t); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s); + _commandMap.Add(commandMapItem); + } + + // CompressTo7zEmail + if ((contextMenuFlags & NContextMenuFlags::kCompressTo7zEmail) != 0 && !_dropMode) + { + CCommandMapItem commandMapItem; + UString s; + FillCommand(kCompressTo7zEmail, s, commandMapItem); + commandMapItem.Archive = archiveName7z; + commandMapItem.ArchiveType = L"7z"; + UString t = UString(L"\"") + GetReducedString(archiveName7z) + UString(L"\""); + s = MyFormatNew(s, t); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s); + _commandMap.Add(commandMapItem); + } + + // CompressToZip + if (contextMenuFlags & NContextMenuFlags::kCompressToZip) + { + CCommandMapItem commandMapItem; + UString s; + FillCommand(kCompressToZip, s, commandMapItem); + if (_dropMode) + commandMapItem.Folder = _dropPath; + else + commandMapItem.Folder = archivePathPrefix; + commandMapItem.Archive = archiveNameZip; + commandMapItem.ArchiveType = L"zip"; + UString t = UString(L"\"") + GetReducedString(archiveNameZip) + UString(L"\""); + s = MyFormatNew(s, t); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s); + _commandMap.Add(commandMapItem); + } + + // CompressToZipEmail + if ((contextMenuFlags & NContextMenuFlags::kCompressToZipEmail) != 0 && !_dropMode) + { + CCommandMapItem commandMapItem; + UString s; + FillCommand(kCompressToZipEmail, s, commandMapItem); + commandMapItem.Archive = archiveNameZip; + commandMapItem.ArchiveType = L"zip"; + UString t = UString(L"\"") + GetReducedString(archiveNameZip) + UString(L"\""); + s = MyFormatNew(s, t); + MyInsertMenu(popupMenu, subIndex++, currentCommandID++, s); + _commandMap.Add(commandMapItem); + } + } + + + // don't use InsertMenu: See MSDN: + // PRB: Duplicate Menu Items In the File Menu For a Shell Context Menu Extension + // ID: Q214477 + + if (cascadedMenu) + { + CMenuItem menuItem; + menuItem.fType = MFT_STRING; + menuItem.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID; + menuItem.wID = currentCommandID++; + menuItem.hSubMenu = popupMenu.Detach(); + menuDestroyer.Disable(); + menuItem.StringValue = LangString(IDS_CONTEXT_POPUP_CAPTION, 0x02000101); + CMenu menu; + menu.Attach(hMenu); + menu.InsertItem(indexMenu++, true, menuItem); + } + + return MAKE_HRESULT(SEVERITY_SUCCESS, 0, currentCommandID - commandIDFirst); +} + + +int CZipContextMenu::FindVerb(const UString &verb) +{ + for(int i = 0; i < _commandMap.Size(); i++) + if(_commandMap[i].Verb.Compare(verb) == 0) + return i; + return -1; +} + +extern const char *kShellFolderClassIDString; + + +static UString GetProgramCommand() +{ + UString path = L"\""; + UString folder; + if (GetProgramFolderPath(folder)) + path += folder; + path += L"7zFM.exe\""; + return path; +} + +STDMETHODIMP CZipContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO commandInfo) +{ + // ::OutputDebugStringA("1"); + int commandOffset; + + // It's fix for bug: crashing in XP. See example in MSDN: "Creating Context Menu Handlers". + + if (commandInfo->cbSize == sizeof(CMINVOKECOMMANDINFOEX) && + (commandInfo->fMask & CMIC_MASK_UNICODE) != 0) + { + LPCMINVOKECOMMANDINFOEX commandInfoEx = (LPCMINVOKECOMMANDINFOEX)commandInfo; + if(HIWORD(commandInfoEx->lpVerbW) == 0) + commandOffset = LOWORD(commandInfo->lpVerb); + else + commandOffset = FindVerb(commandInfoEx->lpVerbW); + } + else + if(HIWORD(commandInfo->lpVerb) == 0) + commandOffset = LOWORD(commandInfo->lpVerb); + else + commandOffset = FindVerb(GetUnicodeString(commandInfo->lpVerb)); + + if(commandOffset < 0 || commandOffset >= _commandMap.Size()) + return E_FAIL; + + const CCommandMapItem commandMapItem = _commandMap[commandOffset]; + ECommandInternalID commandInternalID = commandMapItem.CommandInternalID; + + try + { + switch(commandInternalID) + { + case kOpen: + { + UString params; + params = GetProgramCommand(); + params += L" \""; + params += _fileNames[0]; + params += L"\""; + MyCreateProcess(params, 0, false, 0); + break; + } + case kExtract: + case kExtractHere: + case kExtractTo: + { + ExtractArchives(_fileNames, commandMapItem.Folder, + (commandInternalID == kExtract)); + break; + } + case kTest: + { + TestArchives(_fileNames); + break; + } + case kCompress: + case kCompressEmail: + case kCompressTo7z: + case kCompressTo7zEmail: + case kCompressToZip: + case kCompressToZipEmail: + { + bool email = + (commandInternalID == kCompressEmail) || + (commandInternalID == kCompressTo7zEmail) || + (commandInternalID == kCompressToZipEmail); + bool showDialog = + (commandInternalID == kCompress) || + (commandInternalID == kCompressEmail); + CompressFiles(commandMapItem.Folder, + commandMapItem.Archive, commandMapItem.ArchiveType, + _fileNames, email, showDialog, false); + break; + } + } + } + catch(...) + { + MyMessageBox(IDS_ERROR, 0x02000605); + } + return S_OK; +} + +static void MyCopyString(void *dest, const wchar_t *src, bool writeInUnicode) +{ + if(writeInUnicode) + { + MyStringCopy((wchar_t *)dest, src); + } + else + lstrcpyA((char *)dest, GetAnsiString(src)); +} + +STDMETHODIMP CZipContextMenu::GetCommandString(UINT_PTR commandOffset, UINT uType, + UINT * /* pwReserved */ , LPSTR pszName, UINT /* cchMax */) +{ + int cmdOffset = (int)commandOffset; + switch(uType) + { + case GCS_VALIDATEA: + case GCS_VALIDATEW: + if(cmdOffset < 0 || cmdOffset >= _commandMap.Size()) + return S_FALSE; + else + return S_OK; + } + if(cmdOffset < 0 || cmdOffset >= _commandMap.Size()) + return E_FAIL; + if(uType == GCS_HELPTEXTA || uType == GCS_HELPTEXTW) + { + MyCopyString(pszName, _commandMap[cmdOffset].HelpString, uType == GCS_HELPTEXTW); + return NO_ERROR; + } + if(uType == GCS_VERBA || uType == GCS_VERBW) + { + MyCopyString(pszName, _commandMap[cmdOffset].Verb, uType == GCS_VERBW); + return NO_ERROR; + } + return E_FAIL; +} diff --git a/CPP/7zip/UI/Explorer/ContextMenu.h b/CPP/7zip/UI/Explorer/ContextMenu.h new file mode 100755 index 00000000..60970a22 --- /dev/null +++ b/CPP/7zip/UI/Explorer/ContextMenu.h @@ -0,0 +1,86 @@ +// ContextMenu.h + +#ifndef __CONTEXTMENU_H +#define __CONTEXTMENU_H + +// {23170F69-40C1-278A-1000-000100020000} +DEFINE_GUID(CLSID_CZipContextMenu, +0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00); + +#include "Common/String.h" + +#include "../../FileManager/PluginInterface.h" +#include "../../FileManager/MyCom2.h" + + +class CZipContextMenu: + public IContextMenu, + public IShellExtInit, + public IInitContextMenu, + public CMyUnknownImp +{ + +public: + + enum ECommandInternalID + { + kCommandNULL, + kOpen, + kExtract, + kExtractHere, + kExtractTo, + kTest, + kCompress, + kCompressEmail, + kCompressTo7z, + kCompressTo7zEmail, + kCompressToZip, + kCompressToZipEmail + }; + + struct CCommandMapItem + { + ECommandInternalID CommandInternalID; + UString Verb; + UString HelpString; + UString Folder; + UString Archive; + UString ArchiveType; + }; + + MY_UNKNOWN_IMP3_MT(IContextMenu, IShellExtInit, IInitContextMenu) + + /////////////////////////////// + // IShellExtInit + + STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder, + LPDATAOBJECT dataObject, HKEY hkeyProgID); + + ///////////////////////////// + // IContextMenu + + STDMETHOD(QueryContextMenu)(HMENU hmenu, UINT indexMenu, + UINT idCmdFirst, UINT idCmdLast, UINT uFlags); + STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO lpici); + STDMETHOD(GetCommandString)(UINT_PTR idCmd, UINT uType, UINT *pwReserved, + LPSTR pszName, UINT cchMax); + + + // IInitContextMenu + STDMETHOD(InitContextMenu)(const wchar_t *folder, const wchar_t **names, UINT32 numFiles); +private: + UStringVector _fileNames; + bool _dropMode; + UString _dropPath; + CObjectVector _commandMap; + HRESULT GetFileNames(LPDATAOBJECT dataObject, UStringVector &fileNames); + int FindVerb(const UString &verb); + + void FillCommand(ECommandInternalID id, UString &mainString, + CCommandMapItem &commandMapItem); +public: + CZipContextMenu(); + ~CZipContextMenu(); +}; + +#endif diff --git a/CPP/7zip/UI/Explorer/ContextMenuFlags.h b/CPP/7zip/UI/Explorer/ContextMenuFlags.h new file mode 100755 index 00000000..d138baf9 --- /dev/null +++ b/CPP/7zip/UI/Explorer/ContextMenuFlags.h @@ -0,0 +1,34 @@ +// ContextMenuFlags.h + +#ifndef __SEVENZIP_CONTEXTMENUFLAGS_H +#define __SEVENZIP_CONTEXTMENUFLAGS_H + +namespace NContextMenuFlags +{ + const UINT32 kExtract = 1 << 0; + const UINT32 kExtractHere = 1 << 1; + const UINT32 kExtractTo = 1 << 2; + // const UINT32 kExtractEach = 1 << 3; + + const UINT32 kTest = 1 << 4; + + const UINT32 kOpen = 1 << 5; + + const UINT32 kCompress = 1 << 8; + const UINT32 kCompressTo7z = 1 << 9; + const UINT32 kCompressEmail = 1 << 10; + const UINT32 kCompressTo7zEmail = 1 << 11; + + const UINT32 kCompressToZip = 1 << 12; + const UINT32 kCompressToZipEmail = 1 << 13; + + inline UINT32 GetDefaultFlags() { + return + kOpen | kTest | + kExtract | kExtractHere | kExtractTo | + kCompress | kCompressEmail | + kCompressTo7z | kCompressTo7zEmail | + kCompressToZip | kCompressToZipEmail; } +} + +#endif diff --git a/CPP/7zip/UI/Explorer/DllExports.cpp b/CPP/7zip/UI/Explorer/DllExports.cpp new file mode 100755 index 00000000..fb7daf04 --- /dev/null +++ b/CPP/7zip/UI/Explorer/DllExports.cpp @@ -0,0 +1,315 @@ +// DLLExports.cpp +// +// Notes: +// Win2000: +// If I register at HKCR\Folder\ShellEx then DLL is locked. +// otherwise it unloads after explorer closing. +// but if I call menu for desktop items it's locked all the time + +#include "StdAfx.h" + +// #include + +#include +#include +#include +#include + +#include "Common/ComTry.h" +#include "Common/StringConvert.h" +#include "Windows/DLL.h" +#include "Windows/Registry.h" + +#include "../../IPassword.h" +#include "../../FileManager/LangUtils.h" +#include "../Agent/Agent.h" + +#include "ContextMenu.h" +#include "OptionsDialog.h" + +using namespace NWindows; + +HINSTANCE g_hInstance; +#ifndef _UNICODE +bool g_IsNT = false; +#endif + +LONG g_DllRefCount = 0; // Reference count of this DLL. + +static LPCWSTR kShellExtName = L"7-Zip Shell Extension"; +static LPCTSTR kClsidMask = TEXT("CLSID\\%s"); +static LPCTSTR kClsidInprocMask = TEXT("CLSID\\%s\\InprocServer32"); +static LPCTSTR kApprovedKeyPath = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"); + +// #define ODS(sz) OutputDebugString(L#sz) + +class CShellExtClassFactory: + public IClassFactory, + public CMyUnknownImp +{ +public: + CShellExtClassFactory() { InterlockedIncrement(&g_DllRefCount); } + ~CShellExtClassFactory() { InterlockedDecrement(&g_DllRefCount); } + + + MY_UNKNOWN_IMP1_MT(IClassFactory) + + STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, void**); + STDMETHODIMP LockServer(BOOL); +}; + +STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, + REFIID riid, void **ppvObj) +{ + // ODS("CShellExtClassFactory::CreateInstance()\r\n"); + *ppvObj = NULL; + if (pUnkOuter) + return CLASS_E_NOAGGREGATION; + + CZipContextMenu *shellExt; + try + { + shellExt = new CZipContextMenu(); + } + catch(...) { return E_OUTOFMEMORY; } + if (shellExt == NULL) + return E_OUTOFMEMORY; + + HRESULT res = shellExt->QueryInterface(riid, ppvObj); + if (res != S_OK) + delete shellExt; + return res; +} + + +STDMETHODIMP CShellExtClassFactory::LockServer(BOOL /* fLock */) +{ + return S_OK; // Check it +} + +static bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} + +extern "C" +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID) +{ + // setlocale(LC_COLLATE, ".ACP"); + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hInstance = hInstance; + // ODS("In DLLMain, DLL_PROCESS_ATTACH\r\n"); + #ifdef _UNICODE + if (!IsItWindowsNT()) + return FALSE; + #else + g_IsNT = IsItWindowsNT(); + #endif + } + else if (dwReason == DLL_PROCESS_DETACH) + { + // ODS("In DLLMain, DLL_PROCESS_DETACH\r\n"); + } + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// Used to determine whether the DLL can be unloaded by OLE + +STDAPI DllCanUnloadNow(void) +{ + // ODS("In DLLCanUnloadNow\r\n"); + return (g_DllRefCount == 0 ? S_OK : S_FALSE); +} + +STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) +{ + // ODS("In DllGetClassObject\r\n"); + *ppv = NULL; + if (IsEqualIID(rclsid, CLSID_CZipContextMenu)) + { + CShellExtClassFactory *cf; + try + { + cf = new CShellExtClassFactory; + } + catch(...) { return E_OUTOFMEMORY; } + if (cf == 0) + return E_OUTOFMEMORY; + HRESULT res = cf->QueryInterface(riid, ppv); + if (res != S_OK) + delete cf; + return res; + } + return CLASS_E_CLASSNOTAVAILABLE; + // return _Module.GetClassObject(rclsid, riid, ppv); +} + +static BOOL GetStringFromIID(CLSID clsid, LPTSTR s, int size) +{ + LPWSTR pwsz; + if (StringFromIID(clsid, &pwsz) != S_OK) + return FALSE; + if(!pwsz) + return FALSE; + #ifdef UNICODE + lstrcpyn(s, pwsz, size); + #else + WideCharToMultiByte(CP_ACP, 0, pwsz, -1, s, size, NULL, NULL); + #endif + CoTaskMemFree(pwsz); + s[size - 1] = 0; + return TRUE; +} + +typedef struct +{ + HKEY hRootKey; + LPCTSTR SubKey; + LPCWSTR ValueName; + LPCWSTR Data; +} CRegItem; + +static BOOL RegisterServer(CLSID clsid, LPCWSTR title) +{ + TCHAR clsidString[MAX_PATH]; + if (!GetStringFromIID(clsid, clsidString, MAX_PATH)) + return FALSE; + + UString modulePath; + if (!NDLL::MyGetModuleFileName(g_hInstance, modulePath)) + return FALSE; + + CRegItem clsidEntries[] = + { + HKEY_CLASSES_ROOT, kClsidMask, NULL, title, + HKEY_CLASSES_ROOT, kClsidInprocMask, NULL, modulePath, + HKEY_CLASSES_ROOT, kClsidInprocMask, L"ThreadingModel", L"Apartment", + NULL, NULL, NULL, NULL + }; + + //register the CLSID entries + for(int i = 0; clsidEntries[i].hRootKey; i++) + { + TCHAR subKey[MAX_PATH]; + wsprintf(subKey, clsidEntries[i].SubKey, clsidString); + NRegistry::CKey key; + if (key.Create(clsidEntries[i].hRootKey, subKey, NULL, + REG_OPTION_NON_VOLATILE, KEY_WRITE) != NOERROR) + return FALSE; + key.SetValue(clsidEntries[i].ValueName, clsidEntries[i].Data); + } + + if(IsItWindowsNT()) + { + NRegistry::CKey key; + if (key.Create(HKEY_LOCAL_MACHINE, kApprovedKeyPath, NULL, + REG_OPTION_NON_VOLATILE, KEY_WRITE) == NOERROR) + key.SetValue(GetUnicodeString(clsidString), title); + } + return TRUE; +} + +STDAPI DllRegisterServer(void) +{ + return RegisterServer(CLSID_CZipContextMenu, kShellExtName) ? S_OK: SELFREG_E_CLASS; +} + +static BOOL UnregisterServer(CLSID clsid) +{ + TCHAR clsidString[MAX_PATH]; + if (!GetStringFromIID(clsid, clsidString, MAX_PATH)) + return FALSE; + + TCHAR subKey[MAX_PATH]; + wsprintf(subKey, kClsidInprocMask, clsidString); + RegDeleteKey(HKEY_CLASSES_ROOT, subKey); + + wsprintf (subKey, kClsidMask, clsidString); + RegDeleteKey(HKEY_CLASSES_ROOT, subKey); + + if(IsItWindowsNT()) + { + HKEY hKey; + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, kApprovedKeyPath, 0, KEY_SET_VALUE, &hKey) == NOERROR) + { + RegDeleteValue(hKey, clsidString); + RegCloseKey(hKey); + } + } + return TRUE; +} + +STDAPI DllUnregisterServer(void) +{ + return UnregisterServer(CLSID_CZipContextMenu) ? S_OK: SELFREG_E_CLASS; +} + +STDAPI CreateObject( + const GUID *classID, + const GUID *interfaceID, + void **outObject) +{ + LoadLangOneTime(); + COM_TRY_BEGIN + *outObject = 0; + if (*classID == CLSID_CAgentArchiveHandler) + { + if (*interfaceID == IID_IFolderManager) + { + CMyComPtr manager = new CArchiveFolderManager; + *outObject = manager.Detach(); + return S_OK; + } + return E_NOINTERFACE; + } + if (*classID == CLSID_CSevenZipOptions) + { + if (*interfaceID == IID_IPluginOptions) + { + CMyComPtr options = new CSevenZipOptions; + *outObject = options.Detach(); + return S_OK; + } + return E_NOINTERFACE; + } + return CLASS_E_CLASSNOTAVAILABLE; + COM_TRY_END +} + +STDAPI GetPluginProperty(PROPID propID, PROPVARIANT *value) +{ + ::VariantClear((tagVARIANT *)value); + switch(propID) + { + case NPlugin::kName: + if ((value->bstrVal = ::SysAllocString(L"7-Zip")) != 0) + value->vt = VT_BSTR; + return S_OK; + case NPlugin::kClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CAgentArchiveHandler, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + case NPlugin::kOptionsClassID: + { + if ((value->bstrVal = ::SysAllocStringByteLen( + (const char *)&CLSID_CSevenZipOptions, sizeof(GUID))) != 0) + value->vt = VT_BSTR; + return S_OK; + } + /* + case NArchive::kType: + propVariant = UINT32(0); + break; + */ + } + return S_OK; +} diff --git a/CPP/7zip/UI/Explorer/Explorer.def b/CPP/7zip/UI/Explorer/Explorer.def new file mode 100755 index 00000000..752fbb7a --- /dev/null +++ b/CPP/7zip/UI/Explorer/Explorer.def @@ -0,0 +1,12 @@ +; 7-zip.def + +LIBRARY "7-zip" + +EXPORTS + DllCanUnloadNow PRIVATE + DllGetClassObject PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE + + CreateObject PRIVATE + GetPluginProperty PRIVATE diff --git a/CPP/7zip/UI/Explorer/Explorer.dsp b/CPP/7zip/UI/Explorer/Explorer.dsp new file mode 100755 index 00000000..c395c6d2 --- /dev/null +++ b/CPP/7zip/UI/Explorer/Explorer.dsp @@ -0,0 +1,818 @@ +# Microsoft Developer Studio Project File - Name="Explorer" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Explorer - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Explorer.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Explorer.mak" CFG="Explorer - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Explorer - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Explorer - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Explorer - Win32 ReleaseU" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Explorer - Win32 DebugU" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Explorer - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "NEW_FOLDER_INTERFACE" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Explorer - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "NEW_FOLDER_INTERFACE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "Explorer - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseU" +# PROP BASE Intermediate_Dir "ReleaseU" +# PROP BASE Ignore_Export_Lib 1 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "_MBCS" /Yu"StdAfx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "NEW_FOLDER_INTERFACE" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /opt:NOWIN98 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zipn.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Explorer - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Ignore_Export_Lib 1 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "_MBCS" /Yu"StdAfx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "EXPLORER_EXPORTS" /D "LANG" /D "NEW_FOLDER_INTERFACE" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\7-ZIP\7-Zip.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Explorer - Win32 Release" +# Name "Explorer - Win32 Debug" +# Name "Explorer - Win32 ReleaseU" +# Name "Explorer - Win32 DebugU" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\DllExports.cpp +# End Source File +# Begin Source File + +SOURCE=.\Explorer.def +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiverInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiverInfo.h +# End Source File +# Begin Source File + +SOURCE=..\Common\CompressCall.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\CompressCall.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\HandlerLoader.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +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.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ContextMenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\ContextMenu.h +# End Source File +# Begin Source File + +SOURCE=.\MyMessages.cpp +# End Source File +# Begin Source File + +SOURCE=.\MyMessages.h +# End Source File +# End Group +# Begin Group "Dialogs" + +# PROP Default_Filter "" +# Begin Group "Options" + +# PROP Default_Filter "" +# Begin Group "SystemPage" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\SystemPage\SystemPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\SystemPage\SystemPage.h +# End Source File +# End Group +# Begin Group "FoldersPage" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\FoldersPage\FoldersPage.cpp +# End Source File +# Begin Source File + +SOURCE=.\FoldersPage\FoldersPage.h +# End Source File +# End Group +# End Group +# End Group +# Begin Group "Agent" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Agent\Agent.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\Agent.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentProxy.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentProxy.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\ArchiveFolder.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\ArchiveFolderOpen.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\ArchiveFolderOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\IFileExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\IFolderArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\UpdateCallbackAgent.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\UpdateCallbackAgent.h +# End Source File +# End Group +# Begin Group "FileManager" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\FileManager\FormatUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\FormatUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\HelpUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\HelpUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\IFolder.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\LangUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\LangUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\ProgramLocation.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\ProgramLocation.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\RegistryUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\RegistryUtils.h +# End Source File +# End Group +# Begin Group "SDK" + +# PROP Default_Filter "" +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\MyCom.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Random.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\TextConfig.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\TextConfig.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Types.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Group "Control" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\PropertyPage.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\PropertyPage.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileMapping.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Memory.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Memory.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Menu.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Menu.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\PropVariantConversions.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.h +# End Source File +# End Group +# End Group +# Begin Group "7-zip common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "C" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.c +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=..\..\..\..\C\Sort.h +# End Source File +# End Group +# Begin Source File + +SOURCE=".\7-zip.dll.manifest" +# End Source File +# Begin Source File + +SOURCE=.\ContextMenuFlags.h +# End Source File +# Begin Source File + +SOURCE=.\OptionsDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\OptionsDialog.h +# End Source File +# Begin Source File + +SOURCE=.\RegistryContextMenu.cpp +# End Source File +# Begin Source File + +SOURCE=.\RegistryContextMenu.h +# End Source File +# End Target +# End Project diff --git a/CPP/7zip/UI/Explorer/Explorer.dsw b/CPP/7zip/UI/Explorer/Explorer.dsw new file mode 100755 index 00000000..beb8df7b --- /dev/null +++ b/CPP/7zip/UI/Explorer/Explorer.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Explorer"=".\Explorer.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.cpp b/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.cpp new file mode 100755 index 00000000..776813d8 --- /dev/null +++ b/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.cpp @@ -0,0 +1,157 @@ +// FoldersPage.cpp + +#include "StdAfx.h" + +#include "resource.h" +#include "FoldersPage.h" + +#include "Common/StringConvert.h" +#include "Windows/Defs.h" +#include "Windows/Shell.h" +#include "Windows/ResourceString.h" + +#include "../../../FileManager/HelpUtils.h" +#include "../../Common/ZipRegistry.h" + +#include "../../../FileManager/LangUtils.h" + +using namespace NWindows; + +static CIDLangPair kIDLangPairs[] = +{ + { IDC_FOLDERS_STATIC_WORKING_FOLDER, 0x01000210 }, + { IDC_FOLDERS_WORK_RADIO_SYSTEM, 0x01000211 }, + { IDC_FOLDERS_WORK_RADIO_CURRENT, 0x01000212 }, + { IDC_FOLDERS_WORK_RADIO_SPECIFIED, 0x01000213 }, + { IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE, 0x01000214 } +}; + +static const int kWorkModeButtons[] = +{ + IDC_FOLDERS_WORK_RADIO_SYSTEM, + IDC_FOLDERS_WORK_RADIO_CURRENT, + IDC_FOLDERS_WORK_RADIO_SPECIFIED +}; + +static const int kNumWorkModeButtons = sizeof(kWorkModeButtons) / sizeof(kWorkModeButtons[0]); + +bool CFoldersPage::OnInit() +{ + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + ReadWorkDirInfo(m_WorkDirInfo); + + CheckButton(IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE, m_WorkDirInfo.ForRemovableOnly); + + CheckRadioButton(kWorkModeButtons[0], kWorkModeButtons[kNumWorkModeButtons - 1], + kWorkModeButtons[m_WorkDirInfo.Mode]); + + m_WorkPath.Init(*this, IDC_FOLDERS_WORK_EDIT_PATH); + m_ButtonSetWorkPath.Init(*this, IDC_FOLDERS_WORK_BUTTON_PATH); + + m_WorkPath.SetText(m_WorkDirInfo.Path); + + MyEnableControls(); + + return CPropertyPage::OnInit(); +} + +int CFoldersPage::GetWorkMode() const +{ + for (int i = 0; i < kNumWorkModeButtons; i++) + if(IsButtonCheckedBool(kWorkModeButtons[i])) + return i; + throw 0; +} + +void CFoldersPage::MyEnableControls() +{ + bool enablePath = (GetWorkMode() == NWorkDir::NMode::kSpecified); + m_WorkPath.Enable(enablePath); + m_ButtonSetWorkPath.Enable(enablePath); +} + +void CFoldersPage::GetWorkDir(NWorkDir::CInfo &workDirInfo) +{ + m_WorkPath.GetText(workDirInfo.Path); + workDirInfo.ForRemovableOnly = IsButtonCheckedBool(IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE); + workDirInfo.Mode = NWorkDir::NMode::EEnum(GetWorkMode()); +} + +/* +bool CFoldersPage::WasChanged() +{ + NWorkDir::CInfo workDirInfo; + GetWorkDir(workDirInfo); + return (workDirInfo.Mode != m_WorkDirInfo.Mode || + workDirInfo.ForRemovableOnly != m_WorkDirInfo.ForRemovableOnly || + workDirInfo.Path.Compare(m_WorkDirInfo.Path) != 0); +} +*/ + +void CFoldersPage::ModifiedEvent() +{ + Changed(); + /* + if (WasChanged()) + Changed(); + else + UnChanged(); + */ +} + +bool CFoldersPage::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + for (int i = 0; i < kNumWorkModeButtons; i++) + if (buttonID == kWorkModeButtons[i]) + { + MyEnableControls(); + ModifiedEvent(); + return true; + } + switch(buttonID) + { + case IDC_FOLDERS_WORK_BUTTON_PATH: + OnFoldersWorkButtonPath(); + break; + case IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE: + break; + default: + return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); + } + ModifiedEvent(); + return true; +} + +bool CFoldersPage::OnCommand(int code, int itemID, LPARAM lParam) +{ + if (code == EN_CHANGE && itemID == IDC_FOLDERS_WORK_EDIT_PATH) + { + ModifiedEvent(); + return true; + } + return CPropertyPage::OnCommand(code, itemID, lParam); +} + +void CFoldersPage::OnFoldersWorkButtonPath() +{ + UString currentPath; + m_WorkPath.GetText(currentPath); + UString title = LangString(IDS_FOLDERS_SET_WORK_PATH_TITLE, 0x01000281); + UString resultPath; + if (NShell::BrowseForFolder(HWND(*this), title, currentPath, resultPath)) + m_WorkPath.SetText(resultPath); +} + +LONG CFoldersPage::OnApply() +{ + GetWorkDir(m_WorkDirInfo); + SaveWorkDirInfo(m_WorkDirInfo); + return PSNRET_NOERROR; +} + +static LPCWSTR kFoldersTopic = L"fm/plugins/7-zip/options.htm#folders"; + +void CFoldersPage::OnNotifyHelp() +{ + ShowHelpWindow(NULL, kFoldersTopic); +} diff --git a/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.h b/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.h new file mode 100755 index 00000000..97950fc6 --- /dev/null +++ b/CPP/7zip/UI/Explorer/FoldersPage/FoldersPage.h @@ -0,0 +1,30 @@ +// FoldersPage.h + +#ifndef __FOLDERSPAGE_H +#define __FOLDERSPAGE_H + +#include "Windows/Control/PropertyPage.h" + +#include "../../Common/ZipRegistry.h" + +class CFoldersPage : public NWindows::NControl::CPropertyPage +{ + NWorkDir::CInfo m_WorkDirInfo; + + void MyEnableControls(); + void ModifiedEvent(); + NWindows::NControl::CDialogChildControl m_WorkPath; + NWindows::NControl::CDialogChildControl m_ButtonSetWorkPath; + void OnFoldersWorkButtonPath(); + int GetWorkMode() const; + void GetWorkDir(NWorkDir::CInfo &workDirInfo); + // bool WasChanged(); +public: + virtual bool OnInit(); + virtual bool OnCommand(int code, int itemID, LPARAM lParam); + virtual void OnNotifyHelp(); + virtual LONG OnApply(); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); +}; + +#endif diff --git a/CPP/7zip/UI/Explorer/FoldersPage/resource.h b/CPP/7zip/UI/Explorer/FoldersPage/resource.h new file mode 100755 index 00000000..3052409b --- /dev/null +++ b/CPP/7zip/UI/Explorer/FoldersPage/resource.h @@ -0,0 +1,12 @@ +#define IDD_FOLDERS 900 + +#define IDS_FOLDERS_SET_WORK_PATH_TITLE 103 + +#define IDC_FOLDERS_STATIC_WORKING_FOLDER 1001 + +#define IDC_FOLDERS_WORK_RADIO_SYSTEM 1011 +#define IDC_FOLDERS_WORK_RADIO_CURRENT 1012 +#define IDC_FOLDERS_WORK_RADIO_SPECIFIED 1013 +#define IDC_FOLDERS_WORK_EDIT_PATH 1014 +#define IDC_FOLDERS_WORK_BUTTON_PATH 1015 +#define IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE 1017 diff --git a/CPP/7zip/UI/Explorer/FoldersPage/resource.rc b/CPP/7zip/UI/Explorer/FoldersPage/resource.rc new file mode 100755 index 00000000..96b2c9d3 --- /dev/null +++ b/CPP/7zip/UI/Explorer/FoldersPage/resource.rc @@ -0,0 +1,36 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 196 +#define ySize2 140 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#define marg2 marg +#define marg3 10 +#define gPos (marg + marg2) +#define gSize (xSize2 - marg2 - marg2) +#define gPos2 (gPos + marg3) + + +IDD_FOLDERS DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE +CAPTION "Folders" +MY_FONT +BEGIN + GROUPBOX "&Working folder", IDC_FOLDERS_STATIC_WORKING_FOLDER, marg, marg, xSize2, 98 + CONTROL "&System temp folder", IDC_FOLDERS_WORK_RADIO_SYSTEM, "Button", BS_AUTORADIOBUTTON | WS_GROUP, + gPos, 20, gSize, 10 + CONTROL "&Current", IDC_FOLDERS_WORK_RADIO_CURRENT, "Button", BS_AUTORADIOBUTTON, + gPos, 34, gSize, 10 + CONTROL "Specified:", IDC_FOLDERS_WORK_RADIO_SPECIFIED, "Button", BS_AUTORADIOBUTTON, + gPos, 48, gSize, 10 + EDITTEXT IDC_FOLDERS_WORK_EDIT_PATH, gPos2, 63, gSize - marg3 - bDotsSize - 10, 14, ES_AUTOHSCROLL + PUSHBUTTON "...", IDC_FOLDERS_WORK_BUTTON_PATH, xSize - marg - marg2 - bDotsSize, 63, bDotsSize, bYSize + CONTROL "Use for removable drives only", IDC_FOLDERS_WORK_CHECK_FOR_REMOVABLE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + gPos, 87, gSize, 10 +END + +STRINGTABLE +BEGIN + IDS_FOLDERS_SET_WORK_PATH_TITLE "Specify a location for temporary archive files." +END diff --git a/CPP/7zip/UI/Explorer/MyMessages.cpp b/CPP/7zip/UI/Explorer/MyMessages.cpp new file mode 100755 index 00000000..61d2429d --- /dev/null +++ b/CPP/7zip/UI/Explorer/MyMessages.cpp @@ -0,0 +1,58 @@ +// MyMessages.cpp + +#include "StdAfx.h" + +#include "MyMessages.h" +#include "Common/String.h" +#include "Common/StringConvert.h" + +#include "Windows/Error.h" +#include "Windows/ResourceString.h" + +#ifdef LANG +#include "../../FileManager/LangUtils.h" +#endif + +using namespace NWindows; + +void MyMessageBox(HWND window, LPCWSTR message) +{ + ::MessageBoxW(window, message, L"7-Zip", 0); +} + +void MyMessageBoxResource(HWND window, UINT32 id + #ifdef LANG + ,UINT32 langID + #endif + ) +{ + #ifdef LANG + MyMessageBox(window, LangString(id, langID)); + #else + MyMessageBox(window, MyLoadStringW(id)); + #endif +} + +void MyMessageBox(UINT32 id + #ifdef LANG + ,UINT32 langID + #endif + ) +{ + MyMessageBoxResource(0, id + #ifdef LANG + , langID + #endif + ); +} + +void ShowErrorMessage(HWND window, DWORD message) +{ + MyMessageBox(window, NError::MyFormatMessageW(message)); +} + +void ShowLastErrorMessage(HWND window) +{ + ShowErrorMessage(window, ::GetLastError()); +} + diff --git a/CPP/7zip/UI/Explorer/MyMessages.h b/CPP/7zip/UI/Explorer/MyMessages.h new file mode 100755 index 00000000..1a96f569 --- /dev/null +++ b/CPP/7zip/UI/Explorer/MyMessages.h @@ -0,0 +1,30 @@ +// MyMessages.h + +#ifndef __MYMESSAGES_H +#define __MYMESSAGES_H + +#include "Common/String.h" + +void MyMessageBox(HWND window, LPCWSTR message); + +inline void MyMessageBox(LPCWSTR message) + { MyMessageBox(0, message); } + +void MyMessageBoxResource(HWND window, UINT32 id + #ifdef LANG + ,UINT32 langID + #endif + ); + +void MyMessageBox(UINT32 id + #ifdef LANG + ,UINT32 langID + #endif + ); + +void ShowErrorMessage(HWND window, DWORD errorMessage); +inline void ShowErrorMessage(DWORD errorMessage) + { ShowErrorMessage(0, errorMessage); } +void ShowLastErrorMessage(HWND window = 0); + +#endif diff --git a/CPP/7zip/UI/Explorer/OptionsDialog.cpp b/CPP/7zip/UI/Explorer/OptionsDialog.cpp new file mode 100755 index 00000000..b7831afd --- /dev/null +++ b/CPP/7zip/UI/Explorer/OptionsDialog.cpp @@ -0,0 +1,71 @@ +// OptionsDialog.cpp + +#include "StdAfx.h" + +#include "resource.h" + +#include "OptionsDialog.h" + +#include "Common/StringConvert.h" +#include "Windows/Control/PropertyPage.h" + +#include "../../FileManager/LangUtils.h" +#include "FoldersPage/FoldersPage.h" +#include "FoldersPage/resource.h" +#include "SystemPage/SystemPage.h" +#include "SystemPage/resource.h" + +using namespace NWindows; + +static INT_PTR OptionsDialog(HWND hwndOwner) +{ + CSystemPage systemPage; + CFoldersPage foldersPage; + UINT32 langIDs[] = { 0x01000300, 0x01000200}; + UINT pageIDs[] = { IDD_SYSTEM, IDD_FOLDERS}; + NControl::CPropertyPage *pagePinters[] = { &systemPage, &foldersPage }; + CObjectVector pages; + const int kNumPages = sizeof(langIDs) / sizeof(langIDs[0]); + for (int i = 0; i < kNumPages; i++) + { + NControl::CPageInfo page; + page.Title = LangString(langIDs[i]); + page.ID = pageIDs[i]; + page.Page = pagePinters[i]; + pages.Add(page); + } + return NControl::MyPropertySheet(pages, hwndOwner, + LangString(IDS_CONFIG_DIALOG_CAPTION, 0x01000000)); +} + +STDMETHODIMP CSevenZipOptions::PluginOptions(HWND hWnd, + IPluginOptionsCallback * /* callback */) +{ + /* + CComBSTR programPath; + RETUEN_IF_NOT_S_OK(callback->GetProgramPath(programName))); + */ + OptionsDialog(hWnd); + return S_OK; +} + +STDMETHODIMP CSevenZipOptions::GetFileExtensions(BSTR * /* extensions */) +{ + /* + UString extStrings; + CObjectVector formats; + NZipRootRegistry::ReadArchiverInfoList(formats); + for(int i = 0; i < formats.Size(); i++) + { + if (i != 0) + extStrings += L' '; + extStrings += formats[i].Extension; + } + CComBSTR valueTemp = extStrings; + *extensions = valueTemp.Detach(); + return S_OK; + */ + return E_NOTIMPL; +} + + diff --git a/CPP/7zip/UI/Explorer/OptionsDialog.h b/CPP/7zip/UI/Explorer/OptionsDialog.h new file mode 100755 index 00000000..7e85d357 --- /dev/null +++ b/CPP/7zip/UI/Explorer/OptionsDialog.h @@ -0,0 +1,23 @@ +// OptionsDialog.h + +#ifndef __SEVENZIP_OPTIONSDIALOG_H +#define __SEVENZIP_OPTIONSDIALOG_H + +#include "../../FileManager/PluginInterface.h" +#include "Common/MyCom.h" + +// {23170F69-40C1-278D-1000-000100020000} +DEFINE_GUID(CLSID_CSevenZipOptions, + 0x23170F69, 0x40C1, 0x278D, 0x10, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00); + +class CSevenZipOptions: + public IPluginOptions, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + STDMETHOD(PluginOptions)(HWND hWnd, IPluginOptionsCallback *callback); + STDMETHOD(GetFileExtensions)(BSTR *extensions); +}; + +#endif diff --git a/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp b/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp new file mode 100755 index 00000000..73a8420e --- /dev/null +++ b/CPP/7zip/UI/Explorer/RegistryContextMenu.cpp @@ -0,0 +1,128 @@ +// RegistryContextMenu.cpp + +#include "StdAfx.h" + +#include "RegistryContextMenu.h" +#include "Windows/COM.h" +#include "Windows/Synchronization.h" +#include "Windows/Registry.h" +#include "Windows/FileName.h" + +using namespace NWindows; +using namespace NCOM; +using namespace NRegistry; + +namespace NZipRootRegistry { + +static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection; + +/////////////////////////// +// ContextMenu + +static const TCHAR *kContextMenuKeyName = TEXT("\\shellex\\ContextMenuHandlers\\7-ZIP"); +static const TCHAR *kDragDropMenuKeyName = TEXT("\\shellex\\DragDropHandlers\\7-ZIP"); + +static const TCHAR *kExtensionCLSID = TEXT("{23170F69-40C1-278A-1000-000100020000}"); + +static const TCHAR *kRootKeyNameForFile = TEXT("*"); +static const TCHAR *kRootKeyNameForFolder = TEXT("Folder"); +static const TCHAR *kRootKeyNameForDirectory = TEXT("Directory"); +static const TCHAR *kRootKeyNameForDrive = TEXT("Drive"); + +static CSysString GetFullContextMenuKeyName(const CSysString &keyName) + { return (keyName + kContextMenuKeyName); } + +static CSysString GetFullDragDropMenuKeyName(const CSysString &keyName) + { return (keyName + kDragDropMenuKeyName); } + +static bool CheckContextMenuHandlerCommon(const CSysString &keyName) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey key; + if (key.Open(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(keyName), KEY_READ) + != ERROR_SUCCESS) + return false; + CSysString value; + if (key.QueryValue(NULL, value) != ERROR_SUCCESS) + return false; + return (value.CompareNoCase(kExtensionCLSID) == 0); +} + +static bool CheckDragDropMenuHandlerCommon(const CSysString &keyName) +{ + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey key; + if (key.Open(HKEY_CLASSES_ROOT, GetFullDragDropMenuKeyName(keyName), KEY_READ) != ERROR_SUCCESS) + return false; + CSysString value; + if (key.QueryValue(NULL, value) != ERROR_SUCCESS) + return false; + return (value.CompareNoCase(kExtensionCLSID) == 0); +} + +bool CheckContextMenuHandler() +{ + return CheckContextMenuHandlerCommon(kRootKeyNameForFile) && + // CheckContextMenuHandlerCommon(kRootKeyNameForFolder) && + CheckContextMenuHandlerCommon(kRootKeyNameForDirectory) && + CheckDragDropMenuHandlerCommon(kRootKeyNameForDirectory) && + CheckDragDropMenuHandlerCommon(kRootKeyNameForDrive); +} + +static void DeleteContextMenuHandlerCommon(const CSysString &keyName) +{ + CKey rootKey; + rootKey.Attach(HKEY_CLASSES_ROOT); + rootKey.RecurseDeleteKey(GetFullContextMenuKeyName(keyName)); + rootKey.Detach(); +} + +static void DeleteDragDropMenuHandlerCommon(const CSysString &keyName) +{ + CKey rootKey; + rootKey.Attach(HKEY_CLASSES_ROOT); + rootKey.RecurseDeleteKey(GetFullDragDropMenuKeyName(keyName)); + rootKey.Detach(); +} + +void DeleteContextMenuHandler() +{ + DeleteContextMenuHandlerCommon(kRootKeyNameForFile); + DeleteContextMenuHandlerCommon(kRootKeyNameForFolder); + DeleteContextMenuHandlerCommon(kRootKeyNameForDirectory); + DeleteContextMenuHandlerCommon(kRootKeyNameForDrive); + DeleteDragDropMenuHandlerCommon(kRootKeyNameForFile); + DeleteDragDropMenuHandlerCommon(kRootKeyNameForFolder); + DeleteDragDropMenuHandlerCommon(kRootKeyNameForDirectory); + DeleteDragDropMenuHandlerCommon(kRootKeyNameForDrive); +} + +static void AddContextMenuHandlerCommon(const CSysString &keyName) +{ + DeleteContextMenuHandlerCommon(keyName); + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey key; + key.Create(HKEY_CLASSES_ROOT, GetFullContextMenuKeyName(keyName)); + key.SetValue(NULL, kExtensionCLSID); +} + +static void AddDragDropMenuHandlerCommon(const CSysString &keyName) +{ + DeleteDragDropMenuHandlerCommon(keyName); + NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection); + CKey key; + key.Create(HKEY_CLASSES_ROOT, GetFullDragDropMenuKeyName(keyName)); + key.SetValue(NULL, kExtensionCLSID); +} + +void AddContextMenuHandler() +{ + AddContextMenuHandlerCommon(kRootKeyNameForFile); + // AddContextMenuHandlerCommon(kRootKeyNameForFolder); + AddContextMenuHandlerCommon(kRootKeyNameForDirectory); + + AddDragDropMenuHandlerCommon(kRootKeyNameForDirectory); + AddDragDropMenuHandlerCommon(kRootKeyNameForDrive); +} + +} diff --git a/CPP/7zip/UI/Explorer/RegistryContextMenu.h b/CPP/7zip/UI/Explorer/RegistryContextMenu.h new file mode 100755 index 00000000..52b053da --- /dev/null +++ b/CPP/7zip/UI/Explorer/RegistryContextMenu.h @@ -0,0 +1,13 @@ +// RegistryContextMenu.h + +#ifndef __REGISTRYCONTEXTMENU_H +#define __REGISTRYCONTEXTMENU_H + +namespace NZipRootRegistry { + + bool CheckContextMenuHandler(); + void AddContextMenuHandler(); + void DeleteContextMenuHandler(); +} + +#endif diff --git a/CPP/7zip/UI/Explorer/StdAfx.cpp b/CPP/7zip/UI/Explorer/StdAfx.cpp new file mode 100755 index 00000000..2550270c --- /dev/null +++ b/CPP/7zip/UI/Explorer/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "stdafx.h" diff --git a/CPP/7zip/UI/Explorer/StdAfx.h b/CPP/7zip/UI/Explorer/StdAfx.h new file mode 100755 index 00000000..b9c0ee3a --- /dev/null +++ b/CPP/7zip/UI/Explorer/StdAfx.h @@ -0,0 +1,26 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#define _WIN32_WINNT 0x0400 +// it's hack for Windows NT supporting +#define WINVER 0x0400 + +// #define _WIN32_IE 0x0500 +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/UI/Explorer/SystemPage/SystemPage.cpp b/CPP/7zip/UI/Explorer/SystemPage/SystemPage.cpp new file mode 100755 index 00000000..cc2f974d --- /dev/null +++ b/CPP/7zip/UI/Explorer/SystemPage/SystemPage.cpp @@ -0,0 +1,212 @@ +// SystemPage.cpp + +#include "StdAfx.h" +#include "resource.h" +#include "../resource.h" + +#include "Common/StringConvert.h" +#include "Windows/Defs.h" +#include "Windows/Control/ListView.h" + +#include "SystemPage.h" + +#include "../../Common/ZipRegistry.h" +#include "../RegistryContextMenu.h" +#include "../ContextMenuFlags.h" + +#include "../../../FileManager/HelpUtils.h" +#include "../../../FileManager/LangUtils.h" +#include "../../../FileManager/FormatUtils.h" + +using namespace NContextMenuFlags; + +static CIDLangPair kIDLangPairs[] = +{ + { IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, 0x01000301}, + { IDC_SYSTEM_CASCADED_MENU, 0x01000302}, + { IDC_SYSTEM_STATIC_CONTEXT_MENU_ITEMS, 0x01000310} +}; + +static LPCWSTR kSystemTopic = L"fm/plugins/7-zip/options.htm#system"; + +struct CContextMenuItem +{ + int ControlID; + UINT32 LangID; + UINT32 Flag; +}; + +static CContextMenuItem kMenuItems[] = +{ + { IDS_CONTEXT_OPEN, 0x02000103, kOpen}, + { IDS_CONTEXT_EXTRACT, 0x02000105, kExtract}, + { IDS_CONTEXT_EXTRACT_HERE, 0x0200010B, kExtractHere }, + { IDS_CONTEXT_EXTRACT_TO, 0x0200010D, kExtractTo }, + + { IDS_CONTEXT_TEST, 0x02000109, kTest}, + + { IDS_CONTEXT_COMPRESS, 0x02000107, kCompress }, + { IDS_CONTEXT_COMPRESS_EMAIL, 0x02000111, kCompressEmail }, + { IDS_CONTEXT_COMPRESS_TO, 0x0200010F, kCompressTo7z }, + { IDS_CONTEXT_COMPRESS_TO_EMAIL, 0x02000113, kCompressTo7zEmail}, + { IDS_CONTEXT_COMPRESS_TO, 0x0200010F, kCompressToZip }, + { IDS_CONTEXT_COMPRESS_TO_EMAIL, 0x02000113, kCompressToZipEmail}, +}; + +const int kNumMenuItems = sizeof(kMenuItems) / sizeof(kMenuItems[0]); + +bool CSystemPage::OnInit() +{ + _initMode = true; + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + + CheckButton(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, + NZipRootRegistry::CheckContextMenuHandler()); + + CheckButton(IDC_SYSTEM_CASCADED_MENU, ReadCascadedMenu()); + + UINT32 contextMenuFlags; + if (!ReadContextMenuStatus(contextMenuFlags)) + contextMenuFlags = NContextMenuFlags::GetDefaultFlags(); + + m_ListView.Attach(GetItem(IDC_SYSTEM_OPTIONS_LIST)); + + /* + CheckButton(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, + NRegistryAssociations::CheckContextMenuHandler()); + */ + + UINT32 newFlags = LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT; + m_ListView.SetExtendedListViewStyle(newFlags, newFlags); + + UString s; // = TEXT("Items"); // LangLoadString(IDS_PROPERTY_EXTENSION, 0x02000205); + LVCOLUMNW column; + column.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_FMT | LVCF_SUBITEM; + column.cx = 270; + column.fmt = LVCFMT_LEFT; + column.pszText = (LPWSTR)(LPCWSTR)s; + column.iSubItem = 0; + m_ListView.InsertColumn(0, &column); + + for (int i = 0; i < kNumMenuItems; i++) + { + CContextMenuItem &menuItem = kMenuItems[i]; + LVITEMW item; + item.iItem = i; + item.mask = LVIF_TEXT | LVIF_PARAM; + item.lParam = i; + + UString s = LangString(menuItem.ControlID, menuItem.LangID); + + switch(menuItem.ControlID) + { + case IDS_CONTEXT_EXTRACT_TO: + { + s = MyFormatNew(s, LangString(IDS_CONTEXT_FOLDER, 0x02000140)); + break; + } + case IDS_CONTEXT_COMPRESS_TO: + case IDS_CONTEXT_COMPRESS_TO_EMAIL: + { + UString s2 = LangString(IDS_CONTEXT_ARCHIVE, 0x02000141); + switch(menuItem.Flag) + { + case kCompressTo7z: + case kCompressTo7zEmail: + s2 += L".7z"; + break; + case kCompressToZip: + case kCompressToZipEmail: + s2 += L".zip"; + break; + } + s = MyFormatNew(s, s2); + break; + } + } + + // UString MyFormatNew(const UString &format, const UString &argument); + + item.pszText = (LPWSTR)(LPCWSTR)s; + item.iSubItem = 0; + int itemIndex = m_ListView.InsertItem(&item); + m_ListView.SetCheckState(itemIndex, ((contextMenuFlags & menuItem.Flag) != 0)); + } + + _initMode = false; + return CPropertyPage::OnInit(); +} + +STDAPI DllRegisterServer(void); +STDAPI DllUnregisterServer(void); + +LONG CSystemPage::OnApply() +{ + if (IsButtonCheckedBool(IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU)) + { + DllRegisterServer(); + NZipRootRegistry::AddContextMenuHandler(); + } + else + { + DllUnregisterServer(); + NZipRootRegistry::DeleteContextMenuHandler(); + } + SaveCascadedMenu(IsButtonCheckedBool(IDC_SYSTEM_CASCADED_MENU)); + + UINT32 flags = 0; + for (int i = 0; i < kNumMenuItems; i++) + if (m_ListView.GetCheckState(i)) + flags |= kMenuItems[i].Flag; + SaveContextMenuStatus(flags); + + return PSNRET_NOERROR; +} + +void CSystemPage::OnNotifyHelp() +{ + ShowHelpWindow(NULL, kSystemTopic); +} + +bool CSystemPage::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDC_SYSTEM_CASCADED_MENU: + case IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU: + Changed(); + return true; + } + return CPropertyPage::OnButtonClicked(buttonID, buttonHWND); + +} + +bool CSystemPage::OnNotify(UINT aControlID, LPNMHDR lParam) +{ + if (lParam->hwndFrom == HWND(m_ListView)) + { + switch(lParam->code) + { + case (LVN_ITEMCHANGED): + return OnItemChanged((const NMLISTVIEW *)lParam); + } + } + return CPropertyPage::OnNotify(aControlID, lParam); +} + + +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; +} diff --git a/CPP/7zip/UI/Explorer/SystemPage/SystemPage.h b/CPP/7zip/UI/Explorer/SystemPage/SystemPage.h new file mode 100755 index 00000000..a7de7c79 --- /dev/null +++ b/CPP/7zip/UI/Explorer/SystemPage/SystemPage.h @@ -0,0 +1,25 @@ +// SystemPage.h + +#ifndef __SYSTEMPAGE_H +#define __SYSTEMPAGE_H + +#include "Windows/Control/PropertyPage.h" +#include "Windows/Control/ListView.h" + +#include "../../Common/ArchiverInfo.h" + +class CSystemPage: public NWindows::NControl::CPropertyPage +{ + bool _initMode; + CObjectVector m_Archivers; + NWindows::NControl::CListView m_ListView; +public: + virtual bool OnInit(); + virtual void OnNotifyHelp(); + virtual bool OnNotify(UINT aControlID, LPNMHDR lParam); + virtual bool OnItemChanged(const NMLISTVIEW *info); + virtual LONG OnApply(); + virtual bool OnButtonClicked(int aButtonID, HWND aButtonHWND); +}; + +#endif diff --git a/CPP/7zip/UI/Explorer/SystemPage/resource.h b/CPP/7zip/UI/Explorer/SystemPage/resource.h new file mode 100755 index 00000000..b125849c --- /dev/null +++ b/CPP/7zip/UI/Explorer/SystemPage/resource.h @@ -0,0 +1,6 @@ +#define IDD_SYSTEM 102 + +#define IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU 1010 +#define IDC_SYSTEM_CASCADED_MENU 1011 +#define IDC_SYSTEM_STATIC_CONTEXT_MENU_ITEMS 1020 +#define IDC_SYSTEM_OPTIONS_LIST 1022 diff --git a/CPP/7zip/UI/Explorer/SystemPage/resource.rc b/CPP/7zip/UI/Explorer/SystemPage/resource.rc new file mode 100755 index 00000000..fdfed433 --- /dev/null +++ b/CPP/7zip/UI/Explorer/SystemPage/resource.rc @@ -0,0 +1,24 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 196 +#define ySize2 164 +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +IDD_SYSTEM DIALOG 0, 0, xSize, ySize MY_PAGE_STYLE +CAPTION "System" +MY_FONT +BEGIN + CONTROL "Integrate 7-Zip to shell context menu", IDC_SYSTEM_INTEGRATE_TO_CONTEXT_MENU, + "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, marg, xSize2, 10 + CONTROL "Cascaded context menu", IDC_SYSTEM_CASCADED_MENU, + "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 21, xSize2, 10 + LTEXT "Context menu items:", IDC_SYSTEM_STATIC_CONTEXT_MENU_ITEMS, + marg, 37, xSize2, 8 + CONTROL "List1", IDC_SYSTEM_OPTIONS_LIST, "SysListView32", + LVS_REPORT | LVS_SINGLESEL | LVS_NOCOLUMNHEADER | WS_BORDER | WS_TABSTOP, + marg, 50, xSize2, ySize - marg - 50 +END diff --git a/CPP/7zip/UI/Explorer/makefile b/CPP/7zip/UI/Explorer/makefile new file mode 100755 index 00000000..0fcc57e4 --- /dev/null +++ b/CPP/7zip/UI/Explorer/makefile @@ -0,0 +1,137 @@ +PROG = 7-zip.dll +DEF_FILE = Explorer.def +LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib htmlhelp.lib shell32.lib comctl32.lib ole32.lib comdlg32.lib +CFLAGS = $(CFLAGS) -I ../../../ \ + -DLANG \ + -DNEW_FOLDER_INTERFACE \ + -DWIN_LONG_PATH + +EXPLORER_OBJS = \ + $O\DllExports.obj \ + $O\ContextMenu.obj \ + $O\MyMessages.obj \ + $O\OptionsDialog.obj \ + $O\RegistryContextMenu.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\IntToString.obj \ + $O\Lang.obj \ + $O\ListFileUtils.obj \ + $O\NewHandler.obj \ + $O\Random.obj \ + $O\StdInStream.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\TextConfig.obj \ + $O\UTFConvert.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\Error.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\Menu.obj \ + $O\PropVariant.obj \ + $O\PropVariantConversions.obj \ + $O\Registry.obj \ + $O\ResourceString.obj \ + $O\Shell.obj \ + $O\Synchronization.obj \ + $O\Window.obj \ + +WIN_CTRL_OBJS = \ + $O\Dialog.obj \ + $O\PropertyPage.obj \ + +7ZIP_COMMON_OBJS = \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\StreamUtils.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveName.obj \ + $O\ArchiveOpenCallback.obj \ + $O\ArchiverInfo.obj \ + $O\CompressCall.obj \ + $O\DefaultName.obj \ + $O\EnumDirItems.obj \ + $O\ExtractingFilePath.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + $O\SortUtils.obj \ + $O\UpdateAction.obj \ + $O\UpdateCallback.obj \ + $O\UpdatePair.obj \ + $O\UpdateProduce.obj \ + $O\WorkDir.obj \ + $O\ZipRegistry.obj \ + +AGENT_OBJS = \ + $O\Agent.obj \ + $O\AgentOut.obj \ + $O\AgentProxy.obj \ + $O\ArchiveFolder.obj \ + $O\ArchiveFolderOpen.obj \ + $O\ArchiveFolderOut.obj \ + $O\UpdateCallbackAgent.obj \ + + +FM_COMMON_OBJS = \ + $O\FormatUtils.obj \ + $O\HelpUtils.obj \ + $O\LangUtils.obj \ + $O\ProgramLocation.obj \ + $O\RegistryUtils.obj \ + +C_OBJS = \ + $O\Sort.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(EXPLORER_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(WIN_CTRL_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $(AGENT_OBJS) \ + $(FM_COMMON_OBJS)\ + $(C_OBJS) \ + $O\SystemPage.obj \ + $O\FoldersPage.obj \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(EXPLORER_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(WIN_CTRL_OBJS): ../../../Windows/Control/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(UI_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$(AGENT_OBJS): ../Agent/$(*B).cpp + $(COMPL) +$(FM_COMMON_OBJS): ../../FileManager/$(*B).cpp + $(COMPL) +$O\SystemPage.obj: SystemPage/$(*B).cpp + $(COMPL) +$O\FoldersPage.obj: FoldersPage/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) +$(C_OBJS): ../../../../C/$(*B).c + $(COMPL_O2) diff --git a/CPP/7zip/UI/Explorer/resource.h b/CPP/7zip/UI/Explorer/resource.h new file mode 100755 index 00000000..aec1e7cd --- /dev/null +++ b/CPP/7zip/UI/Explorer/resource.h @@ -0,0 +1,31 @@ +#define IDS_CONTEXT_EXTRACT 42 +#define IDS_CONTEXT_EXTRACT_HELP 43 +#define IDS_CONTEXT_COMPRESS 44 +#define IDS_CONTEXT_COMPRESS_HELP 45 +#define IDS_CONTEXT_OPEN 46 +#define IDS_CONTEXT_OPEN_HELP 47 +#define IDS_CONTEXT_TEST 48 +#define IDS_CONTEXT_TEST_HELP 49 +#define IDS_CONTEXT_CAPTION_HELP 50 +#define IDS_CONTEXT_POPUP_CAPTION 51 + +#define IDS_CONTEXT_EXTRACT_HERE 52 +#define IDS_CONTEXT_EXTRACT_HERE_HELP 53 + +#define IDS_CONTEXT_EXTRACT_TO 54 +#define IDS_CONTEXT_EXTRACT_TO_HELP 55 + +#define IDS_CONTEXT_COMPRESS_TO 56 +#define IDS_CONTEXT_COMPRESS_TO_HELP 57 + +#define IDS_CONTEXT_COMPRESS_EMAIL 58 +#define IDS_CONTEXT_COMPRESS_EMAIL_HELP 59 + +#define IDS_CONTEXT_COMPRESS_TO_EMAIL 60 +#define IDS_CONTEXT_COMPRESS_TO_EMAIL_HELP 61 + +#define IDS_CONTEXT_FOLDER 70 +#define IDS_CONTEXT_ARCHIVE 71 + +#define IDS_ERROR 100 +#define IDS_CONFIG_DIALOG_CAPTION 102 diff --git a/CPP/7zip/UI/Explorer/resource.rc b/CPP/7zip/UI/Explorer/resource.rc new file mode 100755 index 00000000..bf7601d9 --- /dev/null +++ b/CPP/7zip/UI/Explorer/resource.rc @@ -0,0 +1,38 @@ +#include "../../MyVersionInfo.rc" +#include "resource.h" + +MY_VERSION_INFO_DLL("7-Zip Shell Extension", "7-zip") + +1 24 "7-zip.dll.manifest" + +STRINGTABLE +BEGIN + IDS_CONTEXT_EXTRACT "Extract files..." + IDS_CONTEXT_EXTRACT_HELP "Extracts files from the selected archive." + IDS_CONTEXT_COMPRESS "Add to archive..." + IDS_CONTEXT_COMPRESS_HELP "Adds the selected items to archive." + IDS_CONTEXT_OPEN "Open archive" + IDS_CONTEXT_OPEN_HELP "Opens the selected archive." + IDS_CONTEXT_TEST "Test archive" + IDS_CONTEXT_TEST_HELP "Tests integrity of the selected archive." + IDS_CONTEXT_CAPTION_HELP "7-Zip commands" + IDS_CONTEXT_POPUP_CAPTION "7-Zip" + IDS_CONTEXT_EXTRACT_HERE "Extract Here" + IDS_CONTEXT_EXTRACT_HERE_HELP "Extracts files from the selected archive to current folder." + IDS_CONTEXT_EXTRACT_TO "Extract to {0}" + IDS_CONTEXT_EXTRACT_TO_HELP "Extracts files to subfolder." + IDS_CONTEXT_COMPRESS_TO "Add to {0}" + IDS_CONTEXT_COMPRESS_TO_HELP "Adds the selected items to archive." + IDS_CONTEXT_COMPRESS_EMAIL "Compress and email..." + IDS_CONTEXT_COMPRESS_EMAIL_HELP "Compresses the selected items to archive and sends archive via email." + IDS_CONTEXT_COMPRESS_TO_EMAIL "Compress to {0} and email" + IDS_CONTEXT_COMPRESS_TO_EMAIL_HELP "Compresses the selected items to archive and sends archive via email." + IDS_CONTEXT_FOLDER "" + IDS_CONTEXT_ARCHIVE "" + IDS_ERROR "Error" + IDS_CONFIG_DIALOG_CAPTION "7-Zip Options" +END + +#include "FoldersPage/resource.rc" +#include "SystemPage/resource.rc" + diff --git a/CPP/7zip/UI/Far/CLSIDConst.cpp b/CPP/7zip/UI/Far/CLSIDConst.cpp new file mode 100755 index 00000000..a6cea92e --- /dev/null +++ b/CPP/7zip/UI/Far/CLSIDConst.cpp @@ -0,0 +1,8 @@ +// CLSIDConst.cpp + +#include "StdAfx.h" + +#include + +#include "../Agent/Agent.h" +#include "../../IPassword.h" diff --git a/CPP/7zip/UI/Far/ExtractEngine.cpp b/CPP/7zip/UI/Far/ExtractEngine.cpp new file mode 100755 index 00000000..e85df5e1 --- /dev/null +++ b/CPP/7zip/UI/Far/ExtractEngine.cpp @@ -0,0 +1,168 @@ +// ExtractEngine.h + +#include "StdAfx.h" + +#include + +#include "ExtractEngine.h" + +#include "Common/Wildcard.h" +#include "Common/StringConvert.h" + +#include "Windows/Defs.h" + +#include "FarUtils.h" +#include "Messages.h" +#include "OverwriteDialog.h" + +using namespace NWindows; +using namespace NFar; + +extern void PrintMessage(const char *message); + +CExtractCallBackImp::~CExtractCallBackImp() +{ +} + +void CExtractCallBackImp::Init( + UINT codePage, + CProgressBox *progressBox, + bool passwordIsDefined, + const UString &password) +{ + m_PasswordIsDefined = passwordIsDefined; + m_Password = password; + m_CodePage = codePage; + m_ProgressBox = progressBox; +} + +STDMETHODIMP CExtractCallBackImp::SetTotal(UINT64 size) +{ + if (m_ProgressBox != 0) + { + m_ProgressBox->SetTotal(size); + m_ProgressBox->PrintCompeteValue(0); + } + return S_OK; +} + +STDMETHODIMP CExtractCallBackImp::SetCompleted(const UINT64 *completeValue) +{ + if(WasEscPressed()) + return E_ABORT; + if (m_ProgressBox != 0 && completeValue != NULL) + m_ProgressBox->PrintCompeteValue(*completeValue); + return S_OK; +} + +STDMETHODIMP CExtractCallBackImp::AskOverwrite( + const wchar_t *existName, const FILETIME *existTime, const UINT64 *existSize, + const wchar_t *newName, const FILETIME *aNewTime, const UINT64 *newSize, + INT32 *answer) +{ + NOverwriteDialog::CFileInfo oldFileInfo, newFileInfo; + oldFileInfo.Time = *existTime; + oldFileInfo.SizeIsDefined = (existSize != NULL); + if (oldFileInfo.SizeIsDefined) + oldFileInfo.Size = *existSize; + oldFileInfo.Name = GetSystemString(existName, m_CodePage); + + + newFileInfo.Time = *aNewTime; + + newFileInfo.SizeIsDefined = (newSize != NULL); + if (newFileInfo.SizeIsDefined) + newFileInfo.Size = *newSize; + newFileInfo.Name = GetSystemString(newName, m_CodePage); + + NOverwriteDialog::NResult::EEnum result = + NOverwriteDialog::Execute(oldFileInfo, newFileInfo); + + switch(result) + { + case NOverwriteDialog::NResult::kCancel: + // *answer = NOverwriteAnswer::kCancel; + // break; + return E_ABORT; + case NOverwriteDialog::NResult::kNo: + *answer = NOverwriteAnswer::kNo; + break; + case NOverwriteDialog::NResult::kNoToAll: + *answer = NOverwriteAnswer::kNoToAll; + break; + case NOverwriteDialog::NResult::kYesToAll: + *answer = NOverwriteAnswer::kYesToAll; + break; + case NOverwriteDialog::NResult::kYes: + *answer = NOverwriteAnswer::kYes; + break; + case NOverwriteDialog::NResult::kAutoRename: + *answer = NOverwriteAnswer::kAutoRename; + break; + default: + throw 20413; + } + return S_OK; +} + +STDMETHODIMP CExtractCallBackImp::PrepareOperation(const wchar_t *name, INT32 /* askExtractMode */, const UINT64 * /* position */) +{ + m_CurrentFilePath = name; + return S_OK; +} + +STDMETHODIMP CExtractCallBackImp::MessageError(const wchar_t *message) +{ + AString s = UnicodeStringToMultiByte(message, CP_OEMCP); + if (g_StartupInfo.ShowMessage((const char *)s) == -1) + return E_ABORT; + return S_OK; +} + +STDMETHODIMP CExtractCallBackImp::SetOperationResult(INT32 operationResult, bool encrypted) +{ + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kOK: + break; + default: + { + UINT idMessage; + switch(operationResult) + { + case NArchive::NExtract::NOperationResult::kUnSupportedMethod: + idMessage = NMessageID::kExtractUnsupportedMethod; + break; + case NArchive::NExtract::NOperationResult::kCRCError: + idMessage = NMessageID::kExtractCRCFailed; + break; + case NArchive::NExtract::NOperationResult::kDataError: + idMessage = NMessageID::kExtractDataError; + break; + default: + return E_FAIL; + } + char buffer[512]; + sprintf(buffer, g_StartupInfo.GetMsgString(idMessage), + GetSystemString(m_CurrentFilePath, m_CodePage)); + if (g_StartupInfo.ShowMessage(buffer) == -1) + return E_ABORT; + } + } + return S_OK; +} + +extern HRESULT GetPassword(UString &password); + +STDMETHODIMP CExtractCallBackImp::CryptoGetTextPassword(BSTR *password) +{ + if (!m_PasswordIsDefined) + { + RINOK(GetPassword(m_Password)); + m_PasswordIsDefined = true; + } + CMyComBSTR tempName = m_Password; + *password = tempName.Detach(); + + return S_OK; +} diff --git a/CPP/7zip/UI/Far/ExtractEngine.h b/CPP/7zip/UI/Far/ExtractEngine.h new file mode 100755 index 00000000..57c04f76 --- /dev/null +++ b/CPP/7zip/UI/Far/ExtractEngine.h @@ -0,0 +1,68 @@ +// ExtractEngine.h + +#ifndef __EXTRACTENGINE_H +#define __EXTRACTENGINE_H + +#include "Common/MyCom.h" +#include "Common/String.h" + +#include "../../IPassword.h" +#include "../Agent/IFolderArchive.h" + +#include "ProgressBox.h" + +class CExtractCallBackImp: + public IFolderArchiveExtractCallback, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP1(ICryptoGetTextPassword) + + // IProgress + STDMETHOD(SetTotal)(UINT64 size); + STDMETHOD(SetCompleted)(const UINT64 *completeValue); + + // IExtractCallBack + STDMETHOD(AskOverwrite)( + const wchar_t *existName, const FILETIME *existTime, const UINT64 *existSize, + const wchar_t *newName, const FILETIME *newTime, const UINT64 *newSize, + INT32 *result); + STDMETHOD (PrepareOperation)(const wchar_t *name, INT32 askExtractMode, const UINT64 *position); + + STDMETHOD(MessageError)(const wchar_t *message); + STDMETHOD(SetOperationResult)(INT32 resultEOperationResult, bool encrypted); + // ICryptoGetTextPassword + STDMETHOD(CryptoGetTextPassword)(BSTR *password); + +private: + UString m_CurrentFilePath; + + struct CProcessedFileInfo + { + FILETIME UTCLastWriteTime; + bool IsDirectory; + UINT32 Attributes; + } m_ProcessedFileInfo; + + CProgressBox *m_ProgressBox; + UINT m_CodePage; + + bool m_PasswordIsDefined; + UString m_Password; + + void CreateComplexDirectory(const UStringVector &dirPathParts); + /* + void GetPropertyValue(LPITEMIDLIST anItemIDList, PROPID aPropId, + PROPVARIANT *aValue); + bool IsEncrypted(LPITEMIDLIST anItemIDList); + */ + void AddErrorMessage(LPCTSTR message); +public: + ~CExtractCallBackImp(); + void Init(UINT codePage, + CProgressBox *progressBox, + bool passwordIsDefined, const UString &password); +}; + +#endif diff --git a/CPP/7zip/UI/Far/Far.def b/CPP/7zip/UI/Far/Far.def new file mode 100755 index 00000000..d96501e2 --- /dev/null +++ b/CPP/7zip/UI/Far/Far.def @@ -0,0 +1,20 @@ +; 7-ZipFar.def : Declares the module parameters for the DLL. + +LIBRARY "7-ZipFar" +DESCRIPTION '7-ZipFar Windows Dynamic Link Library' + +EXPORTS + SetStartupInfo = _SetStartupInfo@4 + OpenPlugin = _OpenPlugin@8 + OpenFilePlugin = _OpenFilePlugin@12 + ClosePlugin = _ClosePlugin@4 + GetFindData = _GetFindData@16 + FreeFindData = _FreeFindData@12 + SetDirectory = _SetDirectory@12 + GetPluginInfo = _GetPluginInfo@4 + Configure = _Configure@4 + GetOpenPluginInfo = _GetOpenPluginInfo@8 + GetFiles = _GetFiles@24 + PutFiles = _PutFiles@20 + DeleteFiles = _DeleteFiles@16 + ProcessKey = _ProcessKey@12 diff --git a/CPP/7zip/UI/Far/Far.dsp b/CPP/7zip/UI/Far/Far.dsp new file mode 100755 index 00000000..47c44c69 --- /dev/null +++ b/CPP/7zip/UI/Far/Far.dsp @@ -0,0 +1,561 @@ +# Microsoft Developer Studio Project File - Name="Far" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=Far - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "Far.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "Far.mak" CFG="Far - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "Far - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "Far - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "Far - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /YX /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /Yu"StdAfx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"C:\Program Files\Far\Plugins\7-Zip\7-ZipFar.dll" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "Far - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FAR_EXPORTS" /Yu"StdAfx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"C:\Program Files\Far\Plugins\7-Zip\7-ZipFar.dll" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "Far - Win32 Release" +# Name "Far - Win32 Debug" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\CLSIDConst.cpp +# End Source File +# Begin Source File + +SOURCE=.\Far.def +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"StdAfx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "Plugin" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ExtractEngine.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractEngine.h +# End Source File +# Begin Source File + +SOURCE=.\Main.cpp +# End Source File +# Begin Source File + +SOURCE=.\Messages.h +# End Source File +# Begin Source File + +SOURCE=.\OverwriteDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\OverwriteDialog.h +# End Source File +# Begin Source File + +SOURCE=.\Plugin.cpp +# End Source File +# Begin Source File + +SOURCE=.\Plugin.h +# End Source File +# Begin Source File + +SOURCE=.\PluginDelete.cpp +# End Source File +# Begin Source File + +SOURCE=.\PluginRead.cpp +# End Source File +# Begin Source File + +SOURCE=.\PluginWrite.cpp +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallback100.cpp +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallback100.h +# End Source File +# End Group +# Begin Group "Far" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\FarPlugin.h +# End Source File +# Begin Source File + +SOURCE=.\FarUtils.cpp +# End Source File +# Begin Source File + +SOURCE=.\FarUtils.h +# End Source File +# Begin Source File + +SOURCE=.\ProgressBox.cpp +# End Source File +# Begin Source File + +SOURCE=.\ProgressBox.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Defs.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.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\PropVariantConversions.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiverInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiverInfo.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DirItem.h +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractMode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\HandlerLoader.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +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.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.h +# End Source File +# End Group +# Begin Group "Agent" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Agent\Agent.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\Agent.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentOut.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentProxy.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\AgentProxy.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\IFolderArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Agent\UpdateCallbackAgent.cpp +# End Source File +# Begin Source File + +SOURCE=..\Agent\UpdateCallbackAgent.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# Begin Group "7-zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/UI/Far/Far.dsw b/CPP/7zip/UI/Far/Far.dsw new file mode 100755 index 00000000..f4ef0801 --- /dev/null +++ b/CPP/7zip/UI/Far/Far.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Far"=.\Far.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/UI/Far/FarPlugin.h b/CPP/7zip/UI/Far/FarPlugin.h new file mode 100755 index 00000000..f61bbcb4 --- /dev/null +++ b/CPP/7zip/UI/Far/FarPlugin.h @@ -0,0 +1,577 @@ +// FarPlugin.h + +#ifndef __FARPLUGIN_H +#define __FARPLUGIN_H + +#if defined(__BORLANDC__) && (__BORLANDC <= 0x520) + #pragma option -a1 +#elif defined(__GNUC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1100)) + #pragma pack(1) +#else + #pragma pack(push,1) + #if _MSC_VER + #define _export + #endif +#endif + +#define NM 260 + +struct FarFindData +{ + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwReserved0; + DWORD dwReserved1; + char cFileName[ MAX_PATH ]; + char cAlternateFileName[ 14 ]; +}; + +struct PluginPanelItem +{ + FarFindData FindData; + DWORD PackSizeHigh; + DWORD PackSize; + DWORD Flags; + DWORD NumberOfLinks; + char *Description; + char *Owner; + char **CustomColumnData; + int CustomColumnNumber; + DWORD UserData; + DWORD Reserved[3]; +}; + +#define PPIF_PROCESSDESCR 0x80000000 +#define PPIF_SELECTED 0x40000000 +#define PPIF_USERDATA 0x20000000 + +enum { + FMENU_SHOWAMPERSAND=1, + FMENU_WRAPMODE=2, + FMENU_AUTOHIGHLIGHT=4, + FMENU_REVERSEAUTOHIGHLIGHT=8 +}; + + +typedef int (WINAPI *FARAPIMENU)( + int PluginNumber, + int X, + int Y, + int MaxHeight, + unsigned int Flags, + char *Title, + char *Bottom, + char *HelpTopic, + int *BreakKeys, + int *BreakCode, + struct FarMenuItem *Item, + int ItemsNumber +); + +typedef int (WINAPI *FARAPIDIALOG)( + int PluginNumber, + int X1, + int Y1, + int X2, + int Y2, + char *HelpTopic, + struct FarDialogItem *Item, + int ItemsNumber +); + +enum { + FMSG_WARNING=1, + FMSG_ERRORTYPE=2, + FMSG_KEEPBACKGROUND=4, + FMSG_DOWN=8, + FMSG_LEFTALIGN=16 +}; + +typedef int (WINAPI *FARAPIMESSAGE)( + int PluginNumber, + unsigned int Flags, + char *HelpTopic, + char **Items, + int ItemsNumber, + int ButtonsNumber +); + +typedef char* (WINAPI *FARAPIGETMSG)( + int PluginNumber, + int MsgId +); + + +enum DialogItemTypes { + DI_TEXT, + DI_VTEXT, + DI_SINGLEBOX, + DI_DOUBLEBOX, + DI_EDIT, + DI_PSWEDIT, + DI_FIXEDIT, + DI_BUTTON, + DI_CHECKBOX, + DI_RADIOBUTTON +}; + +enum FarDialogItemFlags { + DIF_COLORMASK = 0xff, + DIF_SETCOLOR = 0x100, + DIF_BOXCOLOR = 0x200, + DIF_GROUP = 0x400, + DIF_LEFTTEXT = 0x800, + DIF_MOVESELECT = 0x1000, + DIF_SHOWAMPERSAND = 0x2000, + DIF_CENTERGROUP = 0x4000, + DIF_NOBRACKETS = 0x8000, + DIF_SEPARATOR = 0x10000, + DIF_EDITOR = 0x20000, + DIF_HISTORY = 0x40000 +}; + +struct FarDialogItem +{ + int Type; + int X1,Y1,X2,Y2; + int Focus; + union + { + int Selected; + const char *History; + const char *Mask; + struct FarList *ListItems; + int ListPos; + CHAR_INFO *VBuf; + }; + unsigned int Flags; + int DefaultButton; + char Data[512]; +}; + + +struct FarMenuItem +{ + char Text[128]; + int Selected; + int Checked; + int Separator; +}; + + +enum {FCTL_CLOSEPLUGIN,FCTL_GETPANELINFO,FCTL_GETANOTHERPANELINFO, + FCTL_UPDATEPANEL,FCTL_UPDATEANOTHERPANEL, + FCTL_REDRAWPANEL,FCTL_REDRAWANOTHERPANEL, + FCTL_SETANOTHERPANELDIR,FCTL_GETCMDLINE,FCTL_SETCMDLINE, + FCTL_SETSELECTION,FCTL_SETANOTHERSELECTION, + FCTL_SETVIEWMODE,FCTL_SETANOTHERVIEWMODE,FCTL_INSERTCMDLINE, + FCTL_SETUSERSCREEN,FCTL_SETPANELDIR,FCTL_SETCMDLINEPOS, + FCTL_GETCMDLINEPOS +}; + +enum {PTYPE_FILEPANEL,PTYPE_TREEPANEL,PTYPE_QVIEWPANEL,PTYPE_INFOPANEL}; + +struct PanelInfo +{ + int PanelType; + int Plugin; + RECT PanelRect; + struct PluginPanelItem *PanelItems; + int ItemsNumber; + struct PluginPanelItem *SelectedItems; + int SelectedItemsNumber; + int CurrentItem; + int TopPanelItem; + int Visible; + int Focus; + int ViewMode; + char ColumnTypes[80]; + char ColumnWidths[80]; + char CurDir[NM]; + int ShortNames; + int SortMode; + DWORD Reserved[2]; +}; + + +struct PanelRedrawInfo +{ + int CurrentItem; + int TopPanelItem; +}; + + +typedef int (WINAPI *FARAPICONTROL)( + HANDLE hPlugin, + int Command, + void *Param +); + +typedef HANDLE (WINAPI *FARAPISAVESCREEN)(int X1,int Y1,int X2,int Y2); + +typedef void (WINAPI *FARAPIRESTORESCREEN)(HANDLE hScreen); + +typedef int (WINAPI *FARAPIGETDIRLIST)( + char *Dir, + struct PluginPanelItem **pPanelItem, + int *pItemsNumber +); + +typedef int (WINAPI *FARAPIGETPLUGINDIRLIST)( + int PluginNumber, + HANDLE hPlugin, + char *Dir, + struct PluginPanelItem **pPanelItem, + int *pItemsNumber +); + +typedef void (WINAPI *FARAPIFREEDIRLIST)(struct PluginPanelItem *PanelItem); + +enum VIEWER_FLAGS { + VF_NONMODAL=1,VF_DELETEONCLOSE=2 +}; + +typedef int (WINAPI *FARAPIVIEWER)( + char *FileName, + char *Title, + int X1, + int Y1, + int X2, + int Y2, + DWORD Flags +); + +typedef int (WINAPI *FARAPIEDITOR)( + char *FileName, + char *Title, + int X1, + int Y1, + int X2, + int Y2, + DWORD Flags, + int StartLine, + int StartChar +); + +typedef int (WINAPI *FARAPICMPNAME)( + char *Pattern, + char *String, + int SkipPath +); + + +#define FCT_DETECT 0x40000000 + +struct CharTableSet +{ + char DecodeTable[256]; + char EncodeTable[256]; + char UpperTable[256]; + char LowerTable[256]; + char TableName[128]; +}; + +typedef int (WINAPI *FARAPICHARTABLE)( + int Command, + char *Buffer, + int BufferSize +); + +typedef void (WINAPI *FARAPITEXT)( + int X, + int Y, + int Color, + char *Str +); + + +typedef int (WINAPI *FARAPIEDITORCONTROL)( + int Command, + void *Param +); + + +enum EDITOR_EVENTS { + EE_READ,EE_SAVE,EE_REDRAW,EE_CLOSE +}; + +enum EDITOR_CONTROL_COMMANDS { + ECTL_GETSTRING,ECTL_SETSTRING,ECTL_INSERTSTRING,ECTL_DELETESTRING, + ECTL_DELETECHAR,ECTL_INSERTTEXT,ECTL_GETINFO,ECTL_SETPOSITION, + ECTL_SELECT,ECTL_REDRAW,ECTL_EDITORTOOEM,ECTL_OEMTOEDITOR, + ECTL_TABTOREAL,ECTL_REALTOTAB,ECTL_EXPANDTABS,ECTL_SETTITLE, + ECTL_READINPUT,ECTL_PROCESSINPUT,ECTL_ADDCOLOR,ECTL_GETCOLOR +}; + + +struct EditorGetString +{ + int StringNumber; + char *StringText; + char *StringEOL; + int StringLength; + int SelStart; + int SelEnd; +}; + + +struct EditorSetString +{ + int StringNumber; + char *StringText; + char *StringEOL; + int StringLength; +}; + + +enum EDITOR_OPTIONS { + EOPT_EXPANDTABS=1,EOPT_PERSISTENTBLOCKS=2,EOPT_DELREMOVESBLOCKS=4, + EOPT_AUTOINDENT=8,EOPT_SAVEFILEPOSITION=16,EOPT_AUTODETECTTABLE=32, + EOPT_CURSORBEYONDEOL=64 +}; + + +enum EDITOR_BLOCK_TYPES { + BTYPE_NONE,BTYPE_STREAM,BTYPE_COLUMN +}; + + +struct EditorInfo +{ + int EditorID; + char *FileName; + int WindowSizeX; + int WindowSizeY; + int TotalLines; + int CurLine; + int CurPos; + int CurTabPos; + int TopScreenLine; + int LeftPos; + int Overtype; + int BlockType; + int BlockStartLine; + int AnsiMode; + int TableNum; + DWORD Options; + int TabSize; + DWORD Reserved[8]; +}; + + +struct EditorSetPosition +{ + int CurLine; + int CurPos; + int CurTabPos; + int TopScreenLine; + int LeftPos; + int Overtype; +}; + + +struct EditorSelect +{ + int BlockType; + int BlockStartLine; + int BlockStartPos; + int BlockWidth; + int BlockHeight; +}; + + +struct EditorConvertText +{ + char *Text; + int TextLength; +}; + + +struct EditorConvertPos +{ + int StringNumber; + int SrcPos; + int DestPos; +}; + + +struct EditorColor +{ + int StringNumber; + int ColorItem; + int StartPos; + int EndPos; + int Color; +}; + + +struct PluginStartupInfo +{ + int StructSize; + char ModuleName[NM]; + int ModuleNumber; + char *RootKey; + FARAPIMENU Menu; + FARAPIDIALOG Dialog; + FARAPIMESSAGE Message; + FARAPIGETMSG GetMsg; + FARAPICONTROL Control; + FARAPISAVESCREEN SaveScreen; + FARAPIRESTORESCREEN RestoreScreen; + FARAPIGETDIRLIST GetDirList; + FARAPIGETPLUGINDIRLIST GetPluginDirList; + FARAPIFREEDIRLIST FreeDirList; + FARAPIVIEWER Viewer; + FARAPIEDITOR Editor; + FARAPICMPNAME CmpName; + FARAPICHARTABLE CharTable; + FARAPITEXT Text; + FARAPIEDITORCONTROL EditorControl; +}; + + +enum PLUGIN_FLAGS { + PF_PRELOAD = 0x0001, + PF_DISABLEPANELS = 0x0002, + PF_EDITOR = 0x0004, + PF_VIEWER = 0x0008 +}; + + +struct PluginInfo +{ + int StructSize; + DWORD Flags; + char **DiskMenuStrings; + int *DiskMenuNumbers; + int DiskMenuStringsNumber; + char **PluginMenuStrings; + int PluginMenuStringsNumber; + char **PluginConfigStrings; + int PluginConfigStringsNumber; + char *CommandPrefix; +}; + + +struct InfoPanelLine +{ + char Text[80]; + char Data[80]; + int Separator; +}; + + +struct PanelMode +{ + char *ColumnTypes; + char *ColumnWidths; + char **ColumnTitles; + int FullScreen; + int DetailedStatus; + int AlignExtensions; + int CaseConversion; + char *StatusColumnTypes; + char *StatusColumnWidths; + DWORD Reserved[2]; +}; + + +enum OPENPLUGININFO_FLAGS { + OPIF_USEFILTER = 0x0001, + OPIF_USESORTGROUPS = 0x0002, + OPIF_USEHIGHLIGHTING = 0x0004, + OPIF_ADDDOTS = 0x0008, + OPIF_RAWSELECTION = 0x0010, + OPIF_REALNAMES = 0x0020, + OPIF_SHOWNAMESONLY = 0x0040, + OPIF_SHOWRIGHTALIGNNAMES = 0x0080, + OPIF_SHOWPRESERVECASE = 0x0100, + OPIF_FINDFOLDERS = 0x0200, + OPIF_COMPAREFATTIME = 0x0400, + OPIF_EXTERNALGET = 0x0800, + OPIF_EXTERNALPUT = 0x1000, + OPIF_EXTERNALDELETE = 0x2000, + OPIF_EXTERNALMKDIR = 0x4000, + OPIF_USEATTRHIGHLIGHTING = 0x8000 +}; + + +enum OPENPLUGININFO_SORTMODES { + SM_DEFAULT,SM_UNSORTED,SM_NAME,SM_EXT,SM_MTIME,SM_CTIME, + SM_ATIME,SM_SIZE,SM_DESCR,SM_OWNER,SM_COMPRESSEDSIZE,SM_NUMLINKS +}; + + +struct KeyBarTitles +{ + char *Titles[12]; + char *CtrlTitles[12]; + char *AltTitles[12]; + char *ShiftTitles[12]; +}; + + +struct OpenPluginInfo +{ + int StructSize; + DWORD Flags; + char *HostFile; + char *CurDir; + char *Format; + char *PanelTitle; + struct InfoPanelLine *InfoLines; + int InfoLinesNumber; + char **DescrFiles; + int DescrFilesNumber; + struct PanelMode *PanelModesArray; + int PanelModesNumber; + int StartPanelMode; + int StartSortMode; + int StartSortOrder; + struct KeyBarTitles *KeyBar; + char *ShortcutData; +}; + +enum { + OPEN_DISKMENU, + OPEN_PLUGINSMENU, + OPEN_FINDLIST, + OPEN_SHORTCUT, + OPEN_COMMANDLINE, + OPEN_EDITOR, + OPEN_VIEWER +}; + +enum {PKF_CONTROL=1,PKF_ALT=2,PKF_SHIFT=4}; + +enum FAR_EVENTS { + FE_CHANGEVIEWMODE, + FE_REDRAW, + FE_IDLE, + FE_CLOSE, + FE_BREAK, + FE_COMMAND +}; + +enum OPERATION_MODES { + OPM_SILENT=1, + OPM_FIND=2, + OPM_VIEW=4, + OPM_EDIT=8, + OPM_TOPLEVEL=16, + OPM_DESCR=32 +}; + +#if defined(__BORLANDC__) && (__BORLANDC <= 0x520) + #pragma option -a. +#elif defined(__GNUC__) || (defined(__WATCOMC__) && (__WATCOMC__ < 1100)) + #pragma pack() +#else + #pragma pack(pop) +#endif + +#endif diff --git a/CPP/7zip/UI/Far/FarUtils.cpp b/CPP/7zip/UI/Far/FarUtils.cpp new file mode 100755 index 00000000..abbb6817 --- /dev/null +++ b/CPP/7zip/UI/Far/FarUtils.cpp @@ -0,0 +1,416 @@ +// FarUtils.cpp + +#include "StdAfx.h" + +#include "FarUtils.h" +#include "Common/DynamicBuffer.h" +#include "Common/StringConvert.h" +#include "Windows/Defs.h" +#include "Windows/Console.h" +#include "Windows/Error.h" + +using namespace NWindows; + +namespace NFar { + +CStartupInfo g_StartupInfo; + +void CStartupInfo::Init(const PluginStartupInfo &pluginStartupInfo, + const CSysString &pliginNameForRegestry) +{ + m_Data = pluginStartupInfo; + m_RegistryPath = pluginStartupInfo.RootKey; + m_RegistryPath += '\\'; + m_RegistryPath += pliginNameForRegestry; +} + +const char *CStartupInfo::GetMsgString(int messageId) +{ + return (const char*)m_Data.GetMsg(m_Data.ModuleNumber, messageId); +} + +int CStartupInfo::ShowMessage(unsigned int flags, + const char *helpTopic, const char **items, int numItems, int numButtons) +{ + return m_Data.Message(m_Data.ModuleNumber, flags, (char *)helpTopic, + (char **)items, numItems, numButtons); +} + +namespace NMessageID +{ + enum + { + kOk, + kCancel, + kWarning, + kError + }; +} + +int CStartupInfo::ShowMessage(const char *message) +{ + const char *messagesItems[]= { GetMsgString(NMessageID::kError), message, + GetMsgString(NMessageID::kOk) }; + return ShowMessage(FMSG_WARNING, NULL, messagesItems, + sizeof(messagesItems) / sizeof(messagesItems[0]), 1); +} + +int CStartupInfo::ShowMessage(int messageId) +{ + return ShowMessage(GetMsgString(messageId)); +} + +int CStartupInfo::ShowDialog(int X1, int Y1, int X2, int Y2, + const char *helpTopic, struct FarDialogItem *items, int numItems) +{ + return m_Data.Dialog(m_Data.ModuleNumber, X1, Y1, X2, Y2, (char *)helpTopic, + items, numItems); +} + +int CStartupInfo::ShowDialog(int sizeX, int sizeY, + const char *helpTopic, struct FarDialogItem *items, int numItems) +{ + return ShowDialog(-1, -1, sizeX, sizeY, helpTopic, items, numItems); +} + +inline static BOOL GetBOOLValue(bool v) { return (v? TRUE: FALSE); } + +void CStartupInfo::InitDialogItems(const CInitDialogItem *srcItems, + FarDialogItem *destItems, int numItems) +{ + for (int i = 0; i < numItems; i++) + { + const CInitDialogItem &srcItem = srcItems[i]; + FarDialogItem &destItem = destItems[i]; + + destItem.Type = srcItem.Type; + destItem.X1 = srcItem.X1; + destItem.Y1 = srcItem.Y1; + destItem.X2 = srcItem.X2; + destItem.Y2 = srcItem.Y2; + destItem.Focus = GetBOOLValue(srcItem.Focus); + if(srcItem.HistoryName != NULL) + destItem.History = srcItem.HistoryName; + else + destItem.Selected = GetBOOLValue(srcItem.Selected); + destItem.Flags = srcItem.Flags; + destItem.DefaultButton = GetBOOLValue(srcItem.DefaultButton); + + if(srcItem.DataMessageId < 0) + MyStringCopy(destItem.Data, srcItem.DataString); + else + MyStringCopy(destItem.Data, GetMsgString(srcItem.DataMessageId)); + + /* + if ((unsigned int)Init[i].Data < 0xFFF) + MyStringCopy(destItem.Data, GetMsg((unsigned int)srcItem.Data)); + else + MyStringCopy(destItem.Data,srcItem.Data); + */ + } +} + +// -------------------------------------------- + +HANDLE CStartupInfo::SaveScreen(int X1, int Y1, int X2, int Y2) +{ + return m_Data.SaveScreen(X1, Y1, X2, Y2); +} + +HANDLE CStartupInfo::SaveScreen() +{ + return SaveScreen(0, 0, -1, -1); +} + +void CStartupInfo::RestoreScreen(HANDLE handle) +{ + m_Data.RestoreScreen(handle); +} + +const char kRegestryKeyDelimiter = '\''; + +CSysString CStartupInfo::GetFullKeyName(const CSysString &keyName) const +{ + return (keyName.IsEmpty()) ? m_RegistryPath: + (m_RegistryPath + kRegestryKeyDelimiter + keyName); +} + + +LONG CStartupInfo::CreateRegKey(HKEY parentKey, + const CSysString &keyName, NRegistry::CKey &destKey) const +{ + return destKey.Create(parentKey, GetFullKeyName(keyName)); +} + +LONG CStartupInfo::OpenRegKey(HKEY parentKey, + const CSysString &keyName, NRegistry::CKey &destKey) const +{ + return destKey.Open(parentKey, GetFullKeyName(keyName)); +} + +void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, LPCTSTR value) const +{ + NRegistry::CKey regKey; + CreateRegKey(parentKey, keyName, regKey); + regKey.SetValue(valueName, value); +} + +void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, UINT32 value) const +{ + NRegistry::CKey regKey; + CreateRegKey(parentKey, keyName, regKey); + regKey.SetValue(valueName, value); +} + +void CStartupInfo::SetRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, bool value) const +{ + NRegistry::CKey regKey; + CreateRegKey(parentKey, keyName, regKey); + regKey.SetValue(valueName, value); +} + +CSysString CStartupInfo::QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, const CSysString &valueDefault) const +{ + NRegistry::CKey regKey; + if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS) + return valueDefault; + + CSysString value; + if(regKey.QueryValue(valueName, value) != ERROR_SUCCESS) + return valueDefault; + + return value; +} + +UINT32 CStartupInfo::QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, UINT32 valueDefault) const +{ + NRegistry::CKey regKey; + if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS) + return valueDefault; + + UINT32 value; + if(regKey.QueryValue(valueName, value) != ERROR_SUCCESS) + return valueDefault; + + return value; +} + +bool CStartupInfo::QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, bool valueDefault) const +{ + NRegistry::CKey regKey; + if (OpenRegKey(parentKey, keyName, regKey) != ERROR_SUCCESS) + return valueDefault; + + bool value; + if(regKey.QueryValue(valueName, value) != ERROR_SUCCESS) + return valueDefault; + + return value; +} + +bool CStartupInfo::Control(HANDLE pluginHandle, int command, void *param) +{ + return BOOLToBool(m_Data.Control(pluginHandle, command, param)); +} + +bool CStartupInfo::ControlRequestActivePanel(int command, void *param) +{ + return Control(INVALID_HANDLE_VALUE, command, param); +} + +bool CStartupInfo::ControlGetActivePanelInfo(PanelInfo &panelInfo) +{ + return ControlRequestActivePanel(FCTL_GETPANELINFO, &panelInfo); +} + +bool CStartupInfo::ControlSetSelection(const PanelInfo &panelInfo) +{ + return ControlRequestActivePanel(FCTL_SETSELECTION, (void *)&panelInfo); +} + +bool CStartupInfo::ControlGetActivePanelCurrentItemInfo( + PluginPanelItem &pluginPanelItem) +{ + PanelInfo panelInfo; + if(!ControlGetActivePanelInfo(panelInfo)) + return false; + if(panelInfo.ItemsNumber <= 0) + throw "There are no items"; + pluginPanelItem = panelInfo.PanelItems[panelInfo.CurrentItem]; + return true; +} + +bool CStartupInfo::ControlGetActivePanelSelectedOrCurrentItems( + CObjectVector &pluginPanelItems) +{ + pluginPanelItems.Clear(); + PanelInfo panelInfo; + if(!ControlGetActivePanelInfo(panelInfo)) + return false; + if(panelInfo.ItemsNumber <= 0) + throw "There are no items"; + if (panelInfo.SelectedItemsNumber == 0) + pluginPanelItems.Add(panelInfo.PanelItems[panelInfo.CurrentItem]); + else + for (int i = 0; i < panelInfo.SelectedItemsNumber; i++) + pluginPanelItems.Add(panelInfo.SelectedItems[i]); + return true; +} + +bool CStartupInfo::ControlClearPanelSelection() +{ + PanelInfo panelInfo; + if(!ControlGetActivePanelInfo(panelInfo)) + return false; + for (int i = 0; i < panelInfo.ItemsNumber; i++) + panelInfo.PanelItems[i].Flags &= ~PPIF_SELECTED; + return ControlSetSelection(panelInfo); +} + +//////////////////////////////////////////////// +// menu function + +int CStartupInfo::Menu( + int x, + int y, + int maxHeight, + unsigned int flags, + const char *title, + const char *aBottom, + const char *helpTopic, + int *breakKeys, + int *breakCode, + struct FarMenuItem *items, + int numItems) +{ + return m_Data.Menu(m_Data.ModuleNumber, x, y, maxHeight, flags, (char *)title, + (char *)aBottom, (char *)helpTopic, breakKeys, breakCode, items, numItems); +} + +int CStartupInfo::Menu( + unsigned int flags, + const char *title, + const char *helpTopic, + struct FarMenuItem *items, + int numItems) +{ + return Menu(-1, -1, 0, flags, title, NULL, helpTopic, NULL, + NULL, items, numItems); +} + +int CStartupInfo::Menu( + unsigned int flags, + const char *title, + const char *helpTopic, + const CSysStringVector &items, + int selectedItem) +{ + CRecordVector farMenuItems; + for(int i = 0; i < items.Size(); i++) + { + FarMenuItem item; + item.Checked = 0; + item.Separator = 0; + item.Selected = (i == selectedItem); + AString reducedString = items[i].Left(sizeof(item.Text) / sizeof(item.Text[0]) - 1); + MyStringCopy(item.Text, (const char *)reducedString); + farMenuItems.Add(item); + } + return Menu(flags, title, helpTopic, &farMenuItems.Front(), farMenuItems.Size()); +} + + +////////////////////////////////// +// CScreenRestorer + +CScreenRestorer::~CScreenRestorer() +{ + Restore(); +} +void CScreenRestorer::Save() +{ + if(m_Saved) + return; + m_HANDLE = g_StartupInfo.SaveScreen(); + m_Saved = true; +} + +void CScreenRestorer::Restore() +{ + if(m_Saved) + { + g_StartupInfo.RestoreScreen(m_HANDLE); + m_Saved = false; + } +}; + +static AString DWORDToString(DWORD number) +{ + char buffer[32]; + ultoa(number, buffer, 10); + return buffer; +} + +void PrintErrorMessage(const char *message, int code) +{ + CSysString tmp = message; + tmp += " #"; + tmp += DWORDToString(code); + g_StartupInfo.ShowMessage(tmp); +} + +void PrintErrorMessage(const char *message, const char *text) +{ + CSysString tmp = message; + tmp += ": "; + tmp += text; + g_StartupInfo.ShowMessage(tmp); +} + +bool WasEscPressed() +{ + NConsole::CIn inConsole; + HANDLE handle = ::GetStdHandle(STD_INPUT_HANDLE); + if(handle == INVALID_HANDLE_VALUE) + return true; + inConsole.Attach(handle); + for (;;) + { + DWORD numEvents; + if(!inConsole.GetNumberOfEvents(numEvents)) + return true; + if(numEvents == 0) + return false; + + INPUT_RECORD event; + if(!inConsole.ReadEvent(event, numEvents)) + return true; + if (event.EventType == KEY_EVENT && + event.Event.KeyEvent.bKeyDown && + event.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) + return true; + } +} + +void ShowErrorMessage(DWORD errorCode) +{ + AString message; + NError::MyFormatMessage(errorCode, message); + message.Replace("\x0D", ""); + message.Replace("\x0A", " "); + g_StartupInfo.ShowMessage(SystemStringToOemString(message)); + +} + +void ShowLastErrorMessage() +{ + ShowErrorMessage(::GetLastError()); +} + +} diff --git a/CPP/7zip/UI/Far/FarUtils.h b/CPP/7zip/UI/Far/FarUtils.h new file mode 100755 index 00000000..4fba193d --- /dev/null +++ b/CPP/7zip/UI/Far/FarUtils.h @@ -0,0 +1,185 @@ +// FarUtils.h + +#ifndef __FARUTILS_H +#define __FARUTILS_H + +#include "FarPlugin.h" +#include "Common/String.h" +#include "Common/Vector.h" +#include "Windows/Registry.h" + +namespace NFar { + +namespace NFileOperationReturnCode +{ + enum EEnum + { + kInterruptedByUser = -1, + kError = 0, + kSuccess = 1 + }; +} + +namespace NEditorReturnCode +{ + enum EEnum + { + kOpenError = 0, + kFileWasChanged = 1, + kFileWasNotChanged = 2, + kInterruptedByUser = 3 + }; +} + +struct CInitDialogItem +{ + DialogItemTypes Type; + int X1,Y1,X2,Y2; + bool Focus; + bool Selected; + unsigned int Flags; //FarDialogItemFlags Flags; + bool DefaultButton; + int DataMessageId; + const char *DataString; + const char *HistoryName; + // void InitToFarDialogItem(struct FarDialogItem &anItemDest); +}; + +class CStartupInfo +{ + PluginStartupInfo m_Data; + CSysString m_RegistryPath; + + CSysString GetFullKeyName(const CSysString &keyName) const; + LONG CreateRegKey(HKEY parentKey, + const CSysString &keyName, NWindows::NRegistry::CKey &destKey) const; + LONG OpenRegKey(HKEY parentKey, + const CSysString &keyName, NWindows::NRegistry::CKey &destKey) const; + +public: + void Init(const PluginStartupInfo &pluginStartupInfo, + const CSysString &pliginNameForRegestry); + const char *GetMsgString(int messageId); + int ShowMessage(unsigned int flags, const char *helpTopic, + const char **items, int numItems, int numButtons); + int ShowMessage(const char *message); + int ShowMessage(int messageId); + + int ShowDialog(int X1, int Y1, int X2, int Y2, + const char *helpTopic, struct FarDialogItem *items, int numItems); + int ShowDialog(int sizeX, int sizeY, + const char *helpTopic, struct FarDialogItem *items, int numItems); + + void InitDialogItems(const CInitDialogItem *srcItems, + FarDialogItem *destItems, int numItems); + + HANDLE SaveScreen(int X1, int Y1, int X2, int Y2); + HANDLE SaveScreen(); + void RestoreScreen(HANDLE handle); + + void SetRegKeyValue(HKEY parentKey, const CSysString &keyName, + const LPCTSTR valueName, LPCTSTR value) const; + void SetRegKeyValue(HKEY hRoot, const CSysString &keyName, + const LPCTSTR valueName, UINT32 value) const; + void SetRegKeyValue(HKEY hRoot, const CSysString &keyName, + const LPCTSTR valueName, bool value) const; + + CSysString QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, const CSysString &valueDefault) const; + + UINT32 QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, UINT32 valueDefault) const; + + bool QueryRegKeyValue(HKEY parentKey, const CSysString &keyName, + LPCTSTR valueName, bool valueDefault) const; + + bool Control(HANDLE plugin, int command, void *param); + bool ControlRequestActivePanel(int command, void *param); + bool ControlGetActivePanelInfo(PanelInfo &panelInfo); + bool ControlSetSelection(const PanelInfo &panelInfo); + bool ControlGetActivePanelCurrentItemInfo(PluginPanelItem &pluginPanelItem); + bool ControlGetActivePanelSelectedOrCurrentItems( + CObjectVector &pluginPanelItems); + + bool ControlClearPanelSelection(); + + int Menu( + int x, + int y, + int maxHeight, + unsigned int flags, + const char *title, + const char *aBottom, + const char *helpTopic, + int *breakKeys, + int *breakCode, + FarMenuItem *items, + int numItems); + int Menu( + unsigned int flags, + const char *title, + const char *helpTopic, + FarMenuItem *items, + int numItems); + + int Menu( + unsigned int flags, + const char *title, + const char *helpTopic, + const CSysStringVector &items, + int selectedItem); + + int Editor(const char *fileName, const char *title, + int X1, int Y1, int X2, int Y2, DWORD flags, int startLine, int startChar) + { return m_Data.Editor((char *)fileName, (char *)title, X1, Y1, X2, Y2, + flags, startLine, startChar); } + int Editor(const char *fileName) + { return Editor(fileName, NULL, 0, 0, -1, -1, 0, -1, -1); } + + int Viewer(const char *fileName, const char *title, + int X1, int Y1, int X2, int Y2, DWORD flags) + { return m_Data.Viewer((char *)fileName, (char *)title, X1, Y1, X2, Y2, flags); } + int Viewer(const char *fileName) + { return Viewer(fileName, NULL, 0, 0, -1, -1, VF_NONMODAL); } + +}; + +class CScreenRestorer +{ + bool m_Saved; + HANDLE m_HANDLE; +public: + CScreenRestorer(): m_Saved(false){}; + ~CScreenRestorer(); + void Save(); + void Restore(); +}; + + +extern CStartupInfo g_StartupInfo; + +void PrintErrorMessage(const char *message, int code); +void PrintErrorMessage(const char *message, const char *aText); + +#define MY_TRY_BEGIN try\ + { + +#define MY_TRY_END1(x) }\ + catch(int n) { PrintErrorMessage(x, n); return; }\ + catch(const CSysString &s) { PrintErrorMessage(x, s); return; }\ + catch(const char *s) { PrintErrorMessage(x, s); return; }\ + catch(...) { g_StartupInfo.ShowMessage(x); return; } + +#define MY_TRY_END2(x, y) }\ + catch(int n) { PrintErrorMessage(x, n); return y; }\ + catch(const CSysString &s) { PrintErrorMessage(x, s); return y; }\ + catch(const char *s) { PrintErrorMessage(x, s); return y; }\ + catch(...) { g_StartupInfo.ShowMessage(x); return y; } + +bool WasEscPressed(); +void ShowErrorMessage(DWORD errorCode); +void ShowLastErrorMessage(); + +} + +#endif diff --git a/CPP/7zip/UI/Far/Main.cpp b/CPP/7zip/UI/Far/Main.cpp new file mode 100755 index 00000000..a7994b6d --- /dev/null +++ b/CPP/7zip/UI/Far/Main.cpp @@ -0,0 +1,622 @@ +// Test Align for updating !!!!!!!!!!!!!!!!!! + +#include "StdAfx.h" + +// #include +#include + +#include "Plugin.h" + +#include "Common/Wildcard.h" +#include "Common/DynamicBuffer.h" +#include "Common/StringConvert.h" +#include "Common/Defs.h" + +#include "Windows/FileFind.h" +#include "Windows/FileIO.h" +#include "Windows/FileDir.h" +#include "Windows/Defs.h" + +#include "../../IPassword.h" +#include "../../Common/FileStreams.h" + +#include "../Common/DefaultName.h" +#include "../Common/OpenArchive.h" +#include "../Agent/Agent.h" + +#include "ProgressBox.h" +#include "FarUtils.h" +#include "Messages.h" + +using namespace NWindows; +using namespace NFar; + +static const char *kCommandPrefix = "7-zip"; + +static const int kDescriptionMaxSize = 256; + +static const char *kRegisrtryMainKeyName = ""; + +static const char *kRegisrtryValueNameEnabled = "UsedByDefault3"; +static bool kPluginEnabledDefault = true; + +static const char *kHelpTopicConfig = "Config"; + +extern "C" +{ + void WINAPI SetStartupInfo(struct PluginStartupInfo *info); + HANDLE WINAPI OpenFilePlugin(char *name, const unsigned char *Data, + unsigned int DataSize); + HANDLE WINAPI OpenPlugin(int openFrom, int item); + void WINAPI ClosePlugin(HANDLE plugin); + int WINAPI GetFindData(HANDLE plugin, struct PluginPanelItem **panelItems, + int *itemsNumber, int OpMode); + void WINAPI FreeFindData(HANDLE plugin, struct PluginPanelItem *panelItems, + int itemsNumber); + int WINAPI GetFiles(HANDLE plugin, struct PluginPanelItem *panelItems, + int itemsNumber, int move, char *destPath, int opMode); + int WINAPI SetDirectory(HANDLE plugin, char *dir, int opMode); + void WINAPI GetPluginInfo(struct PluginInfo *info); + int WINAPI Configure(int itemNumber); + void WINAPI GetOpenPluginInfo(HANDLE plugin, struct OpenPluginInfo *info); + int WINAPI PutFiles(HANDLE plugin, struct PluginPanelItem *panelItems, + int itemsNumber, int move, int opMode); + int WINAPI DeleteFiles(HANDLE plugin, PluginPanelItem *panelItems, + int itemsNumber, int opMode); + int WINAPI ProcessKey(HANDLE plugin, int key, unsigned int controlState); +}; + +HINSTANCE g_hInstance; +#ifndef _UNICODE +bool g_IsNT = false; +static bool IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} +#endif + +BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID) +{ + if (dwReason == DLL_PROCESS_ATTACH) + { + g_hInstance = hInstance; + #ifndef _UNICODE + g_IsNT = IsItWindowsNT(); + #endif + } + return TRUE; +} + +static struct COptions +{ + bool Enabled; +} g_Options; + +static const char *kPliginNameForRegestry = "7-ZIP"; + +// #define MY_TRY_BEGIN MY_TRY_BEGIN NCOM::CComInitializer aComInitializer; + +void WINAPI SetStartupInfo(struct PluginStartupInfo *info) +{ + MY_TRY_BEGIN; + g_StartupInfo.Init(*info, kPliginNameForRegestry); + g_Options.Enabled = g_StartupInfo.QueryRegKeyValue( + HKEY_CURRENT_USER, kRegisrtryMainKeyName, + kRegisrtryValueNameEnabled, kPluginEnabledDefault); + MY_TRY_END1("SetStartupInfo"); +} + +class COpenArchiveCallback: + public IArchiveOpenCallback, + public IArchiveOpenVolumeCallback, + public IProgress, + public ICryptoGetTextPassword, + public CMyUnknownImp +{ + DWORD m_StartTickValue; + bool m_MessageBoxIsShown; + CMessageBox *m_MessageBox; + UINT64 m_NumFiles; + UINT64 m_NumFilesMax; + UINT64 m_NumFilesPrev; + bool m_NumFilesDefined; + UINT64 m_NumBytes; + bool m_NumBytesDefined; + UINT32 m_PrevTickCount; + + NWindows::NFile::NFind::CFileInfoW _fileInfo; +public: + bool PasswordIsDefined; + UString Password; + + UString _folderPrefix; + +public: + MY_UNKNOWN_IMP3( + IArchiveOpenVolumeCallback, + IProgress, + ICryptoGetTextPassword + ) + + // IProgress + STDMETHOD(SetTotal)(UINT64 total); + STDMETHOD(SetCompleted)(const UINT64 *aCompleteValue); + + // IArchiveOpenCallback + STDMETHOD(SetTotal)(const UINT64 *numFiles, const UINT64 *numBytes); + STDMETHOD(SetCompleted)(const UINT64 *numFiles, const UINT64 *numBytes); + + // IArchiveOpenVolumeCallback + STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value); + STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream); + + // ICryptoGetTextPassword + STDMETHOD(CryptoGetTextPassword)(BSTR *password); + + void Init(CMessageBox *messageBox) + { + PasswordIsDefined = false; + + m_NumFilesMax = 0; + m_MessageBoxIsShown = false; + m_PrevTickCount = GetTickCount(); + m_MessageBox = messageBox; + } + void ShowMessage(const UINT64 *completed); + + void LoadFileInfo(const UString &folderPrefix, + const UString &fileName) + { + _folderPrefix = folderPrefix; + if (!NWindows::NFile::NFind::FindFile(_folderPrefix + fileName, _fileInfo)) + throw 1; + } +}; + +void COpenArchiveCallback::ShowMessage(const UINT64 *completed) +{ + UINT32 currentTime = GetTickCount(); + if (!m_MessageBoxIsShown) + { + if (currentTime - m_PrevTickCount < 400) + return; + m_MessageBox->Init(g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kReading), 2, 30); + m_MessageBoxIsShown = true; + } + else + { + if (currentTime - m_PrevTickCount < 200) + return; + } + m_PrevTickCount = currentTime; + char aMessage[256]; + sprintf(aMessage, "%5I64u", m_NumFilesMax); + char aMessage2[256]; + aMessage2[0] = '\0'; + if (completed != NULL) + sprintf(aMessage2, "%5I64u", *completed); + const char *aMessages[2] = + {aMessage, aMessage2 }; + m_MessageBox->ShowProcessMessages(aMessages); +} + +STDMETHODIMP COpenArchiveCallback::SetTotal(const UINT64 *numFiles, const UINT64 *numBytes) +{ + if (WasEscPressed()) + return E_ABORT; + m_NumFilesDefined = (numFiles != NULL); + if (m_NumFilesDefined) + m_NumFiles = *numFiles; + m_NumBytesDefined = (numBytes != NULL); + if (m_NumBytesDefined) + m_NumBytes = *numBytes; + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::SetCompleted(const UINT64 *numFiles, const UINT64 * /* numBytes */) +{ + if (WasEscPressed()) + return E_ABORT; + if (numFiles == NULL) + return S_OK; + m_NumFilesMax = *numFiles; + // if (*numFiles % 100 != 0) + // return S_OK; + ShowMessage(NULL); + return S_OK; +} + + +STDMETHODIMP COpenArchiveCallback::SetTotal(const UINT64 /* total */) +{ + if (WasEscPressed()) + return E_ABORT; + /* + aNumFilesDefined = (numFiles != NULL); + if (aNumFilesDefined) + aNumFiles = *numFiles; + aNumBytesDefined = (numBytes != NULL); + if (aNumBytesDefined) + aNumBytes = *numBytes; + */ + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::SetCompleted(const UINT64 *completed) +{ + if (WasEscPressed()) + return E_ABORT; + if (completed == NULL) + return S_OK; + // if (*completed % 100 != 0) + // return S_OK; + ShowMessage(completed); + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::GetStream(const wchar_t *name, + IInStream **inStream) +{ + if (WasEscPressed()) + return E_ABORT; + *inStream = NULL; + UString fullPath = _folderPrefix + name; + if (!NWindows::NFile::NFind::FindFile(fullPath, _fileInfo)) + return S_FALSE; + if (_fileInfo.IsDirectory()) + return S_FALSE; + CInFileStream *inFile = new CInFileStream; + CMyComPtr inStreamTemp = inFile; + if (!inFile->Open(fullPath)) + return ::GetLastError(); + *inStream = inStreamTemp.Detach(); + return S_OK; +} + + +STDMETHODIMP COpenArchiveCallback::GetProperty(PROPID propID, PROPVARIANT *value) +{ + NWindows::NCOM::CPropVariant propVariant; + switch(propID) + { + case kpidName: + propVariant = GetUnicodeString(_fileInfo.Name, CP_OEMCP); + break; + case kpidIsFolder: + propVariant = _fileInfo.IsDirectory(); + break; + case kpidSize: + propVariant = _fileInfo.Size; + break; + case kpidAttributes: + propVariant = (UINT32)_fileInfo.Attributes; + break; + case kpidLastAccessTime: + propVariant = _fileInfo.LastAccessTime; + break; + case kpidCreationTime: + propVariant = _fileInfo.CreationTime; + break; + case kpidLastWriteTime: + propVariant = _fileInfo.LastWriteTime; + break; + } + propVariant.Detach(value); + return S_OK; +} + +HRESULT GetPassword(UString &password) +{ + if (WasEscPressed()) + return E_ABORT; + password.Empty(); + CInitDialogItem initItems[]= + { + { DI_DOUBLEBOX, 3, 1, 72, 4, false, false, 0, false, NMessageID::kGetPasswordTitle, NULL, NULL }, + { DI_TEXT, 5, 2, 0, 0, false, false, DIF_SHOWAMPERSAND, false, NMessageID::kEnterPasswordForFile, NULL, NULL }, + { DI_PSWEDIT, 5, 3, 70, 3, true, false, 0, true, -1, "", NULL } + }; + + const int kNumItems = sizeof(initItems)/sizeof(initItems[0]); + FarDialogItem dialogItems[kNumItems]; + g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumItems); + + // sprintf(DialogItems[1].Data,GetMsg(MGetPasswordForFile),FileName); + if (g_StartupInfo.ShowDialog(76, 6, NULL, dialogItems, kNumItems) < 0) + return (E_ABORT); + + AString oemPassword = dialogItems[2].Data; + password = MultiByteToUnicodeString(oemPassword, CP_OEMCP); + return S_OK; +} + +STDMETHODIMP COpenArchiveCallback::CryptoGetTextPassword(BSTR *password) +{ + if (!PasswordIsDefined) + { + RINOK(GetPassword(Password)); + PasswordIsDefined = true; + } + CMyComBSTR temp = Password; + *password = temp.Detach(); + return S_OK; +} + +/* +HRESULT OpenArchive(const CSysString &fileName, + IInFolderArchive **archiveHandlerResult, + CArchiverInfo &archiverInfoResult, + UString &defaultName, + IArchiveOpenCallback *openArchiveCallback) +{ + HRESULT OpenArchive(const CSysString &fileName, + #ifndef EXCLUDE_COM + HMODULE *module, + #endif + IInArchive **archive, + CArchiverInfo &archiverInfoResult, + IArchiveOpenCallback *openArchiveCallback); +} +*/ + +static HANDLE MyOpenFilePlugin(const char *name) +{ + UINT codePage = ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; + + UString normalizedName = GetUnicodeString(name, codePage); + normalizedName.Trim(); + UString fullName; + int fileNamePartStartIndex; + NFile::NDirectory::MyGetFullPathName(normalizedName, fullName, fileNamePartStartIndex); + NFile::NFind::CFileInfoW fileInfo; + if (!NFile::NFind::FindFile(fullName, fileInfo)) + return INVALID_HANDLE_VALUE; + if (fileInfo.IsDirectory()) + return INVALID_HANDLE_VALUE; + + + CMyComPtr archiveHandler; + + // CArchiverInfo archiverInfoResult; + // ::OutputDebugString("before OpenArchive\n"); + + COpenArchiveCallback *openArchiveCallbackSpec = new COpenArchiveCallback; + + CMyComPtr openArchiveCallback = openArchiveCallbackSpec; + + // if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0) + CScreenRestorer screenRestorer; + CMessageBox m_MessageBox; + { + screenRestorer.Save(); + } + openArchiveCallbackSpec->Init(&m_MessageBox); + openArchiveCallbackSpec->LoadFileInfo( + fullName.Left(fileNamePartStartIndex), + fullName.Mid(fileNamePartStartIndex)); + + // ::OutputDebugString("before OpenArchive\n"); + + archiveHandler = new CAgent; + CMyComBSTR archiveType; + HRESULT result = archiveHandler->Open( + GetUnicodeString(fullName, CP_OEMCP), &archiveType, openArchiveCallback); + /* + HRESULT result = ::OpenArchive(fullName, &archiveHandler, + archiverInfoResult, defaultName, openArchiveCallback); + */ + if (result != S_OK) + { + if (result == E_ABORT) + return (HANDLE)-2; + return INVALID_HANDLE_VALUE; + } + + // ::OutputDebugString("after OpenArchive\n"); + + CPlugin *plugin = new CPlugin( + fullName, + // defaultName, + archiveHandler, + (const wchar_t *)archiveType + ); + if (plugin == NULL) + return(INVALID_HANDLE_VALUE); + plugin->PasswordIsDefined = openArchiveCallbackSpec->PasswordIsDefined; + plugin->Password = openArchiveCallbackSpec->Password; + + return (HANDLE)(plugin); +} + +HANDLE WINAPI OpenFilePlugin(char *name, + const unsigned char * /* data */, unsigned int /* dataSize */) +{ + MY_TRY_BEGIN; + if (name == NULL || (!g_Options.Enabled)) + { + // if (!Opt.ProcessShiftF1) + return(INVALID_HANDLE_VALUE); + } + return MyOpenFilePlugin(name); + MY_TRY_END2("OpenFilePlugin", INVALID_HANDLE_VALUE); +} + +HANDLE WINAPI OpenPlugin(int openFrom, int item) +{ + MY_TRY_BEGIN; + if(openFrom == OPEN_COMMANDLINE) + { + CSysString fileName = (const char *)item; + if(fileName.IsEmpty()) + return INVALID_HANDLE_VALUE; + if (fileName.Length() >= 2 && + fileName[0] == '\"' && fileName[fileName.Length() - 1] == '\"') + fileName = fileName.Mid(1, fileName.Length() - 2); + + return MyOpenFilePlugin(fileName); + } + if(openFrom == OPEN_PLUGINSMENU) + { + switch(item) + { + case 0: + { + PluginPanelItem pluginPanelItem; + if(!g_StartupInfo.ControlGetActivePanelCurrentItemInfo(pluginPanelItem)) + throw 142134; + return MyOpenFilePlugin(pluginPanelItem.FindData.cFileName); + } + case 1: + { + CObjectVector pluginPanelItem; + if(!g_StartupInfo.ControlGetActivePanelSelectedOrCurrentItems(pluginPanelItem)) + throw 142134; + if (CompressFiles(pluginPanelItem) == S_OK) + { + int t = g_StartupInfo.ControlClearPanelSelection(); + g_StartupInfo.ControlRequestActivePanel(FCTL_UPDATEPANEL, NULL); + g_StartupInfo.ControlRequestActivePanel(FCTL_REDRAWPANEL, NULL); + g_StartupInfo.ControlRequestActivePanel(FCTL_UPDATEANOTHERPANEL, NULL); + g_StartupInfo.ControlRequestActivePanel(FCTL_REDRAWANOTHERPANEL, NULL); + } + return INVALID_HANDLE_VALUE; + } + default: + throw 4282215; + } + } + return INVALID_HANDLE_VALUE; + MY_TRY_END2("OpenPlugin", INVALID_HANDLE_VALUE); +} + +void WINAPI ClosePlugin(HANDLE plugin) +{ + MY_TRY_BEGIN; + delete (CPlugin *)plugin; + MY_TRY_END1("ClosePlugin"); +} + +int WINAPI GetFindData(HANDLE plugin, struct PluginPanelItem **panelItems, + int *itemsNumber,int opMode) +{ + MY_TRY_BEGIN; + return(((CPlugin *)plugin)->GetFindData(panelItems, itemsNumber, opMode)); + MY_TRY_END2("GetFindData", FALSE); +} + +void WINAPI FreeFindData(HANDLE plugin, struct PluginPanelItem *panelItems, + int itemsNumber) +{ + MY_TRY_BEGIN; + ((CPlugin *)plugin)->FreeFindData(panelItems, itemsNumber); + MY_TRY_END1("FreeFindData"); +} + +int WINAPI GetFiles(HANDLE plugin, struct PluginPanelItem *panelItems, + int itemsNumber, int move, char *destPath, int opMode) +{ + MY_TRY_BEGIN; + return(((CPlugin *)plugin)->GetFiles(panelItems, itemsNumber, move, destPath, opMode)); + MY_TRY_END2("GetFiles", NFileOperationReturnCode::kError); +} + +int WINAPI SetDirectory(HANDLE plugin, char *dir, int opMode) +{ + MY_TRY_BEGIN; + return(((CPlugin *)plugin)->SetDirectory(dir, opMode)); + MY_TRY_END2("SetDirectory", FALSE); +} + +void WINAPI GetPluginInfo(struct PluginInfo *info) +{ + MY_TRY_BEGIN; + + info->StructSize = sizeof(*info); + info->Flags = 0; + info->DiskMenuStrings = NULL; + info->DiskMenuNumbers = NULL; + info->DiskMenuStringsNumber = 0; + static const char *pluginMenuStrings[2]; + pluginMenuStrings[0] = g_StartupInfo.GetMsgString(NMessageID::kOpenArchiveMenuString); + pluginMenuStrings[1] = g_StartupInfo.GetMsgString(NMessageID::kCreateArchiveMenuString); + info->PluginMenuStrings = (char **)pluginMenuStrings; + info->PluginMenuStringsNumber = 2; + static const char *pluginCfgStrings[1]; + pluginCfgStrings[0] = g_StartupInfo.GetMsgString(NMessageID::kOpenArchiveMenuString); + info->PluginConfigStrings = (char **)pluginCfgStrings; + info->PluginConfigStringsNumber = sizeof(pluginCfgStrings) / sizeof(pluginCfgStrings[0]); + info->CommandPrefix = (char *)kCommandPrefix; + MY_TRY_END1("GetPluginInfo"); +} + +int WINAPI Configure(int itemNumber) +{ + MY_TRY_BEGIN; + + const int kEnabledCheckBoxIndex = 1; + + const int kYSize = 7; + + struct CInitDialogItem initItems[]= + { + { DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kConfigTitle, NULL, NULL }, + { DI_CHECKBOX, 5, 2, 0, 0, true, g_Options.Enabled, 0, false, NMessageID::kConfigPluginEnabled, NULL, NULL }, + { DI_TEXT, 5, 3, 0, 0, false, false, DIF_BOXCOLOR | DIF_SEPARATOR, false, -1, "", NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kOk, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL }, + }; + + const int kNumDialogItems = sizeof(initItems) / sizeof(initItems[0]); + const int kOkButtonIndex = kNumDialogItems - 2; + + FarDialogItem dialogItems[kNumDialogItems]; + g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems); + + int askCode = g_StartupInfo.ShowDialog(76, kYSize, + kHelpTopicConfig, dialogItems, kNumDialogItems); + + if (askCode != kOkButtonIndex) + return (FALSE); + + g_Options.Enabled = BOOLToBool(dialogItems[kEnabledCheckBoxIndex].Selected); + + g_StartupInfo.SetRegKeyValue(HKEY_CURRENT_USER, kRegisrtryMainKeyName, + kRegisrtryValueNameEnabled, g_Options.Enabled); + return(TRUE); + MY_TRY_END2("Configure", FALSE); +} + +void WINAPI GetOpenPluginInfo(HANDLE plugin,struct OpenPluginInfo *info) +{ + MY_TRY_BEGIN; + ((CPlugin *)plugin)->GetOpenPluginInfo(info); + MY_TRY_END1("GetOpenPluginInfo"); +} + +int WINAPI PutFiles(HANDLE plugin, struct PluginPanelItem *panelItems, + int itemsNumber, int move, int opMode) +{ + MY_TRY_BEGIN; + return(((CPlugin *)plugin)->PutFiles(panelItems, itemsNumber, move, opMode)); + MY_TRY_END2("PutFiles", NFileOperationReturnCode::kError); +} + +int WINAPI DeleteFiles(HANDLE plugin, PluginPanelItem *panelItems, + int itemsNumber, int opMode) +{ + MY_TRY_BEGIN; + return(((CPlugin *)plugin)->DeleteFiles(panelItems, itemsNumber, opMode)); + MY_TRY_END2("DeleteFiles", FALSE); +} + +int WINAPI ProcessKey(HANDLE plugin, int key, unsigned int controlState) +{ + MY_TRY_BEGIN; + return (((CPlugin *)plugin)->ProcessKey(key, controlState)); + MY_TRY_END2("ProcessKey", FALSE); +} diff --git a/CPP/7zip/UI/Far/Messages.h b/CPP/7zip/UI/Far/Messages.h new file mode 100755 index 00000000..8b6e2a49 --- /dev/null +++ b/CPP/7zip/UI/Far/Messages.h @@ -0,0 +1,152 @@ +// SevenZip/ Messages.h + +#ifndef __SEVENZIP_MESSAGES_H +#define __SEVENZIP_MESSAGES_H + +namespace NMessageID { + +enum EEnum +{ + kOk, + kCancel, + + kWarning, + kError, + + kArchiveType, + + kProperties, + + kYes, + kNo, + + kName, + kExtension, + kIsFolder, + kSize, + kPackedSize, + kAttributes, + kCreationTime, + kLastAccessTime, + kLastWriteTime, + kSolid, + kCommented, + kEncrypted, + kSplitBefore, + kSplitAfter, + kDictionarySize, + kCRC, + kType, + kAnti, + kMethod, + kHostOS, + kFileSystem, + kUser, + kGroup, + kBlock, + kComment, + kPosition, + + kGetPasswordTitle, + kEnterPasswordForFile, + + kExtractTitle, + kExtractTo, + + kExtractPathMode, + kExtractPathFull, + kExtractPathCurrent, + kExtractPathNo, + + kExtractOwerwriteMode, + kExtractOwerwriteAsk, + kExtractOwerwritePrompt, + kExtractOwerwriteSkip, + kExtractOwerwriteAutoRename, + kExtractOwerwriteAutoRenameExisting, + + kExtractFilesMode, + kExtractFilesSelected, + kExtractFilesAll, + + kExtractPassword, + + kExtractExtract, + kExtractCancel, + + kExtractCanNotOpenOutputFile, + + kExtractUnsupportedMethod, + kExtractCRCFailed, + kExtractDataError, + + kOverwriteTitle, + kOverwriteMessage1, + kOverwriteMessageWouldYouLike, + kOverwriteMessageWithtTisOne, + + kOverwriteBytes, + kOverwriteModifiedOn, + + kOverwriteYes, + kOverwriteYesToAll, + kOverwriteNo, + kOverwriteNoToAll, + kOverwriteAutoRename, + kOverwriteCancel, + + kUpdateNotSupportedForThisArchive, + + kDeleteTitle, + kDeleteFile, + kDeleteFiles, + kDeleteNumberOfFiles, + kDeleteDelete, + kDeleteCancel, + + kUpdateTitle, + kUpdateAddToArchive, + + kUpdateMethod, + kUpdateMethodStore, + kUpdateMethodFastest, + kUpdateMethodFast, + kUpdateMethodNormal, + kUpdateMethodMaximum, + kUpdateMethodUltra, + + kUpdateMode, + kUpdateModeAdd, + kUpdateModeUpdate, + kUpdateModeFreshen, + kUpdateModeSynchronize, + + kUpdateAdd, + kUpdateSelectArchiver, + + kUpdateSelectArchiverMenuTitle, + + // kArcReadFiles, + + kWaitTitle, + + kReading, + kExtracting, + kDeleting, + kUpdating, + + // kReadingList, + + kMoveIsNotSupported, + + kOpenArchiveMenuString, + kCreateArchiveMenuString, + + kConfigTitle, + + kConfigPluginEnabled +}; + +} + +#endif \ No newline at end of file diff --git a/CPP/7zip/UI/Far/OverwriteDialog.cpp b/CPP/7zip/UI/Far/OverwriteDialog.cpp new file mode 100755 index 00000000..028fff4e --- /dev/null +++ b/CPP/7zip/UI/Far/OverwriteDialog.cpp @@ -0,0 +1,109 @@ +// OverwriteDialog.cpp + +#include "StdAfx.h" + +#include + +#include "OverwriteDialog.h" + +#include "Common/String.h" +#include "Common/StringConvert.h" + +#include "Windows/FileName.h" +#include "Windows/Defs.h" +#include "Windows/PropVariantConversions.h" + +#include "FarUtils.h" +#include "Messages.h" + +using namespace NWindows; +using namespace NFar; + +namespace NOverwriteDialog { + +static const char *kHelpTopic = "OverwriteDialog"; + +struct CFileInfoStrings +{ + CSysString Size; + CSysString Time; +}; + +void SetFileInfoStrings(const CFileInfo &fileInfo, + CFileInfoStrings &fileInfoStrings) +{ + char buffer[256]; + + if (fileInfo.SizeIsDefined) + { + sprintf(buffer, "%I64u ", fileInfo.Size); + fileInfoStrings.Size = buffer; + fileInfoStrings.Size += g_StartupInfo.GetMsgString(NMessageID::kOverwriteBytes); + } + else + { + fileInfoStrings.Size = ""; + } + + FILETIME localFileTime; + if (!FileTimeToLocalFileTime(&fileInfo.Time, &localFileTime)) + throw 4190402; + UString timeString = ConvertFileTimeToString(localFileTime); + + fileInfoStrings.Time = g_StartupInfo.GetMsgString(NMessageID::kOverwriteModifiedOn); + fileInfoStrings.Time += " "; + fileInfoStrings.Time += GetSystemString(timeString, CP_OEMCP); +} + +NResult::EEnum Execute(const CFileInfo &oldFileInfo, const CFileInfo &newFileInfo) +{ + const int kYSize = 20; + const int kXSize = 76; + + CFileInfoStrings oldFileInfoStrings; + CFileInfoStrings newFileInfoStrings; + + SetFileInfoStrings(oldFileInfo, oldFileInfoStrings); + SetFileInfoStrings(newFileInfo, newFileInfoStrings); + + struct CInitDialogItem anInitItems[]={ + { DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, NMessageID::kOverwriteTitle, NULL, NULL }, + { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, NMessageID::kOverwriteMessage1, NULL, NULL }, + + { DI_TEXT, 3, 3, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL }, + + { DI_TEXT, 5, 4, 0, 0, false, false, 0, false, NMessageID::kOverwriteMessageWouldYouLike, NULL, NULL }, + + { DI_TEXT, 7, 6, 0, 0, false, false, 0, false, -1, oldFileInfo.Name, NULL }, + { DI_TEXT, 7, 7, 0, 0, false, false, 0, false, -1, oldFileInfoStrings.Size, NULL }, + { DI_TEXT, 7, 8, 0, 0, false, false, 0, false, -1, oldFileInfoStrings.Time, NULL }, + + { DI_TEXT, 5, 10, 0, 0, false, false, 0, false, NMessageID::kOverwriteMessageWithtTisOne, NULL, NULL }, + + { DI_TEXT, 7, 12, 0, 0, false, false, 0, false, -1, newFileInfo.Name, NULL }, + { DI_TEXT, 7, 13, 0, 0, false, false, 0, false, -1, newFileInfoStrings.Size, NULL }, + { DI_TEXT, 7, 14, 0, 0, false, false, 0, false, -1, newFileInfoStrings.Time, NULL }, + + { DI_TEXT, 3, kYSize - 5, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL }, + + { DI_BUTTON, 0, kYSize - 4, 0, 0, true, false, DIF_CENTERGROUP, true, NMessageID::kOverwriteYes, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 4, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteYesToAll, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 4, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteNo, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 4, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteNoToAll, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteAutoRename, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kOverwriteCancel, NULL, NULL } + }; + + const int kNumDialogItems = sizeof(anInitItems) / sizeof(anInitItems[0]); + FarDialogItem aDialogItems[kNumDialogItems]; + g_StartupInfo.InitDialogItems(anInitItems, aDialogItems, kNumDialogItems); + int anAskCode = g_StartupInfo.ShowDialog(kXSize, kYSize, + NULL, aDialogItems, kNumDialogItems); + const int kButtonStartPos = kNumDialogItems - 6; + if (anAskCode >= kButtonStartPos && anAskCode < kNumDialogItems) + return NResult::EEnum(anAskCode - kButtonStartPos); + return NResult::kCancel; +} + +} + diff --git a/CPP/7zip/UI/Far/OverwriteDialog.h b/CPP/7zip/UI/Far/OverwriteDialog.h new file mode 100755 index 00000000..ff1a480e --- /dev/null +++ b/CPP/7zip/UI/Far/OverwriteDialog.h @@ -0,0 +1,33 @@ +// OverwriteDialog.h + +#ifndef OVERWRITEDIALOG_H +#define OVERWRITEDIALOG_H + +#include "Common/String.h" + +namespace NOverwriteDialog { + +struct CFileInfo +{ + bool SizeIsDefined; + UINT64 Size; + FILETIME Time; + CSysString Name; +}; +namespace NResult +{ + enum EEnum + { + kYes, + kYesToAll, + kNo, + kNoToAll, + kAutoRename, + kCancel, + }; +} +NResult::EEnum Execute(const CFileInfo &anOldFileInfo, const CFileInfo &aNewFileInfo); + +} + +#endif diff --git a/CPP/7zip/UI/Far/Plugin.cpp b/CPP/7zip/UI/Far/Plugin.cpp new file mode 100755 index 00000000..0d4b150e --- /dev/null +++ b/CPP/7zip/UI/Far/Plugin.cpp @@ -0,0 +1,693 @@ +// Plugin.cpp + +#include "StdAfx.h" + +#include "Plugin.h" + +#include "Common/StringConvert.h" +#include "Common/Wildcard.h" + +#include "Windows/PropVariantConversions.h" +#include "Windows/FileName.h" +#include "Windows/FileDir.h" + +#include "../Common/PropIDUtils.h" + +#include "Messages.h" +#include "FarUtils.h" + +using namespace NWindows; +using namespace NFar; + +CSysString ConvertPropertyToString2(const PROPVARIANT &propVariant, PROPID propID) +{ + if (propVariant.vt == VT_BSTR) + return GetSystemString(propVariant.bstrVal, CP_OEMCP); + if (propVariant.vt != VT_BOOL) + return GetSystemString(ConvertPropertyToString(propVariant, propID), CP_OEMCP); + int messageID = VARIANT_BOOLToBool(propVariant.boolVal) ? + NMessageID::kYes : NMessageID::kNo; + return g_StartupInfo.GetMsgString(messageID); +} + +CPlugin::CPlugin(const UString &fileName, + // const UString &defaultName, + IInFolderArchive *archiveHandler, + UString archiveTypeName + ): + m_ArchiveHandler(archiveHandler), + m_FileName(fileName), + _archiveTypeName(archiveTypeName) + // , m_DefaultName(defaultName) + // , m_ArchiverInfo(archiverInfo) +{ + if (!NFile::NFind::FindFile(m_FileName, m_FileInfo)) + throw "error"; + archiveHandler->BindToRootFolder(&_folder); +} + +CPlugin::~CPlugin() +{ +} + +static void MyGetFileTime(IFolderFolder *anArchiveFolder, UINT32 itemIndex, + PROPID propID, FILETIME &fileTime) +{ + NCOM::CPropVariant propVariant; + if (anArchiveFolder->GetProperty(itemIndex, propID, &propVariant) != S_OK) + throw 271932; + if (propVariant.vt == VT_EMPTY) + { + fileTime.dwHighDateTime = 0; + fileTime.dwLowDateTime = 0; + } + else + { + if (propVariant.vt != VT_FILETIME) + throw 4191730; + fileTime = propVariant.filetime; + } +} + +void CPlugin::ReadPluginPanelItem(PluginPanelItem &panelItem, UINT32 itemIndex) +{ + NCOM::CPropVariant propVariant; + if (_folder->GetProperty(itemIndex, kpidName, &propVariant) != S_OK) + throw 271932; + + if (propVariant.vt != VT_BSTR) + throw 272340; + + CSysString oemString = UnicodeStringToMultiByte(propVariant.bstrVal, CP_OEMCP); + strcpy(panelItem.FindData.cFileName, oemString); + panelItem.FindData.cAlternateFileName[0] = 0; + + if (_folder->GetProperty(itemIndex, kpidAttributes, &propVariant) != S_OK) + throw 271932; + if (propVariant.vt == VT_UI4) + panelItem.FindData.dwFileAttributes = propVariant.ulVal; + else if (propVariant.vt == VT_EMPTY) + panelItem.FindData.dwFileAttributes = m_FileInfo.Attributes; + else + throw 21631; + + if (_folder->GetProperty(itemIndex, kpidIsFolder, &propVariant) != S_OK) + throw 271932; + if (propVariant.vt == VT_BOOL) + { + if (VARIANT_BOOLToBool(propVariant.boolVal)) + panelItem.FindData.dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; + } + else if (propVariant.vt != VT_EMPTY) + throw 21632; + + if (_folder->GetProperty(itemIndex, kpidSize, &propVariant) != S_OK) + throw 271932; + UINT64 length; + if (propVariant.vt == VT_EMPTY) + length = 0; + else + length = ::ConvertPropVariantToUInt64(propVariant); + panelItem.FindData.nFileSizeLow = UINT32(length); + panelItem.FindData.nFileSizeHigh = UINT32(length >> 32); + + MyGetFileTime(_folder, itemIndex, kpidCreationTime, panelItem.FindData.ftCreationTime); + MyGetFileTime(_folder, itemIndex, kpidLastAccessTime, panelItem.FindData.ftLastAccessTime); + MyGetFileTime(_folder, itemIndex, kpidLastWriteTime, panelItem.FindData.ftLastWriteTime); + + if (panelItem.FindData.ftLastWriteTime.dwHighDateTime == 0 && + panelItem.FindData.ftLastWriteTime.dwLowDateTime == 0) + panelItem.FindData.ftLastWriteTime = m_FileInfo.LastWriteTime; + + if (_folder->GetProperty(itemIndex, kpidPackedSize, &propVariant) != S_OK) + throw 271932; + if (propVariant.vt == VT_EMPTY) + length = 0; + else + length = ::ConvertPropVariantToUInt64(propVariant); + panelItem.PackSize = UINT32(length); + panelItem.PackSizeHigh = UINT32(length >> 32); + + panelItem.Flags = 0; + panelItem.NumberOfLinks = 0; + + panelItem.Description = NULL; + panelItem.Owner = NULL; + panelItem.CustomColumnData = NULL; + panelItem.CustomColumnNumber = 0; + + panelItem.Reserved[0] = 0; + panelItem.Reserved[1] = 0; + panelItem.Reserved[2] = 0; + + +} + +int CPlugin::GetFindData(PluginPanelItem **panelItems, + int *itemsNumber, int opMode) +{ + // CScreenRestorer screenRestorer; + if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0) + { + /* + screenRestorer.Save(); + const char *aMsgItems[]= + { + g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kReadingList) + }; + g_StartupInfo.ShowMessage(0, NULL, aMsgItems, + sizeof(aMsgItems) / sizeof(aMsgItems[0]), 0); + */ + } + + UINT32 numItems; + _folder->GetNumberOfItems(&numItems); + *panelItems = new PluginPanelItem[numItems]; + try + { + for(UINT32 i = 0; i < numItems; i++) + { + PluginPanelItem &panelItem = (*panelItems)[i]; + ReadPluginPanelItem(panelItem, i); + panelItem.UserData = i; + } + } + catch(...) + { + delete [](*panelItems); + throw; + } + *itemsNumber = numItems; + return(TRUE); +} + +void CPlugin::FreeFindData(struct PluginPanelItem *panelItems, + int itemsNumber) +{ + for(int i = 0; i < itemsNumber; i++) + if(panelItems[i].Description != NULL) + delete []panelItems[i].Description; + delete []panelItems; +} + + +void CPlugin::EnterToDirectory(const UString &aDirName) +{ + CMyComPtr newFolder; + _folder->BindToFolder(aDirName, &newFolder); + if(newFolder == NULL) + if (aDirName.IsEmpty()) + return; + else + throw 40325; + _folder = newFolder; +} + +int CPlugin::SetDirectory(const char *aszDir, int opMode) +{ + UString path = MultiByteToUnicodeString(aszDir, CP_OEMCP); + if (path == L"\\") + { + _folder.Release(); + m_ArchiveHandler->BindToRootFolder(&_folder); + } + else if (path == L"..") + { + CMyComPtr newFolder; + _folder->BindToParentFolder(&newFolder); + if (newFolder == NULL) + throw 40312; + _folder = newFolder; + } + else if (path.IsEmpty()) + EnterToDirectory(path); + else + { + if (path[0] == L'\\') + { + _folder.Release(); + m_ArchiveHandler->BindToRootFolder(&_folder); + path = path.Mid(1); + } + UStringVector pathParts; + SplitPathToParts(path, pathParts); + for(int i = 0; i < pathParts.Size(); i++) + EnterToDirectory(pathParts[i]); + } + GetCurrentDir(); + return TRUE; +} + +void CPlugin::GetPathParts(UStringVector &pathParts) +{ + pathParts.Clear(); + CMyComPtr folderItem = _folder; + for (;;) + { + CMyComPtr newFolder; + folderItem->BindToParentFolder(&newFolder); + if (newFolder == NULL) + break; + CMyComBSTR name; + folderItem->GetName(&name); + pathParts.Insert(0, (const wchar_t *)name); + folderItem = newFolder; + } +} + +void CPlugin::GetCurrentDir() +{ + m_CurrentDir.Empty(); + UStringVector pathParts; + GetPathParts(pathParts); + for (int i = 0; i < pathParts.Size(); i++) + { + m_CurrentDir += L'\\'; + m_CurrentDir += pathParts[i]; + } +} + +static char *kPluginFormatName = "7-ZIP"; + + +struct CPROPIDToName +{ + PROPID PropID; + int PluginID; +}; + +static CPROPIDToName kPROPIDToName[] = +{ + { kpidName, NMessageID::kName }, + { kpidExtension, NMessageID::kExtension }, + { kpidIsFolder, NMessageID::kIsFolder }, + { kpidSize, NMessageID::kSize }, + { kpidPackedSize, NMessageID::kPackedSize }, + { kpidAttributes, NMessageID::kAttributes }, + { kpidCreationTime, NMessageID::kCreationTime }, + { kpidLastAccessTime, NMessageID::kLastAccessTime }, + { kpidLastWriteTime, NMessageID::kLastWriteTime }, + { kpidSolid, NMessageID::kSolid }, + { kpidCommented, NMessageID::kCommented }, + { kpidEncrypted, NMessageID::kEncrypted }, + { kpidSplitBefore, NMessageID::kSplitBefore }, + { kpidSplitAfter, NMessageID::kSplitAfter }, + { kpidDictionarySize, NMessageID::kDictionarySize }, + { kpidCRC, NMessageID::kCRC }, + { kpidType, NMessageID::kType }, + { kpidIsAnti, NMessageID::kAnti }, + { kpidMethod, NMessageID::kMethod }, + { kpidHostOS, NMessageID::kHostOS }, + { kpidFileSystem, NMessageID::kFileSystem }, + { kpidUser, NMessageID::kUser }, + { kpidGroup, NMessageID::kGroup }, + { kpidBlock, NMessageID::kBlock }, + { kpidComment, NMessageID::kComment }, + { kpidPosition, NMessageID::kPosition } + +}; + +static const int kNumPROPIDToName = sizeof(kPROPIDToName) / sizeof(kPROPIDToName[0]); + +static int FindPropertyToName(PROPID propID) +{ + for(int i = 0; i < kNumPROPIDToName; i++) + if(kPROPIDToName[i].PropID == propID) + return i; + return -1; +} + +/* +struct CPropertyIDInfo +{ + PROPID PropID; + const char *FarID; + int Width; + // char CharID; +}; + +static CPropertyIDInfo kPropertyIDInfos[] = +{ + { kpidName, "N", 0}, + { kpidSize, "S", 8}, + { kpidPackedSize, "P", 8}, + { kpidAttributes, "A", 0}, + { kpidCreationTime, "DC", 14}, + { kpidLastAccessTime, "DA", 14}, + { kpidLastWriteTime, "DM", 14}, + + { kpidSolid, NULL, 0, 'S'}, + { kpidEncrypted, NULL, 0, 'P'} + + { kpidDictionarySize, IDS_PROPERTY_DICTIONARY_SIZE }, + { kpidSplitBefore, NULL, 'B'}, + { kpidSplitAfter, NULL, 'A'}, + { kpidComment, , NULL, 'C'}, + { kpidCRC, IDS_PROPERTY_CRC } + // { kpidType, L"Type" } +}; + +static const int kNumPropertyIDInfos = sizeof(kPropertyIDInfos) / + sizeof(kPropertyIDInfos[0]); + +static int FindPropertyInfo(PROPID propID) +{ + for(int i = 0; i < kNumPropertyIDInfos; i++) + if(kPropertyIDInfos[i].PropID == propID) + return i; + return -1; +} +*/ + +// char *g_Titles[] = { "a", "f", "v" }; +static void SmartAddToString(AString &aDestString, const char *aSrcString) +{ + if (!aDestString.IsEmpty()) + aDestString += ','; + aDestString += aSrcString; +} + +/* +void CPlugin::AddColumn(PROPID propID) +{ + int index = FindPropertyInfo(propID); + if (index >= 0) + { + for(int i = 0; i < m_ProxyHandler->m_InternalProperties.Size(); i++) + { + const CArchiveItemProperty &aHandlerProperty = m_ProxyHandler->m_InternalProperties[i]; + if (aHandlerProperty.ID == propID) + break; + } + if (i == m_ProxyHandler->m_InternalProperties.Size()) + return; + + const CPropertyIDInfo &aPropertyIDInfo = kPropertyIDInfos[index]; + SmartAddToString(PanelModeColumnTypes, aPropertyIDInfo.FarID); + char aTmp[32]; + itoa(aPropertyIDInfo.Width, aTmp, 10); + SmartAddToString(PanelModeColumnWidths, aTmp); + return; + } +} +*/ + +void CPlugin::GetOpenPluginInfo(struct OpenPluginInfo *info) +{ + info->StructSize = sizeof(*info); + info->Flags = OPIF_USEFILTER | OPIF_USESORTGROUPS| OPIF_USEHIGHLIGHTING| + OPIF_ADDDOTS | OPIF_COMPAREFATTIME; + + UINT codePage = ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; + + strcpy(m_FileNameBuffer, UnicodeStringToMultiByte(m_FileName, codePage)); + info->HostFile = m_FileNameBuffer; // test it it is not static + + strcpy(m_CurrentDirBuffer, UnicodeStringToMultiByte(m_CurrentDir, CP_OEMCP)); + info->CurDir = m_CurrentDirBuffer; + + info->Format = kPluginFormatName; + + UString name; + { + UString fullName; + int index; + NFile::NDirectory::MyGetFullPathName(m_FileName, fullName, index); + name = fullName.Mid(index); + } + + m_PannelTitle = + UString(L' ') + + _archiveTypeName + + UString(L':') + + name + + UString(L' '); + if(!m_CurrentDir.IsEmpty()) + { + // m_PannelTitle += '\\'; + m_PannelTitle += m_CurrentDir; + } + + strcpy(m_PannelTitleBuffer, UnicodeStringToMultiByte(m_PannelTitle, CP_OEMCP)); + info->PanelTitle = m_PannelTitleBuffer; + + memset(m_InfoLines,0,sizeof(m_InfoLines)); + strcpy(m_InfoLines[0].Text,""); + m_InfoLines[0].Separator = TRUE; + + strcpy(m_InfoLines[1].Text, g_StartupInfo.GetMsgString(NMessageID::kArchiveType)); + strcpy(m_InfoLines[1].Data, UnicodeStringToMultiByte(_archiveTypeName, CP_OEMCP)); + + int numItems = 2; + UINT32 numProps; + if (m_ArchiveHandler->GetNumberOfArchiveProperties(&numProps) == S_OK) + { + for (UINT32 i = 0; i < numProps && numItems < 30; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + if (m_ArchiveHandler->GetArchivePropertyInfo(i, &name, &propID, &vt) != S_OK) + continue; + + InfoPanelLine &item = m_InfoLines[numItems]; + int index = FindPropertyToName(propID); + if (index < 0) + { + if (name != 0) + strcpy(item.Text, UnicodeStringToMultiByte( + (const wchar_t *)name, CP_OEMCP)); + else + strcpy(item.Text, ""); + } + else + strcpy(item.Text, g_StartupInfo.GetMsgString(kPROPIDToName[index].PluginID)); + + NCOM::CPropVariant propVariant; + if (m_ArchiveHandler->GetArchiveProperty(propID, &propVariant) != S_OK) + continue; + CSysString s = ConvertPropertyToString2(propVariant, propID); + strcpy(item.Data, s); + numItems++; + } + } + + //m_InfoLines[1].Separator = 0; + + info->InfoLines = m_InfoLines; + info->InfoLinesNumber = numItems; + + + info->DescrFiles = NULL; + info->DescrFilesNumber = 0; + + PanelModeColumnTypes.Empty(); + PanelModeColumnWidths.Empty(); + + /* + AddColumn(kpidName); + AddColumn(kpidSize); + AddColumn(kpidPackedSize); + AddColumn(kpidLastWriteTime); + AddColumn(kpidCreationTime); + AddColumn(kpidLastAccessTime); + AddColumn(kpidAttributes); + + PanelMode.ColumnTypes = (char *)(const char *)PanelModeColumnTypes; + PanelMode.ColumnWidths = (char *)(const char *)PanelModeColumnWidths; + PanelMode.ColumnTitles = NULL; + PanelMode.FullScreen = TRUE; + PanelMode.DetailedStatus = FALSE; + PanelMode.AlignExtensions = FALSE; + PanelMode.CaseConversion = FALSE; + PanelMode.StatusColumnTypes = "N"; + PanelMode.StatusColumnWidths = "0"; + PanelMode.Reserved[0] = 0; + PanelMode.Reserved[1] = 0; + + info->PanelModesArray = &PanelMode; + info->PanelModesNumber = 1; + */ + + info->PanelModesArray = NULL; + info->PanelModesNumber = 0; + + info->StartPanelMode = 0; + info->StartSortMode = 0; + info->KeyBar = NULL; + info->ShortcutData = NULL; +} + +struct CArchiveItemProperty +{ + AString Name; + PROPID ID; + VARTYPE Type; +}; + +HRESULT CPlugin::ShowAttributesWindow() +{ + PluginPanelItem pluginPanelItem; + if (!g_StartupInfo.ControlGetActivePanelCurrentItemInfo(pluginPanelItem)) + return S_FALSE; + if (strcmp(pluginPanelItem.FindData.cFileName, "..") == 0 && + NFile::NFind::NAttributes::IsDirectory(pluginPanelItem.FindData.dwFileAttributes)) + return S_FALSE; + int itemIndex = pluginPanelItem.UserData; + + CObjectVector properties; + UINT32 numProps; + RINOK(m_ArchiveHandler->GetNumberOfProperties(&numProps)); + int i; + for (i = 0; i < (int)numProps; i++) + { + CMyComBSTR name; + PROPID propID; + VARTYPE vt; + RINOK(m_ArchiveHandler->GetPropertyInfo(i, &name, &propID, &vt)); + CArchiveItemProperty destProperty; + destProperty.Type = vt; + destProperty.ID = propID; + if (destProperty.ID == kpidPath) + destProperty.ID = kpidName; + AString propName; + { + if (name != NULL) + destProperty.Name = UnicodeStringToMultiByte( + (const wchar_t *)name, CP_OEMCP); + else + destProperty.Name = "Error"; + } + properties.Add(destProperty); + } + + /* + LPCITEMIDLIST aProperties; + if (index < m_FolderItem->m_DirSubItems.Size()) + { + const CArchiveFolderItem &anItem = m_FolderItem->m_DirSubItems[index]; + aProperties = anItem.m_Properties; + } + else + { + const CArchiveFolderFileItem &anItem = + m_FolderItem->m_FileSubItems[index - m_FolderItem->m_DirSubItems.Size()]; + aProperties = anItem.m_Properties; + } + */ + + const int kPathIndex = 2; + const int kOkButtonIndex = 4; + int size = 2; + CRecordVector initDialogItems; + + int xSize = 70; + CInitDialogItem initDialogItem = + { DI_DOUBLEBOX, 3, 1, xSize - 4, size - 2, false, false, 0, false, NMessageID::kProperties, NULL, NULL }; + initDialogItems.Add(initDialogItem); + AStringVector aValues; + + for (i = 0; i < properties.Size(); i++) + { + const CArchiveItemProperty &property = properties[i]; + + CInitDialogItem initDialogItem = + { DI_TEXT, 5, 3 + i, 0, 0, false, false, 0, false, 0, NULL, NULL }; + int index = FindPropertyToName(property.ID); + if (index < 0) + { + initDialogItem.DataMessageId = -1; + initDialogItem.DataString = property.Name; + } + else + initDialogItem.DataMessageId = kPROPIDToName[index].PluginID; + initDialogItems.Add(initDialogItem); + + NCOM::CPropVariant propVariant; + RINOK(_folder->GetProperty(itemIndex, + property.ID, &propVariant)); + CSysString aString = ConvertPropertyToString2(propVariant, property.ID); + aValues.Add(aString); + + { + CInitDialogItem initDialogItem = + { DI_TEXT, 30, 3 + i, 0, 0, false, false, 0, false, -1, NULL, NULL }; + initDialogItems.Add(initDialogItem); + } + } + + int numLines = aValues.Size(); + for(i = 0; i < numLines; i++) + { + CInitDialogItem &initDialogItem = initDialogItems[1 + i * 2 + 1]; + initDialogItem.DataString = aValues[i]; + } + + int numDialogItems = initDialogItems.Size(); + + CRecordVector dialogItems; + dialogItems.Reserve(numDialogItems); + for(i = 0; i < numDialogItems; i++) + dialogItems.Add(FarDialogItem()); + g_StartupInfo.InitDialogItems(&initDialogItems.Front(), + &dialogItems.Front(), numDialogItems); + + int maxLen = 0; + for (i = 0; i < numLines; i++) + { + FarDialogItem &dialogItem = dialogItems[1 + i * 2]; + int len = strlen(dialogItem.Data); + if (len > maxLen) + maxLen = len; + } + int maxLen2 = 0; + const int kSpace = 10; + for (i = 0; i < numLines; i++) + { + FarDialogItem &dialogItem = dialogItems[1 + i * 2 + 1]; + int len = strlen(dialogItem.Data); + if (len > maxLen2) + maxLen2 = len; + dialogItem.X1 = maxLen + kSpace; + } + size = numLines + 6; + xSize = maxLen + kSpace + maxLen2 + 5; + FarDialogItem &aFirstDialogItem = dialogItems.Front(); + aFirstDialogItem.Y2 = size - 2; + aFirstDialogItem.X2 = xSize - 4; + + int askCode = g_StartupInfo.ShowDialog(xSize, size, NULL, &dialogItems.Front(), numDialogItems); + return S_OK; +} + +int CPlugin::ProcessKey(int aKey, unsigned int controlState) +{ + if (controlState == PKF_CONTROL && aKey == 'A') + { + HRESULT result = ShowAttributesWindow(); + if (result == S_OK) + return TRUE; + if (result == S_FALSE) + return FALSE; + throw "Error"; + } + if ((controlState & PKF_ALT) != 0 && aKey == VK_F6) + { + UString 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); + g_StartupInfo.Control(this, FCTL_UPDATEPANEL, NULL); + g_StartupInfo.Control(this, FCTL_REDRAWPANEL, NULL); + g_StartupInfo.Control(this, FCTL_UPDATEANOTHERPANEL, NULL); + g_StartupInfo.Control(this, FCTL_REDRAWANOTHERPANEL, NULL); + return TRUE; + } + + return FALSE; +} diff --git a/CPP/7zip/UI/Far/Plugin.h b/CPP/7zip/UI/Far/Plugin.h new file mode 100755 index 00000000..0b617cfb --- /dev/null +++ b/CPP/7zip/UI/Far/Plugin.h @@ -0,0 +1,99 @@ +// 7zip/Far/Plugin.h + +#ifndef __7ZIP_FAR_PLUGIN_H +#define __7ZIP_FAR_PLUGIN_H + +#include "Common/MyCom.h" + +#include "Windows/COM.h" +#include "Windows/FileFind.h" +#include "Windows/PropVariant.h" + +#include "../Common/ArchiverInfo.h" +#include "../Agent/IFolderArchive.h" + +#include "FarUtils.h" + +class CPlugin +{ + NWindows::NCOM::CComInitializer m_ComInitializer; + UString m_CurrentDir; + + UString m_PannelTitle; + + InfoPanelLine m_InfoLines[30]; // Change it; + + char m_FileNameBuffer[1024]; + char m_CurrentDirBuffer[1024]; + char m_PannelTitleBuffer[1024]; + + AString PanelModeColumnTypes; + AString PanelModeColumnWidths; + PanelMode PanelMode; + void AddColumn(PROPID aPropID); + + + void EnterToDirectory(const UString &aDirName); + + void GetPathParts(UStringVector &aPathParts); + void GetCurrentDir(); +public: + UString m_FileName; + // UString m_DefaultName; + NWindows::NFile::NFind::CFileInfoW m_FileInfo; + + CMyComPtr m_ArchiveHandler; + CMyComPtr _folder; + + // CArchiverInfo m_ArchiverInfo; + UString _archiveTypeName; + + bool PasswordIsDefined; + UString Password; + + + CPlugin(const UString &fileName, + // const UString &aDefaultName, + IInFolderArchive *archiveHandler, + UString archiveTypeName + ); + ~CPlugin(); + + void ReadValueSafe(PROPID aPropID, NWindows::NCOM::CPropVariant aPropVariant); + void ReadPluginPanelItem(PluginPanelItem &aPanelItem, UINT32 anItemIndex); + + int GetFindData(PluginPanelItem **pPanelItem,int *pItemsNumber,int OpMode); + void FreeFindData(PluginPanelItem *PanelItem,int ItemsNumber); + int SetDirectory(const char *aDir, int opMode); + void GetOpenPluginInfo(struct OpenPluginInfo *anInfo); + + int DeleteFiles(PluginPanelItem *aPanelItems, int itemsNumber, int opMode); + + + HRESULT ExtractFiles( + bool decompressAllItems, + const UINT32 *indices, + UINT32 numIndices, + bool silent, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const UString &destPath, + bool passwordIsDefined, const UString &password); + + NFar::NFileOperationReturnCode::EEnum GetFiles(struct PluginPanelItem *aPanelItem, int itemsNumber, + int move, char *destPath, int opMode); + + NFar::NFileOperationReturnCode::EEnum GetFilesReal(struct PluginPanelItem *aPanelItems, + int itemsNumber, int move, const char *_aDestPath, int opMode, bool aShowBox); + + NFar::NFileOperationReturnCode::EEnum PutFiles(struct PluginPanelItem *aPanelItems, int itemsNumber, + int move, int opMode); + + HRESULT ShowAttributesWindow(); + + int ProcessKey(int aKey, unsigned int aControlState); +}; + +HRESULT CompressFiles(const CObjectVector &aPluginPanelItems); + +#endif diff --git a/CPP/7zip/UI/Far/PluginCommon.cpp b/CPP/7zip/UI/Far/PluginCommon.cpp new file mode 100755 index 00000000..3e8e3cee --- /dev/null +++ b/CPP/7zip/UI/Far/PluginCommon.cpp @@ -0,0 +1,50 @@ +// SevenZip/Plugin.cpp + +#include "StdAfx.h" + +#include "Plugin.h" + +/* +void CPlugin::AddRealIndexOfFile(const CArchiveFolderItem &aFolder, + int anIndexInVector, vector &aRealIndexes) +{ + const CArchiveFolderFileItem &anItem = aFolder.m_FileSubItems[anIndexInVector]; + int aHandlerItemIndex = m_ProxyHandler->GetHandlerItemIndex(anItem.m_Properties); + if(aHandlerItemIndex < 0) + throw "error"; + aRealIndexes.push_back(aHandlerItemIndex); +} + +void CPlugin::AddRealIndexes(const CArchiveFolderItem &anItem, + vector &aRealIndexes) +{ + int aHandlerItemIndex = m_ProxyHandler->GetHandlerItemIndex(anItem.m_Properties); + if(aHandlerItemIndex >= 0) // test -1 value + aRealIndexes.push_back(aHandlerItemIndex); + for(int i = 0; i < anItem.m_DirSubItems.Size(); i++) + AddRealIndexes(anItem.m_DirSubItems[i], aRealIndexes); + for(i = 0; i < anItem.m_FileSubItems.Size(); i++) + AddRealIndexOfFile(anItem, i , aRealIndexes); +} + + +void CPlugin::GetRealIndexes(PluginPanelItem *aPanelItems, int anItemsNumber, + vector &aRealIndexes) +{ + aRealIndexes.clear(); + for(int i = 0; i < anItemsNumber; i++) + { + int anIndex = aPanelItems[i].UserData; + if (anIndex < m_FolderItem->m_DirSubItems.Size()) + { + const CArchiveFolderItem &anItem = m_FolderItem->m_DirSubItems[anIndex]; + AddRealIndexes(anItem, aRealIndexes); + } + else + AddRealIndexOfFile(*m_FolderItem, anIndex - m_FolderItem->m_DirSubItems.Size(), + aRealIndexes); + } + sort(aRealIndexes.begin(), aRealIndexes.end()); +} + +*/ diff --git a/CPP/7zip/UI/Far/PluginDelete.cpp b/CPP/7zip/UI/Far/PluginDelete.cpp new file mode 100755 index 00000000..6a969c15 --- /dev/null +++ b/CPP/7zip/UI/Far/PluginDelete.cpp @@ -0,0 +1,169 @@ +// PluginDelete.cpp + +#include "StdAfx.h" + +#include + +#include "Plugin.h" +#include "Messages.h" +#include "UpdateCallback100.h" + +#include "Windows/FileDir.h" + +#include "../../Common/FileStreams.h" + +#include "Common/StringConvert.h" + +#include "../Common/ZipRegistry.h" +#include "../Common/WorkDir.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) +{ + if (numItems == 0) + return FALSE; + /* + if (!m_ArchiverInfo.UpdateEnabled) + { + g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); + return FALSE; + } + */ + if ((opMode & OPM_SILENT) == 0) + { + const char *msgItems[]= + { + g_StartupInfo.GetMsgString(NMessageID::kDeleteTitle), + g_StartupInfo.GetMsgString(NMessageID::kDeleteFiles), + g_StartupInfo.GetMsgString(NMessageID::kDeleteDelete), + g_StartupInfo.GetMsgString(NMessageID::kDeleteCancel) + }; + char msg[1024]; + if (numItems == 1) + { + sprintf(msg, g_StartupInfo.GetMsgString(NMessageID::kDeleteFile), + panelItems[0].FindData.cFileName); + msgItems[1] = msg; + } + else if (numItems > 1) + { + sprintf(msg, g_StartupInfo.GetMsgString(NMessageID::kDeleteNumberOfFiles), + numItems); + msgItems[1] = msg; + } + if (g_StartupInfo.ShowMessage(FMSG_WARNING, NULL, msgItems, + sizeof(msgItems) / sizeof(msgItems[0]), 2) != 0) + return (FALSE); + } + + CScreenRestorer screenRestorer; + CProgressBox progressBox; + CProgressBox *progressBoxPointer = NULL; + if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0) + { + screenRestorer.Save(); + + progressBoxPointer = &progressBox; + progressBox.Init(g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kDeleting), 1 << 17); + } + + NWorkDir::CInfo workDirInfo; + ReadWorkDirInfo(workDirInfo); + + UString workDir = GetWorkDir(workDirInfo, m_FileName); + CreateComplexDirectory(workDir); + + CTempFileW tempFile; + UString tempFileName; + if (tempFile.Create(workDir, kTempArchivePrefix, tempFileName) == 0) + return FALSE; + + + CRecordVector indices; + indices.Reserve(numItems); + for(int i = 0; i < numItems; i++) + indices.Add(panelItems[i].UserData); + + //////////////////////////// + // Save _folder; + + UStringVector pathVector; + GetPathParts(pathVector); + + CMyComPtr outArchive; + HRESULT result = m_ArchiveHandler.QueryInterface( + IID_IOutFolderArchive, &outArchive); + if(result != S_OK) + { + g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); + return FALSE; + } + outArchive->SetFolder(_folder); + + CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp; + CMyComPtr updateCallback(updateCallbackSpec ); + + updateCallbackSpec->Init(m_ArchiveHandler, &progressBox); + + + result = outArchive->DeleteItems( + tempFileName, + &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)) + { + ShowLastErrorMessage(); + return FALSE; + } + + 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 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 new file mode 100755 index 00000000..503ff639 --- /dev/null +++ b/CPP/7zip/UI/Far/PluginRead.cpp @@ -0,0 +1,278 @@ +// PluginRead.cpp + +#include "StdAfx.h" + +#include "Plugin.h" + +#include "Messages.h" + +#include "Common/StringConvert.h" + +#include "Windows/FileName.h" +#include "Windows/FileFind.h" +#include "Windows/FileDir.h" +#include "Windows/Defs.h" + +#include "../Common/ZipRegistry.h" + +#include "ExtractEngine.h" + +using namespace NFar; +using namespace NWindows; + +static const char *kHelpTopicExtrFromSevenZip = "Extract"; + +static const char kDirDelimiter = '\\'; + +static const char *kExractPathHistoryName = "7-ZipExtractPath"; + +HRESULT CPlugin::ExtractFiles( + bool decompressAllItems, + const UINT32 *indices, + UINT32 numIndices, + bool silent, + NExtract::NPathMode::EEnum pathMode, + NExtract::NOverwriteMode::EEnum overwriteMode, + const UString &destPath, + bool passwordIsDefined, const UString &password) +{ + CScreenRestorer screenRestorer; + CProgressBox progressBox; + CProgressBox *progressBoxPointer = NULL; + if (!silent) + { + screenRestorer.Save(); + + progressBoxPointer = &progressBox; + progressBox.Init(g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kExtracting), 1 << 17); + } + + + CExtractCallBackImp *extractCallbackSpec = new CExtractCallBackImp; + CMyComPtr extractCallback(extractCallbackSpec); + + extractCallbackSpec->Init( + CP_OEMCP, + progressBoxPointer, + /* + GetDefaultName(m_FileName, m_ArchiverInfo.Extension), + m_FileInfo.LastWriteTime, m_FileInfo.Attributes, + */ + passwordIsDefined, password); + + if (decompressAllItems) + return m_ArchiveHandler->Extract(pathMode, overwriteMode, + destPath, BoolToInt(false), extractCallback); + else + { + CMyComPtr archiveFolder; + _folder.QueryInterface(IID_IArchiveFolder, &archiveFolder); + + return archiveFolder->Extract(indices, numIndices, pathMode, overwriteMode, + destPath, BoolToInt(false), extractCallback); + } +} + +NFileOperationReturnCode::EEnum CPlugin::GetFiles(struct PluginPanelItem *panelItems, + int itemsNumber, int move, char *_aDestPath, int opMode) +{ + return GetFilesReal(panelItems, itemsNumber, move, + _aDestPath, opMode, (opMode & OPM_SILENT) == 0); +} + +NFileOperationReturnCode::EEnum CPlugin::GetFilesReal(struct PluginPanelItem *panelItems, + int itemsNumber, int move, const char *_aDestPath, int opMode, bool showBox) +{ + if(move != 0) + { + g_StartupInfo.ShowMessage(NMessageID::kMoveIsNotSupported); + return NFileOperationReturnCode::kError; + } + + CSysString destPath = _aDestPath; + NFile::NName::NormalizeDirPathPrefix(destPath); + + bool extractSelectedFiles = true; + + NExtract::CInfo extractionInfo; + extractionInfo.PathMode = NExtract::NPathMode::kCurrentPathnames; + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; + + bool silent = (opMode & OPM_SILENT) != 0; + bool decompressAllItems = false; + UString password = Password; + bool passwordIsDefined = PasswordIsDefined; + + if (!silent) + { + const int kPathIndex = 2; + + ReadExtractionInfo(extractionInfo); + + const int kPathModeRadioIndex = 4; + const int kOverwriteModeRadioIndex = kPathModeRadioIndex + 4; + const int kNumOverwriteOptions = 6; + const int kFilesModeIndex = kOverwriteModeRadioIndex + kNumOverwriteOptions; + const int kXSize = 76; + const int kYSize = 19; + const int kPasswordYPos = 12; + + const int kXMid = kXSize / 2; + + AString oemPassword = UnicodeStringToMultiByte(password, CP_OEMCP); + + struct CInitDialogItem initItems[]={ + { DI_DOUBLEBOX, 3, 1, kXSize - 4, kYSize - 2, false, false, 0, false, NMessageID::kExtractTitle, NULL, NULL }, + { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, NMessageID::kExtractTo, NULL, NULL }, + + { DI_EDIT, 5, 3, kXSize - 6, 3, true, false, DIF_HISTORY, false, -1, destPath, kExractPathHistoryName}, + // { DI_EDIT, 5, 3, kXSize - 6, 3, true, false, 0, false, -1, destPath, NULL}, + + { DI_SINGLEBOX, 4, 5, kXMid - 2, 5 + 4, false, false, 0, false, NMessageID::kExtractPathMode, NULL, NULL }, + { DI_RADIOBUTTON, 6, 6, 0, 0, false, + extractionInfo.PathMode == NExtract::NPathMode::kFullPathnames, + DIF_GROUP, false, NMessageID::kExtractPathFull, NULL, NULL }, + { DI_RADIOBUTTON, 6, 7, 0, 0, false, + extractionInfo.PathMode == NExtract::NPathMode::kCurrentPathnames, + 0, false, NMessageID::kExtractPathCurrent, NULL, NULL }, + { DI_RADIOBUTTON, 6, 8, 0, 0, false, + extractionInfo.PathMode == NExtract::NPathMode::kNoPathnames, + false, 0, NMessageID::kExtractPathNo, NULL, NULL }, + + { DI_SINGLEBOX, kXMid, 5, kXSize - 6, 5 + kNumOverwriteOptions, false, false, 0, false, NMessageID::kExtractOwerwriteMode, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAskBefore, + DIF_GROUP, false, NMessageID::kExtractOwerwriteAsk, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 7, 0, 0, false, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kWithoutPrompt, + 0, false, NMessageID::kExtractOwerwritePrompt, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 8, 0, 0, false, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kSkipExisting, + 0, false, NMessageID::kExtractOwerwriteSkip, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 9, 0, 0, false, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAutoRename, + 0, false, NMessageID::kExtractOwerwriteAutoRename, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 10, 0, 0, false, + extractionInfo.OverwriteMode == NExtract::NOverwriteMode::kAutoRenameExisting, + 0, false, NMessageID::kExtractOwerwriteAutoRenameExisting, NULL, NULL }, + + { DI_SINGLEBOX, 4, 10, kXMid- 2, 10 + 3, false, false, 0, false, NMessageID::kExtractFilesMode, NULL, NULL }, + { DI_RADIOBUTTON, 6, 11, 0, 0, false, true, DIF_GROUP, false, NMessageID::kExtractFilesSelected, NULL, NULL }, + { DI_RADIOBUTTON, 6, 12, 0, 0, false, false, 0, false, NMessageID::kExtractFilesAll, NULL, NULL }, + + { DI_SINGLEBOX, kXMid, kPasswordYPos, kXSize - 6, kPasswordYPos + 2, false, false, 0, false, NMessageID::kExtractPassword, NULL, NULL }, + { DI_PSWEDIT, kXMid + 2, kPasswordYPos + 1, kXSize - 8, 12, false, false, 0, false, -1, oemPassword, NULL}, + + { DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL }, + + + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kExtractExtract, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kExtractCancel, NULL, NULL } + }; + + const int kNumDialogItems = sizeof(initItems) / sizeof(initItems[0]); + const int kOkButtonIndex = kNumDialogItems - 2; + const int kPasswordIndex = kNumDialogItems - 4; + + FarDialogItem dialogItems[kNumDialogItems]; + g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems); + for (;;) + { + int askCode = g_StartupInfo.ShowDialog(kXSize, kYSize, + kHelpTopicExtrFromSevenZip, dialogItems, kNumDialogItems); + if (askCode != kOkButtonIndex) + return NFileOperationReturnCode::kInterruptedByUser; + destPath = dialogItems[kPathIndex].Data; + destPath.Trim(); + if (destPath.IsEmpty()) + { + if(!NFile::NDirectory::MyGetCurrentDirectory(destPath)) + throw 318016; + NFile::NName::NormalizeDirPathPrefix(destPath); + break; + } + else + { + if(destPath[destPath.Length() - 1] == kDirDelimiter) + break; + } + g_StartupInfo.ShowMessage("You must specify directory path"); + } + + if (dialogItems[kPathModeRadioIndex].Selected) + extractionInfo.PathMode = NExtract::NPathMode::kFullPathnames; + else if (dialogItems[kPathModeRadioIndex + 1].Selected) + extractionInfo.PathMode = NExtract::NPathMode::kCurrentPathnames; + else if (dialogItems[kPathModeRadioIndex + 2].Selected) + extractionInfo.PathMode = NExtract::NPathMode::kNoPathnames; + else + throw 31806; + + if (dialogItems[kOverwriteModeRadioIndex].Selected) + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAskBefore; + else if (dialogItems[kOverwriteModeRadioIndex + 1].Selected) + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kWithoutPrompt; + else if (dialogItems[kOverwriteModeRadioIndex + 2].Selected) + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kSkipExisting; + else if (dialogItems[kOverwriteModeRadioIndex + 3].Selected) + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAutoRename; + else if (dialogItems[kOverwriteModeRadioIndex + 4].Selected) + extractionInfo.OverwriteMode = NExtract::NOverwriteMode::kAutoRenameExisting; + else + throw 31806; + + if (dialogItems[kFilesModeIndex].Selected) + decompressAllItems = false; + else if (dialogItems[kFilesModeIndex + 1].Selected) + decompressAllItems = true; + else + throw 31806; + + SaveExtractionInfo(extractionInfo); + + if (dialogItems[kFilesModeIndex].Selected) + extractSelectedFiles = true; + else if (dialogItems[kFilesModeIndex + 1].Selected) + extractSelectedFiles = false; + else + throw 31806; + + oemPassword = dialogItems[kPasswordIndex].Data; + password = MultiByteToUnicodeString(oemPassword, CP_OEMCP); + passwordIsDefined = !password.IsEmpty(); + } + + NFile::NDirectory::CreateComplexDirectory(destPath); + + /* + vector realIndices; + if (!decompressAllItems) + GetRealIndexes(panelItems, itemsNumber, realIndices); + */ + CRecordVector indices; + indices.Reserve(itemsNumber); + for (int i = 0; i < itemsNumber; i++) + indices.Add(panelItems[i].UserData); + + HRESULT result = ExtractFiles(decompressAllItems, &indices.Front(), itemsNumber, + !showBox, extractionInfo.PathMode, extractionInfo.OverwriteMode, + MultiByteToUnicodeString(destPath, CP_OEMCP), + passwordIsDefined, password); + // HRESULT result = ExtractFiles(decompressAllItems, realIndices, !showBox, + // extractionInfo, destPath, passwordIsDefined, password); + if (result != S_OK) + { + if (result == E_ABORT) + return NFileOperationReturnCode::kInterruptedByUser; + ShowErrorMessage(result); + return NFileOperationReturnCode::kError; + } + + // if(move != 0) + // { + // if(DeleteFiles(panelItems, itemsNumber, opMode) == FALSE) + // return NFileOperationReturnCode::kError; + // } + return NFileOperationReturnCode::kSuccess; +} diff --git a/CPP/7zip/UI/Far/PluginWrite.cpp b/CPP/7zip/UI/Far/PluginWrite.cpp new file mode 100755 index 00000000..d6730985 --- /dev/null +++ b/CPP/7zip/UI/Far/PluginWrite.cpp @@ -0,0 +1,696 @@ +// PluginWrite.cpp + +#include "StdAfx.h" + +#include "Plugin.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" + +#include "ProgressBox.h" +#include "Messages.h" +#include "UpdateCallback100.h" + +using namespace NWindows; +using namespace NFile; +using namespace NDirectory; +using namespace NFar; + +using namespace NUpdateArchive; + +static const char *kHelpTopic = "Update"; + +static LPCWSTR kTempArcivePrefix = L"7zA"; + +static const char *kArchiveHistoryKeyName = "7-ZipArcName"; + +static UINT32 g_MethodMap[] = { 0, 1, 3, 5, 7, 9 }; + +static HRESULT SetOutProperties(IOutFolderArchive *outArchive, UINT32 method) +{ + CMyComPtr setProperties; + if (outArchive->QueryInterface(IID_ISetProperties, (void **)&setProperties) == S_OK) + { + UStringVector realNames; + realNames.Add(UString(L"x")); + NCOM::CPropVariant value = (UInt32)method; + CRecordVector names; + for(int i = 0; i < realNames.Size(); i++) + names.Add(realNames[i]); + RINOK(setProperties->SetProperties(&names.Front(), &value, names.Size())); + } + return S_OK; +} + +NFileOperationReturnCode::EEnum CPlugin::PutFiles( + struct PluginPanelItem *panelItems, int numItems, + int moveMode, int opMode) +{ + if(moveMode != 0) + { + g_StartupInfo.ShowMessage(NMessageID::kMoveIsNotSupported); + return NFileOperationReturnCode::kError; + } + if (numItems == 0) + return NFileOperationReturnCode::kError; + + /* + if (!m_ArchiverInfo.UpdateEnabled) + { + g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); + return NFileOperationReturnCode::kError; + } + */ + + const int kYSize = 14; + const int kXMid = 38; + + NCompression::CInfo compressionInfo; + ReadCompressionInfo(compressionInfo); + + int methodIndex = 0; + for (int i = sizeof(g_MethodMap) / sizeof(g_MethodMap[0]) - 1; i >= 0; i--) + if (compressionInfo.Level >= g_MethodMap[i]) + { + methodIndex = i; + break; + } + + const int kMethodRadioIndex = 2; + const int kModeRadioIndex = kMethodRadioIndex + 7; + + struct CInitDialogItem initItems[]={ + { DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kUpdateTitle, NULL, NULL }, + { DI_SINGLEBOX, 4, 2, kXMid - 2, 2 + 7, false, false, 0, false, NMessageID::kUpdateMethod, NULL, NULL }, + { DI_RADIOBUTTON, 6, 3, 0, 0, methodIndex == 0, methodIndex == 0, + DIF_GROUP, false, NMessageID::kUpdateMethodStore, NULL, NULL }, + { DI_RADIOBUTTON, 6, 4, 0, 0, methodIndex == 1, methodIndex == 1, + 0, false, NMessageID::kUpdateMethodFastest, NULL, NULL }, + { DI_RADIOBUTTON, 6, 5, 0, 0, methodIndex == 2, methodIndex == 2, + 0, false, NMessageID::kUpdateMethodFast, NULL, NULL }, + { DI_RADIOBUTTON, 6, 6, 0, 0, methodIndex == 3, methodIndex == 3, + 0, false, NMessageID::kUpdateMethodNormal, NULL, NULL }, + { DI_RADIOBUTTON, 6, 7, 0, 0, methodIndex == 4, methodIndex == 4, + 0, false, NMessageID::kUpdateMethodMaximum, NULL, NULL }, + { DI_RADIOBUTTON, 6, 8, 0, 0, methodIndex == 5, methodIndex == 5, + 0, false, NMessageID::kUpdateMethodUltra, NULL, NULL }, + + { DI_SINGLEBOX, kXMid, 2, 70, 2 + 5, false, false, 0, false, NMessageID::kUpdateMode, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 3, 0, 0, false, true, + DIF_GROUP, false, NMessageID::kUpdateModeAdd, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 4, 0, 0, false, false, + 0, false, NMessageID::kUpdateModeUpdate, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 5, 0, 0, false, false, + 0, false, NMessageID::kUpdateModeFreshen, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false, false, + 0, false, NMessageID::kUpdateModeSynchronize, NULL, NULL }, + + { DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL }, + + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kUpdateAdd, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL } + }; + + const int kNumDialogItems = sizeof(initItems) / sizeof(initItems[0]); + const int kOkButtonIndex = kNumDialogItems - 2; + FarDialogItem dialogItems[kNumDialogItems]; + g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems); + int askCode = g_StartupInfo.ShowDialog(76, kYSize, + kHelpTopic, dialogItems, kNumDialogItems); + if (askCode != kOkButtonIndex) + return NFileOperationReturnCode::kInterruptedByUser; + + compressionInfo.Level = g_MethodMap[0]; + for (i = 0; i < sizeof(g_MethodMap)/ sizeof(g_MethodMap[0]); i++) + if (dialogItems[kMethodRadioIndex + i].Selected) + compressionInfo.Level = g_MethodMap[i]; + + const CActionSet *actionSet; + + if (dialogItems[kModeRadioIndex].Selected) + actionSet = &kAddActionSet; + else if (dialogItems[kModeRadioIndex + 1].Selected) + actionSet = &kUpdateActionSet; + else if (dialogItems[kModeRadioIndex + 2].Selected) + actionSet = &kFreshActionSet; + else if (dialogItems[kModeRadioIndex + 3].Selected) + actionSet = &kSynchronizeActionSet; + else + throw 51751; + + SaveCompressionInfo(compressionInfo); + + NWorkDir::CInfo workDirInfo; + ReadWorkDirInfo(workDirInfo); + UString workDir = GetWorkDir(workDirInfo, m_FileName); + CreateComplexDirectory(workDir); + + CTempFileW tempFile; + UString tempFileName; + if (tempFile.Create(workDir, kTempArcivePrefix, tempFileName) == 0) + return NFileOperationReturnCode::kError; + + + /* + CSysStringVector fileNames; + for(int i = 0; i < numItems; i++) + { + const PluginPanelItem &panelItem = panelItems[i]; + CSysString fullName; + if (!MyGetFullPathName(panelItem.FindData.cFileName, fullName)) + return NFileOperationReturnCode::kError; + fileNames.Add(fullName); + } + */ + + CScreenRestorer screenRestorer; + CProgressBox progressBox; + CProgressBox *progressBoxPointer = NULL; + if ((opMode & OPM_SILENT) == 0 && (opMode & OPM_FIND ) == 0) + { + screenRestorer.Save(); + + progressBoxPointer = &progressBox; + progressBox.Init(g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kUpdating), 1 << 16); + } + + //////////////////////////// + // Save FolderItem; + UStringVector aPathVector; + GetPathParts(aPathVector); + + /* + 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++) + fileNames.Add(MultiByteToUnicodeString(panelItems[i].FindData.cFileName, CP_OEMCP)); + CRecordVector fileNamePointers; + fileNamePointers.Reserve(numItems); + for(i = 0; i < numItems; i++) + fileNamePointers.Add(fileNames[i]); + + CMyComPtr outArchive; + HRESULT result = m_ArchiveHandler.QueryInterface(IID_IOutFolderArchive, &outArchive); + 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()); + BYTE actionSetByte[NUpdateArchive::NPairState::kNumValues]; + for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) + actionSetByte[i] = actionSet->StateActions[i]; + + CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp; + CMyComPtr updateCallback(updateCallbackSpec ); + + updateCallbackSpec->Init(m_ArchiveHandler, &progressBox); + + if (SetOutProperties(outArchive, compressionInfo.Level) != S_OK) + return NFileOperationReturnCode::kError; + + result = outArchive->DoOperation(NULL, NULL, + tempFileName, 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) + { + ShowErrorMessage(result); + return NFileOperationReturnCode::kError; + } + + _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); + return NFileOperationReturnCode::kError; + } + + /* + if(m_ProxyHandler->ReInit(NULL) != S_OK) + return NFileOperationReturnCode::kError; + */ + + //////////////////////////// + // Restore FolderItem; + + m_ArchiveHandler->BindToRootFolder(&_folder); + for (i = 0; i < aPathVector.Size(); i++) + { + CMyComPtr newFolder; + _folder->BindToFolder(aPathVector[i], &newFolder); + if(!newFolder ) + break; + _folder = newFolder; + } + + /* + if(moveMode != 0) + { + for(int i = 0; i < numItems; i++) + { + const PluginPanelItem &aPluginPanelItem = panelItems[i]; + bool result; + if(NFile::NFind::NAttributes::IsDirectory(aPluginPanelItem.FindData.dwFileAttributes)) + result = NFile::NDirectory::RemoveDirectoryWithSubItems( + aPluginPanelItem.FindData.cFileName); + else + result = NFile::NDirectory::DeleteFileAlways( + aPluginPanelItem.FindData.cFileName); + if(!result) + return NFileOperationReturnCode::kError; + } + } + */ + return NFileOperationReturnCode::kSuccess; +} + + + +/* +// {23170F69-40C1-278A-1000-000100030000} +DEFINE_GUID(CLSID_CAgentArchiveHandler, + 0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00); +*/ + +HRESULT CompressFiles(const CObjectVector &pluginPanelItems) +{ + if (pluginPanelItems.Size() == 0) + return E_FAIL; + + UStringVector fileNames; + for(int i = 0; i < pluginPanelItems.Size(); i++) + { + const PluginPanelItem &panelItem = pluginPanelItems[i]; + CSysString fullName; + if (strcmp(panelItem.FindData.cFileName, "..") == 0 && + NFind::NAttributes::IsDirectory(panelItem.FindData.dwFileAttributes)) + return E_FAIL; + if (strcmp(panelItem.FindData.cFileName, ".") == 0 && + NFind::NAttributes::IsDirectory(panelItem.FindData.dwFileAttributes)) + return E_FAIL; + if (!MyGetFullPathName(panelItem.FindData.cFileName, fullName)) + return E_FAIL; + fileNames.Add(MultiByteToUnicodeString(fullName, CP_OEMCP)); + } + + NCompression::CInfo compressionInfo; + // CZipRegistryManager aZipRegistryManager; + ReadCompressionInfo(compressionInfo); + + int archiverIndex = 0; + + CObjectVector archiverInfoList; + { + CObjectVector fullArchiverInfoList; + ReadArchiverInfoList(fullArchiverInfoList); + for (int i = 0; i < fullArchiverInfoList.Size(); i++) + { + const CArchiverInfo &archiverInfo = fullArchiverInfoList[i]; + if (archiverInfo.UpdateEnabled) + { + if (archiverInfo.Name.CompareNoCase(compressionInfo.ArchiveType) == 0) + archiverIndex = archiverInfoList.Size(); + archiverInfoList.Add(archiverInfo); + } + } + } + if (archiverInfoList.IsEmpty()) + throw "There is no update achivers"; + + + UString resultPath; + { + NName::CParsedPath parsedPath; + parsedPath.ParsePath(fileNames.Front()); + if(parsedPath.PathParts.Size() == 0) + return E_FAIL; + if (fileNames.Size() == 1 || parsedPath.PathParts.Size() == 1) + { + // CSysString pureName, dot, extension; + resultPath = parsedPath.PathParts.Back(); + } + else + { + parsedPath.PathParts.DeleteBack(); + resultPath = parsedPath.PathParts.Back(); + } + } + UString archiveNameSrc = resultPath; + UString archiveName = archiveNameSrc; + + const CArchiverInfo &archiverInfo = archiverInfoList[archiverIndex]; + int prevFormat = archiverIndex; + + if (!archiverInfo.KeepName) + { + int dotPos = archiveName.ReverseFind('.'); + int slashPos = MyMax(archiveName.ReverseFind('\\'), archiveName.ReverseFind('/')); + if (dotPos > slashPos) + archiveName = archiveName.Left(dotPos); + } + archiveName += L'.'; + archiveName += archiverInfo.GetMainExtension(); + + const CActionSet *actionSet = &kAddActionSet; + + for (;;) + { + AString archiveNameA = UnicodeStringToMultiByte(archiveName, CP_OEMCP); + const int kYSize = 16; + const int kXMid = 38; + + const int kArchiveNameIndex = 2; + const int kMethodRadioIndex = kArchiveNameIndex + 2; + const int kModeRadioIndex = kMethodRadioIndex + 7; + + const CArchiverInfo &archiverInfo = archiverInfoList[archiverIndex]; + + char updateAddToArchiveString[512]; + sprintf(updateAddToArchiveString, + g_StartupInfo.GetMsgString(NMessageID::kUpdateAddToArchive), GetSystemString(archiverInfo.Name), CP_OEMCP); + + int methodIndex = 0; + for (int i = sizeof(g_MethodMap) / sizeof(g_MethodMap[0]) - 1; i >= 0; i--) + if (compressionInfo.Level >= g_MethodMap[i]) + { + methodIndex = i; + break; + } + + struct CInitDialogItem initItems[]= + { + { DI_DOUBLEBOX, 3, 1, 72, kYSize - 2, false, false, 0, false, NMessageID::kUpdateTitle, NULL, NULL }, + + { DI_TEXT, 5, 2, 0, 0, false, false, 0, false, -1, updateAddToArchiveString, NULL }, + + { DI_EDIT, 5, 3, 70, 3, true, false, DIF_HISTORY, false, -1, archiveNameA, kArchiveHistoryKeyName}, + // { DI_EDIT, 5, 3, 70, 3, true, false, 0, false, -1, archiveName, NULL}, + + { DI_SINGLEBOX, 4, 4, kXMid - 2, 4 + 7, false, false, 0, false, NMessageID::kUpdateMethod, NULL, NULL }, + { DI_RADIOBUTTON, 6, 5, 0, 0, false, methodIndex == 0, + DIF_GROUP, false, NMessageID::kUpdateMethodStore, NULL, NULL }, + { DI_RADIOBUTTON, 6, 6, 0, 0, false, methodIndex == 1, + 0, false, NMessageID::kUpdateMethodFastest, NULL, NULL }, + { DI_RADIOBUTTON, 6, 7, 0, 0, false, methodIndex == 2, + 0, false, NMessageID::kUpdateMethodFast, NULL, NULL }, + { DI_RADIOBUTTON, 6, 8, 0, 0, false, methodIndex == 3, + 0, false, NMessageID::kUpdateMethodNormal, NULL, NULL }, + { DI_RADIOBUTTON, 6, 9, 0, 0, false, methodIndex == 4, + false, 0, NMessageID::kUpdateMethodMaximum, NULL, NULL }, + { DI_RADIOBUTTON, 6, 10, 0, 0, false, methodIndex == 5, + false, 0, NMessageID::kUpdateMethodUltra, NULL, NULL }, + + { DI_SINGLEBOX, kXMid, 4, 70, 4 + 5, false, false, 0, false, NMessageID::kUpdateMode, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 5, 0, 0, false, + actionSet == &kAddActionSet, + DIF_GROUP, false, NMessageID::kUpdateModeAdd, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 6, 0, 0, false, + actionSet == &kUpdateActionSet, + 0, false, NMessageID::kUpdateModeUpdate, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 7, 0, 0, false, + actionSet == &kFreshActionSet, + 0, false, NMessageID::kUpdateModeFreshen, NULL, NULL }, + { DI_RADIOBUTTON, kXMid + 2, 8, 0, 0, false, + actionSet == &kSynchronizeActionSet, + 0, false, NMessageID::kUpdateModeSynchronize, NULL, NULL }, + + { DI_TEXT, 3, kYSize - 4, 0, 0, false, false, DIF_BOXCOLOR|DIF_SEPARATOR, false, -1, "", NULL }, + + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, true, NMessageID::kUpdateAdd, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kUpdateSelectArchiver, NULL, NULL }, + { DI_BUTTON, 0, kYSize - 3, 0, 0, false, false, DIF_CENTERGROUP, false, NMessageID::kCancel, NULL, NULL } + }; + + const int kNumDialogItems = sizeof(initItems) / sizeof(initItems[0]); + + const int kOkButtonIndex = kNumDialogItems - 3; + const int kSelectarchiverButtonIndex = kNumDialogItems - 2; + + FarDialogItem dialogItems[kNumDialogItems]; + g_StartupInfo.InitDialogItems(initItems, dialogItems, kNumDialogItems); + int askCode = g_StartupInfo.ShowDialog(76, kYSize, + kHelpTopic, dialogItems, kNumDialogItems); + + archiveNameA = dialogItems[kArchiveNameIndex].Data; + archiveNameA.Trim(); + archiveName = MultiByteToUnicodeString(archiveNameA, CP_OEMCP); + + compressionInfo.Level = g_MethodMap[0]; + for (i = 0; i < sizeof(g_MethodMap)/ sizeof(g_MethodMap[0]); i++) + if (dialogItems[kMethodRadioIndex + i].Selected) + compressionInfo.Level = g_MethodMap[i]; + + if (dialogItems[kModeRadioIndex].Selected) + actionSet = &kAddActionSet; + else if (dialogItems[kModeRadioIndex + 1].Selected) + actionSet = &kUpdateActionSet; + else if (dialogItems[kModeRadioIndex + 2].Selected) + actionSet = &kFreshActionSet; + else if (dialogItems[kModeRadioIndex + 3].Selected) + actionSet = &kSynchronizeActionSet; + else + throw 51751; + + if (askCode == kSelectarchiverButtonIndex) + { + CSysStringVector archiverNames; + for(int i = 0; i < archiverInfoList.Size(); i++) + archiverNames.Add(GetSystemString(archiverInfoList[i].Name, + CP_OEMCP)); + + int index = g_StartupInfo.Menu(FMENU_AUTOHIGHLIGHT, + g_StartupInfo.GetMsgString(NMessageID::kUpdateSelectArchiverMenuTitle), + NULL, archiverNames, archiverIndex); + if(index >= 0) + { + const CArchiverInfo &prevArchiverInfo = archiverInfoList[prevFormat]; + if (prevArchiverInfo.KeepName) + { + const UString &prevExtension = prevArchiverInfo.GetMainExtension(); + const int prevExtensionLen = prevExtension.Length(); + if (archiveName.Right(prevExtensionLen).CompareNoCase(prevExtension) == 0) + { + int pos = archiveName.Length() - prevExtensionLen; + UString temp = archiveName.Left(pos); + if (pos > 1) + { + int dotPos = archiveName.ReverseFind('.'); + if (dotPos == pos - 1) + archiveName = archiveName.Left(dotPos); + } + } + } + + archiverIndex = index; + const CArchiverInfo &archiverInfo = + archiverInfoList[archiverIndex]; + prevFormat = archiverIndex; + + if (archiverInfo.KeepName) + archiveName = archiveNameSrc; + else + { + int dotPos = archiveName.ReverseFind('.'); + int slashPos = MyMax(archiveName.ReverseFind('\\'), archiveName.ReverseFind('/')); + if (dotPos > slashPos) + archiveName = archiveName.Left(dotPos); + } + archiveName += L'.'; + archiveName += archiverInfo.GetMainExtension(); + } + continue; + } + + if (askCode != kOkButtonIndex) + return E_ABORT; + + break; + } + + const CArchiverInfo &archiverInfoFinal = archiverInfoList[archiverIndex]; + compressionInfo.ArchiveType = archiverInfoFinal.Name; + SaveCompressionInfo(compressionInfo); + + NWorkDir::CInfo workDirInfo; + ReadWorkDirInfo(workDirInfo); + + UString fullArchiveName; + if (!MyGetFullPathName(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; + + + CScreenRestorer screenRestorer; + CProgressBox progressBox; + CProgressBox *progressBoxPointer = NULL; + + screenRestorer.Save(); + + progressBoxPointer = &progressBox; + progressBox.Init(g_StartupInfo.GetMsgString(NMessageID::kWaitTitle), + g_StartupInfo.GetMsgString(NMessageID::kUpdating), 1 << 16); + + + NFind::CFileInfoW fileInfo; + + CMyComPtr outArchive; + + CMyComPtr archiveHandler; + if(NFind::FindFile(fullArchiveName, fileInfo)) + { + if (fileInfo.IsDirectory()) + throw "There is Directory with such name"; + + CAgent *agentSpec = new CAgent; + archiveHandler = agentSpec; + // CLSID realClassID; + CMyComBSTR archiveType; + RINOK(agentSpec->Open( + GetUnicodeString(fullArchiveName, CP_OEMCP), + // &realClassID, + &archiveType, + NULL)); + + if (archiverInfoFinal.Name.CompareNoCase((const wchar_t *)archiveType) != 0) + throw "Type of existing archive differs from specified type"; + HRESULT result = archiveHandler.QueryInterface( + IID_IOutFolderArchive, &outArchive); + if(result != S_OK) + { + g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); + return E_FAIL; + } + } + else + { + // HRESULT result = outArchive.CoCreateInstance(classID); + CAgent *agentSpec = new CAgent; + outArchive = agentSpec; + + /* + HRESULT result = outArchive.CoCreateInstance(CLSID_CAgentArchiveHandler); + if (result != S_OK) + { + g_StartupInfo.ShowMessage(NMessageID::kUpdateNotSupportedForThisArchive); + return E_FAIL; + } + */ + } + + CRecordVector fileNamePointers; + fileNamePointers.Reserve(fileNames.Size()); + 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()); + BYTE actionSetByte[NUpdateArchive::NPairState::kNumValues]; + for (i = 0; i < NUpdateArchive::NPairState::kNumValues; i++) + actionSetByte[i] = actionSet->StateActions[i]; + + CUpdateCallback100Imp *updateCallbackSpec = new CUpdateCallback100Imp; + CMyComPtr updateCallback(updateCallbackSpec ); + + updateCallbackSpec->Init(archiveHandler, &progressBox); + + + RINOK(SetOutProperties(outArchive, compressionInfo.Level)); + + HRESULT result = outArchive->DoOperation( + GetUnicodeString(archiverInfoFinal.FilePath, CP_OEMCP), + &archiverInfoFinal.ClassID, + tempFileName, actionSetByte, + NULL, updateCallback); + updateCallback.Release(); + outArchive.Release(); + + if (result != S_OK) + { + ShowErrorMessage(result); + return result; + } + + if(archiveHandler) + { + archiveHandler->Close(); + if (!DeleteFileAlways(fullArchiveName)) + { + ShowLastErrorMessage(); + return NFileOperationReturnCode::kError; + } + } + tempFile.DisableDeleting(); + if (!MyMoveFile(tempFileName, fullArchiveName)) + { + ShowLastErrorMessage(); + return E_FAIL; + } + + return S_OK; +} + diff --git a/CPP/7zip/UI/Far/ProgressBox.cpp b/CPP/7zip/UI/Far/ProgressBox.cpp new file mode 100755 index 00000000..64e0e09d --- /dev/null +++ b/CPP/7zip/UI/Far/ProgressBox.cpp @@ -0,0 +1,103 @@ +// ProgressBox.cpp + +#include "StdAfx.h" + +#include + +#include "ProgressBox.h" + +#include "FarUtils.h" + +using namespace NFar; + +static void CopySpaces(char *destString, int numSpaces) +{ + for(int i = 0; i < numSpaces; i++) + destString[i] = ' '; + destString[i] = '\0'; +} + +///////////////////////////////// +// CMessageBox + +const int kNumStringsMax = 10; + +void CMessageBox::Init(const CSysString &title, const CSysString &message, + int numStrings, int width) +{ + if (numStrings > kNumStringsMax) + throw 120620; + m_NumStrings = numStrings; + m_Width = width; + + m_Title = title; + m_Message = message; +} + +const int kNumStaticStrings = 2; + +void CMessageBox::ShowProcessMessages(const char *messages[]) +{ + const char *msgItems[kNumStaticStrings + kNumStringsMax]; + msgItems[0] = m_Title; + msgItems[1] = m_Message; + + char formattedMessages[kNumStringsMax][256]; + + for (int i = 0; i < m_NumStrings; i++) + { + char *formattedMessage = formattedMessages[i]; + int len = strlen(messages[i]); + int size = MyMax(m_Width, len); + int startPos = (size - len) / 2; + CopySpaces(formattedMessage, startPos); + strcpy(formattedMessage + startPos, messages[i]); + CopySpaces(formattedMessage + startPos + len, size - startPos - len); + msgItems[kNumStaticStrings + i] = formattedMessage; + } + + g_StartupInfo.ShowMessage(0, NULL, msgItems, kNumStaticStrings + m_NumStrings, 0); +} + +///////////////////////////////// +// CProgressBox + +void CProgressBox::Init(const CSysString &title, const CSysString &message, + UInt64 step) +{ + CMessageBox::Init(title, message, 1, 22); + m_Step = step; + m_CompletedPrev = 0; + m_Total = 0; +} + + +void CProgressBox::ShowProcessMessage(const char *message) +{ + CMessageBox::ShowProcessMessages(&message); +} + +void CProgressBox::PrintPercent(UInt64 percent) +{ + char valueBuffer[32]; + sprintf(valueBuffer, "%I64u%%", percent); + ShowProcessMessage(valueBuffer); +} + +void CProgressBox::SetTotal(UInt64 total) +{ + m_Total = total; +} + +void CProgressBox::PrintCompeteValue(UInt64 completed) +{ + if (completed >= m_CompletedPrev + m_Step || completed < m_CompletedPrev || + completed == 0) + { + if (m_Total == 0) + PrintPercent(0); + else + PrintPercent(completed * 100 / m_Total); + m_CompletedPrev = completed; + } +} diff --git a/CPP/7zip/UI/Far/ProgressBox.h b/CPP/7zip/UI/Far/ProgressBox.h new file mode 100755 index 00000000..8721b456 --- /dev/null +++ b/CPP/7zip/UI/Far/ProgressBox.h @@ -0,0 +1,35 @@ +// ProgressBox.h + +#ifndef __PROGRESSBOX_H +#define __PROGRESSBOX_H + +#include "Common/String.h" +#include "Common/Types.h" + +class CMessageBox +{ + CSysString m_Title; + CSysString m_Message; + int m_NumStrings; + int m_Width; +public: + void Init(const CSysString &title, + const CSysString &message, int numStrings, int width); + void ShowProcessMessages(const char *messages[]); +}; + +class CProgressBox: public CMessageBox +{ + UInt64 m_Total; + UInt64 m_CompletedPrev; + UInt64 m_Step; +public: + void Init(const CSysString &title, + const CSysString &message, UInt64 step); + void ShowProcessMessage(const char *message); + void PrintPercent(UInt64 percent); + void PrintCompeteValue(UInt64 completed); + void SetTotal(UInt64 total); +}; + +#endif diff --git a/CPP/7zip/UI/Far/StdAfx.cpp b/CPP/7zip/UI/Far/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/UI/Far/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/UI/Far/StdAfx.h b/CPP/7zip/UI/Far/StdAfx.h new file mode 100755 index 00000000..0a7c347b --- /dev/null +++ b/CPP/7zip/UI/Far/StdAfx.h @@ -0,0 +1,12 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include +#include + +#include "Common/NewHandler.h" + +#endif + diff --git a/CPP/7zip/UI/Far/UpdateCallback100.cpp b/CPP/7zip/UI/Far/UpdateCallback100.cpp new file mode 100755 index 00000000..f1a2946e --- /dev/null +++ b/CPP/7zip/UI/Far/UpdateCallback100.cpp @@ -0,0 +1,54 @@ +// UpdateCallback.h + +#include "StdAfx.h" + +#include "UpdateCallback100.h" + +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "FarUtils.h" + +using namespace NFar; + +STDMETHODIMP CUpdateCallback100Imp::SetTotal(UINT64 aSize) +{ + if (m_ProgressBox != 0) + { + m_ProgressBox->SetTotal(aSize); + m_ProgressBox->PrintCompeteValue(0); + } + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::SetCompleted(const UINT64 *aCompleteValue) +{ + if(WasEscPressed()) + return E_ABORT; + if (m_ProgressBox != 0 && aCompleteValue != NULL) + m_ProgressBox->PrintCompeteValue(*aCompleteValue); + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::CompressOperation(const wchar_t *aName) +{ + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::DeleteOperation(const wchar_t *aName) +{ + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::OperationResult(INT32 aOperationResult) +{ + return S_OK; +} + +STDMETHODIMP CUpdateCallback100Imp::UpdateErrorMessage(const wchar_t *message) +{ + CSysString s = UnicodeStringToMultiByte(message, CP_OEMCP); + if (g_StartupInfo.ShowMessage(s) == -1) + return E_ABORT; + return S_OK; +} + diff --git a/CPP/7zip/UI/Far/UpdateCallback100.h b/CPP/7zip/UI/Far/UpdateCallback100.h new file mode 100755 index 00000000..d66137cc --- /dev/null +++ b/CPP/7zip/UI/Far/UpdateCallback100.h @@ -0,0 +1,45 @@ +// UpdateCallback.h + +#ifndef __UPDATECALLBACK100_H +#define __UPDATECALLBACK100_H + +#include "Common/String.h" +#include "Common/MyCom.h" + +#include "../Agent/IFolderArchive.h" + +#include "ProgressBox.h" + +class CUpdateCallback100Imp: + public IFolderArchiveUpdateCallback, + public CMyUnknownImp +{ +public: + MY_UNKNOWN_IMP + + // IProfress + + STDMETHOD(SetTotal)(UINT64 aSize); + STDMETHOD(SetCompleted)(const UINT64 *aCompleteValue); + + // IUpdateCallBack + STDMETHOD(CompressOperation)(const wchar_t *aName); + STDMETHOD(DeleteOperation)(const wchar_t *aName); + STDMETHOD(OperationResult)(INT32 aOperationResult); + STDMETHOD(UpdateErrorMessage)(const wchar_t *message); + +private: + CMyComPtr m_ArchiveHandler; + CProgressBox *m_ProgressBox; +public: + void Init(IInFolderArchive *anArchiveHandler, + CProgressBox *aProgressBox) + { + m_ArchiveHandler = anArchiveHandler; + m_ProgressBox = aProgressBox; + } +}; + + + +#endif diff --git a/CPP/7zip/UI/Far/makefile b/CPP/7zip/UI/Far/makefile new file mode 100755 index 00000000..4dbd1988 --- /dev/null +++ b/CPP/7zip/UI/Far/makefile @@ -0,0 +1,102 @@ +PROG = 7-ZipFar.dll +DEF_FILE = Far.def +LIBS = $(LIBS) user32.lib oleaut32.lib advapi32.lib ole32.lib +CFLAGS = $(CFLAGS) -I ../../../ -DWIN_LONG_PATH + +FAR_OBJS = \ + $O\CLSIDConst.obj \ + $O\ExtractEngine.obj \ + $O\FarUtils.obj \ + $O\Main.obj \ + $O\OverwriteDialog.obj \ + $O\Plugin.obj \ + $O\PluginCommon.obj \ + $O\PluginDelete.obj \ + $O\PluginRead.obj \ + $O\PluginWrite.obj \ + $O\ProgressBox.obj \ + $O\UpdateCallback100.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\IntToString.obj \ + $O\NewHandler.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\DLL.obj \ + $O\Error.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\PropVariant.obj \ + $O\PropVariantConversions.obj \ + $O\Registry.obj \ + $O\Synchronization.obj \ + +7ZIP_COMMON_OBJS = \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\StreamUtils.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveOpenCallback.obj \ + $O\ArchiverInfo.obj \ + $O\DefaultName.obj \ + $O\EnumDirItems.obj \ + $O\ExtractingFilePath.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + $O\SortUtils.obj \ + $O\UpdateAction.obj \ + $O\UpdateCallback.obj \ + $O\UpdatePair.obj \ + $O\UpdateProduce.obj \ + $O\WorkDir.obj \ + $O\ZipRegistry.obj \ + +AGENT_OBJS = \ + $O\Agent.obj \ + $O\AgentOut.obj \ + $O\AgentProxy.obj \ + $O\UpdateCallbackAgent.obj \ + +C_OBJS = \ + $O\Sort.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(FAR_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $(AGENT_OBJS) \ + $(C_OBJS) \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(FAR_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(UI_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$(AGENT_OBJS): ../Agent/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) +$(C_OBJS): ../../../../C/$(*B).c + $(COMPL_O2) diff --git a/CPP/7zip/UI/Far/resource.rc b/CPP/7zip/UI/Far/resource.rc new file mode 100755 index 00000000..a5c2e2f3 --- /dev/null +++ b/CPP/7zip/UI/Far/resource.rc @@ -0,0 +1,3 @@ +#include "../../MyVersionInfo.rc" + +MY_VERSION_INFO_DLL("7-Zip Plugin for FAR Manager", "7-ZipFar") diff --git a/CPP/7zip/UI/GUI/7zG.exe.manifest b/CPP/7zip/UI/GUI/7zG.exe.manifest new file mode 100755 index 00000000..c6ef90e8 --- /dev/null +++ b/CPP/7zip/UI/GUI/7zG.exe.manifest @@ -0,0 +1 @@ +7-Zip GUI. diff --git a/CPP/7zip/UI/GUI/CompressDialog.cpp b/CPP/7zip/UI/GUI/CompressDialog.cpp new file mode 100755 index 00000000..f49bb078 --- /dev/null +++ b/CPP/7zip/UI/GUI/CompressDialog.cpp @@ -0,0 +1,1373 @@ +// CompressDialog.cpp + +#include "StdAfx.h" + +#include "resource.h" +#include "Common/Defs.h" +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "Windows/CommonDialog.h" +#include "Windows/FileDir.h" +#include "Windows/FileName.h" +#include "Windows/ResourceString.h" +#include "Windows/System.h" + +#include "../../FileManager/HelpUtils.h" +#include "../../FileManager/SplitUtils.h" +#include "../../FileManager/FormatUtils.h" + +#include "../Explorer/MyMessages.h" + +#include "../Common/ZipRegistry.h" + +#include "CompressDialog.h" + +#ifndef _UNICODE +extern bool g_IsNT; +#endif + +#ifdef LANG +#include "../../FileManager/LangUtils.h" +#endif + +#include "../Resource/CompressDialog/resource.h" + +#define MY_SIZE_OF_ARRAY(x) (sizeof(x) / sizeof(x[0])) + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDC_STATIC_COMPRESS_ARCHIVE, 0x02000D01 }, + { IDC_STATIC_COMPRESS_FORMAT, 0x02000D03 }, + { IDC_STATIC_COMPRESS_LEVEL, 0x02000D0B }, + { IDC_STATIC_COMPRESS_METHOD, 0x02000D04 }, + { IDC_STATIC_COMPRESS_DICTIONARY, 0x02000D0C }, + { IDC_STATIC_COMPRESS_ORDER, 0x02000D0D }, + { IDC_STATIC_COMPRESS_MEMORY, 0x02000D0E }, + { IDC_STATIC_COMPRESS_MEMORY_DE, 0x02000D0F }, + { IDC_COMPRESS_SOLID, 0x02000D05 }, + { IDC_COMPRESS_MULTI_THREAD, 0x02000D09 }, + { IDC_STATIC_COMPRESS_VOLUME, 0x02000D40 }, + { IDC_STATIC_COMPRESS_PARAMETERS, 0x02000D06 }, + + { IDC_STATIC_COMPRESS_UPDATE_MODE, 0x02000D02 }, + { IDC_STATIC_COMPRESS_OPTIONS, 0x02000D07 }, + { IDC_COMPRESS_SFX, 0x02000D08 }, + + { IDC_COMPRESS_ENCRYPTION, 0x02000D10 }, + { IDC_STATIC_COMPRESS_PASSWORD1, 0x02000B01 }, + { IDC_STATIC_COMPRESS_PASSWORD2, 0x02000B03 }, + { IDC_COMPRESS_CHECK_SHOW_PASSWORD, 0x02000B02 }, + { IDC_STATIC_COMPRESS_ENCRYPTION_METHOD, 0x02000D11 }, + { IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES, 0x02000D0A }, + + { IDOK, 0x02000702 }, + { IDCANCEL, 0x02000710 }, + { IDHELP, 0x02000720 } +}; +#endif + +using namespace NWindows; +using namespace NFile; +using namespace NName; +using namespace NDirectory; + +static const int kHistorySize = 8; + +static LPCWSTR kExeExt = L".exe"; +static LPCWSTR k7zFormat = L"7z"; + +struct CLevelInfo +{ + UInt32 ResourceID; + UInt32 LangID; +}; + +enum ELevel +{ + kStore = 0, + kFastest = 1, + kFast = 3, + kNormal = 5, + kMaximum = 7, + kUltra = 9 +}; + +static const CLevelInfo g_Levels[] = +{ + { IDS_METHOD_STORE, 0x02000D81 }, + { IDS_METHOD_FASTEST, 0x02000D85 }, + { 0, 0 }, + { IDS_METHOD_FAST, 0x02000D84 }, + { 0, 0 }, + { IDS_METHOD_NORMAL, 0x02000D82 }, + { 0, 0 }, + { IDS_METHOD_MAXIMUM, 0x02000D83 }, + { 0, 0 }, + { IDS_METHOD_ULTRA, 0x02000D86 } +}; + +enum EMethodID +{ + kCopy, + kLZMA, + kPPMd, + kBZip2, + kDeflate, + kDeflate64 +}; + +static const LPCWSTR kMethodsNames[] = +{ + L"Copy", + L"LZMA", + L"PPMd", + L"BZip2", + L"Deflate", + L"Deflate64" +}; + +static const EMethodID g_7zMethods[] = +{ + kLZMA, + kPPMd, + kBZip2 +}; + +static const EMethodID g_7zSfxMethods[] = +{ + kCopy, + kLZMA, + kPPMd +}; + +static EMethodID g_ZipMethods[] = +{ + kDeflate, + kDeflate64, + kBZip2 +}; + +static EMethodID g_GZipMethods[] = +{ + kDeflate +}; + +static EMethodID g_BZip2Methods[] = +{ + kBZip2 +}; + +struct CFormatInfo +{ + LPCWSTR Name; + UInt32 LevelsMask; + const EMethodID *MathodIDs; + int NumMethods; + bool Filter; + bool Solid; + bool MultiThread; + bool SFX; + bool Encrypt; + bool EncryptFileNames; +}; + +static const CFormatInfo g_Formats[] = +{ + { + L"", + (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), + 0, 0, + false, false, false, false, false, false + }, + { + k7zFormat, + (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), + g_7zMethods, MY_SIZE_OF_ARRAY(g_7zMethods), + true, true, true, true, true, true + }, + { + L"Zip", + (1 << 0) | (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), + g_ZipMethods, MY_SIZE_OF_ARRAY(g_ZipMethods) , + false, false, true, false, true, false + }, + { + L"GZip", + (1 << 5) | (1 << 7) | (1 << 9), + g_GZipMethods, MY_SIZE_OF_ARRAY(g_GZipMethods), + false, false, false, false, false, false + }, + { + L"BZip2", + (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9), + g_BZip2Methods, + MY_SIZE_OF_ARRAY(g_BZip2Methods), + false, false, true, false, false + }, + { + L"Tar", + (1 << 0), + 0, 0, + false, false, false, false, false, false + } +}; + +static bool IsMethodSupportedBySfx(int methodID) +{ + for (int i = 0; i < MY_SIZE_OF_ARRAY(g_7zSfxMethods); i++) + if (methodID == g_7zSfxMethods[i]) + return true; + return false; +}; + +#ifndef _WIN64 +typedef BOOL (WINAPI *GlobalMemoryStatusExP)(LPMEMORYSTATUSEX lpBuffer); +#endif + +static UInt64 GetPhysicalRamSize() +{ + MEMORYSTATUSEX stat; + stat.dwLength = sizeof(stat); + // return (128 << 20); + #ifdef _WIN64 + if (!::GlobalMemoryStatusEx(&stat)) + return 0; + return stat.ullTotalPhys; + #else + GlobalMemoryStatusExP globalMemoryStatusEx = (GlobalMemoryStatusExP) + ::GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")), + "GlobalMemoryStatusEx"); + if (globalMemoryStatusEx != 0) + if (globalMemoryStatusEx(&stat)) + return stat.ullTotalPhys; + { + MEMORYSTATUS stat; + stat.dwLength = sizeof(stat); + GlobalMemoryStatus(&stat); + return stat.dwTotalPhys; + } + #endif +} + +static UInt64 GetMaxRamSizeForProgram() +{ + UInt64 physSize = GetPhysicalRamSize(); + const UInt64 kMinSysSize = (1 << 24); + if (physSize <= kMinSysSize) + physSize = 0; + else + physSize -= kMinSysSize; + const UInt64 kMinUseSize = (1 << 25); + if (physSize < kMinUseSize) + physSize = kMinUseSize; + return physSize; +} + +bool CCompressDialog::OnInit() +{ + #ifdef LANG + LangSetWindowText(HWND(*this), 0x02000D00); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, MY_SIZE_OF_ARRAY(kIDLangPairs) ); + #endif + _password1Control.Attach(GetItem(IDC_COMPRESS_EDIT_PASSWORD1)); + _password2Control.Attach(GetItem(IDC_COMPRESS_EDIT_PASSWORD2)); + _password1Control.SetText(Info.Password); + _password2Control.SetText(Info.Password); + _encryptionMethod.Attach(GetItem(IDC_COMPRESS_COMBO_ENCRYPTION_METHOD)); + + m_ArchivePath.Attach(GetItem(IDC_COMPRESS_COMBO_ARCHIVE)); + m_Format.Attach(GetItem(IDC_COMPRESS_COMBO_FORMAT)); + m_Level.Attach(GetItem(IDC_COMPRESS_COMBO_LEVEL)); + m_Method.Attach(GetItem(IDC_COMPRESS_COMBO_METHOD)); + m_Dictionary.Attach(GetItem(IDC_COMPRESS_COMBO_DICTIONARY)); + m_Order.Attach(GetItem(IDC_COMPRESS_COMBO_ORDER)); + + m_UpdateMode.Attach(GetItem(IDC_COMPRESS_COMBO_UPDATE_MODE)); + m_Volume.Attach(GetItem(IDC_COMPRESS_COMBO_VOLUME)); + m_Params.Attach(GetItem(IDC_COMPRESS_EDIT_PARAMETERS)); + + AddVolumeItems(m_Volume); + + ReadCompressionInfo(m_RegistryInfo); + CheckButton(IDC_COMPRESS_CHECK_SHOW_PASSWORD, m_RegistryInfo.ShowPassword); + CheckButton(IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES, m_RegistryInfo.EncryptHeaders); + + UpdatePasswordControl(); + + Info.ArchiverInfoIndex = 0; + int i; + for(i = 0; i < m_ArchiverInfoList.Size(); i++) + { + const CArchiverInfo &ai = m_ArchiverInfoList[i]; + m_Format.AddString(ai.Name); + if (ai.Name.CompareNoCase(m_RegistryInfo.ArchiveType) == 0) + Info.ArchiverInfoIndex = i; + } + m_Format.SetCurSel(Info.ArchiverInfoIndex); + + SetArchiveName(Info.ArchiveName); + SetLevel(); + SetParams(); + + for(i = 0; i < m_RegistryInfo.HistoryArchives.Size() && i < kHistorySize; i++) + m_ArchivePath.AddString(m_RegistryInfo.HistoryArchives[i]); + + m_UpdateMode.AddString(LangString(IDS_COMPRESS_UPDATE_MODE_ADD, 0x02000DA1)); + m_UpdateMode.AddString(LangString(IDS_COMPRESS_UPDATE_MODE_UPDATE, 0x02000DA2)); + m_UpdateMode.AddString(LangString(IDS_COMPRESS_UPDATE_MODE_FRESH, 0x02000DA3)); + m_UpdateMode.AddString(LangString(IDS_COMPRESS_UPDATE_MODE_SYNCHRONIZE, 0x02000DA4)); + + m_UpdateMode.SetCurSel(0); + + Info.Solid = m_RegistryInfo.Solid; + Info.MultiThread = m_RegistryInfo.MultiThread; + + CheckButton(IDC_COMPRESS_SOLID, Info.Solid); + CheckButton(IDC_COMPRESS_MULTI_THREAD, Info.MultiThread); + CheckButton(IDC_COMPRESS_SFX, Info.SFXMode); + + CheckControlsEnable(); + + OnButtonSFX(); + + SetEncryptionMethod(); + return CModalDialog::OnInit(); +} + +namespace NCompressDialog +{ + bool CInfo::GetFullPathName(UString &result) const + { + NDirectory::MySetCurrentDirectory(CurrentDirPrefix); + return MyGetFullPathName(ArchiveName, result); + } +} + +void CCompressDialog::UpdatePasswordControl() +{ + bool showPassword = IsShowPasswordChecked(); + TCHAR c = showPassword ? 0: TEXT('*'); + _password1Control.SetPasswordChar(c); + _password2Control.SetPasswordChar(c); + UString password; + _password1Control.GetText(password); + _password1Control.SetText(password); + _password2Control.GetText(password); + _password2Control.SetText(password); + + int cmdShow = showPassword ? SW_HIDE : SW_SHOW; + ShowItem(IDC_STATIC_COMPRESS_PASSWORD2, cmdShow); + _password2Control.Show(cmdShow); +} + +bool CCompressDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + switch(buttonID) + { + case IDC_COMPRESS_BUTTON_SET_ARCHIVE: + { + OnButtonSetArchive(); + return true; + } + case IDC_COMPRESS_SFX: + { + OnButtonSFX(); + return true; + } + case IDC_COMPRESS_CHECK_SHOW_PASSWORD: + { + UpdatePasswordControl(); + return true; + } + case IDC_COMPRESS_MULTI_THREAD: + { + SetMemoryUsage(); + return true; + } + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +static bool IsMultiProcessor() +{ + return NSystem::GetNumberOfProcessors() > 1; +} + +void CCompressDialog::CheckSFXControlsEnable() +{ + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + bool enable = fi.SFX; + if (enable) + { + int methodID = GetMethodID(); + enable = (methodID == -1 || IsMethodSupportedBySfx(methodID)); + } + if (!enable) + CheckButton(IDC_COMPRESS_SFX, false); + EnableItem(IDC_COMPRESS_SFX, enable); +} + +void CCompressDialog::CheckVolumeEnable() +{ + bool isSFX = IsSFX(); + m_Volume.Enable(!isSFX); + if (isSFX) + m_Volume.SetText(TEXT("")); +} + +void CCompressDialog::CheckControlsEnable() +{ + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + Info.SolidIsAllowed = fi.Solid; + bool multiThreadEnable = fi.MultiThread & IsMultiProcessor(); + Info.MultiThreadIsAllowed = multiThreadEnable; + Info.EncryptHeadersIsAllowed = fi.EncryptFileNames; + + EnableItem(IDC_COMPRESS_SOLID, fi.Solid); + EnableItem(IDC_COMPRESS_MULTI_THREAD, multiThreadEnable); + CheckSFXControlsEnable(); + CheckVolumeEnable(); + + EnableItem(IDC_COMPRESS_ENCRYPTION, fi.Encrypt); + + EnableItem(IDC_STATIC_COMPRESS_PASSWORD1, fi.Encrypt); + EnableItem(IDC_STATIC_COMPRESS_PASSWORD2, fi.Encrypt); + EnableItem(IDC_COMPRESS_EDIT_PASSWORD1, fi.Encrypt); + EnableItem(IDC_COMPRESS_EDIT_PASSWORD2, fi.Encrypt); + EnableItem(IDC_COMPRESS_CHECK_SHOW_PASSWORD, fi.Encrypt); + + EnableItem(IDC_STATIC_COMPRESS_ENCRYPTION_METHOD, fi.Encrypt); + EnableItem(IDC_COMPRESS_COMBO_ENCRYPTION_METHOD, fi.Encrypt); + EnableItem(IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES, fi.EncryptFileNames); +} + +bool CCompressDialog::IsSFX() +{ + CWindow sfxButton = GetItem(IDC_COMPRESS_SFX); + return sfxButton.IsEnabled() && IsButtonCheckedBool(IDC_COMPRESS_SFX); +} + +void CCompressDialog::OnButtonSFX() +{ + SetMethod(); + + UString fileName; + m_ArchivePath.GetText(fileName); + int dotPos = fileName.ReverseFind(L'.'); + int slashPos = fileName.ReverseFind(L'\\'); + if (dotPos < 0 || dotPos <= slashPos) + dotPos = -1; + bool isSFX = IsSFX(); + if (isSFX) + { + if (dotPos >= 0) + fileName = fileName.Left(dotPos); + fileName += kExeExt; + m_ArchivePath.SetText(fileName); + } + else + { + if (dotPos >= 0) + { + UString ext = fileName.Mid(dotPos); + if (ext.CompareNoCase(kExeExt) == 0) + { + fileName = fileName.Left(dotPos); + m_ArchivePath.SetText(fileName); + } + } + SetArchiveName2(false); // it's for OnInit + } + + CheckVolumeEnable(); +} + +void CCompressDialog::OnButtonSetArchive() +{ + UString fileName; + m_ArchivePath.GetText(fileName); + fileName.Trim(); + Info.ArchiveName = fileName; + UString fullFileName; + if (!Info.GetFullPathName(fullFileName)) + { + fullFileName = Info.ArchiveName; + return; + } + UString title = LangString(IDS_COMPRESS_SET_ARCHIVE_DIALOG_TITLE, 0x02000D90); + UString s = LangString(IDS_OPEN_TYPE_ALL_FILES, 0x02000DB1); + s += L" (*.*)"; + UString resPath; + if (!MyGetOpenFileName(HWND(*this), title, fullFileName, s, resPath)) + return; + m_ArchivePath.SetText(resPath); +} + +// in ExtractDialog.cpp +extern void AddUniqueString(UStringVector &strings, const UString &srcString); + +static bool IsAsciiString(const UString &s) +{ + for (int i = 0; i < s.Length(); i++) + { + wchar_t c = s[i]; + if (c < 0x20 || c > 0x7F) + return false; + } + return true; +} + +void CCompressDialog::OnOK() +{ + _password1Control.GetText(Info.Password); + if (IsZipFormat()) + { + if (!IsAsciiString(Info.Password)) + { + MyMessageBoxResource(*this, IDS_PASSWORD_USE_ASCII, 0x02000B11); + return; + } + UString method = GetEncryptionMethodSpec(); + method.MakeUpper(); + if (method.Find(L"AES") == 0) + { + if (Info.Password.Length() > 99) + { + MyMessageBoxResource(*this, IDS_PASSWORD_IS_TOO_LONG, 0x02000B12); + return; + } + } + } + if (!IsShowPasswordChecked()) + { + UString password2; + _password2Control.GetText(password2); + if (password2 != Info.Password) + { + MyMessageBoxResource(*this, IDS_PASSWORD_PASSWORDS_DO_NOT_MATCH, 0x02000B10); + return; + } + } + + SaveOptionsInMem(); + UString s; + m_ArchivePath.GetText(s); + s.Trim(); + m_RegistryInfo.HistoryArchives.Clear(); + AddUniqueString(m_RegistryInfo.HistoryArchives, s); + Info.ArchiveName = s; + Info.UpdateMode = NCompressDialog::NUpdateMode::EEnum(m_UpdateMode.GetCurSel()); + + Info.Level = GetLevelSpec(); + Info.Dictionary = GetDictionarySpec(); + Info.Order = GetOrderSpec(); + Info.OrderMode = GetOrderMode(); + Info.Method = GetMethodSpec(); + Info.EncryptionMethod = GetEncryptionMethodSpec(); + + Info.ArchiverInfoIndex = m_Format.GetCurSel(); + + Info.SFXMode = IsSFX(); + m_RegistryInfo.Solid = Info.Solid = IsButtonCheckedBool(IDC_COMPRESS_SOLID); + m_RegistryInfo.MultiThread = Info.MultiThread = IsMultiThread(); + m_RegistryInfo.EncryptHeaders = Info.EncryptHeaders = IsButtonCheckedBool(IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES); + + m_Params.GetText(Info.Options); + UString volumeString; + m_Volume.GetText(volumeString); + volumeString.Trim(); + Info.VolumeSizes.Clear(); + if (!volumeString.IsEmpty()) + { + if (!ParseVolumeSizes(volumeString, Info.VolumeSizes)) + { + MyMessageBoxResource(*this, IDS_COMPRESS_INCORRECT_VOLUME_SIZE, 0x02000D41); + return; + } + if (!Info.VolumeSizes.IsEmpty()) + { + const UInt64 volumeSize = Info.VolumeSizes.Back(); + if (volumeSize < (100 << 10)) + { + wchar_t s[32]; + ConvertUInt64ToString(volumeSize, s); + if (::MessageBoxW(*this, MyFormatNew(IDS_COMPRESS_SPLIT_CONFIRM_MESSAGE, 0x02000D42, s), + L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION | MB_TASKMODAL) != IDYES) + return; + } + } + } + + for(int i = 0; i < m_ArchivePath.GetCount(); i++) + { + UString sTemp; + m_ArchivePath.GetLBText(i, sTemp); + sTemp.Trim(); + AddUniqueString(m_RegistryInfo.HistoryArchives, sTemp); + } + if (m_RegistryInfo.HistoryArchives.Size() > kHistorySize) + m_RegistryInfo.HistoryArchives.DeleteBack(); + + //////////////////// + // Method + + m_RegistryInfo.Level = Info.Level; + m_RegistryInfo.ArchiveType = m_ArchiverInfoList[Info.ArchiverInfoIndex].Name; + + m_RegistryInfo.ShowPassword = IsShowPasswordChecked(); + + SaveCompressionInfo(m_RegistryInfo); + + CModalDialog::OnOK(); +} + +static LPCWSTR kHelpTopic = L"fm/plugins/7-zip/add.htm"; + +void CCompressDialog::OnHelp() +{ + ShowHelpWindow(NULL, kHelpTopic); +} + +bool CCompressDialog::OnCommand(int code, int itemID, LPARAM lParam) +{ + if (code == CBN_SELCHANGE) + { + switch(itemID) + { + case IDC_COMPRESS_COMBO_FORMAT: + { + OnChangeFormat(); + return true; + } + case IDC_COMPRESS_COMBO_LEVEL: + { + const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; + int index = FindRegistryFormatAlways(ai.Name); + NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; + fo.ResetForLevelChange(); + SetMethod(); + CheckSFXNameChange(); + return true; + } + case IDC_COMPRESS_COMBO_METHOD: + { + SetDictionary(); + SetOrder(); + CheckSFXNameChange(); + return true; + } + case IDC_COMPRESS_COMBO_DICTIONARY: + case IDC_COMPRESS_COMBO_ORDER: + { + SetMemoryUsage(); + return true; + } + } + } + return CModalDialog::OnCommand(code, itemID, lParam); +} + +void CCompressDialog::CheckSFXNameChange() +{ + bool isSFX = IsSFX(); + CheckSFXControlsEnable(); + if (isSFX != IsSFX()) + SetArchiveName2(isSFX); +} + +void CCompressDialog::SetArchiveName2(bool prevWasSFX) +{ + UString fileName; + m_ArchivePath.GetText(fileName); + const CArchiverInfo &prevArchiverInfo = m_ArchiverInfoList[m_PrevFormat]; + if (prevArchiverInfo.KeepName || Info.KeepName) + { + UString prevExtension = prevArchiverInfo.GetMainExtension(); + if (prevWasSFX) + prevExtension = kExeExt; + else + prevExtension = UString('.') + prevExtension; + const int prevExtensionLen = prevExtension.Length(); + if (fileName.Length() >= prevExtensionLen) + if (fileName.Right(prevExtensionLen).CompareNoCase(prevExtension) == 0) + fileName = fileName.Left(fileName.Length() - prevExtensionLen); + } + SetArchiveName(fileName); +} + +void CCompressDialog::OnChangeFormat() +{ + bool isSFX = IsSFX(); + SaveOptionsInMem(); + SetLevel(); + SetParams(); + CheckControlsEnable(); + SetArchiveName2(isSFX); + SetEncryptionMethod(); +} + +// if type.KeepName then use OriginalFileName +// else if !KeepName remove extension +// add new extension + +void CCompressDialog::SetArchiveName(const UString &name) +{ + UString fileName = name; + Info.ArchiverInfoIndex = m_Format.GetCurSel(); + const CArchiverInfo &ai = m_ArchiverInfoList[Info.ArchiverInfoIndex]; + m_PrevFormat = Info.ArchiverInfoIndex; + if (ai.KeepName) + { + fileName = OriginalFileName; + } + else + { + if (!Info.KeepName) + { + int dotPos = fileName.ReverseFind('.'); + int slashPos = MyMax(fileName.ReverseFind('\\'), fileName.ReverseFind('/')); + if (dotPos >= 0 && dotPos > slashPos + 1) + fileName = fileName.Left(dotPos); + } + } + + if (IsSFX()) + fileName += kExeExt; + else + { + fileName += L'.'; + fileName += ai.GetMainExtension(); + } + m_ArchivePath.SetText(fileName); +} + +int CCompressDialog::FindRegistryFormat(const UString &name) +{ + for (int i = 0; i < m_RegistryInfo.FormatOptionsVector.Size(); i++) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[i]; + if (GetUnicodeString(fo.FormatID) == name) + return i; + } + return -1; +} + +int CCompressDialog::FindRegistryFormatAlways(const UString &name) +{ + int index = FindRegistryFormat(name); + if (index < 0) + { + NCompression::CFormatOptions fo; + fo.FormatID = GetSystemString(name); + index = m_RegistryInfo.FormatOptionsVector.Add(fo); + } + return index; +} + +int CCompressDialog::GetStaticFormatIndex() +{ + int formatIndex = m_Format.GetCurSel(); + const CArchiverInfo &ai = m_ArchiverInfoList[formatIndex]; + for (int i = 0; i < MY_SIZE_OF_ARRAY(g_Formats); i++) + if (ai.Name.CompareNoCase(g_Formats[i].Name) == 0) + return i; + return 0; // -1; +} + +void CCompressDialog::SetNearestSelectComboBox( + NControl::CComboBox &comboBox, UInt32 value) +{ + for (int i = comboBox.GetCount() - 1; i >= 0; i--) + if ((UInt32)comboBox.GetItemData(i) <= value) + { + comboBox.SetCurSel(i); + return; + } + if (comboBox.GetCount() > 0) + comboBox.SetCurSel(0); +} + +void CCompressDialog::SetLevel() +{ + m_Level.ResetContent(); + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; + int index = FindRegistryFormat(ai.Name); + UInt32 level = kNormal; + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; + if (fo.Level <= kUltra) + level = fo.Level; + else + level = kUltra; + } + int i; + for (i = 0; i <= kUltra; i++) + { + if ((fi.LevelsMask & (1 << i)) != 0) + { + const CLevelInfo &levelInfo = g_Levels[i]; + int index = (int)m_Level.AddString(LangString(levelInfo.ResourceID, levelInfo.LangID)); + m_Level.SetItemData(index, i); + } + } + SetNearestSelectComboBox(m_Level, level); + SetMethod(); +} + +int CCompressDialog::GetLevel() +{ + if (m_Level.GetCount() <= 0) + return -1; + return (int)m_Level.GetItemData(m_Level.GetCurSel()); +} + +int CCompressDialog::GetLevelSpec() +{ + if (m_Level.GetCount() <= 1) + return -1; + return GetLevel(); +} + +int CCompressDialog::GetLevel2() +{ + int level = GetLevel(); + if (level < 0) + level = 5; + return level; +} + +bool CCompressDialog::IsMultiThread() +{ + /* + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + bool multiThreadEnable = fi.MultiThread & IsMultiProcessor(); + if (!multiThreadEnable) + return false; + */ + return IsButtonCheckedBool(IDC_COMPRESS_MULTI_THREAD); +} + +void CCompressDialog::SetMethod() +{ + m_Method.ResetContent(); + if (GetLevel() <= 0) + { + SetDictionary(); + SetOrder(); + return; + } + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; + int index = FindRegistryFormat(ai.Name); + UString defaultMethod; + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; + defaultMethod = fo.Method; + } + bool isSfx = IsSFX(); + for(int m = 0; m < fi.NumMethods; m++) + { + EMethodID methodID = fi.MathodIDs[m]; + if (isSfx) + if (!IsMethodSupportedBySfx(methodID)) + continue; + const LPCWSTR method = kMethodsNames[methodID]; + int itemIndex = (int)m_Method.AddString(GetSystemString(method)); + if (defaultMethod.CompareNoCase(method) == 0 || m == 0) + m_Method.SetCurSel(itemIndex); + } + SetDictionary(); + SetOrder(); +} + +bool CCompressDialog::IsZipFormat() +{ + const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; + return (ai.Name.CompareNoCase(L"zip") == 0); +} + +void CCompressDialog::SetEncryptionMethod() +{ + _encryptionMethod.ResetContent(); + const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; + if (ai.Name.CompareNoCase(L"7z") == 0) + { + _encryptionMethod.AddString(TEXT("AES-256")); + _encryptionMethod.SetCurSel(0); + } + else if (ai.Name.CompareNoCase(L"zip") == 0) + { + int index = FindRegistryFormat(ai.Name); + UString encryptionMethod; + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; + encryptionMethod = fo.EncryptionMethod; + } + _encryptionMethod.AddString(TEXT("ZipCrypto")); + _encryptionMethod.AddString(TEXT("AES-256")); + _encryptionMethod.SetCurSel(encryptionMethod.Find(L"AES") == 0 ? 1 : 0); + } +} + +int CCompressDialog::GetMethodID() +{ + UString methodName; + m_Method.GetText(methodName); + for (int i = 0; i < MY_SIZE_OF_ARRAY(kMethodsNames); i++) + if (methodName.CompareNoCase(kMethodsNames[i]) == 0) + return i; + return -1; +} + +UString CCompressDialog::GetMethodSpec() +{ + if (m_Method.GetCount() <= 1) + return UString(); + UString result; + m_Method.GetText(result); + return result; +} + +UString CCompressDialog::GetEncryptionMethodSpec() +{ + if (m_Method.GetCount() <= 1) + return UString(); + if (_encryptionMethod.GetCurSel() <= 0) + return UString(); + UString result; + _encryptionMethod.GetText(result); + result.Replace(L"-", L""); + return result; +} + +int CCompressDialog::AddDictionarySize(UInt32 size, bool kilo, bool maga) +{ + UInt32 sizePrint = size; + if (kilo) + sizePrint >>= 10; + else if (maga) + sizePrint >>= 20; + TCHAR s[40]; + ConvertUInt64ToString(sizePrint, s); + if (kilo) + lstrcat(s, TEXT(" K")); + else if (maga) + lstrcat(s, TEXT(" M")); + else + lstrcat(s, TEXT(" ")); + lstrcat(s, TEXT("B")); + int index = (int)m_Dictionary.AddString(s); + m_Dictionary.SetItemData(index, size); + return index; +} + +int CCompressDialog::AddDictionarySize(UInt32 size) +{ + if (size > 0) + { + if ((size & 0xFFFFF) == 0) + return AddDictionarySize(size, false, true); + if ((size & 0x3FF) == 0) + return AddDictionarySize(size, true, false); + } + return AddDictionarySize(size, false, false); +} + +void CCompressDialog::SetDictionary() +{ + m_Dictionary.ResetContent(); + const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; + int index = FindRegistryFormat(ai.Name); + UInt32 defaultDictionary = UInt32(-1); + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; + if (fo.Method.CompareNoCase(GetMethodSpec()) == 0) + defaultDictionary = fo.Dictionary; + } + int methodID = GetMethodID(); + int level = GetLevel2(); + if (methodID < 0) + { + SetMemoryUsage(); + return; + } + const UInt64 maxRamSize = GetMaxRamSizeForProgram(); + switch (methodID) + { + case kLZMA: + { + static const UInt32 kMinDicSize = (1 << 16); + if (defaultDictionary == UInt32(-1)) + { + if (level >= 9) + defaultDictionary = (1 << 26); + else if (level >= 7) + defaultDictionary = (1 << 24); + else if (level >= 5) + defaultDictionary = (1 << 22); + else if (level >= 3) + defaultDictionary = (1 << 20); + else + defaultDictionary = (kMinDicSize); + } + int i; + AddDictionarySize(kMinDicSize); + m_Dictionary.SetCurSel(0); + for (i = 20; i <= 30; i++) + for (int j = 0; j < 2; j++) + { + if (i == 20 && j > 0) + continue; + UInt32 dictionary = (1 << i) + (j << (i - 1)); + if (dictionary > + #ifdef _WIN64 + (1 << 30) + #else + (1 << 27) + #endif + ) + continue; + AddDictionarySize(dictionary); + UInt64 decomprSize; + UInt64 requiredComprSize = GetMemoryUsage(dictionary, false, decomprSize); + if (dictionary <= defaultDictionary && requiredComprSize <= maxRamSize) + m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1); + } + + // SetNearestSelectComboBox(m_Dictionary, defaultDictionary); + break; + } + case kPPMd: + { + if (defaultDictionary == UInt32(-1)) + { + if (level >= 9) + defaultDictionary = (192 << 20); + else if (level >= 7) + defaultDictionary = (64 << 20); + else if (level >= 5) + defaultDictionary = (16 << 20); + else + defaultDictionary = (4 << 20); + } + int i; + for (i = 20; i < 31; i++) + for (int j = 0; j < 2; j++) + { + if (i == 20 && j > 0) + continue; + UInt32 dictionary = (1 << i) + (j << (i - 1)); + if (dictionary >= (1 << 31)) + continue; + AddDictionarySize(dictionary); + UInt64 decomprSize; + UInt64 requiredComprSize = GetMemoryUsage(dictionary, false, decomprSize); + if (dictionary <= defaultDictionary && requiredComprSize <= maxRamSize || m_Dictionary.GetCount() == 0) + m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1); + } + SetNearestSelectComboBox(m_Dictionary, defaultDictionary); + break; + } + case kDeflate: + { + AddDictionarySize(32 << 10); + m_Dictionary.SetCurSel(0); + break; + } + case kDeflate64: + { + AddDictionarySize(64 << 10); + m_Dictionary.SetCurSel(0); + break; + } + case kBZip2: + { + UInt32 defaultDictionary; + if (level >= 5) + defaultDictionary = (900 << 10); + else if (level >= 3) + defaultDictionary = (500 << 10); + else + defaultDictionary = (100 << 10); + for (int i = 1; i <= 9; i++) + { + UInt32 dictionary = (i * 100) << 10; + AddDictionarySize(dictionary); + if (dictionary <= defaultDictionary || m_Dictionary.GetCount() == 0) + m_Dictionary.SetCurSel(m_Dictionary.GetCount() - 1); + } + break; + } + } + SetMemoryUsage(); +} + +UInt32 CCompressDialog::GetDictionary() +{ + if (m_Dictionary.GetCount() <= 0) + return (UInt32)-1; + return (UInt32)m_Dictionary.GetItemData(m_Dictionary.GetCurSel()); +} + +UInt32 CCompressDialog::GetDictionarySpec() +{ + if (m_Dictionary.GetCount() <= 1) + return (UInt32)-1; + return GetDictionary(); +} + +int CCompressDialog::AddOrder(UInt32 size) +{ + TCHAR s[40]; + ConvertUInt64ToString(size, s); + int index = (int)m_Order.AddString(s); + m_Order.SetItemData(index, size); + return index; +} + +void CCompressDialog::SetOrder() +{ + m_Order.ResetContent(); + const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; + int index = FindRegistryFormat(ai.Name); + UInt32 defaultOrder = UInt32(-1); + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; + if (fo.Method.CompareNoCase(GetMethodSpec()) == 0) + defaultOrder = fo.Order; + } + int methodID = GetMethodID(); + int level = GetLevel2(); + if (methodID < 0) + { + SetMemoryUsage(); + return; + } + switch (methodID) + { + case kLZMA: + { + if (defaultOrder == UInt32(-1)) + defaultOrder = (level >= 7) ? 64 : 32; + for (int i = 3; i <= 8; i++) + for (int j = 0; j < 2; j++) + { + UInt32 order = (1 << i) + (j << (i - 1)); + if (order <= 256) + AddOrder(order); + } + AddOrder(273); + SetNearestSelectComboBox(m_Order, defaultOrder); + break; + } + case kPPMd: + { + if (defaultOrder == UInt32(-1)) + { + if (level >= 9) + defaultOrder = 32; + else if (level >= 7) + defaultOrder = 16; + else if (level >= 5) + defaultOrder = 6; + else + defaultOrder = 4; + } + int i; + AddOrder(2); + AddOrder(3); + for (i = 2; i < 8; i++) + for (int j = 0; j < 4; j++) + { + UInt32 order = (1 << i) + (j << (i - 2)); + if (order < 32) + AddOrder(order); + } + AddOrder(32); + SetNearestSelectComboBox(m_Order, defaultOrder); + break; + } + case kDeflate: + case kDeflate64: + { + if (defaultOrder == UInt32(-1)) + { + if (level >= 9) + defaultOrder = 128; + else if (level >= 7) + defaultOrder = 64; + else + defaultOrder = 32; + } + int i; + for (i = 3; i <= 8; i++) + for (int j = 0; j < 2; j++) + { + UInt32 order = (1 << i) + (j << (i - 1)); + if (order <= 256) + AddOrder(order); + } + AddOrder(methodID == kDeflate64 ? 257 : 258); + SetNearestSelectComboBox(m_Order, defaultOrder); + break; + } + case kBZip2: + { + break; + } + } + SetMemoryUsage(); +} + +bool CCompressDialog::GetOrderMode() +{ + switch (GetMethodID()) + { + case kPPMd: + return true; + } + return false; +} + +UInt32 CCompressDialog::GetOrder() +{ + if (m_Order.GetCount() <= 0) + return (UInt32)-1; + return (UInt32)m_Order.GetItemData(m_Order.GetCurSel()); +} + +UInt32 CCompressDialog::GetOrderSpec() +{ + if (m_Order.GetCount() <= 1) + return (UInt32)-1; + return GetOrder(); +} + +UInt64 CCompressDialog::GetMemoryUsage(UInt32 dictionary, bool isMultiThread, UInt64 &decompressMemory) +{ + decompressMemory = UInt64(Int64(-1)); + int level = GetLevel2(); + if (level == 0) + { + decompressMemory = (1 << 20); + return decompressMemory; + } + UInt64 size = 0; + + const CFormatInfo &fi = g_Formats[GetStaticFormatIndex()]; + if (fi.Filter && level >= 9) + size += (12 << 20) * 2 + (5 << 20); + switch (GetMethodID()) + { + case kLZMA: + { + UInt32 hs = dictionary - 1; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + hs >>= 1; + hs |= 0xFFFF; + if (hs > (1 << 24)) + hs >>= 1; + hs++; + size += hs * 4; + size += (UInt64)dictionary * 11 / 2; + if (level >= 5) + size += dictionary * 4; + size += (2 << 20); + if (isMultiThread && level >= 5) + size += (2 << 20) + (4 << 20); + + decompressMemory = dictionary + (2 << 20); + return size; + } + case kPPMd: + { + decompressMemory = dictionary + (2 << 20); + return size + decompressMemory; + } + case kDeflate: + case kDeflate64: + { + UInt32 order = GetOrder(); + if (order == UInt32(-1)) + order = 32; + if (level >= 7) + size += (1 << 20); + size += 3 << 20; + decompressMemory = (2 << 20); + return size; + } + case kBZip2: + { + decompressMemory = (7 << 20); + UInt64 memForOneThread = (10 << 20); + if (isMultiThread) + memForOneThread *= NSystem::GetNumberOfProcessors(); + return size + (10 << 20); + } + } + return UInt64(Int64(-1)); +} + +UInt64 CCompressDialog::GetMemoryUsage(UInt64 &decompressMemory) +{ + return GetMemoryUsage(GetDictionary(), IsMultiThread(), decompressMemory); +} + +void CCompressDialog::PrintMemUsage(UINT res, UInt64 value) +{ + if (value == (UInt64)Int64(-1)) + { + SetItemText(res, TEXT("?")); + return; + } + value = (value + (1 << 20) - 1) >> 20; + TCHAR s[40]; + ConvertUInt64ToString(value, s); + lstrcat(s, TEXT(" MB")); + SetItemText(res, s); +} + +void CCompressDialog::SetMemoryUsage() +{ + UInt64 decompressMem; + UInt64 memUsage = GetMemoryUsage(decompressMem); + PrintMemUsage(IDC_STATIC_COMPRESS_MEMORY_VALUE, memUsage); + PrintMemUsage(IDC_STATIC_COMPRESS_MEMORY_DE_VALUE, decompressMem); +} + +void CCompressDialog::SetParams() +{ + const CArchiverInfo &ai = m_ArchiverInfoList[m_Format.GetCurSel()]; + m_Params.SetText(TEXT("")); + int index = FindRegistryFormat(ai.Name); + if (index >= 0) + { + const NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; + m_Params.SetText(fo.Options); + } +} + +void CCompressDialog::SaveOptionsInMem() +{ + const CArchiverInfo &ai = m_ArchiverInfoList[Info.ArchiverInfoIndex]; + int index = FindRegistryFormatAlways(ai.Name); + m_Params.GetText(Info.Options); + Info.Options.Trim(); + NCompression::CFormatOptions &fo = m_RegistryInfo.FormatOptionsVector[index]; + fo.Options = Info.Options; + fo.Level = GetLevelSpec(); + fo.Dictionary = GetDictionarySpec(); + fo.Order = GetOrderSpec(); + fo.Method = GetMethodSpec(); + fo.EncryptionMethod = GetEncryptionMethodSpec(); +} diff --git a/CPP/7zip/UI/GUI/CompressDialog.h b/CPP/7zip/UI/GUI/CompressDialog.h new file mode 100755 index 00000000..87cf5d79 --- /dev/null +++ b/CPP/7zip/UI/GUI/CompressDialog.h @@ -0,0 +1,171 @@ +// CompressDialog.h + +#ifndef __COMPRESSDIALOG_H +#define __COMPRESSDIALOG_H + +#include "../Common/ZipRegistry.h" +#include "../Common/ArchiverInfo.h" +#include "../Resource/CompressDialog/resource.h" + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/Edit.h" +#include "Windows/Control/ComboBox.h" + +namespace NCompressDialog +{ + namespace NUpdateMode + { + enum EEnum + { + kAdd, + kUpdate, + kFresh, + kSynchronize, + }; + } + struct CInfo + { + NUpdateMode::EEnum UpdateMode; + bool SolidIsAllowed; + bool Solid; + + bool MultiThreadIsAllowed; + bool MultiThread; + + CRecordVector VolumeSizes; + + UInt32 Level; + UString Method; + UInt32 Dictionary; + bool OrderMode; + UInt32 Order; + UString Options; + + UString EncryptionMethod; + + bool SFXMode; + + UString ArchiveName; // in: Relative for ; out: abs + UString CurrentDirPrefix; + bool KeepName; + + bool GetFullPathName(UString &result) const; + + int ArchiverInfoIndex; + + UString Password; + bool EncryptHeadersIsAllowed; + bool EncryptHeaders; + + void Init() + { + Level = Dictionary = Order = UInt32(-1); + OrderMode = false; + Method.Empty(); + Options.Empty(); + EncryptionMethod.Empty(); + } + CInfo() + { + Init(); + } + }; +} + +class CCompressDialog: public NWindows::NControl::CModalDialog +{ + NWindows::NControl::CComboBox m_ArchivePath; + NWindows::NControl::CComboBox m_Format; + NWindows::NControl::CComboBox m_Level; + NWindows::NControl::CComboBox m_Method; + NWindows::NControl::CComboBox m_Dictionary; + NWindows::NControl::CComboBox m_Order; + NWindows::NControl::CComboBox m_UpdateMode; + NWindows::NControl::CComboBox m_Volume; + NWindows::NControl::CDialogChildControl m_Params; + + NWindows::NControl::CEdit _password1Control; + NWindows::NControl::CEdit _password2Control; + NWindows::NControl::CComboBox _encryptionMethod; + + NCompression::CInfo m_RegistryInfo; + + int m_PrevFormat; + void SetArchiveName(const UString &name); + int FindRegistryFormat(const UString &name); + int FindRegistryFormatAlways(const UString &name); + + void OnChangeFormat(); + void CheckSFXNameChange(); + void SetArchiveName2(bool prevWasSFX); + + int GetStaticFormatIndex(); + + void SetNearestSelectComboBox(NWindows::NControl::CComboBox &comboBox, UInt32 value); + + void SetLevel(); + int GetLevel(); + int GetLevelSpec(); + int GetLevel2(); + bool IsMultiThread(); + + void SetMethod(); + int GetMethodID(); + UString GetMethodSpec(); + UString GetEncryptionMethodSpec(); + + bool IsZipFormat(); + + void SetEncryptionMethod(); + + int AddDictionarySize(UInt32 size, bool kilo, bool maga); + int AddDictionarySize(UInt32 size); + + void SetDictionary(); + UInt32 GetDictionary(); + UInt32 GetDictionarySpec(); + + int AddOrder(UInt32 size); + void SetOrder(); + bool GetOrderMode(); + UInt32 GetOrder(); + UInt32 GetOrderSpec(); + + UInt64 GetMemoryUsage(UInt32 dictionary, bool isMultiThread, UInt64 &decompressMemory); + UInt64 GetMemoryUsage(UInt64 &decompressMemory); + void PrintMemUsage(UINT res, UInt64 value); + void SetMemoryUsage(); + void SetParams(); + void SaveOptionsInMem(); + + void UpdatePasswordControl(); + bool IsShowPasswordChecked() const + { return IsButtonChecked(IDC_COMPRESS_CHECK_SHOW_PASSWORD) == BST_CHECKED; } +public: + CObjectVector m_ArchiverInfoList; + + NCompressDialog::CInfo Info; + UString OriginalFileName; // for bzip2, gzip2 + + INT_PTR Create(HWND wndParent = 0) + { return CModalDialog::Create(IDD_DIALOG_COMPRESS, wndParent); } + +protected: + + void CheckSFXControlsEnable(); + void CheckVolumeEnable(); + void CheckControlsEnable(); + + void OnButtonSetArchive(); + bool IsSFX(); + void OnButtonSFX(); + + virtual bool OnInit(); + virtual bool OnCommand(int code, int itemID, LPARAM lParam); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + virtual void OnOK(); + virtual void OnHelp(); + +}; + +#endif diff --git a/CPP/7zip/UI/GUI/ExtractDialog.cpp b/CPP/7zip/UI/GUI/ExtractDialog.cpp new file mode 100755 index 00000000..55c871ad --- /dev/null +++ b/CPP/7zip/UI/GUI/ExtractDialog.cpp @@ -0,0 +1,371 @@ +// ExtractDialog.cpp + +#include "StdAfx.h" + +// #include + +#include "ExtractDialog.h" + +#include "Common/StringConvert.h" +#include "Windows/Shell.h" +#include "Windows/FileName.h" +#include "Windows/FileDir.h" +#include "Windows/ResourceString.h" + +#ifndef NO_REGISTRY +#include "../../FileManager/HelpUtils.h" +#endif + +#include "../Common/ZipRegistry.h" + +#include "../../FileManager/LangUtils.h" + +#include "../Resource/Extract/resource.h" +#include "../Resource/ExtractDialog/resource.h" + +// #include "Help/Context/Extract.h" + +using namespace NWindows; +using namespace NFile; +using namespace NName; + +static const int kPathModeButtons[] = +{ + IDC_EXTRACT_RADIO_FULL_PATHNAMES, + IDC_EXTRACT_RADIO_CURRENT_PATHNAMES, + IDC_EXTRACT_RADIO_NO_PATHNAMES +}; + +static const NExtract::NPathMode::EEnum kPathModeButtonsVals[] = +{ + NExtract::NPathMode::kFullPathnames, + NExtract::NPathMode::kCurrentPathnames, + NExtract::NPathMode::kNoPathnames +}; + +static const int kNumPathnamesButtons = sizeof(kPathModeButtons) / sizeof(kPathModeButtons[0]); + +static const int kOverwriteButtons[] = +{ + IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE, + IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT, + IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES, + IDC_EXTRACT_RADIO_AUTO_RENAME, + IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING, +}; + +static const NExtract::NOverwriteMode::EEnum kOverwriteButtonsVals[] = +{ + NExtract::NOverwriteMode::kAskBefore, + NExtract::NOverwriteMode::kWithoutPrompt, + NExtract::NOverwriteMode::kSkipExisting, + NExtract::NOverwriteMode::kAutoRename, + NExtract::NOverwriteMode::kAutoRenameExisting +}; + +static const int kNumOverwriteButtons = sizeof(kOverwriteButtons) / sizeof(kOverwriteButtons[0]); + +/* +static const int kFilesButtons[] = +{ + IDC_EXTRACT_RADIO_SELECTED_FILES, + IDC_EXTRACT_RADIO_ALL_FILES +}; +static const int kNumFilesButtons = sizeof(kFilesButtons) / sizeof(kFilesButtons[0]); +*/ + +#ifndef _SFX +void CExtractDialog::GetPathMode() +{ + for (int i = 0; i < kNumPathnamesButtons; i++) + if(IsButtonCheckedBool(kPathModeButtons[i])) + { + PathMode = kPathModeButtonsVals[i]; + return; + } + throw 1; +} + +void CExtractDialog::SetPathMode() +{ + for (int j = 0; j < 2; j++) + { + for (int i = 0; i < kNumPathnamesButtons; i++) + if(PathMode == kPathModeButtonsVals[i]) + { + CheckRadioButton(kPathModeButtons[0], kPathModeButtons[kNumPathnamesButtons - 1], + kPathModeButtons[i]); + return; + } + PathMode = kPathModeButtonsVals[0]; + } + throw 1; +} + +void CExtractDialog::GetOverwriteMode() +{ + for (int i = 0; i < kNumOverwriteButtons; i++) + if(IsButtonCheckedBool(kOverwriteButtons[i])) + { + OverwriteMode = kOverwriteButtonsVals[i]; + return; + } + throw 0; +} + +void CExtractDialog::SetOverwriteMode() +{ + for (int j = 0; j < 2; j++) + { + for (int i = 0; i < kNumOverwriteButtons; i++) + if(OverwriteMode == kOverwriteButtonsVals[i]) + { + CheckRadioButton(kOverwriteButtons[0], kOverwriteButtons[kNumOverwriteButtons - 1], + kOverwriteButtons[i]); + return; + } + OverwriteMode = kOverwriteButtonsVals[0]; + } + throw 1; +} + +/* +int CExtractDialog::GetFilesMode() const +{ + for (int i = 0; i < kNumFilesButtons; i++) + if(IsButtonCheckedBool(kFilesButtons[i])) + return i; + throw 0; +} +*/ + +#endif + +#ifdef LANG +static CIDLangPair kIDLangPairs[] = +{ + { IDC_STATIC_EXTRACT_EXTRACT_TO, 0x02000801 }, + { IDC_EXTRACT_PATH_MODE, 0x02000810 }, + { IDC_EXTRACT_RADIO_FULL_PATHNAMES, 0x02000811 }, + { IDC_EXTRACT_RADIO_CURRENT_PATHNAMES, 0x02000812 }, + { IDC_EXTRACT_RADIO_NO_PATHNAMES, 0x02000813 }, + { IDC_EXTRACT_OVERWRITE_MODE, 0x02000820 }, + { IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE, 0x02000821 }, + { IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT, 0x02000822 }, + { IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES, 0x02000823 }, + { IDC_EXTRACT_RADIO_AUTO_RENAME, 0x02000824 }, + { IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING, 0x02000825 }, + { IDC_EXTRACT_FILES, 0x02000830 }, + { IDC_EXTRACT_RADIO_SELECTED_FILES, 0x02000831 }, + { IDC_EXTRACT_RADIO_ALL_FILES, 0x02000832 }, + { IDC_EXTRACT_PASSWORD, 0x02000802 }, + { IDC_EXTRACT_CHECK_SHOW_PASSWORD, 0x02000B02 }, + { IDOK, 0x02000702 }, + { IDCANCEL, 0x02000710 }, + { IDHELP, 0x02000720 } + +}; +#endif + +// static const int kWildcardsButtonIndex = 2; + +static const int kHistorySize = 8; + +bool CExtractDialog::OnInit() +{ + #ifdef LANG + LangSetWindowText(HWND(*this), 0x02000800); + LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0])); + #endif + #ifndef _SFX + _passwordControl.Attach(GetItem(IDC_EXTRACT_EDIT_PASSWORD)); + _passwordControl.SetText(Password); + _passwordControl.SetPasswordChar(TEXT('*')); + #endif + + NExtract::CInfo extractionInfo; + + #ifdef NO_REGISTRY + PathMode = NExtract::NPathMode::kFullPathnames; + OverwriteMode = NExtract::NOverwriteMode::kAskBefore; + // extractionInfo.Paths = NExtract::NPathMode::kFullPathnames; + #else + ReadExtractionInfo(extractionInfo); + CheckButton(IDC_EXTRACT_CHECK_SHOW_PASSWORD, extractionInfo.ShowPassword); + UpdatePasswordControl(); + PathMode = extractionInfo.PathMode; + OverwriteMode = extractionInfo.OverwriteMode; + #endif + + _path.Attach(GetItem(IDC_EXTRACT_COMBO_PATH)); + + _path.SetText(DirectoryPath); + + #ifndef NO_REGISTRY + for(int i = 0; i < extractionInfo.Paths.Size() && i < kHistorySize; i++) + _path.AddString(extractionInfo.Paths[i]); + #endif + + /* + if(extractionInfo.Paths.Size() > 0) + _path.SetCurSel(0); + else + _path.SetCurSel(-1); + */ + + + + #ifndef _SFX + SetPathMode(); + SetOverwriteMode(); + + /* + CheckRadioButton(kFilesButtons[0], kFilesButtons[kNumFilesButtons - 1], + kFilesButtons[_filesMode]); + */ + + // CWindow selectedFilesWindow = GetItem(IDC_EXTRACT_RADIO_SELECTED_FILES); + // selectedFilesWindow.Enable(_enableSelectedFilesButton); + + + #endif + + + // CWindow filesWindow = GetItem(IDC_EXTRACT_RADIO_FILES); + // filesWindow.Enable(_enableFilesButton); + + // UpdateWildCardState(); + return CModalDialog::OnInit(); +} + +#ifndef _SFX +void CExtractDialog::UpdatePasswordControl() +{ + _passwordControl.SetPasswordChar((IsButtonChecked( + IDC_EXTRACT_CHECK_SHOW_PASSWORD) == BST_CHECKED) ? 0: TEXT('*')); + UString password; + _passwordControl.GetText(password); + _passwordControl.SetText(password); +} +#endif + +bool CExtractDialog::OnButtonClicked(int buttonID, HWND buttonHWND) +{ + /* + for (int i = 0; i < kNumFilesButtons; i++) + if (buttonID == kFilesButtons[i]) + { + UpdateWildCardState(); + return true; + } + */ + switch(buttonID) + { + case IDC_EXTRACT_BUTTON_SET_PATH: + OnButtonSetPath(); + return true; + #ifndef _SFX + case IDC_EXTRACT_CHECK_SHOW_PASSWORD: + { + UpdatePasswordControl(); + return true; + } + #endif + } + return CModalDialog::OnButtonClicked(buttonID, buttonHWND); +} + +void CExtractDialog::OnButtonSetPath() +{ + UString currentPath; + _path.GetText(currentPath); + UString title = LangStringSpec(IDS_EXTRACT_SET_FOLDER, 0x02000881); + UString resultPath; + if (!NShell::BrowseForFolder(HWND(*this), title, currentPath, resultPath)) + return; + #ifndef NO_REGISTRY + _path.SetCurSel(-1); + #endif + _path.SetText(resultPath); +} + +void AddUniqueString(UStringVector &list, const UString &s) +{ + for(int i = 0; i < list.Size(); i++) + if (s.CompareNoCase(list[i]) == 0) + return; + list.Add(s); +} + +void CExtractDialog::OnOK() +{ + #ifndef _SFX + GetPathMode(); + GetOverwriteMode(); + // _filesMode = (NExtractionDialog::NFilesMode::EEnum)GetFilesMode(); + + _passwordControl.GetText(Password); + #endif + + NExtract::CInfo extractionInfo; + extractionInfo.PathMode = PathMode; + extractionInfo.OverwriteMode = OverwriteMode; + extractionInfo.ShowPassword = (IsButtonChecked( + IDC_EXTRACT_CHECK_SHOW_PASSWORD) == BST_CHECKED); + + UString s; + + #ifdef NO_REGISTRY + + _path.GetText(s); + + #else + + int currentItem = _path.GetCurSel(); + if(currentItem == CB_ERR) + { + _path.GetText(s); + if(_path.GetCount() >= kHistorySize) + currentItem = _path.GetCount() - 1; + } + else + _path.GetLBText(currentItem, s); + + #endif + + s.Trim(); + #ifndef _SFX + AddUniqueString(extractionInfo.Paths, s); + #endif + DirectoryPath = s; + #ifndef NO_REGISTRY + for(int i = 0; i < _path.GetCount(); i++) + if(i != currentItem) + { + UString sTemp; + _path.GetLBText(i, sTemp); + sTemp.Trim(); + AddUniqueString(extractionInfo.Paths, sTemp); + } + SaveExtractionInfo(extractionInfo); + #endif + CModalDialog::OnOK(); +} + +/* +void CExtractDialog::UpdateWildCardState() +{ + // UpdateData(TRUE); + // m_Wildcards.EnableWindow(BoolToBOOL(m_Files == kWildcardsButtonIndex)); +} +*/ + +#ifndef NO_REGISTRY +static LPCWSTR kHelpTopic = L"fm/plugins/7-zip/extract.htm"; +void CExtractDialog::OnHelp() +{ + ShowHelpWindow(NULL, kHelpTopic); + CModalDialog::OnHelp(); +} +#endif + diff --git a/CPP/7zip/UI/GUI/ExtractDialog.h b/CPP/7zip/UI/GUI/ExtractDialog.h new file mode 100755 index 00000000..0020c693 --- /dev/null +++ b/CPP/7zip/UI/GUI/ExtractDialog.h @@ -0,0 +1,77 @@ +// ExtractDialog.h + +#ifndef __EXTRACTDIALOG_H +#define __EXTRACTDIALOG_H + +#include "resource.h" + +#include "Windows/Control/Dialog.h" +#include "Windows/Control/Edit.h" +#include "Windows/Control/ComboBox.h" + +#ifndef NO_REGISTRY +#include "../Common/ZipRegistry.h" +#endif +#include "../Common/ExtractMode.h" + +namespace NExtractionDialog +{ + /* + namespace NFilesMode + { + enum EEnum + { + kSelected, + kAll, + kSpecified + }; + } + */ +} + +class CExtractDialog: public NWindows::NControl::CModalDialog +{ + #ifdef NO_REGISTRY + NWindows::NControl::CDialogChildControl _path; + #else + NWindows::NControl::CComboBox _path; + #endif + + #ifndef _SFX + NWindows::NControl::CEdit _passwordControl; + #endif + + #ifndef _SFX + void GetPathMode(); + void SetPathMode(); + void GetOverwriteMode(); + void SetOverwriteMode(); + // int GetFilesMode() const; + void UpdatePasswordControl(); + #endif + + void OnButtonSetPath(); + + virtual bool OnInit(); + virtual bool OnButtonClicked(int buttonID, HWND buttonHWND); + virtual void OnOK(); + #ifndef NO_REGISTRY + virtual void OnHelp(); + #endif +public: + // bool _enableSelectedFilesButton; + // bool _enableFilesButton; + // NExtractionDialog::NFilesMode::EEnum FilesMode; + + UString DirectoryPath; + #ifndef _SFX + UString Password; + #endif + NExtract::NPathMode::EEnum PathMode; + NExtract::NOverwriteMode::EEnum OverwriteMode; + + INT_PTR Create(HWND aWndParent = 0) + { return CModalDialog::Create(IDD_DIALOG_EXTRACT, aWndParent); } +}; + +#endif diff --git a/CPP/7zip/UI/GUI/ExtractGUI.cpp b/CPP/7zip/UI/GUI/ExtractGUI.cpp new file mode 100755 index 00000000..395df5a9 --- /dev/null +++ b/CPP/7zip/UI/GUI/ExtractGUI.cpp @@ -0,0 +1,172 @@ +// ExtractGUI.cpp + +#include "StdAfx.h" + +#include "ExtractGUI.h" + +#include "Common/StringConvert.h" + +#include "Windows/FileDir.h" +#include "Windows/Error.h" +#include "Windows/FileFind.h" +#include "Windows/Thread.h" + +#include "../../FileManager/FormatUtils.h" +#include "../../FileManager/ExtractCallback.h" +#include "../../FileManager/LangUtils.h" + +#include "../Common/ArchiveExtractCallback.h" +#include "../Explorer/MyMessages.h" +#include "../Resource/Extract/resource.h" + +#include "OpenCallbackGUI.h" +#include "ExtractDialog.h" + +using namespace NWindows; + +static const wchar_t *kIncorrectOutDir = L"Incorrect output directory path"; + +struct CThreadExtracting +{ + CExtractCallbackImp *ExtractCallbackSpec; + + UStringVector *ArchivePaths; + UStringVector *ArchivePathsFull; + const NWildcard::CCensorNode *WildcardCensor; + const CExtractOptions *Options; + COpenCallbackGUI *OpenCallback; + CMyComPtr ExtractCallback; + + UString ErrorMessage; + HRESULT Result; + + DWORD Process() + { + ExtractCallbackSpec->ProgressDialog.WaitCreating(); + try + { + Result = DecompressArchives(*ArchivePaths, *ArchivePathsFull, + *WildcardCensor, *Options, OpenCallback, ExtractCallback, ErrorMessage); + } + catch(const UString &s) + { + ErrorMessage = s; + Result = E_FAIL; + } + catch(const wchar_t *s) + { + ErrorMessage = s; + Result = E_FAIL; + } + catch(const char *s) + { + ErrorMessage = GetUnicodeString(s); + Result = E_FAIL; + } + catch(...) + { + Result = E_FAIL; + } + ExtractCallbackSpec->ProgressDialog.MyClose(); + return 0; + } + static DWORD WINAPI MyThreadFunction(void *param) + { + return ((CThreadExtracting *)param)->Process(); + } +}; + +HRESULT ExtractGUI( + UStringVector &archivePaths, + UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + CExtractOptions &options, + bool showDialog, + COpenCallbackGUI *openCallback, + CExtractCallbackImp *extractCallback) +{ + CThreadExtracting extracter; + + if (!options.TestMode) + { + UString outputDir = options.OutputDir; + if (outputDir.IsEmpty()) + NFile::NDirectory::MyGetCurrentDirectory(outputDir); + if (showDialog) + { + CExtractDialog dialog; + if (!NFile::NDirectory::MyGetFullPathName(outputDir, dialog.DirectoryPath)) + { + MyMessageBox(kIncorrectOutDir); + return E_FAIL; + } + NFile::NName::NormalizeDirPathPrefix(dialog.DirectoryPath); + + // dialog.OverwriteMode = options.OverwriteMode; + // dialog.PathMode = options.PathMode; + + if(dialog.Create(0) != IDOK) + return E_ABORT; + outputDir = dialog.DirectoryPath; + options.OverwriteMode = dialog.OverwriteMode; + options.PathMode = dialog.PathMode; + #ifndef _SFX + openCallback->Password = dialog.Password; + openCallback->PasswordIsDefined = !dialog.Password.IsEmpty(); + #endif + } + if (!NFile::NDirectory::MyGetFullPathName(outputDir, options.OutputDir)) + { + MyMessageBox(kIncorrectOutDir); + return E_FAIL; + } + NFile::NName::NormalizeDirPathPrefix(options.OutputDir); + + /* + if(!NFile::NDirectory::CreateComplexDirectory(options.OutputDir)) + { + UString s = GetUnicodeString(NError::MyFormatMessage(GetLastError())); + UString s2 = MyFormatNew(IDS_CANNOT_CREATE_FOLDER, + #ifdef LANG + 0x02000603, + #endif + options.OutputDir); + MyMessageBox(s2 + UString(L"\n") + s); + return E_FAIL; + } + */ + } + + UString title = LangStringSpec(options.TestMode ? IDS_PROGRESS_TESTING : IDS_PROGRESS_EXTRACTING, + options.TestMode ? 0x02000F90: 0x02000890); + + extracter.ExtractCallbackSpec = extractCallback; + extracter.ExtractCallback = extractCallback; + extracter.ExtractCallbackSpec->Init(); + + extracter.ArchivePaths = &archivePaths; + extracter.ArchivePathsFull = &archivePathsFull; + extracter.WildcardCensor = &wildcardCensor; + extracter.Options = &options; + extracter.OpenCallback = openCallback; + + CThread thread; + if (!thread.Create(CThreadExtracting::MyThreadFunction, &extracter)) + throw 271824; + extracter.ExtractCallbackSpec->StartProgressDialog(title); + if (extracter.Result == S_OK && options.TestMode && + extracter.ExtractCallbackSpec->Messages.IsEmpty() && + extracter.ExtractCallbackSpec->NumArchiveErrors == 0) + { + #ifndef _SFX + MessageBoxW(0, LangString(IDS_MESSAGE_NO_ERRORS, 0x02000608), + LangString(IDS_PROGRESS_TESTING, 0x02000F90), 0); + #endif + } + if (extracter.Result != S_OK) + if (!extracter.ErrorMessage.IsEmpty()) + throw extracter.ErrorMessage; + return extracter.Result; +} + + diff --git a/CPP/7zip/UI/GUI/ExtractGUI.h b/CPP/7zip/UI/GUI/ExtractGUI.h new file mode 100755 index 00000000..5a0b157d --- /dev/null +++ b/CPP/7zip/UI/GUI/ExtractGUI.h @@ -0,0 +1,20 @@ +// GUI/ExtractGUI.h + +#ifndef __EXTRACT_GUI_H +#define __EXTRACT_GUI_H + +#include "../Common/Extract.h" +#include "OpenCallbackGUI.h" + +#include "../../FileManager/ExtractCallback.h" + +HRESULT ExtractGUI( + UStringVector &archivePaths, + UStringVector &archivePathsFull, + const NWildcard::CCensorNode &wildcardCensor, + CExtractOptions &options, + bool showDialog, + COpenCallbackGUI *openCallback, + CExtractCallbackImp *extractCallback); + +#endif diff --git a/CPP/7zip/UI/GUI/FM.ico b/CPP/7zip/UI/GUI/FM.ico new file mode 100755 index 00000000..3a0a34da Binary files /dev/null and b/CPP/7zip/UI/GUI/FM.ico differ diff --git a/CPP/7zip/UI/GUI/GUI.cpp b/CPP/7zip/UI/GUI/GUI.cpp new file mode 100755 index 00000000..fe956dbd --- /dev/null +++ b/CPP/7zip/UI/GUI/GUI.cpp @@ -0,0 +1,260 @@ +// GUI.cpp + +#include "StdAfx.h" + +#include + +#include "Common/NewHandler.h" +#include "Common/StringConvert.h" +#include "Common/CommandLineParser.h" +#include "Common/Exception.h" + +#include "Windows/COM.h" +#include "Windows/FileMapping.h" +#include "Windows/FileDir.h" +#include "Windows/Synchronization.h" +#include "Windows/Error.h" +#include "Windows/FileName.h" +#ifdef _WIN32 +#include "Windows/MemoryLock.h" +#include "Common/Alloc.h" +#endif + +#include "../../IStream.h" +#include "../../IPassword.h" + +#include "../../FileManager/StringUtils.h" + +#include "../Common/ExitCode.h" +#include "../Common/ArchiveCommandLine.h" + +#include "../Resource/Extract/resource.h" +#include "../Explorer/MyMessages.h" + +#include "ExtractGUI.h" +#include "UpdateGUI.h" + +using namespace NWindows; + +HINSTANCE g_hInstance; +#ifndef _UNICODE +bool g_IsNT = false; +#endif + +static const wchar_t *kExceptionErrorMessage = L"Error:"; +static const wchar_t *kUserBreak = L"Break signaled"; + +static const wchar_t *kMemoryExceptionMessage = L"ERROR: Can't allocate required memory!"; +static const wchar_t *kUnknownExceptionMessage = L"Unknown Error"; +static const wchar_t *kInternalExceptionMessage = L"Internal Error #"; + +static const wchar_t *kIncorrectCommandMessage = L"Incorrect command"; + +static void ErrorMessage(const wchar_t *message) +{ + MessageBoxW(0, message, L"7-Zip GUI", MB_ICONERROR); +} + +int Main2() +{ + /* + TCHAR t[512]; + GetCurrentDirectory(512, t); + ErrorMessage(t); + return 0; + */ + + UStringVector commandStrings; + NCommandLineParser::SplitCommandLine(GetCommandLineW(), commandStrings); + if(commandStrings.Size() <= 1) + { + MessageBoxW(0, L"Specify command", L"7-Zip", 0); + return 0; + } + commandStrings.Delete(0); + + CArchiveCommandLineOptions options; + CArchiveCommandLineParser parser; + + parser.Parse1(commandStrings, options); + parser.Parse2(options); + + #ifdef _WIN32 + if (options.LargePages) + NSecurity::EnableLockMemoryPrivilege(); + #endif + + bool isExtractGroupCommand = options.Command.IsFromExtractGroup(); + + if (isExtractGroupCommand) + { + CExtractCallbackImp *ecs = new CExtractCallbackImp; + CMyComPtr extractCallback = ecs; + ecs->PasswordIsDefined = options.PasswordEnabled; + ecs->Password = options.Password; + ecs->Init(); + + COpenCallbackGUI openCallback; + openCallback.PasswordIsDefined = options.PasswordEnabled; + openCallback.Password = options.Password; + + CExtractOptions eo; + eo.StdOutMode = options.StdOutMode; + eo.OutputDir = options.OutputDir; + eo.YesToAll = options.YesToAll; + eo.OverwriteMode = options.OverwriteMode; + eo.PathMode = options.Command.GetPathMode(); + eo.TestMode = options.Command.IsTestMode(); + #ifdef COMPRESS_MT + eo.Properties = options.ExtractProperties; + #endif + + HRESULT result = ExtractGUI( + options.ArchivePathsSorted, + options.ArchivePathsFullSorted, + options.WildcardCensor.Pairs.Front().Head, + eo, options.ShowDialog, &openCallback, ecs); + if (result != S_OK) + throw CSystemException(result); + if (ecs->Messages.Size() > 0 || ecs->NumArchiveErrors != 0) + return NExitCode::kFatalError; + } + else if (options.Command.IsFromUpdateGroup()) + { + bool passwordIsDefined = + options.PasswordEnabled && !options.Password.IsEmpty(); + + COpenCallbackGUI openCallback; + openCallback.PasswordIsDefined = passwordIsDefined; + openCallback.Password = options.Password; + + CUpdateCallbackGUI callback; + // callback.EnablePercents = options.EnablePercents; + callback.PasswordIsDefined = passwordIsDefined; + callback.AskPassword = options.PasswordEnabled && options.Password.IsEmpty(); + callback.Password = options.Password; + // callback.StdOutMode = options.UpdateOptions.StdOutMode; + callback.Init(); + + CUpdateErrorInfo errorInfo; + + HRESULT result = UpdateGUI( + options.WildcardCensor, options.UpdateOptions, + options.ShowDialog, + errorInfo, &openCallback, &callback); + + if (result != S_OK) + { + if (!errorInfo.Message.IsEmpty()) + ErrorMessage(errorInfo.Message); + throw CSystemException(result); + } + if (callback.FailedFiles.Size() > 0) + return NExitCode::kWarning; + } + else + { + ErrorMessage(L"Use correct command"); + return 0; + } + return 0; +} + +static bool inline IsItWindowsNT() +{ + OSVERSIONINFO versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); + if (!::GetVersionEx(&versionInfo)) + return false; + return (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); +} + +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */, LPSTR /* lpCmdLine */, int /* nCmdShow */) +{ + g_hInstance = hInstance; + #ifdef _UNICODE + if (!IsItWindowsNT()) + { + MyMessageBox(L"This program requires Windows NT/2000/XP/2003"); + return NExitCode::kFatalError; + } + #else + g_IsNT = IsItWindowsNT(); + #endif + + #ifdef _WIN32 + SetLargePageSize(); + #endif + + InitCommonControls(); + + ReloadLang(); + + // setlocale(LC_COLLATE, ".ACP"); + try + { + return Main2(); + } + catch(const CNewException &) + { + MyMessageBox(kMemoryExceptionMessage); + return (NExitCode::kMemoryError); + } + catch(const CArchiveCommandLineException &e) + { + MyMessageBox(GetUnicodeString(e)); + return (NExitCode::kUserError); + } + catch(const CSystemException &systemError) + { + if (systemError.ErrorCode == E_OUTOFMEMORY) + { + MyMessageBox(kMemoryExceptionMessage); + return (NExitCode::kMemoryError); + } + if (systemError.ErrorCode == E_ABORT) + { + // MyMessageBox(kUserBreak); + return (NExitCode::kUserBreak); + } + UString message; + NError::MyFormatMessage(systemError.ErrorCode, message); + MyMessageBox(message); + return (NExitCode::kFatalError); + } + /* + catch(NExitCode::EEnum &exitCode) + { + g_StdErr << kInternalExceptionMessage << exitCode << endl; + return (exitCode); + } + */ + catch(const UString &s) + { + MyMessageBox(s); + return (NExitCode::kFatalError); + } + catch(const AString &s) + { + MyMessageBox(GetUnicodeString(s)); + return (NExitCode::kFatalError); + } + catch(const char *s) + { + MyMessageBox(GetUnicodeString(s)); + return (NExitCode::kFatalError); + } + /* + catch(int t) + { + g_StdErr << kInternalExceptionMessage << t << endl; + return (NExitCode::kFatalError); + } + */ + catch(...) + { + MyMessageBox(kUnknownExceptionMessage); + return (NExitCode::kFatalError); + } +} + diff --git a/CPP/7zip/UI/GUI/GUI.dsp b/CPP/7zip/UI/GUI/GUI.dsp new file mode 100755 index 00000000..dadb9648 --- /dev/null +++ b/CPP/7zip/UI/GUI/GUI.dsp @@ -0,0 +1,904 @@ +# Microsoft Developer Studio Project File - Name="GUI" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=GUI - Win32 DebugU +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "GUI.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "GUI.mak" CFG="GUI - Win32 DebugU" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "GUI - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "GUI - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "GUI - Win32 ReleaseU" (based on "Win32 (x86) Application") +!MESSAGE "GUI - Win32 DebugU" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "GUI - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "COMPRESS_MT" /D "WIN_LONG_PATH" /Yu"stdafx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Program Files\7-Zip\7zg.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "GUI - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "COMPRESS_MT" /D "WIN_LONG_PATH" /Yu"stdafx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Program Files\7-Zip\7zg.exe" /pdbtype:sept + +!ELSEIF "$(CFG)" == "GUI - Win32 ReleaseU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ReleaseU" +# PROP BASE Intermediate_Dir "ReleaseU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "ReleaseU" +# PROP Intermediate_Dir "ReleaseU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c +# ADD CPP /nologo /Gz /MD /W3 /GX /O1 /I "..\..\..\\" /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "COMPRESS_MT" /D "WIN_LONG_PATH" /Yu"stdafx.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 /out:"C:\UTIL\7zg.exe" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /subsystem:windows /machine:I386 /out:"C:\Program Files\7-Zip\7zgn.exe" /opt:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "GUI - Win32 DebugU" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "DebugU" +# PROP BASE Intermediate_Dir "DebugU" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DebugU" +# PROP Intermediate_Dir "DebugU" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /Gz /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\\" /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "LANG" /D "COMPRESS_MT" /D "WIN_LONG_PATH" /Yu"stdafx.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\UTIL\7zg.exe" /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib htmlhelp.lib /nologo /subsystem:windows /debug /machine:I386 /out:"C:\Program Files\7-Zip\7zgn.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "GUI - Win32 Release" +# Name "GUI - Win32 Debug" +# Name "GUI - Win32 ReleaseU" +# Name "GUI - Win32 DebugU" +# Begin Group "Spec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\7zG.exe.manifest +# End Source File +# Begin Source File + +SOURCE=.\FM.ico +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "SDK" + +# PROP Default_Filter "" +# Begin Group "Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Alloc.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\CommandLineParser.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\IntToString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Lang.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\ListFileUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\NewHandler.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StdInStream.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\String.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\StringToInt.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\TextConfig.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\TextConfig.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\UTFConvert.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Vector.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Common\Wildcard.h +# End Source File +# End Group +# Begin Group "Windows" + +# PROP Default_Filter "" +# Begin Group "Control" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ComboBox.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ComboBox.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Dialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\Edit.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ListView.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ListView.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Control\ProgressBar.h +# End Source File +# End Group +# Begin Source File + +SOURCE=..\..\..\Windows\CommonDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\CommonDialog.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\DLL.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Error.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileDir.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileFind.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileIO.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\FileName.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\MemoryLock.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\PropVariantConversions.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\PropVariantConversions.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Registry.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\ResourceString.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Shell.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Synchronization.h +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\..\Windows\Window.h +# End Source File +# End Group +# End Group +# Begin Group "UI Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Common\ArchiveCommandLine.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveCommandLine.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiveOpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiverInfo.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ArchiverInfo.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\DefaultName.h +# End Source File +# Begin Source File + +SOURCE=..\Common\DirItem.h +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\EnumDirItems.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExitCode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Extract.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Extract.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractingFilePath.h +# End Source File +# Begin Source File + +SOURCE=..\Common\ExtractMode.h +# End Source File +# Begin Source File + +SOURCE=..\Common\HandlerLoader.h +# End Source File +# Begin Source File + +SOURCE=..\Common\IFileExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\OpenArchive.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Property.h +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\PropIDUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SetProperties.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SetProperties.h +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\SortUtils.h +# End Source File +# Begin Source File + +SOURCE=..\Common\TempFiles.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\TempFiles.h +# End Source File +# Begin Source File + +SOURCE=..\Common\Update.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\Update.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateAction.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateCallback.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdatePair.h +# End Source File +# Begin Source File + +SOURCE=..\Common\UpdateProduce.cpp +# End Source File +# Begin Source File + +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.cpp +# End Source File +# Begin Source File + +SOURCE=..\Common\ZipRegistry.h +# End Source File +# End Group +# Begin Group "Explorer" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Explorer\MyMessages.cpp +# End Source File +# Begin Source File + +SOURCE=..\Explorer\MyMessages.h +# End Source File +# End Group +# Begin Group "Dialogs" + +# PROP Default_Filter "" +# Begin Group "Progress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\FileManager\Resource\ProgressDialog2\ProgressDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\ProgressDialog2\ProgressDialog.h +# End Source File +# End Group +# Begin Group "Messages" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\MessagesDialog\MessagesDialog.h +# End Source File +# End Group +# Begin Group "Overwtite" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\FileManager\Resource\OverwriteDialog\OverwriteDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\OverwriteDialog\OverwriteDialog.h +# End Source File +# End Group +# Begin Group "Password" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\FileManager\Resource\PasswordDialog\PasswordDialog.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\Resource\PasswordDialog\PasswordDialog.h +# End Source File +# End Group +# Begin Group "Compress Dialog" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\CompressDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\CompressDialog.h +# End Source File +# End Group +# Begin Group "Extract Dialog" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ExtractDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractDialog.h +# End Source File +# End Group +# End Group +# Begin Group "FM Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\FileManager\ExtractCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\ExtractCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\FolderInterface.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\FormatUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\FormatUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\HelpUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\HelpUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\LangUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\LangUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\OpenCallback.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\OpenCallback.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\ProgramLocation.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\ProgramLocation.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\RegistryUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\RegistryUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\SplitUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\SplitUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\StringUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\StringUtils.h +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\UpdateCallback100.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\FileManager\UpdateCallback100.h +# End Source File +# End Group +# Begin Group "Engine" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ExtractGUI.cpp +# End Source File +# Begin Source File + +SOURCE=.\ExtractGUI.h +# End Source File +# Begin Source File + +SOURCE=.\GUI.cpp +# End Source File +# Begin Source File + +SOURCE=.\OpenCallbackGUI.cpp +# End Source File +# Begin Source File + +SOURCE=.\OpenCallbackGUI.h +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallbackGUI.cpp +# End Source File +# Begin Source File + +SOURCE=.\UpdateCallbackGUI.h +# End Source File +# Begin Source File + +SOURCE=.\UpdateGUI.cpp +# End Source File +# Begin Source File + +SOURCE=.\UpdateGUI.h +# End Source File +# End Group +# Begin Group "7-zip Common" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FilePathAutoRename.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\FileStreams.h +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Common\StreamUtils.h +# End Source File +# End Group +# Begin Group "Compress" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.cpp +# End Source File +# Begin Source File + +SOURCE=..\..\Compress\Copy\CopyCoder.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CPP/7zip/UI/GUI/GUI.dsw b/CPP/7zip/UI/GUI/GUI.dsw new file mode 100755 index 00000000..85d33484 --- /dev/null +++ b/CPP/7zip/UI/GUI/GUI.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "GUI"=.\GUI.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CPP/7zip/UI/GUI/OpenCallbackGUI.cpp b/CPP/7zip/UI/GUI/OpenCallbackGUI.cpp new file mode 100755 index 00000000..bc6cf393 --- /dev/null +++ b/CPP/7zip/UI/GUI/OpenCallbackGUI.cpp @@ -0,0 +1,65 @@ +// OpenCallbackGUI.cpp + +#include "StdAfx.h" + +#include "OpenCallbackGUI.h" + +#include "Common/StdOutStream.h" +#include "Common/StdInStream.h" +#include "Common/StringConvert.h" + +#ifndef _NO_CRYPTO +#include "../../FileManager/Resource/PasswordDialog/PasswordDialog.h" +#endif + +HRESULT COpenCallbackGUI::CheckBreak() +{ + return S_OK; +} + +HRESULT COpenCallbackGUI::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */) +{ + return S_OK; +} + +HRESULT COpenCallbackGUI::SetCompleted(const UInt64 * /* files */, const UInt64 * /* bytes */) +{ + return S_OK; +} + +#ifndef _NO_CRYPTO +HRESULT COpenCallbackGUI::CryptoGetTextPassword(BSTR *password) +{ + PasswordWasAsked = true; + if (!PasswordIsDefined) + { + CPasswordDialog dialog; + if (dialog.Create(ParentWindow) == IDCANCEL) + return E_ABORT; + Password = dialog.Password; + PasswordIsDefined = true; + } + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} + +HRESULT COpenCallbackGUI::GetPasswordIfAny(UString &password) +{ + if (PasswordIsDefined) + password = Password; + return S_OK; +} + +bool COpenCallbackGUI::WasPasswordAsked() +{ + return PasswordWasAsked; +} + +void COpenCallbackGUI::ClearPasswordWasAskedFlag() +{ + PasswordWasAsked = false; +} + +#endif + diff --git a/CPP/7zip/UI/GUI/OpenCallbackGUI.h b/CPP/7zip/UI/GUI/OpenCallbackGUI.h new file mode 100755 index 00000000..6b531d3c --- /dev/null +++ b/CPP/7zip/UI/GUI/OpenCallbackGUI.h @@ -0,0 +1,35 @@ +// OpenCallbackGUI.h + +#ifndef __OPEN_CALLBACK_GUI_H +#define __OPEN_CALLBACK_GUI_H + +#include "../Common/ArchiveOpenCallback.h" + +class COpenCallbackGUI: public IOpenCallbackUI +{ +public: + HRESULT CheckBreak(); + HRESULT SetTotal(const UInt64 *files, const UInt64 *bytes); + HRESULT SetCompleted(const UInt64 *files, const UInt64 *bytes); + #ifndef _NO_CRYPTO + HRESULT CryptoGetTextPassword(BSTR *password); + HRESULT GetPasswordIfAny(UString &password); + bool WasPasswordAsked(); + void ClearPasswordWasAskedFlag(); + + bool PasswordIsDefined; + UString Password; + bool PasswordWasAsked; + #endif + + HWND ParentWindow; + + COpenCallbackGUI(): + #ifndef _NO_CRYPTO + PasswordIsDefined(false), + PasswordWasAsked(false), + #endif + ParentWindow(0) {} +}; + +#endif diff --git a/CPP/7zip/UI/GUI/StdAfx.cpp b/CPP/7zip/UI/GUI/StdAfx.cpp new file mode 100755 index 00000000..d0feea85 --- /dev/null +++ b/CPP/7zip/UI/GUI/StdAfx.cpp @@ -0,0 +1,3 @@ +// StdAfx.cpp + +#include "StdAfx.h" diff --git a/CPP/7zip/UI/GUI/StdAfx.h b/CPP/7zip/UI/GUI/StdAfx.h new file mode 100755 index 00000000..46ea51cf --- /dev/null +++ b/CPP/7zip/UI/GUI/StdAfx.h @@ -0,0 +1,13 @@ +// StdAfx.h + +#ifndef __STDAFX_H +#define __STDAFX_H + +#include +#include +#include +#include + +#include "Common/NewHandler.h" + +#endif diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp b/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp new file mode 100755 index 00000000..eff29953 --- /dev/null +++ b/CPP/7zip/UI/GUI/UpdateCallbackGUI.cpp @@ -0,0 +1,167 @@ +// UpdateCallbackGUI.cpp + +#include "StdAfx.h" + +#include "UpdateCallbackGUI.h" + +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "Common/Defs.h" + +#include "Windows/PropVariant.h" +#include "Windows/Error.h" +#include "../../FileManager/Resource/MessagesDialog/MessagesDialog.h" +#include "../../FileManager/Resource/PasswordDialog/PasswordDialog.h" + +using namespace NWindows; + +CUpdateCallbackGUI::~CUpdateCallbackGUI() +{ + if (!Messages.IsEmpty()) + { + CMessagesDialog messagesDialog; + messagesDialog.Messages = &Messages; + messagesDialog.Create(ParentWindow); + } +} + +void CUpdateCallbackGUI::Init() +{ + FailedFiles.Clear(); + Messages.Clear(); + NumArchiveErrors = 0; +} + +void CUpdateCallbackGUI::AddErrorMessage(LPCWSTR message) +{ + Messages.Add(message); +} + +void CUpdateCallbackGUI::AddErrorMessage(const wchar_t *name, DWORD systemError) +{ + AddErrorMessage( + UString(L"WARNING: ") + + NError::MyFormatMessageW(systemError) + + UString(L": ") + + UString(name)); +} + +HRESULT CUpdateCallbackGUI::OpenResult(const wchar_t *name, HRESULT result) +{ + if (result != S_OK) + { + AddErrorMessage (UString(L"Error: ") + name + + UString(L" is not supported archive")); + } + return S_OK; +} + +HRESULT CUpdateCallbackGUI::StartScanning() +{ + return S_OK; +} + +HRESULT CUpdateCallbackGUI::CanNotFindError(const wchar_t *name, DWORD systemError) +{ + FailedFiles.Add(name); + AddErrorMessage(name, systemError); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::FinishScanning() +{ + return S_OK; +} + +HRESULT CUpdateCallbackGUI::StartArchive(const wchar_t *name, bool /* updating */) +{ + ProgressDialog.ProgressSynch.SetTitleFileName(name); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::FinishArchive() +{ + return S_OK; +} + +HRESULT CUpdateCallbackGUI::CheckBreak() +{ + for (;;) + { + if(ProgressDialog.ProgressSynch.GetStopped()) + return E_ABORT; + if(!ProgressDialog.ProgressSynch.GetPaused()) + break; + ::Sleep(100); + } + return S_OK; +} + +HRESULT CUpdateCallbackGUI::Finilize() +{ + return S_OK; +} + +HRESULT CUpdateCallbackGUI::SetTotal(UInt64 total) +{ + ProgressDialog.ProgressSynch.SetProgress(total, 0); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::SetCompleted(const UInt64 *completeValue) +{ + RINOK(CheckBreak()); + if (completeValue != NULL) + ProgressDialog.ProgressSynch.SetPos(*completeValue); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::GetStream(const wchar_t *name, bool /* isAnti */) +{ + ProgressDialog.ProgressSynch.SetCurrentFileName(name); + return S_OK; +} + +HRESULT CUpdateCallbackGUI::OpenFileError(const wchar_t *name, DWORD systemError) +{ + FailedFiles.Add(name); + // if (systemError == ERROR_SHARING_VIOLATION) + { + AddErrorMessage(name, systemError); + return S_FALSE; + } + // return systemError; +} + +HRESULT CUpdateCallbackGUI::SetOperationResult(Int32 /* operationResult */) +{ + return S_OK; +} + +HRESULT CUpdateCallbackGUI::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password) +{ + if (!PasswordIsDefined) + { + if (AskPassword) + { + CPasswordDialog dialog; + if (dialog.Create(ParentWindow) == IDCANCEL) + return E_ABORT; + Password = dialog.Password; + PasswordIsDefined = true; + } + } + *passwordIsDefined = BoolToInt(PasswordIsDefined); + CMyComBSTR tempName(Password); + *password = tempName.Detach(); + return S_OK; +} + +/* +It doesn't work, since main stream waits Dialog +HRESULT CUpdateCallbackGUI::CloseProgress() +{ + ProgressDialog.MyClose(); + return S_OK; +}; +*/ \ No newline at end of file diff --git a/CPP/7zip/UI/GUI/UpdateCallbackGUI.h b/CPP/7zip/UI/GUI/UpdateCallbackGUI.h new file mode 100755 index 00000000..16f0220c --- /dev/null +++ b/CPP/7zip/UI/GUI/UpdateCallbackGUI.h @@ -0,0 +1,63 @@ +// UpdateCallbackGUI.h + +#ifndef __UPDATE_CALLBACK_GUI_H +#define __UPDATE_CALLBACK_GUI_H + +#include "../Common/Update.h" +#include "../../FileManager/Resource/ProgressDialog2/ProgressDialog.h" + +class CUpdateCallbackGUI: public IUpdateCallbackUI2 +{ +public: + // bool StdOutMode; + bool PasswordIsDefined; + UString Password; + bool AskPassword; + + CUpdateCallbackGUI(): + PasswordIsDefined(false), + AskPassword(false), + // StdOutMode(false) + ParentWindow(0) + {} + + ~CUpdateCallbackGUI(); + void Init(); + + HRESULT OpenResult(const wchar_t *name, HRESULT result); + + HRESULT StartScanning(); + HRESULT CanNotFindError(const wchar_t *name, DWORD systemError); + HRESULT FinishScanning(); + + HRESULT StartArchive(const wchar_t *name, bool updating); + HRESULT FinishArchive(); + + HRESULT CheckBreak(); + HRESULT Finilize(); + HRESULT SetTotal(UInt64 total); + HRESULT SetCompleted(const UInt64 *completeValue); + + HRESULT GetStream(const wchar_t *name, bool isAnti); + HRESULT OpenFileError(const wchar_t *name, DWORD systemError); + HRESULT SetOperationResult(Int32 operationResult); + HRESULT CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password); + + // HRESULT CloseProgress(); + + UStringVector FailedFiles; + + CProgressDialog ProgressDialog; + HWND ParentWindow; + void StartProgressDialog(const UString &title) + { + ProgressDialog.Create(title, ParentWindow); + } + + UStringVector Messages; + int NumArchiveErrors; + void AddErrorMessage(LPCWSTR message); + void AddErrorMessage(const wchar_t *name, DWORD systemError); +}; + +#endif diff --git a/CPP/7zip/UI/GUI/UpdateGUI.cpp b/CPP/7zip/UI/GUI/UpdateGUI.cpp new file mode 100755 index 00000000..e39e7faf --- /dev/null +++ b/CPP/7zip/UI/GUI/UpdateGUI.cpp @@ -0,0 +1,397 @@ +// UpdateGUI.cpp + +#include "StdAfx.h" + +#include "UpdateGUI.h" + +#include "resource.h" +#include "Common/StringConvert.h" +#include "Common/IntToString.h" +#include "Common/StringToInt.h" + +#include "Windows/FileDir.h" +#include "Windows/Error.h" +#include "Windows/FileFind.h" +#include "Windows/Thread.h" + +#include "../../FileManager/FormatUtils.h" +#include "../../FileManager/ExtractCallback.h" +#include "../../FileManager/StringUtils.h" + +#include "../Common/ArchiveExtractCallback.h" +#include "../Common/WorkDir.h" +#include "../Explorer/MyMessages.h" +#include "../Resource/Extract/resource.h" + +#include "OpenCallbackGUI.h" +#include "CompressDialog.h" +#include "UpdateGUI.h" + +using namespace NWindows; +using namespace NFile; + +static const wchar_t *kIncorrectOutDir = L"Incorrect output directory path"; +static const wchar_t *kDefaultSfxModule = L"7z.sfx"; +static const wchar_t *kSFXExtension = L"exe"; + +struct CThreadUpdating +{ + CUpdateCallbackGUI *UpdateCallbackGUI; + + const NWildcard::CCensor *WildcardCensor; + CUpdateOptions *Options; + COpenCallbackGUI *OpenCallback; + + CUpdateErrorInfo *ErrorInfo; + HRESULT Result; + + DWORD Process() + { + UpdateCallbackGUI->ProgressDialog.WaitCreating(); + try + { + Result = UpdateArchive(*WildcardCensor, *Options, + *ErrorInfo, OpenCallback, UpdateCallbackGUI); + } + catch(const UString &s) + { + ErrorInfo->Message = s; + Result = E_FAIL; + } + catch(const wchar_t *s) + { + ErrorInfo->Message = s; + Result = E_FAIL; + } + catch(const char *s) + { + ErrorInfo->Message = GetUnicodeString(s); + Result = E_FAIL; + } + catch(...) + { + Result = E_FAIL; + } + UpdateCallbackGUI->ProgressDialog.MyClose(); + return 0; + } + static DWORD WINAPI MyThreadFunction(void *param) + { + return ((CThreadUpdating *)param)->Process(); + } +}; + +static void AddProp(CObjectVector &properties, + const UString &name, const UString &value) +{ + CProperty prop; + prop.Name = name; + prop.Value = value; + properties.Add(prop); +} + +static void AddProp(CObjectVector &properties, + const UString &name, UInt32 value) +{ + wchar_t tmp[32]; + ConvertUInt64ToString(value, tmp); + AddProp(properties, name, tmp); +} + +static void AddProp(CObjectVector &properties, + const UString &name, bool value) +{ + AddProp(properties, name, value ? UString(L"on"): UString(L"off")); +} + +static bool IsThereMethodOverride(bool is7z, const UString &propertiesString) +{ + UStringVector strings; + SplitString(propertiesString, strings); + for (int i = 0; i < strings.Size(); i++) + { + const UString &s = strings[i]; + if (is7z) + { + const wchar_t *end; + UInt64 n = ConvertStringToUInt64(s, &end); + if (n == 0 && *end == L'=') + return true; + } + else + { + if (s.Length() > 0) + if (s[0] == L'm' && s[1] == L'=') + return true; + } + } + return false; +} + +static void ParseAndAddPropertires(CObjectVector &properties, + const UString &propertiesString) +{ + UStringVector strings; + SplitString(propertiesString, strings); + for (int i = 0; i < strings.Size(); i++) + { + const UString &s = strings[i]; + CProperty property; + int index = s.Find(L'='); + if (index < 0) + property.Name = s; + else + { + property.Name = s.Left(index); + property.Value = s.Mid(index + 1); + } + properties.Add(property); + } +} + +static void SetOutProperties( + CObjectVector &properties, + bool is7z, + UInt32 level, + bool setMethod, + const UString &method, + UInt32 dictionary, + bool orderMode, + UInt32 order, + bool solidModeIsAllowed, bool solidMode, + bool multiThreadIsAllowed, bool multiThread, + const UString &encryptionMethod, + bool encryptHeadersIsAllowed, bool encryptHeaders, + bool /* sfxMode */) +{ + if (level != (UInt32)(Int32)-1) + AddProp(properties, L"x", (UInt32)level); + if (setMethod) + { + if (!method.IsEmpty()) + AddProp(properties, is7z ? L"0": L"m", method); + if (dictionary != (UInt32)(Int32)-1) + { + UString name; + if (is7z) + name = L"0"; + if (orderMode) + name += L"mem"; + else + name += L"d"; + wchar_t s[32]; + ConvertUInt64ToString(dictionary, s); + size_t len = wcslen(s); + s[len++] = L'B'; + s[len] = L'\0'; + AddProp(properties, name, UString(s)); + } + if (order != (UInt32)(Int32)-1) + { + UString name; + if (is7z) + name = L"0"; + if (orderMode) + name += L"o"; + else + name += L"fb"; + AddProp(properties, name, (UInt32)order); + } + } + + if (!encryptionMethod.IsEmpty()) + AddProp(properties, L"em", encryptionMethod); + + if (encryptHeadersIsAllowed) + AddProp(properties, L"he", encryptHeaders); + if (solidModeIsAllowed) + AddProp(properties, L"s", solidMode); + if (multiThreadIsAllowed) + AddProp(properties, L"mt", multiThread); +} + +static HRESULT ShowDialog(const NWildcard::CCensor &censor, + CUpdateOptions &options, CUpdateCallbackGUI *callback) +{ + if (options.Commands.Size() != 1) + throw "It must be one command"; + CObjectVector archivers; + CArchiverInfo archiverInfo; + ReadArchiverInfoList(archivers); + UString currentDirPrefix; + { + if (!NDirectory::MyGetCurrentDirectory(currentDirPrefix)) + return E_FAIL; + NName::NormalizeDirPathPrefix(currentDirPrefix); + } + + bool oneFile = false; + NFind::CFileInfoW fileInfo; + if (censor.Pairs.Size() > 0) + { + const NWildcard::CPair &pair = censor.Pairs[0]; + if (pair.Head.IncludeItems.Size() > 0) + { + const NWildcard::CItem &item = pair.Head.IncludeItems[0]; + if (item.ForFile) + { + UString name = pair.Prefix; + for (int i = 0; i < item.PathParts.Size(); i++) + { + if (i > 0) + name += L'\\'; + name += item.PathParts[i]; + } + if (NFind::FindFile(name, fileInfo)) + { + if (censor.Pairs.Size() == 1 && pair.Head.IncludeItems.Size() == 1) + oneFile = !fileInfo.IsDirectory(); + } + } + } + } + + CCompressDialog dialog; + NCompressDialog::CInfo &di = dialog.Info; + for(int i = 0; i < archivers.Size(); i++) + { + const CArchiverInfo &ai = archivers[i]; + if (ai.UpdateEnabled && (oneFile || !ai.KeepName)) + dialog.m_ArchiverInfoList.Add(ai); + } + if(dialog.m_ArchiverInfoList.Size() == 0) + { + MyMessageBox(L"No Update Engines"); + return E_FAIL; + } + + // di.ArchiveName = options.ArchivePath.GetFinalPath(); + di.ArchiveName = options.ArchivePath.GetPathWithoutExt(); + dialog.OriginalFileName = fileInfo.Name; + + di.CurrentDirPrefix = currentDirPrefix; + di.SFXMode = options.SfxMode; + + di.Solid = true; + di.MultiThread = false; + + if (callback->PasswordIsDefined) + di.Password = callback->Password; + + di.KeepName = !oneFile; + + if(dialog.Create(0) != IDOK) + return E_ABORT; + + options.VolumesSizes = di.VolumeSizes; + /* + if (di.VolumeSizeIsDefined) + { + MyMessageBox(L"Splitting to volumes is not supported"); + return E_FAIL; + } + */ + + NUpdateArchive::CActionSet &actionSet = options.Commands.Front().ActionSet; + + switch(di.UpdateMode) + { + case NCompressDialog::NUpdateMode::kAdd: + actionSet = NUpdateArchive::kAddActionSet; + break; + case NCompressDialog::NUpdateMode::kUpdate: + actionSet = NUpdateArchive::kUpdateActionSet; + break; + case NCompressDialog::NUpdateMode::kFresh: + actionSet = NUpdateArchive::kFreshActionSet; + break; + case NCompressDialog::NUpdateMode::kSynchronize: + actionSet = NUpdateArchive::kSynchronizeActionSet; + break; + default: + throw 1091756; + } + archiverInfo = dialog.m_ArchiverInfoList[di.ArchiverInfoIndex]; + callback->PasswordIsDefined = (!di.Password.IsEmpty()); + if (callback->PasswordIsDefined) + callback->Password = di.Password; + + options.MethodMode.Properties.Clear(); + + bool is7z = archiverInfo.Name.CompareNoCase(L"7z") == 0; + bool methodOverride = IsThereMethodOverride(is7z, di.Options); + + SetOutProperties( + options.MethodMode.Properties, + is7z, + di.Level, + !methodOverride, + di.Method, + di.Dictionary, + di.OrderMode, di.Order, + di.SolidIsAllowed, di.Solid, + di.MultiThreadIsAllowed, di.MultiThread, + di.EncryptionMethod, + di.EncryptHeadersIsAllowed, di.EncryptHeaders, + di.SFXMode); + + ParseAndAddPropertires(options.MethodMode.Properties, di.Options); + + if (di.SFXMode) + options.SfxMode = true; + options.MethodMode.FilePath = archiverInfo.FilePath; + options.MethodMode.ClassID = archiverInfo.ClassID; + + options.ArchivePath.VolExtension = archiverInfo.GetMainExtension(); + if(di.SFXMode) + options.ArchivePath.BaseExtension = kSFXExtension; + else + options.ArchivePath.BaseExtension = options.ArchivePath.VolExtension; + options.ArchivePath.ParseFromPath(di.ArchiveName); + + NWorkDir::CInfo workDirInfo; + ReadWorkDirInfo(workDirInfo); + options.WorkingDir.Empty(); + if (workDirInfo.Mode != NWorkDir::NMode::kCurrent) + { + UString fullPath; + NDirectory::MyGetFullPathName(di.ArchiveName, fullPath); + options.WorkingDir = GetWorkDir(workDirInfo, fullPath); + NFile::NDirectory::CreateComplexDirectory(options.WorkingDir); + } + return S_OK; +} + +HRESULT UpdateGUI( + const NWildcard::CCensor &censor, + CUpdateOptions &options, + bool showDialog, + CUpdateErrorInfo &errorInfo, + COpenCallbackGUI *openCallback, + CUpdateCallbackGUI *callback) +{ + if (showDialog) + { + RINOK(ShowDialog(censor, options, callback)); + } + if (options.SfxMode && options.SfxModule.IsEmpty()) + options.SfxModule = kDefaultSfxModule; + + CThreadUpdating tu; + + tu.UpdateCallbackGUI = callback; + tu.UpdateCallbackGUI->Init(); + + tu.WildcardCensor = &censor; + tu.Options = &options; + tu.OpenCallback = openCallback; + tu.ErrorInfo = &errorInfo; + + CThread thread; + if (!thread.Create(CThreadUpdating::MyThreadFunction, &tu)) + throw 271824; + tu.UpdateCallbackGUI->StartProgressDialog(LangString(IDS_PROGRESS_COMPRESSING, 0x02000DC0)); + return tu.Result; +} + + diff --git a/CPP/7zip/UI/GUI/UpdateGUI.h b/CPP/7zip/UI/GUI/UpdateGUI.h new file mode 100755 index 00000000..c5061aca --- /dev/null +++ b/CPP/7zip/UI/GUI/UpdateGUI.h @@ -0,0 +1,20 @@ +// GUI/UpdateGUI.h + +#ifndef __UPDATE_GUI_H +#define __UPDATE_GUI_H + +#include "../Common/Update.h" +#include "OpenCallbackGUI.h" +#include "UpdateCallbackGUI.h" + +#include "../../FileManager/UpdateCallback100.h" + +HRESULT UpdateGUI( + const NWildcard::CCensor &censor, + CUpdateOptions &options, + bool showDialog, + CUpdateErrorInfo &errorInfo, + COpenCallbackGUI *openCallback, + CUpdateCallbackGUI *callback); + +#endif diff --git a/CPP/7zip/UI/GUI/makefile b/CPP/7zip/UI/GUI/makefile new file mode 100755 index 00000000..bc6af149 --- /dev/null +++ b/CPP/7zip/UI/GUI/makefile @@ -0,0 +1,135 @@ +PROG = 7zG.exe +LIBS = $(LIBS) user32.lib advapi32.lib oleaut32.lib shell32.lib comctl32.lib htmlhelp.lib ole32.lib comdlg32.lib +CFLAGS = $(CFLAGS) -I ../../../ -DLANG -DCOMPRESS_MT -DWIN_LONG_PATH + +GUI_OBJS = \ + $O\CompressDialog.obj \ + $O\ExtractDialog.obj \ + $O\ExtractGUI.obj \ + $O\GUI.obj \ + $O\OpenCallbackGUI.obj \ + $O\UpdateCallbackGUI.obj \ + $O\UpdateGUI.obj \ + +COMMON_OBJS = \ + $O\Alloc.obj \ + $O\CommandLineParser.obj \ + $O\IntToString.obj \ + $O\Lang.obj \ + $O\ListFileUtils.obj \ + $O\NewHandler.obj \ + $O\StdInStream.obj \ + $O\String.obj \ + $O\StringConvert.obj \ + $O\StringToInt.obj \ + $O\TextConfig.obj \ + $O\UTFConvert.obj \ + $O\Vector.obj \ + $O\Wildcard.obj \ + +WIN_OBJS = \ + $O\CommonDialog.obj \ + $O\DLL.obj \ + $O\Error.obj \ + $O\FileDir.obj \ + $O\FileFind.obj \ + $O\FileIO.obj \ + $O\FileName.obj \ + $O\MemoryLock.obj \ + $O\PropVariant.obj \ + $O\PropVariantConversions.obj \ + $O\Registry.obj \ + $O\ResourceString.obj \ + $O\Shell.obj \ + $O\Synchronization.obj \ + $O\Window.obj \ + +WIN_CTRL_OBJS = \ + $O\ComboBox.obj \ + $O\Dialog.obj \ + $O\ListView.obj \ + +7ZIP_COMMON_OBJS = \ + $O\FilePathAutoRename.obj \ + $O\FileStreams.obj \ + $O\StreamUtils.obj \ + +UI_COMMON_OBJS = \ + $O\ArchiveCommandLine.obj \ + $O\ArchiveExtractCallback.obj \ + $O\ArchiveOpenCallback.obj \ + $O\ArchiverInfo.obj \ + $O\DefaultName.obj \ + $O\EnumDirItems.obj \ + $O\Extract.obj \ + $O\ExtractingFilePath.obj \ + $O\OpenArchive.obj \ + $O\PropIDUtils.obj \ + $O\SetProperties.obj \ + $O\SortUtils.obj \ + $O\TempFiles.obj \ + $O\Update.obj \ + $O\UpdateAction.obj \ + $O\UpdateCallback.obj \ + $O\UpdatePair.obj \ + $O\UpdateProduce.obj \ + $O\WorkDir.obj \ + $O\ZipRegistry.obj \ + +FM_OBJS = \ + $O\ExtractCallback.obj \ + $O\FormatUtils.obj \ + $O\HelpUtils.obj \ + $O\LangUtils.obj \ + $O\OpenCallback.obj \ + $O\ProgramLocation.obj \ + $O\RegistryUtils.obj \ + $O\SplitUtils.obj \ + $O\StringUtils.obj \ + $O\UpdateCallback100.obj \ + +OBJS = \ + $O\StdAfx.obj \ + $(GUI_OBJS) \ + $(COMMON_OBJS) \ + $(WIN_OBJS) \ + $(WIN_CTRL_OBJS) \ + $(7ZIP_COMMON_OBJS) \ + $(UI_COMMON_OBJS) \ + $(FM_OBJS)\ + $O\MyMessages.obj \ + $O\MessagesDialog.obj \ + $O\OverwriteDialog.obj \ + $O\PasswordDialog.obj \ + $O\ProgressDialog.obj \ + $O\CopyCoder.obj \ + $O\resource.res + +!include "../../../Build.mak" + +$(GUI_OBJS): $(*B).cpp + $(COMPL) +$(COMMON_OBJS): ../../../Common/$(*B).cpp + $(COMPL) +$(WIN_OBJS): ../../../Windows/$(*B).cpp + $(COMPL) +$(WIN_CTRL_OBJS): ../../../Windows/Control/$(*B).cpp + $(COMPL) +$(7ZIP_COMMON_OBJS): ../../Common/$(*B).cpp + $(COMPL) +$(UI_COMMON_OBJS): ../Common/$(*B).cpp + $(COMPL) +$(FM_OBJS): ../../FileManager/$(*B).cpp + $(COMPL) +$O\MyMessages.obj: ../Explorer/MyMessages.cpp + $(COMPL) +$O\MessagesDialog.obj: ../../FileManager/Resource/MessagesDialog/$(*B).cpp + $(COMPL) +$O\OverwriteDialog.obj: ../../FileManager/Resource/OverwriteDialog./$(*B).cpp + $(COMPL) +$O\PasswordDialog.obj: ../../FileManager/Resource/PasswordDialog/$(*B).cpp + $(COMPL) +$O\ProgressDialog.obj: ../../FileManager/Resource/ProgressDialog2/$(*B).cpp + $(COMPL) +$O\CopyCoder.obj: ../../Compress/Copy/$(*B).cpp + $(COMPL) diff --git a/CPP/7zip/UI/GUI/resource.h b/CPP/7zip/UI/GUI/resource.h new file mode 100755 index 00000000..d88af787 --- /dev/null +++ b/CPP/7zip/UI/GUI/resource.h @@ -0,0 +1,45 @@ +#define IDS_CONTEXT_EXTRACT 42 +#define IDS_CONTEXT_EXTRACT_HELP 43 +#define IDS_CONTEXT_COMPRESS 44 +#define IDS_CONTEXT_COMPRESS_HELP 45 +#define IDS_CONTEXT_OPEN 46 +#define IDS_CONTEXT_OPEN_HELP 47 +#define IDS_CONTEXT_TEST 48 +#define IDS_CONTEXT_TEST_HELP 49 +#define IDS_CONTEXT_CAPTION_HELP 50 +#define IDS_CONTEXT_POPUP_CAPTION 51 +#define IDS_OPEN_TYPE_ALL_FILES 80 + +#define IDS_METHOD_STORE 81 +#define IDS_METHOD_NORMAL 82 +#define IDS_METHOD_MAXIMUM 83 +#define IDS_METHOD_FAST 84 +#define IDS_METHOD_FASTEST 85 +#define IDS_METHOD_ULTRA 86 + +#define IDS_COMPRESS_UPDATE_MODE_ADD 90 +#define IDS_COMPRESS_UPDATE_MODE_UPDATE 91 +#define IDS_COMPRESS_UPDATE_MODE_FRESH 92 +#define IDS_COMPRESS_UPDATE_MODE_SYNCHRONIZE 93 + +#define IDS_COMPRESS_SPLIT_CONFIRM_MESSAGE 94 +#define IDS_COMPRESS_INCORRECT_VOLUME_SIZE 95 + +#define IDS_COMPRESS_SET_ARCHIVE_DIALOG_TITLE 96 +#define IDS_CANT_UPDATE_ARCHIVE 97 + +#define IDS_PROGRESS_COMPRESSING 98 +#define IDS_PROGRESS_TESTING 99 +#define IDS_ERROR 100 +#define IDS_MESSAGE_NO_ERRORS 101 +#define IDS_CONFIG_DIALOG_CAPTION 102 + +#define IDS_PASSWORD_USE_ASCII 110 +#define IDS_PASSWORD_PASSWORDS_DO_NOT_MATCH 111 +#define IDS_PASSWORD_IS_TOO_LONG 112 + +#define IDD_DIALOG_EXTRACT 137 +#define IDB_DELETE 149 +#define IDC_LIST1 1067 +#define IDC_COLUMN_EDIT_WIDTH 1068 + diff --git a/CPP/7zip/UI/GUI/resource.rc b/CPP/7zip/UI/GUI/resource.rc new file mode 100755 index 00000000..19f7e61b --- /dev/null +++ b/CPP/7zip/UI/GUI/resource.rc @@ -0,0 +1,57 @@ +#include "../../MyVersionInfo.rc" +#include +#include "resource.h" + +MY_VERSION_INFO_APP("7-Zip GUI", "7zg") + +IDI_ICON1 ICON "FM.ico" + +1 24 MOVEABLE PURE "7zG.exe.manifest" + +STRINGTABLE +BEGIN + IDS_CONTEXT_EXTRACT "Extract files..." + IDS_CONTEXT_EXTRACT_HELP "Extracts files from the selected archive." + IDS_CONTEXT_COMPRESS "Add to archive..." + IDS_CONTEXT_COMPRESS_HELP "Adds the selected items to archive." + IDS_CONTEXT_OPEN "Open" + IDS_CONTEXT_OPEN_HELP "Opens the selected archive." + IDS_CONTEXT_TEST "Test archive" + IDS_CONTEXT_TEST_HELP "Tests integrity of the selected archive." + IDS_CONTEXT_CAPTION_HELP "7-Zip commands" + IDS_CONTEXT_POPUP_CAPTION "7-Zip" + IDS_OPEN_TYPE_ALL_FILES "All Files" + IDS_METHOD_STORE "Store" + IDS_METHOD_NORMAL "Normal" + IDS_METHOD_MAXIMUM "Maximum" + IDS_METHOD_FAST "Fast" + IDS_METHOD_FASTEST "Fastest" + IDS_METHOD_ULTRA "Ultra" + IDS_COMPRESS_UPDATE_MODE_ADD "Add and replace files" + IDS_COMPRESS_UPDATE_MODE_UPDATE "Update and add files" + IDS_COMPRESS_UPDATE_MODE_FRESH "Freshen existing files" + IDS_COMPRESS_UPDATE_MODE_SYNCHRONIZE "Synchronize files" + IDS_COMPRESS_SET_ARCHIVE_DIALOG_TITLE "Browse" + IDS_COMPRESS_INCORRECT_VOLUME_SIZE "Incorrect volume size" + IDS_COMPRESS_SPLIT_CONFIRM_MESSAGE "Specified volume size: {0} bytes.\nAre you sure you want to split archive into such volumes?" + + IDS_PASSWORD_USE_ASCII "Use only English letters, numbers and special characters (!, #, $, ...) for password." + IDS_PASSWORD_PASSWORDS_DO_NOT_MATCH "Passwords do not match" + IDS_PASSWORD_IS_TOO_LONG "Password is too long" + + IDS_CANT_UPDATE_ARCHIVE "Can not update archive '{0}'" + IDS_PROGRESS_COMPRESSING "Compressing" + IDS_PROGRESS_TESTING "Testing" + IDS_ERROR "Error" + IDS_MESSAGE_NO_ERRORS "There are no errors" + IDS_CONFIG_DIALOG_CAPTION "7-Zip Options" +END + +#include "../../FileManager/Resource/PropertyName/resource.rc" +#include "../../FileManager/Resource/OverwriteDialog/resource.rc" +#include "../../FileManager/Resource/PasswordDialog/resource.rc" +#include "../../FileManager/Resource/MessagesDialog/resource.rc" +#include "../../FileManager/Resource/ProgressDialog2/resource.rc" +#include "../Resource/Extract/resource.rc" +#include "../Resource/ExtractDialog/resource.rc" +#include "../Resource/CompressDialog/resource.rc" diff --git a/CPP/7zip/UI/Resource/CompressDialog/resource.h b/CPP/7zip/UI/Resource/CompressDialog/resource.h new file mode 100755 index 00000000..847bb3f9 --- /dev/null +++ b/CPP/7zip/UI/Resource/CompressDialog/resource.h @@ -0,0 +1,40 @@ +#define IDD_DIALOG_COMPRESS 152 +#define IDC_STATIC_COMPRESS_MEMORY 1022 +#define IDC_STATIC_COMPRESS_MEMORY_DE 1023 +#define IDC_STATIC_COMPRESS_MEMORY_VALUE 1027 +#define IDC_STATIC_COMPRESS_MEMORY_DE_VALUE 1028 +#define IDC_COMPRESS_COMBO_ARCHIVE 1072 +#define IDC_COMPRESS_BUTTON_SET_ARCHIVE 1073 +#define IDC_COMPRESS_COMBO_LEVEL 1074 +#define IDC_COMPRESS_COMBO_UPDATE_MODE 1075 +#define IDC_COMPRESS_COMBO_FORMAT 1076 +#define IDC_COMPRESS_COMBO_VOLUME 1077 +#define IDC_COMPRESS_COMBO_METHOD 1078 +#define IDC_COMPRESS_COMBO_DICTIONARY 1079 +#define IDC_COMPRESS_COMBO_ORDER 1080 +#define IDC_COMPRESS_SFX 1090 +#define IDC_COMPRESS_EDIT_PARAMETERS 1091 +#define IDC_COMPRESS_SOLID 1092 +#define IDC_COMPRESS_MULTI_THREAD 1093 +#define IDC_STATIC_COMPRESS_ARCHIVE 1097 +#define IDC_STATIC_COMPRESS_FORMAT 1098 +#define IDC_STATIC_COMPRESS_LEVEL 1099 +#define IDC_STATIC_COMPRESS_PARAMETERS 1100 +#define IDC_STATIC_COMPRESS_UPDATE_MODE 1101 +#define IDC_STATIC_COMPRESS_OPTIONS 1102 +#define IDC_STATIC_COMPRESS_VOLUME 1103 +#define IDC_STATIC_COMPRESS_METHOD 1104 +#define IDC_STATIC_COMPRESS_DICTIONARY 1105 +#define IDC_STATIC_COMPRESS_ORDER 1106 + +#define IDC_COMPRESS_ENCRYPTION 1110 +#define IDC_STATIC_COMPRESS_PASSWORD1 1111 +#define IDC_COMPRESS_EDIT_PASSWORD1 1112 +#define IDC_STATIC_COMPRESS_PASSWORD2 1113 +#define IDC_COMPRESS_EDIT_PASSWORD2 1114 +#define IDC_COMPRESS_CHECK_SHOW_PASSWORD 1115 + +#define IDC_STATIC_COMPRESS_ENCRYPTION_METHOD 1120 +#define IDC_COMPRESS_COMBO_ENCRYPTION_METHOD 1121 + +#define IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES 1122 diff --git a/CPP/7zip/UI/Resource/CompressDialog/resource.rc b/CPP/7zip/UI/Resource/CompressDialog/resource.rc new file mode 100755 index 00000000..9019a1af --- /dev/null +++ b/CPP/7zip/UI/Resource/CompressDialog/resource.rc @@ -0,0 +1,117 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 344 +#define ySize2 295 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#undef gSize +#undef gSpace +#undef g0XSize +#undef g1XPos +#undef g1XSize +#undef g2XSize +#undef g3XPos +#undef g3XSize +#undef g4XPos +#undef g4XPos2 +#undef g4XSize +#undef g4XSize2 +#undef bXPos1 +#undef bXPos2 +#undef bXPos3 +#undef bYPos + +#define gSize 160 +#define gSpace 24 + +#define g0XSize 82 +#define g1XPos (marg + g0XSize) +#define g1XSize (gSize - g0XSize) + +#define g2XSize 122 +#define g3XPos (marg + g2XSize) +#define g3XSize (gSize - g2XSize) + +#define g4XPos (marg + gSize + gSpace) +#define g4XPos2 (g4XPos + 7) +#define g4XSize (xSize2 - gSize - gSpace) +#define g4XSize2 (g4XSize - 14) + +#define bXPos1 (xSize - marg - bXSize) +#define bXPos2 (bXPos1 - 10 - bXSize) +#define bXPos3 (bXPos2 - 10 - bXSize) + +#define bYPos (ySize - marg - bYSize) + +IDD_DIALOG_COMPRESS DIALOG 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "Add to Archive" +MY_FONT +BEGIN + LTEXT "&Archive:", IDC_STATIC_COMPRESS_ARCHIVE, marg, marg, xSize2, 8 + COMBOBOX IDC_COMPRESS_COMBO_ARCHIVE, marg, 18, xSize2 - bDotsSize - 12, 126, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "...", IDC_COMPRESS_BUTTON_SET_ARCHIVE, xSize - marg - bDotsSize, 17, bDotsSize, bYSize, WS_GROUP + + LTEXT "Archive &format:", IDC_STATIC_COMPRESS_FORMAT, marg, 41, g0XSize, 8 + COMBOBOX IDC_COMPRESS_COMBO_FORMAT, g1XPos, 39, g1XSize , 80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + LTEXT "Compression &level:",IDC_STATIC_COMPRESS_LEVEL, marg, 62, g0XSize, 8 + COMBOBOX IDC_COMPRESS_COMBO_LEVEL, g1XPos, 60, g1XSize, 80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + LTEXT "Compression &method:",IDC_STATIC_COMPRESS_METHOD, marg, 83, g0XSize, 8 + COMBOBOX IDC_COMPRESS_COMBO_METHOD, g1XPos, 81, g1XSize, 80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + LTEXT "&Dictionary size:",IDC_STATIC_COMPRESS_DICTIONARY, marg, 104, g0XSize, 8 + COMBOBOX IDC_COMPRESS_COMBO_DICTIONARY, g1XPos, 102, g1XSize, 167, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + LTEXT "&Word size:",IDC_STATIC_COMPRESS_ORDER, marg, 125, g0XSize, 8 + COMBOBOX IDC_COMPRESS_COMBO_ORDER, g1XPos, 123, g1XSize, 141, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + + LTEXT "Memory usage for Compressing:", IDC_STATIC_COMPRESS_MEMORY, marg, 149, g2XSize, 8 + RTEXT "0", IDC_STATIC_COMPRESS_MEMORY_VALUE, g3XPos, 149, g3XSize, 8 + + LTEXT "Memory usage for Decompressing:", IDC_STATIC_COMPRESS_MEMORY_DE, marg, 163, g2XSize, 8 + RTEXT "0",IDC_STATIC_COMPRESS_MEMORY_DE_VALUE, g3XPos, 163, g3XSize, 8 + + + CONTROL "Create &Solid archive", IDC_COMPRESS_SOLID,"Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 181, gSize, 10 + CONTROL "Multi-threading", IDC_COMPRESS_MULTI_THREAD, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + marg, 195, gSize, 10 + + LTEXT "Split to &volumes, bytes:", IDC_STATIC_COMPRESS_VOLUME, marg, 215, gSize, 8 + COMBOBOX IDC_COMPRESS_COMBO_VOLUME, marg, 227, gSize, 73, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + + LTEXT "&Parameters:",IDC_STATIC_COMPRESS_PARAMETERS, marg, 250, xSize2, 8 + EDITTEXT IDC_COMPRESS_EDIT_PARAMETERS, marg, 262, xSize2, 14, ES_AUTOHSCROLL + + LTEXT "&Update mode:",IDC_STATIC_COMPRESS_UPDATE_MODE, g4XPos, 39, g4XSize, 8 + COMBOBOX IDC_COMPRESS_COMBO_UPDATE_MODE, g4XPos, 51, g4XSize, 80, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + GROUPBOX "Options",IDC_STATIC_COMPRESS_OPTIONS, g4XPos, 73, g4XSize, 32 + CONTROL "Create SF&X archive",IDC_COMPRESS_SFX, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + g4XPos2, 87, g4XSize2, 10 + + GROUPBOX "Encryption",IDC_COMPRESS_ENCRYPTION, g4XPos, 113, g4XSize, 127 + + LTEXT "Enter password:",IDC_STATIC_COMPRESS_PASSWORD1, g4XPos2, 127, g4XSize2, 8 + EDITTEXT IDC_COMPRESS_EDIT_PASSWORD1, g4XPos2, 139, g4XSize2, 14, ES_PASSWORD | ES_AUTOHSCROLL + LTEXT "Reenter password:",IDC_STATIC_COMPRESS_PASSWORD2, g4XPos2, 159, g4XSize2, 8 + EDITTEXT IDC_COMPRESS_EDIT_PASSWORD2, g4XPos2, 171, g4XSize2, 14, ES_PASSWORD | ES_AUTOHSCROLL + + CONTROL "Show Password",IDC_COMPRESS_CHECK_SHOW_PASSWORD,"Button", BS_AUTOCHECKBOX | WS_TABSTOP, + g4XPos2, 192, g4XSize2, 10 + + LTEXT "&Encryption method:",IDC_STATIC_COMPRESS_ENCRYPTION_METHOD, g4XPos2, 208, 80, 8 + COMBOBOX IDC_COMPRESS_COMBO_ENCRYPTION_METHOD, g4XPos2 + 90, 206, g4XSize2 - 90, 198, CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + CONTROL "Encrypt file &names", IDC_COMPRESS_CHECK_ENCRYPT_FILE_NAMES, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, + g4XPos2, 224, g4XSize2, 10 + + DEFPUSHBUTTON "OK", IDOK, bXPos3, bYPos, bXSize, bYSize, WS_GROUP + PUSHBUTTON "Cancel", IDCANCEL, bXPos2, bYPos, bXSize, bYSize + PUSHBUTTON "Help", IDHELP, bXPos1, bYPos, bXSize, bYSize +END diff --git a/CPP/7zip/UI/Resource/Extract/resource.h b/CPP/7zip/UI/Resource/Extract/resource.h new file mode 100755 index 00000000..917c0a34 --- /dev/null +++ b/CPP/7zip/UI/Resource/Extract/resource.h @@ -0,0 +1,15 @@ +#define IDS_CANNOT_CREATE_FOLDER 200 +#define IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE 201 + +#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC 202 +#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR 203 +#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_UNSUPPORTED_METHOD 204 +#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC_ENCRYPTED 205 +#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED 206 + +#define IDS_EXTRACT_SET_FOLDER 207 +#define IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CANNOT_OPEN_FILE 208 +#define IDS_PROGRESS_EXTRACTING 209 + +#define IDS_CANT_OPEN_ARCHIVE 103 +#define IDS_CANT_OPEN_ENCRYPTED_ARCHIVE 104 diff --git a/CPP/7zip/UI/Resource/Extract/resource.rc b/CPP/7zip/UI/Resource/Extract/resource.rc new file mode 100755 index 00000000..d3fd1df9 --- /dev/null +++ b/CPP/7zip/UI/Resource/Extract/resource.rc @@ -0,0 +1,19 @@ +#include "resource.h" + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +STRINGTABLE DISCARDABLE +BEGIN + IDS_CANNOT_CREATE_FOLDER "Cannot create folder '{0}'" + IDS_OPEN_IS_NOT_SUPORTED_ARCHIVE "File is not supported archive." + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC "CRC failed in '{0}'. File is broken." + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR "Data error in '{0}'. File is broken" + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CRC_ENCRYPTED "CRC failed in encrypted file '{0}'. Wrong password?" + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED "Data error in encrypted file '{0}'. Wrong password?" + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_UNSUPPORTED_METHOD "Unsupported compression method for '{0}'." + IDS_EXTRACT_SET_FOLDER "Specify a location for extracted files." + IDS_MESSAGES_DIALOG_EXTRACT_MESSAGE_CANNOT_OPEN_FILE "Can not open output file '{0}'." + IDS_PROGRESS_EXTRACTING "Extracting" + IDS_CANT_OPEN_ARCHIVE "Can not open file '{0}' as archive" + IDS_CANT_OPEN_ENCRYPTED_ARCHIVE "Can not open encrypted archive '{0}'. Wrong password?" +END diff --git a/CPP/7zip/UI/Resource/ExtractDialog/resource.h b/CPP/7zip/UI/Resource/ExtractDialog/resource.h new file mode 100755 index 00000000..338a2561 --- /dev/null +++ b/CPP/7zip/UI/Resource/ExtractDialog/resource.h @@ -0,0 +1,26 @@ +#define IDC_STATIC_EXTRACT_EXTRACT_TO 1020 +#define IDC_EXTRACT_COMBO_PATH 1021 +#define IDC_EXTRACT_BUTTON_SET_PATH 1022 + + +#define IDC_EXTRACT_PATH_MODE 1040 +#define IDC_EXTRACT_RADIO_FULL_PATHNAMES 1041 +#define IDC_EXTRACT_RADIO_CURRENT_PATHNAMES 1042 +#define IDC_EXTRACT_RADIO_NO_PATHNAMES 1043 + +#define IDC_EXTRACT_OVERWRITE_MODE 1050 +#define IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE 1051 +#define IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT 1052 +#define IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES 1053 +#define IDC_EXTRACT_RADIO_SELECTED_FILES 1054 +#define IDC_EXTRACT_RADIO_ALL_FILES 1055 +#define IDC_EXTRACT_RADIO_AUTO_RENAME 1056 +#define IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING 1057 + + +#define IDC_EXTRACT_FILES 1060 + +#define IDC_EXTRACT_PASSWORD 1100 +#define IDC_EXTRACT_EDIT_PASSWORD 1101 +#define IDC_EXTRACT_CHECK_SHOW_PASSWORD 1102 + diff --git a/CPP/7zip/UI/Resource/ExtractDialog/resource.rc b/CPP/7zip/UI/Resource/ExtractDialog/resource.rc new file mode 100755 index 00000000..05cf5ea6 --- /dev/null +++ b/CPP/7zip/UI/Resource/ExtractDialog/resource.rc @@ -0,0 +1,80 @@ +#include "resource.h" +#include "../../../GuiCommon.rc" + +#define xSize2 285 +#define ySize2 204 + +#define xSize (xSize2 + marg + marg) +#define ySize (ySize2 + marg + marg) + +#undef g1XSize +#undef g1XSize2 +#undef g1XPos2 +#undef g2XPos +#undef g2XPos2 +#undef g2XSize +#undef g2XSize2 + +#define bYPos (ySize - marg - bYSize) + +#define g1XSize 127 +#define g1XSize2 (g1XSize - 13) +#define g1XPos2 (marg + 7) + +#define gSpace 14 +#define g2XPos (marg + g1XSize + gSpace) +#define g2XPos2 (g2XPos + 7) +#define g2XSize (xSize2 - g1XSize - gSpace) +#define g2XSize2 (g2XSize - 14) + +#define bXPos1 (xSize - marg - bXSize) +#define bXPos2 (bXPos1 - 10 - bXSize) +#define bXPos3 (bXPos2 - 10 - bXSize) + +IDD_DIALOG_EXTRACT DIALOG DISCARDABLE 0, 0, xSize, ySize MY_MODAL_DIALOG_STYLE +CAPTION "Extract" +MY_FONT +BEGIN + LTEXT "E&xtract to:", IDC_STATIC_EXTRACT_EXTRACT_TO, marg, marg, xSize2, 8 + + COMBOBOX IDC_EXTRACT_COMBO_PATH, marg, 21, xSize2 - bDotsSize - 13, 126, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP + + PUSHBUTTON "...", IDC_EXTRACT_BUTTON_SET_PATH, xSize - marg - bDotsSize, 20, bDotsSize, bYSize, WS_GROUP + + GROUPBOX "Path mode",IDC_EXTRACT_PATH_MODE, marg, 44, g1XSize, 57 + CONTROL "Full pathnames", IDC_EXTRACT_RADIO_FULL_PATHNAMES,"Button", BS_AUTORADIOBUTTON | WS_GROUP, + g1XPos2, 57, g1XSize2, 10 + CONTROL "Current pathnames",IDC_EXTRACT_RADIO_CURRENT_PATHNAMES, "Button", BS_AUTORADIOBUTTON, + g1XPos2, 71, g1XSize2, 10 + CONTROL "No pathnames", IDC_EXTRACT_RADIO_NO_PATHNAMES, "Button", BS_AUTORADIOBUTTON, + g1XPos2, 85, g1XSize2, 10 + + GROUPBOX "Overwrite mode",IDC_EXTRACT_OVERWRITE_MODE, g2XPos, 44, g2XSize, 88, WS_GROUP + CONTROL "Ask before overwrite", IDC_EXTRACT_RADIO_ASK_BEFORE_OVERWRITE, "Button", BS_AUTORADIOBUTTON | WS_GROUP, + g2XPos2, 57, g2XSize2, 10 + CONTROL "Overwrite without prompt", IDC_EXTRACT_RADIO_OVERWRITE_WITHOUT_PROMPT, "Button", BS_AUTORADIOBUTTON, + g2XPos2, 71, g2XSize2, 10 + CONTROL "Skip existing files", IDC_EXTRACT_RADIO_SKIP_EXISTING_FILES, "Button", BS_AUTORADIOBUTTON, + g2XPos2, 85, g2XSize2, 10 + CONTROL "Auto rename", IDC_EXTRACT_RADIO_AUTO_RENAME, "Button", BS_AUTORADIOBUTTON, + g2XPos2, 99, g2XSize2, 10 + CONTROL "Auto rename existing files", IDC_EXTRACT_RADIO_AUTO_RENAME_EXISTING, "Button", BS_AUTORADIOBUTTON, + g2XPos2,113, g2XSize2, 10 + + GROUPBOX "Files",IDC_EXTRACT_FILES, marg, 140, 127, 48, NOT WS_VISIBLE | WS_DISABLED | WS_GROUP + CONTROL "&Selected files",IDC_EXTRACT_RADIO_SELECTED_FILES, "Button", BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_DISABLED | WS_GROUP, + g1XPos2, 153, g1XSize2, 10 + CONTROL "&All files",IDC_EXTRACT_RADIO_ALL_FILES, "Button", BS_AUTORADIOBUTTON | NOT WS_VISIBLE | WS_DISABLED, + g1XPos2, 166, g1XSize2, 10 + + GROUPBOX "Password",IDC_EXTRACT_PASSWORD, g2XPos, 142, g2XSize, 46 + EDITTEXT IDC_EXTRACT_EDIT_PASSWORD,154,153,130,14, ES_PASSWORD | ES_AUTOHSCROLL + CONTROL "Show Password",IDC_EXTRACT_CHECK_SHOW_PASSWORD,"Button", BS_AUTOCHECKBOX | WS_TABSTOP, + g2XPos2, 172, g2XSize2, 10 + + DEFPUSHBUTTON "OK", IDOK, bXPos3, bYPos, bXSize, bYSize, WS_GROUP + PUSHBUTTON "Cancel", IDCANCEL, bXPos2, bYPos, bXSize, bYSize + PUSHBUTTON "Help", IDHELP, bXPos1, bYPos, bXSize, bYSize +END + + diff --git a/CPP/7zip/UI/makefile b/CPP/7zip/UI/makefile new file mode 100755 index 00000000..942beaa0 --- /dev/null +++ b/CPP/7zip/UI/makefile @@ -0,0 +1,10 @@ +DIRS = \ + Client7z\~ \ + Console\~ \ + Explorer\~ \ + GUI\~ \ + +all: $(DIRS) + +$(DIRS): +!include "../SubBuild.mak" -- cgit v1.2.3