mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-11 08:07:12 -06:00
15.05
This commit is contained in:
committed by
Kornel Lesiński
parent
0713a3ab80
commit
54490d51d5
@@ -29,7 +29,7 @@ bool CAboutDialog::OnInit()
|
||||
UString s = L"7-Zip " LLL(MY_VERSION);
|
||||
#ifdef MY_CPU_64BIT
|
||||
s += L" [";
|
||||
s += LangString(IDS_PROP_BIT64);
|
||||
AddLangString(s, IDS_PROP_BIT64);
|
||||
s += L']';
|
||||
#endif
|
||||
|
||||
|
||||
839
CPP/7zip/UI/FileManager/AltStreamsFolder.cpp
Normal file
839
CPP/7zip/UI/FileManager/AltStreamsFolder.cpp
Normal file
@@ -0,0 +1,839 @@
|
||||
// AltStreamsFolder.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Common/ComTry.h"
|
||||
#include "../../../Common/StringConvert.h"
|
||||
#include "../../../Common/Wildcard.h"
|
||||
|
||||
#include "../../../Windows/ErrorMsg.h"
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileIO.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
|
||||
#include "../Common/ExtractingFilePath.h"
|
||||
|
||||
#include "../Agent/IFolderArchive.h"
|
||||
|
||||
#include "AltStreamsFolder.h"
|
||||
#include "FSDrives.h"
|
||||
#include "FSFolder.h"
|
||||
|
||||
#include "SysIconUtils.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NFind;
|
||||
using namespace NDir;
|
||||
using namespace NName;
|
||||
|
||||
#ifndef USE_UNICODE_FSTRING
|
||||
int CompareFileNames_ForFolderList(const FChar *s1, const FChar *s2);
|
||||
#endif
|
||||
|
||||
#ifndef UNDER_CE
|
||||
|
||||
namespace NFsFolder
|
||||
{
|
||||
bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace NAltStreamsFolder {
|
||||
|
||||
static const Byte kProps[] =
|
||||
{
|
||||
kpidName,
|
||||
kpidSize,
|
||||
kpidPackSize
|
||||
};
|
||||
|
||||
static unsigned GetFsParentPrefixSize(const FString &path)
|
||||
{
|
||||
if (IsNetworkShareRootPath(path))
|
||||
return 0;
|
||||
unsigned prefixSize = GetRootPrefixSize(path);
|
||||
if (prefixSize == 0 || prefixSize >= path.Len())
|
||||
return 0;
|
||||
FString parentPath = path;
|
||||
int pos = parentPath.ReverseFind_PathSepar();
|
||||
if (pos < 0)
|
||||
return 0;
|
||||
if (pos == (int)parentPath.Len() - 1)
|
||||
{
|
||||
parentPath.DeleteBack();
|
||||
pos = parentPath.ReverseFind_PathSepar();
|
||||
if (pos < 0)
|
||||
return 0;
|
||||
}
|
||||
if ((unsigned)pos + 1 < prefixSize)
|
||||
return 0;
|
||||
return pos + 1;
|
||||
}
|
||||
|
||||
HRESULT CAltStreamsFolder::Init(const FString &path /* , IFolderFolder *parentFolder */)
|
||||
{
|
||||
// _parentFolder = parentFolder;
|
||||
if (path.Back() != ':')
|
||||
return E_FAIL;
|
||||
|
||||
_pathPrefix = path;
|
||||
_pathBaseFile = path;
|
||||
_pathBaseFile.DeleteBack();
|
||||
|
||||
{
|
||||
CFileInfo fi;
|
||||
if (!fi.Find(_pathBaseFile))
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
unsigned prefixSize = GetFsParentPrefixSize(_pathBaseFile);
|
||||
if (prefixSize == 0)
|
||||
return S_OK;
|
||||
FString parentPath = _pathBaseFile;
|
||||
parentPath.DeleteFrom(prefixSize);
|
||||
|
||||
_findChangeNotification.FindFirst(parentPath, false,
|
||||
FILE_NOTIFY_CHANGE_FILE_NAME
|
||||
| FILE_NOTIFY_CHANGE_DIR_NAME
|
||||
| FILE_NOTIFY_CHANGE_ATTRIBUTES
|
||||
| FILE_NOTIFY_CHANGE_SIZE
|
||||
| FILE_NOTIFY_CHANGE_LAST_WRITE
|
||||
/*
|
||||
| FILE_NOTIFY_CHANGE_LAST_ACCESS
|
||||
| FILE_NOTIFY_CHANGE_CREATION
|
||||
| FILE_NOTIFY_CHANGE_SECURITY
|
||||
*/
|
||||
);
|
||||
/*
|
||||
if (_findChangeNotification.IsHandleAllocated())
|
||||
return S_OK;
|
||||
return GetLastError();
|
||||
*/
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::LoadItems()
|
||||
{
|
||||
Int32 dummy;
|
||||
WasChanged(&dummy);
|
||||
Clear();
|
||||
|
||||
CStreamEnumerator enumerator(_pathBaseFile);
|
||||
|
||||
CStreamInfo si;
|
||||
for (;;)
|
||||
{
|
||||
bool found;
|
||||
if (!enumerator.Next(si, found))
|
||||
{
|
||||
// if (GetLastError() == ERROR_ACCESS_DENIED)
|
||||
// break;
|
||||
// return E_FAIL;
|
||||
break;
|
||||
}
|
||||
if (!found)
|
||||
break;
|
||||
if (si.IsMainStream())
|
||||
continue;
|
||||
CAltStream ss;
|
||||
ss.Name = si.GetReducedName();
|
||||
if (!ss.Name.IsEmpty() && ss.Name[0] == ':')
|
||||
ss.Name.Delete(0);
|
||||
|
||||
ss.Size = si.Size;
|
||||
ss.PackSize_Defined = false;
|
||||
ss.PackSize = si.Size;
|
||||
Streams.Add(ss);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::GetNumberOfItems(UInt32 *numItems)
|
||||
{
|
||||
*numItems = Streams.Size();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#ifdef USE_UNICODE_FSTRING
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::GetItemPrefix(UInt32 /* index */, const wchar_t **name, unsigned *len)
|
||||
{
|
||||
*name = 0;
|
||||
*len = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::GetItemName(UInt32 index, const wchar_t **name, unsigned *len)
|
||||
{
|
||||
*name = 0;
|
||||
*len = 0;
|
||||
{
|
||||
const CAltStream &ss = Streams[index];
|
||||
*name = ss.Name;
|
||||
*len = ss.Name.Len();
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(UInt64) CAltStreamsFolder::GetItemSize(UInt32 index)
|
||||
{
|
||||
return Streams[index].Size;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
{
|
||||
CAltStream &ss = Streams[index];
|
||||
switch (propID)
|
||||
{
|
||||
case kpidIsDir: prop = false; break;
|
||||
case kpidIsAltStream: prop = true; break;
|
||||
case kpidName: prop = ss.Name; break;
|
||||
case kpidSize: prop = ss.Size; break;
|
||||
case kpidPackSize:
|
||||
#ifdef UNDER_CE
|
||||
prop = ss.Size;
|
||||
#else
|
||||
if (!ss.PackSize_Defined)
|
||||
{
|
||||
ss.PackSize_Defined = true;
|
||||
if (!NFsFolder::MyGetCompressedFileSizeW(_pathPrefix + us2fs(ss.Name), ss.PackSize))
|
||||
ss.PackSize = ss.Size;
|
||||
}
|
||||
prop = ss.PackSize;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
// returns Position of extension including '.'
|
||||
|
||||
static inline const wchar_t *GetExtensionPtr(const UString &name)
|
||||
{
|
||||
int dotPos = name.ReverseFind_Dot();
|
||||
return name.Ptr((dotPos < 0) ? name.Len() : dotPos);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(Int32) CAltStreamsFolder::CompareItems(UInt32 index1, UInt32 index2, PROPID propID, Int32 /* propIsRaw */)
|
||||
{
|
||||
const CAltStream &ss1 = Streams[index1];
|
||||
const CAltStream &ss2 = Streams[index2];
|
||||
|
||||
switch (propID)
|
||||
{
|
||||
case kpidName:
|
||||
{
|
||||
return CompareFileNames_ForFolderList(ss1.Name, ss2.Name);
|
||||
// return MyStringCompareNoCase(ss1.Name, ss2.Name);
|
||||
}
|
||||
case kpidSize:
|
||||
return MyCompare(ss1.Size, ss2.Size);
|
||||
case kpidPackSize:
|
||||
{
|
||||
#ifdef UNDER_CE
|
||||
return MyCompare(ss1.Size, ss2.Size);
|
||||
#else
|
||||
// PackSize can be undefined here
|
||||
return MyCompare(
|
||||
ss1.PackSize,
|
||||
ss2.PackSize);
|
||||
#endif
|
||||
}
|
||||
|
||||
case kpidExtension:
|
||||
return CompareFileNames_ForFolderList(
|
||||
GetExtensionPtr(ss1.Name),
|
||||
GetExtensionPtr(ss2.Name));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::BindToFolder(UInt32 /* index */, IFolderFolder **resultFolder)
|
||||
{
|
||||
*resultFolder = 0;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::BindToFolder(const wchar_t * /* name */, IFolderFolder **resultFolder)
|
||||
{
|
||||
*resultFolder = 0;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
static const CFSTR kSuperPrefix = FTEXT("\\\\?\\");
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::BindToParentFolder(IFolderFolder **resultFolder)
|
||||
{
|
||||
*resultFolder = 0;
|
||||
/*
|
||||
if (_parentFolder)
|
||||
{
|
||||
CMyComPtr<IFolderFolder> parentFolder = _parentFolder;
|
||||
*resultFolder = parentFolder.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
if (IsDriveRootPath_SuperAllowed(_pathBaseFile))
|
||||
{
|
||||
CFSDrives *drivesFolderSpec = new CFSDrives;
|
||||
CMyComPtr<IFolderFolder> drivesFolder = drivesFolderSpec;
|
||||
drivesFolderSpec->Init();
|
||||
*resultFolder = drivesFolder.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
parentPath.DeleteFrom(pos + 1);
|
||||
|
||||
if (parentPath == kSuperPrefix)
|
||||
{
|
||||
#ifdef UNDER_CE
|
||||
*resultFolder = 0;
|
||||
#else
|
||||
CFSDrives *drivesFolderSpec = new CFSDrives;
|
||||
CMyComPtr<IFolderFolder> drivesFolder = drivesFolderSpec;
|
||||
drivesFolderSpec->Init(false, true);
|
||||
*resultFolder = drivesFolder.Detach();
|
||||
#endif
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
FString parentPathReduced = parentPath.Left(pos);
|
||||
|
||||
#ifndef UNDER_CE
|
||||
pos = parentPathReduced.ReverseFind_PathSepar();
|
||||
if (pos == 1)
|
||||
{
|
||||
if (!IS_PATH_SEPAR_CHAR(parentPath[0]))
|
||||
return E_FAIL;
|
||||
CNetFolder *netFolderSpec = new CNetFolder;
|
||||
CMyComPtr<IFolderFolder> netFolder = netFolderSpec;
|
||||
netFolderSpec->Init(fs2us(parentPath));
|
||||
*resultFolder = netFolder.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
CFSFolder *parentFolderSpec = new CFSFolder;
|
||||
CMyComPtr<IFolderFolder> parentFolder = parentFolderSpec;
|
||||
RINOK(parentFolderSpec->Init(parentPath, 0));
|
||||
*resultFolder = parentFolder.Detach();
|
||||
*/
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::GetNumberOfProperties(UInt32 *numProperties)
|
||||
{
|
||||
*numProperties = ARRAY_SIZE(kProps);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::GetPropertyInfo IMP_IFolderFolder_GetProp(kProps)
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch (propID)
|
||||
{
|
||||
case kpidType: prop = "AltStreamsFolder"; break;
|
||||
case kpidPath: prop = fs2us(_pathPrefix); break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::WasChanged(Int32 *wasChanged)
|
||||
{
|
||||
bool wasChangedMain = false;
|
||||
for (;;)
|
||||
{
|
||||
if (!_findChangeNotification.IsHandleAllocated())
|
||||
{
|
||||
*wasChanged = BoolToInt(false);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
DWORD waitResult = ::WaitForSingleObject(_findChangeNotification, 0);
|
||||
bool wasChangedLoc = (waitResult == WAIT_OBJECT_0);
|
||||
if (wasChangedLoc)
|
||||
{
|
||||
_findChangeNotification.FindNext();
|
||||
wasChangedMain = true;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
*wasChanged = BoolToInt(wasChangedMain);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::Clone(IFolderFolder **resultFolder)
|
||||
{
|
||||
CAltStreamsFolder *folderSpec = new CAltStreamsFolder;
|
||||
CMyComPtr<IFolderFolder> folderNew = folderSpec;
|
||||
folderSpec->Init(_pathPrefix);
|
||||
*resultFolder = folderNew.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CAltStreamsFolder::GetAbsPath(const wchar_t *name, FString &absPath)
|
||||
{
|
||||
absPath.Empty();
|
||||
if (!IsAbsolutePath(name))
|
||||
absPath += _pathPrefix;
|
||||
absPath += us2fs(name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
|
||||
const wchar_t *message, const FString &fileName)
|
||||
{
|
||||
UString s = message;
|
||||
s += L" : ";
|
||||
s += fs2us(fileName);
|
||||
return callback->ShowMessage(s);
|
||||
}
|
||||
|
||||
static HRESULT SendMessageError(IFolderArchiveUpdateCallback *callback,
|
||||
const wchar_t *message, const FString &fileName)
|
||||
{
|
||||
UString s = message;
|
||||
s += L" : ";
|
||||
s += fs2us(fileName);
|
||||
return callback->UpdateErrorMessage(s);
|
||||
}
|
||||
|
||||
static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
|
||||
const char *message, const FString &fileName)
|
||||
{
|
||||
return SendMessageError(callback, MultiByteToUnicodeString(message), fileName);
|
||||
}
|
||||
|
||||
/*
|
||||
static HRESULT SendMessageError(IFolderArchiveUpdateCallback *callback,
|
||||
const char *message, const FString &fileName)
|
||||
{
|
||||
return SendMessageError(callback, MultiByteToUnicodeString(message), fileName);
|
||||
}
|
||||
*/
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::CreateFolder(const wchar_t * /* name */, IProgress * /* progress */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::CreateFile(const wchar_t *name, IProgress * /* progress */)
|
||||
{
|
||||
FString absPath;
|
||||
GetAbsPath(name, absPath);
|
||||
NIO::COutFile outFile;
|
||||
if (!outFile.Create(absPath, false))
|
||||
return ::GetLastError();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static DWORD Return_LastError_or_FAIL()
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
if (errorCode == 0)
|
||||
errorCode = (DWORD)E_FAIL;
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
static UString GetLastErrorMessage()
|
||||
{
|
||||
return NError::MyFormatMessage(Return_LastError_or_FAIL());
|
||||
}
|
||||
|
||||
static HRESULT UpdateFile(NFsFolder::CCopyStateIO &state, CFSTR inPath, CFSTR outPath, IFolderArchiveUpdateCallback *callback)
|
||||
{
|
||||
if (NFind::DoesFileOrDirExist(outPath))
|
||||
{
|
||||
RINOK(SendMessageError(callback, NError::MyFormatMessage(ERROR_ALREADY_EXISTS), outPath));
|
||||
CFileInfo fi;
|
||||
if (fi.Find(inPath))
|
||||
{
|
||||
if (state.TotalSize >= fi.Size)
|
||||
state.TotalSize -= fi.Size;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
{
|
||||
if (callback)
|
||||
RINOK(callback->CompressOperation(fs2us(inPath)));
|
||||
RINOK(state.MyCopyFile(inPath, outPath));
|
||||
if (state.ErrorFileIndex >= 0)
|
||||
{
|
||||
if (state.ErrorMessage.IsEmpty())
|
||||
state.ErrorMessage = GetLastErrorMessage();
|
||||
FString errorName;
|
||||
if (state.ErrorFileIndex == 0)
|
||||
errorName = inPath;
|
||||
else
|
||||
errorName = outPath;
|
||||
if (callback)
|
||||
RINOK(SendMessageError(callback, state.ErrorMessage, errorName));
|
||||
}
|
||||
if (callback)
|
||||
RINOK(callback->OperationResult(0));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::Rename(UInt32 index, const wchar_t *newName, IProgress *progress)
|
||||
{
|
||||
CMyComPtr<IFolderArchiveUpdateCallback> callback;
|
||||
if (progress)
|
||||
{
|
||||
RINOK(progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&callback));
|
||||
}
|
||||
|
||||
FString destPath = _pathPrefix + us2fs(newName);
|
||||
|
||||
const CAltStream &ss = Streams[index];
|
||||
|
||||
if (callback)
|
||||
{
|
||||
RINOK(callback->SetNumFiles(1));
|
||||
RINOK(callback->SetTotal(ss.Size));
|
||||
}
|
||||
|
||||
NFsFolder::CCopyStateIO state;
|
||||
state.Progress = progress;
|
||||
state.TotalSize = 0;
|
||||
state.DeleteSrcFile = true;
|
||||
|
||||
return UpdateFile(state, _pathPrefix + us2fs(ss.Name), destPath, callback);
|
||||
}
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::Delete(const UInt32 *indices, UInt32 numItems,IProgress *progress)
|
||||
{
|
||||
RINOK(progress->SetTotal(numItems));
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
const CAltStream &ss = Streams[indices[i]];
|
||||
const FString fullPath = _pathPrefix + us2fs(ss.Name);
|
||||
bool result = DeleteFileAlways(fullPath);
|
||||
if (!result)
|
||||
return Return_LastError_or_FAIL();
|
||||
UInt64 completed = i;
|
||||
RINOK(progress->SetCompleted(&completed));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::SetProperty(UInt32 /* index */, PROPID /* propID */,
|
||||
const PROPVARIANT * /* value */, IProgress * /* progress */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex)
|
||||
{
|
||||
const CAltStream &ss = Streams[index];
|
||||
*iconIndex = 0;
|
||||
int iconIndexTemp;
|
||||
if (GetRealIconIndex(_pathPrefix + us2fs(ss.Name),
|
||||
0 // fi.Attrib
|
||||
, iconIndexTemp) != 0)
|
||||
{
|
||||
*iconIndex = iconIndexTemp;
|
||||
return S_OK;
|
||||
}
|
||||
return Return_LastError_or_FAIL();
|
||||
}
|
||||
|
||||
/*
|
||||
class CGetProp:
|
||||
public IGetProp,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
// const CArc *Arc;
|
||||
// UInt32 IndexInArc;
|
||||
UString Name; // relative path
|
||||
UInt64 Size;
|
||||
|
||||
MY_UNKNOWN_IMP1(IGetProp)
|
||||
INTERFACE_IGetProp(;)
|
||||
};
|
||||
|
||||
STDMETHODIMP CGetProp::GetProp(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
if (propID == kpidName)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
NCOM::CPropVariant prop = Name;
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
if (propID == kpidSize)
|
||||
{
|
||||
NCOM::CPropVariant prop = Size;
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
NCOM::CPropVariant prop;
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
static HRESULT CopyStream(
|
||||
NFsFolder::CCopyStateIO &state,
|
||||
const FString &srcPath,
|
||||
const CFileInfo &srcFileInfo,
|
||||
const CAltStream &srcAltStream,
|
||||
const FString &destPathSpec,
|
||||
IFolderOperationsExtractCallback *callback)
|
||||
{
|
||||
FString destPath = destPathSpec;
|
||||
if (CompareFileNames(destPath, srcPath) == 0)
|
||||
{
|
||||
RINOK(SendMessageError(callback, "can not copy file onto itself", destPath));
|
||||
return E_ABORT;
|
||||
}
|
||||
|
||||
Int32 writeAskResult;
|
||||
CMyComBSTR destPathResult;
|
||||
RINOK(callback->AskWrite(
|
||||
fs2us(srcPath),
|
||||
BoolToInt(false),
|
||||
&srcFileInfo.MTime, &srcAltStream.Size,
|
||||
fs2us(destPath),
|
||||
&destPathResult,
|
||||
&writeAskResult));
|
||||
|
||||
if (IntToBool(writeAskResult))
|
||||
{
|
||||
RINOK(callback->SetCurrentFilePath(fs2us(srcPath)));
|
||||
FString destPathNew = us2fs((LPCOLESTR)destPathResult);
|
||||
RINOK(state.MyCopyFile(srcPath, destPathNew));
|
||||
if (state.ErrorFileIndex >= 0)
|
||||
{
|
||||
if (state.ErrorMessage.IsEmpty())
|
||||
state.ErrorMessage = GetLastErrorMessage();
|
||||
FString errorName;
|
||||
if (state.ErrorFileIndex == 0)
|
||||
errorName = srcPath;
|
||||
else
|
||||
errorName = destPathNew;
|
||||
RINOK(SendMessageError(callback, state.ErrorMessage, errorName));
|
||||
return E_ABORT;
|
||||
}
|
||||
state.StartPos += state.CurrentSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state.TotalSize >= srcAltStream.Size)
|
||||
{
|
||||
state.TotalSize -= srcAltStream.Size;
|
||||
RINOK(state.Progress->SetTotal(state.TotalSize));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 numItems,
|
||||
Int32 /* includeAltStreams */, Int32 /* replaceAltStreamColon */,
|
||||
const wchar_t *path, IFolderOperationsExtractCallback *callback)
|
||||
{
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
|
||||
/*
|
||||
CMyComPtr<IFolderExtractToStreamCallback> ExtractToStreamCallback;
|
||||
RINOK(callback->QueryInterface(IID_IFolderExtractToStreamCallback, (void **)&ExtractToStreamCallback));
|
||||
if (ExtractToStreamCallback)
|
||||
{
|
||||
Int32 useStreams = 0;
|
||||
if (ExtractToStreamCallback->UseExtractToStream(&useStreams) != S_OK)
|
||||
useStreams = 0;
|
||||
if (useStreams == 0)
|
||||
ExtractToStreamCallback.Release();
|
||||
}
|
||||
*/
|
||||
|
||||
UInt64 totalSize = 0;
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
totalSize += Streams[indices[i]].Size;
|
||||
}
|
||||
RINOK(callback->SetTotal(totalSize));
|
||||
RINOK(callback->SetNumFiles(numItems));
|
||||
}
|
||||
|
||||
/*
|
||||
if (ExtractToStreamCallback)
|
||||
{
|
||||
CGetProp *GetProp_Spec = new CGetProp;
|
||||
CMyComPtr<IGetProp> GetProp= GetProp_Spec;
|
||||
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
UInt32 index = indices[i];
|
||||
const CAltStream &ss = Streams[index];
|
||||
GetProp_Spec->Name = ss.Name;
|
||||
GetProp_Spec->Size = ss.Size;
|
||||
CMyComPtr<ISequentialOutStream> outStream;
|
||||
RINOK(ExtractToStreamCallback->GetStream7(GetProp_Spec->Name, BoolToInt(false), &outStream,
|
||||
NArchive::NExtract::NAskMode::kExtract, GetProp)); // isDir
|
||||
FString srcPath;
|
||||
GetFullPath(ss, srcPath);
|
||||
RINOK(ExtractToStreamCallback->PrepareOperation7(NArchive::NExtract::NAskMode::kExtract));
|
||||
RINOK(ExtractToStreamCallback->SetOperationResult7(NArchive::NExtract::NOperationResult::kOK, BoolToInt(false))); // _encrypted
|
||||
// RINOK(CopyStream(state, srcPath, fi, ss, destPath2, callback, completedSize));
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
FString destPath = us2fs(path);
|
||||
if (destPath.IsEmpty() /* && !ExtractToStreamCallback */)
|
||||
return E_INVALIDARG;
|
||||
|
||||
bool isAltDest = NName::IsAltPathPrefix(destPath);;
|
||||
bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back()));
|
||||
|
||||
if (isDirectPath)
|
||||
{
|
||||
if (numItems > 1)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
CFileInfo fi;
|
||||
if (!fi.Find(_pathBaseFile))
|
||||
return GetLastError();
|
||||
|
||||
NFsFolder::CCopyStateIO state;
|
||||
state.Progress = callback;
|
||||
state.DeleteSrcFile = IntToBool(moveMode);
|
||||
state.TotalSize = totalSize;
|
||||
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
UInt32 index = indices[i];
|
||||
const CAltStream &ss = Streams[index];
|
||||
FString destPath2 = destPath;
|
||||
if (!isDirectPath)
|
||||
destPath2 += us2fs(Get_Correct_FsFile_Name(ss.Name));
|
||||
FString srcPath;
|
||||
GetFullPath(ss, srcPath);
|
||||
RINOK(CopyStream(state, srcPath, fi, ss, destPath2, callback));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::CopyFrom(Int32 /* moveMode */, const wchar_t * /* fromFolderPath */,
|
||||
const wchar_t * const * /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */)
|
||||
{
|
||||
/*
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
|
||||
CMyComPtr<IFolderArchiveUpdateCallback> callback;
|
||||
if (progress)
|
||||
{
|
||||
RINOK(progress->QueryInterface(IID_IFolderArchiveUpdateCallback, (void **)&callback));
|
||||
}
|
||||
|
||||
if (CompareFileNames(fromFolderPath, fs2us(_pathPrefix)) == 0)
|
||||
{
|
||||
RINOK(SendMessageError(callback, "can not copy file onto itself", _pathPrefix));
|
||||
return E_ABORT;
|
||||
}
|
||||
|
||||
if (callback)
|
||||
RINOK(callback->SetNumFiles(numItems));
|
||||
|
||||
UInt64 totalSize = 0;
|
||||
|
||||
UInt32 i;
|
||||
|
||||
FString path;
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
path = us2fs(fromFolderPath);
|
||||
path += us2fs(itemsPaths[i]);
|
||||
|
||||
CFileInfo fi;
|
||||
if (!fi.Find(path))
|
||||
return ::GetLastError();
|
||||
if (fi.IsDir())
|
||||
return E_NOTIMPL;
|
||||
totalSize += fi.Size;
|
||||
}
|
||||
|
||||
RINOK(progress->SetTotal(totalSize));
|
||||
|
||||
// UInt64 completedSize = 0;
|
||||
|
||||
NFsFolder::CCopyStateIO state;
|
||||
state.Progress = progress;
|
||||
state.DeleteSrcFile = IntToBool(moveMode);
|
||||
state.TotalSize = totalSize;
|
||||
|
||||
// we need to clear READ-ONLY of parent before creating alt stream
|
||||
{
|
||||
DWORD attrib = GetFileAttrib(_pathBaseFile);
|
||||
if (attrib != INVALID_FILE_ATTRIBUTES
|
||||
&& (attrib & FILE_ATTRIBUTE_READONLY) != 0)
|
||||
{
|
||||
if (!SetFileAttrib(_pathBaseFile, attrib & ~FILE_ATTRIBUTE_READONLY))
|
||||
{
|
||||
if (callback)
|
||||
{
|
||||
RINOK(SendMessageError(callback, GetLastErrorMessage(), _pathBaseFile));
|
||||
return S_OK;
|
||||
}
|
||||
return Return_LastError_or_FAIL();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
path = us2fs(fromFolderPath);
|
||||
path += us2fs(itemsPaths[i]);
|
||||
|
||||
FString destPath = _pathPrefix + us2fs(itemsPaths[i]);
|
||||
|
||||
RINOK(UpdateFile(state, path, destPath, callback));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
*/
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP CAltStreamsFolder::CopyFromFile(UInt32 /* index */, const wchar_t * /* fullFilePath */, IProgress * /* progress */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
}
|
||||
100
CPP/7zip/UI/FileManager/AltStreamsFolder.h
Normal file
100
CPP/7zip/UI/FileManager/AltStreamsFolder.h
Normal file
@@ -0,0 +1,100 @@
|
||||
// AltStreamsFolder.h
|
||||
|
||||
#ifndef __ALT_STREAMS_FOLDER_H
|
||||
#define __ALT_STREAMS_FOLDER_H
|
||||
|
||||
#include "../../../Common/MyCom.h"
|
||||
|
||||
#include "../../../Windows/FileFind.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
#include "IFolder.h"
|
||||
|
||||
namespace NAltStreamsFolder {
|
||||
|
||||
class CAltStreamsFolder;
|
||||
|
||||
struct CAltStream
|
||||
{
|
||||
UInt64 Size;
|
||||
UInt64 PackSize;
|
||||
bool PackSize_Defined;
|
||||
UString Name;
|
||||
};
|
||||
|
||||
|
||||
class CAltStreamsFolder:
|
||||
public IFolderFolder,
|
||||
public IFolderCompare,
|
||||
#ifdef USE_UNICODE_FSTRING
|
||||
public IFolderGetItemName,
|
||||
#endif
|
||||
public IFolderWasChanged,
|
||||
public IFolderOperations,
|
||||
// public IFolderOperationsDeleteToRecycleBin,
|
||||
public IFolderClone,
|
||||
public IFolderGetSystemIconIndex,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
public:
|
||||
MY_QUERYINTERFACE_BEGIN2(IFolderFolder)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderCompare)
|
||||
#ifdef USE_UNICODE_FSTRING
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderGetItemName)
|
||||
#endif
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderWasChanged)
|
||||
// MY_QUERYINTERFACE_ENTRY(IFolderOperationsDeleteToRecycleBin)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderOperations)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderClone)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderGetSystemIconIndex)
|
||||
MY_QUERYINTERFACE_END
|
||||
MY_ADDREF_RELEASE
|
||||
|
||||
|
||||
INTERFACE_FolderFolder(;)
|
||||
INTERFACE_FolderOperations(;)
|
||||
|
||||
STDMETHOD_(Int32, CompareItems)(UInt32 index1, UInt32 index2, PROPID propID, Int32 propIsRaw);
|
||||
|
||||
#ifdef USE_UNICODE_FSTRING
|
||||
INTERFACE_IFolderGetItemName(;)
|
||||
#endif
|
||||
STDMETHOD(WasChanged)(Int32 *wasChanged);
|
||||
STDMETHOD(Clone)(IFolderFolder **resultFolder);
|
||||
|
||||
STDMETHOD(GetSystemIconIndex)(UInt32 index, Int32 *iconIndex);
|
||||
|
||||
private:
|
||||
FString _pathBaseFile; // folder
|
||||
FString _pathPrefix; // folder:
|
||||
|
||||
CObjectVector<CAltStream> Streams;
|
||||
// CMyComPtr<IFolderFolder> _parentFolder;
|
||||
|
||||
NWindows::NFile::NFind::CFindChangeNotification _findChangeNotification;
|
||||
|
||||
HRESULT GetItemFullSize(unsigned index, UInt64 &size, IProgress *progress);
|
||||
void GetAbsPath(const wchar_t *name, FString &absPath);
|
||||
|
||||
public:
|
||||
// path must be with ':' at tail
|
||||
HRESULT Init(const FString &path /* , IFolderFolder *parentFolder */);
|
||||
|
||||
CAltStreamsFolder() {}
|
||||
|
||||
void GetFullPath(const CAltStream &item, FString &path) const
|
||||
{
|
||||
path = _pathPrefix;
|
||||
path += us2fs(item.Name);
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
Streams.Clear();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -140,8 +140,8 @@ HRESULT CApp::CreateOnePanel(int panelIndex, const UString &mainPath, const UStr
|
||||
}
|
||||
|
||||
static void CreateToolbar(HWND parent,
|
||||
NWindows::NControl::CImageList &imageList,
|
||||
NWindows::NControl::CToolBar &toolBar,
|
||||
NControl::CImageList &imageList,
|
||||
NControl::CToolBar &toolBar,
|
||||
bool largeButtons)
|
||||
{
|
||||
toolBar.Attach(::CreateWindowEx(0, TOOLBARCLASSNAME, NULL, 0
|
||||
@@ -364,7 +364,8 @@ void CApp::Save()
|
||||
if (panel._parentFolders.IsEmpty())
|
||||
path = panel._currentFolderPrefix;
|
||||
else
|
||||
path = GetFolderPath(panel._parentFolders[0].ParentFolder);
|
||||
path = panel._parentFolders[0].ParentFolderPath;
|
||||
// GetFolderPath(panel._parentFolders[0].ParentFolder);
|
||||
SavePanelPath(i, path);
|
||||
listMode.Panels[i] = panel.GetListViewMode();
|
||||
SaveFlatView(i, panel._flatModeForArc);
|
||||
@@ -380,9 +381,12 @@ void CApp::Release()
|
||||
Panels[i].Release();
|
||||
}
|
||||
|
||||
// reduces path to part that exists on disk
|
||||
// reduces path to part that exists on disk (or root prefix of path)
|
||||
// output path is normalized (with WCHAR_PATH_SEPARATOR)
|
||||
static void ReducePathToRealFileSystemPath(UString &path)
|
||||
{
|
||||
unsigned prefixSize = GetRootPrefixSize(path);
|
||||
|
||||
while (!path.IsEmpty())
|
||||
{
|
||||
if (NFind::DoesDirExist(us2fs(path)))
|
||||
@@ -390,63 +394,59 @@ static void ReducePathToRealFileSystemPath(UString &path)
|
||||
NName::NormalizeDirPathPrefix(path);
|
||||
break;
|
||||
}
|
||||
int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR);
|
||||
int pos = path.ReverseFind_PathSepar();
|
||||
if (pos < 0)
|
||||
{
|
||||
path.Empty();
|
||||
break;
|
||||
}
|
||||
path.DeleteFrom(pos + 1);
|
||||
if (path.Len() == 3 && path[1] == L':')
|
||||
if ((unsigned)pos + 1 == prefixSize)
|
||||
break;
|
||||
if (path.Len() > 2 && path[0] == '\\' && path[1] == '\\')
|
||||
{
|
||||
int nextPos = path.Find(WCHAR_PATH_SEPARATOR, 2); // pos after \\COMPNAME
|
||||
if (nextPos > 0 && path.Find(WCHAR_PATH_SEPARATOR, nextPos + 1) == pos)
|
||||
break;
|
||||
}
|
||||
path.DeleteFrom(pos);
|
||||
}
|
||||
}
|
||||
|
||||
// return true for dir\, if dir exist
|
||||
// returns: true, if such dir exists or is root
|
||||
/*
|
||||
static bool CheckFolderPath(const UString &path)
|
||||
{
|
||||
UString pathReduced = path;
|
||||
ReducePathToRealFileSystemPath(pathReduced);
|
||||
return (pathReduced == path);
|
||||
}
|
||||
*/
|
||||
|
||||
extern UString ConvertSizeToString(UInt64 value);
|
||||
|
||||
static UString AddSizeValue(UInt64 size)
|
||||
static void AddSizeValue(UString &s, UInt64 size)
|
||||
{
|
||||
return MyFormatNew(IDS_FILE_SIZE, ConvertSizeToString(size));
|
||||
s += MyFormatNew(IDS_FILE_SIZE, ConvertSizeToString(size));
|
||||
}
|
||||
|
||||
static void AddValuePair1(UString &s, UINT resourceID, UInt64 size)
|
||||
{
|
||||
s += LangString(resourceID);
|
||||
AddLangString(s, resourceID);
|
||||
s += L": ";
|
||||
s += AddSizeValue(size);
|
||||
s += L'\n';
|
||||
AddSizeValue(s, size);
|
||||
s.Add_LF();
|
||||
}
|
||||
|
||||
void AddValuePair2(UString &s, UINT resourceID, UInt64 num, UInt64 size)
|
||||
{
|
||||
if (num == 0)
|
||||
return;
|
||||
s += LangString(resourceID);
|
||||
AddLangString(s, resourceID);
|
||||
s += L": ";
|
||||
s += ConvertSizeToString(num);
|
||||
|
||||
if (size != (UInt64)(Int64)-1)
|
||||
{
|
||||
s += L" ( ";
|
||||
s += AddSizeValue(size);
|
||||
AddSizeValue(s, size);
|
||||
s += L" )";
|
||||
}
|
||||
s += L'\n';
|
||||
s.Add_LF();
|
||||
}
|
||||
|
||||
static void AddPropValueToSum(IFolderFolder *folder, int index, PROPID propID, UInt64 &sum)
|
||||
@@ -490,7 +490,7 @@ UString CPanel::GetItemsInfoString(const CRecordVector<UInt32> &indices)
|
||||
if (numDefined == 2)
|
||||
AddValuePair1(info, IDS_PROP_SIZE, filesSize + foldersSize);
|
||||
|
||||
info += L"\n";
|
||||
info.Add_LF();
|
||||
info += _currentFolderPrefix;
|
||||
|
||||
for (i = 0; i < indices.Size() && (int)i < (int)kCopyDialog_NumInfoLines - 6; i++)
|
||||
@@ -499,7 +499,7 @@ UString CPanel::GetItemsInfoString(const CRecordVector<UInt32> &indices)
|
||||
int index = indices[i];
|
||||
info += GetItemRelPath(index);
|
||||
if (IsItem_Folder(index))
|
||||
info += WCHAR_PATH_SEPARATOR;
|
||||
info.Add_PathSepar();
|
||||
}
|
||||
if (i != indices.Size())
|
||||
info += L"\n ...";
|
||||
@@ -508,6 +508,20 @@ UString CPanel::GetItemsInfoString(const CRecordVector<UInt32> &indices)
|
||||
|
||||
bool IsCorrectFsName(const UString &name);
|
||||
|
||||
|
||||
|
||||
/* Returns true, if path is path that can be used as path for File System functions
|
||||
*/
|
||||
|
||||
/*
|
||||
static bool IsFsPath(const FString &path)
|
||||
{
|
||||
if (!IsAbsolutePath(path))
|
||||
return false;
|
||||
unsigned prefixSize = GetRootPrefixSize(path);
|
||||
}
|
||||
*/
|
||||
|
||||
void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
|
||||
{
|
||||
int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
|
||||
@@ -517,7 +531,12 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
|
||||
CPanel::CDisableTimerProcessing disableTimerProcessing1(destPanel);
|
||||
CPanel::CDisableTimerProcessing disableTimerProcessing2(srcPanel);
|
||||
|
||||
if (!srcPanel.DoesItSupportOperations())
|
||||
if (move)
|
||||
{
|
||||
if (!srcPanel.CheckBeforeUpdate(IDS_MOVE))
|
||||
return;
|
||||
}
|
||||
else if (!srcPanel.DoesItSupportOperations())
|
||||
{
|
||||
srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
|
||||
return;
|
||||
@@ -544,13 +563,15 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
|
||||
srcPanel.GetOperatedIndicesSmart(indices);
|
||||
if (indices.Size() == 0)
|
||||
return;
|
||||
destPath = destPanel._currentFolderPrefix;
|
||||
destPath = destPanel.GetFsPath();
|
||||
if (NumPanels == 1)
|
||||
ReducePathToRealFileSystemPath(destPath);
|
||||
}
|
||||
}
|
||||
|
||||
UStringVector copyFolders;
|
||||
ReadCopyHistory(copyFolders);
|
||||
|
||||
{
|
||||
CCopyDialog copyDialog;
|
||||
|
||||
@@ -583,10 +604,10 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
|
||||
if (IsAbsolutePath(destPath))
|
||||
destPath.Empty();
|
||||
else
|
||||
destPath = srcPanel._currentFolderPrefix;
|
||||
destPath = srcPanel.GetFsPath();
|
||||
destPath += correctName;
|
||||
|
||||
#ifndef UNDER_CE
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
if (destPath.Len() > 0 && destPath[0] == '\\')
|
||||
if (destPath.Len() == 1 || destPath[1] != '\\')
|
||||
{
|
||||
@@ -595,59 +616,112 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (indices.Size() > 1 ||
|
||||
(!destPath.IsEmpty() && destPath.Back() == WCHAR_PATH_SEPARATOR) ||
|
||||
NFind::DoesDirExist(us2fs(destPath)) ||
|
||||
srcPanel.IsArcFolder())
|
||||
bool possibleToUseDestPanel = false;
|
||||
|
||||
if (CompareFileNames(destPath, destPanel.GetFsPath()) == 0)
|
||||
{
|
||||
CreateComplexDir(us2fs(destPath));
|
||||
NName::NormalizeDirPathPrefix(destPath);
|
||||
if (!CheckFolderPath(destPath))
|
||||
if (NumPanels == 1 || CompareFileNames(destPath, srcPanel.GetFsPath()) == 0)
|
||||
{
|
||||
if (NumPanels < 2 || destPath != destPanel._currentFolderPrefix || !destPanel.DoesItSupportOperations())
|
||||
{
|
||||
srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
useDestPanel = true;
|
||||
srcPanel.MessageBoxMyError(L"Can not copy files onto itself");
|
||||
return;
|
||||
}
|
||||
|
||||
if (destPanel.DoesItSupportOperations())
|
||||
possibleToUseDestPanel = true;
|
||||
}
|
||||
|
||||
bool destIsFsPath = false;
|
||||
|
||||
if (possibleToUseDestPanel)
|
||||
{
|
||||
if (destPanel.IsFSFolder() || destPanel.IsAltStreamsFolder())
|
||||
destIsFsPath = true;
|
||||
else if (destPanel.IsFSDrivesFolder() || destPanel.IsRootFolder())
|
||||
{
|
||||
srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!IsCorrectFsName(destPath))
|
||||
if (IsAltPathPrefix(us2fs(destPath)))
|
||||
{
|
||||
srcPanel.MessageBoxError(E_INVALIDARG);
|
||||
// we allow alt streams dest only to alt stream folder in second panel
|
||||
srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
int pos = destPath.ReverseFind(WCHAR_PATH_SEPARATOR);
|
||||
if (pos >= 0)
|
||||
{
|
||||
UString prefix = destPath.Left(pos + 1);
|
||||
CreateComplexDir(us2fs(prefix));
|
||||
if (!CheckFolderPath(prefix))
|
||||
/*
|
||||
FString basePath = us2fs(destPath);
|
||||
basePath.DeleteBack();
|
||||
if (!DoesFileOrDirExist(basePath))
|
||||
{
|
||||
srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
|
||||
srcPanel.MessageBoxError2Lines(basePath, ERROR_FILE_NOT_FOUND); // GetLastError()
|
||||
return;
|
||||
}
|
||||
destIsFsPath = true;
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
if (indices.Size() == 1 &&
|
||||
!destPath.IsEmpty() && destPath.Back() != WCHAR_PATH_SEPARATOR)
|
||||
{
|
||||
int pos = destPath.ReverseFind_PathSepar();
|
||||
if (pos < 0)
|
||||
{
|
||||
srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
{
|
||||
/*
|
||||
#ifdef _WIN32
|
||||
UString name = destPath.Ptr(pos + 1);
|
||||
if (name.Find(L':') >= 0)
|
||||
{
|
||||
srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
UString prefix = destPath.Left(pos + 1);
|
||||
if (!CreateComplexDir(us2fs(prefix)))
|
||||
{
|
||||
srcPanel.MessageBoxError2Lines(prefix, GetLastError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
// bool isFolder = srcPanael.IsItem_Folder(indices[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
NName::NormalizeDirPathPrefix(destPath);
|
||||
if (!CreateComplexDir(us2fs(destPath)))
|
||||
{
|
||||
srcPanel.MessageBoxError2Lines(destPath, GetLastError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
destIsFsPath = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!destIsFsPath)
|
||||
useDestPanel = true;
|
||||
|
||||
AddUniqueStringToHeadOfList(copyFolders, destPath);
|
||||
while (copyFolders.Size() > 20)
|
||||
copyFolders.DeleteBack();
|
||||
SaveCopyHistory(copyFolders);
|
||||
}
|
||||
|
||||
/*
|
||||
if (destPath == destPanel._currentFolderPrefix)
|
||||
{
|
||||
if (destPanel.GetFolderTypeID() == L"PhysDrive")
|
||||
useDestPanel = true;
|
||||
}
|
||||
*/
|
||||
bool useSrcPanel = !useDestPanel || !srcPanel.Is_IO_FS_Folder();
|
||||
|
||||
bool useSrcPanel = (!useDestPanel || !srcPanel.IsFsOrDrivesFolder() || destPanel.IsFSFolder());
|
||||
bool useTemp = useSrcPanel && useDestPanel;
|
||||
if (useTemp && NumPanels == 1)
|
||||
{
|
||||
srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
CTempDir tempDirectory;
|
||||
FString tempDirPrefix;
|
||||
if (useTemp)
|
||||
@@ -666,6 +740,7 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
|
||||
CPanel::CDisableNotify disableNotify2(srcPanel);
|
||||
|
||||
HRESULT result = S_OK;
|
||||
|
||||
if (useSrcPanel)
|
||||
{
|
||||
CCopyToOptions options;
|
||||
@@ -685,12 +760,13 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
|
||||
if (useTemp)
|
||||
folderPrefix = fs2us(tempDirPrefix);
|
||||
else
|
||||
folderPrefix = srcPanel._currentFolderPrefix;
|
||||
folderPrefix = srcPanel.GetFsPath();
|
||||
filePaths.ClearAndReserve(indices.Size());
|
||||
FOR_VECTOR (i, indices)
|
||||
filePaths.AddInReserved(srcPanel.GetItemRelPath(indices[i]));
|
||||
filePaths.AddInReserved(srcPanel.GetItemRelPath2(indices[i]));
|
||||
result = destPanel.CopyFrom(move, folderPrefix, filePaths, true, 0);
|
||||
}
|
||||
|
||||
if (result != S_OK)
|
||||
{
|
||||
// disableNotify1.Restore();
|
||||
@@ -705,15 +781,18 @@ void CApp::OnCopy(bool move, bool copyToSame, int srcPanelIndex)
|
||||
}
|
||||
|
||||
RefreshTitleAlways();
|
||||
|
||||
if (copyToSame || move)
|
||||
{
|
||||
srcPanel.RefreshListCtrl(srcSelState);
|
||||
}
|
||||
|
||||
if (!copyToSame)
|
||||
{
|
||||
destPanel.RefreshListCtrl(destSelState);
|
||||
srcPanel.KillSelection();
|
||||
}
|
||||
|
||||
disableNotify1.Restore();
|
||||
disableNotify2.Restore();
|
||||
srcPanel.SetFocusToList();
|
||||
@@ -831,7 +910,7 @@ void CApp::RefreshTitle(int panelIndex, bool always)
|
||||
void AddUniqueStringToHead(UStringVector &list, const UString &s)
|
||||
{
|
||||
for (unsigned i = 0; i < list.Size();)
|
||||
if (s.IsEqualToNoCase(list[i]))
|
||||
if (s.IsEqualTo_NoCase(list[i]))
|
||||
list.Delete(i);
|
||||
else
|
||||
i++;
|
||||
@@ -848,7 +927,7 @@ void CFolderHistory::Normalize()
|
||||
|
||||
void CFolderHistory::AddString(const UString &s)
|
||||
{
|
||||
NWindows::NSynchronization::CCriticalSectionLock lock(_criticalSection);
|
||||
NSynchronization::CCriticalSectionLock lock(_criticalSection);
|
||||
AddUniqueStringToHead(Strings, s);
|
||||
Normalize();
|
||||
}
|
||||
|
||||
@@ -195,6 +195,7 @@ public:
|
||||
void CopyTo() { OnCopy(false, false, GetFocusedPanelIndex()); }
|
||||
void MoveTo() { OnCopy(true, false, GetFocusedPanelIndex()); }
|
||||
void Delete(bool toRecycleBin) { GetFocusedPanel().DeleteItems(toRecycleBin); }
|
||||
HRESULT CalculateCrc2(const UString &methodName);
|
||||
void CalculateCrc(const UString &methodName);
|
||||
void DiffFiles();
|
||||
void Split();
|
||||
@@ -204,6 +205,7 @@ public:
|
||||
|
||||
#ifndef UNDER_CE
|
||||
void Link();
|
||||
void OpenAltStreams() { GetFocusedPanel().OpenAltStreams(); }
|
||||
#endif
|
||||
|
||||
void CreateFolder() { GetFocusedPanel().CreateFolder(); }
|
||||
|
||||
@@ -77,7 +77,7 @@ static void MessageBox_HResError(HWND wnd, HRESULT errorCode, const wchar_t *nam
|
||||
UString s = HResultToMessage(errorCode);
|
||||
if (name)
|
||||
{
|
||||
s += L'\n';
|
||||
s.Add_LF();
|
||||
s += name;
|
||||
}
|
||||
MessageBox_Error_Global(wnd, s);
|
||||
@@ -209,7 +209,7 @@ bool CBrowseDialog::OnInit()
|
||||
FOR_VECTOR (i, Filters)
|
||||
{
|
||||
if (i != 0)
|
||||
s += L' ';
|
||||
s.Add_Space();
|
||||
s += Filters[i];
|
||||
}
|
||||
}
|
||||
@@ -256,14 +256,16 @@ bool CBrowseDialog::OnInit()
|
||||
_topDirPrefix.Empty();
|
||||
{
|
||||
int rootSize = GetRootPrefixSize(FilePath);
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
// We can go up from root folder to drives list
|
||||
if (NName::IsDrivePath(FilePath))
|
||||
if (IsDrivePath(FilePath))
|
||||
rootSize = 0;
|
||||
else if (IsSuperPath(FilePath))
|
||||
{
|
||||
if (NName::IsDrivePath(&FilePath[kSuperPathPrefixSize]))
|
||||
if (IsDrivePath(FilePath.Ptr(kSuperPathPrefixSize)))
|
||||
rootSize = kSuperPathPrefixSize;
|
||||
}
|
||||
#endif
|
||||
_topDirPrefix.SetFrom(FilePath, rootSize);
|
||||
}
|
||||
|
||||
@@ -466,7 +468,7 @@ bool CBrowseDialog::GetParentPath(const UString &path, UString &parentPrefix, US
|
||||
return false;
|
||||
if (s.Back() == WCHAR_PATH_SEPARATOR)
|
||||
return false;
|
||||
int pos = s.ReverseFind(WCHAR_PATH_SEPARATOR);
|
||||
int pos = s.ReverseFind_PathSepar();
|
||||
parentPrefix.SetFrom(s, pos + 1);
|
||||
name = s.Ptr(pos + 1);
|
||||
return true;
|
||||
@@ -856,7 +858,7 @@ bool MyBrowseForFile(HWND owner, LPCWSTR title, LPCWSTR path,
|
||||
return false;
|
||||
{
|
||||
UString s = errorMessage;
|
||||
s += L"\n";
|
||||
s.Add_LF();
|
||||
s += path;
|
||||
MessageBox_Error_Global(owner, s);
|
||||
}
|
||||
@@ -904,27 +906,32 @@ bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result
|
||||
result.Empty();
|
||||
|
||||
UString path = path2;
|
||||
path.Replace('/', WCHAR_PATH_SEPARATOR);
|
||||
path.Replace(L'/', WCHAR_PATH_SEPARATOR);
|
||||
unsigned start = 0;
|
||||
UString base;
|
||||
if (NName::IsAbsolutePath(path))
|
||||
|
||||
if (IsAbsolutePath(path))
|
||||
{
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
if (IsSuperOrDevicePath(path))
|
||||
{
|
||||
result = path;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
int pos = GetRootPrefixSize(path);
|
||||
if (pos > 0)
|
||||
start = pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
if (IsSuperOrDevicePath(relBase))
|
||||
{
|
||||
result = path;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
base = relBase;
|
||||
}
|
||||
|
||||
@@ -954,6 +961,7 @@ bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result
|
||||
result += path.Left(start);
|
||||
bool checkExist = true;
|
||||
UString cur;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (start == path.Len())
|
||||
@@ -979,7 +987,7 @@ bool CorrectFsPath(const UString &relBase, const UString &path2, UString &result
|
||||
result += cur;
|
||||
if (slashPos < 0)
|
||||
break;
|
||||
result += WCHAR_PATH_SEPARATOR;
|
||||
result.Add_PathSepar();
|
||||
start = slashPos + 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ bool MyBrowseForFolder(HWND owner, LPCWSTR title, LPCWSTR path, UString &resultP
|
||||
bool MyBrowseForFile(HWND owner, LPCWSTR title, LPCWSTR path, LPCWSTR filterDescription, LPCWSTR filter, UString &resultPath);
|
||||
|
||||
/* CorrectFsPath removes undesirable characters in names (dots and spaces at the end of file)
|
||||
But it doesn't change "bad" name in any of the following caes:
|
||||
But it doesn't change "bad" name in any of the following cases:
|
||||
- path is Super Path (with \\?\ prefix)
|
||||
- path is relative and relBase is Super Path
|
||||
- there is file or dir in filesystem with specified "bad" name */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "EditPageRes.h"
|
||||
#include "../../GuiCommon.rc"
|
||||
|
||||
#define xc 200
|
||||
#define xc 240
|
||||
#define yc 80
|
||||
|
||||
IDD_EDIT MY_PAGE
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#endif
|
||||
|
||||
#include "../GUI/ExtractRes.h"
|
||||
#include "resourceGui.h"
|
||||
|
||||
#include "ExtractCallback.h"
|
||||
#include "FormatUtils.h"
|
||||
@@ -30,6 +31,7 @@
|
||||
#ifndef _NO_CRYPTO
|
||||
#include "PasswordDialog.h"
|
||||
#endif
|
||||
#include "PropertyName.h"
|
||||
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
@@ -39,6 +41,10 @@ CExtractCallbackImp::~CExtractCallbackImp() {}
|
||||
|
||||
void CExtractCallbackImp::Init()
|
||||
{
|
||||
_lang_Extracting = LangString(IDS_PROGRESS_EXTRACTING);
|
||||
_lang_Testing = LangString(IDS_PROGRESS_TESTING);
|
||||
_lang_Skipping = LangString(IDS_PROGRESS_SKIPPING);
|
||||
|
||||
NumArchiveErrors = 0;
|
||||
ThereAreMessageErrors = false;
|
||||
#ifndef _SFX
|
||||
@@ -97,6 +103,11 @@ HRESULT CExtractCallbackImp::Open_SetCompleted(const UInt64 * /* numFiles */, co
|
||||
return ProgressDialog->Sync.CheckStop();
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackImp::Open_Finished()
|
||||
{
|
||||
return ProgressDialog->Sync.CheckStop();
|
||||
}
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
|
||||
HRESULT CExtractCallbackImp::Open_CryptoGetTextPassword(BSTR *password)
|
||||
@@ -104,6 +115,7 @@ HRESULT CExtractCallbackImp::Open_CryptoGetTextPassword(BSTR *password)
|
||||
return CryptoGetTextPassword(password);
|
||||
}
|
||||
|
||||
/*
|
||||
HRESULT CExtractCallbackImp::Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password)
|
||||
{
|
||||
passwordIsDefined = PasswordIsDefined;
|
||||
@@ -116,10 +128,11 @@ bool CExtractCallbackImp::Open_WasPasswordAsked()
|
||||
return PasswordWasAsked;
|
||||
}
|
||||
|
||||
void CExtractCallbackImp::Open_ClearPasswordWasAskedFlag()
|
||||
void CExtractCallbackImp::Open_Clear_PasswordWasAsked_Flag()
|
||||
{
|
||||
PasswordWasAsked = false;
|
||||
}
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
@@ -179,10 +192,21 @@ STDMETHODIMP CExtractCallbackImp::AskOverwrite(
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, bool isFolder, Int32 /* askExtractMode */, const UInt64 * /* position */)
|
||||
STDMETHODIMP CExtractCallbackImp::PrepareOperation(const wchar_t *name, Int32 isFolder, Int32 askExtractMode, const UInt64 * /* position */)
|
||||
{
|
||||
_isFolder = isFolder;
|
||||
return SetCurrentFilePath2(name);
|
||||
_isFolder = IntToBool(isFolder);
|
||||
_currentFilePath = name;
|
||||
|
||||
const UString *msg = &_lang_Empty;
|
||||
switch (askExtractMode)
|
||||
{
|
||||
case NArchive::NExtract::NAskMode::kExtract: msg = &_lang_Extracting; break;
|
||||
case NArchive::NExtract::NAskMode::kTest: msg = &_lang_Testing; break;
|
||||
case NArchive::NExtract::NAskMode::kSkip: msg = &_lang_Skipping; break;
|
||||
// default: s = "Unknown operation";
|
||||
}
|
||||
|
||||
return ProgressDialog->Sync.Set_Status2(*msg, name, IntToBool(isFolder));
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::MessageError(const wchar_t *s)
|
||||
@@ -208,7 +232,98 @@ STDMETHODIMP CExtractCallbackImp::ShowMessage(const wchar_t *s)
|
||||
|
||||
#endif
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 opRes, bool encrypted)
|
||||
void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s)
|
||||
{
|
||||
s.Empty();
|
||||
|
||||
if (opRes == NArchive::NExtract::NOperationResult::kOK)
|
||||
return;
|
||||
|
||||
UINT messageID = 0;
|
||||
UINT id = 0;
|
||||
|
||||
switch (opRes)
|
||||
{
|
||||
case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
|
||||
messageID = IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD;
|
||||
id = IDS_EXTRACT_MSG_UNSUPPORTED_METHOD;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kDataError:
|
||||
messageID = encrypted ?
|
||||
IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED:
|
||||
IDS_EXTRACT_MESSAGE_DATA_ERROR;
|
||||
id = IDS_EXTRACT_MSG_DATA_ERROR;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kCRCError:
|
||||
messageID = encrypted ?
|
||||
IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED:
|
||||
IDS_EXTRACT_MESSAGE_CRC_ERROR;
|
||||
id = IDS_EXTRACT_MSG_CRC_ERROR;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kUnavailable:
|
||||
id = IDS_EXTRACT_MSG_UNAVAILABLE_DATA;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kUnexpectedEnd:
|
||||
id = IDS_EXTRACT_MSG_UEXPECTED_END;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kDataAfterEnd:
|
||||
id = IDS_EXTRACT_MSG_DATA_AFTER_END;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kIsNotArc:
|
||||
id = IDS_EXTRACT_MSG_IS_NOT_ARC;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kHeadersError:
|
||||
id = IDS_EXTRACT_MSG_HEADERS_ERROR;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kWrongPassword:
|
||||
id = IDS_EXTRACT_MSG_WRONG_PSW_CLAIM;
|
||||
break;
|
||||
/*
|
||||
default:
|
||||
messageID = IDS_EXTRACT_MESSAGE_UNKNOWN_ERROR;
|
||||
break;
|
||||
*/
|
||||
}
|
||||
|
||||
UString msg;
|
||||
UString msgOld;
|
||||
|
||||
#ifndef _SFX
|
||||
if (id != 0)
|
||||
LangString_OnlyFromLangFile(id, msg);
|
||||
if (messageID != 0 && msg.IsEmpty())
|
||||
LangString_OnlyFromLangFile(messageID, msgOld);
|
||||
#endif
|
||||
|
||||
if (msg.IsEmpty() && !msgOld.IsEmpty())
|
||||
s = MyFormatNew(msgOld, fileName);
|
||||
else
|
||||
{
|
||||
if (msg.IsEmpty() && id != 0)
|
||||
LangString(id, msg);
|
||||
if (!msg.IsEmpty())
|
||||
s += msg;
|
||||
else
|
||||
{
|
||||
char temp[16];
|
||||
ConvertUInt32ToString(opRes, temp);
|
||||
s.AddAscii("Error #");
|
||||
s.AddAscii(temp);
|
||||
}
|
||||
|
||||
if (encrypted && opRes != NArchive::NExtract::NOperationResult::kWrongPassword)
|
||||
{
|
||||
// s.AddAscii(" : ");
|
||||
// AddLangString(s, IDS_EXTRACT_MSG_ENCRYPTED);
|
||||
s.AddAscii(" : ");
|
||||
AddLangString(s, IDS_EXTRACT_MSG_WRONG_PSW_GUESS);
|
||||
}
|
||||
s.AddAscii(" : ");
|
||||
s += fileName;
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 opRes, Int32 encrypted)
|
||||
{
|
||||
switch (opRes)
|
||||
{
|
||||
@@ -216,93 +331,9 @@ STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 opRes, bool encrypted
|
||||
break;
|
||||
default:
|
||||
{
|
||||
UINT messageID = 0;
|
||||
UINT id = 0;
|
||||
|
||||
switch (opRes)
|
||||
{
|
||||
case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
|
||||
messageID = IDS_EXTRACT_MESSAGE_UNSUPPORTED_METHOD;
|
||||
id = IDS_EXTRACT_MSG_UNSUPPORTED_METHOD;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kDataError:
|
||||
messageID = encrypted ?
|
||||
IDS_EXTRACT_MESSAGE_DATA_ERROR_ENCRYPTED:
|
||||
IDS_EXTRACT_MESSAGE_DATA_ERROR;
|
||||
id = IDS_EXTRACT_MSG_DATA_ERROR;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kCRCError:
|
||||
messageID = encrypted ?
|
||||
IDS_EXTRACT_MESSAGE_CRC_ERROR_ENCRYPTED:
|
||||
IDS_EXTRACT_MESSAGE_CRC_ERROR;
|
||||
id = IDS_EXTRACT_MSG_CRC_ERROR;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kUnavailable:
|
||||
id = IDS_EXTRACT_MSG_UNAVAILABLE_DATA;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kUnexpectedEnd:
|
||||
id = IDS_EXTRACT_MSG_UEXPECTED_END;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kDataAfterEnd:
|
||||
id = IDS_EXTRACT_MSG_DATA_AFTER_END;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kIsNotArc:
|
||||
id = IDS_EXTRACT_MSG_IS_NOT_ARC;
|
||||
break;
|
||||
case NArchive::NExtract::NOperationResult::kHeadersError:
|
||||
id = IDS_EXTRACT_MSG_HEADERS_ERROR;
|
||||
break;
|
||||
/*
|
||||
default:
|
||||
messageID = IDS_EXTRACT_MESSAGE_UNKNOWN_ERROR;
|
||||
break;
|
||||
*/
|
||||
}
|
||||
if (_needWriteArchivePath)
|
||||
{
|
||||
if (!_currentArchivePath.IsEmpty())
|
||||
AddError_Message(_currentArchivePath);
|
||||
_needWriteArchivePath = false;
|
||||
}
|
||||
|
||||
UString msg;
|
||||
UString msgOld;
|
||||
|
||||
#ifndef _SFX
|
||||
if (id != 0)
|
||||
LangString_OnlyFromLangFile(id, msg);
|
||||
if (messageID != 0 && msg.IsEmpty())
|
||||
LangString_OnlyFromLangFile(messageID, msgOld);
|
||||
#endif
|
||||
|
||||
UString s;
|
||||
if (msg.IsEmpty() && !msgOld.IsEmpty())
|
||||
s = MyFormatNew(msgOld, _currentFilePath);
|
||||
else
|
||||
{
|
||||
if (msg.IsEmpty())
|
||||
LangString(id, msg);
|
||||
if (!msg.IsEmpty())
|
||||
s += msg;
|
||||
else
|
||||
{
|
||||
wchar_t temp[16];
|
||||
ConvertUInt32ToString(opRes, temp);
|
||||
s += L"Error #";
|
||||
s += temp;
|
||||
}
|
||||
|
||||
if (encrypted)
|
||||
{
|
||||
// s += L" : ";
|
||||
// s += LangString(IDS_EXTRACT_MSG_ENCRYPTED);
|
||||
s += L" : ";
|
||||
s += LangString(IDS_EXTRACT_MSG_WRONG_PSW);
|
||||
}
|
||||
s += L" : ";
|
||||
s += _currentFilePath;
|
||||
}
|
||||
|
||||
SetExtractErrorMessage(opRes, encrypted, _currentFilePath, s);
|
||||
Add_ArchiveName_Error();
|
||||
AddError_Message(s);
|
||||
}
|
||||
}
|
||||
@@ -318,10 +349,22 @@ STDMETHODIMP CExtractCallbackImp::SetOperationResult(Int32 opRes, bool encrypted
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::ReportExtractResult(Int32 opRes, Int32 encrypted, const wchar_t *name)
|
||||
{
|
||||
if (opRes != NArchive::NExtract::NOperationResult::kOK)
|
||||
{
|
||||
UString s;
|
||||
SetExtractErrorMessage(opRes, encrypted, name, s);
|
||||
Add_ArchiveName_Error();
|
||||
AddError_Message(s);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
// IExtractCallbackUI
|
||||
|
||||
HRESULT CExtractCallbackImp::BeforeOpen(const wchar_t *name)
|
||||
HRESULT CExtractCallbackImp::BeforeOpen(const wchar_t *name, bool /* testMode */)
|
||||
{
|
||||
#ifndef _SFX
|
||||
RINOK(ProgressDialog->Sync.CheckStop());
|
||||
@@ -357,27 +400,6 @@ HRESULT CExtractCallbackImp::SetCurrentFilePath(const wchar_t *path)
|
||||
|
||||
UString HResultToMessage(HRESULT errorCode);
|
||||
|
||||
HRESULT CExtractCallbackImp::OpenResult(const wchar_t *name, HRESULT result, bool encrypted)
|
||||
{
|
||||
if (result != S_OK)
|
||||
{
|
||||
UString s;
|
||||
if (result == S_FALSE)
|
||||
s = MyFormatNew(encrypted ? IDS_CANT_OPEN_ENCRYPTED_ARCHIVE : IDS_CANT_OPEN_ARCHIVE, name);
|
||||
else
|
||||
{
|
||||
s = name;
|
||||
s += L": ";
|
||||
s += HResultToMessage(result);
|
||||
}
|
||||
MessageError(s);
|
||||
NumArchiveErrors++;
|
||||
}
|
||||
_currentArchivePath = name;
|
||||
_needWriteArchivePath = true;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const UInt32 k_ErrorFlagsIds[] =
|
||||
{
|
||||
IDS_EXTRACT_MSG_IS_NOT_ARC,
|
||||
@@ -393,9 +415,16 @@ static const UInt32 k_ErrorFlagsIds[] =
|
||||
IDS_EXTRACT_MSG_CRC_ERROR
|
||||
};
|
||||
|
||||
static void AddNewLineString(UString &s, const UString &m)
|
||||
{
|
||||
s += m;
|
||||
s.Add_LF();
|
||||
}
|
||||
|
||||
UString GetOpenArcErrorMessage(UInt32 errorFlags)
|
||||
{
|
||||
UString s;
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(k_ErrorFlagsIds); i++)
|
||||
{
|
||||
UInt32 f = ((UInt32)1 << i);
|
||||
@@ -407,14 +436,15 @@ UString GetOpenArcErrorMessage(UInt32 errorFlags)
|
||||
continue;
|
||||
if (f == kpv_ErrorFlags_EncryptedHeadersError)
|
||||
{
|
||||
m += L" : ";
|
||||
m += LangString(IDS_EXTRACT_MSG_WRONG_PSW);
|
||||
m.AddAscii(" : ");
|
||||
AddLangString(m, IDS_EXTRACT_MSG_WRONG_PSW_GUESS);
|
||||
}
|
||||
if (!s.IsEmpty())
|
||||
s += L'\n';
|
||||
s.Add_LF();
|
||||
s += m;
|
||||
errorFlags &= ~f;
|
||||
}
|
||||
|
||||
if (errorFlags != 0)
|
||||
{
|
||||
char sz[16];
|
||||
@@ -422,74 +452,151 @@ UString GetOpenArcErrorMessage(UInt32 errorFlags)
|
||||
sz[1] = 'x';
|
||||
ConvertUInt32ToHex(errorFlags, sz + 2);
|
||||
if (!s.IsEmpty())
|
||||
s += L'\n';
|
||||
s += GetUnicodeString(AString(sz));
|
||||
s.Add_LF();
|
||||
s.AddAscii(sz);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackImp::SetError(int level, const wchar_t *name,
|
||||
UInt32 errorFlags, const wchar_t *errors,
|
||||
UInt32 warningFlags, const wchar_t *warnings)
|
||||
static void ErrorInfo_Print(UString &s, const CArcErrorInfo &er)
|
||||
{
|
||||
NumArchiveErrors++;
|
||||
UInt32 errorFlags = er.GetErrorFlags();
|
||||
UInt32 warningFlags = er.GetWarningFlags();
|
||||
|
||||
if (errorFlags != 0)
|
||||
AddNewLineString(s, GetOpenArcErrorMessage(errorFlags));
|
||||
|
||||
if (!er.ErrorMessage.IsEmpty())
|
||||
AddNewLineString(s, er.ErrorMessage);
|
||||
|
||||
if (warningFlags != 0)
|
||||
{
|
||||
s += GetNameOfProperty(kpidWarningFlags, L"Warnings");
|
||||
s.AddAscii(":");
|
||||
s.Add_LF();
|
||||
AddNewLineString(s, GetOpenArcErrorMessage(warningFlags));
|
||||
}
|
||||
|
||||
if (!er.WarningMessage.IsEmpty())
|
||||
{
|
||||
s += GetNameOfProperty(kpidWarning, L"Warning");
|
||||
s.AddAscii(": ");
|
||||
s += er.WarningMessage;
|
||||
s.Add_LF();
|
||||
}
|
||||
}
|
||||
|
||||
static UString GetBracedType(const wchar_t *type)
|
||||
{
|
||||
UString s = L'[';
|
||||
s += type;
|
||||
s += L']';
|
||||
return s;
|
||||
}
|
||||
|
||||
void OpenResult_GUI(UString &s, const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result)
|
||||
{
|
||||
FOR_VECTOR (level, arcLink.Arcs)
|
||||
{
|
||||
const CArc &arc = arcLink.Arcs[level];
|
||||
const CArcErrorInfo &er = arc.ErrorInfo;
|
||||
|
||||
if (!er.IsThereErrorOrWarning() && er.ErrorFormatIndex < 0)
|
||||
continue;
|
||||
|
||||
if (s.IsEmpty())
|
||||
{
|
||||
s += name;
|
||||
s.Add_LF();
|
||||
}
|
||||
|
||||
if (level != 0)
|
||||
{
|
||||
AddNewLineString(s, arc.Path);
|
||||
}
|
||||
|
||||
ErrorInfo_Print(s, er);
|
||||
|
||||
if (er.ErrorFormatIndex >= 0)
|
||||
{
|
||||
AddNewLineString(s, GetNameOfProperty(kpidWarning, L"Warning"));
|
||||
if (arc.FormatIndex == er.ErrorFormatIndex)
|
||||
{
|
||||
AddNewLineString(s, LangString(IDS_IS_OPEN_WITH_OFFSET));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddNewLineString(s, MyFormatNew(IDS_CANT_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(er.ErrorFormatIndex))));
|
||||
AddNewLineString(s, MyFormatNew(IDS_IS_OPEN_AS_TYPE, GetBracedType(codecs->GetFormatNamePtr(arc.FormatIndex))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result != S_OK)
|
||||
{
|
||||
s += name;
|
||||
s.Add_LF();
|
||||
if (!arcLink.Arcs.IsEmpty())
|
||||
AddNewLineString(s, arcLink.NonOpen_ArcPath);
|
||||
|
||||
if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0 || result == S_FALSE)
|
||||
{
|
||||
UINT id = IDS_CANT_OPEN_ARCHIVE;
|
||||
UString param;
|
||||
if (arcLink.PasswordWasAsked)
|
||||
id = IDS_CANT_OPEN_ENCRYPTED_ARCHIVE;
|
||||
else if (arcLink.NonOpen_ErrorInfo.ErrorFormatIndex >= 0)
|
||||
{
|
||||
id = IDS_CANT_OPEN_AS_TYPE;
|
||||
param = GetBracedType(codecs->GetFormatNamePtr(arcLink.NonOpen_ErrorInfo.ErrorFormatIndex));
|
||||
}
|
||||
UString s2 = MyFormatNew(id, param);
|
||||
s2.Replace(L" ''", L"");
|
||||
s2.Replace(L"''", L"");
|
||||
s += s2;
|
||||
}
|
||||
else
|
||||
s += HResultToMessage(result);
|
||||
|
||||
s.Add_LF();
|
||||
ErrorInfo_Print(s, arcLink.NonOpen_ErrorInfo);
|
||||
}
|
||||
|
||||
if (!s.IsEmpty() && s.Back() == '\n')
|
||||
s.DeleteBack();
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackImp::OpenResult(const CCodecs *codecs, const CArchiveLink &arcLink, const wchar_t *name, HRESULT result)
|
||||
{
|
||||
_currentArchivePath = name;
|
||||
_needWriteArchivePath = true;
|
||||
|
||||
UString s;
|
||||
OpenResult_GUI(s, codecs, arcLink, name, result);
|
||||
if (!s.IsEmpty())
|
||||
{
|
||||
NumArchiveErrors++;
|
||||
AddError_Message(s);
|
||||
_needWriteArchivePath = false;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackImp::ThereAreNoFiles()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CExtractCallbackImp::Add_ArchiveName_Error()
|
||||
{
|
||||
if (_needWriteArchivePath)
|
||||
{
|
||||
if (!_currentArchivePath.IsEmpty())
|
||||
AddError_Message(_currentArchivePath);
|
||||
_needWriteArchivePath = false;
|
||||
}
|
||||
|
||||
if (level != 0)
|
||||
{
|
||||
UString s;
|
||||
s += name;
|
||||
s += L": ";
|
||||
MessageError(s);
|
||||
}
|
||||
|
||||
if (errorFlags != 0)
|
||||
MessageError(GetOpenArcErrorMessage(errorFlags));
|
||||
|
||||
if (errors && wcslen(errors) != 0)
|
||||
MessageError(errors);
|
||||
|
||||
if (warningFlags != 0)
|
||||
MessageError((UString)L"Warnings: " + GetOpenArcErrorMessage(warningFlags));
|
||||
|
||||
if (warnings && wcslen(warnings) != 0)
|
||||
MessageError((UString)L"Warnings: " + warnings);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackImp::OpenTypeWarning(const wchar_t *name, const wchar_t *okType, const wchar_t *errorType)
|
||||
{
|
||||
UString s = L"Warning:\n";
|
||||
s += name;
|
||||
s += L"\n";
|
||||
if (wcscmp(okType, errorType) == 0)
|
||||
{
|
||||
s += L"The archive is open with offset";
|
||||
}
|
||||
else
|
||||
{
|
||||
s += L"Can not open the file as [";
|
||||
s += errorType;
|
||||
s += L"] archive\n";
|
||||
s += L"The file is open as [";
|
||||
s += okType;
|
||||
s += L"] archive";
|
||||
}
|
||||
MessageError(s);
|
||||
NumArchiveErrors++;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackImp::ThereAreNoFiles()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CExtractCallbackImp::ExtractResult(HRESULT result)
|
||||
@@ -499,7 +606,10 @@ HRESULT CExtractCallbackImp::ExtractResult(HRESULT result)
|
||||
NumArchiveErrors++;
|
||||
if (result == E_ABORT || result == ERROR_DISK_FULL)
|
||||
return result;
|
||||
MessageError(_currentFilePath);
|
||||
|
||||
Add_ArchiveName_Error();
|
||||
if (!_currentFilePath.IsEmpty())
|
||||
MessageError(_currentFilePath);
|
||||
MessageError(NError::MyFormatMessage(result));
|
||||
return S_OK;
|
||||
}
|
||||
@@ -564,7 +674,7 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
|
||||
{
|
||||
if (!destFileInfo.IsDir())
|
||||
{
|
||||
RINOK(MessageError("can not replace file with folder with same name: ", destPathSys));
|
||||
RINOK(MessageError("can not replace file with folder with same name", destPathSys));
|
||||
return E_ABORT;
|
||||
}
|
||||
*writeAnswer = BoolToInt(false);
|
||||
@@ -573,8 +683,9 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
|
||||
|
||||
if (destFileInfo.IsDir())
|
||||
{
|
||||
RINOK(MessageError("can not replace folder with file with same name: ", destPathSys));
|
||||
return E_FAIL;
|
||||
RINOK(MessageError("can not replace folder with file with same name", destPathSys));
|
||||
*writeAnswer = BoolToInt(false);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
switch (OverwriteMode)
|
||||
@@ -583,13 +694,9 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
|
||||
return S_OK;
|
||||
case NExtract::NOverwriteMode::kAsk:
|
||||
{
|
||||
Int32 overwiteResult;
|
||||
Int32 overwriteResult;
|
||||
UString destPathSpec = destPath;
|
||||
int slashPos = destPathSpec.ReverseFind(L'/');
|
||||
#ifdef _WIN32
|
||||
int slash1Pos = destPathSpec.ReverseFind(L'\\');
|
||||
slashPos = MyMax(slashPos, slash1Pos);
|
||||
#endif
|
||||
int slashPos = destPathSpec.ReverseFind_PathSepar();
|
||||
destPathSpec.DeleteFrom(slashPos + 1);
|
||||
destPathSpec += fs2us(destFileInfo.Name);
|
||||
|
||||
@@ -598,9 +705,9 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
|
||||
&destFileInfo.MTime, &destFileInfo.Size,
|
||||
srcPath,
|
||||
srcTime, srcSize,
|
||||
&overwiteResult));
|
||||
&overwriteResult));
|
||||
|
||||
switch (overwiteResult)
|
||||
switch (overwriteResult)
|
||||
{
|
||||
case NOverwriteAnswer::kCancel: return E_ABORT;
|
||||
case NOverwriteAnswer::kNo: return S_OK;
|
||||
@@ -618,7 +725,7 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
|
||||
{
|
||||
if (!AutoRenamePath(destPathSys))
|
||||
{
|
||||
RINOK(MessageError("can not create name for file: ", destPathSys));
|
||||
RINOK(MessageError("can not create name for file", destPathSys));
|
||||
return E_ABORT;
|
||||
}
|
||||
destPathResultTemp = fs2us(destPathSys);
|
||||
@@ -626,7 +733,7 @@ STDMETHODIMP CExtractCallbackImp::AskWrite(
|
||||
else
|
||||
if (!NDir::DeleteFileAlways(destPathSys))
|
||||
{
|
||||
RINOK(MessageError("can not delete output file: ", destPathSys));
|
||||
RINOK(MessageError("can not delete output file", destPathSys));
|
||||
return E_ABORT;
|
||||
}
|
||||
}
|
||||
@@ -783,7 +890,7 @@ STDMETHODIMP CExtractCallbackImp::PrepareOperation7(Int32 askExtractMode)
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
STDMETHODIMP CExtractCallbackImp::SetOperationResult7(Int32 opRes, bool encrypted)
|
||||
STDMETHODIMP CExtractCallbackImp::SetOperationResult7(Int32 opRes, Int32 encrypted)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
if (VirtFileSystem && _newVirtFileWasAdded)
|
||||
@@ -865,7 +972,7 @@ HRESULT CVirtFileSystem::FlushToDisk(bool closeLast)
|
||||
while (_numFlushed < Files.Size())
|
||||
{
|
||||
const CVirtFile &file = Files[_numFlushed];
|
||||
const FString path = DirPrefix + us2fs(GetCorrectFsPath(file.Name));
|
||||
const FString path = DirPrefix + us2fs(Get_Correct_FsFile_Name(file.Name));
|
||||
if (!_fileIsOpen)
|
||||
{
|
||||
if (!_outFileStreamSpec->Create(path, false))
|
||||
|
||||
@@ -36,8 +36,7 @@ class CGrowBuf
|
||||
Byte *_items;
|
||||
size_t _size;
|
||||
|
||||
CGrowBuf(const CGrowBuf &buffer);
|
||||
void operator=(const CGrowBuf &buffer);
|
||||
CLASS_NO_COPY(CGrowBuf);
|
||||
|
||||
public:
|
||||
bool ReAlloc_KeepData(size_t newSize, size_t keepSize)
|
||||
@@ -45,7 +44,8 @@ public:
|
||||
void *buf = MyAlloc(newSize);
|
||||
if (!buf)
|
||||
return false;
|
||||
memcpy(buf, _items, keepSize);
|
||||
if (keepSize != 0)
|
||||
memcpy(buf, _items, keepSize);
|
||||
MyFree(_items);
|
||||
_items = (Byte *)buf;
|
||||
_size = newSize;
|
||||
@@ -55,8 +55,8 @@ public:
|
||||
CGrowBuf(): _items(0), _size(0) {}
|
||||
~CGrowBuf() { MyFree(_items); }
|
||||
|
||||
operator Byte *() { return _items; };
|
||||
operator const Byte *() const { return _items; };
|
||||
operator Byte *() { return _items; }
|
||||
operator const Byte *() const { return _items; }
|
||||
size_t Size() const { return _size; }
|
||||
};
|
||||
|
||||
@@ -135,10 +135,11 @@ public:
|
||||
{
|
||||
if (_fileMode)
|
||||
return false;
|
||||
if (Files.Size() < 1 || Files[0].IsAltStream || Files[0].IsDir)
|
||||
if (Files.Size() < 1 || /* Files[0].IsAltStream || */ Files[0].IsDir)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t GetMemStreamWrittenSize() const { return _pos; }
|
||||
|
||||
CVirtFileSystem(): _outFileStreamSpec(NULL), MaxTotalAllocSize((UInt64)0 - 1) {}
|
||||
@@ -165,6 +166,7 @@ public:
|
||||
class CExtractCallbackImp:
|
||||
public IExtractCallbackUI, // it includes IFolderArchiveExtractCallback
|
||||
public IOpenCallbackUI,
|
||||
public IFolderArchiveExtractCallback2,
|
||||
#ifndef _SFX
|
||||
public IFolderOperationsExtractCallback,
|
||||
public IFolderExtractToStreamCallback,
|
||||
@@ -176,8 +178,10 @@ class CExtractCallbackImp:
|
||||
public CMyUnknownImp
|
||||
{
|
||||
HRESULT MessageError(const char *message, const FString &path);
|
||||
void Add_ArchiveName_Error();
|
||||
public:
|
||||
MY_QUERYINTERFACE_BEGIN2(IFolderArchiveExtractCallback)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderArchiveExtractCallback2)
|
||||
#ifndef _SFX
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderOperationsExtractCallback)
|
||||
MY_QUERYINTERFACE_ENTRY(IFolderExtractToStreamCallback)
|
||||
@@ -191,33 +195,12 @@ public:
|
||||
|
||||
INTERFACE_IProgress(;)
|
||||
INTERFACE_IOpenCallbackUI(;)
|
||||
|
||||
// IFolderArchiveExtractCallback
|
||||
INTERFACE_IFolderArchiveExtractCallback(;)
|
||||
INTERFACE_IFolderArchiveExtractCallback2(;)
|
||||
// STDMETHOD(SetTotalFiles)(UInt64 total);
|
||||
// STDMETHOD(SetCompletedFiles)(const UInt64 *value);
|
||||
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, bool isFolder, Int32 askExtractMode, const UInt64 *position);
|
||||
|
||||
STDMETHOD(MessageError)(const wchar_t *message);
|
||||
STDMETHOD(SetOperationResult)(Int32 operationResult, bool encrypted);
|
||||
|
||||
// IExtractCallbackUI
|
||||
|
||||
HRESULT BeforeOpen(const wchar_t *name);
|
||||
HRESULT OpenResult(const wchar_t *name, HRESULT result, bool encrypted);
|
||||
HRESULT SetError(int level, const wchar_t *name,
|
||||
UInt32 errorFlags, const wchar_t *errors,
|
||||
UInt32 warningFlags, const wchar_t *warnings);
|
||||
HRESULT ThereAreNoFiles();
|
||||
HRESULT ExtractResult(HRESULT result);
|
||||
HRESULT OpenTypeWarning(const wchar_t *name, const wchar_t *okType, const wchar_t *errorType);
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
HRESULT SetPassword(const UString &password);
|
||||
#endif
|
||||
INTERFACE_IExtractCallbackUI(;)
|
||||
|
||||
#ifndef _SFX
|
||||
// IFolderOperationsExtractCallback
|
||||
@@ -295,6 +278,12 @@ public:
|
||||
UString Password;
|
||||
#endif
|
||||
|
||||
|
||||
UString _lang_Extracting;
|
||||
UString _lang_Testing;
|
||||
UString _lang_Skipping;
|
||||
UString _lang_Empty;
|
||||
|
||||
CExtractCallbackImp():
|
||||
#ifndef _NO_CRYPTO
|
||||
PasswordIsDefined(false),
|
||||
|
||||
@@ -49,6 +49,9 @@ static UString g_MainPath;
|
||||
static UString g_ArcFormat;
|
||||
static bool g_Maximized = false;
|
||||
|
||||
// HRESULT LoadGlobalCodecs();
|
||||
void FreeGlobalCodecs();
|
||||
|
||||
#ifndef UNDER_CE
|
||||
|
||||
DWORD g_ComCtl32Version;
|
||||
@@ -568,6 +571,13 @@ static int WINAPI WinMain2(int nCmdShow)
|
||||
if (!InitInstance (nCmdShow))
|
||||
return FALSE;
|
||||
|
||||
// we will load Global_Codecs at first use instead.
|
||||
/*
|
||||
OutputDebugStringW(L"Before LoadGlobalCodecs");
|
||||
LoadGlobalCodecs();
|
||||
OutputDebugStringW(L"After LoadGlobalCodecs");
|
||||
*/
|
||||
|
||||
#ifndef _UNICODE
|
||||
if (g_IsNT)
|
||||
{
|
||||
@@ -597,6 +607,10 @@ static int WINAPI WinMain2(int nCmdShow)
|
||||
}
|
||||
}
|
||||
|
||||
// Destructor of g_CodecsReleaser can release DLLs.
|
||||
// But we suppose that it's better to release DLLs here (before destructor).
|
||||
FreeGlobalCodecs();
|
||||
|
||||
g_HWND = 0;
|
||||
#ifndef UNDER_CE
|
||||
OleUninitialize();
|
||||
@@ -780,35 +794,45 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
xSizes[1] = 0;
|
||||
|
||||
g_App.CreateDragTarget();
|
||||
|
||||
bool archiveIsOpened;
|
||||
bool encrypted;
|
||||
bool needOpenFile = false;
|
||||
if (!g_MainPath.IsEmpty() /* && g_OpenArchive */)
|
||||
|
||||
UString fullPath = g_MainPath;
|
||||
if (!fullPath.IsEmpty() /* && g_OpenArchive */)
|
||||
{
|
||||
if (NFile::NFind::DoesFileExist(us2fs(g_MainPath)))
|
||||
if (!NFile::NName::IsAbsolutePath(fullPath))
|
||||
{
|
||||
FString fullPathF;
|
||||
if (NFile::NName::GetFullPath(us2fs(fullPath), fullPathF))
|
||||
fullPath = fs2us(fullPathF);
|
||||
}
|
||||
if (NFile::NFind::DoesFileExist(us2fs(fullPath)))
|
||||
needOpenFile = true;
|
||||
}
|
||||
HRESULT res = g_App.Create(hWnd, g_MainPath, g_ArcFormat, xSizes, archiveIsOpened, encrypted);
|
||||
|
||||
HRESULT res = g_App.Create(hWnd, fullPath, g_ArcFormat, xSizes, archiveIsOpened, encrypted);
|
||||
|
||||
if (res == E_ABORT)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (needOpenFile && !archiveIsOpened || res != S_OK)
|
||||
{
|
||||
UString message = L"Error";
|
||||
if (res == S_FALSE || res == S_OK)
|
||||
{
|
||||
message = MyFormatNew(encrypted ?
|
||||
IDS_CANT_OPEN_ENCRYPTED_ARCHIVE :
|
||||
IDS_CANT_OPEN_ARCHIVE,
|
||||
g_MainPath);
|
||||
IDS_CANT_OPEN_ENCRYPTED_ARCHIVE :
|
||||
IDS_CANT_OPEN_ARCHIVE,
|
||||
fullPath);
|
||||
}
|
||||
else if (res != S_OK)
|
||||
message = HResultToMessage(res);
|
||||
ErrorMessage(message);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// g_SplitterPos = 0;
|
||||
|
||||
// ::DragAcceptFiles(hWnd, TRUE);
|
||||
@@ -816,6 +840,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
// ::DragAcceptFiles(hWnd, FALSE);
|
||||
@@ -839,11 +864,13 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
g_StartCaptureSplitterPos = g_Splitter.GetPos();
|
||||
::SetCapture(hWnd);
|
||||
break;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
{
|
||||
::ReleaseCapture();
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
if ((wParam & MK_LBUTTON) != 0 && ::GetCapture() == hWnd)
|
||||
@@ -880,10 +907,12 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_SETFOCUS:
|
||||
// g_App.SetFocus(g_App.LastFocusedPanel);
|
||||
g_App.SetFocusToLastItem();
|
||||
break;
|
||||
|
||||
/*
|
||||
case WM_ACTIVATE:
|
||||
{
|
||||
@@ -900,6 +929,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
case kLangWasChangedMessage:
|
||||
MyLoadMenu();
|
||||
@@ -910,11 +940,13 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
case WM_SETTINGCHANGE:
|
||||
break;
|
||||
*/
|
||||
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
g_App.OnNotify((int)wParam, (LPNMHDR)lParam);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
case WM_DROPFILES:
|
||||
{
|
||||
|
||||
@@ -219,6 +219,14 @@ SOURCE=.\Test.bmp
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AltStreamsFolder.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\AltStreamsFolder.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\FSDrives.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -1026,6 +1034,10 @@ SOURCE=..\..\..\Windows\Window.h
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\Common.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\Common\ComTry.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -1399,6 +1411,14 @@ SOURCE=..\GUI\HashGUI.cpp
|
||||
|
||||
SOURCE=..\GUI\HashGUI.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\GUI\UpdateCallbackGUI2.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\GUI\UpdateCallbackGUI2.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# Begin Group "Compress"
|
||||
|
||||
@@ -60,6 +60,7 @@ FM_OBJS = \
|
||||
!IFNDEF UNDER_CE
|
||||
|
||||
FM_OBJS = $(FM_OBJS) \
|
||||
$O\AltStreamsFolder.obj \
|
||||
$O\FSDrives.obj \
|
||||
$O\LinkDialog.obj \
|
||||
$O\NetFolder.obj \
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileIO.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
#include "../../../Windows/FileSystem.h"
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
|
||||
@@ -27,8 +28,8 @@ using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NFind;
|
||||
|
||||
static CFSTR kVolPrefix = FTEXT("\\\\.\\");
|
||||
static CFSTR kLongPrefix = FTEXT("\\\\?\\");
|
||||
static const CFSTR kVolPrefix = FTEXT("\\\\.\\");
|
||||
static const CFSTR kSuperPrefix = FTEXT("\\\\?\\");
|
||||
|
||||
FString CDriveInfo::GetDeviceFileIoName() const
|
||||
{
|
||||
@@ -53,6 +54,7 @@ static HRESULT CopyFileSpec(CFSTR fromPath, CFSTR toPath, bool writeToDisk, UInt
|
||||
if (!inFile.GetLength(fileSize))
|
||||
::GetLastError();
|
||||
}
|
||||
|
||||
NIO::COutFile outFile;
|
||||
if (writeToDisk)
|
||||
{
|
||||
@@ -62,6 +64,7 @@ static HRESULT CopyFileSpec(CFSTR fromPath, CFSTR toPath, bool writeToDisk, UInt
|
||||
else
|
||||
if (!outFile.Create(toPath, true))
|
||||
return GetLastError();
|
||||
|
||||
CPhysTempBuffer tempBuffer;
|
||||
tempBuffer.buffer = MidAlloc(bufferSize);
|
||||
if (!tempBuffer.buffer)
|
||||
@@ -93,12 +96,14 @@ static HRESULT CopyFileSpec(CFSTR fromPath, CFSTR toPath, bool writeToDisk, UInt
|
||||
return E_FAIL;
|
||||
pos += curSize;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const PROPID kProps[] =
|
||||
{
|
||||
kpidName,
|
||||
// kpidOutName,
|
||||
kpidTotalSize,
|
||||
kpidFreeSpace,
|
||||
kpidType,
|
||||
@@ -107,7 +112,7 @@ static const PROPID kProps[] =
|
||||
kpidClusterSize
|
||||
};
|
||||
|
||||
static const char *kDriveTypes[] =
|
||||
static const char * const kDriveTypes[] =
|
||||
{
|
||||
"Unknown"
|
||||
, "No Root Dir"
|
||||
@@ -219,6 +224,16 @@ STDMETHODIMP CFSDrives::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT
|
||||
{
|
||||
case kpidIsDir: prop = !_volumeMode; break;
|
||||
case kpidName: prop = di.Name; break;
|
||||
case kpidOutName:
|
||||
if (!di.Name.IsEmpty() && di.Name.Back() == ':')
|
||||
{
|
||||
FString s = di.Name;
|
||||
s.DeleteBack();
|
||||
AddExt(s, itemIndex);
|
||||
prop = s;
|
||||
}
|
||||
break;
|
||||
|
||||
case kpidTotalSize: if (di.KnownSize) prop = di.DriveSize; break;
|
||||
case kpidFreeSpace: if (di.KnownSizes) prop = di.FreeSpace; break;
|
||||
case kpidClusterSize: if (di.KnownSizes) prop = di.ClusterSize; break;
|
||||
@@ -240,14 +255,11 @@ HRESULT CFSDrives::BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder)
|
||||
return S_OK;
|
||||
NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder;
|
||||
CMyComPtr<IFolderFolder> subFolder = fsFolderSpec;
|
||||
if (_longMode)
|
||||
{
|
||||
RINOK(fsFolderSpec->Init((FString)kLongPrefix + name, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(fsFolderSpec->Init(name, 0));
|
||||
}
|
||||
FString path;
|
||||
if (_superMode)
|
||||
path = kSuperPrefix;
|
||||
path += name;
|
||||
RINOK(fsFolderSpec->Init(path));
|
||||
*resultFolder = subFolder.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
@@ -295,8 +307,8 @@ STDMETHODIMP CFSDrives::GetFolderProperty(PROPID propID, PROPVARIANT *value)
|
||||
case kpidPath:
|
||||
if (_volumeMode)
|
||||
prop = kVolPrefix;
|
||||
else if (_longMode)
|
||||
prop = kLongPrefix;
|
||||
else if (_superMode)
|
||||
prop = kSuperPrefix;
|
||||
else
|
||||
prop = (UString)LangString(IDS_COMPUTER) + WCHAR_PATH_SEPARATOR;
|
||||
break;
|
||||
@@ -322,19 +334,20 @@ STDMETHODIMP CFSDrives::GetSystemIconIndex(UInt32 index, Int32 *iconIndex)
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
const wchar_t *CFSDrives::GetExt(unsigned index) const
|
||||
void CFSDrives::AddExt(FString &s, unsigned index) const
|
||||
{
|
||||
s += FTEXT('.');
|
||||
const CDriveInfo &di = _drives[index];
|
||||
const wchar_t *ext;
|
||||
const char *ext;
|
||||
if (di.DriveType == DRIVE_CDROM)
|
||||
ext = L"iso";
|
||||
else if (di.FileSystemName.Find(L"NTFS") >= 0)
|
||||
ext = L"ntfs";
|
||||
else if (di.FileSystemName.Find(L"FAT") >= 0)
|
||||
ext = L"fat";
|
||||
ext = "iso";
|
||||
else if (di.FileSystemName.IsPrefixedBy_Ascii_NoCase("NTFS"))
|
||||
ext = "ntfs";
|
||||
else if (di.FileSystemName.IsPrefixedBy_Ascii_NoCase("FAT"))
|
||||
ext = "fat";
|
||||
else
|
||||
ext = L"img";
|
||||
return ext;
|
||||
ext = "img";
|
||||
s.AddAscii(ext);
|
||||
}
|
||||
|
||||
HRESULT CFSDrives::GetFileSize(unsigned index, UInt64 &fileSize) const
|
||||
@@ -352,12 +365,12 @@ STDMETHODIMP CFSDrives::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 num
|
||||
Int32 /* includeAltStreams */, Int32 /* replaceAltStreamColon */,
|
||||
const wchar_t *path, IFolderOperationsExtractCallback *callback)
|
||||
{
|
||||
if (moveMode)
|
||||
return E_NOTIMPL;
|
||||
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
|
||||
if (moveMode)
|
||||
return E_NOTIMPL;
|
||||
|
||||
if (!_volumeMode)
|
||||
return E_NOTIMPL;
|
||||
|
||||
@@ -372,11 +385,14 @@ STDMETHODIMP CFSDrives::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 num
|
||||
RINOK(callback->SetTotal(totalSize));
|
||||
RINOK(callback->SetNumFiles(numItems));
|
||||
|
||||
UString destPath = path;
|
||||
FString destPath = us2fs(path);
|
||||
if (destPath.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
bool directName = (destPath.Back() != WCHAR_PATH_SEPARATOR);
|
||||
if (directName)
|
||||
|
||||
bool isAltDest = NName::IsAltPathPrefix(destPath);
|
||||
bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back()));
|
||||
|
||||
if (isDirectPath)
|
||||
{
|
||||
if (numItems > 1)
|
||||
return E_INVALIDARG;
|
||||
@@ -389,19 +405,19 @@ STDMETHODIMP CFSDrives::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 num
|
||||
{
|
||||
unsigned index = indices[i];
|
||||
const CDriveInfo &di = _drives[index];
|
||||
UString destPath2 = destPath;
|
||||
UString name = fs2us(di.Name);
|
||||
if (!directName)
|
||||
FString destPath2 = destPath;
|
||||
|
||||
if (!isDirectPath)
|
||||
{
|
||||
UString destName = name;
|
||||
if (!destName.IsEmpty() && destName.Back() == L':')
|
||||
FString destName = di.Name;
|
||||
if (!destName.IsEmpty() && destName.Back() == ':')
|
||||
{
|
||||
destName.DeleteBack();
|
||||
destName += L'.';
|
||||
destName += GetExt(index);
|
||||
AddExt(destName, index);
|
||||
}
|
||||
destPath2 += destName;
|
||||
}
|
||||
|
||||
FString srcPath = di.GetDeviceFileIoName();
|
||||
|
||||
UInt64 fileSize = 0;
|
||||
@@ -410,15 +426,23 @@ STDMETHODIMP CFSDrives::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 num
|
||||
return E_FAIL;
|
||||
}
|
||||
if (!di.KnownSize)
|
||||
{
|
||||
totalSize += fileSize;
|
||||
RINOK(callback->SetTotal(totalSize));
|
||||
RINOK(callback->SetTotal(totalSize));
|
||||
}
|
||||
|
||||
Int32 writeAskResult;
|
||||
CMyComBSTR destPathResult;
|
||||
RINOK(callback->AskWrite(fs2us(srcPath), BoolToInt(false), NULL, &fileSize,
|
||||
destPath2, &destPathResult, &writeAskResult));
|
||||
fs2us(destPath2), &destPathResult, &writeAskResult));
|
||||
|
||||
if (!IntToBool(writeAskResult))
|
||||
{
|
||||
if (totalSize >= fileSize)
|
||||
totalSize -= fileSize;
|
||||
RINOK(callback->SetTotal(totalSize));
|
||||
continue;
|
||||
}
|
||||
|
||||
RINOK(callback->SetCurrentFilePath(fs2us(srcPath)));
|
||||
|
||||
@@ -427,11 +451,12 @@ STDMETHODIMP CFSDrives::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 num
|
||||
RINOK(CopyFileSpec(srcPath, us2fs(destPathResult), false, fileSize, bufferSize, completedSize, callback));
|
||||
completedSize += fileSize;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CFSDrives::CopyFrom(Int32 /* moveMode */, const wchar_t * /* fromFolderPath */,
|
||||
const wchar_t ** /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */)
|
||||
const wchar_t * const * /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
@@ -36,10 +36,10 @@ class CFSDrives:
|
||||
{
|
||||
CObjectVector<CDriveInfo> _drives;
|
||||
bool _volumeMode;
|
||||
bool _longMode;
|
||||
bool _superMode;
|
||||
|
||||
HRESULT BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder);
|
||||
const wchar_t *GetExt(unsigned index) const;
|
||||
void AddExt(FString &s, unsigned index) const;
|
||||
HRESULT GetFileSize(unsigned index, UInt64 &fileSize) const;
|
||||
public:
|
||||
MY_UNKNOWN_IMP2(IFolderGetSystemIconIndex, IFolderOperations)
|
||||
@@ -49,10 +49,10 @@ public:
|
||||
|
||||
STDMETHOD(GetSystemIconIndex)(UInt32 index, Int32 *iconIndex);
|
||||
|
||||
void Init(bool volMode = false, bool longMode = false)
|
||||
void Init(bool volMode = false, bool superMode = false)
|
||||
{
|
||||
_volumeMode = volMode;
|
||||
_longMode = longMode;
|
||||
_superMode = superMode;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
// But real support version for that function is NT 3.1 (probably)
|
||||
// So we must define GetCompressedFileSizeW
|
||||
EXTERN_C_BEGIN
|
||||
WINBASEAPI DWORD WINAPI GetCompressedFileSizeW(LPCWSTR lpFileName, LPDWORD lpFileSizeHigh );
|
||||
WINBASEAPI DWORD WINAPI GetCompressedFileSizeW(LPCWSTR lpFileName, LPDWORD lpFileSizeHigh);
|
||||
EXTERN_C_END
|
||||
#endif
|
||||
#endif
|
||||
@@ -68,20 +68,23 @@ static const Byte kProps[] =
|
||||
kpidPrefix
|
||||
};
|
||||
|
||||
HRESULT CFSFolder::Init(const FString &path, IFolderFolder *parentFolder)
|
||||
HRESULT CFSFolder::Init(const FString &path /* , IFolderFolder *parentFolder */)
|
||||
{
|
||||
_parentFolder = parentFolder;
|
||||
// _parentFolder = parentFolder;
|
||||
_path = path;
|
||||
|
||||
_findChangeNotification.FindFirst(_path, false,
|
||||
FILE_NOTIFY_CHANGE_FILE_NAME |
|
||||
FILE_NOTIFY_CHANGE_DIR_NAME |
|
||||
FILE_NOTIFY_CHANGE_ATTRIBUTES |
|
||||
FILE_NOTIFY_CHANGE_SIZE |
|
||||
FILE_NOTIFY_CHANGE_LAST_WRITE /*|
|
||||
FILE_NOTIFY_CHANGE_LAST_ACCESS |
|
||||
FILE_NOTIFY_CHANGE_CREATION |
|
||||
FILE_NOTIFY_CHANGE_SECURITY */);
|
||||
FILE_NOTIFY_CHANGE_FILE_NAME
|
||||
| FILE_NOTIFY_CHANGE_DIR_NAME
|
||||
| FILE_NOTIFY_CHANGE_ATTRIBUTES
|
||||
| FILE_NOTIFY_CHANGE_SIZE
|
||||
| FILE_NOTIFY_CHANGE_LAST_WRITE
|
||||
/*
|
||||
| FILE_NOTIFY_CHANGE_LAST_ACCESS
|
||||
| FILE_NOTIFY_CHANGE_CREATION
|
||||
| FILE_NOTIFY_CHANGE_SECURITY
|
||||
*/
|
||||
);
|
||||
if (!_findChangeNotification.IsHandleAllocated())
|
||||
{
|
||||
DWORD lastError = GetLastError();
|
||||
@@ -99,7 +102,7 @@ HRESULT CFsFolderStat::Enumerate()
|
||||
{
|
||||
RINOK(Progress->SetCompleted(NULL));
|
||||
}
|
||||
Path += FCHAR_PATH_SEPARATOR;
|
||||
Path.Add_PathSepar();
|
||||
unsigned len = Path.Len();
|
||||
Path += FCHAR_ANY_MASK;
|
||||
CEnumerator enumerator(Path);
|
||||
@@ -124,7 +127,7 @@ HRESULT CFsFolderStat::Enumerate()
|
||||
|
||||
#ifndef UNDER_CE
|
||||
|
||||
static bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size)
|
||||
bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size)
|
||||
{
|
||||
DWORD highPart;
|
||||
DWORD lowPart = INVALID_FILE_SIZE;
|
||||
@@ -140,10 +143,10 @@ static bool MyGetCompressedFileSizeW(CFSTR path, UInt64 &size)
|
||||
#ifdef WIN_LONG_PATH
|
||||
if (USE_SUPER_PATH)
|
||||
{
|
||||
UString longPath;
|
||||
if (GetSuperPath(path, longPath, USE_MAIN_PATH))
|
||||
UString superPath;
|
||||
if (GetSuperPath(path, superPath, USE_MAIN_PATH))
|
||||
{
|
||||
lowPart = ::GetCompressedFileSizeW(longPath, &highPart);
|
||||
lowPart = ::GetCompressedFileSizeW(superPath, &highPart);
|
||||
if (lowPart != INVALID_FILE_SIZE || ::GetLastError() == NO_ERROR)
|
||||
{
|
||||
size = ((UInt64)highPart << 32) | lowPart;
|
||||
@@ -279,11 +282,10 @@ bool CFSFolder::LoadComments()
|
||||
if (len >= (1 << 28))
|
||||
return false;
|
||||
AString s;
|
||||
char *p = s.GetBuffer((unsigned)((size_t)len + 1));
|
||||
char *p = s.GetBuf((unsigned)(size_t)len);
|
||||
UInt32 processedSize;
|
||||
file.Read(p, (UInt32)len, processedSize);
|
||||
p[len] = 0;
|
||||
s.ReleaseBuffer();
|
||||
s.ReleaseBuf_CalcLen((unsigned)(size_t)len);
|
||||
if (processedSize != len)
|
||||
return false;
|
||||
file.Close();
|
||||
@@ -293,14 +295,6 @@ bool CFSFolder::LoadComments()
|
||||
return _comments.ReadFromString(unicodeString);
|
||||
}
|
||||
|
||||
static bool IsAscii(const AString &s)
|
||||
{
|
||||
for (unsigned i = 0; i < s.Len(); i++)
|
||||
if ((Byte)s[i] >= 0x80)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CFSFolder::SaveComments()
|
||||
{
|
||||
AString utf;
|
||||
@@ -309,7 +303,7 @@ bool CFSFolder::SaveComments()
|
||||
_comments.SaveToString(unicode);
|
||||
ConvertUnicodeToUTF8(unicode, utf);
|
||||
}
|
||||
if (!IsAscii(utf))
|
||||
if (!utf.IsAscii())
|
||||
utf.Insert(0, "\xEF\xBB\xBF" "\r\n");
|
||||
|
||||
FString path = _path + kDescriptionFileName;
|
||||
@@ -576,7 +570,7 @@ STDMETHODIMP CFSFolder::GetRawProp(UInt32
|
||||
|
||||
static inline CFSTR GetExtensionPtr(const FString &name)
|
||||
{
|
||||
int dotPos = name.ReverseFind(FTEXT('.'));
|
||||
int dotPos = name.ReverseFind_Dot();
|
||||
return name.Ptr((dotPos < 0) ? name.Len() : dotPos);
|
||||
}
|
||||
|
||||
@@ -686,7 +680,7 @@ HRESULT CFSFolder::BindToFolderSpec(CFSTR name, IFolderFolder **resultFolder)
|
||||
*resultFolder = 0;
|
||||
CFSFolder *folderSpec = new CFSFolder;
|
||||
CMyComPtr<IFolderFolder> subFolder = folderSpec;
|
||||
RINOK(folderSpec->Init(_path + name + FCHAR_PATH_SEPARATOR, 0));
|
||||
RINOK(folderSpec->Init(_path + name + FCHAR_PATH_SEPARATOR));
|
||||
*resultFolder = subFolder.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
@@ -700,6 +694,7 @@ void CFSFolder::GetPrefix(const CDirItem &item, FString &prefix) const
|
||||
prefix.Empty();
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
void CFSFolder::GetPrefix(const CDirItem &item, FString &prefix) const
|
||||
{
|
||||
@@ -714,20 +709,17 @@ void CFSFolder::GetPrefix(const CDirItem &item, FString &prefix) const
|
||||
parent = cur.Parent;
|
||||
}
|
||||
|
||||
unsigned totalLen = len;
|
||||
wchar_t *p = prefix.GetBuffer(len);
|
||||
wchar_t *p = prefix.GetBuf_SetEnd(len) + len;
|
||||
parent = item.Parent;
|
||||
|
||||
while (parent >= 0)
|
||||
{
|
||||
const CDirItem &cur = Files[parent];
|
||||
// path = cur->Name + FCHAR_PATH_SEPARATOR + path;
|
||||
MyStringCopy(p + len - cur.Name.Len() - 1, (const wchar_t *)cur.Name);
|
||||
p[--len] = FCHAR_PATH_SEPARATOR;
|
||||
len -= cur.Name.Len();
|
||||
*(--p) = FCHAR_PATH_SEPARATOR;
|
||||
p -= cur.Name.Len();
|
||||
wmemcpy(p, cur.Name, cur.Name.Len());
|
||||
parent = cur.Parent;
|
||||
}
|
||||
prefix.ReleaseBuffer(totalLen);
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -752,24 +744,26 @@ STDMETHODIMP CFSFolder::BindToFolder(const wchar_t *name, IFolderFolder **result
|
||||
return BindToFolderSpec(us2fs(name), resultFolder);
|
||||
}
|
||||
|
||||
static CFSTR kLongPrefix = FTEXT("\\\\?\\");
|
||||
static const CFSTR kSuperPrefix = FTEXT("\\\\?\\");
|
||||
|
||||
STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)
|
||||
{
|
||||
*resultFolder = 0;
|
||||
/*
|
||||
if (_parentFolder)
|
||||
{
|
||||
CMyComPtr<IFolderFolder> parentFolder = _parentFolder;
|
||||
*resultFolder = parentFolder.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
if (_path.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
int pos = _path.ReverseFind(FCHAR_PATH_SEPARATOR);
|
||||
int pos = _path.ReverseFind_PathSepar();
|
||||
if (pos < 0 || pos != (int)_path.Len() - 1)
|
||||
return E_FAIL;
|
||||
FString parentPath = _path.Left(pos);
|
||||
pos = parentPath.ReverseFind(FCHAR_PATH_SEPARATOR);
|
||||
pos = parentPath.ReverseFind_PathSepar();
|
||||
if (pos < 0)
|
||||
{
|
||||
#ifdef UNDER_CE
|
||||
@@ -783,9 +777,10 @@ STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
parentPath.DeleteFrom(pos + 1);
|
||||
|
||||
if (parentPath == kLongPrefix)
|
||||
if (parentPath == kSuperPrefix)
|
||||
{
|
||||
#ifdef UNDER_CE
|
||||
*resultFolder = 0;
|
||||
@@ -801,10 +796,10 @@ STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)
|
||||
FString parentPathReduced = parentPath.Left(pos);
|
||||
|
||||
#ifndef UNDER_CE
|
||||
pos = parentPathReduced.ReverseFind(FCHAR_PATH_SEPARATOR);
|
||||
pos = parentPathReduced.ReverseFind_PathSepar();
|
||||
if (pos == 1)
|
||||
{
|
||||
if (parentPath[0] != FCHAR_PATH_SEPARATOR)
|
||||
if (!IS_PATH_SEPAR_CHAR(parentPath[0]))
|
||||
return E_FAIL;
|
||||
CNetFolder *netFolderSpec = new CNetFolder;
|
||||
CMyComPtr<IFolderFolder> netFolder = netFolderSpec;
|
||||
@@ -818,6 +813,7 @@ STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)
|
||||
CMyComPtr<IFolderFolder> parentFolder = parentFolderSpec;
|
||||
RINOK(parentFolderSpec->Init(parentPath, 0));
|
||||
*resultFolder = parentFolder.Detach();
|
||||
*/
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -837,7 +833,7 @@ STDMETHODIMP CFSFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch (propID)
|
||||
{
|
||||
case kpidType: prop = L"FSFolder"; break;
|
||||
case kpidType: prop = "FSFolder"; break;
|
||||
case kpidPath: prop = fs2us(_path); break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
@@ -874,7 +870,7 @@ STDMETHODIMP CFSFolder::Clone(IFolderFolder **resultFolder)
|
||||
{
|
||||
CFSFolder *fsFolderSpec = new CFSFolder;
|
||||
CMyComPtr<IFolderFolder> folderNew = fsFolderSpec;
|
||||
fsFolderSpec->Init(_path, 0);
|
||||
fsFolderSpec->Init(_path);
|
||||
*resultFolder = folderNew.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1060,7 +1056,7 @@ STDMETHODIMP CFSFolder::SetProperty(UInt32 index, PROPID propID,
|
||||
CTextPair pair;
|
||||
pair.ID = filename;
|
||||
pair.ID.Trim();
|
||||
pair.Value = value->bstrVal;
|
||||
pair.Value.SetFromBstr(value->bstrVal);
|
||||
pair.Value.Trim();
|
||||
if (pair.Value.IsEmpty())
|
||||
_comments.DeletePair(filename);
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
|
||||
#include "../../../Windows/FileFind.h"
|
||||
|
||||
#include "../../Archive/IArchive.h"
|
||||
|
||||
#include "IFolder.h"
|
||||
#include "TextPairs.h"
|
||||
#include "..\..\Archive\IArchive.h"
|
||||
|
||||
namespace NFsFolder {
|
||||
|
||||
@@ -133,7 +134,7 @@ private:
|
||||
CObjectVector<CDirItem> Files;
|
||||
FStringVector Folders;
|
||||
// CObjectVector<CAltStream> Streams;
|
||||
CMyComPtr<IFolderFolder> _parentFolder;
|
||||
// CMyComPtr<IFolderFolder> _parentFolder;
|
||||
|
||||
bool _commentsAreLoaded;
|
||||
CPairsStorage _comments;
|
||||
@@ -158,9 +159,9 @@ private:
|
||||
#endif
|
||||
|
||||
public:
|
||||
HRESULT Init(const FString &path, IFolderFolder *parentFolder);
|
||||
#ifdef UNDER_CE
|
||||
HRESULT InitToRoot() { return Init(FTEXT("\\"), NULL); }
|
||||
HRESULT Init(const FString &path /* , IFolderFolder *parentFolder */);
|
||||
#if !defined(_WIN32) || defined(UNDER_CE)
|
||||
HRESULT InitToRoot() { return Init(FSTRING_PATH_SEPARATOR /* , NULL */); }
|
||||
#endif
|
||||
|
||||
CFSFolder() : _flatMode(false)
|
||||
@@ -178,6 +179,7 @@ public:
|
||||
}
|
||||
|
||||
// void GetPrefix(const CDirItem &item, FString &prefix) const;
|
||||
|
||||
FString GetRelPath(const CDirItem &item) const;
|
||||
|
||||
void Clear()
|
||||
@@ -188,6 +190,24 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct CCopyStateIO
|
||||
{
|
||||
IProgress *Progress;
|
||||
UInt64 TotalSize;
|
||||
UInt64 StartPos;
|
||||
UInt64 CurrentSize;
|
||||
bool DeleteSrcFile;
|
||||
|
||||
int ErrorFileIndex;
|
||||
UString ErrorMessage;
|
||||
|
||||
CCopyStateIO(): DeleteSrcFile(false), TotalSize(0), StartPos(0) {}
|
||||
|
||||
HRESULT MyCopyFile(CFSTR inPath, CFSTR outPath);
|
||||
};
|
||||
|
||||
HRESULT SendLastErrorMessage(IFolderOperationsExtractCallback *callback, const FString &fileName);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -29,6 +29,75 @@ extern bool g_IsNT;
|
||||
|
||||
namespace NFsFolder {
|
||||
|
||||
HRESULT CCopyStateIO::MyCopyFile(CFSTR inPath, CFSTR outPath)
|
||||
{
|
||||
ErrorFileIndex = -1;
|
||||
ErrorMessage.Empty();
|
||||
CurrentSize = 0;
|
||||
|
||||
{
|
||||
const size_t kBufSize = 1 << 16;
|
||||
CByteArr buf(kBufSize);
|
||||
|
||||
NIO::CInFile inFile;
|
||||
NIO::COutFile outFile;
|
||||
|
||||
if (!inFile.Open(inPath))
|
||||
{
|
||||
ErrorFileIndex = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (!outFile.Create(outPath, true))
|
||||
{
|
||||
ErrorFileIndex = 1;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
UInt32 num;
|
||||
if (!inFile.Read(buf, kBufSize, num))
|
||||
{
|
||||
ErrorFileIndex = 0;
|
||||
return S_OK;
|
||||
}
|
||||
if (num == 0)
|
||||
break;
|
||||
|
||||
UInt32 written = 0;
|
||||
if (!outFile.Write(buf, num, written))
|
||||
{
|
||||
ErrorFileIndex = 1;
|
||||
return S_OK;
|
||||
}
|
||||
if (written != num)
|
||||
{
|
||||
ErrorMessage = L"Write error";
|
||||
return S_OK;
|
||||
}
|
||||
CurrentSize += num;
|
||||
if (Progress)
|
||||
{
|
||||
UInt64 completed = StartPos + CurrentSize;
|
||||
RINOK(Progress->SetCompleted(&completed));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (DeleteSrcFile)
|
||||
{
|
||||
if (!DeleteFileAlways(inPath))
|
||||
{
|
||||
ErrorFileIndex = 0;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
static bool IsItWindows2000orHigher()
|
||||
{
|
||||
@@ -43,8 +112,13 @@ static bool IsItWindows2000orHigher()
|
||||
|
||||
struct CProgressInfo
|
||||
{
|
||||
UInt64 TotalSize;
|
||||
UInt64 StartPos;
|
||||
UInt64 FileSize;
|
||||
IProgress *Progress;
|
||||
HRESULT ProgressResult;
|
||||
|
||||
void Init() { ProgressResult = S_OK; }
|
||||
};
|
||||
|
||||
#ifndef PROGRESS_CONTINUE
|
||||
@@ -71,7 +145,7 @@ DWORD
|
||||
#endif
|
||||
|
||||
static DWORD CALLBACK CopyProgressRoutine(
|
||||
LARGE_INTEGER /* TotalFileSize */, // file size
|
||||
LARGE_INTEGER TotalFileSize, // file size
|
||||
LARGE_INTEGER TotalBytesTransferred, // bytes transferred
|
||||
LARGE_INTEGER /* StreamSize */, // bytes in stream
|
||||
LARGE_INTEGER /* StreamBytesTransferred */, // bytes transferred for stream
|
||||
@@ -82,14 +156,27 @@ static DWORD CALLBACK CopyProgressRoutine(
|
||||
LPVOID lpData // from CopyFileEx
|
||||
)
|
||||
{
|
||||
CProgressInfo &progressInfo = *(CProgressInfo *)lpData;
|
||||
UInt64 completed = progressInfo.StartPos + TotalBytesTransferred.QuadPart;
|
||||
if (progressInfo.Progress->SetCompleted(&completed) != S_OK)
|
||||
return PROGRESS_CANCEL;
|
||||
return PROGRESS_CONTINUE;
|
||||
TotalFileSize = TotalFileSize;
|
||||
// TotalBytesTransferred = TotalBytesTransferred;
|
||||
// StreamSize = StreamSize;
|
||||
// StreamBytesTransferred = StreamBytesTransferred;
|
||||
// dwStreamNumber = dwStreamNumber;
|
||||
// dwCallbackReason = dwCallbackReason;
|
||||
|
||||
CProgressInfo &pi = *(CProgressInfo *)lpData;
|
||||
|
||||
if ((UInt64)TotalFileSize.QuadPart > pi.FileSize)
|
||||
{
|
||||
pi.TotalSize += (UInt64)TotalFileSize.QuadPart - pi.FileSize;
|
||||
pi.FileSize = (UInt64)TotalFileSize.QuadPart;
|
||||
pi.ProgressResult = pi.Progress->SetTotal(pi.TotalSize);
|
||||
}
|
||||
UInt64 completed = pi.StartPos + TotalBytesTransferred.QuadPart;
|
||||
pi.ProgressResult = pi.Progress->SetCompleted(&completed);
|
||||
return (pi.ProgressResult == S_OK ? PROGRESS_CONTINUE : PROGRESS_CANCEL);
|
||||
}
|
||||
|
||||
typedef BOOL (WINAPI * CopyFileExPointer)(
|
||||
typedef BOOL (WINAPI * Func_CopyFileExA)(
|
||||
IN LPCSTR lpExistingFileName,
|
||||
IN LPCSTR lpNewFileName,
|
||||
IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
|
||||
@@ -98,7 +185,7 @@ typedef BOOL (WINAPI * CopyFileExPointer)(
|
||||
IN DWORD dwCopyFlags
|
||||
);
|
||||
|
||||
typedef BOOL (WINAPI * CopyFileExPointerW)(
|
||||
typedef BOOL (WINAPI * Func_CopyFileExW)(
|
||||
IN LPCWSTR lpExistingFileName,
|
||||
IN LPCWSTR lpNewFileName,
|
||||
IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
|
||||
@@ -107,67 +194,7 @@ typedef BOOL (WINAPI * CopyFileExPointerW)(
|
||||
IN DWORD dwCopyFlags
|
||||
);
|
||||
|
||||
static bool FsCopyFile(CFSTR oldFile, CFSTR newFile, IProgress *progress, UInt64 &completedSize)
|
||||
{
|
||||
CProgressInfo progressInfo;
|
||||
progressInfo.Progress = progress;
|
||||
progressInfo.StartPos = completedSize;
|
||||
BOOL CancelFlag = FALSE;
|
||||
#ifndef _UNICODE
|
||||
if (g_IsNT)
|
||||
#endif
|
||||
{
|
||||
const wchar_t *k_DllName =
|
||||
#ifdef UNDER_CE
|
||||
L"coredll.dll"
|
||||
#else
|
||||
L"kernel32.dll"
|
||||
#endif
|
||||
;
|
||||
CopyFileExPointerW copyFunctionW = (CopyFileExPointerW)
|
||||
My_GetProcAddress(::GetModuleHandleW(k_DllName), "CopyFileExW");
|
||||
|
||||
IF_USE_MAIN_PATH_2(oldFile, newFile)
|
||||
{
|
||||
if (copyFunctionW == 0)
|
||||
return BOOLToBool(::CopyFileW(fs2us(oldFile), fs2us(newFile), TRUE));
|
||||
if (copyFunctionW(fs2us(oldFile), fs2us(newFile), CopyProgressRoutine,
|
||||
&progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS))
|
||||
return true;
|
||||
}
|
||||
#ifdef WIN_LONG_PATH
|
||||
if (USE_SUPER_PATH_2)
|
||||
{
|
||||
UString longPathExisting, longPathNew;
|
||||
if (!GetSuperPaths(oldFile, newFile, longPathExisting, longPathNew, USE_MAIN_PATH_2))
|
||||
return false;
|
||||
if (copyFunctionW(longPathExisting, longPathNew, CopyProgressRoutine,
|
||||
&progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS))
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
#ifndef _UNICODE
|
||||
else
|
||||
{
|
||||
CopyFileExPointer copyFunction = (CopyFileExPointer)
|
||||
::GetProcAddress(::GetModuleHandleA("kernel32.dll"),
|
||||
"CopyFileExA");
|
||||
if (copyFunction != 0)
|
||||
{
|
||||
if (copyFunction(fs2fas(oldFile), fs2fas(newFile),
|
||||
CopyProgressRoutine,&progressInfo, &CancelFlag, COPY_FILE_FAIL_IF_EXISTS))
|
||||
return true;
|
||||
if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
|
||||
return false;
|
||||
}
|
||||
return BOOLToBool(::CopyFile(fs2fas(oldFile), fs2fas(newFile), TRUE));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef BOOL (WINAPI * MoveFileWithProgressPointer)(
|
||||
typedef BOOL (WINAPI * Func_MoveFileWithProgressW)(
|
||||
IN LPCWSTR lpExistingFileName,
|
||||
IN LPCWSTR lpNewFileName,
|
||||
IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
|
||||
@@ -175,42 +202,144 @@ typedef BOOL (WINAPI * MoveFileWithProgressPointer)(
|
||||
IN DWORD dwFlags
|
||||
);
|
||||
|
||||
#ifdef UNDER_CE
|
||||
#define NON_CE_VAR(_v_)
|
||||
#else
|
||||
#define NON_CE_VAR(_v_) _v_
|
||||
#endif
|
||||
struct CCopyState
|
||||
{
|
||||
CProgressInfo ProgressInfo;
|
||||
IFolderOperationsExtractCallback *Callback;
|
||||
UInt64 TotalSize;
|
||||
bool MoveMode;
|
||||
bool UseReadWriteMode;
|
||||
|
||||
static bool FsMoveFile(CFSTR oldFile, CFSTR newFile,
|
||||
IProgress * NON_CE_VAR(progress),
|
||||
UInt64 & NON_CE_VAR(completedSize))
|
||||
Func_CopyFileExW my_CopyFileExW;
|
||||
#ifndef UNDER_CE
|
||||
Func_MoveFileWithProgressW my_MoveFileWithProgressW;
|
||||
#endif
|
||||
#ifndef _UNICODE
|
||||
Func_CopyFileExA my_CopyFileExA;
|
||||
#endif
|
||||
|
||||
void Prepare();
|
||||
bool CopyFile_NT(const wchar_t *oldFile, const wchar_t *newFile);
|
||||
bool CopyFile_Sys(CFSTR oldFile, CFSTR newFile);
|
||||
bool MoveFile_Sys(CFSTR oldFile, CFSTR newFile);
|
||||
|
||||
HRESULT CallProgress();
|
||||
|
||||
bool IsCallbackProgressError() { return ProgressInfo.ProgressResult != S_OK; }
|
||||
};
|
||||
|
||||
HRESULT CCopyState::CallProgress()
|
||||
{
|
||||
return ProgressInfo.Progress->SetCompleted(&ProgressInfo.StartPos);
|
||||
}
|
||||
|
||||
void CCopyState::Prepare()
|
||||
{
|
||||
my_CopyFileExW = NULL;
|
||||
#ifndef UNDER_CE
|
||||
my_MoveFileWithProgressW = NULL;
|
||||
#endif
|
||||
#ifndef _UNICODE
|
||||
my_CopyFileExA = NULL;
|
||||
if (!g_IsNT)
|
||||
{
|
||||
my_CopyFileExA = (Func_CopyFileExA)::GetProcAddress(::GetModuleHandleA("kernel32.dll"), "CopyFileExA");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
HMODULE module = ::GetModuleHandleW(
|
||||
#ifdef UNDER_CE
|
||||
L"coredll.dll"
|
||||
#else
|
||||
L"kernel32.dll"
|
||||
#endif
|
||||
);
|
||||
my_CopyFileExW = (Func_CopyFileExW)My_GetProcAddress(module, "CopyFileExW");
|
||||
#ifndef UNDER_CE
|
||||
my_MoveFileWithProgressW = (Func_MoveFileWithProgressW)My_GetProcAddress(module, "MoveFileWithProgressW");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* WinXP-64:
|
||||
CopyFileW(fromFile, toFile:altStream)
|
||||
OK - there are NO alt streams in fromFile
|
||||
ERROR_INVALID_PARAMETER - there are alt streams in fromFile
|
||||
*/
|
||||
|
||||
bool CCopyState::CopyFile_NT(const wchar_t *oldFile, const wchar_t *newFile)
|
||||
{
|
||||
BOOL cancelFlag = FALSE;
|
||||
if (my_CopyFileExW)
|
||||
return BOOLToBool(my_CopyFileExW(oldFile, newFile, CopyProgressRoutine,
|
||||
&ProgressInfo, &cancelFlag, COPY_FILE_FAIL_IF_EXISTS));
|
||||
return BOOLToBool(::CopyFileW(oldFile, newFile, TRUE));
|
||||
}
|
||||
|
||||
bool CCopyState::CopyFile_Sys(CFSTR oldFile, CFSTR newFile)
|
||||
{
|
||||
#ifndef _UNICODE
|
||||
if (!g_IsNT)
|
||||
{
|
||||
if (my_CopyFileExA)
|
||||
{
|
||||
BOOL cancelFlag = FALSE;
|
||||
if (my_CopyFileExA(fs2fas(oldFile), fs2fas(newFile),
|
||||
CopyProgressRoutine, &ProgressInfo, &cancelFlag, COPY_FILE_FAIL_IF_EXISTS))
|
||||
return true;
|
||||
if (::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
|
||||
return false;
|
||||
}
|
||||
return BOOLToBool(::CopyFile(fs2fas(oldFile), fs2fas(newFile), TRUE));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
IF_USE_MAIN_PATH_2(oldFile, newFile)
|
||||
{
|
||||
if (CopyFile_NT(fs2us(oldFile), fs2us(newFile)))
|
||||
return true;
|
||||
}
|
||||
#ifdef WIN_LONG_PATH
|
||||
if (USE_SUPER_PATH_2)
|
||||
{
|
||||
if (IsCallbackProgressError())
|
||||
return false;
|
||||
UString superPathOld, superPathNew;
|
||||
if (!GetSuperPaths(oldFile, newFile, superPathOld, superPathNew, USE_MAIN_PATH_2))
|
||||
return false;
|
||||
if (CopyFile_NT(superPathOld, superPathNew))
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CCopyState::MoveFile_Sys(CFSTR oldFile, CFSTR newFile)
|
||||
{
|
||||
#ifndef UNDER_CE
|
||||
// if (IsItWindows2000orHigher())
|
||||
// {
|
||||
CProgressInfo progressInfo;
|
||||
progressInfo.Progress = progress;
|
||||
progressInfo.StartPos = completedSize;
|
||||
|
||||
MoveFileWithProgressPointer moveFunction = (MoveFileWithProgressPointer)
|
||||
My_GetProcAddress(::GetModuleHandle(TEXT("kernel32.dll")),
|
||||
"MoveFileWithProgressW");
|
||||
if (moveFunction != 0)
|
||||
if (my_MoveFileWithProgressW)
|
||||
{
|
||||
IF_USE_MAIN_PATH_2(oldFile, newFile)
|
||||
{
|
||||
if (moveFunction(fs2us(oldFile), fs2us(newFile), CopyProgressRoutine,
|
||||
&progressInfo, MOVEFILE_COPY_ALLOWED))
|
||||
if (my_MoveFileWithProgressW(fs2us(oldFile), fs2us(newFile), CopyProgressRoutine,
|
||||
&ProgressInfo, MOVEFILE_COPY_ALLOWED))
|
||||
return true;
|
||||
}
|
||||
#ifdef WIN_LONG_PATH
|
||||
if ((!(USE_MAIN_PATH_2) || ::GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) && USE_SUPER_PATH_2)
|
||||
{
|
||||
UString longPathExisting, longPathNew;
|
||||
if (!GetSuperPaths(oldFile, newFile, longPathExisting, longPathNew, USE_MAIN_PATH_2))
|
||||
if (IsCallbackProgressError())
|
||||
return false;
|
||||
if (moveFunction(longPathExisting, longPathNew, CopyProgressRoutine,
|
||||
&progressInfo, MOVEFILE_COPY_ALLOWED))
|
||||
UString superPathOld, superPathNew;
|
||||
if (!GetSuperPaths(oldFile, newFile, superPathOld, superPathNew, USE_MAIN_PATH_2))
|
||||
return false;
|
||||
if (my_MoveFileWithProgressW(superPathOld, superPathNew, CopyProgressRoutine,
|
||||
&ProgressInfo, MOVEFILE_COPY_ALLOWED))
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@@ -226,7 +355,10 @@ static bool FsMoveFile(CFSTR oldFile, CFSTR newFile,
|
||||
static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
|
||||
const wchar_t *message, const FString &fileName)
|
||||
{
|
||||
return callback->ShowMessage(message + fs2us(fileName));
|
||||
UString s = message;
|
||||
s += L" : ";
|
||||
s += fs2us(fileName);
|
||||
return callback->ShowMessage(s);
|
||||
}
|
||||
|
||||
static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
|
||||
@@ -235,41 +367,104 @@ static HRESULT SendMessageError(IFolderOperationsExtractCallback *callback,
|
||||
return SendMessageError(callback, MultiByteToUnicodeString(message), fileName);
|
||||
}
|
||||
|
||||
static HRESULT FsCopyFile(
|
||||
static DWORD Return_LastError_or_FAIL()
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
if (errorCode == 0)
|
||||
errorCode = (DWORD)E_FAIL;
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
static UString GetLastErrorMessage()
|
||||
{
|
||||
return NError::MyFormatMessage(Return_LastError_or_FAIL());
|
||||
}
|
||||
|
||||
HRESULT SendLastErrorMessage(IFolderOperationsExtractCallback *callback, const FString &fileName)
|
||||
{
|
||||
return SendMessageError(callback, GetLastErrorMessage(), fileName);
|
||||
}
|
||||
|
||||
static HRESULT CopyFile_Ask(
|
||||
CCopyState &state,
|
||||
const FString &srcPath,
|
||||
const CFileInfo &srcFileInfo,
|
||||
const FString &destPathSpec,
|
||||
IFolderOperationsExtractCallback *callback,
|
||||
UInt64 &completedSize)
|
||||
const FString &destPath)
|
||||
{
|
||||
FString destPath = destPathSpec;
|
||||
if (CompareFileNames(destPath, srcPath) == 0)
|
||||
{
|
||||
RINOK(SendMessageError(callback, "can not copy file onto itself: ", destPath));
|
||||
RINOK(SendMessageError(state.Callback,
|
||||
state.MoveMode ?
|
||||
"can not move file onto itself" :
|
||||
"can not copy file onto itself"
|
||||
, destPath));
|
||||
return E_ABORT;
|
||||
}
|
||||
|
||||
Int32 writeAskResult;
|
||||
CMyComBSTR destPathResult;
|
||||
RINOK(callback->AskWrite(
|
||||
RINOK(state.Callback->AskWrite(
|
||||
fs2us(srcPath),
|
||||
BoolToInt(false),
|
||||
&srcFileInfo.MTime, &srcFileInfo.Size,
|
||||
fs2us(destPath),
|
||||
&destPathResult,
|
||||
&writeAskResult));
|
||||
|
||||
if (IntToBool(writeAskResult))
|
||||
{
|
||||
FString destPathNew = us2fs((const wchar_t *)(BSTR)destPathResult);
|
||||
RINOK(callback->SetCurrentFilePath(fs2us(srcPath)));
|
||||
if (!FsCopyFile(srcPath, destPathNew, callback, completedSize))
|
||||
FString destPathNew = us2fs((LPCOLESTR)destPathResult);
|
||||
RINOK(state.Callback->SetCurrentFilePath(fs2us(srcPath)));
|
||||
|
||||
if (state.UseReadWriteMode)
|
||||
{
|
||||
RINOK(SendMessageError(callback, NError::MyFormatMessage(GetLastError()) + L" : ", destPathNew));
|
||||
return E_ABORT;
|
||||
NFsFolder::CCopyStateIO state2;
|
||||
state2.Progress = state.Callback;
|
||||
state2.DeleteSrcFile = state.MoveMode;
|
||||
state2.TotalSize = state.TotalSize;
|
||||
state2.StartPos = state.ProgressInfo.StartPos;
|
||||
RINOK(state2.MyCopyFile(srcPath, destPathNew));
|
||||
if (state2.ErrorFileIndex >= 0)
|
||||
{
|
||||
if (state2.ErrorMessage.IsEmpty())
|
||||
state2.ErrorMessage = GetLastErrorMessage();
|
||||
FString errorName;
|
||||
if (state2.ErrorFileIndex == 0)
|
||||
errorName = srcPath;
|
||||
else
|
||||
errorName = destPathNew;
|
||||
RINOK(SendMessageError(state.Callback, state2.ErrorMessage, errorName));
|
||||
return E_ABORT;
|
||||
}
|
||||
state.ProgressInfo.StartPos += state2.CurrentSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.ProgressInfo.FileSize = srcFileInfo.Size;
|
||||
bool res;
|
||||
if (state.MoveMode)
|
||||
res = state.MoveFile_Sys(srcPath, destPathNew);
|
||||
else
|
||||
res = state.CopyFile_Sys(srcPath, destPathNew);
|
||||
RINOK(state.ProgressInfo.ProgressResult);
|
||||
if (!res)
|
||||
{
|
||||
// GetLastError() is ERROR_REQUEST_ABORTED in case of PROGRESS_CANCEL.
|
||||
RINOK(SendMessageError(state.Callback, GetLastErrorMessage(), destPathNew));
|
||||
return E_ABORT;
|
||||
}
|
||||
state.ProgressInfo.StartPos += state.ProgressInfo.FileSize;
|
||||
}
|
||||
}
|
||||
completedSize += srcFileInfo.Size;
|
||||
return callback->SetCompleted(&completedSize);
|
||||
else
|
||||
{
|
||||
if (state.TotalSize >= srcFileInfo.Size)
|
||||
{
|
||||
state.TotalSize -= srcFileInfo.Size;
|
||||
RINOK(state.ProgressInfo.Progress->SetTotal(state.TotalSize));
|
||||
}
|
||||
}
|
||||
return state.CallProgress();
|
||||
}
|
||||
|
||||
static FString CombinePath(const FString &folderPath, const FString &fileName)
|
||||
@@ -288,123 +483,70 @@ static bool IsDestChild(const FString &src, const FString &dest)
|
||||
}
|
||||
|
||||
static HRESULT CopyFolder(
|
||||
const FString &srcPath,
|
||||
const FString &destPath,
|
||||
IFolderOperationsExtractCallback *callback,
|
||||
UInt64 &completedSize)
|
||||
CCopyState &state,
|
||||
const FString &srcPath, // without TAIL separator
|
||||
const FString &destPath) // without TAIL separator
|
||||
{
|
||||
RINOK(callback->SetCompleted(&completedSize));
|
||||
RINOK(state.CallProgress());
|
||||
|
||||
if (IsDestChild(srcPath, destPath))
|
||||
{
|
||||
RINOK(SendMessageError(callback, "can not copy folder onto itself: ", destPath));
|
||||
RINOK(SendMessageError(state.Callback,
|
||||
state.MoveMode ?
|
||||
"can not copy folder onto itself" :
|
||||
"can not move folder onto itself"
|
||||
, destPath));
|
||||
return E_ABORT;
|
||||
}
|
||||
|
||||
if (state.MoveMode)
|
||||
{
|
||||
if (state.MoveFile_Sys(srcPath, destPath))
|
||||
return S_OK;
|
||||
|
||||
// MSDN: MoveFile() fails for dirs on different volumes.
|
||||
}
|
||||
|
||||
if (!CreateComplexDir(destPath))
|
||||
{
|
||||
RINOK(SendMessageError(callback, "can not create folder: ", destPath));
|
||||
RINOK(SendMessageError(state.Callback, "can not create folder", destPath));
|
||||
return E_ABORT;
|
||||
}
|
||||
|
||||
CEnumerator enumerator(CombinePath(srcPath, FSTRING_ANY_MASK));
|
||||
CDirItem fi;
|
||||
while (enumerator.Next(fi))
|
||||
|
||||
for (;;)
|
||||
{
|
||||
NFind::CFileInfo fi;
|
||||
bool found;
|
||||
if (!enumerator.Next(fi, found))
|
||||
{
|
||||
SendLastErrorMessage(state.Callback, srcPath);
|
||||
return S_OK;
|
||||
}
|
||||
if (!found)
|
||||
break;
|
||||
const FString srcPath2 = CombinePath(srcPath, fi.Name);
|
||||
const FString destPath2 = CombinePath(destPath, fi.Name);
|
||||
if (fi.IsDir())
|
||||
{
|
||||
RINOK(CopyFolder(srcPath2, destPath2, callback, completedSize))
|
||||
RINOK(CopyFolder(state, srcPath2, destPath2))
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(FsCopyFile(srcPath2, fi, destPath2, callback, completedSize));
|
||||
RINOK(CopyFile_Ask(state, srcPath2, fi, destPath2));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Move Operations
|
||||
|
||||
static HRESULT FsMoveFile(
|
||||
const FString &srcPath,
|
||||
const CFileInfo &srcFileInfo,
|
||||
const FString &destPath,
|
||||
IFolderOperationsExtractCallback *callback,
|
||||
UInt64 &completedSize)
|
||||
{
|
||||
if (CompareFileNames(destPath, srcPath) == 0)
|
||||
if (state.MoveMode)
|
||||
{
|
||||
RINOK(SendMessageError(callback, "can not move file onto itself: ", srcPath));
|
||||
return E_ABORT;
|
||||
}
|
||||
|
||||
Int32 writeAskResult;
|
||||
CMyComBSTR destPathResult;
|
||||
RINOK(callback->AskWrite(
|
||||
fs2us(srcPath),
|
||||
BoolToInt(false),
|
||||
&srcFileInfo.MTime, &srcFileInfo.Size,
|
||||
fs2us(destPath),
|
||||
&destPathResult,
|
||||
&writeAskResult));
|
||||
if (IntToBool(writeAskResult))
|
||||
{
|
||||
FString destPathNew = us2fs((const wchar_t *)(BSTR)destPathResult);
|
||||
RINOK(callback->SetCurrentFilePath(fs2us(srcPath)));
|
||||
if (!FsMoveFile(srcPath, destPathNew, callback, completedSize))
|
||||
if (!RemoveDir(srcPath))
|
||||
{
|
||||
RINOK(SendMessageError(callback, "can not move to file: ", destPathNew));
|
||||
RINOK(SendMessageError(state.Callback, "can not remove folder", srcPath));
|
||||
return E_ABORT;
|
||||
}
|
||||
}
|
||||
completedSize += srcFileInfo.Size;
|
||||
RINOK(callback->SetCompleted(&completedSize));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT FsMoveFolder(
|
||||
const FString &srcPath,
|
||||
const FString &destPath,
|
||||
IFolderOperationsExtractCallback *callback,
|
||||
UInt64 &completedSize)
|
||||
{
|
||||
if (IsDestChild(srcPath, destPath))
|
||||
{
|
||||
RINOK(SendMessageError(callback, "can not move folder onto itself: ", destPath));
|
||||
return E_ABORT;
|
||||
}
|
||||
|
||||
if (FsMoveFile(srcPath, destPath, callback, completedSize))
|
||||
return S_OK;
|
||||
|
||||
if (!CreateComplexDir(destPath))
|
||||
{
|
||||
RINOK(SendMessageError(callback, "can not create folder: ", destPath));
|
||||
return E_ABORT;
|
||||
}
|
||||
{
|
||||
CEnumerator enumerator(CombinePath(srcPath, FSTRING_ANY_MASK));
|
||||
CDirItem fi;
|
||||
while (enumerator.Next(fi))
|
||||
{
|
||||
const FString srcPath2 = CombinePath(srcPath, fi.Name);
|
||||
const FString destPath2 = CombinePath(destPath, fi.Name);
|
||||
if (fi.IsDir())
|
||||
{
|
||||
RINOK(FsMoveFolder(srcPath2, destPath2, callback, completedSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(FsMoveFile(srcPath2, fi, destPath2, callback, completedSize));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!RemoveDir(srcPath))
|
||||
{
|
||||
RINOK(SendMessageError(callback, "can not remove folder: ", srcPath));
|
||||
return E_ABORT;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -415,33 +557,44 @@ STDMETHODIMP CFSFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 num
|
||||
if (numItems == 0)
|
||||
return S_OK;
|
||||
|
||||
CFsFolderStat stat;
|
||||
stat.Progress = callback;
|
||||
RINOK(GetItemsFullSize(indices, numItems, stat));
|
||||
RINOK(callback->SetTotal(stat.Size));
|
||||
RINOK(callback->SetNumFiles(stat.NumFiles));
|
||||
|
||||
FString destPath = us2fs(path);
|
||||
if (destPath.IsEmpty())
|
||||
return E_INVALIDARG;
|
||||
bool directName = (destPath.Back() != FCHAR_PATH_SEPARATOR);
|
||||
if (directName)
|
||||
|
||||
bool isAltDest = NName::IsAltPathPrefix(destPath);;
|
||||
bool isDirectPath = (!isAltDest && !IsPathSepar(destPath.Back()));
|
||||
|
||||
if (isDirectPath)
|
||||
{
|
||||
if (numItems > 1)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Does CreateComplexDir work in network ?
|
||||
if (!CreateComplexDir(destPath))
|
||||
{
|
||||
RINOK(SendMessageError(callback, "can not create folder: ", destPath));
|
||||
return E_ABORT;
|
||||
}
|
||||
}
|
||||
|
||||
CFsFolderStat stat;
|
||||
stat.Progress = callback;
|
||||
RINOK(GetItemsFullSize(indices, numItems, stat));
|
||||
|
||||
if (stat.NumFolders != 0 && isAltDest)
|
||||
return E_NOTIMPL;
|
||||
|
||||
RINOK(callback->SetTotal(stat.Size));
|
||||
RINOK(callback->SetNumFiles(stat.NumFiles));
|
||||
|
||||
UInt64 completedSize = 0;
|
||||
RINOK(callback->SetCompleted(&completedSize));
|
||||
|
||||
CCopyState state;
|
||||
state.ProgressInfo.TotalSize = stat.Size;
|
||||
state.ProgressInfo.TotalSize = stat.Size;
|
||||
state.ProgressInfo.StartPos = 0;
|
||||
state.ProgressInfo.Progress = callback;
|
||||
state.ProgressInfo.Init();
|
||||
state.Callback = callback;
|
||||
state.MoveMode = IntToBool(moveMode);
|
||||
state.UseReadWriteMode = isAltDest;
|
||||
state.Prepare();
|
||||
state.TotalSize = stat.Size;
|
||||
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
UInt32 index = indices[i];
|
||||
@@ -449,38 +602,25 @@ STDMETHODIMP CFSFolder::CopyTo(Int32 moveMode, const UInt32 *indices, UInt32 num
|
||||
continue;
|
||||
const CDirItem &fi = Files[index];
|
||||
FString destPath2 = destPath;
|
||||
if (!directName)
|
||||
if (!isDirectPath)
|
||||
destPath2 += fi.Name;
|
||||
FString srcPath;
|
||||
GetFullPath(fi, srcPath);
|
||||
|
||||
if (fi.IsDir())
|
||||
{
|
||||
if (moveMode)
|
||||
{
|
||||
RINOK(FsMoveFolder(srcPath, destPath2, callback, completedSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(CopyFolder(srcPath, destPath2, callback, completedSize));
|
||||
}
|
||||
RINOK(CopyFolder(state, srcPath, destPath2));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (moveMode)
|
||||
{
|
||||
RINOK(FsMoveFile(srcPath, fi, destPath2, callback, completedSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(FsCopyFile(srcPath, fi, destPath2, callback, completedSize));
|
||||
}
|
||||
RINOK(CopyFile_Ask(state, srcPath, fi, destPath2));
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CFSFolder::CopyFrom(Int32 /* moveMode */, const wchar_t * /* fromFolderPath */,
|
||||
const wchar_t ** /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */)
|
||||
const wchar_t * const * /* itemsPaths */, UInt32 /* numItems */, IProgress * /* progress */)
|
||||
{
|
||||
/*
|
||||
UInt64 numFolders, numFiles, totalSize;
|
||||
|
||||
@@ -55,12 +55,10 @@ static int FindPlugin(const CObjectVector<CPluginInfo> &plugins, const UString &
|
||||
}
|
||||
*/
|
||||
|
||||
static const FChar kExtensionDelimiter = FTEXT('.');
|
||||
|
||||
static void SplitNameToPureNameAndExtension(const FString &fullName,
|
||||
FString &pureName, FString &extensionDelimiter, FString &extension)
|
||||
{
|
||||
int index = fullName.ReverseFind(kExtensionDelimiter);
|
||||
int index = fullName.ReverseFind_Dot();
|
||||
if (index < 0)
|
||||
{
|
||||
pureName = fullName;
|
||||
@@ -70,7 +68,7 @@ static void SplitNameToPureNameAndExtension(const FString &fullName,
|
||||
else
|
||||
{
|
||||
pureName.SetFrom(fullName, index);
|
||||
extensionDelimiter = kExtensionDelimiter;
|
||||
extensionDelimiter = FTEXT('.');
|
||||
extension = fullName.Ptr(index + 1);
|
||||
}
|
||||
}
|
||||
@@ -89,7 +87,7 @@ HRESULT OpenFileFolderPlugin(
|
||||
|
||||
FString extension, name, pureName, dot;
|
||||
|
||||
int slashPos = path.ReverseFind(FCHAR_PATH_SEPARATOR);
|
||||
int slashPos = path.ReverseFind_PathSepar();
|
||||
FString dirPrefix;
|
||||
FString fileName;
|
||||
if (slashPos >= 0)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
int CExtDatabase::FindExt(const UString &ext)
|
||||
{
|
||||
FOR_VECTOR (i, Exts)
|
||||
if (Exts[i].Ext.IsEqualToNoCase(ext))
|
||||
if (Exts[i].Ext.IsEqualTo_NoCase(ext))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "FoldersPageRes.h"
|
||||
#include "../../GuiCommon.rc"
|
||||
|
||||
#define xc 196
|
||||
#define xc 240
|
||||
#define yc 100
|
||||
|
||||
IDD_FOLDERS MY_PAGE
|
||||
|
||||
@@ -36,6 +36,21 @@ FOLDER_INTERFACE(IFolderFolder, 0x00)
|
||||
INTERFACE_FolderFolder(PURE)
|
||||
};
|
||||
|
||||
/*
|
||||
IFolderAltStreams::
|
||||
BindToAltStreams((UInt32)(Int32)-1, ... ) means alt streams of that folder
|
||||
*/
|
||||
|
||||
#define INTERFACE_FolderAltStreams(x) \
|
||||
STDMETHOD(BindToAltStreams)(UInt32 index, IFolderFolder **resultFolder) x; \
|
||||
STDMETHOD(BindToAltStreams)(const wchar_t *name, IFolderFolder **resultFolder) x; \
|
||||
STDMETHOD(AreAltStreamsSupported)(UInt32 index, Int32 *isSupported) x; \
|
||||
|
||||
FOLDER_INTERFACE(IFolderAltStreams, 0x17)
|
||||
{
|
||||
INTERFACE_FolderAltStreams(PURE)
|
||||
};
|
||||
|
||||
FOLDER_INTERFACE(IFolderWasChanged, 0x04)
|
||||
{
|
||||
STDMETHOD(WasChanged)(Int32 *wasChanged) PURE;
|
||||
@@ -67,7 +82,7 @@ FOLDER_INTERFACE_SUB(IFolderOperationsExtractCallback, IProgress, 0x0B)
|
||||
Int32 includeAltStreams, Int32 replaceAltStreamCharsMode, \
|
||||
const wchar_t *path, IFolderOperationsExtractCallback *callback) x; \
|
||||
STDMETHOD(CopyFrom)(Int32 moveMode, const wchar_t *fromFolderPath, \
|
||||
const wchar_t **itemsPaths, UInt32 numItems, IProgress *progress) x; \
|
||||
const wchar_t * const *itemsPaths, UInt32 numItems, IProgress *progress) x; \
|
||||
STDMETHOD(SetProperty)(UInt32 index, PROPID propID, const PROPVARIANT *value, IProgress *progress) x; \
|
||||
STDMETHOD(CopyFromFile)(UInt32 index, const wchar_t *fullFilePath, IProgress *progress) x; \
|
||||
|
||||
|
||||
@@ -63,8 +63,7 @@ bool CLangPage::OnInit()
|
||||
|
||||
if (!LangOpen(lang, dirPrefix + fi.Name))
|
||||
{
|
||||
if (!error.IsEmpty())
|
||||
error += L' ';
|
||||
error.Add_Space_if_NotEmpty();
|
||||
error += fs2us(fi.Name);
|
||||
continue;
|
||||
}
|
||||
@@ -80,7 +79,7 @@ bool CLangPage::OnInit()
|
||||
index = (int)_langCombo.AddString(s);
|
||||
_langCombo.SetItemData(index, _paths.Size());
|
||||
_paths.Add(shortName);
|
||||
if (g_LangID.IsEqualToNoCase(shortName))
|
||||
if (g_LangID.IsEqualTo_NoCase(shortName))
|
||||
_langCombo.SetCurSel(index);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "LangPageRes.h"
|
||||
#include "../../GuiCommon.rc"
|
||||
|
||||
#define xc 148
|
||||
#define xc 160
|
||||
#define yc 100
|
||||
|
||||
IDD_LANG DIALOG 0, 0, xs, ys MY_PAGE_STYLE MY_FONT
|
||||
|
||||
@@ -115,6 +115,11 @@ UString LangString(UInt32 langID)
|
||||
return MyLoadString(langID);
|
||||
}
|
||||
|
||||
void AddLangString(UString &s, UInt32 langID)
|
||||
{
|
||||
s += LangString(langID);
|
||||
}
|
||||
|
||||
void LangString(UInt32 langID, UString &dest)
|
||||
{
|
||||
const wchar_t *s = g_Lang.Get(langID);
|
||||
@@ -166,7 +171,7 @@ static void FindShortNames(UInt32 primeLang, UStringVector &names)
|
||||
p++;
|
||||
}
|
||||
while (p != p2)
|
||||
s += (wchar_t)*p++;
|
||||
s += (wchar_t)(Byte)*p++;
|
||||
names.Add(s);
|
||||
}
|
||||
p = p2 + 1;
|
||||
|
||||
@@ -25,13 +25,15 @@ void LangSetDlgItems_Colon(HWND dialog, const UInt32 *ids, unsigned numItems);
|
||||
void LangSetWindowText(HWND window, UInt32 langID);
|
||||
|
||||
UString LangString(UInt32 langID);
|
||||
void AddLangString(UString &s, UInt32 langID);
|
||||
void LangString(UInt32 langID, UString &dest);
|
||||
void LangString_OnlyFromLangFile(UInt32 langID, UString &dest);
|
||||
|
||||
|
||||
#else
|
||||
|
||||
inline UString LangString(UInt32 langID) { return NWindows::MyLoadString(langID); }
|
||||
inline void LangString(UInt32 langID, UString &dest) { NWindows::MyLoadString(langID, dest); }
|
||||
inline void AddLangString(UString &s, UInt32 langID) { s += NWindows::MyLoadString(langID); }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -321,14 +321,14 @@ void CApp::Link()
|
||||
int index = indices[0];
|
||||
const UString itemName = srcPanel.GetItemName(index);
|
||||
|
||||
UString srcPath = srcPanel._currentFolderPrefix + srcPanel.GetItemPrefix(index);
|
||||
UString srcPath = srcPanel.GetFsPath() + srcPanel.GetItemPrefix(index);
|
||||
UString path = srcPath;
|
||||
{
|
||||
int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
|
||||
CPanel &destPanel = Panels[destPanelIndex];
|
||||
if (NumPanels > 1)
|
||||
if (destPanel.IsFSFolder())
|
||||
path = destPanel._currentFolderPrefix;
|
||||
path = destPanel.GetFsPath();
|
||||
}
|
||||
|
||||
CLinkDialog dlg;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "MenuPageRes.h"
|
||||
#include "../../GuiCommon.rc"
|
||||
|
||||
#define xc 196
|
||||
#define xc 240
|
||||
#define yc 196
|
||||
|
||||
IDD_MENU MY_PAGE
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "App.h"
|
||||
#include "HelpUtils.h"
|
||||
#include "LangUtils.h"
|
||||
#include "MyLoadMenu.h"
|
||||
#include "RegistryUtils.h"
|
||||
|
||||
#include "resource.h"
|
||||
@@ -100,19 +101,19 @@ public:
|
||||
#define MIIM_FTYPE 0x00000100
|
||||
#endif
|
||||
|
||||
static UINT Get_fMaskForString()
|
||||
static UINT Get_fMask_for_String()
|
||||
{
|
||||
return g_IsNew_fMask ? MIIM_STRING : MIIM_TYPE;
|
||||
}
|
||||
|
||||
static UINT Get_fMaskForFTypeAndString()
|
||||
static UINT Get_fMask_for_FType_and_String()
|
||||
{
|
||||
return g_IsNew_fMask ? (MIIM_STRING | MIIM_FTYPE) : MIIM_TYPE;
|
||||
}
|
||||
*/
|
||||
|
||||
static inline UINT Get_fMaskForString() { return MIIM_TYPE; }
|
||||
static inline UINT Get_fMaskForFTypeAndString() { return MIIM_TYPE; }
|
||||
static inline UINT Get_fMask_for_String() { return MIIM_TYPE; }
|
||||
static inline UINT Get_fMask_for_FType_and_String() { return MIIM_TYPE; }
|
||||
|
||||
static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex)
|
||||
{
|
||||
@@ -121,7 +122,7 @@ static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex)
|
||||
for (int i = 0;; i++)
|
||||
{
|
||||
CMenuItem item;
|
||||
item.fMask = Get_fMaskForString() | MIIM_SUBMENU | MIIM_ID;
|
||||
item.fMask = Get_fMask_for_String() | MIIM_SUBMENU | MIIM_ID;
|
||||
item.fType = MFT_STRING;
|
||||
if (!menu.GetItem(i, true, item))
|
||||
break;
|
||||
@@ -157,14 +158,13 @@ static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex)
|
||||
if (newString.IsEmpty())
|
||||
continue;
|
||||
|
||||
UString shorcutString = item.StringValue;
|
||||
int tabPos = shorcutString.ReverseFind(wchar_t('\t'));
|
||||
int tabPos = item.StringValue.ReverseFind(L'\t');
|
||||
if (tabPos >= 0)
|
||||
newString += shorcutString.Ptr(tabPos);
|
||||
newString += item.StringValue.Ptr(tabPos);
|
||||
}
|
||||
{
|
||||
item.StringValue = newString;
|
||||
item.fMask = Get_fMaskForString();
|
||||
item.fMask = Get_fMask_for_String();
|
||||
item.fType = MFT_STRING;
|
||||
menu.SetItem(i, true, item);
|
||||
}
|
||||
@@ -203,7 +203,7 @@ static void CopyMenu(HMENU srcMenuSpec, HMENU destMenuSpec)
|
||||
for (int i = 0;; i++)
|
||||
{
|
||||
CMenuItem item;
|
||||
item.fMask = MIIM_SUBMENU | MIIM_STATE | MIIM_ID | Get_fMaskForFTypeAndString();
|
||||
item.fMask = MIIM_SUBMENU | MIIM_STATE | MIIM_ID | Get_fMask_for_FType_and_String();
|
||||
item.fType = MFT_STRING;
|
||||
|
||||
if (!srcMenu.GetItem(i, true, item))
|
||||
@@ -307,13 +307,14 @@ void OnMenuActivating(HWND /* hWnd */, HMENU hMenu, int position)
|
||||
subMenu.Attach(menu.GetSubMenu(0));
|
||||
subMenu.RemoveAllItems();
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
UString s = LangString(IDS_BOOKMARK);
|
||||
s += L' ';
|
||||
s.Add_Space();
|
||||
wchar_t c = (wchar_t)(L'0' + i);
|
||||
s += c;
|
||||
s += L"\tAlt+Shift+";
|
||||
s.AddAscii("\tAlt+Shift+");
|
||||
s += c;
|
||||
subMenu.AppendItem(MF_STRING, kSetBookmarkMenuID + i, s);
|
||||
}
|
||||
@@ -332,7 +333,7 @@ void OnMenuActivating(HWND /* hWnd */, HMENU hMenu, int position)
|
||||
}
|
||||
if (s.IsEmpty())
|
||||
s = L'-';
|
||||
s += L"\tAlt+";
|
||||
s.AddAscii("\tAlt+");
|
||||
s += (wchar_t)(L'0' + i);
|
||||
menu.AppendItem(MF_STRING, kOpenBookmarkMenuID + i, s);
|
||||
}
|
||||
@@ -348,8 +349,7 @@ void OnMenuUnActivating(HWND hWnd, HMENU hMenu, int id)
|
||||
}
|
||||
*/
|
||||
|
||||
void LoadFileMenu(HMENU hMenu, int startPos, bool programMenu,
|
||||
bool isFsFolder, int numItems, bool allAreFiles)
|
||||
void CFileMenu::Load(HMENU hMenu, unsigned startPos)
|
||||
{
|
||||
CMenu destMenu;
|
||||
destMenu.Attach(hMenu);
|
||||
@@ -357,15 +357,17 @@ void LoadFileMenu(HMENU hMenu, int startPos, bool programMenu,
|
||||
UString diffPath;
|
||||
ReadRegDiff(diffPath);
|
||||
|
||||
int numRealItems = startPos;
|
||||
for (int i = 0;; i++)
|
||||
unsigned numRealItems = startPos;
|
||||
for (unsigned i = 0;; i++)
|
||||
{
|
||||
CMenuItem item;
|
||||
|
||||
item.fMask = MIIM_SUBMENU | MIIM_STATE | MIIM_ID | Get_fMaskForFTypeAndString();
|
||||
item.fMask = MIIM_SUBMENU | MIIM_STATE | MIIM_ID | Get_fMask_for_FType_and_String();
|
||||
item.fType = MFT_STRING;
|
||||
|
||||
if (!g_FileMenu.GetItem(i, true, item))
|
||||
break;
|
||||
|
||||
{
|
||||
if (!programMenu && item.wID == IDCLOSE)
|
||||
continue;
|
||||
@@ -376,6 +378,26 @@ void LoadFileMenu(HMENU hMenu, int startPos, bool programMenu,
|
||||
bool isOneFsFile = (isFsFolder && numItems == 1 && allAreFiles);
|
||||
bool disable = (!isOneFsFile && (item.wID == IDM_SPLIT || item.wID == IDM_COMBINE));
|
||||
|
||||
if (readOnly)
|
||||
{
|
||||
switch (item.wID)
|
||||
{
|
||||
case IDM_RENAME:
|
||||
case IDM_MOVE_TO:
|
||||
case IDM_DELETE:
|
||||
case IDM_COMMENT:
|
||||
case IDM_CREATE_FOLDER:
|
||||
case IDM_CREATE_FILE:
|
||||
disable = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (item.wID == IDM_LINK && numItems != 1)
|
||||
disable = true;
|
||||
|
||||
if (item.wID == IDM_ALT_STREAMS)
|
||||
disable = !isAltStreamsSupported;
|
||||
|
||||
bool isBigScreen = NControl::IsDialogSizeOK(40, 200);
|
||||
|
||||
if (!isBigScreen && (disable || item.IsSeparator()))
|
||||
@@ -434,6 +456,7 @@ bool ExecuteFileCommand(int id)
|
||||
case IDM_CREATE_FILE: g_App.CreateFile(); break;
|
||||
#ifndef UNDER_CE
|
||||
case IDM_LINK: g_App.Link(); break;
|
||||
case IDM_ALT_STREAMS: g_App.OpenAltStreams(); break;
|
||||
#endif
|
||||
default: return false;
|
||||
}
|
||||
|
||||
@@ -9,8 +9,28 @@ void OnMenuActivating(HWND hWnd, HMENU hMenu, int position);
|
||||
|
||||
bool OnMenuCommand(HWND hWnd, int id);
|
||||
void MyLoadMenu();
|
||||
void LoadFileMenu(HMENU hMenu, int startPos, bool programMenu,
|
||||
bool isFsFolder, int numItems, bool allAreFiles);
|
||||
|
||||
struct CFileMenu
|
||||
{
|
||||
bool programMenu;
|
||||
bool readOnly;
|
||||
bool isFsFolder;
|
||||
bool allAreFiles;
|
||||
bool isAltStreamsSupported;
|
||||
int numItems;
|
||||
|
||||
CFileMenu():
|
||||
programMenu(false),
|
||||
readOnly(false),
|
||||
isFsFolder(false),
|
||||
allAreFiles(false),
|
||||
isAltStreamsSupported(true),
|
||||
numItems(0)
|
||||
{}
|
||||
|
||||
void Load(HMENU hMenu, unsigned startPos);
|
||||
};
|
||||
|
||||
bool ExecuteFileCommand(int id);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -73,7 +73,15 @@ void CNetFolder::Init(const NWindows::NNet::CResourceW *netResource,
|
||||
_netResourcePointer = &_netResource;
|
||||
|
||||
// if (_netResource.DisplayType == RESOURCEDISPLAYTYPE_SERVER)
|
||||
_path = _netResource.RemoteName + WCHAR_PATH_SEPARATOR;
|
||||
_path = _netResource.RemoteName;
|
||||
|
||||
/* WinXP-64: When we move UP from Network share without _parentFolder chain,
|
||||
we can get empty _netResource.RemoteName. Do we need to use Provider there ? */
|
||||
if (_path.IsEmpty())
|
||||
_path = _netResource.Provider;
|
||||
|
||||
if (!_path.IsEmpty())
|
||||
_path.Add_PathSepar();
|
||||
}
|
||||
_parentFolder = parentFolder;
|
||||
}
|
||||
@@ -111,7 +119,7 @@ STDMETHODIMP CNetFolder::LoadItems()
|
||||
if (!resource.RemoteNameIsDefined) // For Win 98, I don't know what's wrong
|
||||
resource.RemoteName = resource.Comment;
|
||||
resource.Name = resource.RemoteName;
|
||||
int pos = resource.Name.ReverseFind(WCHAR_PATH_SEPARATOR);
|
||||
int pos = resource.Name.ReverseFind_PathSepar();
|
||||
if (pos >= 0)
|
||||
{
|
||||
// _path = resource.Name.Left(pos + 1);
|
||||
@@ -186,7 +194,7 @@ STDMETHODIMP CNetFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder
|
||||
{
|
||||
NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder;
|
||||
CMyComPtr<IFolderFolder> subFolder = fsFolderSpec;
|
||||
RINOK(fsFolderSpec->Init(us2fs(resource.RemoteName + WCHAR_PATH_SEPARATOR), this));
|
||||
RINOK(fsFolderSpec->Init(us2fs(resource.RemoteName + WCHAR_PATH_SEPARATOR))); // , this
|
||||
*resultFolder = subFolder.Detach();
|
||||
}
|
||||
else
|
||||
@@ -237,7 +245,7 @@ STDMETHODIMP CNetFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
{
|
||||
case kpidType: prop = L"NetFolder"; break;
|
||||
case kpidType: prop = "NetFolder"; break;
|
||||
case kpidPath: prop = _path; break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
|
||||
@@ -50,7 +50,7 @@ void COverwriteDialog::SetFileInfoControl(int textID, int iconID,
|
||||
sizeString = MyFormatNew(IDS_FILE_SIZE, NumberToString(fileInfo.Size));
|
||||
|
||||
const UString &fileName = fileInfo.Name;
|
||||
int slashPos = fileName.ReverseFind(WCHAR_PATH_SEPARATOR);
|
||||
int slashPos = fileName.ReverseFind_PathSepar();
|
||||
UString s1 = fileName.Left(slashPos + 1);
|
||||
UString s2 = fileName.Ptr(slashPos + 1);
|
||||
|
||||
@@ -58,18 +58,18 @@ void COverwriteDialog::SetFileInfoControl(int textID, int iconID,
|
||||
ReduceString(s2);
|
||||
|
||||
UString s = s1;
|
||||
s += L'\n';
|
||||
s.Add_LF();
|
||||
s += s2;
|
||||
s += L'\n';
|
||||
s.Add_LF();
|
||||
s += sizeString;
|
||||
s += L'\n';
|
||||
s.Add_LF();
|
||||
|
||||
if (fileInfo.TimeIsDefined)
|
||||
{
|
||||
FILETIME localFileTime;
|
||||
if (!FileTimeToLocalFileTime(&fileInfo.Time, &localFileTime))
|
||||
throw 4190402;
|
||||
s += LangString(IDS_PROP_MTIME);
|
||||
AddLangString(s, IDS_PROP_MTIME);
|
||||
s += L": ";
|
||||
wchar_t t[32];
|
||||
ConvertFileTimeToString(localFileTime, t);
|
||||
|
||||
@@ -477,7 +477,7 @@ bool CPanel::OnCreate(CREATESTRUCT * /* createStruct */)
|
||||
_comboBoxEdit.SetUserDataLongPtr(LONG_PTR(&_comboBoxEdit));
|
||||
_comboBoxEdit._panel = this;
|
||||
#ifndef _UNICODE
|
||||
if(g_IsNT)
|
||||
if (g_IsNT)
|
||||
_comboBoxEdit._origWindowProc =
|
||||
(WNDPROC)_comboBoxEdit.SetLongPtrW(GWLP_WNDPROC, LONG_PTR(ComboBoxEditSubclassProc));
|
||||
else
|
||||
@@ -675,7 +675,7 @@ void CPanel::MessageBoxError2Lines(LPCWSTR message, HRESULT errorCode)
|
||||
UString m = message;
|
||||
if (errorCode != 0)
|
||||
{
|
||||
m += L'\n';
|
||||
m.Add_LF();
|
||||
m += HResultToMessage(errorCode);
|
||||
}
|
||||
MessageBoxMyError(m);
|
||||
@@ -708,29 +708,32 @@ void CPanel::SetFocusToLastRememberedItem()
|
||||
|
||||
UString CPanel::GetFolderTypeID() const
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
if (_folder->GetFolderProperty(kpidType, &prop) == S_OK)
|
||||
if (prop.vt == VT_BSTR)
|
||||
return (const wchar_t *)prop.bstrVal;
|
||||
return L"";
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
if (_folder->GetFolderProperty(kpidType, &prop) == S_OK)
|
||||
if (prop.vt == VT_BSTR)
|
||||
return (const wchar_t *)prop.bstrVal;
|
||||
}
|
||||
return UString();
|
||||
}
|
||||
|
||||
bool CPanel::IsFolderTypeEqTo(const wchar_t *s) const
|
||||
bool CPanel::IsFolderTypeEqTo(const char *s) const
|
||||
{
|
||||
return GetFolderTypeID() == s;
|
||||
return StringsAreEqual_Ascii(GetFolderTypeID(), s);
|
||||
}
|
||||
|
||||
bool CPanel::IsRootFolder() const { return IsFolderTypeEqTo(L"RootFolder"); }
|
||||
bool CPanel::IsFSFolder() const { return IsFolderTypeEqTo(L"FSFolder"); }
|
||||
bool CPanel::IsFSDrivesFolder() const { return IsFolderTypeEqTo(L"FSDrives"); }
|
||||
bool CPanel::IsRootFolder() const { return IsFolderTypeEqTo("RootFolder"); }
|
||||
bool CPanel::IsFSFolder() const { return IsFolderTypeEqTo("FSFolder"); }
|
||||
bool CPanel::IsFSDrivesFolder() const { return IsFolderTypeEqTo("FSDrives"); }
|
||||
bool CPanel::IsAltStreamsFolder() const { return IsFolderTypeEqTo("AltStreamsFolder"); }
|
||||
bool CPanel::IsArcFolder() const
|
||||
{
|
||||
return GetFolderTypeID().IsPrefixedBy(L"7-Zip");
|
||||
return GetFolderTypeID().IsPrefixedBy_Ascii_NoCase("7-Zip");
|
||||
}
|
||||
|
||||
UString CPanel::GetFsPath() const
|
||||
{
|
||||
if (IsFSDrivesFolder() && !IsDeviceDrivesPrefix())
|
||||
if (IsFSDrivesFolder() && !IsDeviceDrivesPrefix() && !IsSuperDrivesPrefix())
|
||||
return UString();
|
||||
return _currentFolderPrefix;
|
||||
}
|
||||
@@ -744,12 +747,6 @@ UString CPanel::GetDriveOrNetworkPrefix() const
|
||||
return drive;
|
||||
}
|
||||
|
||||
bool CPanel::DoesItSupportOperations() const
|
||||
{
|
||||
CMyComPtr<IFolderOperations> folderOperations;
|
||||
return _folder.QueryInterface(IID_IFolderOperations, &folderOperations) == S_OK;
|
||||
}
|
||||
|
||||
void CPanel::SetListViewMode(UInt32 index)
|
||||
{
|
||||
if (index >= 4)
|
||||
@@ -805,7 +802,7 @@ void CPanel::AddToArchive()
|
||||
{
|
||||
CRecordVector<UInt32> indices;
|
||||
GetOperatedItemIndices(indices);
|
||||
if (!IsFsOrDrivesFolder())
|
||||
if (!Is_IO_FS_Folder())
|
||||
{
|
||||
MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
|
||||
return;
|
||||
@@ -817,20 +814,16 @@ void CPanel::AddToArchive()
|
||||
}
|
||||
UStringVector names;
|
||||
|
||||
UString curPrefix = _currentFolderPrefix;
|
||||
UString destCurDirPrefix = _currentFolderPrefix;
|
||||
const UString curPrefix = GetFsPath();
|
||||
UString destCurDirPrefix = curPrefix;
|
||||
if (IsFSDrivesFolder())
|
||||
{
|
||||
destCurDirPrefix = ROOT_FS_FOLDER;
|
||||
if (!IsDeviceDrivesPrefix())
|
||||
curPrefix.Empty();
|
||||
}
|
||||
|
||||
FOR_VECTOR (i, indices)
|
||||
names.Add(curPrefix + GetItemRelPath(indices[i]));
|
||||
names.Add(curPrefix + GetItemRelPath2(indices[i]));
|
||||
bool fromPrev = (names.Size() > 1);
|
||||
const UString archiveName = CreateArchiveName(names.Front(), fromPrev, false);
|
||||
HRESULT res = CompressFiles(destCurDirPrefix, archiveName, L"",
|
||||
const UString arcName = CreateArchiveName(names.Front(), fromPrev, false);
|
||||
HRESULT res = CompressFiles(destCurDirPrefix, arcName, L"",
|
||||
true, // addExtension
|
||||
names, false, true, false);
|
||||
if (res != S_OK)
|
||||
@@ -841,23 +834,24 @@ void CPanel::AddToArchive()
|
||||
// KillSelection();
|
||||
}
|
||||
|
||||
static UString GetSubFolderNameForExtract(const UString &archiveName)
|
||||
static UString GetSubFolderNameForExtract(const UString &arcPath)
|
||||
{
|
||||
UString res = archiveName;
|
||||
int slashPos = res.ReverseFind(WCHAR_PATH_SEPARATOR);
|
||||
int dotPos = res.ReverseFind(L'.');
|
||||
if (dotPos < 0 || slashPos > dotPos)
|
||||
res += L'~';
|
||||
UString s = arcPath;
|
||||
int slashPos = s.ReverseFind_PathSepar();
|
||||
int dotPos = s.ReverseFind_Dot();
|
||||
if (dotPos <= slashPos + 1)
|
||||
s += L'~';
|
||||
else
|
||||
{
|
||||
res.DeleteFrom(dotPos);
|
||||
res.TrimRight();
|
||||
s.DeleteFrom(dotPos);
|
||||
s.TrimRight();
|
||||
}
|
||||
return res;
|
||||
return s;
|
||||
}
|
||||
|
||||
void CPanel::GetFilePaths(const CRecordVector<UInt32> &indices, UStringVector &paths, bool allowFolders)
|
||||
{
|
||||
const UString prefix = GetFsPath();
|
||||
FOR_VECTOR (i, indices)
|
||||
{
|
||||
int index = indices[i];
|
||||
@@ -866,7 +860,7 @@ void CPanel::GetFilePaths(const CRecordVector<UInt32> &indices, UStringVector &p
|
||||
paths.Clear();
|
||||
break;
|
||||
}
|
||||
paths.Add(GetItemFullPath(index));
|
||||
paths.Add(prefix + GetItemRelPath2(index));
|
||||
}
|
||||
if (paths.Size() == 0)
|
||||
{
|
||||
@@ -888,26 +882,31 @@ void CPanel::ExtractArchives()
|
||||
GetFilePaths(indices, paths);
|
||||
if (paths.IsEmpty())
|
||||
return;
|
||||
UString folderName;
|
||||
|
||||
UString outFolder = GetFsPath();
|
||||
if (indices.Size() == 1)
|
||||
folderName = GetSubFolderNameForExtract(GetItemRelPath(indices[0]));
|
||||
outFolder += GetSubFolderNameForExtract(GetItemRelPath(indices[0]));
|
||||
else
|
||||
folderName = L"*";
|
||||
::ExtractArchives(paths, _currentFolderPrefix + folderName + UString(WCHAR_PATH_SEPARATOR)
|
||||
outFolder += L'*';
|
||||
outFolder.Add_PathSepar();
|
||||
|
||||
::ExtractArchives(paths, outFolder
|
||||
, true // showDialog
|
||||
, false // elimDup
|
||||
);
|
||||
}
|
||||
|
||||
void AddValuePair(UINT resourceID, UInt64 value, UString &s)
|
||||
/*
|
||||
static void AddValuePair(UINT resourceID, UInt64 value, UString &s)
|
||||
{
|
||||
wchar_t sz[32];
|
||||
s += LangString(resourceID);
|
||||
AddLangString(s, resourceID);
|
||||
char sz[32];
|
||||
s += L": ";
|
||||
ConvertUInt64ToString(value, sz);
|
||||
s += sz;
|
||||
s += L'\n';
|
||||
s.AddAsciiStr(sz);
|
||||
s.Add_LF();
|
||||
}
|
||||
*/
|
||||
|
||||
class CThreadTest: public CProgressThreadVirt
|
||||
{
|
||||
@@ -939,8 +938,8 @@ HRESULT CThreadTest::ProcessVirt()
|
||||
AddValuePair(IDS_PROP_FILES, ExtractCallbackSpec->NumFiles, s);
|
||||
// AddValuePair(IDS_PROP_SIZE, ExtractCallbackSpec->UnpackSize, s);
|
||||
// AddSizePair(IDS_COMPRESSED_COLON, Stat.PackSize, s);
|
||||
s += L'\n';
|
||||
s += LangString(IDS_MESSAGE_NO_ERRORS);
|
||||
s.Add_LF();
|
||||
AddLangString(s, IDS_MESSAGE_NO_ERRORS);
|
||||
FinalMessage.OkMessage.Message = s;
|
||||
}
|
||||
return S_OK;
|
||||
@@ -948,18 +947,18 @@ HRESULT CThreadTest::ProcessVirt()
|
||||
*/
|
||||
|
||||
/*
|
||||
static void AddSizePair(UINT resourceID, UInt32 langID, UInt64 value, UString &s)
|
||||
static void AddSizePair(UInt32 langID, UInt64 value, UString &s)
|
||||
{
|
||||
wchar_t sz[32];
|
||||
s += LangString(resourceID, langID);
|
||||
char sz[32];
|
||||
AddLangString(s, langID);
|
||||
s += L' ';
|
||||
ConvertUInt64ToString(value, sz);
|
||||
s += sz;
|
||||
s.AddAsciiStr(sz);
|
||||
ConvertUInt64ToString(value >> 20, sz);
|
||||
s += L" (";
|
||||
s += sz;
|
||||
s += L" MB)";
|
||||
s += L'\n';
|
||||
s.AddAsciiStr(" (");
|
||||
s.AddAsciiStr(sz);
|
||||
s.AddAsciiStr(" MB)");
|
||||
s.Add_LF();
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "../../../Windows/DLL.h"
|
||||
#include "../../../Windows/FileDir.h"
|
||||
#include "../../../Windows/FileFind.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
#include "../../../Windows/Handle.h"
|
||||
#include "../../../Windows/Synchronization.h"
|
||||
|
||||
@@ -43,10 +44,10 @@ const int kParentFolderID = 100;
|
||||
|
||||
const int kParentIndex = -1;
|
||||
|
||||
#ifdef UNDER_CE
|
||||
#if !defined(_WIN32) || defined(UNDER_CE)
|
||||
#define ROOT_FS_FOLDER L"\\"
|
||||
#else
|
||||
#define ROOT_FS_FOLDER L"C:\\\\"
|
||||
#define ROOT_FS_FOLDER L"C:\\"
|
||||
#endif
|
||||
|
||||
struct CPanelCallback
|
||||
@@ -117,12 +118,13 @@ struct CTempFileInfo
|
||||
struct CFolderLink: public CTempFileInfo
|
||||
{
|
||||
NWindows::NDLL::CLibrary Library;
|
||||
CMyComPtr<IFolderFolder> ParentFolder;
|
||||
CMyComPtr<IFolderFolder> ParentFolder; // can be NULL, if parent is FS folder (in _parentFolders[0])
|
||||
UString ParentFolderPath; // including tail slash (doesn't include paths parts of parent in next level)
|
||||
bool UsePassword;
|
||||
UString Password;
|
||||
bool IsVirtual;
|
||||
|
||||
UString VirtualPath;
|
||||
UString VirtualPath; // without tail slash
|
||||
CFolderLink(): UsePassword(false), IsVirtual(false) {}
|
||||
|
||||
bool WasChanged(const NWindows::NFile::NFind::CFileInfo &newFileInfo) const
|
||||
@@ -146,7 +148,7 @@ enum MyMessages
|
||||
#endif
|
||||
};
|
||||
|
||||
UString GetFolderPath(IFolderFolder * folder);
|
||||
UString GetFolderPath(IFolderFolder *folder);
|
||||
|
||||
class CPanel;
|
||||
|
||||
@@ -380,27 +382,11 @@ public:
|
||||
CMyComPtr<IFolderCompare> _folderCompare;
|
||||
CMyComPtr<IFolderGetItemName> _folderGetItemName;
|
||||
CMyComPtr<IArchiveGetRawProps> _folderRawProps;
|
||||
CMyComPtr<IFolderAltStreams> _folderAltStreams;
|
||||
CMyComPtr<IFolderOperations> _folderOperations;
|
||||
|
||||
void ReleaseFolder()
|
||||
{
|
||||
_folderCompare.Release();
|
||||
_folderGetItemName.Release();
|
||||
_folderRawProps.Release();
|
||||
_folder.Release();
|
||||
_thereAreDeletedItems = false;
|
||||
}
|
||||
|
||||
void SetNewFolder(IFolderFolder *newFolder)
|
||||
{
|
||||
ReleaseFolder();
|
||||
_folder = newFolder;
|
||||
if (_folder)
|
||||
{
|
||||
_folder.QueryInterface(IID_IFolderCompare, &_folderCompare);
|
||||
_folder.QueryInterface(IID_IFolderGetItemName, &_folderGetItemName);
|
||||
_folder.QueryInterface(IID_IArchiveGetRawProps, &_folderRawProps);
|
||||
}
|
||||
}
|
||||
void ReleaseFolder();
|
||||
void SetNewFolder(IFolderFolder *newFolder);
|
||||
|
||||
// CMyComPtr<IFolderGetSystemIconIndex> _folderGetSystemIconIndex;
|
||||
|
||||
@@ -417,9 +403,11 @@ public:
|
||||
bool IsItem_AltStream(int itemIndex) const;
|
||||
|
||||
UString GetItemName(int itemIndex) const;
|
||||
void GetItemNameFast(int itemIndex, UString &s) const;
|
||||
UString GetItemName_for_Copy(int itemIndex) const;
|
||||
void GetItemName(int itemIndex, UString &s) const;
|
||||
UString GetItemPrefix(int itemIndex) const;
|
||||
UString GetItemRelPath(int itemIndex) const;
|
||||
UString GetItemRelPath2(int itemIndex) const;
|
||||
UString GetItemFullPath(int itemIndex) const;
|
||||
UInt64 GetItemSize(int itemIndex) const;
|
||||
|
||||
@@ -438,6 +426,7 @@ public:
|
||||
void LoadFullPathAndShow();
|
||||
void FoldersHistory();
|
||||
void OpenParentFolder();
|
||||
void CloseOneLevel();
|
||||
void CloseOpenFolders();
|
||||
void OpenRootFolder();
|
||||
|
||||
@@ -554,19 +543,65 @@ public:
|
||||
void KillSelection();
|
||||
|
||||
UString GetFolderTypeID() const;
|
||||
bool IsFolderTypeEqTo(const wchar_t *s) const;
|
||||
|
||||
bool IsFolderTypeEqTo(const char *s) const;
|
||||
bool IsRootFolder() const;
|
||||
bool IsFSFolder() const;
|
||||
bool IsFSDrivesFolder() const;
|
||||
bool IsAltStreamsFolder() const;
|
||||
bool IsArcFolder() const;
|
||||
bool IsFsOrDrivesFolder() const { return IsFSFolder() || IsFSDrivesFolder(); }
|
||||
|
||||
/*
|
||||
c:\Dir
|
||||
Computer\
|
||||
\\?\
|
||||
\\.\
|
||||
*/
|
||||
bool Is_IO_FS_Folder() const
|
||||
{
|
||||
return IsFSFolder() || IsFSDrivesFolder() || IsAltStreamsFolder();
|
||||
}
|
||||
|
||||
bool Is_Slow_Icon_Folder() const
|
||||
{
|
||||
return IsFSFolder() || IsAltStreamsFolder();
|
||||
}
|
||||
|
||||
// bool IsFsOrDrivesFolder() const { return IsFSFolder() || IsFSDrivesFolder(); }
|
||||
bool IsDeviceDrivesPrefix() const { return _currentFolderPrefix == L"\\\\.\\"; }
|
||||
bool IsSuperDrivesPrefix() const { return _currentFolderPrefix == L"\\\\?\\"; }
|
||||
|
||||
/*
|
||||
c:\Dir
|
||||
Computer\
|
||||
\\?\
|
||||
*/
|
||||
bool IsFsOrPureDrivesFolder() const { return IsFSFolder() || (IsFSDrivesFolder() && !IsDeviceDrivesPrefix()); }
|
||||
|
||||
/*
|
||||
c:\Dir
|
||||
Computer\
|
||||
\\?\
|
||||
\\SERVER\
|
||||
*/
|
||||
bool IsFolder_with_FsItems() const
|
||||
{
|
||||
if (IsFsOrPureDrivesFolder())
|
||||
return true;
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
FString prefix = us2fs(GetFsPath());
|
||||
return (prefix.Len() == NWindows::NFile::NName::GetNetworkServerPrefixSize(prefix));
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
UString GetFsPath() const;
|
||||
UString GetDriveOrNetworkPrefix() const;
|
||||
|
||||
bool DoesItSupportOperations() const;
|
||||
bool DoesItSupportOperations() const { return _folderOperations != NULL; }
|
||||
bool IsThereReadOnlyFolder() const;
|
||||
bool CheckBeforeUpdate(UINT resourceID);
|
||||
|
||||
bool _processTimer;
|
||||
bool _processNotify;
|
||||
@@ -574,58 +609,56 @@ public:
|
||||
|
||||
class CDisableTimerProcessing
|
||||
{
|
||||
bool _processTimerMem;
|
||||
CLASS_NO_COPY(CDisableTimerProcessing);
|
||||
|
||||
bool _processTimer;
|
||||
|
||||
CPanel &_panel;
|
||||
|
||||
CDisableTimerProcessing(const CDisableTimerProcessing &);
|
||||
CDisableTimerProcessing& operator=(const CDisableTimerProcessing &);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
CDisableTimerProcessing(CPanel &panel): _panel(panel) { Disable(); }
|
||||
~CDisableTimerProcessing() { Restore(); }
|
||||
void Disable()
|
||||
{
|
||||
_processTimerMem = _panel._processTimer;
|
||||
_processTimer = _panel._processTimer;
|
||||
_panel._processTimer = false;
|
||||
}
|
||||
void Restore()
|
||||
{
|
||||
_panel._processTimer = _processTimerMem;
|
||||
_panel._processTimer = _processTimer;
|
||||
}
|
||||
};
|
||||
|
||||
class CDisableNotify
|
||||
{
|
||||
bool _processNotifyMem;
|
||||
bool _processStatusBarMem;
|
||||
CLASS_NO_COPY(CDisableNotify);
|
||||
|
||||
bool _processNotify;
|
||||
bool _processStatusBar;
|
||||
|
||||
CPanel &_panel;
|
||||
|
||||
CDisableNotify(const CDisableNotify &);
|
||||
CDisableNotify& operator=(const CDisableNotify &);
|
||||
|
||||
public:
|
||||
|
||||
CDisableNotify(CPanel &panel): _panel(panel) { Disable(); }
|
||||
~CDisableNotify() { Restore(); }
|
||||
void Disable()
|
||||
{
|
||||
_processNotifyMem = _panel._processNotify;
|
||||
_processStatusBarMem = _panel._processStatusBar;
|
||||
_processNotify = _panel._processNotify;
|
||||
_processStatusBar = _panel._processStatusBar;
|
||||
_panel._processNotify = false;
|
||||
_panel._processStatusBar = false;
|
||||
}
|
||||
void SetMemMode_Enable()
|
||||
{
|
||||
_processNotifyMem = true;
|
||||
_processStatusBarMem = true;
|
||||
_processNotify = true;
|
||||
_processStatusBar = true;
|
||||
}
|
||||
void Restore()
|
||||
{
|
||||
_panel._processNotify = _processNotifyMem;
|
||||
_panel._processStatusBar = _processStatusBarMem;
|
||||
_panel._processNotify = _processNotify;
|
||||
_panel._processStatusBar = _processStatusBar;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -647,10 +680,12 @@ public:
|
||||
void MessageBoxLastError(LPCWSTR caption);
|
||||
void MessageBoxLastError();
|
||||
|
||||
void MessageBoxErrorForUpdate(HRESULT errorCode, UINT resourceID);
|
||||
// void MessageBoxErrorForUpdate(HRESULT errorCode, UINT resourceID);
|
||||
|
||||
void MessageBoxErrorLang(UINT resourceID);
|
||||
|
||||
void OpenAltStreams();
|
||||
|
||||
void OpenFocusedItemAsInternal();
|
||||
void OpenSelectedItems(bool internal);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// PanelExtract.cpp
|
||||
/// PanelCopy.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
@@ -79,18 +79,25 @@ HRESULT CPanelCopyThread::ProcessVirt()
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
#ifdef EXTERNAL_CODECS
|
||||
|
||||
static void ThrowException_if_Error(HRESULT res)
|
||||
{
|
||||
if (res != S_OK)
|
||||
throw CSystemException(res);
|
||||
}
|
||||
|
||||
#endif
|
||||
*/
|
||||
|
||||
|
||||
HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &indices,
|
||||
UStringVector *messages,
|
||||
bool &usePassword, UString &password)
|
||||
{
|
||||
CMyComPtr<IFolderOperations> folderOperations;
|
||||
if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
|
||||
if (!_folderOperations)
|
||||
{
|
||||
UString errorMessage = LangString(IDS_OPERATION_IS_NOT_SUPPORTED);
|
||||
if (options.showErrorMessages)
|
||||
@@ -100,8 +107,17 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
HRESULT res;
|
||||
HRESULT res = S_OK;
|
||||
|
||||
{
|
||||
/*
|
||||
#ifdef EXTERNAL_CODECS
|
||||
CExternalCodecs g_ExternalCodecs;
|
||||
#endif
|
||||
*/
|
||||
/* extracter.Hash uses g_ExternalCodecs
|
||||
extracter must be declared after g_ExternalCodecs for correct destructor order !!! */
|
||||
|
||||
CPanelCopyThread extracter;
|
||||
|
||||
extracter.ExtractCallbackSpec = new CExtractCallbackImp;
|
||||
@@ -113,11 +129,6 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
|
||||
|
||||
extracter.ExtractCallbackSpec->StreamMode = options.streamMode;
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
CExternalCodecs __externalCodecs;
|
||||
#else
|
||||
CMyComPtr<IUnknown> compressCodecsInfo;
|
||||
#endif
|
||||
|
||||
if (indices.Size() == 1)
|
||||
extracter.FirstFilePath = GetItemRelPath(indices[0]);
|
||||
@@ -131,19 +142,16 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
|
||||
|
||||
if (!options.hashMethods.IsEmpty())
|
||||
{
|
||||
{
|
||||
CCodecs *codecs = new CCodecs;
|
||||
ThrowException_if_Error(codecs->Load());
|
||||
#ifdef EXTERNAL_CODECS
|
||||
__externalCodecs.GetCodecs = codecs;
|
||||
__externalCodecs.GetHashers = codecs;
|
||||
ThrowException_if_Error(__externalCodecs.LoadCodecs());
|
||||
#else
|
||||
compressCodecsInfo = codecs;
|
||||
#endif
|
||||
}
|
||||
/* this code is used when we call CRC calculation for files in side archive
|
||||
But new code uses global codecs so we don't need to call LoadGlobalCodecs again */
|
||||
|
||||
extracter.Hash.SetMethods(EXTERNAL_CODECS_VARS options.hashMethods);
|
||||
/*
|
||||
#ifdef EXTERNAL_CODECS
|
||||
ThrowException_if_Error(LoadGlobalCodecs());
|
||||
#endif
|
||||
*/
|
||||
|
||||
extracter.Hash.SetMethods(EXTERNAL_CODECS_VARS_G options.hashMethods);
|
||||
extracter.ExtractCallbackSpec->SetHashMethods(&extracter.Hash);
|
||||
}
|
||||
else if (options.testMode)
|
||||
@@ -153,7 +161,6 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
|
||||
|
||||
extracter.Hash.Init();
|
||||
|
||||
|
||||
UString title;
|
||||
{
|
||||
UInt32 titleID = IDS_COPYING;
|
||||
@@ -185,7 +192,7 @@ HRESULT CPanel::CopyTo(CCopyToOptions &options, const CRecordVector<UInt32> &ind
|
||||
extracter.ExtractCallbackSpec->OverwriteMode = NExtract::NOverwriteMode::kAsk;
|
||||
extracter.ExtractCallbackSpec->Init();
|
||||
extracter.Indices = indices;
|
||||
extracter.FolderOperations = folderOperations;
|
||||
extracter.FolderOperations = _folderOperations;
|
||||
|
||||
extracter.ExtractCallbackSpec->PasswordIsDefined = usePassword;
|
||||
extracter.ExtractCallbackSpec->Password = password;
|
||||
@@ -244,10 +251,8 @@ struct CThreadUpdate
|
||||
HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStringVector &filePaths,
|
||||
bool showErrorMessages, UStringVector *messages)
|
||||
{
|
||||
CMyComPtr<IFolderOperations> folderOperations;
|
||||
_folder.QueryInterface(IID_IFolderOperations, &folderOperations);
|
||||
HRESULT res;
|
||||
if (!folderOperations)
|
||||
if (!_folderOperations)
|
||||
res = E_NOINTERFACE;
|
||||
else
|
||||
{
|
||||
@@ -255,6 +260,7 @@ HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStri
|
||||
updater.MoveMode = moveMode;
|
||||
updater.UpdateCallbackSpec = new CUpdateCallback100Imp;
|
||||
updater.UpdateCallback = updater.UpdateCallbackSpec;
|
||||
updater.UpdateCallbackSpec->Init();
|
||||
|
||||
updater.UpdateCallbackSpec->ProgressDialog = &updater.ProgressDialog;
|
||||
|
||||
@@ -263,10 +269,18 @@ HRESULT CPanel::CopyFrom(bool moveMode, const UString &folderPrefix, const UStri
|
||||
|
||||
updater.ProgressDialog.MainWindow = GetParent();
|
||||
updater.ProgressDialog.MainTitle = progressWindowTitle;
|
||||
updater.ProgressDialog.MainAddTitle = title + UString(L' ');
|
||||
updater.ProgressDialog.MainAddTitle = title + L' ';
|
||||
|
||||
updater.UpdateCallbackSpec->Init(false, L"");
|
||||
updater.FolderOperations = folderOperations;
|
||||
{
|
||||
if (!_parentFolders.IsEmpty())
|
||||
{
|
||||
const CFolderLink &fl = _parentFolders.Back();
|
||||
updater.UpdateCallbackSpec->PasswordIsDefined = fl.UsePassword;
|
||||
updater.UpdateCallbackSpec->Password = fl.Password;
|
||||
}
|
||||
}
|
||||
|
||||
updater.FolderOperations = _folderOperations;
|
||||
updater.FolderPrefix = folderPrefix;
|
||||
updater.FileNames.ClearAndReserve(filePaths.Size());
|
||||
unsigned i;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "../../../Windows/FileFind.h"
|
||||
#include "../../../Windows/FileIO.h"
|
||||
#include "../../../Windows/FileName.h"
|
||||
|
||||
#include "../Common/LoadCodecs.h"
|
||||
|
||||
@@ -19,12 +20,18 @@
|
||||
using namespace NWindows;
|
||||
using namespace NFile;
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
extern CExternalCodecs g_ExternalCodecs;
|
||||
HRESULT LoadGlobalCodecs();
|
||||
#endif
|
||||
|
||||
static const UInt32 kBufSize = (1 << 15);
|
||||
|
||||
struct CDirEnumerator
|
||||
{
|
||||
bool EnterToDirs;
|
||||
FString BasePrefix;
|
||||
FString BasePrefix_for_Open;
|
||||
FStringVector FilePaths;
|
||||
|
||||
CObjectVector<NFind::CEnumerator> Enumerators;
|
||||
@@ -54,22 +61,27 @@ DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &r
|
||||
{
|
||||
filled = false;
|
||||
resPath.Empty();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
bool isRootPrefix = (BasePrefix.IsEmpty() || (NName::IsSuperPath(BasePrefix) && BasePrefix[NName::kSuperPathPrefixSize] == 0));
|
||||
#endif
|
||||
|
||||
if (Enumerators.IsEmpty())
|
||||
{
|
||||
if (Index >= FilePaths.Size())
|
||||
return S_OK;
|
||||
const FString &path = FilePaths[Index++];
|
||||
int pos = path.ReverseFind(FCHAR_PATH_SEPARATOR);
|
||||
int pos = path.ReverseFind_PathSepar();
|
||||
if (pos >= 0)
|
||||
resPath.SetFrom(path, pos + 1);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (BasePrefix.IsEmpty() && path.Len() == 2 && path[1] == ':')
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
if (isRootPrefix && path.Len() == 2 && NName::IsDrivePath2(path))
|
||||
{
|
||||
// we use "c:" item as directory item
|
||||
fi.Clear();
|
||||
fi.ClearBase();
|
||||
fi.Name = path;
|
||||
fi.SetAsDir();
|
||||
fi.Size = 0;
|
||||
@@ -82,9 +94,12 @@ DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &r
|
||||
resPath = path;
|
||||
return error;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
bool found;
|
||||
|
||||
if (Enumerators.Back().Next(fi, found))
|
||||
{
|
||||
if (found)
|
||||
@@ -101,18 +116,22 @@ DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &r
|
||||
Prefixes.DeleteBack();
|
||||
return error;
|
||||
}
|
||||
|
||||
Enumerators.DeleteBack();
|
||||
Prefixes.DeleteBack();
|
||||
}
|
||||
|
||||
resPath += fi.Name;
|
||||
|
||||
if (EnterToDirs && fi.IsDir())
|
||||
{
|
||||
FString s = resPath;
|
||||
s += FCHAR_PATH_SEPARATOR;
|
||||
s.Add_PathSepar();
|
||||
Prefixes.Add(s);
|
||||
s += FCHAR_ANY_MASK;
|
||||
Enumerators.Add(NFind::CEnumerator(BasePrefix + s));
|
||||
}
|
||||
|
||||
filled = true;
|
||||
return S_OK;
|
||||
}
|
||||
@@ -137,10 +156,9 @@ void CThreadCrc::AddErrorMessage(DWORD systemError, const FChar *name)
|
||||
void CThreadCrc::SetStatus(const UString &s2)
|
||||
{
|
||||
UString s = s2;
|
||||
if (Enumerator.BasePrefix)
|
||||
if (!Enumerator.BasePrefix.IsEmpty())
|
||||
{
|
||||
if (!s.IsEmpty())
|
||||
s += L' ';
|
||||
s.Add_Space_if_NotEmpty();
|
||||
s += fs2us(Enumerator.BasePrefix);
|
||||
}
|
||||
ProgressDialog.Sync.Set_Status(s);
|
||||
@@ -201,10 +219,10 @@ HRESULT CThreadCrc::ProcessVirt()
|
||||
*/
|
||||
if (needPrint)
|
||||
{
|
||||
RINOK(sync.ScanProgress(numFiles, totalSize, fs2us(path), fi.IsDir()));
|
||||
RINOK(sync.ScanProgress(numFiles, totalSize, path, fi.IsDir()));
|
||||
}
|
||||
}
|
||||
RINOK(sync.ScanProgress(numFiles, totalSize, L"", false));
|
||||
RINOK(sync.ScanProgress(numFiles, totalSize, FString(), false));
|
||||
// sync.SetNumFilesTotal(numFiles);
|
||||
// sync.SetProgress(totalSize, 0);
|
||||
// SetStatus(LangString(IDS_CHECKSUM_CALCULATING));
|
||||
@@ -235,7 +253,7 @@ HRESULT CThreadCrc::ProcessVirt()
|
||||
if (!fi.IsDir())
|
||||
{
|
||||
NIO::CInFile inFile;
|
||||
tempPath = Enumerator.BasePrefix;
|
||||
tempPath = Enumerator.BasePrefix_for_Open;
|
||||
tempPath += path;
|
||||
if (!inFile.Open(tempPath))
|
||||
{
|
||||
@@ -289,13 +307,8 @@ HRESULT CThreadCrc::ProcessVirt()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void ThrowException_if_Error(HRESULT res)
|
||||
{
|
||||
if (res != S_OK)
|
||||
throw CSystemException(res);
|
||||
}
|
||||
|
||||
void CApp::CalculateCrc(const UString &methodName)
|
||||
HRESULT CApp::CalculateCrc2(const UString &methodName)
|
||||
{
|
||||
int srcPanelIndex = GetFocusedPanelIndex();
|
||||
CPanel &srcPanel = Panels[srcPanelIndex];
|
||||
@@ -303,9 +316,9 @@ void CApp::CalculateCrc(const UString &methodName)
|
||||
CRecordVector<UInt32> indices;
|
||||
srcPanel.GetOperatedIndicesSmart(indices);
|
||||
if (indices.IsEmpty())
|
||||
return;
|
||||
return S_OK;
|
||||
|
||||
if (!srcPanel.IsFsOrDrivesFolder())
|
||||
if (!srcPanel.Is_IO_FS_Folder())
|
||||
{
|
||||
CCopyToOptions options;
|
||||
options.streamMode = true;
|
||||
@@ -313,27 +326,13 @@ void CApp::CalculateCrc(const UString &methodName)
|
||||
options.hashMethods.Add(methodName);
|
||||
|
||||
UStringVector messages;
|
||||
HRESULT res = srcPanel.CopyTo(options, indices, &messages);
|
||||
if (res != S_OK)
|
||||
{
|
||||
if (res != E_ABORT)
|
||||
srcPanel.MessageBoxError(res);
|
||||
}
|
||||
return;
|
||||
return srcPanel.CopyTo(options, indices, &messages);
|
||||
}
|
||||
|
||||
CCodecs *codecs = new CCodecs;
|
||||
#ifdef EXTERNAL_CODECS
|
||||
CExternalCodecs __externalCodecs;
|
||||
__externalCodecs.GetCodecs = codecs;
|
||||
__externalCodecs.GetHashers = codecs;
|
||||
#else
|
||||
CMyComPtr<IUnknown> compressCodecsInfo = codecs;
|
||||
#endif
|
||||
ThrowException_if_Error(codecs->Load());
|
||||
|
||||
#ifdef EXTERNAL_CODECS
|
||||
ThrowException_if_Error(__externalCodecs.LoadCodecs());
|
||||
LoadGlobalCodecs();
|
||||
|
||||
#endif
|
||||
|
||||
{
|
||||
@@ -341,11 +340,23 @@ void CApp::CalculateCrc(const UString &methodName)
|
||||
{
|
||||
UStringVector methods;
|
||||
methods.Add(methodName);
|
||||
t.Hash.SetMethods(EXTERNAL_CODECS_VARS methods);
|
||||
RINOK(t.Hash.SetMethods(EXTERNAL_CODECS_VARS_G methods));
|
||||
}
|
||||
FOR_VECTOR (i, indices)
|
||||
t.Enumerator.FilePaths.Add(us2fs(srcPanel.GetItemRelPath(indices[i])));
|
||||
t.Enumerator.BasePrefix = us2fs(srcPanel.GetFsPath());
|
||||
|
||||
UString basePrefix = srcPanel.GetFsPath();
|
||||
UString basePrefix2 = basePrefix;
|
||||
if (basePrefix2.Back() == ':')
|
||||
{
|
||||
int pos = basePrefix2.ReverseFind_PathSepar();
|
||||
if (pos >= 0)
|
||||
basePrefix2.DeleteFrom(pos + 1);
|
||||
}
|
||||
|
||||
t.Enumerator.BasePrefix = us2fs(basePrefix);
|
||||
t.Enumerator.BasePrefix_for_Open = us2fs(basePrefix2);
|
||||
|
||||
t.Enumerator.EnterToDirs = !GetFlatMode();
|
||||
|
||||
t.ProgressDialog.ShowCompressionInfo = false;
|
||||
@@ -354,10 +365,22 @@ void CApp::CalculateCrc(const UString &methodName)
|
||||
|
||||
t.ProgressDialog.MainWindow = _window;
|
||||
t.ProgressDialog.MainTitle = L"7-Zip"; // LangString(IDS_APP_TITLE);
|
||||
t.ProgressDialog.MainAddTitle = title + UString(L' ');
|
||||
t.ProgressDialog.MainAddTitle = title;
|
||||
t.ProgressDialog.MainAddTitle.Add_Space();
|
||||
|
||||
if (t.Create(title, _window) != S_OK)
|
||||
return;
|
||||
RINOK(t.Create(title, _window));
|
||||
}
|
||||
RefreshTitleAlways();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CApp::CalculateCrc(const UString &methodName)
|
||||
{
|
||||
HRESULT res = CalculateCrc2(methodName);
|
||||
if (res != S_OK && res != E_ABORT)
|
||||
{
|
||||
int srcPanelIndex = GetFocusedPanelIndex();
|
||||
CPanel &srcPanel = Panels[srcPanelIndex];
|
||||
srcPanel.MessageBoxError(res);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,9 +296,11 @@ static bool CopyNamesToHGlobal(NMemory::CGlobal &hgDrop, const UStringVector &na
|
||||
|
||||
void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
|
||||
{
|
||||
CDisableTimerProcessing disableTimerProcessing2(*this);
|
||||
if (!DoesItSupportOperations())
|
||||
return;
|
||||
|
||||
CDisableTimerProcessing disableTimerProcessing2(*this);
|
||||
|
||||
CRecordVector<UInt32> indices;
|
||||
GetOperatedItemIndices(indices);
|
||||
if (indices.Size() == 0)
|
||||
@@ -312,7 +314,7 @@ void CPanel::OnDrag(LPNMLISTVIEW /* nmListView */)
|
||||
|
||||
bool isFSFolder = IsFSFolder();
|
||||
if (isFSFolder)
|
||||
dirPrefix = us2fs(_currentFolderPrefix);
|
||||
dirPrefix = us2fs(GetFsPath());
|
||||
else
|
||||
{
|
||||
tempDirectory.Create(kTempDirPrefix);
|
||||
@@ -580,7 +582,9 @@ bool CDropTarget::IsItSameDrive() const
|
||||
return false;
|
||||
if (!IsFsFolderPath())
|
||||
return false;
|
||||
|
||||
UString drive;
|
||||
|
||||
if (m_Panel->IsFSFolder())
|
||||
{
|
||||
drive = m_Panel->GetDriveOrNetworkPrefix();
|
||||
@@ -594,13 +598,14 @@ bool CDropTarget::IsItSameDrive() const
|
||||
|
||||
if (m_SourcePaths.Size() == 0)
|
||||
return false;
|
||||
|
||||
FOR_VECTOR (i, m_SourcePaths)
|
||||
{
|
||||
if (MyStringCompareNoCase_N(m_SourcePaths[i], drive, drive.Len()) != 0)
|
||||
if (!m_SourcePaths[i].IsPrefixedBy_NoCase(drive))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
DWORD CDropTarget::GetEffect(DWORD keyState, POINTL /* pt */, DWORD allowedEffect)
|
||||
@@ -635,13 +640,11 @@ UString CDropTarget::GetTargetPath() const
|
||||
{
|
||||
if (!IsFsFolderPath())
|
||||
return UString();
|
||||
UString path = m_Panel->_currentFolderPrefix;
|
||||
if (m_Panel->IsFSDrivesFolder())
|
||||
path.Empty();
|
||||
UString path = m_Panel->GetFsPath();
|
||||
if (m_SubFolderIndex >= 0 && !m_SubFolderName.IsEmpty())
|
||||
{
|
||||
path += m_SubFolderName;
|
||||
path += WCHAR_PATH_SEPARATOR;
|
||||
path.Add_PathSepar();
|
||||
}
|
||||
return path;
|
||||
}
|
||||
@@ -728,7 +731,7 @@ STDMETHODIMP CDropTarget::Drop(IDataObject *dataObject, DWORD keyState,
|
||||
UString path = GetTargetPath();
|
||||
if (m_IsAppTarget && m_Panel)
|
||||
if (m_Panel->IsFSFolder())
|
||||
path = m_Panel->_currentFolderPrefix;
|
||||
path = m_Panel->GetFsPath();
|
||||
m_Panel->DropObject(dataObject, path);
|
||||
}
|
||||
}
|
||||
@@ -779,7 +782,7 @@ static bool AreThereNamesFromTemp(const UStringVector &fileNames)
|
||||
if (tempPath.IsEmpty())
|
||||
return false;
|
||||
FOR_VECTOR (i, fileNames)
|
||||
if (MyStringCompareNoCase_N(fileNames[i], tempPath, tempPath.Len()) == 0)
|
||||
if (fileNames[i].IsPrefixedBy_NoCase(tempPath))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -28,10 +28,38 @@ using namespace NWindows;
|
||||
using namespace NFile;
|
||||
using namespace NFind;
|
||||
|
||||
void CPanel::ReleaseFolder()
|
||||
{
|
||||
_folder.Release();
|
||||
|
||||
_folderCompare.Release();
|
||||
_folderGetItemName.Release();
|
||||
_folderRawProps.Release();
|
||||
_folderAltStreams.Release();
|
||||
_folderOperations.Release();
|
||||
|
||||
_thereAreDeletedItems = false;
|
||||
}
|
||||
|
||||
void CPanel::SetNewFolder(IFolderFolder *newFolder)
|
||||
{
|
||||
ReleaseFolder();
|
||||
_folder = newFolder;
|
||||
if (_folder)
|
||||
{
|
||||
_folder.QueryInterface(IID_IFolderCompare, &_folderCompare);
|
||||
_folder.QueryInterface(IID_IFolderGetItemName, &_folderGetItemName);
|
||||
_folder.QueryInterface(IID_IArchiveGetRawProps, &_folderRawProps);
|
||||
_folder.QueryInterface(IID_IFolderAltStreams, &_folderAltStreams);
|
||||
_folder.QueryInterface(IID_IFolderOperations, &_folderOperations);
|
||||
}
|
||||
}
|
||||
|
||||
void CPanel::SetToRootFolder()
|
||||
{
|
||||
ReleaseFolder();
|
||||
_library.Free();
|
||||
|
||||
CRootFolder *rootFolderSpec = new CRootFolder;
|
||||
SetNewFolder(rootFolderSpec);
|
||||
rootFolderSpec->Init();
|
||||
@@ -39,105 +67,188 @@ void CPanel::SetToRootFolder()
|
||||
|
||||
HRESULT CPanel::BindToPath(const UString &fullPath, const UString &arcFormat, bool &archiveIsOpened, bool &encrypted)
|
||||
{
|
||||
UString path = fullPath;
|
||||
#ifdef _WIN32
|
||||
path.Replace(L'/', WCHAR_PATH_SEPARATOR);
|
||||
#endif
|
||||
|
||||
archiveIsOpened = false;
|
||||
encrypted = false;
|
||||
|
||||
CDisableTimerProcessing disableTimerProcessing(*this);
|
||||
CDisableNotify disableNotify(*this);
|
||||
|
||||
if (_parentFolders.Size() > 0)
|
||||
for (; !_parentFolders.IsEmpty(); CloseOneLevel())
|
||||
{
|
||||
const UString &virtPath = _parentFolders.Back().VirtualPath;
|
||||
if (fullPath.IsPrefixedBy(virtPath))
|
||||
// ---------- we try to use open archive ----------
|
||||
|
||||
const CFolderLink &link = _parentFolders.Back();
|
||||
const UString &virtPath = link.VirtualPath;
|
||||
if (!path.IsPrefixedBy(virtPath))
|
||||
continue;
|
||||
UString relatPath = path.Ptr(virtPath.Len());
|
||||
if (!relatPath.IsEmpty())
|
||||
{
|
||||
for (;;)
|
||||
if (!IS_PATH_SEPAR(relatPath[0]))
|
||||
continue;
|
||||
else
|
||||
relatPath.Delete(0);
|
||||
}
|
||||
|
||||
UString relatPath2 = relatPath;
|
||||
if (!relatPath2.IsEmpty() && !IS_PATH_SEPAR(relatPath2.Back()))
|
||||
relatPath2.Add_PathSepar();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const UString foldPath = GetFolderPath(_folder);
|
||||
if (relatPath2 == foldPath)
|
||||
break;
|
||||
if (relatPath.IsPrefixedBy(foldPath))
|
||||
{
|
||||
CMyComPtr<IFolderFolder> newFolder;
|
||||
HRESULT res = _folder->BindToParentFolder(&newFolder);
|
||||
if (!newFolder || res != S_OK)
|
||||
break;
|
||||
SetNewFolder(newFolder);
|
||||
path = relatPath.Ptr(foldPath.Len());
|
||||
break;
|
||||
}
|
||||
UStringVector parts;
|
||||
SplitPathToParts(fullPath.Ptr(virtPath.Len()), parts);
|
||||
FOR_VECTOR (i, parts)
|
||||
CMyComPtr<IFolderFolder> newFolder;
|
||||
if (_folder->BindToParentFolder(&newFolder) != S_OK)
|
||||
throw 20140918;
|
||||
if (!newFolder) // we exit from loop above if (relatPath.IsPrefixedBy(empty path for root folder)
|
||||
throw 20140918;
|
||||
SetNewFolder(newFolder);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (_parentFolders.IsEmpty())
|
||||
{
|
||||
// ---------- we open file or folder from file system ----------
|
||||
|
||||
CloseOpenFolders();
|
||||
UString sysPath = path;
|
||||
|
||||
unsigned prefixSize = NName::GetRootPrefixSize(sysPath);
|
||||
if (prefixSize == 0 || sysPath[prefixSize] == 0)
|
||||
sysPath.Empty();
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
if (!sysPath.IsEmpty() && sysPath.Back() == ':' &&
|
||||
(sysPath.Len() != 2 || !NName::IsDrivePath2(sysPath)))
|
||||
{
|
||||
UString baseFile = sysPath;
|
||||
baseFile.DeleteBack();
|
||||
if (NFind::DoesFileOrDirExist(us2fs(baseFile)))
|
||||
sysPath.Empty();
|
||||
}
|
||||
#endif
|
||||
|
||||
CFileInfo fileInfo;
|
||||
|
||||
while (!sysPath.IsEmpty())
|
||||
{
|
||||
if (fileInfo.Find(us2fs(sysPath)))
|
||||
break;
|
||||
int pos = sysPath.ReverseFind_PathSepar();
|
||||
if (pos < 0)
|
||||
sysPath.Empty();
|
||||
else
|
||||
{
|
||||
const UString &s = parts[i];
|
||||
if ((i == 0 || i == parts.Size() - 1) && s.IsEmpty())
|
||||
continue;
|
||||
CMyComPtr<IFolderFolder> newFolder;
|
||||
HRESULT res = _folder->BindToFolder(s, &newFolder);
|
||||
if (!newFolder || res != S_OK)
|
||||
break;
|
||||
SetNewFolder(newFolder);
|
||||
/*
|
||||
if (reducedParts.Size() > 0 || pos < (int)sysPath.Len() - 1)
|
||||
reducedParts.Add(sysPath.Ptr(pos + 1));
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
if (pos == 2 && NName::IsDrivePath2(sysPath) && sysPath.Len() > 3)
|
||||
pos++;
|
||||
#endif
|
||||
|
||||
sysPath.DeleteFrom(pos);
|
||||
}
|
||||
}
|
||||
|
||||
SetToRootFolder();
|
||||
|
||||
CMyComPtr<IFolderFolder> newFolder;
|
||||
|
||||
if (sysPath.IsEmpty())
|
||||
{
|
||||
_folder->BindToFolder(path, &newFolder);
|
||||
}
|
||||
else if (fileInfo.IsDir())
|
||||
{
|
||||
NName::NormalizeDirPathPrefix(sysPath);
|
||||
_folder->BindToFolder(sysPath, &newFolder);
|
||||
}
|
||||
else
|
||||
{
|
||||
FString dirPrefix, fileName;
|
||||
NDir::GetFullPathAndSplit(us2fs(sysPath), dirPrefix, fileName);
|
||||
HRESULT res;
|
||||
// = OpenItemAsArchive(fs2us(fileName), arcFormat, encrypted);
|
||||
{
|
||||
CTempFileInfo tfi;
|
||||
tfi.RelPath = fs2us(fileName);
|
||||
tfi.FolderPath = dirPrefix;
|
||||
tfi.FilePath = us2fs(sysPath);
|
||||
res = OpenItemAsArchive(NULL, tfi, sysPath, arcFormat, encrypted);
|
||||
}
|
||||
|
||||
if (res == S_FALSE)
|
||||
_folder->BindToFolder(fs2us(dirPrefix), &newFolder);
|
||||
else
|
||||
{
|
||||
RINOK(res);
|
||||
archiveIsOpened = true;
|
||||
_parentFolders.Back().ParentFolderPath = fs2us(dirPrefix);
|
||||
path.DeleteFrontal(sysPath.Len());
|
||||
if (!path.IsEmpty() && IS_PATH_SEPAR(path[0]))
|
||||
path.Delete(0);
|
||||
}
|
||||
}
|
||||
if (newFolder)
|
||||
{
|
||||
SetNewFolder(newFolder);
|
||||
// LoadFullPath();
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// ---------- we open folder remPath in archive and sub archives ----------
|
||||
|
||||
CloseOpenFolders();
|
||||
UString sysPath = fullPath;
|
||||
CFileInfo fileInfo;
|
||||
UStringVector reducedParts;
|
||||
while (!sysPath.IsEmpty())
|
||||
{
|
||||
if (fileInfo.Find(us2fs(sysPath)))
|
||||
break;
|
||||
int pos = sysPath.ReverseFind(WCHAR_PATH_SEPARATOR);
|
||||
if (pos < 0)
|
||||
sysPath.Empty();
|
||||
else
|
||||
for (unsigned curPos = 0; curPos != path.Len();)
|
||||
{
|
||||
if (reducedParts.Size() > 0 || pos < (int)sysPath.Len() - 1)
|
||||
reducedParts.Add(sysPath.Ptr(pos + 1));
|
||||
sysPath.DeleteFrom(pos);
|
||||
}
|
||||
}
|
||||
SetToRootFolder();
|
||||
CMyComPtr<IFolderFolder> newFolder;
|
||||
if (sysPath.IsEmpty())
|
||||
{
|
||||
if (_folder->BindToFolder(fullPath, &newFolder) == S_OK)
|
||||
SetNewFolder(newFolder);
|
||||
}
|
||||
else if (fileInfo.IsDir())
|
||||
{
|
||||
NName::NormalizeDirPathPrefix(sysPath);
|
||||
if (_folder->BindToFolder(sysPath, &newFolder) == S_OK)
|
||||
SetNewFolder(newFolder);
|
||||
}
|
||||
else
|
||||
{
|
||||
FString dirPrefix, fileName;
|
||||
NDir::GetFullPathAndSplit(us2fs(sysPath), dirPrefix, fileName);
|
||||
if (_folder->BindToFolder(fs2us(dirPrefix), &newFolder) == S_OK)
|
||||
{
|
||||
SetNewFolder(newFolder);
|
||||
LoadFullPath();
|
||||
UString s = path.Ptr(curPos);
|
||||
int slashPos = NName::FindSepar(s);
|
||||
unsigned skipLen = s.Len();
|
||||
if (slashPos >= 0)
|
||||
{
|
||||
HRESULT res = OpenItemAsArchive(fs2us(fileName), arcFormat, encrypted);
|
||||
if (res != S_FALSE)
|
||||
s.DeleteFrom(slashPos);
|
||||
skipLen = slashPos + 1;
|
||||
}
|
||||
|
||||
CMyComPtr<IFolderFolder> newFolder;
|
||||
_folder->BindToFolder(s, &newFolder);
|
||||
if (newFolder)
|
||||
curPos += skipLen;
|
||||
else if (_folderAltStreams)
|
||||
{
|
||||
int pos = s.Find(L':');
|
||||
if (pos >= 0)
|
||||
{
|
||||
RINOK(res);
|
||||
}
|
||||
/*
|
||||
if (res == E_ABORT)
|
||||
return res;
|
||||
*/
|
||||
if (res == S_OK)
|
||||
{
|
||||
archiveIsOpened = true;
|
||||
for (int i = reducedParts.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
CMyComPtr<IFolderFolder> newFolder;
|
||||
_folder->BindToFolder(reducedParts[i], &newFolder);
|
||||
if (!newFolder)
|
||||
break;
|
||||
SetNewFolder(newFolder);
|
||||
}
|
||||
UString baseName = s;
|
||||
baseName.DeleteFrom(pos);
|
||||
if (_folderAltStreams->BindToAltStreams(baseName, &newFolder) == S_OK && newFolder)
|
||||
curPos += pos + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!newFolder)
|
||||
break;
|
||||
|
||||
SetNewFolder(newFolder);
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -163,10 +274,12 @@ void CPanel::OpenBookmark(int index)
|
||||
|
||||
UString GetFolderPath(IFolderFolder *folder)
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
if (folder->GetFolderProperty(kpidPath, &prop) == S_OK)
|
||||
if (prop.vt == VT_BSTR)
|
||||
return (wchar_t *)prop.bstrVal;
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
if (folder->GetFolderProperty(kpidPath, &prop) == S_OK)
|
||||
if (prop.vt == VT_BSTR)
|
||||
return (wchar_t *)prop.bstrVal;
|
||||
}
|
||||
return UString();
|
||||
}
|
||||
|
||||
@@ -176,9 +289,10 @@ void CPanel::LoadFullPath()
|
||||
FOR_VECTOR (i, _parentFolders)
|
||||
{
|
||||
const CFolderLink &folderLink = _parentFolders[i];
|
||||
_currentFolderPrefix += GetFolderPath(folderLink.ParentFolder);
|
||||
_currentFolderPrefix += folderLink.ParentFolderPath;
|
||||
// GetFolderPath(folderLink.ParentFolder);
|
||||
_currentFolderPrefix += folderLink.RelPath;
|
||||
_currentFolderPrefix += WCHAR_PATH_SEPARATOR;
|
||||
_currentFolderPrefix.Add_PathSepar();
|
||||
}
|
||||
if (_folder)
|
||||
_currentFolderPrefix += GetFolderPath(_folder);
|
||||
@@ -364,7 +478,7 @@ bool CPanel::OnComboBoxCommand(UINT code, LPARAM /* param */, LRESULT &result)
|
||||
{
|
||||
UString name = pathParts[i];
|
||||
sumPass += name;
|
||||
sumPass += WCHAR_PATH_SEPARATOR;
|
||||
sumPass.Add_PathSepar();
|
||||
CFileInfo info;
|
||||
DWORD attrib = FILE_ATTRIBUTE_DIRECTORY;
|
||||
if (info.Find(us2fs(sumPass)))
|
||||
@@ -496,73 +610,104 @@ void CPanel::FoldersHistory()
|
||||
void CPanel::OpenParentFolder()
|
||||
{
|
||||
LoadFullPath(); // Maybe we don't need it ??
|
||||
UString focucedName;
|
||||
if (!_currentFolderPrefix.IsEmpty() &&
|
||||
_currentFolderPrefix.Back() == WCHAR_PATH_SEPARATOR)
|
||||
|
||||
UString parentFolderPrefix;
|
||||
UString focusedName;
|
||||
|
||||
if (!_currentFolderPrefix.IsEmpty())
|
||||
{
|
||||
focucedName = _currentFolderPrefix;
|
||||
focucedName.DeleteBack();
|
||||
if (focucedName != L"\\\\.")
|
||||
wchar_t c = _currentFolderPrefix.Back();
|
||||
if (c == WCHAR_PATH_SEPARATOR || c == ':')
|
||||
{
|
||||
int pos = focucedName.ReverseFind(WCHAR_PATH_SEPARATOR);
|
||||
if (pos >= 0)
|
||||
focucedName.DeleteFrontal(pos + 1);
|
||||
focusedName = _currentFolderPrefix;
|
||||
focusedName.DeleteBack();
|
||||
/*
|
||||
if (c == ':' && !focusedName.IsEmpty() && focusedName.Back() == WCHAR_PATH_SEPARATOR)
|
||||
{
|
||||
focusedName.DeleteBack();
|
||||
}
|
||||
else
|
||||
*/
|
||||
if (focusedName != L"\\\\." &&
|
||||
focusedName != L"\\\\?")
|
||||
{
|
||||
int pos = focusedName.ReverseFind_PathSepar();
|
||||
if (pos >= 0)
|
||||
{
|
||||
parentFolderPrefix = focusedName;
|
||||
parentFolderPrefix.DeleteFrom(pos + 1);
|
||||
focusedName.DeleteFrontal(pos + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CDisableTimerProcessing disableTimerProcessing(*this);
|
||||
CDisableNotify disableNotify(*this);
|
||||
|
||||
CMyComPtr<IFolderFolder> newFolder;
|
||||
_folder->BindToParentFolder(&newFolder);
|
||||
|
||||
// newFolder.Release(); // for test
|
||||
|
||||
if (newFolder)
|
||||
SetNewFolder(newFolder);
|
||||
else
|
||||
{
|
||||
if (_parentFolders.IsEmpty())
|
||||
bool needSetFolder = true;
|
||||
if (!_parentFolders.IsEmpty())
|
||||
{
|
||||
SetToRootFolder();
|
||||
if (focucedName.IsEmpty())
|
||||
focucedName = GetItemName(0);
|
||||
{
|
||||
const CFolderLink &link = _parentFolders.Back();
|
||||
parentFolderPrefix = link.ParentFolderPath;
|
||||
focusedName = link.RelPath;
|
||||
}
|
||||
CloseOneLevel();
|
||||
needSetFolder = (!_folder);
|
||||
}
|
||||
else
|
||||
|
||||
if (needSetFolder)
|
||||
{
|
||||
ReleaseFolder();
|
||||
_library.Free();
|
||||
CFolderLink &link = _parentFolders.Back();
|
||||
SetNewFolder(link.ParentFolder);
|
||||
_library.Attach(link.Library.Detach());
|
||||
focucedName = link.RelPath;
|
||||
if (_parentFolders.Size() > 1)
|
||||
OpenParentArchiveFolder();
|
||||
_parentFolders.DeleteBack();
|
||||
if (_parentFolders.IsEmpty())
|
||||
_flatMode = _flatModeForDisk;
|
||||
{
|
||||
bool archiveIsOpened;
|
||||
bool encrypted;
|
||||
BindToPath(parentFolderPrefix, UString(), archiveIsOpened, encrypted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UStringVector selectedItems;
|
||||
/*
|
||||
if (!focucedName.IsEmpty())
|
||||
selectedItems.Add(focucedName);
|
||||
if (!focusedName.IsEmpty())
|
||||
selectedItems.Add(focusedName);
|
||||
*/
|
||||
LoadFullPath();
|
||||
// ::SetCurrentDirectory(::_currentFolderPrefix);
|
||||
RefreshListCtrl(focucedName, -1, true, selectedItems);
|
||||
RefreshListCtrl(focusedName, -1, true, selectedItems);
|
||||
// _listView.EnsureVisible(_listView.GetFocusedItem(), false);
|
||||
}
|
||||
|
||||
void CPanel::CloseOneLevel()
|
||||
{
|
||||
ReleaseFolder();
|
||||
_library.Free();
|
||||
{
|
||||
CFolderLink &link = _parentFolders.Back();
|
||||
if (link.ParentFolder)
|
||||
SetNewFolder(link.ParentFolder);
|
||||
_library.Attach(link.Library.Detach());
|
||||
}
|
||||
if (_parentFolders.Size() > 1)
|
||||
OpenParentArchiveFolder();
|
||||
_parentFolders.DeleteBack();
|
||||
if (_parentFolders.IsEmpty())
|
||||
_flatMode = _flatModeForDisk;
|
||||
}
|
||||
|
||||
void CPanel::CloseOpenFolders()
|
||||
{
|
||||
while (_parentFolders.Size() > 0)
|
||||
{
|
||||
ReleaseFolder();
|
||||
_library.Free();
|
||||
SetNewFolder(_parentFolders.Back().ParentFolder);
|
||||
_library.Attach(_parentFolders.Back().Library.Detach());
|
||||
if (_parentFolders.Size() > 1)
|
||||
OpenParentArchiveFolder();
|
||||
_parentFolders.DeleteBack();
|
||||
}
|
||||
while (!_parentFolders.IsEmpty())
|
||||
CloseOneLevel();
|
||||
_flatMode = _flatModeForDisk;
|
||||
ReleaseFolder();
|
||||
_library.Free();
|
||||
@@ -618,3 +763,45 @@ void CPanel::OpenFolder(int index)
|
||||
_listView.SetItemState_Selected(_listView.GetFocusedItem());
|
||||
_listView.EnsureVisible(_listView.GetFocusedItem(), false);
|
||||
}
|
||||
|
||||
void CPanel::OpenAltStreams()
|
||||
{
|
||||
CRecordVector<UInt32> indices;
|
||||
GetOperatedItemIndices(indices);
|
||||
Int32 realIndex = -1;
|
||||
if (indices.Size() > 1)
|
||||
return;
|
||||
if (indices.Size() == 1)
|
||||
realIndex = indices[0];
|
||||
|
||||
if (_folderAltStreams)
|
||||
{
|
||||
CMyComPtr<IFolderFolder> newFolder;
|
||||
_folderAltStreams->BindToAltStreams(realIndex, &newFolder);
|
||||
if (newFolder)
|
||||
{
|
||||
CDisableTimerProcessing disableTimerProcessing(*this);
|
||||
CDisableNotify disableNotify(*this);
|
||||
SetNewFolder(newFolder);
|
||||
RefreshListCtrl(UString(), -1, true, UStringVector());
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
UString path;
|
||||
if (realIndex >= 0)
|
||||
path = GetItemFullPath(realIndex);
|
||||
else
|
||||
{
|
||||
path = GetFsPath();
|
||||
if (!NName::IsDriveRootPath_SuperAllowed(us2fs(path)))
|
||||
if (!path.IsEmpty() && IS_PATH_SEPAR(path.Back()))
|
||||
path.DeleteBack();
|
||||
}
|
||||
|
||||
path += L':';
|
||||
BindToPathAndRefresh(path);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -157,7 +157,8 @@ public:
|
||||
|
||||
static bool IsNameVirus(const UString &name)
|
||||
{
|
||||
return (name.Find(L" ") >= 0);
|
||||
// return (name.Find(L" ") >= 0);
|
||||
return (wcsstr(name, L" ") != NULL);
|
||||
}
|
||||
|
||||
struct CTmpProcessInfo: public CTempFileInfo
|
||||
@@ -223,7 +224,13 @@ HRESULT CPanel::OpenItemAsArchive(IInStream *inStream,
|
||||
folderLink.Password = password;
|
||||
folderLink.UsePassword = encrypted;
|
||||
|
||||
folderLink.ParentFolder = _folder;
|
||||
if (_folder)
|
||||
folderLink.ParentFolderPath = GetFolderPath(_folder);
|
||||
else
|
||||
folderLink.ParentFolderPath = _currentFolderPrefix;
|
||||
if (!_parentFolders.IsEmpty())
|
||||
folderLink.ParentFolder = _folder;
|
||||
|
||||
_parentFolders.Add(folderLink);
|
||||
_parentFolders.Back().Library.Attach(_library.Detach());
|
||||
|
||||
@@ -272,7 +279,7 @@ HRESULT CPanel::OpenItemAsArchive(IInStream *inStream,
|
||||
if (!values[0].IsEmpty())
|
||||
{
|
||||
if (!s2.IsEmpty())
|
||||
s2 += L"\n";
|
||||
s2.Add_LF();
|
||||
s2 += L"[";
|
||||
s2 += values[2];
|
||||
s2 += L"] Error: ";
|
||||
@@ -283,7 +290,7 @@ HRESULT CPanel::OpenItemAsArchive(IInStream *inStream,
|
||||
if (!s.IsEmpty())
|
||||
s += L"--------------------\n";
|
||||
s += values[1];
|
||||
s += L"\n";
|
||||
s.Add_LF();
|
||||
s += s2;
|
||||
}
|
||||
}
|
||||
@@ -305,8 +312,8 @@ HRESULT CPanel::OpenItemAsArchive(const UString &relPath, const UString &arcForm
|
||||
{
|
||||
CTempFileInfo tfi;
|
||||
tfi.RelPath = relPath;
|
||||
tfi.FolderPath = us2fs(_currentFolderPrefix);
|
||||
const UString fullPath = _currentFolderPrefix + relPath;
|
||||
tfi.FolderPath = us2fs(GetFsPath());
|
||||
const UString fullPath = GetFsPath() + relPath;
|
||||
tfi.FilePath = us2fs(fullPath);
|
||||
return OpenItemAsArchive(NULL, tfi, fullPath, arcFormat, encrypted);
|
||||
}
|
||||
@@ -316,7 +323,7 @@ HRESULT CPanel::OpenItemAsArchive(int index)
|
||||
CDisableTimerProcessing disableTimerProcessing1(*this);
|
||||
CDisableNotify disableNotify(*this);
|
||||
bool encrypted;
|
||||
HRESULT res = OpenItemAsArchive(GetItemRelPath(index), UString(), encrypted);
|
||||
HRESULT res = OpenItemAsArchive(GetItemRelPath2(index), UString(), encrypted);
|
||||
if (res != S_OK)
|
||||
{
|
||||
RefreshTitle(true); // in case of error we must refresh changed title of 7zFM
|
||||
@@ -379,7 +386,7 @@ static const char *kStartExtensions =
|
||||
|
||||
static bool FindExt(const char *p, const UString &name)
|
||||
{
|
||||
int dotPos = name.ReverseFind('.');
|
||||
int dotPos = name.ReverseFind_Dot();
|
||||
if (dotPos < 0 || dotPos == (int)name.Len() - 1)
|
||||
return false;
|
||||
|
||||
@@ -409,10 +416,7 @@ static bool DoItemAlwaysStart(const UString &name)
|
||||
return FindExt(kStartExtensions, name);
|
||||
}
|
||||
|
||||
static UString GetQuotedString(const UString &s)
|
||||
{
|
||||
return UString(L'\"') + s + UString(L'\"');
|
||||
}
|
||||
UString GetQuotedString(const UString &s);
|
||||
|
||||
static HRESULT StartEditApplication(const UString &path, bool useEditor, HWND window, CProcess &process)
|
||||
{
|
||||
@@ -455,13 +459,17 @@ void CApp::DiffFiles()
|
||||
{
|
||||
const CPanel &destPanel = Panels[1 - LastFocusedPanel];
|
||||
path1 = panel.GetItemFullPath(indices[0]);
|
||||
const UString relPath = panel.GetItemRelPath(indices[0]);
|
||||
CRecordVector<UInt32> indices2;
|
||||
destPanel.GetSelectedItemsIndices(indices2);
|
||||
if (indices2.Size() == 1)
|
||||
path2 = destPanel.GetItemFullPath(indices2[0]);
|
||||
else
|
||||
{
|
||||
UString relPath = panel.GetItemRelPath2(indices[0]);
|
||||
if (panel._flatMode && !destPanel._flatMode)
|
||||
relPath = panel.GetItemName(indices[0]);
|
||||
path2 = destPanel._currentFolderPrefix + relPath;
|
||||
}
|
||||
}
|
||||
else
|
||||
return;
|
||||
@@ -471,7 +479,9 @@ void CApp::DiffFiles()
|
||||
if (command.IsEmpty())
|
||||
return;
|
||||
|
||||
UString param = GetQuotedString(path1) + L' ' + GetQuotedString(path2);
|
||||
UString param = GetQuotedString(path1);
|
||||
param.Add_Space();
|
||||
param += GetQuotedString(path2);
|
||||
|
||||
HRESULT res = MyCreateProcess(command, param);
|
||||
if (res == SZ_OK)
|
||||
@@ -573,11 +583,11 @@ void CPanel::OpenFolderExternal(int index)
|
||||
UString name;
|
||||
if (index == kParentIndex)
|
||||
{
|
||||
int pos = fsPrefix.ReverseFind(WCHAR_PATH_SEPARATOR);
|
||||
int pos = fsPrefix.ReverseFind_PathSepar();
|
||||
if (pos >= 0 && pos == (int)fsPrefix.Len() - 1)
|
||||
{
|
||||
UString s = fsPrefix.Left(pos);
|
||||
pos = s.ReverseFind(WCHAR_PATH_SEPARATOR);
|
||||
pos = s.ReverseFind_PathSepar();
|
||||
if (pos >= 0)
|
||||
fsPrefix.SetFrom(s, pos + 1);
|
||||
}
|
||||
@@ -591,7 +601,7 @@ void CPanel::OpenFolderExternal(int index)
|
||||
void CPanel::OpenItem(int index, bool tryInternal, bool tryExternal)
|
||||
{
|
||||
CDisableTimerProcessing disableTimerProcessing(*this);
|
||||
UString name = GetItemRelPath(index);
|
||||
UString name = GetItemRelPath2(index);
|
||||
if (IsNameVirus(name))
|
||||
{
|
||||
MessageBoxErrorLang(IDS_VIRUS);
|
||||
@@ -650,8 +660,7 @@ HRESULT CThreadCopyFrom::ProcessVirt()
|
||||
HRESULT CPanel::OnOpenItemChanged(UInt32 index, const wchar_t *fullFilePath,
|
||||
bool usePassword, const UString &password)
|
||||
{
|
||||
CMyComPtr<IFolderOperations> folderOperations;
|
||||
if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
|
||||
if (!_folderOperations)
|
||||
{
|
||||
MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
|
||||
return E_FAIL;
|
||||
@@ -663,8 +672,13 @@ HRESULT CPanel::OnOpenItemChanged(UInt32 index, const wchar_t *fullFilePath,
|
||||
t.UpdateCallbackSpec->ProgressDialog = &t.ProgressDialog;
|
||||
t.ItemIndex = index;
|
||||
t.FullPath = fullFilePath;
|
||||
t.FolderOperations = folderOperations;
|
||||
t.UpdateCallbackSpec->Init(usePassword, password);
|
||||
t.FolderOperations = _folderOperations;
|
||||
|
||||
t.UpdateCallbackSpec->Init();
|
||||
t.UpdateCallbackSpec->PasswordIsDefined = usePassword;
|
||||
t.UpdateCallbackSpec->Password = password;
|
||||
|
||||
|
||||
RINOK(t.Create(GetItemName(index), (HWND)*this));
|
||||
return t.Result;
|
||||
}
|
||||
@@ -862,8 +876,11 @@ STDMETHODIMP CBufSeqOutStream_WithFile::Write(const void *data, UInt32 size, UIn
|
||||
{
|
||||
if (_size - _pos >= size)
|
||||
{
|
||||
memcpy(_buffer + _pos, data, size);
|
||||
_pos += size;
|
||||
if (size != 0)
|
||||
{
|
||||
memcpy(_buffer + _pos, data, size);
|
||||
_pos += size;
|
||||
}
|
||||
if (processedSize)
|
||||
*processedSize = (UInt32)size;
|
||||
return S_OK;
|
||||
@@ -931,8 +948,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
|
||||
return;
|
||||
}
|
||||
|
||||
CMyComPtr<IFolderOperations> folderOperations;
|
||||
if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
|
||||
if (!_folderOperations)
|
||||
{
|
||||
MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
|
||||
return;
|
||||
@@ -951,7 +967,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
|
||||
FString tempDir = tempDirectory.GetPath();
|
||||
FString tempDirNorm = tempDir;
|
||||
NName::NormalizeDirPathPrefix(tempDirNorm);
|
||||
const FString tempFilePath = tempDirNorm + us2fs(GetCorrectFsPath(name));
|
||||
const FString tempFilePath = tempDirNorm + us2fs(Get_Correct_FsFile_Name(name));
|
||||
|
||||
CTempFileInfo tempFileInfo;
|
||||
tempFileInfo.FileIndex = index;
|
||||
@@ -1029,7 +1045,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
|
||||
bool isAltStream = IsItem_AltStream(index);
|
||||
|
||||
CCopyToOptions options;
|
||||
options.includeAltStreams = false;
|
||||
options.includeAltStreams = true;
|
||||
options.replaceAltStreamChars = isAltStream;
|
||||
|
||||
if (tryAsArchive)
|
||||
@@ -1137,11 +1153,11 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
|
||||
return;
|
||||
|
||||
CProcess process;
|
||||
/* HRESULT res; */
|
||||
// HRESULT res;
|
||||
if (editMode)
|
||||
/* res = */ StartEditApplication(fs2us(tempFilePath), useEditor, (HWND)*this, process);
|
||||
else
|
||||
/* res = */ StartApplication(fs2us(tempDirNorm), fs2us(tempFilePath), (HWND)*this, process);
|
||||
/* res = */ StartApplication(fs2us(tempDirNorm), fs2us(tempFilePath), (HWND)*this, process);
|
||||
|
||||
if ((HANDLE)process == 0)
|
||||
return;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "../../../../C/Sort.h"
|
||||
|
||||
#include "../../../Windows/FileName.h"
|
||||
#include "../../../Windows/Menu.h"
|
||||
#include "../../../Windows/PropVariant.h"
|
||||
#include "../../../Windows/PropVariantConv.h"
|
||||
@@ -103,7 +104,7 @@ HRESULT CPanel::InitColumns()
|
||||
_properties.Clear();
|
||||
|
||||
_needSaveInfo = true;
|
||||
bool isFsFolder = IsFSFolder();
|
||||
bool isFsFolder = IsFSFolder() || IsAltStreamsFolder();
|
||||
|
||||
{
|
||||
UInt32 numProps;
|
||||
@@ -401,7 +402,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
|
||||
int cursorIndex = -1;
|
||||
|
||||
CMyComPtr<IFolderGetSystemIconIndex> folderGetSystemIconIndex;
|
||||
if (!IsFSFolder() || _showRealFileIcons)
|
||||
if (!Is_Slow_Icon_Folder() || _showRealFileIcons)
|
||||
_folder.QueryInterface(IID_IFolderGetSystemIconIndex, &folderGetSystemIconIndex);
|
||||
|
||||
if (!IsFSFolder())
|
||||
@@ -436,7 +437,8 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
|
||||
int subItem = 0;
|
||||
item.iSubItem = subItem++;
|
||||
item.lParam = kParentIndex;
|
||||
item.pszText = const_cast<wchar_t *>((const wchar_t *)itemName);
|
||||
// item.pszText = const_cast<wchar_t *>((const wchar_t *)itemName);
|
||||
item.pszText = LPSTR_TEXTCALLBACKW;
|
||||
UInt32 attrib = FILE_ATTRIBUTE_DIRECTORY;
|
||||
item.iImage = _extToIconMap.GetIconIndex(attrib, itemName);
|
||||
if (item.iImage < 0)
|
||||
@@ -451,19 +453,23 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
|
||||
UString correctedName;
|
||||
UString itemName;
|
||||
UString relPath;
|
||||
|
||||
for (UInt32 i = 0; i < numItems; i++)
|
||||
{
|
||||
const wchar_t *name = NULL;
|
||||
unsigned nameLen = 0;
|
||||
|
||||
if (_folderGetItemName)
|
||||
_folderGetItemName->GetItemName(i, &name, &nameLen);
|
||||
if (name == NULL)
|
||||
if (!name)
|
||||
{
|
||||
GetItemNameFast(i, itemName);
|
||||
GetItemName(i, itemName);
|
||||
name = itemName;
|
||||
nameLen = itemName.Len();
|
||||
}
|
||||
|
||||
bool selected = false;
|
||||
|
||||
if (!focusedName.IsEmpty() || !selectedNames.IsEmpty())
|
||||
{
|
||||
relPath.Empty();
|
||||
@@ -495,6 +501,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
|
||||
if (selectedNames.FindInSorted(relPath) >= 0)
|
||||
selected = true;
|
||||
}
|
||||
|
||||
_selectedStatusVector.AddInReserved(selected);
|
||||
|
||||
item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
|
||||
@@ -567,6 +574,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
|
||||
// }
|
||||
|
||||
bool defined = false;
|
||||
|
||||
if (folderGetSystemIconIndex)
|
||||
{
|
||||
folderGetSystemIconIndex->GetSystemIconIndex(i, &item.iImage);
|
||||
@@ -585,6 +593,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
|
||||
item.iImage = _extToIconMap.GetIconIndex(attrib, name);
|
||||
}
|
||||
}
|
||||
|
||||
if (item.iImage < 0)
|
||||
item.iImage = 0;
|
||||
|
||||
@@ -592,6 +601,7 @@ HRESULT CPanel::RefreshListCtrl(const UString &focusedName, int focusedPos, bool
|
||||
return E_FAIL;
|
||||
listViewItemCount++;
|
||||
}
|
||||
|
||||
// OutputDebugStringA("End2\n");
|
||||
|
||||
if (_listView.GetItemCount() > 0 && cursorIndex >= 0)
|
||||
@@ -831,7 +841,24 @@ UString CPanel::GetItemName(int itemIndex) const
|
||||
return prop.bstrVal;
|
||||
}
|
||||
|
||||
void CPanel::GetItemNameFast(int itemIndex, UString &s) const
|
||||
UString CPanel::GetItemName_for_Copy(int itemIndex) const
|
||||
{
|
||||
if (itemIndex == kParentIndex)
|
||||
return L"..";
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
if (_folder->GetProperty(itemIndex, kpidOutName, &prop) == S_OK)
|
||||
{
|
||||
if (prop.vt == VT_BSTR)
|
||||
return prop.bstrVal;
|
||||
if (prop.vt != VT_EMPTY)
|
||||
throw 2723401;
|
||||
}
|
||||
}
|
||||
return GetItemName(itemIndex);
|
||||
}
|
||||
|
||||
void CPanel::GetItemName(int itemIndex, UString &s) const
|
||||
{
|
||||
if (itemIndex == kParentIndex)
|
||||
{
|
||||
@@ -843,8 +870,7 @@ void CPanel::GetItemNameFast(int itemIndex, UString &s) const
|
||||
throw 2723400;
|
||||
if (prop.vt != VT_BSTR)
|
||||
throw 2723401;
|
||||
s.Empty();
|
||||
s += prop.bstrVal;
|
||||
s.SetFromBstr(prop.bstrVal);
|
||||
}
|
||||
|
||||
UString CPanel::GetItemPrefix(int itemIndex) const
|
||||
@@ -856,7 +882,7 @@ UString CPanel::GetItemPrefix(int itemIndex) const
|
||||
throw 2723400;
|
||||
UString prefix;
|
||||
if (prop.vt == VT_BSTR)
|
||||
prefix = prop.bstrVal;
|
||||
prefix.SetFromBstr(prop.bstrVal);
|
||||
return prefix;
|
||||
}
|
||||
|
||||
@@ -865,9 +891,22 @@ UString CPanel::GetItemRelPath(int itemIndex) const
|
||||
return GetItemPrefix(itemIndex) + GetItemName(itemIndex);
|
||||
}
|
||||
|
||||
UString CPanel::GetItemRelPath2(int itemIndex) const
|
||||
{
|
||||
UString s = GetItemRelPath(itemIndex);
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
if (s.Len() == 2 && NFile::NName::IsDrivePath2(s))
|
||||
{
|
||||
if (IsFSDrivesFolder() && !IsDeviceDrivesPrefix())
|
||||
s.Add_PathSepar();
|
||||
}
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
|
||||
UString CPanel::GetItemFullPath(int itemIndex) const
|
||||
{
|
||||
return _currentFolderPrefix + GetItemRelPath(itemIndex);
|
||||
return GetFsPath() + GetItemRelPath2(itemIndex);
|
||||
}
|
||||
|
||||
bool CPanel::GetItem_BoolProp(UInt32 itemIndex, PROPID propID) const
|
||||
@@ -928,6 +967,7 @@ void CPanel::ReadListViewInfo()
|
||||
void CPanel::SaveListViewInfo()
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < _visibleProperties.Size(); i++)
|
||||
{
|
||||
CItemProperty &prop = _visibleProperties[i];
|
||||
@@ -945,6 +985,7 @@ void CPanel::SaveListViewInfo()
|
||||
PROPID sortPropID = _sortID;
|
||||
|
||||
_visibleProperties.Sort();
|
||||
|
||||
for (i = 0; i < _visibleProperties.Size(); i++)
|
||||
{
|
||||
const CItemProperty &prop = _visibleProperties[i];
|
||||
@@ -954,6 +995,7 @@ void CPanel::SaveListViewInfo()
|
||||
columnInfo.Width = prop.Width;
|
||||
viewInfo.Columns.Add(columnInfo);
|
||||
}
|
||||
|
||||
for (i = 0; i < _properties.Size(); i++)
|
||||
{
|
||||
const CItemProperty &prop = _properties[i];
|
||||
@@ -1025,21 +1067,24 @@ void CPanel::ShowColumnsContextMenu(int x, int y)
|
||||
else
|
||||
{
|
||||
int visibleIndex = _visibleProperties.FindItemWithID(prop.ID);
|
||||
_visibleProperties.Delete(visibleIndex);
|
||||
/*
|
||||
if (_sortIndex == index)
|
||||
if (visibleIndex >= 0)
|
||||
{
|
||||
_visibleProperties.Delete(visibleIndex);
|
||||
/*
|
||||
if (_sortIndex == index)
|
||||
{
|
||||
_sortIndex = 0;
|
||||
_ascending = true;
|
||||
}
|
||||
*/
|
||||
if (_sortID == prop.ID)
|
||||
{
|
||||
_sortID = kpidName;
|
||||
_ascending = true;
|
||||
}
|
||||
|
||||
_listView.DeleteColumn(visibleIndex);
|
||||
}
|
||||
*/
|
||||
if (_sortID == prop.ID)
|
||||
{
|
||||
_sortID = kpidName;
|
||||
_ascending = true;
|
||||
}
|
||||
|
||||
_listView.DeleteColumn(visibleIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,30 +19,57 @@
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
static void ConvertSizeToString(UInt64 value, wchar_t *dest)
|
||||
{
|
||||
char s[32];
|
||||
ConvertUInt64ToString(value, s);
|
||||
unsigned i = MyStringLen(s);
|
||||
unsigned pos = ARRAY_SIZE(s);
|
||||
s[--pos] = 0;
|
||||
while (i > 3)
|
||||
{
|
||||
s[--pos] = s[--i];
|
||||
s[--pos] = s[--i];
|
||||
s[--pos] = s[--i];
|
||||
s[--pos] = L' ';
|
||||
}
|
||||
while (i > 0)
|
||||
s[--pos] = s[--i];
|
||||
#define INT_TO_STR_SPEC(v) \
|
||||
while (v >= 10) { temp[i++] = (unsigned char)('0' + (unsigned)(v % 10)); v /= 10; } \
|
||||
*s++ = (unsigned char)('0' + (unsigned)v);
|
||||
|
||||
for (;;)
|
||||
static void ConvertSizeToString(UInt64 val, wchar_t *s) throw()
|
||||
{
|
||||
unsigned char temp[32];
|
||||
unsigned i = 0;
|
||||
|
||||
if (val <= (UInt32)0xFFFFFFFF)
|
||||
{
|
||||
char c = s[pos++];
|
||||
*dest++ = (unsigned char)c;
|
||||
if (c == 0)
|
||||
break;
|
||||
UInt32 val32 = (UInt32)val;
|
||||
INT_TO_STR_SPEC(val32)
|
||||
}
|
||||
else
|
||||
{
|
||||
INT_TO_STR_SPEC(val)
|
||||
}
|
||||
|
||||
if (i < 3)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
*s++ = temp[i - 1];
|
||||
if (i == 2)
|
||||
*s++ = temp[0];
|
||||
}
|
||||
*s = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned r = i % 3;
|
||||
if (r != 0)
|
||||
{
|
||||
s[0] = temp[--i];
|
||||
if (r == 2)
|
||||
s[1] = temp[--i];
|
||||
s += r;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
s[0] = ' ';
|
||||
s[1] = temp[i - 1];
|
||||
s[2] = temp[i - 2];
|
||||
s[3] = temp[i - 3];
|
||||
s += 4;
|
||||
}
|
||||
while (i -= 3);
|
||||
|
||||
*s = 0;
|
||||
}
|
||||
|
||||
UString ConvertSizeToString(UInt64 value)
|
||||
@@ -52,29 +79,62 @@ UString ConvertSizeToString(UInt64 value)
|
||||
return s;
|
||||
}
|
||||
|
||||
static inline char GetHex(Byte value)
|
||||
static inline unsigned GetHex(unsigned v)
|
||||
{
|
||||
return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
|
||||
return (v < 10) ? ('0' + v) : ('A' + (v - 10));
|
||||
}
|
||||
|
||||
void HexToString(char *dest, const Byte *data, UInt32 size)
|
||||
/*
|
||||
static void HexToString(char *dest, const Byte *data, UInt32 size)
|
||||
{
|
||||
for (UInt32 i = 0; i < size; i++)
|
||||
{
|
||||
Byte b = data[i];
|
||||
dest[0] = GetHex((Byte)((b >> 4) & 0xF));
|
||||
dest[1] = GetHex((Byte)(b & 0xF));
|
||||
unsigned b = data[i];
|
||||
dest[0] = GetHex((b >> 4) & 0xF);
|
||||
dest[1] = GetHex(b & 0xF);
|
||||
dest += 2;
|
||||
}
|
||||
*dest = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
bool IsSizeProp(UINT propID) throw()
|
||||
{
|
||||
switch (propID)
|
||||
{
|
||||
case kpidSize:
|
||||
case kpidPackSize:
|
||||
case kpidNumSubDirs:
|
||||
case kpidNumSubFiles:
|
||||
case kpidOffset:
|
||||
case kpidLinks:
|
||||
case kpidNumBlocks:
|
||||
case kpidNumVolumes:
|
||||
case kpidPhySize:
|
||||
case kpidHeadersSize:
|
||||
case kpidTotalSize:
|
||||
case kpidFreeSpace:
|
||||
case kpidClusterSize:
|
||||
case kpidNumErrors:
|
||||
case kpidNumStreams:
|
||||
case kpidNumAltStreams:
|
||||
case kpidAltStreamsSize:
|
||||
case kpidVirtualSize:
|
||||
case kpidUnpackSize:
|
||||
case kpidTotalPhySize:
|
||||
case kpidTailSize:
|
||||
case kpidEmbeddedStubSize:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
LRESULT CPanel::SetItemText(LVITEMW &item)
|
||||
{
|
||||
|
||||
if (_dontShowMode)
|
||||
return 0;
|
||||
UInt32 realIndex = GetRealIndex(item);
|
||||
|
||||
/*
|
||||
if ((item.mask & LVIF_IMAGE) != 0)
|
||||
{
|
||||
@@ -107,10 +167,31 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
|
||||
if ((item.mask & LVIF_TEXT) == 0)
|
||||
return 0;
|
||||
|
||||
if (realIndex == kParentIndex)
|
||||
LPWSTR text = item.pszText;
|
||||
|
||||
if (item.cchTextMax > 0)
|
||||
text[0] = 0;
|
||||
|
||||
if (item.cchTextMax <= 1)
|
||||
return 0;
|
||||
|
||||
const CItemProperty &property = _visibleProperties[item.iSubItem];
|
||||
PROPID propID = property.ID;
|
||||
|
||||
if (realIndex == kParentIndex)
|
||||
{
|
||||
if (propID == kpidName)
|
||||
{
|
||||
if (item.cchTextMax > 2)
|
||||
{
|
||||
text[0] = '.';
|
||||
text[1] = '.';
|
||||
text[2] = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (property.IsRawProp)
|
||||
{
|
||||
@@ -118,10 +199,10 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
|
||||
UInt32 dataSize;
|
||||
UInt32 propType;
|
||||
RINOK(_folderRawProps->GetRawProp(realIndex, propID, &data, &dataSize, &propType));
|
||||
int limit = item.cchTextMax - 1;
|
||||
unsigned limit = item.cchTextMax - 1;
|
||||
if (dataSize == 0)
|
||||
{
|
||||
item.pszText[0] = 0;
|
||||
text[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -131,15 +212,15 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
|
||||
ConvertNtReparseToString((const Byte *)data, dataSize, s);
|
||||
if (!s.IsEmpty())
|
||||
{
|
||||
int i;
|
||||
unsigned i;
|
||||
for (i = 0; i < limit; i++)
|
||||
{
|
||||
wchar_t c = s[i];
|
||||
if (c == 0)
|
||||
break;
|
||||
item.pszText[i] = c;
|
||||
text[i] = c;
|
||||
}
|
||||
item.pszText[i] = 0;
|
||||
text[i] = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -149,45 +230,45 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
|
||||
ConvertNtSecureToString((const Byte *)data, dataSize, s);
|
||||
if (!s.IsEmpty())
|
||||
{
|
||||
int i;
|
||||
unsigned i;
|
||||
for (i = 0; i < limit; i++)
|
||||
{
|
||||
wchar_t c = s[i];
|
||||
wchar_t c = (Byte)s[i];
|
||||
if (c == 0)
|
||||
break;
|
||||
item.pszText[i] = c;
|
||||
text[i] = c;
|
||||
}
|
||||
item.pszText[i] = 0;
|
||||
text[i] = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
{
|
||||
const UInt32 kMaxDataSize = 64;
|
||||
const unsigned kMaxDataSize = 64;
|
||||
if (dataSize > kMaxDataSize)
|
||||
{
|
||||
char temp[64];
|
||||
char temp[32];
|
||||
MyStringCopy(temp, "data:");
|
||||
ConvertUInt32ToString(dataSize, temp + 5);
|
||||
int i;
|
||||
unsigned i;
|
||||
for (i = 0; i < limit; i++)
|
||||
{
|
||||
wchar_t c = temp[i];
|
||||
wchar_t c = (Byte)temp[i];
|
||||
if (c == 0)
|
||||
break;
|
||||
item.pszText[i] = c;
|
||||
text[i] = c;
|
||||
}
|
||||
item.pszText[i] = 0;
|
||||
text[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((int)dataSize > limit)
|
||||
if (dataSize > limit)
|
||||
dataSize = limit;
|
||||
WCHAR *dest = item.pszText;
|
||||
WCHAR *dest = text;
|
||||
for (UInt32 i = 0; i < dataSize; i++)
|
||||
{
|
||||
Byte b = ((const Byte *)data)[i];
|
||||
dest[0] = GetHex((Byte)((b >> 4) & 0xF));
|
||||
dest[1] = GetHex((Byte)(b & 0xF));
|
||||
unsigned b = ((const Byte *)data)[i];
|
||||
dest[0] = (WCHAR)GetHex((b >> 4) & 0xF);
|
||||
dest[1] = (WCHAR)GetHex(b & 0xF);
|
||||
dest += 2;
|
||||
}
|
||||
*dest = 0;
|
||||
@@ -230,11 +311,7 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
|
||||
*/
|
||||
|
||||
if (item.cchTextMax < 32)
|
||||
{
|
||||
if (item.cchTextMax > 0)
|
||||
item.pszText[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (propID == kpidName)
|
||||
{
|
||||
@@ -245,35 +322,36 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
|
||||
_folderGetItemName->GetItemName(realIndex, &name, &nameLen);
|
||||
if (name)
|
||||
{
|
||||
int dest = 0;
|
||||
int limit = item.cchTextMax - 1;
|
||||
for (int i = 0; dest < limit;)
|
||||
unsigned dest = 0;
|
||||
unsigned limit = item.cchTextMax - 1;
|
||||
for (unsigned i = 0; dest < limit;)
|
||||
{
|
||||
wchar_t c = name[i++];
|
||||
if (c == 0)
|
||||
break;
|
||||
item.pszText[dest++] = c;
|
||||
text[dest++] = c;
|
||||
if (c != ' ')
|
||||
continue;
|
||||
if (name[i + 1] != ' ')
|
||||
continue;
|
||||
|
||||
int t = 2;
|
||||
unsigned t = 2;
|
||||
for (; name[i + t] == ' '; t++);
|
||||
if (t >= 4 && dest + 4 <= limit)
|
||||
{
|
||||
item.pszText[dest++] = '.';
|
||||
item.pszText[dest++] = '.';
|
||||
item.pszText[dest++] = '.';
|
||||
item.pszText[dest++] = ' ';
|
||||
text[dest++] = '.';
|
||||
text[dest++] = '.';
|
||||
text[dest++] = '.';
|
||||
text[dest++] = ' ';
|
||||
i += t;
|
||||
}
|
||||
}
|
||||
item.pszText[dest] = 0;
|
||||
text[dest] = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (propID == kpidPrefix)
|
||||
{
|
||||
if (_folderGetItemName)
|
||||
@@ -283,73 +361,65 @@ LRESULT CPanel::SetItemText(LVITEMW &item)
|
||||
_folderGetItemName->GetItemPrefix(realIndex, &name, &nameLen);
|
||||
if (name)
|
||||
{
|
||||
int dest = 0;
|
||||
int limit = item.cchTextMax - 1;
|
||||
for (int i = 0; dest < limit;)
|
||||
unsigned dest = 0;
|
||||
unsigned limit = item.cchTextMax - 1;
|
||||
for (unsigned i = 0; dest < limit;)
|
||||
{
|
||||
wchar_t c = name[i++];
|
||||
if (c == 0)
|
||||
break;
|
||||
item.pszText[dest++] = c;
|
||||
text[dest++] = c;
|
||||
}
|
||||
item.pszText[dest] = 0;
|
||||
text[dest] = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT res = _folder->GetProperty(realIndex, propID, &prop);
|
||||
|
||||
if (res != S_OK)
|
||||
{
|
||||
MyStringCopy(item.pszText, L"Error: ");
|
||||
MyStringCopy(text, L"Error: ");
|
||||
// s = UString(L"Error: ") + HResultToMessage(res);
|
||||
}
|
||||
else if ((prop.vt == VT_UI8 || prop.vt == VT_UI4 || prop.vt == VT_UI2) && (
|
||||
propID == kpidSize ||
|
||||
propID == kpidPackSize ||
|
||||
propID == kpidNumSubDirs ||
|
||||
propID == kpidNumSubFiles ||
|
||||
propID == kpidPosition ||
|
||||
propID == kpidNumBlocks ||
|
||||
propID == kpidClusterSize ||
|
||||
propID == kpidTotalSize ||
|
||||
propID == kpidFreeSpace ||
|
||||
propID == kpidUnpackSize
|
||||
))
|
||||
else if ((prop.vt == VT_UI8 || prop.vt == VT_UI4 || prop.vt == VT_UI2) && IsSizeProp(propID))
|
||||
{
|
||||
UInt64 v = 0;
|
||||
ConvertPropVariantToUInt64(prop, v);
|
||||
ConvertSizeToString(v, item.pszText);
|
||||
ConvertSizeToString(v, text);
|
||||
}
|
||||
else if (prop.vt == VT_BSTR)
|
||||
{
|
||||
int limit = item.cchTextMax - 1;
|
||||
unsigned limit = item.cchTextMax - 1;
|
||||
const wchar_t *src = prop.bstrVal;
|
||||
int i;
|
||||
unsigned i;
|
||||
for (i = 0; i < limit; i++)
|
||||
{
|
||||
wchar_t c = src[i];
|
||||
if (c == 0) break;
|
||||
if (c == 0xA) c = ' ';
|
||||
if (c == 0xD) c = ' ';
|
||||
item.pszText[i] = c;
|
||||
text[i] = c;
|
||||
}
|
||||
item.pszText[i] = 0;
|
||||
text[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
char temp[64];
|
||||
ConvertPropertyToShortString(temp, prop, propID, false);
|
||||
int i;
|
||||
int limit = item.cchTextMax - 1;
|
||||
unsigned i;
|
||||
unsigned limit = item.cchTextMax - 1;
|
||||
for (i = 0; i < limit; i++)
|
||||
{
|
||||
wchar_t c = temp[i];
|
||||
wchar_t c = (Byte)temp[i];
|
||||
if (c == 0)
|
||||
break;
|
||||
item.pszText[i] = c;
|
||||
text[i] = c;
|
||||
}
|
||||
item.pszText[i] = 0;
|
||||
text[i] = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -606,7 +676,7 @@ void CPanel::Refresh_StatusBar()
|
||||
|
||||
if (indices.Size() > 0)
|
||||
{
|
||||
// for (int ttt = 0; ttt < 1000; ttt++) {
|
||||
// for (unsigned ttt = 0; ttt < 1000; ttt++) {
|
||||
UInt64 totalSize = 0;
|
||||
FOR_VECTOR (i, indices)
|
||||
totalSize += GetItemSize(indices[i]);
|
||||
@@ -632,10 +702,10 @@ void CPanel::Refresh_StatusBar()
|
||||
char dateString2[32];
|
||||
dateString2[0] = 0;
|
||||
ConvertPropertyToShortString(dateString2, prop, kpidMTime, false);
|
||||
for (int i = 0;; i++)
|
||||
for (unsigned i = 0;; i++)
|
||||
{
|
||||
char c = dateString2[i];
|
||||
dateString[i] = c;
|
||||
dateString[i] = (Byte)c;
|
||||
if (c == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -49,11 +49,12 @@ void CPanel::InvokeSystemCommand(const char *command)
|
||||
contextMenu->InvokeCommand(&ci);
|
||||
}
|
||||
|
||||
static const wchar_t *kSeparator = L"----------------------------\n";
|
||||
static const wchar_t *kSeparatorSmall = L"----\n";
|
||||
static const wchar_t *kPropValueSeparator = L": ";
|
||||
static const char *kSeparator = "----------------------------\n";
|
||||
static const char *kSeparatorSmall = "----\n";
|
||||
static const char *kPropValueSeparator = ": ";
|
||||
|
||||
extern UString ConvertSizeToString(UInt64 value);
|
||||
extern UString ConvertSizeToString(UInt64 value) throw();
|
||||
bool IsSizeProp(UINT propID) throw();
|
||||
|
||||
UString GetOpenArcErrorMessage(UInt32 errorFlags);
|
||||
|
||||
@@ -74,20 +75,7 @@ static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR,
|
||||
val = GetOpenArcErrorMessage(flags);
|
||||
}
|
||||
if (val.IsEmpty())
|
||||
if ((prop.vt == VT_UI8 || prop.vt == VT_UI4 || prop.vt == VT_UI2) && (
|
||||
propID == kpidSize ||
|
||||
propID == kpidPackSize ||
|
||||
propID == kpidNumSubDirs ||
|
||||
propID == kpidNumSubFiles ||
|
||||
propID == kpidNumBlocks ||
|
||||
propID == kpidClusterSize ||
|
||||
propID == kpidTotalSize ||
|
||||
propID == kpidFreeSpace ||
|
||||
propID == kpidPhySize ||
|
||||
propID == kpidHeadersSize ||
|
||||
propID == kpidFreeSpace ||
|
||||
propID == kpidUnpackSize
|
||||
))
|
||||
if ((prop.vt == VT_UI8 || prop.vt == VT_UI4 || prop.vt == VT_UI2) && IsSizeProp(propID))
|
||||
{
|
||||
UInt64 v = 0;
|
||||
ConvertPropVariantToUInt64(prop, v);
|
||||
@@ -99,13 +87,13 @@ static void AddPropertyString(PROPID propID, const wchar_t *nameBSTR,
|
||||
if (!val.IsEmpty())
|
||||
{
|
||||
s += GetNameOfProperty(propID, nameBSTR);
|
||||
s += kPropValueSeparator;
|
||||
s.AddAscii(kPropValueSeparator);
|
||||
/*
|
||||
if (propID == kpidComment)
|
||||
s += L'\n';
|
||||
s.Add_LF();
|
||||
*/
|
||||
s += val;
|
||||
s += L'\n';
|
||||
s.Add_LF();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -210,21 +198,21 @@ void CPanel::Properties()
|
||||
}
|
||||
}
|
||||
message += GetNameOfProperty(propID, name);
|
||||
message += kPropValueSeparator;
|
||||
message += GetUnicodeString(s);
|
||||
message += L'\n';
|
||||
message.AddAscii(kPropValueSeparator);
|
||||
message.AddAscii(s);
|
||||
message.Add_LF();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
message += kSeparator;
|
||||
message.AddAscii(kSeparator);
|
||||
}
|
||||
|
||||
/*
|
||||
message += LangString(IDS_PROP_FILE_TYPE, 0x02000214);
|
||||
AddLangString(message, IDS_PROP_FILE_TYPE);
|
||||
message += kPropValueSeparator;
|
||||
message += GetFolderTypeID();
|
||||
message += L"\n";
|
||||
message.Add_LF();
|
||||
*/
|
||||
|
||||
{
|
||||
@@ -277,7 +265,7 @@ void CPanel::Properties()
|
||||
{
|
||||
const int kNumSpecProps = ARRAY_SIZE(kSpecProps);
|
||||
|
||||
message += kSeparator;
|
||||
message.AddAscii(kSeparator);
|
||||
|
||||
for (Int32 i = -(int)kNumSpecProps; i < (Int32)numProps; i++)
|
||||
{
|
||||
@@ -302,7 +290,7 @@ void CPanel::Properties()
|
||||
UInt32 numProps;
|
||||
if (getProps->GetArcNumProps2(level, &numProps) == S_OK)
|
||||
{
|
||||
message += kSeparatorSmall;
|
||||
message.AddAscii(kSeparatorSmall);
|
||||
for (Int32 i = 0; i < (Int32)numProps; i++)
|
||||
{
|
||||
CMyComBSTR name;
|
||||
@@ -414,9 +402,7 @@ HRESULT CPanel::CreateShellContextMenu(
|
||||
FOR_VECTOR (i, operatedIndices)
|
||||
{
|
||||
LPITEMIDLIST pidl;
|
||||
UString fileName = GetItemRelPath(operatedIndices[i]);
|
||||
if (IsFSDrivesFolder())
|
||||
fileName += WCHAR_PATH_SEPARATOR;
|
||||
UString fileName = GetItemRelPath2(operatedIndices[i]);
|
||||
RINOK(parentFolder->ParseDisplayName(GetParent(), 0,
|
||||
(wchar_t *)(const wchar_t *)fileName, &eaten, &pidl, 0));
|
||||
pidls.AddInReserved(pidl);
|
||||
@@ -574,11 +560,11 @@ void CPanel::CreateSevenZipMenu(HMENU menuSpec,
|
||||
if (contextMenu.QueryInterface(IID_IInitContextMenu, &initContextMenu) != S_OK)
|
||||
return;
|
||||
*/
|
||||
UString currentFolderUnicode = _currentFolderPrefix;
|
||||
UString currentFolderUnicode = GetFsPath();
|
||||
UStringVector names;
|
||||
unsigned i;
|
||||
for (i = 0; i < operatedIndices.Size(); i++)
|
||||
names.Add(currentFolderUnicode + GetItemRelPath(operatedIndices[i]));
|
||||
names.Add(currentFolderUnicode + GetItemRelPath2(operatedIndices[i]));
|
||||
CRecordVector<const wchar_t *> namePointers;
|
||||
for (i = 0; i < operatedIndices.Size(); i++)
|
||||
namePointers.Add(names[i]);
|
||||
@@ -598,6 +584,74 @@ void CPanel::CreateSevenZipMenu(HMENU menuSpec,
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsReadOnlyFolder(IFolderFolder *folder)
|
||||
{
|
||||
if (!folder)
|
||||
return false;
|
||||
|
||||
bool res = false;
|
||||
{
|
||||
NCOM::CPropVariant prop;
|
||||
if (folder->GetFolderProperty(kpidReadOnly, &prop) == S_OK)
|
||||
if (prop.vt == VT_BOOL)
|
||||
res = VARIANT_BOOLToBool(prop.boolVal);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool CPanel::IsThereReadOnlyFolder() const
|
||||
{
|
||||
if (!_folderOperations)
|
||||
return true;
|
||||
if (IsReadOnlyFolder(_folder))
|
||||
return true;
|
||||
FOR_VECTOR (i, _parentFolders)
|
||||
{
|
||||
if (IsReadOnlyFolder(_parentFolders[i].ParentFolder))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CPanel::CheckBeforeUpdate(UINT resourceID)
|
||||
{
|
||||
if (!_folderOperations)
|
||||
{
|
||||
MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
|
||||
// resourceID = resourceID;
|
||||
// MessageBoxErrorForUpdate(E_NOINTERFACE, resourceID);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = (int)_parentFolders.Size(); i >= 0; i--)
|
||||
{
|
||||
IFolderFolder *folder;
|
||||
if (i == (int)_parentFolders.Size())
|
||||
folder = _folder;
|
||||
else
|
||||
folder = _parentFolders[i].ParentFolder;
|
||||
|
||||
if (!IsReadOnlyFolder(folder))
|
||||
continue;
|
||||
|
||||
UString s;
|
||||
AddLangString(s, resourceID);
|
||||
s.Add_LF();
|
||||
AddLangString(s, IDS_OPERATION_IS_NOT_SUPPORTED);
|
||||
s.Add_LF();
|
||||
if (i == 0)
|
||||
s += GetFolderPath(folder);
|
||||
else
|
||||
s += _parentFolders[i - 1].VirtualPath;
|
||||
s.Add_LF();
|
||||
AddLangString(s, IDS_PROP_READ_ONLY);
|
||||
MessageBoxMyError(s);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPanel::CreateFileMenu(HMENU menuSpec,
|
||||
CMyComPtr<IContextMenu> &sevenZipContextMenu,
|
||||
CMyComPtr<IContextMenu> &systemContextMenu,
|
||||
@@ -631,8 +685,38 @@ void CPanel::CreateFileMenu(HMENU menuSpec,
|
||||
if (IsItem_Folder(operatedIndices[i]))
|
||||
break;
|
||||
bool allAreFiles = (i == operatedIndices.Size());
|
||||
LoadFileMenu(menu, menu.GetItemCount(), programMenu,
|
||||
IsFSFolder(), operatedIndices.Size(), allAreFiles);
|
||||
|
||||
CFileMenu fm;
|
||||
|
||||
fm.readOnly = IsThereReadOnlyFolder();
|
||||
fm.isFsFolder = Is_IO_FS_Folder();
|
||||
fm.programMenu = programMenu;
|
||||
fm.allAreFiles = allAreFiles;
|
||||
fm.numItems = operatedIndices.Size();
|
||||
|
||||
fm.isAltStreamsSupported = false;
|
||||
|
||||
if (_folderAltStreams)
|
||||
{
|
||||
if (operatedIndices.Size() <= 1)
|
||||
{
|
||||
Int32 realIndex = -1;
|
||||
if (operatedIndices.Size() == 1)
|
||||
realIndex = operatedIndices[0];
|
||||
Int32 val = 0;
|
||||
if (_folderAltStreams->AreAltStreamsSupported(realIndex, &val) == S_OK)
|
||||
fm.isAltStreamsSupported = IntToBool(val);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fm.numItems == 0)
|
||||
fm.isAltStreamsSupported = IsFSFolder();
|
||||
else
|
||||
fm.isAltStreamsSupported = IsFolder_with_FsItems();
|
||||
}
|
||||
|
||||
fm.Load(menu, menu.GetItemCount());
|
||||
}
|
||||
|
||||
bool CPanel::InvokePluginCommand(int id)
|
||||
@@ -654,26 +738,31 @@ bool CPanel::InvokePluginCommand(int id,
|
||||
else
|
||||
offset = id - kSevenZipStartMenuID;
|
||||
|
||||
#ifndef use_CMINVOKECOMMANDINFOEXR
|
||||
CMINVOKECOMMANDINFO
|
||||
#ifdef use_CMINVOKECOMMANDINFOEX
|
||||
CMINVOKECOMMANDINFOEX
|
||||
#else
|
||||
CMINVOKECOMMANDINFOEX
|
||||
CMINVOKECOMMANDINFO
|
||||
#endif
|
||||
commandInfo;
|
||||
commandInfo;
|
||||
|
||||
memset(&commandInfo, 0, sizeof(commandInfo));
|
||||
commandInfo.cbSize = sizeof(commandInfo);
|
||||
|
||||
commandInfo.fMask = 0
|
||||
#ifdef use_CMINVOKECOMMANDINFOEXR
|
||||
| CMIC_MASK_UNICODE
|
||||
#ifdef use_CMINVOKECOMMANDINFOEX
|
||||
| CMIC_MASK_UNICODE
|
||||
#endif
|
||||
;
|
||||
;
|
||||
|
||||
commandInfo.hwnd = GetParent();
|
||||
commandInfo.lpVerb = (LPCSTR)(MAKEINTRESOURCE(offset));
|
||||
commandInfo.lpParameters = NULL;
|
||||
CSysString currentFolderSys = GetSystemString(_currentFolderPrefix);
|
||||
commandInfo.lpDirectory = (LPCSTR)(LPCTSTR)(currentFolderSys);
|
||||
commandInfo.nShow = SW_SHOW;
|
||||
#ifdef use_CMINVOKECOMMANDINFOEXR
|
||||
|
||||
#ifdef use_CMINVOKECOMMANDINFOEX
|
||||
|
||||
commandInfo.lpParametersW = NULL;
|
||||
commandInfo.lpTitle = "";
|
||||
commandInfo.lpVerbW = (LPCWSTR)(MAKEINTRESOURCEW(offset));
|
||||
@@ -684,7 +773,9 @@ bool CPanel::InvokePluginCommand(int id,
|
||||
// commandInfo.ptInvoke.y = yPos;
|
||||
commandInfo.ptInvoke.x = 0;
|
||||
commandInfo.ptInvoke.y = 0;
|
||||
|
||||
#endif
|
||||
|
||||
HRESULT result;
|
||||
if (isSystemMenu)
|
||||
result = systemContextMenu->InvokeCommand(LPCMINVOKECOMMANDINFO(&commandInfo));
|
||||
|
||||
@@ -85,16 +85,15 @@ HRESULT CThreadFolderOperations::DoOperation(CPanel &panel, const UString &progr
|
||||
ProgressDialog.Sync.FinalMessage.ErrorMessage.Title = titleError;
|
||||
Result = S_OK;
|
||||
|
||||
bool usePassword = false;
|
||||
UString password;
|
||||
UpdateCallbackSpec->Init();
|
||||
|
||||
if (panel._parentFolders.Size() > 0)
|
||||
{
|
||||
const CFolderLink &fl = panel._parentFolders.Back();
|
||||
usePassword = fl.UsePassword;
|
||||
password = fl.Password;
|
||||
UpdateCallbackSpec->PasswordIsDefined = fl.UsePassword;
|
||||
UpdateCallbackSpec->Password = fl.Password;
|
||||
}
|
||||
|
||||
UpdateCallbackSpec->Init(usePassword, password);
|
||||
|
||||
ProgressDialog.MainWindow = panel._mainWindow; // panel.GetParent()
|
||||
ProgressDialog.MainTitle = L"7-Zip"; // LangString(IDS_APP_TITLE);
|
||||
@@ -108,6 +107,7 @@ HRESULT CThreadFolderOperations::DoOperation(CPanel &panel, const UString &progr
|
||||
typedef int (WINAPI * SHFileOperationWP)(LPSHFILEOPSTRUCTW lpFileOp);
|
||||
#endif
|
||||
|
||||
/*
|
||||
void CPanel::MessageBoxErrorForUpdate(HRESULT errorCode, UINT resourceID)
|
||||
{
|
||||
if (errorCode == E_NOINTERFACE)
|
||||
@@ -115,6 +115,7 @@ void CPanel::MessageBoxErrorForUpdate(HRESULT errorCode, UINT resourceID)
|
||||
else
|
||||
MessageBoxError(errorCode, LangString(resourceID));
|
||||
}
|
||||
*/
|
||||
|
||||
void CPanel::DeleteItems(bool NON_CE_VAR(toRecycleBin))
|
||||
{
|
||||
@@ -137,8 +138,8 @@ void CPanel::DeleteItems(bool NON_CE_VAR(toRecycleBin))
|
||||
CDynamicBuffer<CHAR> buffer;
|
||||
FOR_VECTOR (i, indices)
|
||||
{
|
||||
const AString path = GetSystemString(GetFsPath() + GetItemRelPath(indices[i]));
|
||||
memcpy(buffer.GetCurPtrAndGrow(path.Len() + 1), (const CHAR *)path, (path.Len() + 1) * sizeof(CHAR));
|
||||
const AString path = GetSystemString(GetItemFullPath(indices[i]));
|
||||
buffer.AddData(path, path.Len() + 1);
|
||||
}
|
||||
*buffer.GetCurPtrAndGrow(1) = 0;
|
||||
SHFILEOPSTRUCTA fo;
|
||||
@@ -163,13 +164,14 @@ void CPanel::DeleteItems(bool NON_CE_VAR(toRecycleBin))
|
||||
{
|
||||
CDynamicBuffer<WCHAR> buffer;
|
||||
unsigned maxLen = 0;
|
||||
const UString prefix = GetFsPath();
|
||||
FOR_VECTOR (i, indices)
|
||||
{
|
||||
// L"\\\\?\\") doesn't work here.
|
||||
const UString path = GetFsPath() + GetItemRelPath(indices[i]);
|
||||
const UString path = prefix + GetItemRelPath2(indices[i]);
|
||||
if (path.Len() > maxLen)
|
||||
maxLen = path.Len();
|
||||
memcpy(buffer.GetCurPtrAndGrow(path.Len() + 1), (const WCHAR *)path, (path.Len() + 1) * sizeof(WCHAR));
|
||||
buffer.AddData(path, path.Len() + 1);
|
||||
}
|
||||
*buffer.GetCurPtrAndGrow(1) = 0;
|
||||
if (maxLen >= MAX_PATH)
|
||||
@@ -220,19 +222,15 @@ void CPanel::DeleteItems(bool NON_CE_VAR(toRecycleBin))
|
||||
|
||||
// DeleteItemsInternal
|
||||
|
||||
CMyComPtr<IFolderOperations> folderOperations;
|
||||
if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
|
||||
{
|
||||
MessageBoxErrorForUpdate(E_NOINTERFACE, IDS_ERROR_DELETING);
|
||||
if (!CheckBeforeUpdate(IDS_ERROR_DELETING))
|
||||
return;
|
||||
}
|
||||
|
||||
UInt32 titleID, messageID;
|
||||
UString messageParam;
|
||||
if (indices.Size() == 1)
|
||||
{
|
||||
int index = indices[0];
|
||||
messageParam = GetItemRelPath(index);
|
||||
messageParam = GetItemRelPath2(index);
|
||||
if (IsItem_Folder(index))
|
||||
{
|
||||
titleID = IDS_CONFIRM_FOLDER_DELETE;
|
||||
@@ -256,7 +254,7 @@ void CPanel::DeleteItems(bool NON_CE_VAR(toRecycleBin))
|
||||
CDisableNotify disableNotify(*this);
|
||||
{
|
||||
CThreadFolderOperations op(FOLDER_TYPE_DELETE);
|
||||
op.FolderOperations = folderOperations;
|
||||
op.FolderOperations = _folderOperations;
|
||||
op.Indices = indices;
|
||||
op.DoOperation(*this,
|
||||
LangString(IDS_DELETING),
|
||||
@@ -271,25 +269,14 @@ BOOL CPanel::OnBeginLabelEdit(LV_DISPINFOW * lpnmh)
|
||||
int realIndex = GetRealIndex(lpnmh->item);
|
||||
if (realIndex == kParentIndex)
|
||||
return TRUE;
|
||||
CMyComPtr<IFolderOperations> folderOperations;
|
||||
if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
|
||||
if (IsThereReadOnlyFolder())
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static UString GetLastPart(const UString name)
|
||||
{
|
||||
int slashPos = name.ReverseFind(L'/');
|
||||
#ifdef _WIN32
|
||||
int slash1Pos = name.ReverseFind(L'\\');
|
||||
slashPos = MyMax(slashPos, slash1Pos);
|
||||
#endif
|
||||
return name.Ptr(slashPos + 1);
|
||||
}
|
||||
|
||||
bool IsCorrectFsName(const UString &name)
|
||||
{
|
||||
const UString lastPart = GetLastPart(name);
|
||||
const UString lastPart = name.Ptr(name.ReverseFind_PathSepar() + 1);
|
||||
return
|
||||
lastPart != L"." &&
|
||||
lastPart != L"..";
|
||||
@@ -299,7 +286,7 @@ bool CorrectFsPath(const UString &relBase, const UString &path, UString &result)
|
||||
|
||||
bool CPanel::CorrectFsPath(const UString &path2, UString &result)
|
||||
{
|
||||
return ::CorrectFsPath(_currentFolderPrefix, path2, result);
|
||||
return ::CorrectFsPath(GetFsPath(), path2, result);
|
||||
}
|
||||
|
||||
BOOL CPanel::OnEndLabelEdit(LV_DISPINFOW * lpnmh)
|
||||
@@ -307,12 +294,10 @@ BOOL CPanel::OnEndLabelEdit(LV_DISPINFOW * lpnmh)
|
||||
if (lpnmh->item.pszText == NULL)
|
||||
return FALSE;
|
||||
CDisableTimerProcessing disableTimerProcessing2(*this);
|
||||
CMyComPtr<IFolderOperations> folderOperations;
|
||||
if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
|
||||
{
|
||||
MessageBoxErrorForUpdate(E_NOINTERFACE, IDS_ERROR_RENAMING);
|
||||
|
||||
if (!CheckBeforeUpdate(IDS_ERROR_RENAMING))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
UString newName = lpnmh->item.pszText;
|
||||
if (!IsCorrectFsName(newName))
|
||||
{
|
||||
@@ -342,7 +327,7 @@ BOOL CPanel::OnEndLabelEdit(LV_DISPINFOW * lpnmh)
|
||||
CDisableNotify disableNotify(*this);
|
||||
{
|
||||
CThreadFolderOperations op(FOLDER_TYPE_RENAME);
|
||||
op.FolderOperations = folderOperations;
|
||||
op.FolderOperations = _folderOperations;
|
||||
op.Index = realIndex;
|
||||
op.Name = newName;
|
||||
/* HRESULTres = */ op.DoOperation(*this,
|
||||
@@ -377,12 +362,9 @@ bool Dlg_CreateFolder(HWND wnd, UString &destName);
|
||||
|
||||
void CPanel::CreateFolder()
|
||||
{
|
||||
CMyComPtr<IFolderOperations> folderOperations;
|
||||
if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
|
||||
{
|
||||
MessageBoxErrorForUpdate(E_NOINTERFACE, IDS_CREATE_FOLDER_ERROR);
|
||||
if (!CheckBeforeUpdate(IDS_CREATE_FOLDER_ERROR))
|
||||
return;
|
||||
}
|
||||
|
||||
CDisableTimerProcessing disableTimerProcessing2(*this);
|
||||
CSelectedState state;
|
||||
SaveSelectedState(state);
|
||||
@@ -412,7 +394,7 @@ void CPanel::CreateFolder()
|
||||
CDisableNotify disableNotify(*this);
|
||||
{
|
||||
CThreadFolderOperations op(FOLDER_TYPE_CREATE_FOLDER);
|
||||
op.FolderOperations = folderOperations;
|
||||
op.FolderOperations = _folderOperations;
|
||||
op.Name = newName;
|
||||
res = op.DoOperation(*this,
|
||||
LangString(IDS_CREATE_FOLDER),
|
||||
@@ -439,12 +421,9 @@ void CPanel::CreateFolder()
|
||||
|
||||
void CPanel::CreateFile()
|
||||
{
|
||||
CMyComPtr<IFolderOperations> folderOperations;
|
||||
if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
|
||||
{
|
||||
MessageBoxErrorForUpdate(E_NOINTERFACE, IDS_CREATE_FILE_ERROR);
|
||||
if (!CheckBeforeUpdate(IDS_CREATE_FILE_ERROR))
|
||||
return;
|
||||
}
|
||||
|
||||
CDisableTimerProcessing disableTimerProcessing2(*this);
|
||||
CSelectedState state;
|
||||
SaveSelectedState(state);
|
||||
@@ -471,10 +450,11 @@ void CPanel::CreateFile()
|
||||
newName = correctName;
|
||||
}
|
||||
|
||||
HRESULT result = folderOperations->CreateFile(newName, 0);
|
||||
HRESULT result = _folderOperations->CreateFile(newName, 0);
|
||||
if (result != S_OK)
|
||||
{
|
||||
MessageBoxErrorForUpdate(result, IDS_CREATE_FILE_ERROR);
|
||||
MessageBoxError(result, LangString(IDS_CREATE_FILE_ERROR));
|
||||
// MessageBoxErrorForUpdate(result, IDS_CREATE_FILE_ERROR);
|
||||
return;
|
||||
}
|
||||
int pos = newName.Find(WCHAR_PATH_SEPARATOR);
|
||||
@@ -489,6 +469,8 @@ void CPanel::CreateFile()
|
||||
|
||||
void CPanel::RenameFile()
|
||||
{
|
||||
if (!CheckBeforeUpdate(IDS_ERROR_RENAMING))
|
||||
return;
|
||||
int index = _listView.GetFocusedItem();
|
||||
if (index >= 0)
|
||||
_listView.EditLabel(index);
|
||||
@@ -496,6 +478,8 @@ void CPanel::RenameFile()
|
||||
|
||||
void CPanel::ChangeComment()
|
||||
{
|
||||
if (!CheckBeforeUpdate(IDS_COMMENT))
|
||||
return;
|
||||
CDisableTimerProcessing disableTimerProcessing2(*this);
|
||||
int index = _listView.GetFocusedItem();
|
||||
if (index < 0)
|
||||
@@ -505,13 +489,6 @@ void CPanel::ChangeComment()
|
||||
return;
|
||||
CSelectedState state;
|
||||
SaveSelectedState(state);
|
||||
CMyComPtr<IFolderOperations> folderOperations;
|
||||
if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK)
|
||||
{
|
||||
MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
UString comment;
|
||||
{
|
||||
NCOM::CPropVariant propVariant;
|
||||
@@ -522,17 +499,19 @@ void CPanel::ChangeComment()
|
||||
else if (propVariant.vt != VT_EMPTY)
|
||||
return;
|
||||
}
|
||||
UString name = GetItemRelPath(realIndex);
|
||||
UString name = GetItemRelPath2(realIndex);
|
||||
CComboDialog dlg;
|
||||
dlg.Title = name + L' ' + LangString(IDS_COMMENT);
|
||||
dlg.Title = name;
|
||||
dlg.Title += L" : ";
|
||||
AddLangString(dlg.Title, IDS_COMMENT);
|
||||
dlg.Value = comment;
|
||||
LangString(IDS_COMMENT2, dlg.Static);
|
||||
if (dlg.Create(GetParent()) != IDOK)
|
||||
return;
|
||||
NCOM::CPropVariant propVariant = (const wchar_t *)dlg.Value;
|
||||
NCOM::CPropVariant propVariant = dlg.Value.Ptr();
|
||||
|
||||
CDisableNotify disableNotify(*this);
|
||||
HRESULT result = folderOperations->SetProperty(realIndex, kpidComment, &propVariant, NULL);
|
||||
HRESULT result = _folderOperations->SetProperty(realIndex, kpidComment, &propVariant, NULL);
|
||||
if (result != S_OK)
|
||||
{
|
||||
if (result == E_NOINTERFACE)
|
||||
|
||||
@@ -22,7 +22,9 @@ void CPanel::OnShiftSelectMessage()
|
||||
return;
|
||||
int startItem = MyMin(focusedItem, _prevFocusedItem);
|
||||
int finishItem = MyMax(focusedItem, _prevFocusedItem);
|
||||
for (int i = 0; i < _listView.GetItemCount(); i++)
|
||||
|
||||
int numItems = _listView.GetItemCount();
|
||||
for (int i = 0; i < numItems; i++)
|
||||
{
|
||||
int realIndex = GetRealItemIndex(i);
|
||||
if (realIndex == kParentIndex)
|
||||
@@ -34,6 +36,7 @@ void CPanel::OnShiftSelectMessage()
|
||||
_listView.RedrawItem(i);
|
||||
}
|
||||
}
|
||||
|
||||
_prevFocusedItem = focusedItem;
|
||||
}
|
||||
|
||||
@@ -45,6 +48,7 @@ void CPanel::OnArrowWithShift()
|
||||
if (focusedItem < 0)
|
||||
return;
|
||||
int realIndex = GetRealItemIndex(focusedItem);
|
||||
|
||||
if (_selectionIsDefined)
|
||||
{
|
||||
if (realIndex != kParentIndex)
|
||||
@@ -64,6 +68,7 @@ void CPanel::OnArrowWithShift()
|
||||
_selectedStatusVector[realIndex] = _selectMark;
|
||||
}
|
||||
}
|
||||
|
||||
_prevFocusedItem = focusedItem;
|
||||
PostMessage(kShiftSelectMessage);
|
||||
_listView.RedrawItem(focusedItem);
|
||||
@@ -165,13 +170,6 @@ void CPanel::SelectByType(bool selectMode)
|
||||
UString name = GetItemName(realIndex);
|
||||
bool isItemFolder = IsItem_Folder(realIndex);
|
||||
|
||||
/*
|
||||
UInt32 numItems;
|
||||
_folder->GetNumberOfItems(&numItems);
|
||||
if ((UInt32)_selectedStatusVector.Size() != numItems)
|
||||
throw 11111;
|
||||
*/
|
||||
|
||||
if (isItemFolder)
|
||||
{
|
||||
FOR_VECTOR (i, _selectedStatusVector)
|
||||
@@ -180,11 +178,11 @@ void CPanel::SelectByType(bool selectMode)
|
||||
}
|
||||
else
|
||||
{
|
||||
int pos = name.ReverseFind(L'.');
|
||||
int pos = name.ReverseFind_Dot();
|
||||
if (pos < 0)
|
||||
{
|
||||
FOR_VECTOR (i, _selectedStatusVector)
|
||||
if (IsItem_Folder(i) == isItemFolder && GetItemName(i).ReverseFind(L'.') < 0)
|
||||
if (IsItem_Folder(i) == isItemFolder && GetItemName(i).ReverseFind_Dot() < 0)
|
||||
_selectedStatusVector[i] = selectMode;
|
||||
}
|
||||
else
|
||||
@@ -196,6 +194,7 @@ void CPanel::SelectByType(bool selectMode)
|
||||
_selectedStatusVector[i] = selectMode;
|
||||
}
|
||||
}
|
||||
|
||||
UpdateSelection();
|
||||
}
|
||||
|
||||
@@ -253,10 +252,11 @@ void CPanel::OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate)
|
||||
{
|
||||
if (itemActivate->hdr.hwndFrom != HWND(_listView))
|
||||
return;
|
||||
// It will be work only for Version 4.71 (IE 4);
|
||||
// It will work only for Version 4.71 (IE 4);
|
||||
int indexInList = itemActivate->iItem;
|
||||
if (indexInList < 0)
|
||||
return;
|
||||
|
||||
#ifndef UNDER_CE
|
||||
if ((itemActivate->uKeyFlags & LVKF_SHIFT) != 0)
|
||||
{
|
||||
@@ -264,9 +264,11 @@ void CPanel::OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate)
|
||||
int focusedIndex = _startGroupSelect;
|
||||
if (focusedIndex < 0)
|
||||
return;
|
||||
unsigned startItem = MyMin((unsigned)focusedIndex, (unsigned)indexInList);
|
||||
unsigned finishItem = MyMax((unsigned)focusedIndex, (unsigned)indexInList);
|
||||
FOR_VECTOR (i, _selectedStatusVector)
|
||||
int startItem = MyMin(focusedIndex, indexInList);
|
||||
int finishItem = MyMax(focusedIndex, indexInList);
|
||||
|
||||
int numItems = _listView.GetItemCount();
|
||||
for (int i = 0; i < numItems; i++)
|
||||
{
|
||||
int realIndex = GetRealItemIndex(i);
|
||||
if (realIndex == kParentIndex)
|
||||
@@ -283,6 +285,7 @@ void CPanel::OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate)
|
||||
#endif
|
||||
{
|
||||
_startGroupSelect = indexInList;
|
||||
|
||||
#ifndef UNDER_CE
|
||||
if ((itemActivate->uKeyFlags & LVKF_CONTROL) != 0)
|
||||
{
|
||||
@@ -295,5 +298,6 @@ void CPanel::OnLeftClick(MY_NMLISTVIEW_NMITEMACTIVATE *itemActivate)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ static int CompareFileNames_Le16(const Byte *s1, unsigned size1, const Byte *s2,
|
||||
|
||||
static inline const wchar_t *GetExtensionPtr(const UString &name)
|
||||
{
|
||||
int dotPos = name.ReverseFind(L'.');
|
||||
int dotPos = name.ReverseFind_Dot();
|
||||
return name.Ptr((dotPos < 0) ? name.Len() : dotPos);
|
||||
}
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ HRESULT CThreadSplit::ProcessVirt()
|
||||
if (!outFile.Create(name, false))
|
||||
{
|
||||
HRESULT res = GetLastError();
|
||||
SetErrorPath1(name);
|
||||
AddErrorPath(name);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -165,7 +165,7 @@ void CApp::Split()
|
||||
{
|
||||
int srcPanelIndex = GetFocusedPanelIndex();
|
||||
CPanel &srcPanel = Panels[srcPanelIndex];
|
||||
if (!srcPanel.IsFSFolder())
|
||||
if (!srcPanel.Is_IO_FS_Folder())
|
||||
{
|
||||
srcPanel.MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED);
|
||||
return;
|
||||
@@ -187,13 +187,13 @@ void CApp::Split()
|
||||
}
|
||||
const UString itemName = srcPanel.GetItemName(index);
|
||||
|
||||
UString srcPath = srcPanel._currentFolderPrefix + srcPanel.GetItemPrefix(index);
|
||||
UString srcPath = srcPanel.GetFsPath() + srcPanel.GetItemPrefix(index);
|
||||
UString path = srcPath;
|
||||
int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
|
||||
CPanel &destPanel = Panels[destPanelIndex];
|
||||
if (NumPanels > 1)
|
||||
if (destPanel.IsFSFolder())
|
||||
path = destPanel._currentFolderPrefix;
|
||||
path = destPanel.GetFsPath();
|
||||
CSplitDialog splitDialog;
|
||||
splitDialog.FilePath = srcPanel.GetItemRelPath(index);
|
||||
splitDialog.Path = path;
|
||||
@@ -243,12 +243,13 @@ void CApp::Split()
|
||||
|
||||
progressDialog.MainWindow = _window;
|
||||
progressDialog.MainTitle = progressWindowTitle;
|
||||
progressDialog.MainAddTitle = title + L' ';
|
||||
progressDialog.MainAddTitle = title;
|
||||
progressDialog.MainAddTitle.Add_Space();
|
||||
progressDialog.Sync.Set_TitleFileName(itemName);
|
||||
|
||||
|
||||
spliter.FilePath = us2fs(srcPath + itemName);
|
||||
spliter.VolBasePath = us2fs(path + itemName);
|
||||
spliter.VolBasePath = us2fs(path + srcPanel.GetItemName_for_Copy(index));
|
||||
spliter.VolumeSizes = splitDialog.VolumeSizes;
|
||||
|
||||
// if (splitDialog.VolumeSizes.Size() == 0) return;
|
||||
@@ -285,7 +286,7 @@ HRESULT CThreadCombine::ProcessVirt()
|
||||
if (!outFile.Create(OutputPath, false))
|
||||
{
|
||||
HRESULT res = GetLastError();
|
||||
SetErrorPath1(OutputPath);
|
||||
AddErrorPath(OutputPath);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -304,7 +305,7 @@ HRESULT CThreadCombine::ProcessVirt()
|
||||
if (!inFile.Open(nextName))
|
||||
{
|
||||
HRESULT res = GetLastError();
|
||||
SetErrorPath1(nextName);
|
||||
AddErrorPath(nextName);
|
||||
return res;
|
||||
}
|
||||
sync.Set_FilePath(fs2us(nextName));
|
||||
@@ -314,7 +315,7 @@ HRESULT CThreadCombine::ProcessVirt()
|
||||
if (!inFile.Read(buffer, kBufSize, processedSize))
|
||||
{
|
||||
HRESULT res = GetLastError();
|
||||
SetErrorPath1(nextName);
|
||||
AddErrorPath(nextName);
|
||||
return res;
|
||||
}
|
||||
if (processedSize == 0)
|
||||
@@ -323,7 +324,7 @@ HRESULT CThreadCombine::ProcessVirt()
|
||||
if (!outFile.Write(buffer, needSize, processedSize))
|
||||
{
|
||||
HRESULT res = GetLastError();
|
||||
SetErrorPath1(OutputPath);
|
||||
AddErrorPath(OutputPath);
|
||||
return res;
|
||||
}
|
||||
if (needSize != processedSize)
|
||||
@@ -364,13 +365,13 @@ void CApp::Combine()
|
||||
}
|
||||
const UString itemName = srcPanel.GetItemName(index);
|
||||
|
||||
UString srcPath = srcPanel._currentFolderPrefix + srcPanel.GetItemPrefix(index);
|
||||
UString srcPath = srcPanel.GetFsPath() + srcPanel.GetItemPrefix(index);
|
||||
UString path = srcPath;
|
||||
int destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
|
||||
CPanel &destPanel = Panels[destPanelIndex];
|
||||
if (NumPanels > 1)
|
||||
if (destPanel.IsFSFolder())
|
||||
path = destPanel._currentFolderPrefix;
|
||||
path = destPanel.GetFsPath();
|
||||
|
||||
CVolSeqName volSeqName;
|
||||
if (!volSeqName.ParseName(itemName))
|
||||
@@ -408,7 +409,7 @@ void CApp::Combine()
|
||||
UString info;
|
||||
AddValuePair2(info, IDS_PROP_FILES, combiner.Names.Size(), combiner.TotalSize);
|
||||
|
||||
info += L"\n";
|
||||
info.Add_LF();
|
||||
info += srcPath;
|
||||
|
||||
unsigned i;
|
||||
@@ -425,7 +426,7 @@ void CApp::Combine()
|
||||
CCopyDialog copyDialog;
|
||||
copyDialog.Value = path;
|
||||
LangString(IDS_COMBINE, copyDialog.Title);
|
||||
copyDialog.Title += ' ';
|
||||
copyDialog.Title.Add_Space();
|
||||
copyDialog.Title += srcPanel.GetItemRelPath(index);
|
||||
LangString(IDS_COMBINE_TO, copyDialog.Static);
|
||||
copyDialog.Info = info;
|
||||
@@ -468,7 +469,8 @@ void CApp::Combine()
|
||||
|
||||
progressDialog.MainWindow = _window;
|
||||
progressDialog.MainTitle = progressWindowTitle;
|
||||
progressDialog.MainAddTitle = title + L' ';
|
||||
progressDialog.MainAddTitle = title;
|
||||
progressDialog.MainAddTitle.Add_Space();
|
||||
|
||||
combiner.InputDirPrefix = us2fs(srcPath);
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
PLUGIN_INTERFACE(IInitContextMenu, 0x00)
|
||||
{
|
||||
STDMETHOD(InitContextMenu)(const wchar_t *folder, const wchar_t **names, UInt32 numFiles) PURE;
|
||||
STDMETHOD(InitContextMenu)(const wchar_t *folder, const wchar_t * const *names, UInt32 numFiles) PURE;
|
||||
};
|
||||
|
||||
PLUGIN_INTERFACE(IPluginOptionsCallback, 0x01)
|
||||
|
||||
@@ -28,7 +28,7 @@ static const UINT kTimerElapse =
|
||||
#ifdef UNDER_CE
|
||||
500
|
||||
#else
|
||||
100
|
||||
200
|
||||
#endif
|
||||
;
|
||||
|
||||
@@ -104,13 +104,13 @@ HRESULT CProgressSync::CheckStop()
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CProgressSync::ScanProgress(UInt64 numFiles, UInt64 totalSize, const UString &fileName, bool isDir)
|
||||
HRESULT CProgressSync::ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir)
|
||||
{
|
||||
{
|
||||
CRITICAL_LOCK
|
||||
_totalFiles = numFiles;
|
||||
_totalBytes = totalSize;
|
||||
_filePath = fileName;
|
||||
_filePath = fs2us(fileName);
|
||||
_isDir = isDir;
|
||||
// _completedBytes = 0;
|
||||
CHECK_STOP
|
||||
@@ -118,10 +118,14 @@ HRESULT CProgressSync::ScanProgress(UInt64 numFiles, UInt64 totalSize, const USt
|
||||
return CheckStop();
|
||||
}
|
||||
|
||||
void CProgressSync::Set_NumFilesTotal(UInt64 val)
|
||||
HRESULT CProgressSync::Set_NumFilesTotal(UInt64 val)
|
||||
{
|
||||
CRITICAL_LOCK
|
||||
_totalFiles = val;
|
||||
{
|
||||
CRITICAL_LOCK
|
||||
_totalFiles = val;
|
||||
CHECK_STOP
|
||||
}
|
||||
return CheckStop();
|
||||
}
|
||||
|
||||
void CProgressSync::Set_NumBytesTotal(UInt64 val)
|
||||
@@ -171,16 +175,34 @@ void CProgressSync::Set_TitleFileName(const UString &fileName)
|
||||
CRITICAL_LOCK
|
||||
_titleFileName = fileName;
|
||||
}
|
||||
|
||||
void CProgressSync::Set_Status(const UString &s)
|
||||
{
|
||||
CRITICAL_LOCK
|
||||
_status = s;
|
||||
}
|
||||
|
||||
void CProgressSync::Set_FilePath(const UString &path, bool isDir)
|
||||
HRESULT CProgressSync::Set_Status2(const UString &s, const wchar_t *path, bool isDir)
|
||||
{
|
||||
{
|
||||
CRITICAL_LOCK
|
||||
_status = s;
|
||||
if (path)
|
||||
_filePath = path;
|
||||
else
|
||||
_filePath.Empty();
|
||||
_isDir = isDir;
|
||||
}
|
||||
return CheckStop();
|
||||
}
|
||||
|
||||
void CProgressSync::Set_FilePath(const wchar_t *path, bool isDir)
|
||||
{
|
||||
CRITICAL_LOCK
|
||||
_filePath = path;
|
||||
if (path)
|
||||
_filePath = path;
|
||||
else
|
||||
_filePath.Empty();
|
||||
_isDir = isDir;
|
||||
}
|
||||
|
||||
@@ -199,7 +221,7 @@ void CProgressSync::AddError_Message_Name(const wchar_t *message, const wchar_t
|
||||
if (message && *message != 0 )
|
||||
{
|
||||
if (!s.IsEmpty())
|
||||
s += L'\n';
|
||||
s.Add_LF();
|
||||
s += message;
|
||||
if (!s.IsEmpty() && s.Back() == L'\n')
|
||||
s.DeleteBack();
|
||||
@@ -633,7 +655,6 @@ static unsigned GetPower64(UInt64 val)
|
||||
if (high == 0)
|
||||
return GetPower32((UInt32)val);
|
||||
return GetPower32(high) + 32;
|
||||
|
||||
}
|
||||
|
||||
static UInt64 MyMultAndDiv(UInt64 mult1, UInt64 mult2, UInt64 divider)
|
||||
@@ -867,7 +888,7 @@ void CProgressDialog::UpdateStatInfo(bool showAll)
|
||||
s1 = _filePath;
|
||||
else
|
||||
{
|
||||
int slashPos = _filePath.ReverseFind(WCHAR_PATH_SEPARATOR);
|
||||
int slashPos = _filePath.ReverseFind_PathSepar();
|
||||
if (slashPos >= 0)
|
||||
{
|
||||
s1.SetFrom(_filePath, slashPos + 1);
|
||||
@@ -878,7 +899,7 @@ void CProgressDialog::UpdateStatInfo(bool showAll)
|
||||
}
|
||||
ReduceString(s1, _numReduceSymbols);
|
||||
ReduceString(s2, _numReduceSymbols);
|
||||
s1 += L'\n';
|
||||
s1.Add_LF();
|
||||
s1 += s2;
|
||||
SetItemText(IDT_PROGRESS_FILE_NAME, s1);
|
||||
}
|
||||
@@ -1025,22 +1046,22 @@ void CProgressDialog::SetTitleText()
|
||||
if (Sync.Get_Paused())
|
||||
{
|
||||
s += _paused_String;
|
||||
s += L' ';
|
||||
s.Add_Space();
|
||||
}
|
||||
if (IS_DEFINED_VAL(_prevPercentValue))
|
||||
{
|
||||
wchar_t temp[32];
|
||||
char temp[32];
|
||||
ConvertUInt64ToString(_prevPercentValue, temp);
|
||||
s += temp;
|
||||
s.AddAscii(temp);
|
||||
s += L'%';
|
||||
}
|
||||
if (!_foreground)
|
||||
{
|
||||
s += L' ';
|
||||
s.Add_Space();
|
||||
s += _backgrounded_String;
|
||||
}
|
||||
|
||||
s += L' ';
|
||||
s.Add_Space();
|
||||
#ifndef _SFX
|
||||
{
|
||||
unsigned len = s.Len();
|
||||
@@ -1055,7 +1076,7 @@ void CProgressDialog::SetTitleText()
|
||||
{
|
||||
UString fileName = _titleFileName;
|
||||
ReduceString(fileName, kTitleFileNameSizeLimit);
|
||||
s += L' ';
|
||||
s.Add_Space();
|
||||
s += fileName;
|
||||
}
|
||||
SetText(s);
|
||||
@@ -1239,7 +1260,7 @@ static void AddMessageToString(UString &dest, const UString &src)
|
||||
if (!src.IsEmpty())
|
||||
{
|
||||
if (!dest.IsEmpty())
|
||||
dest += L'\n';
|
||||
dest.Add_LF();
|
||||
dest += src;
|
||||
}
|
||||
}
|
||||
@@ -1266,8 +1287,15 @@ void CProgressThreadVirt::Process()
|
||||
m = HResultToMessage(Result);
|
||||
}
|
||||
AddMessageToString(m, FinalMessage.ErrorMessage.Message);
|
||||
AddMessageToString(m, fs2us(ErrorPath1));
|
||||
AddMessageToString(m, fs2us(ErrorPath2));
|
||||
|
||||
{
|
||||
FOR_VECTOR(i, ErrorPaths)
|
||||
{
|
||||
if (i >= 32)
|
||||
break;
|
||||
AddMessageToString(m, fs2us(ErrorPaths[i]));
|
||||
}
|
||||
}
|
||||
|
||||
CProgressSync &sync = ProgressDialog.Sync;
|
||||
NSynchronization::CCriticalSectionLock lock(sync._cs);
|
||||
|
||||
@@ -80,9 +80,9 @@ public:
|
||||
}
|
||||
|
||||
HRESULT CheckStop();
|
||||
HRESULT ScanProgress(UInt64 numFiles, UInt64 totalSize, const UString &fileName, bool isDir = false);
|
||||
HRESULT ScanProgress(UInt64 numFiles, UInt64 totalSize, const FString &fileName, bool isDir = false);
|
||||
|
||||
void Set_NumFilesTotal(UInt64 val);
|
||||
HRESULT Set_NumFilesTotal(UInt64 val);
|
||||
void Set_NumBytesTotal(UInt64 val);
|
||||
void Set_NumFilesCur(UInt64 val);
|
||||
HRESULT Set_NumBytesCur(const UInt64 *val);
|
||||
@@ -91,7 +91,8 @@ public:
|
||||
|
||||
void Set_TitleFileName(const UString &fileName);
|
||||
void Set_Status(const UString &s);
|
||||
void Set_FilePath(const UString &path, bool isDir = false);
|
||||
HRESULT Set_Status2(const UString &s, const wchar_t *path, bool isDir = false);
|
||||
void Set_FilePath(const wchar_t *path, bool isDir = false);
|
||||
|
||||
void AddError_Message(const wchar_t *message);
|
||||
void AddError_Message_Name(const wchar_t *message, const wchar_t *name);
|
||||
@@ -274,9 +275,8 @@ public:
|
||||
|
||||
class CProgressThreadVirt
|
||||
{
|
||||
FString ErrorPath1;
|
||||
FString ErrorPath2;
|
||||
protected:
|
||||
FStringVector ErrorPaths;
|
||||
CProgressFinalMessage FinalMessage;
|
||||
|
||||
// error if any of HRESULT, ErrorMessage, ErrorPath
|
||||
@@ -299,8 +299,7 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetErrorPath1(const FString &path) { ErrorPath1 = path; }
|
||||
void SetErrorPath2(const FString &path) { ErrorPath2 = path; }
|
||||
void AddErrorPath(const FString &path) { ErrorPaths.Add(path); }
|
||||
|
||||
HRESULT Create(const UString &title, HWND parentWindow = 0);
|
||||
CProgressThreadVirt(): Result(E_FAIL), ThreadFinishedOK(false) {}
|
||||
|
||||
@@ -94,4 +94,6 @@ BEGIN
|
||||
IDS_PROP_HARD_LINK "Hard Link"
|
||||
IDS_PROP_INODE "iNode"
|
||||
IDS_PROP_STREAM_ID "Stream ID"
|
||||
IDS_PROP_READ_ONLY "Read-only"
|
||||
IDS_PROP_OUT_NAME "Out Name"
|
||||
END
|
||||
|
||||
@@ -90,3 +90,5 @@
|
||||
#define IDS_PROP_HARD_LINK 1090
|
||||
#define IDS_PROP_INODE 1091
|
||||
#define IDS_PROP_STREAM_ID 1092
|
||||
#define IDS_PROP_READ_ONLY 1093
|
||||
#define IDS_PROP_OUT_NAME 1094
|
||||
|
||||
@@ -86,8 +86,7 @@ bool CShellExtInfo::ReadFromRegistry(HKEY hkey, const CSysString &ext)
|
||||
|
||||
bool CShellExtInfo::IsIt7Zip() const
|
||||
{
|
||||
UString s = GetUnicodeString(k7zipPrefix);
|
||||
return MyStringCompareNoCase_N(GetUnicodeString(ProgramKey), s, s.Len()) == 0;
|
||||
return IsString1PrefixedByString2_NoCase(GetUnicodeString(ProgramKey), GetUnicodeString(k7zipPrefix));
|
||||
}
|
||||
|
||||
LONG DeleteShellExtensionInfo(HKEY hkey, const CSysString &ext)
|
||||
|
||||
@@ -10,11 +10,25 @@
|
||||
|
||||
#include "../../PropID.h"
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
#define USE_WIN_PATHS
|
||||
#endif
|
||||
|
||||
static const unsigned kNumRootFolderItems =
|
||||
#ifdef USE_WIN_PATHS
|
||||
4
|
||||
#else
|
||||
1
|
||||
#endif
|
||||
;
|
||||
|
||||
|
||||
#include "FSFolder.h"
|
||||
#include "LangUtils.h"
|
||||
#ifndef UNDER_CE
|
||||
#ifdef USE_WIN_PATHS
|
||||
#include "NetFolder.h"
|
||||
#include "FSDrives.h"
|
||||
#include "AltStreamsFolder.h"
|
||||
#endif
|
||||
#include "RootFolder.h"
|
||||
#include "SysIconUtils.h"
|
||||
@@ -30,10 +44,10 @@ static const PROPID kProps[] =
|
||||
|
||||
UString RootFolder_GetName_Computer(int &iconIndex)
|
||||
{
|
||||
#ifdef UNDER_CE
|
||||
GetRealIconIndex(FTEXT("\\"), FILE_ATTRIBUTE_DIRECTORY, iconIndex);
|
||||
#else
|
||||
#ifdef USE_WIN_PATHS
|
||||
iconIndex = GetIconIndexForCSIDL(CSIDL_DRIVES);
|
||||
#else
|
||||
GetRealIconIndex(FSTRING_PATH_SEPARATOR, FILE_ATTRIBUTE_DIRECTORY, iconIndex);
|
||||
#endif
|
||||
return LangString(IDS_COMPUTER);
|
||||
}
|
||||
@@ -53,21 +67,21 @@ UString RootFolder_GetName_Documents(int &iconIndex)
|
||||
enum
|
||||
{
|
||||
ROOT_INDEX_COMPUTER = 0
|
||||
#ifndef UNDER_CE
|
||||
#ifdef USE_WIN_PATHS
|
||||
, ROOT_INDEX_DOCUMENTS
|
||||
, ROOT_INDEX_NETWORK
|
||||
, ROOT_INDEX_VOLUMES
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifndef UNDER_CE
|
||||
#ifdef USE_WIN_PATHS
|
||||
static const wchar_t *kVolPrefix = L"\\\\.";
|
||||
#endif
|
||||
|
||||
void CRootFolder::Init()
|
||||
{
|
||||
_names[ROOT_INDEX_COMPUTER] = RootFolder_GetName_Computer(_iconIndices[ROOT_INDEX_COMPUTER]);
|
||||
#ifndef UNDER_CE
|
||||
#ifdef USE_WIN_PATHS
|
||||
_names[ROOT_INDEX_DOCUMENTS] = RootFolder_GetName_Documents(_iconIndices[ROOT_INDEX_DOCUMENTS]);
|
||||
_names[ROOT_INDEX_NETWORK] = RootFolder_GetName_Network(_iconIndices[ROOT_INDEX_NETWORK]);
|
||||
_names[ROOT_INDEX_VOLUMES] = kVolPrefix;
|
||||
@@ -124,8 +138,7 @@ UString GetMyDocsPath()
|
||||
us = GetUnicodeString(s2);
|
||||
}
|
||||
#endif
|
||||
if (us.Len() > 0 && us.Back() != WCHAR_PATH_SEPARATOR)
|
||||
us += WCHAR_PATH_SEPARATOR;
|
||||
NFile::NName::NormalizeDirPathPrefix(us);
|
||||
return us;
|
||||
}
|
||||
|
||||
@@ -133,14 +146,8 @@ STDMETHODIMP CRootFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolde
|
||||
{
|
||||
*resultFolder = NULL;
|
||||
CMyComPtr<IFolderFolder> subFolder;
|
||||
#ifdef UNDER_CE
|
||||
if (index == ROOT_INDEX_COMPUTER)
|
||||
{
|
||||
NFsFolder::CFSFolder *fsFolder = new NFsFolder::CFSFolder;
|
||||
subFolder = fsFolder;
|
||||
fsFolder->InitToRoot();
|
||||
}
|
||||
#else
|
||||
|
||||
#ifdef USE_WIN_PATHS
|
||||
if (index == ROOT_INDEX_COMPUTER || index == ROOT_INDEX_VOLUMES)
|
||||
{
|
||||
CFSDrives *fsDrivesSpec = new CFSDrives;
|
||||
@@ -160,12 +167,20 @@ STDMETHODIMP CRootFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolde
|
||||
{
|
||||
NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder;
|
||||
subFolder = fsFolderSpec;
|
||||
RINOK(fsFolderSpec->Init(us2fs(s), NULL));
|
||||
RINOK(fsFolderSpec->Init(us2fs(s)));
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (index == ROOT_INDEX_COMPUTER)
|
||||
{
|
||||
NFsFolder::CFSFolder *fsFolder = new NFsFolder::CFSFolder;
|
||||
subFolder = fsFolder;
|
||||
fsFolder->InitToRoot();
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
|
||||
*resultFolder = subFolder.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
@@ -185,6 +200,7 @@ STDMETHODIMP CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resu
|
||||
*resultFolder = 0;
|
||||
UString name2 = name;
|
||||
name2.Trim();
|
||||
|
||||
if (name2.IsEmpty())
|
||||
{
|
||||
CRootFolder *rootFolderSpec = new CRootFolder;
|
||||
@@ -193,21 +209,25 @@ STDMETHODIMP CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resu
|
||||
*resultFolder = rootFolder.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
for (int i = 0; i < kNumRootFolderItems; i++)
|
||||
|
||||
for (unsigned i = 0; i < kNumRootFolderItems; i++)
|
||||
if (AreEqualNames(name2, _names[i]))
|
||||
return BindToFolder((UInt32)i, resultFolder);
|
||||
#ifdef UNDER_CE
|
||||
if (name2 == L"\\")
|
||||
return BindToFolder((UInt32)ROOT_INDEX_COMPUTER, resultFolder);
|
||||
#else
|
||||
|
||||
#ifdef USE_WIN_PATHS
|
||||
if (AreEqualNames(name2, L"My Documents") ||
|
||||
AreEqualNames(name2, L"Documents"))
|
||||
return BindToFolder((UInt32)ROOT_INDEX_DOCUMENTS, resultFolder);
|
||||
#else
|
||||
if (name2 == WSTRING_PATH_SEPARATOR)
|
||||
return BindToFolder((UInt32)ROOT_INDEX_COMPUTER, resultFolder);
|
||||
#endif
|
||||
|
||||
if (AreEqualNames(name2, L"My Computer") ||
|
||||
AreEqualNames(name2, L"Computer"))
|
||||
return BindToFolder((UInt32)ROOT_INDEX_COMPUTER, resultFolder);
|
||||
if (name2 == UString(WCHAR_PATH_SEPARATOR))
|
||||
|
||||
if (name2 == WSTRING_PATH_SEPARATOR)
|
||||
{
|
||||
CMyComPtr<IFolderFolder> subFolder = this;
|
||||
*resultFolder = subFolder.Detach();
|
||||
@@ -219,7 +239,7 @@ STDMETHODIMP CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resu
|
||||
|
||||
CMyComPtr<IFolderFolder> subFolder;
|
||||
|
||||
#ifndef UNDER_CE
|
||||
#ifdef USE_WIN_PATHS
|
||||
if (name2.IsPrefixedBy(kVolPrefix))
|
||||
{
|
||||
CFSDrives *folderSpec = new CFSDrives;
|
||||
@@ -232,16 +252,22 @@ STDMETHODIMP CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resu
|
||||
subFolder = folderSpec;
|
||||
folderSpec->Init(false, true);
|
||||
}
|
||||
else if (name2.Back() == ':')
|
||||
{
|
||||
NAltStreamsFolder::CAltStreamsFolder *folderSpec = new NAltStreamsFolder::CAltStreamsFolder;
|
||||
subFolder = folderSpec;
|
||||
if (folderSpec->Init(us2fs(name2)) != S_OK)
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (name2[name2.Len() - 1] != WCHAR_PATH_SEPARATOR)
|
||||
name2 += WCHAR_PATH_SEPARATOR;
|
||||
NFile::NName::NormalizeDirPathPrefix(name2);
|
||||
NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder;
|
||||
subFolder = fsFolderSpec;
|
||||
if (fsFolderSpec->Init(us2fs(name2), 0) != S_OK)
|
||||
if (fsFolderSpec->Init(us2fs(name2)) != S_OK)
|
||||
{
|
||||
#ifndef UNDER_CE
|
||||
#ifdef USE_WIN_PATHS
|
||||
if (name2[0] == WCHAR_PATH_SEPARATOR)
|
||||
{
|
||||
CNetFolder *netFolderSpec = new CNetFolder;
|
||||
@@ -253,6 +279,7 @@ STDMETHODIMP CRootFolder::BindToFolder(const wchar_t *name, IFolderFolder **resu
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
*resultFolder = subFolder.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
@@ -267,11 +294,11 @@ IMP_IFolderFolder_Props(CRootFolder)
|
||||
|
||||
STDMETHODIMP CRootFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
NWindows::NCOM::CPropVariant prop;
|
||||
switch(propID)
|
||||
NCOM::CPropVariant prop;
|
||||
switch (propID)
|
||||
{
|
||||
case kpidType: prop = L"RootFolder"; break;
|
||||
case kpidPath: prop = L""; break;
|
||||
case kpidType: prop = "RootFolder"; break;
|
||||
case kpidPath: prop = ""; break;
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
|
||||
@@ -7,21 +7,15 @@
|
||||
|
||||
#include "IFolder.h"
|
||||
|
||||
const int kNumRootFolderItems =
|
||||
#ifdef UNDER_CE
|
||||
1
|
||||
#else
|
||||
4
|
||||
#endif
|
||||
;
|
||||
const unsigned kNumRootFolderItems_Max = 4;
|
||||
|
||||
class CRootFolder:
|
||||
public IFolderFolder,
|
||||
public IFolderGetSystemIconIndex,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
UString _names[kNumRootFolderItems];
|
||||
int _iconIndices[kNumRootFolderItems];
|
||||
UString _names[kNumRootFolderItems_Max];
|
||||
int _iconIndices[kNumRootFolderItems_Max];
|
||||
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(IFolderGetSystemIconIndex)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "SettingsPageRes.h"
|
||||
#include "../../GuiCommon.rc"
|
||||
|
||||
#define xc 200
|
||||
#define xc 240
|
||||
#define yc 120
|
||||
|
||||
IDD_SETTINGS MY_PAGE
|
||||
|
||||
@@ -38,7 +38,7 @@ bool CSplitDialog::OnInit()
|
||||
{
|
||||
UString title;
|
||||
GetText(title);
|
||||
title += L' ';
|
||||
title.Add_Space();
|
||||
title += FilePath;
|
||||
SetText(title);
|
||||
}
|
||||
|
||||
@@ -54,14 +54,17 @@ void SplitString(const UString &srcString, UStringVector &destStrings)
|
||||
destStrings.Add(s);
|
||||
}
|
||||
|
||||
/*
|
||||
UString JoinStrings(const UStringVector &srcStrings)
|
||||
{
|
||||
|
||||
UString s;
|
||||
FOR_VECTOR (i, srcStrings)
|
||||
{
|
||||
if (i != 0)
|
||||
s += L' ';
|
||||
s.Add_Space();
|
||||
s += srcStrings[i];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../../../Common/StringConvert.h"
|
||||
#include "../../../Common/Defs.h"
|
||||
|
||||
#include "../../../Windows/DLL.h"
|
||||
#include "../../../Windows/ErrorMsg.h"
|
||||
@@ -16,6 +17,10 @@
|
||||
|
||||
using namespace NWindows;
|
||||
|
||||
#ifndef _UNICODE
|
||||
extern bool g_IsNT;
|
||||
#endif
|
||||
|
||||
static const UInt32 kLangIDs[] =
|
||||
{
|
||||
IDT_SYSTEM_ASSOCIATE
|
||||
@@ -48,8 +53,8 @@ int CSystemPage::AddIcon(const UString &iconPath, int iconIndex)
|
||||
// we expand path from REG_EXPAND_SZ registry item.
|
||||
UString path;
|
||||
DWORD size = MAX_PATH + 10;
|
||||
DWORD needLen = ::ExpandEnvironmentStringsW(iconPath, path.GetBuffer((int)size + 1), size);
|
||||
path.ReleaseBuffer();
|
||||
DWORD needLen = ::ExpandEnvironmentStringsW(iconPath, path.GetBuf(size + 2), size);
|
||||
path.ReleaseBuf_CalcLen(size);
|
||||
if (needLen == 0 || needLen >= size)
|
||||
path = iconPath;
|
||||
int num = ExtractIconExW(path, iconIndex, NULL, &hicon, 1);
|
||||
@@ -140,32 +145,49 @@ bool CSystemPage::OnInit()
|
||||
|
||||
_listView.InsertColumn(0, LangString(IDS_PROP_FILE_TYPE), 72);
|
||||
|
||||
CSysString s;
|
||||
UString s;
|
||||
|
||||
#if NUM_EXT_GROUPS == 1
|
||||
s = TEXT("Program");
|
||||
s.SetFromAscii("Program");
|
||||
#else
|
||||
#ifndef UNDER_CE
|
||||
DWORD size = 256;
|
||||
BOOL res = GetUserName(s.GetBuffer(size), &size);
|
||||
s.ReleaseBuffer();
|
||||
const unsigned kSize = 256;
|
||||
BOOL res;
|
||||
|
||||
DWORD size = kSize;
|
||||
#ifndef _UNICODE
|
||||
if (!g_IsNT)
|
||||
{
|
||||
AString s2;
|
||||
res = GetUserNameA(s2.GetBuf(size), &size);
|
||||
s2.ReleaseBuf_CalcLen(MyMin((unsigned)size, kSize));
|
||||
s = GetUnicodeString(s2);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
res = GetUserNameW(s.GetBuf(size), &size);
|
||||
s.ReleaseBuf_CalcLen(MyMin((unsigned)size, kSize));
|
||||
}
|
||||
|
||||
if (!res)
|
||||
#endif
|
||||
s = TEXT("Current User");
|
||||
s.SetFromAscii("Current User");
|
||||
#endif
|
||||
|
||||
LVCOLUMN ci;
|
||||
LV_COLUMNW ci;
|
||||
ci.mask = LVCF_TEXT | LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
|
||||
ci.cx = 100;
|
||||
ci.pszText = (TCHAR *)(const TCHAR *)s;
|
||||
ci.iSubItem = 1;
|
||||
ci.cx = 128;
|
||||
ci.fmt = LVCFMT_CENTER;
|
||||
ci.pszText = (WCHAR *)(const WCHAR *)s;
|
||||
ci.iSubItem = 1;
|
||||
_listView.InsertColumn(1, &ci);
|
||||
|
||||
#if NUM_EXT_GROUPS > 1
|
||||
{
|
||||
LangString(IDS_SYSTEM_ALL_USERS, s);
|
||||
ci.pszText = (WCHAR *)(const WCHAR *)s;
|
||||
ci.iSubItem = 2;
|
||||
ci.pszText = (LPTSTR)TEXT("All Users");
|
||||
_listView.InsertColumn(2, &ci);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -40,7 +40,7 @@ struct CModifiedExtInfo: public NRegistryAssoc::CShellExtInfo
|
||||
Other = true;
|
||||
if (IsIt7Zip())
|
||||
{
|
||||
Other7Zip = !iconPath.IsEqualToNoCase(IconPath);
|
||||
Other7Zip = !iconPath.IsEqualTo_NoCase(IconPath);
|
||||
if (!Other7Zip)
|
||||
{
|
||||
State = kExtState_7Zip;
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
#include "SystemPageRes.h"
|
||||
#include "../../GuiCommon.rc"
|
||||
|
||||
#define xc 200
|
||||
#define yc 250
|
||||
#define xc 240
|
||||
#define yc 252
|
||||
|
||||
IDD_SYSTEM DIALOG 0, 0, xs, ys MY_PAGE_STYLE MY_FONT
|
||||
CAPTION "System"
|
||||
BEGIN
|
||||
LTEXT "Associate 7-Zip with:", IDT_SYSTEM_ASSOCIATE, m, m, xc, 8
|
||||
PUSHBUTTON "+", IDB_SYSTEM_CURRENT, 72, m + 12, 40, bys
|
||||
PUSHBUTTON "+", IDB_SYSTEM_ALL, 140, m + 12, 40, bys
|
||||
PUSHBUTTON "+", IDB_SYSTEM_CURRENT, 80, m + 12, 40, bys
|
||||
PUSHBUTTON "+", IDB_SYSTEM_ALL, 166, m + 12, 40, bys
|
||||
CONTROL "List1", IDL_SYSTEM_ASSOCIATE, "SysListView32",
|
||||
LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,
|
||||
m, m + 32, xc, (yc - m - 32 - 1)
|
||||
m, m + 32, xc, (yc - 32)
|
||||
END
|
||||
|
||||
#ifdef UNDER_CE
|
||||
@@ -32,7 +32,12 @@ BEGIN
|
||||
PUSHBUTTON "+", IDB_SYSTEM_CURRENT, 60, m + 12, 40, bys
|
||||
CONTROL "List1", IDL_SYSTEM_ASSOCIATE, "SysListView32",
|
||||
LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SHAREIMAGELISTS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,
|
||||
m, m + 32, xc, (yc - m - 32 - 1 - 8)
|
||||
m, m + 32, xc, (yc - 32)
|
||||
END
|
||||
|
||||
#endif
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_SYSTEM_ALL_USERS "All users"
|
||||
END
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define IDD_SYSTEM_2 12200
|
||||
|
||||
#define IDT_SYSTEM_ASSOCIATE 2201
|
||||
#define IDS_SYSTEM_ALL_USERS 2202
|
||||
|
||||
#define IDL_SYSTEM_ASSOCIATE 100
|
||||
#define IDB_SYSTEM_CURRENT 101
|
||||
|
||||
@@ -185,6 +185,6 @@ void CPairsStorage::SaveToString(UString &text) const
|
||||
text += L' ';
|
||||
text += pair.Value;
|
||||
text += L'\x0D';
|
||||
text += L'\n';
|
||||
text.Add_LF();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class CPairsStorage
|
||||
int FindID(const UString &id) const;
|
||||
void Sort();
|
||||
public:
|
||||
void Clear() { Pairs.Clear(); };
|
||||
void Clear() { Pairs.Clear(); }
|
||||
bool ReadFromString(const UString &text);
|
||||
void SaveToString(UString &text) const;
|
||||
|
||||
|
||||
@@ -2,13 +2,27 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "PasswordDialog.h"
|
||||
#include "../../../Windows/ErrorMsg.h"
|
||||
|
||||
#include "../GUI/resource3.h"
|
||||
|
||||
#include "LangUtils.h"
|
||||
#include "UpdateCallback100.h"
|
||||
|
||||
STDMETHODIMP CUpdateCallback100Imp::ScanProgress(UInt64 /* numFolders */, UInt64 numFiles, UInt64 totalSize, const wchar_t *path, Int32 /* isDir */)
|
||||
{
|
||||
return ProgressDialog->Sync.ScanProgress(numFiles, totalSize, us2fs(path));
|
||||
}
|
||||
|
||||
STDMETHODIMP CUpdateCallback100Imp::ScanError(const wchar_t *path, HRESULT errorCode)
|
||||
{
|
||||
ProgressDialog->Sync.AddError_Code_Name(errorCode, path);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CUpdateCallback100Imp::SetNumFiles(UInt64 numFiles)
|
||||
{
|
||||
ProgressDialog->Sync.Set_NumFilesTotal(numFiles);
|
||||
return S_OK;
|
||||
return ProgressDialog->Sync.Set_NumFilesTotal(numFiles);
|
||||
}
|
||||
|
||||
STDMETHODIMP CUpdateCallback100Imp::SetTotal(UInt64 size)
|
||||
@@ -30,35 +44,63 @@ STDMETHODIMP CUpdateCallback100Imp::SetRatioInfo(const UInt64 *inSize, const UIn
|
||||
|
||||
STDMETHODIMP CUpdateCallback100Imp::CompressOperation(const wchar_t *name)
|
||||
{
|
||||
ProgressDialog->Sync.Set_FilePath(name);
|
||||
return S_OK;
|
||||
return SetOperation_Base(NUpdateNotifyOp::kAdd, name, false);
|
||||
}
|
||||
|
||||
STDMETHODIMP CUpdateCallback100Imp::DeleteOperation(const wchar_t *name)
|
||||
{
|
||||
ProgressDialog->Sync.Set_FilePath(name);
|
||||
return S_OK;
|
||||
return SetOperation_Base(NUpdateNotifyOp::kDelete, name, false);
|
||||
}
|
||||
|
||||
STDMETHODIMP CUpdateCallback100Imp::OperationResult(Int32 /* operationResult */)
|
||||
{
|
||||
ProgressDialog->Sync.Set_NumFilesCur(++_numFiles);
|
||||
ProgressDialog->Sync.Set_NumFilesCur(++NumFiles);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, const wchar_t *fileName, UString &s);
|
||||
|
||||
HRESULT CUpdateCallback100Imp::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name)
|
||||
{
|
||||
if (opRes != NArchive::NExtract::NOperationResult::kOK)
|
||||
{
|
||||
UString s;
|
||||
SetExtractErrorMessage(opRes, isEncrypted, name, s);
|
||||
ProgressDialog->Sync.AddError_Message(s);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallback100Imp::ReportUpdateOperation(UInt32 notifyOp, const wchar_t *name, Int32 isDir)
|
||||
{
|
||||
return SetOperation_Base(notifyOp, name, IntToBool(isDir));
|
||||
}
|
||||
|
||||
STDMETHODIMP CUpdateCallback100Imp::UpdateErrorMessage(const wchar_t *message)
|
||||
{
|
||||
ProgressDialog->Sync.AddError_Message(message);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CUpdateCallback100Imp::OpenFileError(const wchar_t *path, HRESULT errorCode)
|
||||
{
|
||||
ProgressDialog->Sync.AddError_Code_Name(errorCode, path);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CUpdateCallback100Imp::ReadingFileError(const wchar_t *path, HRESULT errorCode)
|
||||
{
|
||||
ProgressDialog->Sync.AddError_Code_Name(errorCode, path);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CUpdateCallback100Imp::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
|
||||
{
|
||||
*password = NULL;
|
||||
*passwordIsDefined = BoolToInt(_passwordIsDefined);
|
||||
if (!_passwordIsDefined)
|
||||
*passwordIsDefined = BoolToInt(PasswordIsDefined);
|
||||
if (!PasswordIsDefined)
|
||||
return S_OK;
|
||||
return StringToBstr(_password, password);
|
||||
return StringToBstr(Password, password);
|
||||
}
|
||||
|
||||
STDMETHODIMP CUpdateCallback100Imp::SetTotal(const UInt64 * /* files */, const UInt64 * /* bytes */)
|
||||
@@ -74,14 +116,9 @@ STDMETHODIMP CUpdateCallback100Imp::SetCompleted(const UInt64 * /* files */, con
|
||||
STDMETHODIMP CUpdateCallback100Imp::CryptoGetTextPassword(BSTR *password)
|
||||
{
|
||||
*password = NULL;
|
||||
if (!_passwordIsDefined)
|
||||
if (!PasswordIsDefined)
|
||||
{
|
||||
CPasswordDialog dialog;
|
||||
ProgressDialog->WaitCreating();
|
||||
if (dialog.Create(*ProgressDialog) != IDOK)
|
||||
return E_ABORT;
|
||||
_password = dialog.Password;
|
||||
_passwordIsDefined = true;
|
||||
RINOK(ShowAskPasswordDialog())
|
||||
}
|
||||
return StringToBstr(_password, password);
|
||||
return StringToBstr(Password, password);
|
||||
}
|
||||
|
||||
@@ -9,26 +9,29 @@
|
||||
|
||||
#include "../Agent/IFolderArchive.h"
|
||||
|
||||
#include "../GUI/UpdateCallbackGUI2.h"
|
||||
|
||||
#include "ProgressDialog2.h"
|
||||
|
||||
class CUpdateCallback100Imp:
|
||||
public IFolderArchiveUpdateCallback,
|
||||
public IFolderArchiveUpdateCallback2,
|
||||
public IFolderScanProgress,
|
||||
public ICryptoGetTextPassword2,
|
||||
public ICryptoGetTextPassword,
|
||||
public IArchiveOpenCallback,
|
||||
public ICompressProgressInfo,
|
||||
public CUpdateCallbackGUI2,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
bool _passwordIsDefined;
|
||||
UString _password;
|
||||
UInt64 _numFiles;
|
||||
public:
|
||||
CProgressDialog *ProgressDialog;
|
||||
|
||||
CUpdateCallback100Imp(): ProgressDialog(0) {}
|
||||
// CUpdateCallback100Imp() {}
|
||||
|
||||
MY_UNKNOWN_IMP5(
|
||||
MY_UNKNOWN_IMP7(
|
||||
IFolderArchiveUpdateCallback,
|
||||
IFolderArchiveUpdateCallback2,
|
||||
IFolderScanProgress,
|
||||
ICryptoGetTextPassword2,
|
||||
ICryptoGetTextPassword,
|
||||
IArchiveOpenCallback,
|
||||
@@ -37,18 +40,13 @@ public:
|
||||
INTERFACE_IProgress(;)
|
||||
INTERFACE_IArchiveOpenCallback(;)
|
||||
INTERFACE_IFolderArchiveUpdateCallback(;)
|
||||
INTERFACE_IFolderArchiveUpdateCallback2(;)
|
||||
INTERFACE_IFolderScanProgress(;)
|
||||
|
||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
|
||||
|
||||
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
|
||||
STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
|
||||
|
||||
void Init(bool passwordIsDefined, const UString &password)
|
||||
{
|
||||
_passwordIsDefined = passwordIsDefined;
|
||||
_password = password;
|
||||
_numFiles = 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -302,7 +302,7 @@ void ReadCopyHistory(UStringVector &folders)
|
||||
void AddUniqueStringToHeadOfList(UStringVector &list, const UString &s)
|
||||
{
|
||||
for (unsigned i = 0; i < list.Size();)
|
||||
if (s.IsEqualToNoCase(list[i]))
|
||||
if (s.IsEqualTo_NoCase(list[i]))
|
||||
list.Delete(i);
|
||||
else
|
||||
i++;
|
||||
|
||||
@@ -97,6 +97,7 @@ EXPLORER_OBJS = \
|
||||
|
||||
GUI_OBJS = \
|
||||
$O\HashGUI.obj \
|
||||
$O\UpdateCallbackGUI2.obj \
|
||||
|
||||
COMPRESS_OBJS = \
|
||||
$O\CopyCoder.obj \
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#define IDM_CREATE_FILE 556
|
||||
// #define IDM_EXIT 557
|
||||
#define IDM_LINK 558
|
||||
#define IDM_ALT_STREAMS 559
|
||||
|
||||
#define IDM_SELECT_ALL 600
|
||||
#define IDM_DESELECT_ALL 601
|
||||
|
||||
@@ -48,6 +48,7 @@ BEGIN
|
||||
MENUITEM "Create File\tCtrl+N", IDM_CREATE_FILE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Link...", IDM_LINK
|
||||
MENUITEM "&Alternate streams", IDM_ALT_STREAMS
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "E&xit\tAlt+F4", IDCLOSE
|
||||
END
|
||||
@@ -252,5 +253,6 @@ END
|
||||
#include "SplitDialog.rc"
|
||||
#include "SystemPage.rc"
|
||||
#include "../GUI/Extract.rc"
|
||||
#include "../GUI/resource3.rc"
|
||||
#include "../Explorer/resource2.rc"
|
||||
#include "resourceGui.rc"
|
||||
|
||||
Reference in New Issue
Block a user