summaryrefslogtreecommitdiffstats
path: root/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/FileManager/FSFolder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/FileManager/FSFolder.cpp')
-rw-r--r--installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/FileManager/FSFolder.cpp701
1 files changed, 701 insertions, 0 deletions
diff --git a/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/FileManager/FSFolder.cpp b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/FileManager/FSFolder.cpp
new file mode 100644
index 000000000..9c2aaa613
--- /dev/null
+++ b/installerbuilder/libinstaller/3rdparty/p7zip_9.04/unix/CPP/7zip/UI/FileManager/FSFolder.cpp
@@ -0,0 +1,701 @@
+// FSFolder.cpp
+
+#include "StdAfx.h"
+
+#include "FSFolder.h"
+
+#include "Common/StringConvert.h"
+#include "Common/UTFConvert.h"
+#include "Common/ComTry.h"
+
+#include "Windows/Defs.h"
+#include "Windows/PropVariant.h"
+#include "Windows/FileDir.h"
+#include "Windows/FileIO.h"
+
+#include "../../PropID.h"
+
+#include "SysIconUtils.h"
+#ifdef _WIN32
+#include "FSDrives.h"
+#include "NetFolder.h"
+#endif
+
+namespace NWindows {
+namespace NFile {
+
+bool GetLongPath(LPCWSTR path, UString &longPath);
+
+}}
+
+using namespace NWindows;
+using namespace NFile;
+using namespace NFind;
+
+namespace NFsFolder {
+
+static STATPROPSTG kProperties[] =
+{
+ { NULL, kpidName, VT_BSTR},
+ // { NULL, kpidIsDir, VT_BOOL},
+ { NULL, kpidSize, VT_UI8},
+ { NULL, kpidMTime, VT_FILETIME},
+ { NULL, kpidCTime, VT_FILETIME},
+ { NULL, kpidATime, VT_FILETIME},
+ { NULL, kpidAttrib, VT_UI4},
+ { NULL, kpidPackSize, VT_UI8},
+ { NULL, kpidComment, VT_BSTR},
+ { NULL, kpidPrefix, VT_BSTR}
+};
+
+HRESULT CFSFolder::Init(const UString &path, IFolderFolder *parentFolder)
+{
+ _parentFolder = parentFolder;
+ _path = path;
+
+#ifdef _WIN32
+ _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 */);
+ if (!_findChangeNotification.IsHandleAllocated())
+ {
+ DWORD lastError = GetLastError();
+ CFindFile findFile;
+ CFileInfoW fileInfo;
+ if (!findFile.FindFirst(_path + UString(L"*"), fileInfo))
+ return lastError;
+ }
+#endif
+ return S_OK;
+}
+
+HRESULT GetFolderSize(const UString &path, UInt64 &numFolders, UInt64 &numFiles, UInt64 &size, IProgress *progress)
+{
+ RINOK(progress->SetCompleted(NULL));
+ numFiles = numFolders = size = 0;
+ CEnumeratorW enumerator(path + UString(WSTRING_PATH_SEPARATOR L"*"));
+ CFileInfoW fileInfo;
+ while (enumerator.Next(fileInfo))
+ {
+ if (fileInfo.IsDir())
+ {
+ UInt64 subFolders, subFiles, subSize;
+ RINOK(GetFolderSize(path + UString(WSTRING_PATH_SEPARATOR) + fileInfo.Name, subFolders, subFiles, subSize, progress));
+ numFolders += subFolders;
+ numFolders++;
+ numFiles += subFiles;
+ size += subSize;
+ }
+ else
+ {
+ numFiles++;
+ size += fileInfo.Size;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CFSFolder::LoadSubItems(CDirItem &dirItem, const UString &path)
+{
+ {
+ CEnumeratorW enumerator(path + L"*");
+ CDirItem fileInfo;
+ while (enumerator.Next(fileInfo))
+ {
+ fileInfo.CompressedSizeIsDefined = false;
+ /*
+ if (!GetCompressedFileSize(_path + fileInfo.Name,
+ fileInfo.CompressedSize))
+ fileInfo.CompressedSize = fileInfo.Size;
+ */
+ if (fileInfo.IsDir())
+ {
+ // fileInfo.Size = GetFolderSize(_path + fileInfo.Name);
+ fileInfo.Size = 0;
+ }
+ dirItem.Files.Add(fileInfo);
+ }
+ }
+ if (!_flatMode)
+ return S_OK;
+
+ for (int i = 0; i < dirItem.Files.Size(); i++)
+ {
+ CDirItem &item = dirItem.Files[i];
+ if (item.IsDir())
+ LoadSubItems(item, path + item.Name + WCHAR_PATH_SEPARATOR);
+ }
+ return S_OK;
+}
+
+void CFSFolder::AddRefs(CDirItem &dirItem)
+{
+ int i;
+ for (i = 0; i < dirItem.Files.Size(); i++)
+ {
+ CDirItem &item = dirItem.Files[i];
+ item.Parent = &dirItem;
+ _refs.Add(&item);
+ }
+ if (!_flatMode)
+ return;
+ for (i = 0; i < dirItem.Files.Size(); i++)
+ {
+ CDirItem &item = dirItem.Files[i];
+ if (item.IsDir())
+ AddRefs(item);
+ }
+}
+
+STDMETHODIMP CFSFolder::LoadItems()
+{
+ // OutputDebugString(TEXT("Start\n"));
+ INT32 dummy;
+ WasChanged(&dummy);
+ Clear();
+ RINOK(LoadSubItems(_root, _path));
+ AddRefs(_root);
+
+ // OutputDebugString(TEXT("Finish\n"));
+ _commentsAreLoaded = false;
+ return S_OK;
+}
+
+static const wchar_t *kDescriptionFileName = L"descript.ion";
+
+bool CFSFolder::LoadComments()
+{
+ if (_commentsAreLoaded)
+ return true;
+ _comments.Clear();
+ _commentsAreLoaded = true;
+ NIO::CInFile file;
+ if (!file.Open(_path + kDescriptionFileName))
+ return false;
+ UInt64 length;
+ if (!file.GetLength(length))
+ return false;
+ if (length >= (1 << 28))
+ return false;
+ AString s;
+ char *p = s.GetBuffer((int)((size_t)length + 1));
+ UInt32 processedSize;
+ file.Read(p, (UInt32)length, processedSize);
+ p[length] = 0;
+ s.ReleaseBuffer();
+ if (processedSize != length)
+ return false;
+ file.Close();
+ UString unicodeString;
+ if (!ConvertUTF8ToUnicode(s, unicodeString))
+ return false;
+ return _comments.ReadFromString(unicodeString);
+}
+
+static bool IsAscii(const UString &testString)
+{
+ for (int i = 0; i < testString.Length(); i++)
+ if (testString[i] >= 0x80)
+ return false;
+ return true;
+}
+
+bool CFSFolder::SaveComments()
+{
+ NIO::COutFile file;
+ if (!file.Create(_path + kDescriptionFileName, true))
+ return false;
+ UString unicodeString;
+ _comments.SaveToString(unicodeString);
+ AString utfString;
+ ConvertUnicodeToUTF8(unicodeString, utfString);
+ UInt32 processedSize;
+ if (!IsAscii(unicodeString))
+ {
+ Byte bom [] = { 0xEF, 0xBB, 0xBF, 0x0D, 0x0A };
+ file.Write(bom , sizeof(bom), processedSize);
+ }
+ file.Write(utfString, utfString.Length(), processedSize);
+ _commentsAreLoaded = false;
+ return true;
+}
+
+STDMETHODIMP CFSFolder::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = _refs.Size();
+ return S_OK;
+}
+
+/*
+STDMETHODIMP CFSFolder::GetNumberOfSubFolders(UInt32 *numSubFolders)
+{
+ UInt32 numSubFoldersLoc = 0;
+ for (int i = 0; i < _files.Size(); i++)
+ if (_files[i].IsDir())
+ numSubFoldersLoc++;
+ *numSubFolders = numSubFoldersLoc;
+ return S_OK;
+}
+*/
+
+#ifdef _WIN32
+bool MyGetCompressedFileSizeW(LPCWSTR fileName, UInt64 &size)
+{
+ DWORD highPart;
+ DWORD lowPart = ::GetCompressedFileSizeW(fileName, &highPart);
+ if (lowPart == INVALID_FILE_SIZE && ::GetLastError() != NO_ERROR)
+ {
+ #ifdef WIN_LONG_PATH
+ {
+ UString longPath;
+ if (GetLongPath(fileName, longPath))
+ lowPart = ::GetCompressedFileSizeW(longPath, &highPart);
+ }
+ #endif
+ if (lowPart == INVALID_FILE_SIZE && ::GetLastError() != NO_ERROR)
+ return false;
+ }
+ size = (UInt64(highPart) << 32) | lowPart;
+ return true;
+}
+#endif
+
+STDMETHODIMP CFSFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value)
+{
+ NCOM::CPropVariant prop;
+ if (itemIndex >= (UInt32)_refs.Size())
+ return E_INVALIDARG;
+ CDirItem &fileInfo = *_refs[itemIndex];
+ switch(propID)
+ {
+ case kpidIsDir: prop = fileInfo.IsDir(); break;
+ case kpidName: prop = fileInfo.Name; break;
+ case kpidSize: if (!fileInfo.IsDir()) prop = fileInfo.Size; break;
+ case kpidPackSize:
+ if (!fileInfo.CompressedSizeIsDefined)
+ {
+ fileInfo.CompressedSizeIsDefined = true;
+#ifdef _WIN32
+ if (fileInfo.IsDir () ||
+ !MyGetCompressedFileSizeW(_path + GetRelPath(fileInfo), fileInfo.CompressedSize))
+#endif
+ fileInfo.CompressedSize = fileInfo.Size;
+ }
+ prop = fileInfo.CompressedSize;
+ break;
+ case kpidAttrib: prop = (UInt32)fileInfo.Attrib; break;
+ case kpidCTime: prop = fileInfo.CTime; break;
+ case kpidATime: prop = fileInfo.ATime; break;
+ case kpidMTime: prop = fileInfo.MTime; break;
+ case kpidComment:
+ {
+ LoadComments();
+ UString comment;
+ if (_comments.GetValue(GetRelPath(fileInfo), comment))
+ prop = comment;
+ break;
+ }
+ case kpidPrefix:
+ {
+ if (_flatMode)
+ {
+ prop = GetPrefix(fileInfo);
+ }
+ break;
+ }
+ }
+ prop.Detach(value);
+ return S_OK;
+}
+
+HRESULT CFSFolder::BindToFolderSpec(const wchar_t *name, IFolderFolder **resultFolder)
+{
+ *resultFolder = 0;
+ CFSFolder *folderSpec = new CFSFolder;
+ CMyComPtr<IFolderFolder> subFolder = folderSpec;
+ RINOK(folderSpec->Init(_path + name + UString(WCHAR_PATH_SEPARATOR), 0));
+ *resultFolder = subFolder.Detach();
+ return S_OK;
+}
+
+UString CFSFolder::GetPrefix(const CDirItem &item) const
+{
+ UString path;
+ CDirItem *cur = item.Parent;
+ while (cur->Parent != 0)
+ {
+ path = cur->Name + UString(WCHAR_PATH_SEPARATOR) + path;
+ cur = cur->Parent;
+ }
+ return path;
+}
+
+UString CFSFolder::GetRelPath(const CDirItem &item) const
+{
+ return GetPrefix(item) + item.Name;
+}
+
+STDMETHODIMP CFSFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder)
+{
+ *resultFolder = 0;
+ const CDirItem &fileInfo = *_refs[index];
+ if (!fileInfo.IsDir())
+ return E_INVALIDARG;
+ return BindToFolderSpec(GetRelPath(fileInfo), resultFolder);
+}
+
+STDMETHODIMP CFSFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder)
+{
+ return BindToFolderSpec(name, resultFolder);
+}
+
+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;
+ printf("CFSFolder::BindToParentFolder path='%ls'\n",(const wchar_t *)_path);
+ int pos = _path.ReverseFind(WCHAR_PATH_SEPARATOR);
+ if (pos < 0 || pos != _path.Length() - 1)
+ return E_FAIL;
+ UString parentPath = _path.Left(pos);
+ printf("CFSFolder::BindToParentFolder parentPath='%ls'\n",(const wchar_t *)parentPath);
+ pos = parentPath.ReverseFind(WCHAR_PATH_SEPARATOR);
+ if (pos < 0)
+ {
+#ifdef _WIN32
+ parentPath.Empty();
+ CFSDrives *drivesFolderSpec = new CFSDrives;
+ CMyComPtr<IFolderFolder> drivesFolder = drivesFolderSpec;
+ drivesFolderSpec->Init();
+ *resultFolder = drivesFolder.Detach();
+#else
+ parentPath = WSTRING_PATH_SEPARATOR;
+ CFSFolder *parentFolderSpec = new CFSFolder;
+ CMyComPtr<IFolderFolder> parentFolder = parentFolderSpec;
+ printf("CFSFolder::BindToParentFolder Init-0 with parentPath='%ls'\n",(const wchar_t *)parentPath);
+ RINOK(parentFolderSpec->Init(parentPath, 0));
+ *resultFolder = parentFolder.Detach();
+#endif
+ return S_OK;
+ }
+ UString parentPathReduced = parentPath.Left(pos);
+ parentPath = parentPath.Left(pos + 1);
+ pos = parentPathReduced.ReverseFind(WCHAR_PATH_SEPARATOR);
+ if (pos == 1)
+ {
+#ifdef _WIN32
+ if (parentPath[0] != WCHAR_PATH_SEPARATOR)
+ return E_FAIL;
+ CNetFolder *netFolderSpec = new CNetFolder;
+ CMyComPtr<IFolderFolder> netFolder = netFolderSpec;
+ netFolderSpec->Init(parentPath);
+ *resultFolder = netFolder.Detach();
+#else
+ parentPath = WSTRING_PATH_SEPARATOR;
+ CFSFolder *parentFolderSpec = new CFSFolder;
+ CMyComPtr<IFolderFolder> parentFolder = parentFolderSpec;
+ printf("CFSFolder::BindToParentFolder Init-1 with parentPath='%ls'\n",(const wchar_t *)parentPath);
+ RINOK(parentFolderSpec->Init(parentPath, 0));
+ *resultFolder = parentFolder.Detach();
+#endif // ifdef _WIN32
+ return S_OK;
+ }
+ CFSFolder *parentFolderSpec = new CFSFolder;
+ CMyComPtr<IFolderFolder> parentFolder = parentFolderSpec;
+ printf("CFSFolder::BindToParentFolder Init-2 with parentPath='%ls'\n",(const wchar_t *)parentPath);
+ RINOK(parentFolderSpec->Init(parentPath, 0));
+ *resultFolder = parentFolder.Detach();
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::GetNumberOfProperties(UInt32 *numProperties)
+{
+ *numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
+ if (!_flatMode)
+ (*numProperties)--;
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::GetPropertyInfo(UInt32 index,
+ BSTR *name, PROPID *propID, VARTYPE *varType)
+{
+ if (index >= sizeof(kProperties) / sizeof(kProperties[0]))
+ return E_INVALIDARG;
+ const STATPROPSTG &prop = kProperties[index];
+ *propID = prop.propid;
+ *varType = prop.vt;
+ *name = 0;
+ return S_OK;
+}
+
+
+STDMETHODIMP CFSFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
+{
+ COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant prop;
+ switch(propID)
+ {
+ case kpidType: prop = L"FSFolder"; break;
+ case kpidPath: prop = _path; break;
+ }
+ prop.Detach(value);
+ return S_OK;
+ COM_TRY_END
+}
+
+STDMETHODIMP CFSFolder::WasChanged(INT32 *wasChanged)
+{
+ bool wasChangedMain = false;
+#ifdef _WIN32
+ 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;
+ }
+#endif
+ *wasChanged = BoolToInt(wasChangedMain);
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::Clone(IFolderFolder **resultFolder)
+{
+ CFSFolder *fsFolderSpec = new CFSFolder;
+ CMyComPtr<IFolderFolder> folderNew = fsFolderSpec;
+ fsFolderSpec->Init(_path, 0);
+ *resultFolder = folderNew.Detach();
+ return S_OK;
+}
+
+HRESULT CFSFolder::GetItemsFullSize(const UInt32 *indices, UInt32 numItems,
+ UInt64 &numFolders, UInt64 &numFiles, UInt64 &size, IProgress *progress)
+{
+ numFiles = numFolders = size = 0;
+ UInt32 i;
+ for (i = 0; i < numItems; i++)
+ {
+ int index = indices[i];
+ if (index >= _refs.Size())
+ return E_INVALIDARG;
+ const CDirItem &fileInfo = *_refs[index];
+ if (fileInfo.IsDir())
+ {
+ UInt64 subFolders, subFiles, subSize;
+ RINOK(GetFolderSize(_path + GetRelPath(fileInfo), subFolders, subFiles, subSize, progress));
+ numFolders += subFolders;
+ numFolders++;
+ numFiles += subFiles;
+ size += subSize;
+ }
+ else
+ {
+ numFiles++;
+ size += fileInfo.Size;
+ }
+ }
+ return S_OK;
+}
+
+HRESULT CFSFolder::GetItemFullSize(int index, UInt64 &size, IProgress *progress)
+{
+ const CDirItem &fileInfo = *_refs[index];
+ if (fileInfo.IsDir())
+ {
+ /*
+ CMyComPtr<IFolderFolder> subFolder;
+ RINOK(BindToFolder(index, &subFolder));
+ CMyComPtr<IFolderReload> aFolderReload;
+ subFolder.QueryInterface(&aFolderReload);
+ aFolderReload->Reload();
+ UInt32 numItems;
+ RINOK(subFolder->GetNumberOfItems(&numItems));
+ CMyComPtr<IFolderGetItemFullSize> aGetItemFullSize;
+ subFolder.QueryInterface(&aGetItemFullSize);
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ UInt64 size;
+ RINOK(aGetItemFullSize->GetItemFullSize(i, &size));
+ *totalSize += size;
+ }
+ */
+ UInt64 numFolders, numFiles;
+ return GetFolderSize(_path + GetRelPath(fileInfo), numFolders, numFiles, size, progress);
+ }
+ size = fileInfo.Size;
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::GetItemFullSize(UInt32 index, PROPVARIANT *value, IProgress *progress)
+{
+ NCOM::CPropVariant prop;
+ if (index >= (UInt32)_refs.Size())
+ return E_INVALIDARG;
+ UInt64 size = 0;
+ HRESULT result = GetItemFullSize(index, size, progress);
+ prop = size;
+ prop.Detach(value);
+ return result;
+}
+
+HRESULT CFSFolder::GetComplexName(const wchar_t *name, UString &resultPath)
+{
+ UString newName = name;
+ resultPath = _path + newName;
+ if (newName.Length() < 1)
+ return S_OK;
+ if (newName[0] == WCHAR_PATH_SEPARATOR)
+ {
+ resultPath = newName;
+ return S_OK;
+ }
+ if (newName.Length() < 2)
+ return S_OK;
+ if (newName[1] == L':')
+ resultPath = newName;
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::CreateFolder(const wchar_t *name, IProgress * /* progress */)
+{
+ UString processedName;
+ RINOK(GetComplexName(name, processedName));
+ if(NDirectory::MyCreateDirectory(processedName))
+ return S_OK;
+ if(::GetLastError() == ERROR_ALREADY_EXISTS)
+ return ::GetLastError();
+ if (!NDirectory::CreateComplexDirectory(processedName))
+ return ::GetLastError();
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::CreateFile(const wchar_t *name, IProgress * /* progress */)
+{
+ UString processedName;
+ RINOK(GetComplexName(name, processedName));
+ NIO::COutFile outFile;
+ if (!outFile.Create(processedName, false))
+ return ::GetLastError();
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::Rename(UInt32 index, const wchar_t *newName, IProgress * /* progress */)
+{
+ const CDirItem &fileInfo = *_refs[index];
+ const UString fullPrefix = _path + GetPrefix(fileInfo);
+ if (!NDirectory::MyMoveFile(fullPrefix + fileInfo.Name, fullPrefix + newName))
+ return GetLastError();
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::Delete(const UInt32 *indices, UInt32 numItems,IProgress *progress)
+{
+#ifdef _WIN32
+ RINOK(progress->SetTotal(numItems));
+ for (UInt32 i = 0; i < numItems; i++)
+ {
+ const CDirItem &fileInfo = *_refs[indices[i]];
+ const UString fullPath = _path + GetRelPath(fileInfo);
+ bool result;
+ if (fileInfo.IsDir())
+ result = NDirectory::RemoveDirectoryWithSubItems(fullPath);
+ else
+ result = NDirectory::DeleteFileAlways(fullPath);
+ if (!result)
+ return GetLastError();
+ UInt64 completed = i;
+ RINOK(progress->SetCompleted(&completed));
+ }
+#endif
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::SetProperty(UInt32 index, PROPID propID,
+ const PROPVARIANT *value, IProgress * /* progress */)
+{
+ if (index >= (UInt32)_refs.Size())
+ return E_INVALIDARG;
+ CDirItem &fileInfo = *_refs[index];
+ if (fileInfo.Parent->Parent != 0)
+ return E_NOTIMPL;
+ switch(propID)
+ {
+ case kpidComment:
+ {
+ UString filename = fileInfo.Name;
+ filename.Trim();
+ if (value->vt == VT_EMPTY)
+ _comments.DeletePair(filename);
+ else if (value->vt == VT_BSTR)
+ {
+ CTextPair pair;
+ pair.ID = filename;
+ pair.ID.Trim();
+ pair.Value = value->bstrVal;
+ pair.Value.Trim();
+ if (pair.Value.IsEmpty())
+ _comments.DeletePair(filename);
+ else
+ _comments.AddPair(pair);
+ }
+ else
+ return E_INVALIDARG;
+ SaveComments();
+ break;
+ }
+ default:
+ return E_NOTIMPL;
+ }
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::GetSystemIconIndex(UInt32 index, INT32 *iconIndex)
+{
+#ifdef _WIN32
+ if (index >= (UInt32)_refs.Size())
+ return E_INVALIDARG;
+ const CDirItem &fileInfo = *_refs[index];
+ *iconIndex = 0;
+ int iconIndexTemp;
+ if (GetRealIconIndex(_path + GetRelPath(fileInfo), fileInfo.Attributes, iconIndexTemp) != 0)
+ {
+ *iconIndex = iconIndexTemp;
+ return S_OK;
+ }
+ return GetLastError();
+#endif
+ *iconIndex = 0;
+ return S_OK;
+}
+
+STDMETHODIMP CFSFolder::SetFlatMode(Int32 flatMode)
+{
+ _flatMode = IntToBool(flatMode);
+ return S_OK;
+}
+
+}