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