xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/FileManager/NetFolder.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // NetFolder.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../../../Windows/PropVariant.h"
6 
7 #include "../../PropID.h"
8 
9 #include "FSFolder.h"
10 #include "NetFolder.h"
11 #include "SysIconUtils.h"
12 
13 using namespace NWindows;
14 using namespace NNet;
15 
16 static const Byte  kProps[] =
17 {
18   kpidName,
19   kpidLocalName,
20   kpidComment,
21   kpidProvider
22 };
23 
Init(const UString & path)24 void CNetFolder::Init(const UString &path)
25 {
26   /*
27   if (path.Len() > 2)
28   {
29     if (path[0] == L'\\' && path[1] == L'\\')
30     {
31       CResource netResource;
32       netResource.RemoteName = GetSystemString(path.Left(path.Len() - 1));
33       netResource.Scope = RESOURCE_GLOBALNET;
34       netResource.Type = RESOURCETYPE_DISK;
35       netResource.DisplayType = RESOURCEDISPLAYTYPE_SERVER;
36       netResource.Usage = RESOURCEUSAGE_CONTAINER;
37       Init(&netResource, 0, path);
38       return;
39     }
40   }
41   Init(0, 0 , L"");
42   */
43   CResourceW resource;
44   resource.RemoteNameIsDefined = true;
45   if (!path.IsEmpty())
46     resource.RemoteName.SetFrom(path, path.Len() - 1);
47   resource.ProviderIsDefined = false;
48   resource.LocalNameIsDefined = false;
49   resource.CommentIsDefined = false;
50   resource.Type = RESOURCETYPE_DISK;
51   resource.Scope = RESOURCE_GLOBALNET;
52   resource.Usage = 0;
53   resource.DisplayType = 0;
54   CResourceW destResource;
55   UString systemPathPart;
56   DWORD result = GetResourceInformation(resource, destResource, systemPathPart);
57   if (result == NO_ERROR)
58     Init(&destResource, NULL, path);
59   else
60     Init(NULL, NULL , L"");
61   return;
62 }
63 
Init(const NWindows::NNet::CResourceW * netResource,IFolderFolder * parentFolder,const UString & path)64 void CNetFolder::Init(const NWindows::NNet::CResourceW *netResource,
65       IFolderFolder *parentFolder, const UString &path)
66 {
67   _path = path;
68   if (!netResource)
69     _netResourcePointer = NULL;
70   else
71   {
72     _netResource = *netResource;
73     _netResourcePointer = &_netResource;
74 
75     // if (_netResource.DisplayType == RESOURCEDISPLAYTYPE_SERVER)
76     _path = _netResource.RemoteName;
77 
78     /* WinXP-64: When we move UP from Network share without _parentFolder chain,
79          we can get empty _netResource.RemoteName. Do we need to use Provider there ? */
80     if (_path.IsEmpty())
81       _path = _netResource.Provider;
82 
83     if (!_path.IsEmpty())
84       _path.Add_PathSepar();
85   }
86   _parentFolder = parentFolder;
87 }
88 
Z7_COM7F_IMF(CNetFolder::LoadItems ())89 Z7_COM7F_IMF(CNetFolder::LoadItems())
90 {
91   _items.Clear();
92   CEnum enumerator;
93 
94   for (;;)
95   {
96     DWORD result = enumerator.Open(
97       RESOURCE_GLOBALNET,
98       RESOURCETYPE_DISK,
99       0,        // enumerate all resources
100       _netResourcePointer
101       );
102     if (result == NO_ERROR)
103       break;
104     if (result != ERROR_ACCESS_DENIED)
105       return HRESULT_FROM_WIN32(result);
106     if (_netResourcePointer)
107     result = AddConnection2(_netResource,
108         NULL, NULL, CONNECT_INTERACTIVE);
109     if (result != NO_ERROR)
110       return HRESULT_FROM_WIN32(result);
111   }
112 
113   for (;;)
114   {
115     CResourceEx resource;
116     const DWORD result = enumerator.Next(resource);
117     if (result == NO_ERROR)
118     {
119       if (!resource.RemoteNameIsDefined) // For Win 98, I don't know what's wrong
120         resource.RemoteName = resource.Comment;
121       resource.Name = resource.RemoteName;
122       const int pos = resource.Name.ReverseFind_PathSepar();
123       if (pos >= 0)
124       {
125         // _path = resource.Name.Left(pos + 1);
126         resource.Name.DeleteFrontal((unsigned)pos + 1);
127       }
128       _items.Add(resource);
129     }
130     else if (result == ERROR_NO_MORE_ITEMS)
131       break;
132     else
133       return HRESULT_FROM_WIN32(result);
134   }
135 
136   /*
137   It's too slow for some systems.
138   if (_netResourcePointer && _netResource.DisplayType == RESOURCEDISPLAYTYPE_SERVER)
139   {
140     for (char c = 'a'; c <= 'z'; c++)
141     {
142       CResourceEx resource;
143       resource.Name = UString(wchar_t(c)) + L'$';
144       resource.RemoteNameIsDefined = true;
145       resource.RemoteName = _path + resource.Name;
146 
147       NFile::NFind::CFindFile findFile;
148       NFile::NFind::CFileInfo fileInfo;
149       if (!findFile.FindFirst(us2fs(resource.RemoteName) + FString(FCHAR_PATH_SEPARATOR) + FCHAR_ANY_MASK, fileInfo))
150         continue;
151       resource.Usage = RESOURCEUSAGE_CONNECTABLE;
152       resource.LocalNameIsDefined = false;
153       resource.CommentIsDefined = false;
154       resource.ProviderIsDefined = false;
155       _items.Add(resource);
156     }
157   }
158   */
159   return S_OK;
160 }
161 
162 
Z7_COM7F_IMF(CNetFolder::GetNumberOfItems (UInt32 * numItems))163 Z7_COM7F_IMF(CNetFolder::GetNumberOfItems(UInt32 *numItems))
164 {
165   *numItems = _items.Size();
166   return S_OK;
167 }
168 
Z7_COM7F_IMF(CNetFolder::GetProperty (UInt32 itemIndex,PROPID propID,PROPVARIANT * value))169 Z7_COM7F_IMF(CNetFolder::GetProperty(UInt32 itemIndex, PROPID propID, PROPVARIANT *value))
170 {
171   NCOM::CPropVariant prop;
172   const CResourceEx &item = _items[itemIndex];
173   switch (propID)
174   {
175     case kpidIsDir:  prop = true; break;
176     case kpidName:
177       // if (item.RemoteNameIsDefined)
178         prop = item.Name;
179       break;
180     case kpidLocalName:  if (item.LocalNameIsDefined) prop = item.LocalName; break;
181     case kpidComment: if (item.CommentIsDefined) prop = item.Comment; break;
182     case kpidProvider: if (item.ProviderIsDefined) prop = item.Provider; break;
183   }
184   prop.Detach(value);
185   return S_OK;
186 }
187 
Z7_COM7F_IMF(CNetFolder::BindToFolder (UInt32 index,IFolderFolder ** resultFolder))188 Z7_COM7F_IMF(CNetFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder))
189 {
190   *resultFolder = NULL;
191   const CResourceEx &resource = _items[index];
192   if (resource.Usage == RESOURCEUSAGE_CONNECTABLE ||
193       resource.DisplayType == RESOURCEDISPLAYTYPE_SHARE)
194   {
195     NFsFolder::CFSFolder *fsFolderSpec = new NFsFolder::CFSFolder;
196     CMyComPtr<IFolderFolder> subFolder = fsFolderSpec;
197     RINOK(fsFolderSpec->Init(us2fs(resource.RemoteName + WCHAR_PATH_SEPARATOR))) // , this
198     *resultFolder = subFolder.Detach();
199   }
200   else
201   {
202     CNetFolder *netFolder = new CNetFolder;
203     CMyComPtr<IFolderFolder> subFolder = netFolder;
204     netFolder->Init(&resource, this, resource.Name + WCHAR_PATH_SEPARATOR);
205     *resultFolder = subFolder.Detach();
206   }
207   return S_OK;
208 }
209 
Z7_COM7F_IMF(CNetFolder::BindToFolder (const wchar_t *,IFolderFolder **))210 Z7_COM7F_IMF(CNetFolder::BindToFolder(const wchar_t * /* name */, IFolderFolder ** /* resultFolder */))
211 {
212   return E_NOTIMPL;
213 }
214 
Z7_COM7F_IMF(CNetFolder::BindToParentFolder (IFolderFolder ** resultFolder))215 Z7_COM7F_IMF(CNetFolder::BindToParentFolder(IFolderFolder **resultFolder))
216 {
217   *resultFolder = NULL;
218   if (_parentFolder)
219   {
220     CMyComPtr<IFolderFolder> parentFolder = _parentFolder;
221     *resultFolder = parentFolder.Detach();
222     return S_OK;
223   }
224   if (_netResourcePointer)
225   {
226     CResourceW resourceParent;
227     const DWORD result = GetResourceParent(_netResource, resourceParent);
228     if (result != NO_ERROR)
229       return HRESULT_FROM_WIN32(result);
230     if (!_netResource.RemoteNameIsDefined)
231       return S_OK;
232 
233     CNetFolder *netFolder = new CNetFolder;
234     CMyComPtr<IFolderFolder> subFolder = netFolder;
235     netFolder->Init(&resourceParent, NULL, WSTRING_PATH_SEPARATOR);
236     *resultFolder = subFolder.Detach();
237   }
238   return S_OK;
239 }
240 
241 IMP_IFolderFolder_Props(CNetFolder)
242 
Z7_COM7F_IMF(CNetFolder::GetFolderProperty (PROPID propID,PROPVARIANT * value))243 Z7_COM7F_IMF(CNetFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value))
244 {
245   NWindows::NCOM::CPropVariant prop;
246   switch (propID)
247   {
248     case kpidType: prop = "NetFolder"; break;
249     case kpidPath: prop = _path; break;
250   }
251   prop.Detach(value);
252   return S_OK;
253 }
254 
Z7_COM7F_IMF(CNetFolder::GetSystemIconIndex (UInt32 index,Int32 * iconIndex))255 Z7_COM7F_IMF(CNetFolder::GetSystemIconIndex(UInt32 index, Int32 *iconIndex))
256 {
257   *iconIndex = -1;
258   if (index >= _items.Size())
259     return E_INVALIDARG;
260   const CResourceW &resource = _items[index];
261   if (resource.DisplayType == RESOURCEDISPLAYTYPE_SERVER ||
262       resource.Usage == RESOURCEUSAGE_CONNECTABLE)
263   {
264     return Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT(
265         us2fs(resource.RemoteName), FILE_ATTRIBUTE_DIRECTORY, iconIndex);
266   }
267   else
268   {
269 #if 0
270     return S_FALSE;
271 #else
272     return Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT(
273         FTEXT("__DIR__"), FILE_ATTRIBUTE_DIRECTORY, iconIndex);
274 #endif
275   }
276 }
277