diff options
Diffstat (limited to 'CPP/7zip/UI/Far/Main.cpp')
-rwxr-xr-x | CPP/7zip/UI/Far/Main.cpp | 622 |
1 files changed, 622 insertions, 0 deletions
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 <locale.h> +#include <initguid.h> + +#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<IInStream> 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<IInFolderArchive> archiveHandler; + + // CArchiverInfo archiverInfoResult; + // ::OutputDebugString("before OpenArchive\n"); + + COpenArchiveCallback *openArchiveCallbackSpec = new COpenArchiveCallback; + + CMyComPtr<IArchiveOpenCallback> 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> 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); +} |