1 /*
2  * Network Connections Shell Folder
3  *
4  * Copyright 2008       Johannes Anderwald <johannes.anderwald@reactos.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include "precomp.h"
22 
23 #define MAX_PROPERTY_SHEET_PAGE (10)
24 
25 /***********************************************************************
26 *   IShellFolder implementation
27 */
28 
29 class CNetworkConnections final :
30     public IPersistFolder2,
31     public IShellExtInit,
32     public IShellFolder2,
33     public IOleCommandTarget,
34     public IShellFolderViewCB,
35     public IShellExecuteHookW
36 {
37     public:
38         CNetworkConnections();
39 
40         /* IUnknown */
41         virtual HRESULT WINAPI QueryInterface(REFIID riid, LPVOID *ppvOut);
42         virtual ULONG WINAPI AddRef();
43         virtual ULONG WINAPI Release();
44 
45         // IPersistFolder2
46         virtual HRESULT WINAPI GetClassID(CLSID *lpClassId);
47         virtual HRESULT WINAPI Initialize(PCIDLIST_ABSOLUTE pidl);
48         virtual HRESULT WINAPI GetCurFolder(PIDLIST_ABSOLUTE *pidl);
49 
50         // IShellFolder
51         virtual HRESULT WINAPI ParseDisplayName(HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName, DWORD *pchEaten, PIDLIST_RELATIVE *ppidl, DWORD *pdwAttributes);
52         virtual HRESULT WINAPI EnumObjects(HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList);
53         virtual HRESULT WINAPI BindToObject(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut);
54         virtual HRESULT WINAPI BindToStorage(PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID *ppvOut);
55         virtual HRESULT WINAPI CompareIDs(LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2);
56         virtual HRESULT WINAPI CreateViewObject(HWND hwndOwner, REFIID riid, LPVOID *ppvOut);
57         virtual HRESULT WINAPI GetAttributesOf(UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD *rgfInOut);
58         virtual HRESULT WINAPI GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid, UINT * prgfInOut, LPVOID * ppvOut);
59         virtual HRESULT WINAPI GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet);
60         virtual HRESULT WINAPI SetNameOf(HWND hwndOwner, PCUITEMID_CHILD pidl, LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD *pPidlOut);
61 
62         // IShellFolder2
63         virtual HRESULT WINAPI GetDefaultSearchGUID(GUID *pguid);
64         virtual HRESULT WINAPI EnumSearches(IEnumExtraSearch **ppenum);
65         virtual HRESULT WINAPI GetDefaultColumn(DWORD dwRes, ULONG *pSort, ULONG *pDisplay);
66         virtual HRESULT WINAPI GetDefaultColumnState(UINT iColumn, DWORD *pcsFlags);
67         virtual HRESULT WINAPI GetDetailsEx(PCUITEMID_CHILD pidl, const SHCOLUMNID *pscid, VARIANT *pv);
68         virtual HRESULT WINAPI GetDetailsOf(PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS *psd);
69         virtual HRESULT WINAPI MapColumnToSCID(UINT column, SHCOLUMNID *pscid);
70 
71         // IShellExtInit
72         virtual HRESULT WINAPI Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID);
73 
74         // IOleCommandTarget
75         virtual HRESULT WINAPI Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut);
76         virtual HRESULT WINAPI QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText);
77 
78         // IShellFolderViewCB
79         virtual HRESULT WINAPI MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam);
80 
81         // IShellExecuteHookW
82         virtual HRESULT WINAPI Execute(LPSHELLEXECUTEINFOW pei);
83 
84     private:
85         ~CNetworkConnections();
86 
87         LONG m_ref;
88         /* both paths are parsible from the desktop */
89         PIDLIST_ABSOLUTE m_pidlRoot;
90         IOleCommandTarget *m_lpOleCmd;
91 };
92 
93 class CNetConUiObject final :
94     public IContextMenu3,
95     public IObjectWithSite,
96     public IQueryInfo,
97     public IExtractIconW
98 {
99     public:
100         CNetConUiObject(PCUITEMID_CHILD pidl, IOleCommandTarget *lpOleCmd);
101 
102         // IUnknown
103         virtual HRESULT WINAPI QueryInterface(REFIID riid, LPVOID *ppvOut);
104         virtual ULONG WINAPI AddRef();
105         virtual ULONG WINAPI Release();
106 
107         // IContextMenu3
108         virtual HRESULT WINAPI QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
109         virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpici);
110         virtual HRESULT WINAPI GetCommandString(UINT_PTR idCmd, UINT uType, UINT *pwReserved, LPSTR pszName, UINT cchMax);
111         virtual HRESULT WINAPI HandleMenuMsg( UINT uMsg, WPARAM wParam, LPARAM lParam);
112         virtual HRESULT WINAPI HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult);
113 
114         // IObjectWithSite
115         virtual HRESULT WINAPI SetSite(IUnknown *punk);
116         virtual HRESULT WINAPI GetSite(REFIID iid, void **ppvSite);
117 
118         // IQueryInfo
119         virtual HRESULT WINAPI GetInfoFlags(DWORD *pdwFlags);
120         virtual HRESULT WINAPI GetInfoTip(DWORD dwFlags, WCHAR **ppwszTip);
121 
122         // IExtractIconW
123         virtual HRESULT STDMETHODCALLTYPE GetIconLocation(UINT uFlags, LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags);
124         virtual HRESULT STDMETHODCALLTYPE Extract(LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
125 
126     private:
127         ~CNetConUiObject();
128 
129         LONG m_ref;
130         PCUITEMID_CHILD m_pidl;
131         IUnknown *m_pUnknown;
132         IOleCommandTarget *m_lpOleCmd;
133 };
134 
135 static const shvheader NetConnectSFHeader[] = {
136     {IDS_SHV_COLUMN_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 20},
137     {IDS_SHV_COLUMN_TYPE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 8},
138     {IDS_SHV_COLUMN_STATE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
139     {IDS_SHV_COLUMN_DEVNAME, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12},
140     {IDS_SHV_COLUMN_PHONE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
141     {IDS_SHV_COLUMN_OWNER, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5}
142 };
143 
144 #define NETCONNECTSHELLVIEWCOLUMNS 6
145 
146 #define COLUMN_NAME     0
147 #define COLUMN_TYPE     1
148 #define COLUMN_STATUS   2
149 #define COLUMN_DEVNAME  3
150 #define COLUMN_PHONE    4
151 #define COLUMN_OWNER    5
152 
153 HRESULT ShowNetConnectionStatus(IOleCommandTarget * lpOleCmd, INetConnection * pNetConnect, HWND hwnd);
154 
155 CNetworkConnections::CNetworkConnections() :
156     m_ref(0),
157     m_pidlRoot(_ILCreateNetConnect())
158 {
159     HRESULT hr;
160     hr = CoCreateInstance(CLSID_ConnectionTray, NULL, CLSCTX_INPROC_SERVER, IID_IOleCommandTarget, reinterpret_cast<PVOID*>(&m_lpOleCmd));
161     if (FAILED(hr))
162     {
163         ERR("CoCreateInstance failed with %lx\n", hr);
164         m_lpOleCmd = NULL;
165     }
166 }
167 
168 CNetworkConnections::~CNetworkConnections()
169 {
170     if (m_lpOleCmd)
171         m_lpOleCmd->Release();
172     SHFree(m_pidlRoot);
173 }
174 
175 /**************************************************************************
176  *	ISF_NetConnect_fnQueryInterface
177  *
178  * NOTE
179  *     supports not IPersist/IPersistFolder
180  */
181 HRESULT WINAPI CNetworkConnections::QueryInterface(REFIID riid, LPVOID *ppvObj)
182 {
183     *ppvObj = NULL;
184 
185     if (IsEqualIID(riid, IID_IUnknown) ||
186         IsEqualIID (riid, IID_IPersist) ||
187         IsEqualIID (riid, IID_IPersistFolder) ||
188         IsEqualIID (riid, IID_IPersistFolder2))
189     {
190         *ppvObj = static_cast<IPersistFolder2*>(this);
191     }
192     else if (IsEqualIID(riid, IID_IShellFolder) ||
193              IsEqualIID(riid, IID_IShellFolder2))
194     {
195         *ppvObj = static_cast<IShellFolder2*>(this);
196     }
197     else if (IsEqualIID(riid, IID_IShellExtInit))
198     {
199         *ppvObj = static_cast<IShellExtInit*>(this);
200     }
201     else if (IsEqualIID(riid, IID_IOleCommandTarget))
202     {
203         *ppvObj = static_cast<IOleCommandTarget*>(this);
204     }
205     else if (IsEqualIID(riid, IID_IShellFolderViewCB))
206     {
207         *ppvObj = static_cast<IShellFolderViewCB*>(this);
208     }
209     else if (IsEqualIID(riid, IID_IShellExecuteHookW))
210     {
211         *ppvObj = static_cast<IShellExecuteHookW*>(this);
212     }
213 
214     if (*ppvObj)
215     {
216         AddRef();
217         return S_OK;
218     }
219 
220     return E_NOINTERFACE;
221 }
222 
223 ULONG WINAPI CNetworkConnections::AddRef()
224 {
225     ULONG refCount = InterlockedIncrement(&m_ref);
226 
227     return refCount;
228 }
229 
230 ULONG WINAPI CNetworkConnections::Release()
231 {
232     ULONG refCount = InterlockedDecrement(&m_ref);
233 
234     if (!refCount)
235         delete this;
236 
237     return refCount;
238 }
239 
240 /**************************************************************************
241 *	ISF_NetConnect_fnParseDisplayName
242 */
243 HRESULT WINAPI CNetworkConnections::ParseDisplayName (
244                HWND hwndOwner, LPBC pbcReserved, LPOLESTR lpszDisplayName,
245                DWORD * pchEaten, PIDLIST_RELATIVE * ppidl, DWORD * pdwAttributes)
246 {
247     HRESULT hr = E_UNEXPECTED;
248 
249     *ppidl = 0;
250     if (pchEaten)
251         *pchEaten = 0;		/* strange but like the original */
252 
253     return hr;
254 }
255 
256 /**************************************************************************
257  *  CreateNetConnectEnumList()
258  */
259 static BOOL CreateNetConnectEnumList(CEnumIDList *list, DWORD dwFlags)
260 {
261     HRESULT hr;
262     INetConnectionManager *pNetConMan;
263     IEnumNetConnection *pEnumCon;
264     INetConnection *INetCon;
265     ULONG Count;
266     PITEMID_CHILD pidl;
267 
268     /* get an instance to of IConnectionManager */
269     hr = INetConnectionManager_Constructor(NULL, IID_INetConnectionManager, (LPVOID*)&pNetConMan);
270     if (FAILED(hr))
271         return FALSE;
272 
273     hr = pNetConMan->EnumConnections(NCME_DEFAULT, &pEnumCon);
274     if (FAILED(hr))
275     {
276         pNetConMan->Release();
277         return FALSE;
278     }
279 
280     do
281     {
282         hr = pEnumCon->Next(1, &INetCon, &Count);
283         if (hr == S_OK)
284         {
285             pidl = ILCreateNetConnectItem(INetCon);
286             if (pidl)
287             {
288                 list->AddToEnumList(pidl);
289             }
290         }
291         else
292         {
293             break;
294         }
295     } while (TRUE);
296 
297     pEnumCon->Release();
298     pNetConMan->Release();
299 
300     return TRUE;
301 }
302 
303 /**************************************************************************
304 *		ISF_NetConnect_fnEnumObjects
305 */
306 HRESULT WINAPI CNetworkConnections::EnumObjects(
307                HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST *ppEnumIDList)
308 {
309     CEnumIDList *pList = new CEnumIDList;
310     *ppEnumIDList = static_cast<LPENUMIDLIST>(pList);
311     if (!pList)
312         return E_OUTOFMEMORY;
313 
314     pList->AddRef();
315     CreateNetConnectEnumList(pList, dwFlags);
316     return S_OK;
317 }
318 
319 /**************************************************************************
320 *		ISF_NetConnect_fnBindToObject
321 */
322 HRESULT WINAPI CNetworkConnections::BindToObject (
323                PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
324 {
325     return E_NOTIMPL;
326 }
327 
328 /**************************************************************************
329 *	ISF_NetConnect_fnBindToStorage
330 */
331 HRESULT WINAPI CNetworkConnections::BindToStorage(
332                PCUIDLIST_RELATIVE pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
333 {
334     *ppvOut = NULL;
335     return E_NOTIMPL;
336 }
337 
338 /**************************************************************************
339 * 	ISF_NetConnect_fnCompareIDs
340 */
341 
342 HRESULT WINAPI CNetworkConnections::CompareIDs(
343                LPARAM lParam, PCUIDLIST_RELATIVE pidl1, PCUIDLIST_RELATIVE pidl2)
344 {
345     return E_NOTIMPL;
346 }
347 
348 /**************************************************************************
349 *	ISF_NetConnect_fnCreateViewObject
350 */
351 HRESULT WINAPI CNetworkConnections::CreateViewObject(
352                HWND hwndOwner, REFIID riid, LPVOID * ppvOut)
353 {
354     CSFV cvf;
355     HRESULT hr = E_NOINTERFACE;
356 
357     if (!ppvOut)
358         return hr;
359 
360     *ppvOut = NULL;
361 
362     if (IsEqualIID(riid, IID_IShellView))
363     {
364         ZeroMemory(&cvf, sizeof(cvf));
365         cvf.cbSize = sizeof(cvf);
366         cvf.pshf = static_cast<IShellFolder*>(this);
367 
368         IShellView* pShellView;
369         hr = SHCreateShellFolderViewEx(&cvf, &pShellView);
370         if (SUCCEEDED(hr))
371         {
372             hr = pShellView->QueryInterface(riid, ppvOut);
373             pShellView->Release();
374         }
375     }
376 
377     return hr;
378 }
379 
380 /**************************************************************************
381 *  ISF_NetConnect_fnGetAttributesOf
382 */
383 HRESULT WINAPI CNetworkConnections::GetAttributesOf(
384                UINT cidl, PCUITEMID_CHILD_ARRAY apidl, DWORD * rgfInOut)
385 {
386     //IGenericSFImpl *This = (IGenericSFImpl *)iface;
387     HRESULT hr = S_OK;
388     static const DWORD dwNetConnectAttributes = SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR |
389         SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER | SFGAO_CANRENAME | SFGAO_CANDELETE;
390 
391     static const DWORD dwNetConnectItemAttributes = SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR |
392         SFGAO_FILESYSANCESTOR | SFGAO_CANRENAME;
393 
394     if (!rgfInOut)
395         return E_INVALIDARG;
396 
397     if (cidl && !apidl)
398         return E_INVALIDARG;
399 
400     if (*rgfInOut == 0)
401         *rgfInOut = ~0;
402 
403     if (cidl == 0)
404         *rgfInOut = dwNetConnectAttributes;
405     else
406         *rgfInOut = dwNetConnectItemAttributes;
407 
408     /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
409     *rgfInOut &= ~SFGAO_VALIDATE;
410 
411     return hr;
412 }
413 
414 /**************************************************************************
415 *	ISF_NetConnect_fnGetUIObjectOf
416 *
417 * PARAMETERS
418 *  hwndOwner [in]  Parent window for any output
419 *  cidl      [in]  array size
420 *  apidl     [in]  simple pidl array
421 *  riid      [in]  Requested Interface
422 *  prgfInOut [   ] reserved
423 *  ppvObject [out] Resulting Interface
424 *
425 */
426 
427 HRESULT IContextMenuImpl_Constructor(REFIID riid, PCUITEMID_CHILD pidl, LPVOID * ppvOut, IOleCommandTarget * lpOleCmd)
428 {
429     CNetConUiObject *pMenu = new CNetConUiObject(pidl, lpOleCmd);
430     if (!pMenu)
431         return E_OUTOFMEMORY;
432 
433     pMenu->AddRef();
434     HRESULT hr = pMenu->QueryInterface(riid, ppvOut);
435     pMenu->Release();
436     return hr;
437 }
438 
439 HRESULT WINAPI CNetworkConnections::GetUIObjectOf(
440                HWND hwndOwner, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, REFIID riid,
441                UINT * prgfInOut, LPVOID * ppvOut)
442 {
443     IUnknown *pObj = NULL;
444     HRESULT hr = E_INVALIDARG;
445 
446     if (!ppvOut)
447         return hr;
448 
449     *ppvOut = NULL;
450 
451     if ((IsEqualIID(riid, IID_IContextMenu) || IsEqualIID (riid, IID_IContextMenu2) || IsEqualIID(riid, IID_IContextMenu3) ||
452          IsEqualIID(riid, IID_IQueryInfo) || IsEqualIID(riid, IID_IExtractIconW)) && cidl >= 1)
453     {
454         return IContextMenuImpl_Constructor(riid, apidl[0], ppvOut, m_lpOleCmd);
455     }
456     else
457         hr = E_NOINTERFACE;
458 
459     *ppvOut = pObj;
460     return hr;
461 }
462 
463 /**************************************************************************
464 *	ISF_NetConnect_fnGetDisplayNameOf
465 *
466 */
467 HRESULT WINAPI CNetworkConnections::GetDisplayNameOf(PCUITEMID_CHILD pidl, DWORD dwFlags, LPSTRRET strRet)
468 {
469     LPWSTR pszName;
470     HRESULT hr = E_FAIL;
471     NETCON_PROPERTIES * pProperties;
472     const VALUEStruct * val;
473 
474     if (!strRet)
475         return E_INVALIDARG;
476 
477     pszName = static_cast<LPWSTR>(CoTaskMemAlloc(MAX_PATH * sizeof(WCHAR)));
478     if (!pszName)
479         return E_OUTOFMEMORY;
480 
481     if (_ILIsNetConnect(pidl))
482     {
483         if (LoadStringW(netshell_hInstance, IDS_NETWORKCONNECTION, pszName, MAX_PATH))
484         {
485             pszName[MAX_PATH-1] = L'\0';
486             hr = S_OK;
487         }
488     }
489     else
490     {
491         val = _ILGetValueStruct(pidl);
492         if (val)
493         {
494             if (val->pItem->GetProperties(&pProperties) == S_OK)
495             {
496                 if (pProperties->pszwName)
497                 {
498                     wcscpy(pszName, pProperties->pszwName);
499                     hr = S_OK;
500                 }
501                 NcFreeNetconProperties(pProperties);
502             }
503         }
504 
505     }
506 
507     if (SUCCEEDED(hr))
508     {
509         strRet->uType = STRRET_WSTR;
510         strRet->pOleStr = pszName;
511     }
512     else
513     {
514         CoTaskMemFree(pszName);
515     }
516 
517     return hr;
518 }
519 
520 /**************************************************************************
521 *  ISF_NetConnect_fnSetNameOf
522 *  Changes the name of a file object or subfolder, possibly changing its item
523 *  identifier in the process.
524 *
525 * PARAMETERS
526 *  hwndOwner [in]  Owner window for output
527 *  pidl      [in]  simple pidl of item to change
528 *  lpszName  [in]  the items new display name
529 *  dwFlags   [in]  SHGNO formatting flags
530 *  ppidlOut  [out] simple pidl returned
531 */
532 HRESULT WINAPI CNetworkConnections::SetNameOf (
533                HWND hwndOwner, PCUITEMID_CHILD pidl,	/*simple pidl */
534                LPCOLESTR lpName, DWORD dwFlags, PITEMID_CHILD * pPidlOut)
535 {
536     const VALUEStruct * val;
537 
538     val = _ILGetValueStruct(pidl);
539     if (!val)
540         return E_FAIL;
541 
542    if (!val->pItem)
543        return E_FAIL;
544 
545     return val->pItem->Rename(lpName);
546 }
547 
548 HRESULT WINAPI CNetworkConnections::GetDefaultSearchGUID(GUID * pguid)
549 {
550     return E_NOTIMPL;
551 }
552 
553 HRESULT WINAPI CNetworkConnections::EnumSearches(IEnumExtraSearch ** ppenum)
554 {
555     return E_NOTIMPL;
556 }
557 
558 HRESULT WINAPI CNetworkConnections::GetDefaultColumn(DWORD dwRes, ULONG * pSort, ULONG * pDisplay)
559 {
560     if (pSort)
561         *pSort = 0;
562     if (pDisplay)
563         *pDisplay = 0;
564 
565     return S_OK;
566 }
567 
568 HRESULT WINAPI CNetworkConnections::GetDefaultColumnState(UINT iColumn, DWORD * pcsFlags)
569 {
570     if (!pcsFlags || iColumn >= NETCONNECTSHELLVIEWCOLUMNS)
571         return E_INVALIDARG;
572     *pcsFlags = NetConnectSFHeader[iColumn].pcsFlags;
573     return S_OK;
574 }
575 
576 HRESULT WINAPI CNetworkConnections::GetDetailsEx(
577                PCUITEMID_CHILD pidl, const SHCOLUMNID * pscid, VARIANT * pv)
578 {
579     return E_NOTIMPL;
580 }
581 
582 HRESULT WINAPI CNetworkConnections::GetDetailsOf(
583                PCUITEMID_CHILD pidl, UINT iColumn, SHELLDETAILS * psd)
584 {
585     WCHAR buffer[MAX_PATH] = {0};
586     HRESULT hr = E_FAIL;
587     const VALUEStruct * val;
588     NETCON_PROPERTIES * pProperties;
589 
590     if (iColumn >= NETCONNECTSHELLVIEWCOLUMNS)
591         return E_FAIL;
592 
593     psd->fmt = NetConnectSFHeader[iColumn].fmt;
594     psd->cxChar = NetConnectSFHeader[iColumn].cxChar;
595     if (pidl == NULL)
596     {
597         psd->str.uType = STRRET_WSTR;
598         if (LoadStringW(netshell_hInstance, NetConnectSFHeader[iColumn].colnameid, buffer, MAX_PATH))
599             hr = SHStrDupW(buffer, &psd->str.pOleStr);
600 
601         return hr;
602     }
603 
604     if (iColumn == COLUMN_NAME)
605     {
606         psd->str.uType = STRRET_WSTR;
607         return GetDisplayNameOf(pidl, SHGDN_NORMAL, &psd->str);
608     }
609 
610     val = _ILGetValueStruct(pidl);
611     if (!val)
612         return E_FAIL;
613 
614    if (!val->pItem)
615        return E_FAIL;
616 
617     if (val->pItem->GetProperties(&pProperties) != S_OK)
618         return E_FAIL;
619 
620 
621     switch (iColumn)
622     {
623         case COLUMN_TYPE:
624             if (pProperties->MediaType  == NCM_LAN || pProperties->MediaType == NCM_SHAREDACCESSHOST_RAS)
625             {
626                 if (LoadStringW(netshell_hInstance, IDS_TYPE_ETHERNET, buffer, MAX_PATH))
627                 {
628                     psd->str.uType = STRRET_WSTR;
629                     hr = SHStrDupW(buffer, &psd->str.pOleStr);
630                 }
631             }
632             break;
633         case COLUMN_STATUS:
634             buffer[0] = L'\0';
635             if (pProperties->Status == NCS_HARDWARE_DISABLED)
636                 LoadStringW(netshell_hInstance, IDS_STATUS_NON_OPERATIONAL, buffer, MAX_PATH);
637             else if (pProperties->Status == NCS_DISCONNECTED)
638                 LoadStringW(netshell_hInstance, IDS_STATUS_UNREACHABLE, buffer, MAX_PATH);
639             else if (pProperties->Status == NCS_MEDIA_DISCONNECTED)
640                 LoadStringW(netshell_hInstance, IDS_STATUS_DISCONNECTED, buffer, MAX_PATH);
641             else if (pProperties->Status == NCS_CONNECTING)
642                 LoadStringW(netshell_hInstance, IDS_STATUS_CONNECTING, buffer, MAX_PATH);
643             else if (pProperties->Status == NCS_CONNECTED)
644                 LoadStringW(netshell_hInstance, IDS_STATUS_CONNECTED, buffer, MAX_PATH);
645 
646             if (buffer[0])
647             {
648                 buffer[MAX_PATH-1] = L'\0';
649                 psd->str.uType = STRRET_WSTR;
650                 hr = SHStrDupW(buffer, &psd->str.pOleStr);
651             }
652             break;
653         case COLUMN_DEVNAME:
654             if (pProperties->pszwDeviceName)
655             {
656                 wcscpy(buffer, pProperties->pszwDeviceName);
657                 buffer[MAX_PATH-1] = L'\0';
658                 psd->str.uType = STRRET_WSTR;
659                 hr = SHStrDupW(buffer, &psd->str.pOleStr);
660             }
661             else
662             {
663                 psd->str.cStr[0] = '\0';
664                 psd->str.uType = STRRET_CSTR;
665             }
666             break;
667         case COLUMN_PHONE:
668         case COLUMN_OWNER:
669             psd->str.cStr[0] = '\0';
670             psd->str.uType = STRRET_CSTR;
671             break;
672     }
673 
674     NcFreeNetconProperties(pProperties);
675     return hr;
676 }
677 
678 HRESULT WINAPI CNetworkConnections::MapColumnToSCID(UINT column, SHCOLUMNID *pscid)
679 {
680     return E_NOTIMPL;
681 }
682 
683 //IObjectWithSite
684 //IInternetSecurityManager
685 
686 /**************************************************************************
687 * IContextMenu2 Implementation
688 */
689 
690 CNetConUiObject::CNetConUiObject(PCUITEMID_CHILD pidl, IOleCommandTarget *lpOleCmd)
691     : m_ref(0),
692       m_pidl(pidl),
693       m_pUnknown(NULL),
694       m_lpOleCmd(lpOleCmd)
695 {
696     if (m_lpOleCmd)
697         m_lpOleCmd->AddRef();
698 }
699 
700 CNetConUiObject::~CNetConUiObject()
701 {
702     if (m_lpOleCmd)
703         m_lpOleCmd->Release();
704 }
705 
706 /************************************************************************
707  * ISF_NetConnect_IContextMenu_QueryInterface
708  */
709 HRESULT WINAPI CNetConUiObject::QueryInterface(REFIID iid, LPVOID *ppvObject)
710 {
711     *ppvObject = NULL;
712 
713     if (IsEqualIID(iid, IID_IContextMenu) || IsEqualIID(iid, IID_IContextMenu2) || IsEqualIID(iid, IID_IContextMenu3))
714         *ppvObject = static_cast<IContextMenu3*>(this);
715     else if (IsEqualIID(iid, IID_IObjectWithSite))
716         *ppvObject = static_cast<IObjectWithSite*>(this);
717     else if (IsEqualIID(iid, IID_IQueryInfo))
718         *ppvObject = static_cast<IQueryInfo*>(this);
719     else if (IsEqualIID(iid, IID_IExtractIconW))
720         *ppvObject = static_cast<IExtractIconW*>(this);
721 
722     if (*ppvObject)
723     {
724         AddRef();
725         return S_OK;
726     }
727 
728     return E_NOINTERFACE;
729 }
730 
731 /************************************************************************
732  * ISF_NetConnect_IContextMenu_AddRef
733  */
734 ULONG WINAPI CNetConUiObject::AddRef()
735 {
736     ULONG refCount;
737 
738     refCount = InterlockedIncrement(&m_ref);
739 
740     return refCount;
741 }
742 
743 /************************************************************************
744  * ISF_NetConnect_IContextMenu_Release
745  */
746 ULONG WINAPI CNetConUiObject::Release()
747 {
748     ULONG refCount;
749 
750     refCount = InterlockedDecrement(&m_ref);
751     if (!refCount)
752         delete this;
753 
754     return refCount;
755 }
756 
757 void WINAPI _InsertMenuItemW (
758     HMENU hmenu,
759     UINT indexMenu,
760     BOOL fByPosition,
761     UINT wID,
762     UINT fType,
763     LPCWSTR dwTypeData,
764     UINT fState)
765 {
766     MENUITEMINFOW mii;
767     WCHAR szText[100];
768 
769     ZeroMemory(&mii, sizeof(mii));
770     mii.cbSize = sizeof(mii);
771     if (fType == MFT_SEPARATOR)
772     {
773         mii.fMask = MIIM_ID | MIIM_TYPE;
774     }
775     else if (fType == MFT_STRING)
776     {
777         mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
778         if ((ULONG_PTR)HIWORD((ULONG_PTR)dwTypeData) == 0)
779         {
780             if (LoadStringW(netshell_hInstance, LOWORD((ULONG_PTR)dwTypeData), szText, sizeof(szText)/sizeof(WCHAR)))
781             {
782                 szText[(sizeof(szText)/sizeof(WCHAR))-1] = 0;
783                 mii.dwTypeData = szText;
784             }
785             else
786             {
787                 return;
788             }
789         }
790         else
791         {
792             mii.dwTypeData = (LPWSTR) dwTypeData;
793         }
794         mii.fState = fState;
795     }
796 
797     mii.wID = wID;
798     mii.fType = fType;
799     InsertMenuItemW( hmenu, indexMenu, fByPosition, &mii);
800 }
801 
802 /**************************************************************************
803 * ISF_NetConnect_IContextMenu_QueryContextMenu()
804 */
805 HRESULT WINAPI CNetConUiObject::QueryContextMenu(
806 	HMENU hMenu,
807 	UINT indexMenu,
808 	UINT idCmdFirst,
809 	UINT idCmdLast,
810 	UINT uFlags)
811 {
812     const VALUEStruct * val;
813     NETCON_PROPERTIES * pProperties;
814 
815     val = _ILGetValueStruct(m_pidl);
816     if (!val)
817         return E_FAIL;
818 
819     if (val->pItem->GetProperties(&pProperties) != S_OK)
820         return E_FAIL;
821 
822     if (pProperties->Status == NCS_HARDWARE_DISABLED)
823         _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_ACTIVATE, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_ACTIVATE), MFS_DEFAULT);
824     else
825         _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_DEACTIVATE, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_DEACTIVATE), MFS_ENABLED);
826 
827     if (pProperties->Status == NCS_HARDWARE_DISABLED || pProperties->Status == NCS_MEDIA_DISCONNECTED || pProperties->Status == NCS_DISCONNECTED)
828         _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_STATUS, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_STATUS), MFS_GRAYED);
829     else if (pProperties->Status == NCS_CONNECTED)
830         _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_STATUS, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_STATUS), MFS_DEFAULT);
831     else
832         _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_STATUS, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_STATUS), MFS_ENABLED);
833 
834     if (pProperties->Status == NCS_HARDWARE_DISABLED || pProperties->Status == NCS_MEDIA_DISCONNECTED)
835         _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_REPAIR, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_REPAIR), MFS_GRAYED);
836     else
837         _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_REPAIR, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_REPAIR), MFS_ENABLED);
838 
839     _InsertMenuItemW(hMenu, indexMenu++, TRUE, -1, MFT_SEPARATOR, NULL, MFS_ENABLED);
840     _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_CREATELINK, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_CREATELINK), MFS_ENABLED);
841 
842     if (pProperties->dwCharacter & NCCF_ALLOW_REMOVAL)
843         _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_DELETE, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_DELETE), MFS_ENABLED);
844     else
845         _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_DELETE, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_DELETE), MFS_GRAYED);
846 
847     if (pProperties->dwCharacter & NCCF_ALLOW_RENAME)
848         _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_RENAME, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_RENAME), MFS_ENABLED);
849     else
850         _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_RENAME, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_RENAME), MFS_GRAYED);
851 
852     _InsertMenuItemW(hMenu, indexMenu++, TRUE, -1, MFT_SEPARATOR, NULL, MFS_ENABLED);
853     if (pProperties->Status == NCS_CONNECTED)
854         _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_PROPERTIES, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_PROPERTIES), MFS_ENABLED);
855     else
856         _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_PROPERTIES, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_PROPERTIES),  MFS_DEFAULT);
857     NcFreeNetconProperties(pProperties);
858     return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 9);
859 }
860 
861 BOOL
862 CALLBACK
863 PropSheetExCallback(HPROPSHEETPAGE hPage, LPARAM lParam)
864 {
865     PROPSHEETHEADERW *pinfo = (PROPSHEETHEADERW *)lParam;
866 
867     if (pinfo->nPages < MAX_PROPERTY_SHEET_PAGE)
868     {
869         pinfo->phpage[pinfo->nPages++] = hPage;
870         return TRUE;
871     }
872     return FALSE;
873 }
874 
875 HRESULT
876 ShowNetConnectionStatus(
877     IOleCommandTarget *lpOleCmd,
878     INetConnection *pNetConnect,
879     HWND hwnd)
880 {
881     NETCON_PROPERTIES *pProperties;
882     HRESULT hr;
883 
884     if (!lpOleCmd)
885         return E_FAIL;
886 
887     if (pNetConnect->GetProperties(&pProperties) != S_OK)
888         return E_FAIL;
889 
890     hr = lpOleCmd->Exec(&pProperties->guidId, OLECMDID_NEW, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
891 
892     NcFreeNetconProperties(pProperties);
893     return hr;
894 }
895 
896 HRESULT
897 ShowNetConnectionProperties(
898     INetConnection *pNetConnect,
899     HWND hwnd)
900 {
901     HRESULT hr;
902     CLSID ClassID;
903     PROPSHEETHEADERW pinfo;
904     HPROPSHEETPAGE hppages[MAX_PROPERTY_SHEET_PAGE];
905     INetConnectionPropertyUi * pNCP;
906     NETCON_PROPERTIES * pProperties;
907 
908     if (pNetConnect->GetProperties(&pProperties) != S_OK)
909         return E_FAIL;
910 
911     hr = pNetConnect->GetUiObjectClassId(&ClassID);
912     if (FAILED(hr))
913     {
914         NcFreeNetconProperties(pProperties);
915         return hr;
916     }
917 
918     hr = CoCreateInstance(ClassID, NULL, CLSCTX_INPROC_SERVER, IID_INetConnectionPropertyUi, (LPVOID*)&pNCP);
919     if (FAILED(hr))
920     {
921         NcFreeNetconProperties(pProperties);
922         return hr;
923     }
924 
925     hr = pNCP->SetConnection(pNetConnect);
926     if (SUCCEEDED(hr))
927     {
928         ZeroMemory(&pinfo, sizeof(PROPSHEETHEADERW));
929         ZeroMemory(hppages, sizeof(hppages));
930         pinfo.dwSize = sizeof(PROPSHEETHEADERW);
931         pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE | PSH_NOAPPLYNOW;
932         pinfo.phpage = hppages;
933         pinfo.hwndParent = hwnd;
934 
935         pinfo.pszCaption = pProperties->pszwName;
936         hr = pNCP->AddPages(hwnd, PropSheetExCallback, (LPARAM)&pinfo);
937         if (SUCCEEDED(hr))
938         {
939             if (PropertySheetW(&pinfo) < 0)
940                 hr = E_FAIL;
941         }
942     }
943     pNCP->Release();
944     NcFreeNetconProperties(pProperties);
945     return hr;
946 }
947 
948 
949 /**************************************************************************
950 * ISF_NetConnect_IContextMenu_InvokeCommand()
951 */
952 HRESULT WINAPI CNetConUiObject::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
953 {
954     const VALUEStruct * val;
955 
956     val = _ILGetValueStruct(m_pidl);
957     if (!val)
958         return E_FAIL;
959 
960     if (lpcmi->lpVerb == MAKEINTRESOURCEA(IDS_NET_STATUS) ||
961         lpcmi->lpVerb == MAKEINTRESOURCEA(IDS_NET_STATUS-1)) //HACK for Windows XP
962     {
963         return ShowNetConnectionStatus(m_lpOleCmd, val->pItem, lpcmi->hwnd);
964     }
965     else if (lpcmi->lpVerb == MAKEINTRESOURCEA(IDS_NET_PROPERTIES) ||
966              lpcmi->lpVerb == MAKEINTRESOURCEA(10099)) //HACK for Windows XP
967     {
968         /* FIXME perform version checks */
969         return ShowNetConnectionProperties(val->pItem, lpcmi->hwnd);
970     }
971 
972     return S_OK;
973 }
974 
975 /**************************************************************************
976  *  ISF_NetConnect_IContextMenu_GetCommandString()
977  *
978  */
979 HRESULT WINAPI CNetConUiObject::GetCommandString(
980 	UINT_PTR idCommand,
981 	UINT uFlags,
982 	UINT* lpReserved,
983 	LPSTR lpszName,
984 	UINT uMaxNameLen)
985 {
986 	return E_FAIL;
987 }
988 
989 /**************************************************************************
990 * ISF_NetConnect_IContextMenu_HandleMenuMsg()
991 */
992 HRESULT WINAPI CNetConUiObject::HandleMenuMsg(
993 	UINT uMsg,
994 	WPARAM wParam,
995 	LPARAM lParam)
996 {
997     return E_NOTIMPL;
998 }
999 
1000 HRESULT WINAPI CNetConUiObject::HandleMenuMsg2(
1001     UINT uMsg,
1002     WPARAM wParam,
1003     LPARAM lParam,
1004     LRESULT *plResult)
1005 {
1006     return E_NOTIMPL;
1007 }
1008 
1009 HRESULT WINAPI CNetConUiObject::GetSite(REFIID riid, PVOID *ppvSite)
1010 {
1011     HRESULT hr;
1012     IUnknown *pUnknown;
1013 
1014     if (!m_pUnknown)
1015     {
1016         *ppvSite = NULL;
1017         return E_FAIL;
1018     }
1019 
1020     hr = m_pUnknown->QueryInterface(riid, reinterpret_cast<PVOID*>(&pUnknown));
1021     if (SUCCEEDED(hr))
1022     {
1023         pUnknown->AddRef();
1024         *ppvSite = pUnknown;
1025         return S_OK;
1026     }
1027 
1028     *ppvSite = NULL;
1029     return hr;
1030 }
1031 
1032 HRESULT WINAPI CNetConUiObject::SetSite(IUnknown *pUnkSite)
1033 {
1034     if (!pUnkSite)
1035     {
1036         if (m_pUnknown)
1037         {
1038             m_pUnknown->Release();
1039             m_pUnknown = NULL;
1040         }
1041     }
1042     else
1043     {
1044         pUnkSite->AddRef();
1045         if (m_pUnknown)
1046             m_pUnknown->Release();
1047         m_pUnknown = pUnkSite;
1048     }
1049 
1050     return S_OK;
1051 }
1052 
1053 /************************************************************************
1054  *	ISF_NetConnect_IExtractIcon_GetIconLocation
1055  */
1056 HRESULT WINAPI CNetConUiObject::GetIconLocation(
1057     UINT uFlags,
1058     LPWSTR szIconFile,
1059     UINT cchMax,
1060     int *piIndex,
1061     UINT *pwFlags)
1062 {
1063     const VALUEStruct *val;
1064     NETCON_PROPERTIES *pProperties;
1065 
1066     *pwFlags = 0;
1067     if (!GetModuleFileNameW(netshell_hInstance, szIconFile, cchMax))
1068     {
1069         ERR("GetModuleFileNameW failed\n");
1070         return E_FAIL;
1071     }
1072 
1073     val = _ILGetValueStruct(m_pidl);
1074     if (!val)
1075     {
1076         ERR("_ILGetValueStruct failed\n");
1077         return E_FAIL;
1078     }
1079 
1080     if (val->pItem->GetProperties(&pProperties) != NOERROR)
1081     {
1082         ERR("INetConnection_GetProperties failed\n");
1083         return E_FAIL;
1084     }
1085 
1086     if (pProperties->Status == NCS_CONNECTED || pProperties->Status == NCS_CONNECTING)
1087         *piIndex = -IDI_NET_IDLE;
1088     else
1089         *piIndex = -IDI_NET_OFF;
1090 
1091     NcFreeNetconProperties(pProperties);
1092 
1093     return NOERROR;
1094 }
1095 
1096 /************************************************************************
1097  *	ISF_NetConnect_IExtractIcon_Extract
1098  */
1099 HRESULT WINAPI CNetConUiObject::Extract(
1100     LPCWSTR pszFile,
1101     UINT nIconIndex,
1102     HICON *phiconLarge,
1103     HICON *phiconSmall,
1104     UINT nIconSize)
1105 {
1106     //IContextMenuImpl * This = impl_from_IExtractIcon(iface);
1107     if (nIconIndex == IDI_NET_IDLE)
1108     {
1109         *phiconLarge = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_IDLE), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
1110         *phiconSmall = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_IDLE), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
1111         return NOERROR;
1112     }
1113     else if (nIconIndex == IDI_NET_OFF)
1114     {
1115         *phiconLarge = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_OFF), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
1116         *phiconSmall = (HICON)LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_OFF), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
1117         return NOERROR;
1118     }
1119 
1120     return S_FALSE;
1121 }
1122 
1123 /************************************************************************
1124  *	ISF_NetConnect_PersistFolder2_GetClassID
1125  */
1126 HRESULT WINAPI CNetworkConnections::GetClassID(CLSID *lpClassId)
1127 {
1128     if (!lpClassId)
1129         return E_POINTER;
1130 
1131     *lpClassId = CLSID_ConnectionFolder;
1132 
1133     return S_OK;
1134 }
1135 
1136 /************************************************************************
1137  *	ISF_NetConnect_PersistFolder2_Initialize
1138  *
1139  * NOTES: it makes no sense to change the pidl
1140  */
1141 HRESULT WINAPI CNetworkConnections::Initialize(PCIDLIST_ABSOLUTE pidl)
1142 {
1143     SHFree(m_pidlRoot);
1144     m_pidlRoot = ILClone(pidl);
1145 
1146     return S_OK;
1147 }
1148 
1149 /**************************************************************************
1150  *	ISF_NetConnect_PersistFolder2_GetCurFolder
1151  */
1152 HRESULT WINAPI CNetworkConnections::GetCurFolder(PIDLIST_ABSOLUTE *pidl)
1153 {
1154     if (!pidl)
1155         return E_POINTER;
1156 
1157     *pidl = ILClone(m_pidlRoot);
1158 
1159     return S_OK;
1160 }
1161 
1162 /************************************************************************
1163  *	ISF_NetConnect_ShellExecuteHookW_Execute
1164  */
1165 HRESULT WINAPI CNetworkConnections::Execute(LPSHELLEXECUTEINFOW pei)
1166 {
1167     const VALUEStruct *val;
1168     NETCON_PROPERTIES * pProperties;
1169 
1170     val = _ILGetValueStruct(ILFindLastID((ITEMIDLIST*)pei->lpIDList));
1171     if (!val)
1172         return E_FAIL;
1173 
1174     if (val->pItem->GetProperties(&pProperties) != NOERROR)
1175         return E_FAIL;
1176 
1177     if (pProperties->Status == NCS_CONNECTED)
1178     {
1179         NcFreeNetconProperties(pProperties);
1180         return ShowNetConnectionStatus(m_lpOleCmd, val->pItem, pei->hwnd);
1181     }
1182 
1183     NcFreeNetconProperties(pProperties);
1184 
1185     return S_OK;
1186 }
1187 
1188 HRESULT WINAPI CNetworkConnections::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID)
1189 {
1190     FIXME("CNetworkConnections::Initialize()\n");
1191     return E_NOTIMPL;
1192 }
1193 
1194 HRESULT WINAPI CNetworkConnections::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
1195 {
1196     FIXME("CNetworkConnections::Exec()\n");
1197     return E_NOTIMPL;
1198 }
1199 
1200 HRESULT WINAPI CNetworkConnections::QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
1201 {
1202     FIXME("CNetworkConnections::QueryStatus()\n");
1203     return E_NOTIMPL;
1204 }
1205 
1206 HRESULT WINAPI CNetworkConnections::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam)
1207 {
1208     FIXME("CNetworkConnections::MessageSFVCB()\n");
1209     return E_NOTIMPL;
1210 }
1211 
1212 HRESULT WINAPI CNetConUiObject::GetInfoFlags(DWORD *pdwFlags)
1213 {
1214     *pdwFlags = 0;
1215 
1216     return S_OK;
1217 }
1218 
1219 /************************************************************************
1220  *	ISF_NetConnect_PersistFolder2_Initialize
1221  *
1222  * NOTES: it makes no sense to change the pidl
1223  */
1224 HRESULT WINAPI CNetConUiObject::GetInfoTip(DWORD dwFlags, WCHAR **ppwszTip)
1225 {
1226     *ppwszTip = NULL;
1227     return S_OK;
1228 }
1229 
1230 /**************************************************************************
1231 *	ISF_NetConnect_Constructor
1232 */
1233 HRESULT WINAPI ISF_NetConnect_Constructor(IUnknown *pUnkOuter, REFIID riid, LPVOID *ppv)
1234 {
1235     TRACE("ISF_NetConnect_Constructor\n");
1236 
1237     if (!ppv)
1238         return E_POINTER;
1239     if (pUnkOuter)
1240         return CLASS_E_NOAGGREGATION;
1241 
1242     CNetworkConnections *pnc = new CNetworkConnections;
1243     if (!pnc)
1244         return E_OUTOFMEMORY;
1245 
1246     pnc->AddRef();
1247     HRESULT hr = pnc->QueryInterface(riid, ppv);
1248     pnc->Release();
1249 
1250     return hr;
1251 }
1252