7zip/CPP/7zip/UI/FileManager/NetFolder.cpp
Igor Pavlov e008ce3976 24.08
2024-08-12 16:50:32 +05:00

277 lines
7.3 KiB
C++

// NetFolder.cpp
#include "StdAfx.h"
#include "../../../Windows/PropVariant.h"
#include "../../PropID.h"
#include "FSFolder.h"
#include "NetFolder.h"
#include "SysIconUtils.h"
using namespace NWindows;
using namespace NNet;
static const Byte kProps[] =
{
kpidName,
kpidLocalName,
kpidComment,
kpidProvider
};
void CNetFolder::Init(const UString &path)
{
/*
if (path.Len() > 2)
{
if (path[0] == L'\\' && path[1] == L'\\')
{
CResource netResource;
netResource.RemoteName = GetSystemString(path.Left(path.Len() - 1));
netResource.Scope = RESOURCE_GLOBALNET;
netResource.Type = RESOURCETYPE_DISK;
netResource.DisplayType = RESOURCEDISPLAYTYPE_SERVER;
netResource.Usage = RESOURCEUSAGE_CONTAINER;
Init(&netResource, 0, path);
return;
}
}
Init(0, 0 , L"");
*/
CResourceW resource;
resource.RemoteNameIsDefined = true;
if (!path.IsEmpty())
resource.RemoteName.SetFrom(path, path.Len() - 1);
resource.ProviderIsDefined = false;
resource.LocalNameIsDefined = false;
resource.CommentIsDefined = false;
resource.Type = RESOURCETYPE_DISK;
resource.Scope = RESOURCE_GLOBALNET;
resource.Usage = 0;
resource.DisplayType = 0;
CResourceW destResource;
UString systemPathPart;
DWORD result = GetResourceInformation(resource, destResource, systemPathPart);
if (result == NO_ERROR)
Init(&destResource, NULL, path);
else
Init(NULL, NULL , L"");
return;
}
void CNetFolder::Init(const NWindows::NNet::CResourceW *netResource,
IFolderFolder *parentFolder, const UString &path)
{
_path = path;
if (!netResource)
_netResourcePointer = NULL;
else
{
_netResource = *netResource;
_netResourcePointer = &_netResource;
// if (_netResource.DisplayType == RESOURCEDISPLAYTYPE_SERVER)
_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;
}
Z7_COM7F_IMF(CNetFolder::LoadItems())
{
_items.Clear();
CEnum enumerator;
for (;;)
{
DWORD result = enumerator.Open(
RESOURCE_GLOBALNET,
RESOURCETYPE_DISK,
0, // enumerate all resources
_netResourcePointer
);
if (result == NO_ERROR)
break;
if (result != ERROR_ACCESS_DENIED)
return HRESULT_FROM_WIN32(result);
if (_netResourcePointer)
result = AddConnection2(_netResource,
NULL, NULL, CONNECT_INTERACTIVE);
if (result != NO_ERROR)
return HRESULT_FROM_WIN32(result);
}
for (;;)
{
CResourceEx resource;
const DWORD result = enumerator.Next(resource);
if (result == NO_ERROR)
{
if (!resource.RemoteNameIsDefined) // For Win 98, I don't know what's wrong
resource.RemoteName = resource.Comment;
resource.Name = resource.RemoteName;
const int pos = resource.Name.ReverseFind_PathSepar();
if (pos >= 0)
{
// _path = resource.Name.Left(pos + 1);
resource.Name.DeleteFrontal((unsigned)pos + 1);
}
_items.Add(resource);
}
else if (result == ERROR_NO_MORE_ITEMS)
break;
else
return HRESULT_FROM_WIN32(result);
}
/*
It's too slow for some systems.
if (_netResourcePointer && _netResource.DisplayType == RESOURCEDISPLAYTYPE_SERVER)
{
for (char c = 'a'; c <= 'z'; c++)
{
CResourceEx resource;
resource.Name = UString(wchar_t(c)) + L'$';
resource.RemoteNameIsDefined = true;
resource.RemoteName = _path + resource.Name;
NFile::NFind::CFindFile findFile;
NFile::NFind::CFileInfo fileInfo;
if (!findFile.FindFirst(us2fs(resource.RemoteName) + FString(FCHAR_PATH_SEPARATOR) + FCHAR_ANY_MASK, fileInfo))
continue;
resource.Usage = RESOURCEUSAGE_CONNECTABLE;
resource.LocalNameIsDefined = false;
resource.CommentIsDefined = false;
resource.ProviderIsDefined = false;
_items.Add(resource);
}
}
*/
return S_OK;
}
Z7_COM7F_IMF(CNetFolder::GetNumberOfItems(UInt32 *numItems))
{
*numItems = _items.Size();
return S_OK;
}
Z7_COM7F_IMF(CNetFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value))
{
NCOM::CPropVariant prop;
const CResourceEx &item = _items[itemIndex];
switch (propID)
{
case kpidIsDir: prop = true; break;
case kpidName:
// if (item.RemoteNameIsDefined)
prop = item.Name;
break;
case kpidLocalName: if (item.LocalNameIsDefined) prop = item.LocalName; break;
case kpidComment: if (item.CommentIsDefined) prop = item.Comment; break;
case kpidProvider: if (item.ProviderIsDefined) prop = item.Provider; break;
}
prop.Detach(value);
return S_OK;
}
Z7_COM7F_IMF(CNetFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder))
{
*resultFolder = NULL;
const CResourceEx &resource = _items[index];
if (resource.Usage == RESOURCEUSAGE_CONNECTABLE ||
resource.DisplayType == RESOURCEDISPLAYTYPE_SHARE)
{
NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder;
CMyComPtr<IFolderFolder> subFolder = fsFolderSpec;
RINOK(fsFolderSpec->Init(us2fs(resource.RemoteName + WCHAR_PATH_SEPARATOR))) // , this
*resultFolder = subFolder.Detach();
}
else
{
CNetFolder *netFolder = new CNetFolder;
CMyComPtr<IFolderFolder> subFolder = netFolder;
netFolder->Init(&resource, this, resource.Name + WCHAR_PATH_SEPARATOR);
*resultFolder = subFolder.Detach();
}
return S_OK;
}
Z7_COM7F_IMF(CNetFolder::BindToFolder(const wchar_t * /* name */, IFolderFolder ** /* resultFolder */))
{
return E_NOTIMPL;
}
Z7_COM7F_IMF(CNetFolder::BindToParentFolder(IFolderFolder **resultFolder))
{
*resultFolder = NULL;
if (_parentFolder)
{
CMyComPtr<IFolderFolder> parentFolder = _parentFolder;
*resultFolder = parentFolder.Detach();
return S_OK;
}
if (_netResourcePointer)
{
CResourceW resourceParent;
const DWORD result = GetResourceParent(_netResource, resourceParent);
if (result != NO_ERROR)
return HRESULT_FROM_WIN32(result);
if (!_netResource.RemoteNameIsDefined)
return S_OK;
CNetFolder *netFolder = new CNetFolder;
CMyComPtr<IFolderFolder> subFolder = netFolder;
netFolder->Init(&resourceParent, NULL, WSTRING_PATH_SEPARATOR);
*resultFolder = subFolder.Detach();
}
return S_OK;
}
IMP_IFolderFolder_Props(CNetFolder)
Z7_COM7F_IMF(CNetFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value))
{
NWindows::NCOM::CPropVariant prop;
switch (propID)
{
case kpidType: prop = "NetFolder"; break;
case kpidPath: prop = _path; break;
}
prop.Detach(value);
return S_OK;
}
Z7_COM7F_IMF(CNetFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex))
{
*iconIndex = -1;
if (index >= _items.Size())
return E_INVALIDARG;
const CResourceW &resource = _items[index];
if (resource.DisplayType == RESOURCEDISPLAYTYPE_SERVER ||
resource.Usage == RESOURCEUSAGE_CONNECTABLE)
{
return Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT(
us2fs(resource.RemoteName), FILE_ATTRIBUTE_DIRECTORY, iconIndex);
}
else
{
#if 0
return S_FALSE;
#else
return Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT(
FTEXT("__DIR__"), FILE_ATTRIBUTE_DIRECTORY, iconIndex);
#endif
}
}