2021-12-27 01:00:00 +01:00
|
|
|
// 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)
|
2023-06-21 02:00:00 +02:00
|
|
|
Init(&destResource, NULL, path);
|
2021-12-27 01:00:00 +01:00
|
|
|
else
|
2023-06-21 02:00:00 +02:00
|
|
|
Init(NULL, NULL , L"");
|
2021-12-27 01:00:00 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CNetFolder::Init(const NWindows::NNet::CResourceW *netResource,
|
|
|
|
|
IFolderFolder *parentFolder, const UString &path)
|
|
|
|
|
{
|
|
|
|
|
_path = path;
|
2023-06-21 02:00:00 +02:00
|
|
|
if (!netResource)
|
|
|
|
|
_netResourcePointer = NULL;
|
2021-12-27 01:00:00 +01:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-21 02:00:00 +02:00
|
|
|
Z7_COM7F_IMF(CNetFolder::LoadItems())
|
2021-12-27 01:00:00 +01:00
|
|
|
{
|
|
|
|
|
_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)
|
2023-06-21 02:00:00 +02:00
|
|
|
return HRESULT_FROM_WIN32(result);
|
|
|
|
|
if (_netResourcePointer)
|
2021-12-27 01:00:00 +01:00
|
|
|
result = AddConnection2(_netResource,
|
2023-06-21 02:00:00 +02:00
|
|
|
NULL, NULL, CONNECT_INTERACTIVE);
|
2021-12-27 01:00:00 +01:00
|
|
|
if (result != NO_ERROR)
|
2023-06-21 02:00:00 +02:00
|
|
|
return HRESULT_FROM_WIN32(result);
|
2021-12-27 01:00:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (;;)
|
|
|
|
|
{
|
|
|
|
|
CResourceEx resource;
|
2023-06-21 02:00:00 +02:00
|
|
|
const DWORD result = enumerator.Next(resource);
|
2021-12-27 01:00:00 +01:00
|
|
|
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;
|
2023-06-21 02:00:00 +02:00
|
|
|
const int pos = resource.Name.ReverseFind_PathSepar();
|
2021-12-27 01:00:00 +01:00
|
|
|
if (pos >= 0)
|
|
|
|
|
{
|
|
|
|
|
// _path = resource.Name.Left(pos + 1);
|
2023-06-21 02:00:00 +02:00
|
|
|
resource.Name.DeleteFrontal((unsigned)pos + 1);
|
2021-12-27 01:00:00 +01:00
|
|
|
}
|
|
|
|
|
_items.Add(resource);
|
|
|
|
|
}
|
|
|
|
|
else if (result == ERROR_NO_MORE_ITEMS)
|
|
|
|
|
break;
|
|
|
|
|
else
|
2023-06-21 02:00:00 +02:00
|
|
|
return HRESULT_FROM_WIN32(result);
|
2021-12-27 01:00:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-06-21 02:00:00 +02:00
|
|
|
Z7_COM7F_IMF(CNetFolder::GetNumberOfItems(UInt32 *numItems))
|
2021-12-27 01:00:00 +01:00
|
|
|
{
|
|
|
|
|
*numItems = _items.Size();
|
|
|
|
|
return S_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-21 02:00:00 +02:00
|
|
|
Z7_COM7F_IMF(CNetFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value))
|
2021-12-27 01:00:00 +01:00
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-21 02:00:00 +02:00
|
|
|
Z7_COM7F_IMF(CNetFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder))
|
2021-12-27 01:00:00 +01:00
|
|
|
{
|
2023-06-21 02:00:00 +02:00
|
|
|
*resultFolder = NULL;
|
2021-12-27 01:00:00 +01:00
|
|
|
const CResourceEx &resource = _items[index];
|
|
|
|
|
if (resource.Usage == RESOURCEUSAGE_CONNECTABLE ||
|
|
|
|
|
resource.DisplayType == RESOURCEDISPLAYTYPE_SHARE)
|
|
|
|
|
{
|
|
|
|
|
NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder;
|
|
|
|
|
CMyComPtr<IFolderFolder> subFolder = fsFolderSpec;
|
2023-06-21 02:00:00 +02:00
|
|
|
RINOK(fsFolderSpec->Init(us2fs(resource.RemoteName + WCHAR_PATH_SEPARATOR))) // , this
|
2021-12-27 01:00:00 +01:00
|
|
|
*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;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-21 02:00:00 +02:00
|
|
|
Z7_COM7F_IMF(CNetFolder::BindToFolder(const wchar_t * /* name */, IFolderFolder ** /* resultFolder */))
|
2021-12-27 01:00:00 +01:00
|
|
|
{
|
|
|
|
|
return E_NOTIMPL;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-21 02:00:00 +02:00
|
|
|
Z7_COM7F_IMF(CNetFolder::BindToParentFolder(IFolderFolder **resultFolder))
|
2021-12-27 01:00:00 +01:00
|
|
|
{
|
2023-06-21 02:00:00 +02:00
|
|
|
*resultFolder = NULL;
|
2021-12-27 01:00:00 +01:00
|
|
|
if (_parentFolder)
|
|
|
|
|
{
|
|
|
|
|
CMyComPtr<IFolderFolder> parentFolder = _parentFolder;
|
|
|
|
|
*resultFolder = parentFolder.Detach();
|
|
|
|
|
return S_OK;
|
|
|
|
|
}
|
2023-06-21 02:00:00 +02:00
|
|
|
if (_netResourcePointer)
|
2021-12-27 01:00:00 +01:00
|
|
|
{
|
|
|
|
|
CResourceW resourceParent;
|
2023-06-21 02:00:00 +02:00
|
|
|
const DWORD result = GetResourceParent(_netResource, resourceParent);
|
2021-12-27 01:00:00 +01:00
|
|
|
if (result != NO_ERROR)
|
2023-06-21 02:00:00 +02:00
|
|
|
return HRESULT_FROM_WIN32(result);
|
2021-12-27 01:00:00 +01:00
|
|
|
if (!_netResource.RemoteNameIsDefined)
|
|
|
|
|
return S_OK;
|
|
|
|
|
|
|
|
|
|
CNetFolder *netFolder = new CNetFolder;
|
|
|
|
|
CMyComPtr<IFolderFolder> subFolder = netFolder;
|
2023-06-21 02:00:00 +02:00
|
|
|
netFolder->Init(&resourceParent, NULL, WSTRING_PATH_SEPARATOR);
|
2021-12-27 01:00:00 +01:00
|
|
|
*resultFolder = subFolder.Detach();
|
|
|
|
|
}
|
|
|
|
|
return S_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
IMP_IFolderFolder_Props(CNetFolder)
|
|
|
|
|
|
2023-06-21 02:00:00 +02:00
|
|
|
Z7_COM7F_IMF(CNetFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value))
|
2021-12-27 01:00:00 +01:00
|
|
|
{
|
|
|
|
|
NWindows::NCOM::CPropVariant prop;
|
|
|
|
|
switch (propID)
|
|
|
|
|
{
|
|
|
|
|
case kpidType: prop = "NetFolder"; break;
|
|
|
|
|
case kpidPath: prop = _path; break;
|
|
|
|
|
}
|
|
|
|
|
prop.Detach(value);
|
|
|
|
|
return S_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-21 02:00:00 +02:00
|
|
|
Z7_COM7F_IMF(CNetFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex))
|
2021-12-27 01:00:00 +01:00
|
|
|
{
|
2024-08-11 02:00:00 +02:00
|
|
|
*iconIndex = -1;
|
|
|
|
|
if (index >= _items.Size())
|
2021-12-27 01:00:00 +01:00
|
|
|
return E_INVALIDARG;
|
|
|
|
|
const CResourceW &resource = _items[index];
|
|
|
|
|
if (resource.DisplayType == RESOURCEDISPLAYTYPE_SERVER ||
|
|
|
|
|
resource.Usage == RESOURCEUSAGE_CONNECTABLE)
|
|
|
|
|
{
|
2024-08-11 02:00:00 +02:00
|
|
|
return Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT(
|
|
|
|
|
us2fs(resource.RemoteName), FILE_ATTRIBUTE_DIRECTORY, iconIndex);
|
2021-12-27 01:00:00 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-08-11 02:00:00 +02:00
|
|
|
#if 0
|
|
|
|
|
return S_FALSE;
|
|
|
|
|
#else
|
|
|
|
|
return Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT(
|
|
|
|
|
FTEXT("__DIR__"), FILE_ATTRIBUTE_DIRECTORY, iconIndex);
|
|
|
|
|
#endif
|
2021-12-27 01:00:00 +01:00
|
|
|
}
|
|
|
|
|
}
|