Sync with trunk (r48545)
[reactos.git] / dll / win32 / netshell / shfldr_netconnect.c
1 /*
2 * Network Connections Shell Folder
3 *
4 * Copyright 2008 Johannes Anderwald <janderwald@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 WINE_DEFAULT_DEBUG_CHANNEL (shell);
24
25 #define MAX_PROPERTY_SHEET_PAGE (10)
26
27 /***********************************************************************
28 * IShellFolder implementation
29 */
30
31 typedef struct {
32 const IShellFolder2Vtbl *lpVtbl;
33 LONG ref;
34
35 const IPersistFolder2Vtbl *lpVtblPersistFolder2;
36 const IShellExecuteHookWVtbl *lpVtblShellExecuteHookW;
37 //const IPersistIDListVtbl *lpVtblPersistIDList;
38
39 /* both paths are parsible from the desktop */
40 LPITEMIDLIST pidlRoot; /* absolute pidl */
41 LPITEMIDLIST pidl; /* enumerated pidl */
42 IOleCommandTarget * lpOleCmd;
43 } IGenericSFImpl, *LPIGenericSFImpl;
44
45 typedef struct
46 {
47 const IContextMenu3Vtbl *lpVtblContextMenu;
48 const IObjectWithSiteVtbl *lpVtblObjectWithSite;
49 const IQueryInfoVtbl *lpVtblQueryInfo;
50 const IExtractIconWVtbl *lpVtblExtractIconW;
51 LONG ref;
52 LPCITEMIDLIST apidl;
53 IUnknown *pUnknown;
54 IOleCommandTarget * lpOleCmd;
55 }IContextMenuImpl, *LPIContextMenuImpl;
56
57 static const shvheader NetConnectSFHeader[] = {
58 {IDS_SHV_COLUMN_NAME, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 20},
59 {IDS_SHV_COLUMN_TYPE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 8},
60 {IDS_SHV_COLUMN_STATE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
61 {IDS_SHV_COLUMN_DEVNAME, SHCOLSTATE_TYPE_DATE | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 12},
62 {IDS_SHV_COLUMN_PHONE, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 10},
63 {IDS_SHV_COLUMN_OWNER, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 5}
64 };
65
66 #define NETCONNECTSHELLVIEWCOLUMNS 6
67
68 #define COLUMN_NAME 0
69 #define COLUMN_TYPE 1
70 #define COLUMN_STATUS 2
71 #define COLUMN_DEVNAME 3
72 #define COLUMN_PHONE 4
73 #define COLUMN_OWNER 5
74
75 HRESULT ShowNetConnectionStatus(IOleCommandTarget * lpOleCmd, INetConnection * pNetConnect, HWND hwnd);
76
77 static const IContextMenu3Vtbl vt_ContextMenu3;
78 static const IObjectWithSiteVtbl vt_ObjectWithSite;
79 static const IQueryInfoVtbl vt_QueryInfo;
80 static const IExtractIconWVtbl vt_ExtractIconW;
81
82 static __inline LPIContextMenuImpl impl_from_IExtractIcon(IExtractIconW *iface)
83 {
84 return (LPIContextMenuImpl)((char *)iface - FIELD_OFFSET(IContextMenuImpl, lpVtblExtractIconW));
85 }
86
87
88 static __inline LPIContextMenuImpl impl_from_IObjectWithSite(IObjectWithSite *iface)
89 {
90 return (LPIContextMenuImpl)((char *)iface - FIELD_OFFSET(IContextMenuImpl, lpVtblObjectWithSite));
91 }
92
93 static __inline LPIGenericSFImpl impl_from_IPersistFolder2(IPersistFolder2 *iface)
94 {
95 return (LPIGenericSFImpl)((char *)iface - FIELD_OFFSET(IGenericSFImpl, lpVtblPersistFolder2));
96 }
97
98 static __inline LPIGenericSFImpl impl_from_IShellExecuteHookW(IShellExecuteHookW *iface)
99 {
100 return (LPIGenericSFImpl)((char *)iface - FIELD_OFFSET(IGenericSFImpl, lpVtblShellExecuteHookW));
101 }
102
103 static __inline LPIContextMenuImpl impl_from_IQueryInfo(IQueryInfo *iface)
104 {
105 return (LPIContextMenuImpl)((char *)iface - FIELD_OFFSET(IContextMenuImpl, lpVtblQueryInfo));
106 }
107
108
109 /**************************************************************************
110 * ISF_NetConnect_fnQueryInterface
111 *
112 * NOTE
113 * supports not IPersist/IPersistFolder
114 */
115 static HRESULT WINAPI ISF_NetConnect_fnQueryInterface (IShellFolder2 *iface, REFIID riid, LPVOID *ppvObj)
116 {
117 IGenericSFImpl *This = (IGenericSFImpl *)iface;
118
119 *ppvObj = NULL;
120
121 if (IsEqualIID (riid, &IID_IUnknown) ||
122 IsEqualIID (riid, &IID_IShellFolder) ||
123 IsEqualIID (riid, &IID_IShellFolder2))
124 {
125 *ppvObj = This;
126 }
127 else if (IsEqualIID (riid, &IID_IPersistFolder) ||
128 IsEqualIID (riid, &IID_IPersistFolder2))
129 {
130 *ppvObj = (LPVOID *)&This->lpVtblPersistFolder2;
131 }
132 else if (IsEqualIID(riid, &IID_IShellExecuteHookW))
133 {
134 *ppvObj = (LPVOID *)&This->lpVtblShellExecuteHookW;
135 }
136 #if 0
137 else if (IsEqualIID(riid, &IID_IPersistIDList))
138 {
139 //*ppvObj = (LPVOID *)&This->lpVtblPersistIDList;
140 }
141 #endif
142 if (*ppvObj)
143 {
144 IUnknown_AddRef ((IUnknown *) (*ppvObj));
145 return S_OK;
146 }
147
148 /* TODO:
149 * IID_IPersistFreeThreadedObject
150 * IID_IBrowserFrameOptions
151 * IID_IShellIconOverlay
152 * IID_IPersistIDList
153 * IID_IPersist
154 */
155
156 return E_NOINTERFACE;
157 }
158
159 static ULONG WINAPI ISF_NetConnect_fnAddRef (IShellFolder2 * iface)
160 {
161 IGenericSFImpl *This = (IGenericSFImpl *)iface;
162 ULONG refCount = InterlockedIncrement(&This->ref);
163
164 return refCount;
165 }
166
167 static ULONG WINAPI ISF_NetConnect_fnRelease (IShellFolder2 * iface)
168 {
169 IGenericSFImpl *This = (IGenericSFImpl *)iface;
170 ULONG refCount = InterlockedDecrement(&This->ref);
171
172
173 if (!refCount)
174 {
175 SHFree (This->pidlRoot);
176 CoTaskMemFree(This);
177 }
178 return refCount;
179 }
180
181 /**************************************************************************
182 * ISF_NetConnect_fnParseDisplayName
183 */
184 static HRESULT WINAPI ISF_NetConnect_fnParseDisplayName (IShellFolder2 * iface,
185 HWND hwndOwner, LPBC pbcReserved, LPOLESTR lpszDisplayName,
186 DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
187 {
188 //IGenericSFImpl *This = (IGenericSFImpl *)iface;
189
190 HRESULT hr = E_UNEXPECTED;
191
192 *ppidl = 0;
193 if (pchEaten)
194 *pchEaten = 0; /* strange but like the original */
195
196 return hr;
197 }
198
199 /**************************************************************************
200 * CreateNetConnectEnumListss()
201 */
202 static BOOL CreateNetConnectEnumList(IEnumIDList *list, DWORD dwFlags)
203 {
204 HRESULT hr;
205 INetConnectionManager * INetConMan;
206 IEnumNetConnection * IEnumCon;
207 INetConnection * INetCon;
208 ULONG Count;
209 LPITEMIDLIST pidl;
210
211 /* get an instance to of IConnectionManager */
212 hr = INetConnectionManager_Constructor(NULL, &IID_INetConnectionManager, (LPVOID*)&INetConMan);
213 if (FAILED(hr))
214 return FALSE;
215
216 hr = INetConnectionManager_EnumConnections(INetConMan, NCME_DEFAULT, &IEnumCon);
217 if (FAILED(hr))
218 {
219 INetConnectionManager_Release(INetConMan);
220 return FALSE;
221 }
222
223 do
224 {
225 hr = IEnumNetConnection_Next(IEnumCon, 1, &INetCon, &Count);
226 if (hr == S_OK)
227 {
228 pidl = ILCreateNetConnectItem(INetCon);
229 if (pidl)
230 {
231 AddToEnumList(list, pidl);
232 }
233 }
234 else
235 {
236 break;
237 }
238 }while(TRUE);
239
240 IEnumNetConnection_Release(IEnumCon);
241 INetConnectionManager_Release(INetConMan);
242
243 return TRUE;
244 }
245
246 /**************************************************************************
247 * ISF_NetConnect_fnEnumObjects
248 */
249 static HRESULT WINAPI ISF_NetConnect_fnEnumObjects (IShellFolder2 * iface,
250 HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST * ppEnumIDList)
251 {
252 //IGenericSFImpl *This = (IGenericSFImpl *)iface;
253
254 *ppEnumIDList = IEnumIDList_Constructor();
255 if(*ppEnumIDList)
256 CreateNetConnectEnumList(*ppEnumIDList, dwFlags);
257
258
259 return (*ppEnumIDList) ? S_OK : E_OUTOFMEMORY;
260 }
261
262 /**************************************************************************
263 * ISF_NetConnect_fnBindToObject
264 */
265 static HRESULT WINAPI ISF_NetConnect_fnBindToObject (IShellFolder2 * iface,
266 LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
267 {
268 //IGenericSFImpl *This = (IGenericSFImpl *)iface;
269
270 return E_NOTIMPL;
271 }
272
273 /**************************************************************************
274 * ISF_NetConnect_fnBindToStorage
275 */
276 static HRESULT WINAPI ISF_NetConnect_fnBindToStorage (IShellFolder2 * iface,
277 LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
278 {
279 //IGenericSFImpl *This = (IGenericSFImpl *)iface;
280
281
282 *ppvOut = NULL;
283 return E_NOTIMPL;
284 }
285
286 /**************************************************************************
287 * ISF_NetConnect_fnCompareIDs
288 */
289
290 static HRESULT WINAPI ISF_NetConnect_fnCompareIDs (IShellFolder2 * iface,
291 LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
292 {
293 //IGenericSFImpl *This = (IGenericSFImpl *)iface;
294
295
296
297 return E_NOTIMPL;
298 }
299
300 /**************************************************************************
301 * ISF_NetConnect_fnCreateViewObject
302 */
303 static HRESULT WINAPI ISF_NetConnect_fnCreateViewObject (IShellFolder2 * iface,
304 HWND hwndOwner, REFIID riid, LPVOID * ppvOut)
305 {
306 //IGenericSFImpl *This = (IGenericSFImpl *)iface;
307 IShellView* pShellView;
308 CSFV cvf;
309 HRESULT hr = E_NOINTERFACE;
310
311 if (!ppvOut)
312 return hr;
313
314 *ppvOut = NULL;
315
316 if (IsEqualIID (riid, &IID_IShellView))
317 {
318 ZeroMemory(&cvf, sizeof(cvf));
319 cvf.cbSize = sizeof(cvf);
320 cvf.pshf = (IShellFolder*)iface;
321
322 hr = SHCreateShellFolderViewEx(&cvf, &pShellView);
323 if (SUCCEEDED(hr))
324 {
325 hr = IShellView_QueryInterface (pShellView, riid, ppvOut);
326 IShellView_Release (pShellView);
327 }
328 }
329
330 return hr;
331 }
332
333 /**************************************************************************
334 * ISF_NetConnect_fnGetAttributesOf
335 */
336 static HRESULT WINAPI ISF_NetConnect_fnGetAttributesOf (IShellFolder2 * iface,
337 UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
338 {
339 //IGenericSFImpl *This = (IGenericSFImpl *)iface;
340 HRESULT hr = S_OK;
341 static const DWORD dwNetConnectAttributes = SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR |
342 SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER | SFGAO_CANRENAME | SFGAO_CANDELETE;
343
344 static const DWORD dwNetConnectItemAttributes = SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR |
345 SFGAO_FILESYSANCESTOR | SFGAO_CANRENAME;
346
347 if (!rgfInOut)
348 return E_INVALIDARG;
349
350 if (cidl && !apidl)
351 return E_INVALIDARG;
352
353 if (*rgfInOut == 0)
354 *rgfInOut = ~0;
355
356 if(cidl == 0)
357 *rgfInOut = dwNetConnectAttributes;
358 else
359 *rgfInOut = dwNetConnectItemAttributes;
360
361 /* make sure SFGAO_VALIDATE is cleared, some apps depend on that */
362 *rgfInOut &= ~SFGAO_VALIDATE;
363
364 return hr;
365 }
366
367 /**************************************************************************
368 * ISF_NetConnect_fnGetUIObjectOf
369 *
370 * PARAMETERS
371 * hwndOwner [in] Parent window for any output
372 * cidl [in] array size
373 * apidl [in] simple pidl array
374 * riid [in] Requested Interface
375 * prgfInOut [ ] reserved
376 * ppvObject [out] Resulting Interface
377 *
378 */
379 static HRESULT IContextMenuImpl_Constructor(REFIID riid, LPCITEMIDLIST apidl, LPVOID * ppvOut, IOleCommandTarget * lpOleCmd)
380 {
381 IUnknown *pObj = NULL;
382 IContextMenuImpl * pMenu = CoTaskMemAlloc(sizeof(IContextMenuImpl));
383 if (!pMenu)
384 return E_OUTOFMEMORY;
385
386 ZeroMemory(pMenu, sizeof(IContextMenuImpl));
387
388 pMenu->apidl = apidl;
389 pMenu->lpVtblContextMenu = &vt_ContextMenu3;
390 pMenu->lpVtblObjectWithSite = &vt_ObjectWithSite;
391 pMenu->lpVtblExtractIconW = &vt_ExtractIconW;
392 pMenu->lpVtblQueryInfo = &vt_QueryInfo;
393 pMenu->pUnknown = NULL;
394 pMenu->lpOleCmd = lpOleCmd;
395 pMenu->ref = 1;
396
397 if (IsEqualIID(riid, &IID_IContextMenu) || IsEqualIID(riid, &IID_IContextMenu2)|| IsEqualIID(riid, &IID_IContextMenu3))
398 pObj = (IUnknown*)(&pMenu->lpVtblContextMenu);
399 else if(IsEqualIID(riid, &IID_IQueryInfo))
400 pObj = (IUnknown*)(&pMenu->lpVtblQueryInfo);
401 else if(IsEqualIID(riid, &IID_IExtractIconW))
402 pObj = (IUnknown*)(&pMenu->lpVtblExtractIconW);
403 else
404 return E_NOINTERFACE;
405
406 IUnknown_AddRef(pObj);
407
408
409 *ppvOut = pObj;
410 return S_OK;
411 }
412
413 static HRESULT WINAPI ISF_NetConnect_fnGetUIObjectOf (IShellFolder2 * iface,
414 HWND hwndOwner, UINT cidl, LPCITEMIDLIST * apidl, REFIID riid,
415 UINT * prgfInOut, LPVOID * ppvOut)
416 {
417 IGenericSFImpl *This = (IGenericSFImpl *)iface;
418
419 IUnknown *pObj = NULL;
420 HRESULT hr = E_INVALIDARG;
421
422 if (!ppvOut)
423 return hr;
424
425 *ppvOut = NULL;
426
427 if ((IsEqualIID (riid, &IID_IContextMenu) || IsEqualIID (riid, &IID_IContextMenu2) || IsEqualIID(riid, &IID_IContextMenu3) ||
428 IsEqualIID(riid, &IID_IQueryInfo) || IsEqualIID(riid, &IID_IExtractIconW)) && (cidl >= 1))
429 {
430 return IContextMenuImpl_Constructor(riid, apidl[0], ppvOut, This->lpOleCmd);
431 }
432 else
433 hr = E_NOINTERFACE;
434
435 *ppvOut = pObj;
436 return hr;
437 }
438
439 /**************************************************************************
440 * ISF_NetConnect_fnGetDisplayNameOf
441 *
442 */
443 static HRESULT WINAPI ISF_NetConnect_fnGetDisplayNameOf (IShellFolder2 * iface,
444 LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
445 {
446 LPWSTR pszName;
447 HRESULT hr = E_FAIL;
448 NETCON_PROPERTIES * pProperties;
449 VALUEStruct * val;
450 //IGenericSFImpl *This = (IGenericSFImpl *)iface;
451
452 if (!strRet)
453 return E_INVALIDARG;
454
455 pszName = CoTaskMemAlloc(MAX_PATH * sizeof(WCHAR));
456 if (!pszName)
457 return E_OUTOFMEMORY;
458
459 if (_ILIsNetConnect (pidl))
460 {
461 if (LoadStringW(netshell_hInstance, IDS_NETWORKCONNECTION, pszName, MAX_PATH))
462 {
463 pszName[MAX_PATH-1] = L'\0';
464 hr = S_OK;
465 }
466 }
467 else
468 {
469 val = _ILGetValueStruct(pidl);
470 if (val)
471 {
472 if (INetConnection_GetProperties(val->pItem, &pProperties) == NOERROR)
473 {
474 if (pProperties->pszwName)
475 {
476 wcscpy(pszName, pProperties->pszwName);
477 hr = S_OK;
478 }
479 NcFreeNetconProperties(pProperties);
480 }
481 }
482
483 }
484
485 if (SUCCEEDED(hr))
486 {
487 strRet->uType = STRRET_WSTR;
488 strRet->u.pOleStr = pszName;
489 }
490 else
491 {
492 CoTaskMemFree(pszName);
493 }
494
495 return hr;
496 }
497
498 /**************************************************************************
499 * ISF_NetConnect_fnSetNameOf
500 * Changes the name of a file object or subfolder, possibly changing its item
501 * identifier in the process.
502 *
503 * PARAMETERS
504 * hwndOwner [in] Owner window for output
505 * pidl [in] simple pidl of item to change
506 * lpszName [in] the items new display name
507 * dwFlags [in] SHGNO formatting flags
508 * ppidlOut [out] simple pidl returned
509 */
510 static HRESULT WINAPI ISF_NetConnect_fnSetNameOf (IShellFolder2 * iface,
511 HWND hwndOwner, LPCITEMIDLIST pidl, /*simple pidl */
512 LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
513 {
514 //IGenericSFImpl *This = (IGenericSFImpl *)iface;
515
516 return E_NOTIMPL;
517 }
518
519 static HRESULT WINAPI ISF_NetConnect_fnGetDefaultSearchGUID (
520 IShellFolder2 * iface, GUID * pguid)
521 {
522 //IGenericSFImpl *This = (IGenericSFImpl *)iface;
523
524 return E_NOTIMPL;
525 }
526
527 static HRESULT WINAPI ISF_NetConnect_fnEnumSearches (IShellFolder2 * iface,
528 IEnumExtraSearch ** ppenum)
529 {
530 //IGenericSFImpl *This = (IGenericSFImpl *)iface;
531
532 return E_NOTIMPL;
533 }
534
535 static HRESULT WINAPI ISF_NetConnect_fnGetDefaultColumn (IShellFolder2 * iface,
536 DWORD dwRes, ULONG * pSort, ULONG * pDisplay)
537 {
538 //IGenericSFImpl *This = (IGenericSFImpl *)iface;
539
540 if (pSort)
541 *pSort = 0;
542 if (pDisplay)
543 *pDisplay = 0;
544
545 return S_OK;
546 }
547
548 static HRESULT WINAPI ISF_NetConnect_fnGetDefaultColumnState (
549 IShellFolder2 * iface, UINT iColumn, DWORD * pcsFlags)
550 {
551 //IGenericSFImpl *This = (IGenericSFImpl *)iface;
552
553 if (!pcsFlags || iColumn >= NETCONNECTSHELLVIEWCOLUMNS)
554 return E_INVALIDARG;
555 *pcsFlags = NetConnectSFHeader[iColumn].pcsFlags;
556 return S_OK;
557 }
558
559 static HRESULT WINAPI ISF_NetConnect_fnGetDetailsEx (IShellFolder2 * iface,
560 LPCITEMIDLIST pidl, const SHCOLUMNID * pscid, VARIANT * pv)
561 {
562 //IGenericSFImpl *This = (IGenericSFImpl *)iface;
563
564 return E_NOTIMPL;
565 }
566
567 static HRESULT WINAPI ISF_NetConnect_fnGetDetailsOf (IShellFolder2 * iface,
568 LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS * psd)
569 {
570 //IGenericSFImpl *This = (IGenericSFImpl *)iface;
571 WCHAR buffer[MAX_PATH] = {0};
572 HRESULT hr = E_FAIL;
573 VALUEStruct * val;
574 NETCON_PROPERTIES * pProperties;
575
576 if (iColumn >= NETCONNECTSHELLVIEWCOLUMNS)
577 return E_FAIL;
578
579 psd->fmt = NetConnectSFHeader[iColumn].fmt;
580 psd->cxChar = NetConnectSFHeader[iColumn].cxChar;
581 if (pidl == NULL)
582 {
583 psd->str.uType = STRRET_WSTR;
584 if (LoadStringW(netshell_hInstance, NetConnectSFHeader[iColumn].colnameid, buffer, MAX_PATH))
585 hr = SHStrDupW(buffer, &psd->str.u.pOleStr);
586
587 return hr;
588 }
589
590 if (iColumn == COLUMN_NAME)
591 {
592 psd->str.uType = STRRET_WSTR;
593 return IShellFolder2_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL, &psd->str);
594 }
595
596 val = _ILGetValueStruct(pidl);
597 if (!val)
598 return E_FAIL;
599
600 if (!val->pItem)
601 return E_FAIL;
602
603 if (INetConnection_GetProperties((INetConnection*)val->pItem, &pProperties) != NOERROR)
604 return E_FAIL;
605
606
607 switch(iColumn)
608 {
609 case COLUMN_TYPE:
610 if (pProperties->MediaType == NCM_LAN || pProperties->MediaType == NCM_SHAREDACCESSHOST_RAS)
611 {
612 if (LoadStringW(netshell_hInstance, IDS_TYPE_ETHERNET, buffer, MAX_PATH))
613 {
614 psd->str.uType = STRRET_WSTR;
615 hr = SHStrDupW(buffer, &psd->str.u.pOleStr);
616 }
617 }
618 break;
619 case COLUMN_STATUS:
620 buffer[0] = L'\0';
621 if (pProperties->Status == NCS_HARDWARE_DISABLED)
622 LoadStringW(netshell_hInstance, IDS_STATUS_NON_OPERATIONAL, buffer, MAX_PATH);
623 else if (pProperties->Status == NCS_DISCONNECTED)
624 LoadStringW(netshell_hInstance, IDS_STATUS_UNREACHABLE, buffer, MAX_PATH);
625 else if (pProperties->Status == NCS_MEDIA_DISCONNECTED)
626 LoadStringW(netshell_hInstance, IDS_STATUS_DISCONNECTED, buffer, MAX_PATH);
627 else if (pProperties->Status == NCS_CONNECTING)
628 LoadStringW(netshell_hInstance, IDS_STATUS_CONNECTING, buffer, MAX_PATH);
629 else if (pProperties->Status == NCS_CONNECTED)
630 LoadStringW(netshell_hInstance, IDS_STATUS_CONNECTED, buffer, MAX_PATH);
631
632 if (buffer[0])
633 {
634 buffer[MAX_PATH-1] = L'\0';
635 psd->str.uType = STRRET_WSTR;
636 hr = SHStrDupW(buffer, &psd->str.u.pOleStr);
637 }
638 break;
639 case COLUMN_DEVNAME:
640 if (pProperties->pszwDeviceName)
641 {
642 wcscpy(buffer, pProperties->pszwDeviceName);
643 buffer[MAX_PATH-1] = L'\0';
644 psd->str.uType = STRRET_WSTR;
645 hr = SHStrDupW(buffer, &psd->str.u.pOleStr);
646 }
647 else
648 {
649 psd->str.u.cStr[0] = '\0';
650 psd->str.uType = STRRET_CSTR;
651 }
652 break;
653 case COLUMN_PHONE:
654 case COLUMN_OWNER:
655 psd->str.u.cStr[0] = '\0';
656 psd->str.uType = STRRET_CSTR;
657 break;
658 }
659
660 NcFreeNetconProperties(pProperties);
661 return hr;
662 }
663
664 static HRESULT WINAPI ISF_NetConnect_fnMapColumnToSCID (IShellFolder2 * iface,
665 UINT column, SHCOLUMNID * pscid)
666 {
667 //IGenericSFImpl *This = (IGenericSFImpl *)iface;
668
669 return E_NOTIMPL;
670 }
671
672 static const IShellFolder2Vtbl vt_ShellFolder2 = {
673 ISF_NetConnect_fnQueryInterface,
674 ISF_NetConnect_fnAddRef,
675 ISF_NetConnect_fnRelease,
676 ISF_NetConnect_fnParseDisplayName,
677 ISF_NetConnect_fnEnumObjects,
678 ISF_NetConnect_fnBindToObject,
679 ISF_NetConnect_fnBindToStorage,
680 ISF_NetConnect_fnCompareIDs,
681 ISF_NetConnect_fnCreateViewObject,
682 ISF_NetConnect_fnGetAttributesOf,
683 ISF_NetConnect_fnGetUIObjectOf,
684 ISF_NetConnect_fnGetDisplayNameOf,
685 ISF_NetConnect_fnSetNameOf,
686 /* ShellFolder2 */
687 ISF_NetConnect_fnGetDefaultSearchGUID,
688 ISF_NetConnect_fnEnumSearches,
689 ISF_NetConnect_fnGetDefaultColumn,
690 ISF_NetConnect_fnGetDefaultColumnState,
691 ISF_NetConnect_fnGetDetailsEx,
692 ISF_NetConnect_fnGetDetailsOf,
693 ISF_NetConnect_fnMapColumnToSCID
694 };
695 //IObjectWithSite
696 //IInternetSecurityManager
697
698 /**************************************************************************
699 * IContextMenu2 Implementation
700 */
701
702 /************************************************************************
703 * ISF_NetConnect_IContextMenu_QueryInterface
704 */
705 static HRESULT WINAPI ISF_NetConnect_IContextMenu3_QueryInterface(IContextMenu3 * iface, REFIID iid, LPVOID * ppvObject)
706 {
707 //LPOLESTR pStr;
708 IContextMenuImpl * This = (IContextMenuImpl*)iface;
709
710 if (IsEqualIID(iid, &IID_IContextMenu) || IsEqualIID(iid, &IID_IContextMenu2) || IsEqualIID(iid, &IID_IContextMenu3))
711 {
712 *ppvObject = (IUnknown*) &This->lpVtblContextMenu;
713 InterlockedIncrement(&This->ref);
714 return S_OK;
715 }
716 else if (IsEqualIID(iid, &IID_IObjectWithSite))
717 {
718 *ppvObject = (IUnknown*) &This->lpVtblObjectWithSite;
719 InterlockedIncrement(&This->ref);
720 return S_OK;
721 }
722 else if (IsEqualIID(iid, &IID_IQueryInfo))
723 {
724 *ppvObject = (IUnknown*) &This->lpVtblQueryInfo;
725 InterlockedIncrement(&This->ref);
726 return S_OK;
727 }
728
729 //StringFromCLSID(iid, &pStr);
730 //MessageBoxW(NULL, L"ISF_NetConnect_IContextMenu2_QueryInterface unhandled", pStr, MB_OK);
731 return E_NOINTERFACE;
732 }
733
734 /************************************************************************
735 * ISF_NetConnect_IContextMenu_AddRef
736 */
737 static ULONG WINAPI ISF_NetConnect_IContextMenu3_AddRef(IContextMenu3 * iface)
738 {
739 ULONG refCount;
740 IContextMenuImpl * This = (IContextMenuImpl*)iface;
741
742 refCount = InterlockedIncrement(&This->ref);
743
744 return refCount;
745 }
746
747 /************************************************************************
748 * ISF_NetConnect_IContextMenu_Release
749 */
750 static ULONG WINAPI ISF_NetConnect_IContextMenu3_Release(IContextMenu3 * iface)
751 {
752 ULONG refCount;
753 IContextMenuImpl * This = (IContextMenuImpl*)iface;
754
755 refCount = InterlockedDecrement(&This->ref);
756 if (!refCount)
757 {
758 CoTaskMemFree(This);
759 }
760 return refCount;
761 }
762
763 void WINAPI _InsertMenuItemW (
764 HMENU hmenu,
765 UINT indexMenu,
766 BOOL fByPosition,
767 UINT wID,
768 UINT fType,
769 LPCWSTR dwTypeData,
770 UINT fState)
771 {
772 MENUITEMINFOW mii;
773 WCHAR szText[100];
774
775 ZeroMemory(&mii, sizeof(mii));
776 mii.cbSize = sizeof(mii);
777 if (fType == MFT_SEPARATOR)
778 {
779 mii.fMask = MIIM_ID | MIIM_TYPE;
780 }
781 else if (fType == MFT_STRING)
782 {
783 mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
784 if ((ULONG_PTR)HIWORD((ULONG_PTR)dwTypeData) == 0)
785 {
786 if (LoadStringW(netshell_hInstance, LOWORD((ULONG_PTR)dwTypeData), szText, sizeof(szText)/sizeof(WCHAR)))
787 {
788 szText[(sizeof(szText)/sizeof(WCHAR))-1] = 0;
789 mii.dwTypeData = szText;
790 }
791 else
792 {
793 return;
794 }
795 }
796 else
797 {
798 mii.dwTypeData = (LPWSTR) dwTypeData;
799 }
800 mii.fState = fState;
801 }
802
803 mii.wID = wID;
804 mii.fType = fType;
805 InsertMenuItemW( hmenu, indexMenu, fByPosition, &mii);
806 }
807
808 /**************************************************************************
809 * ISF_NetConnect_IContextMenu_QueryContextMenu()
810 */
811 static HRESULT WINAPI ISF_NetConnect_IContextMenu3_QueryContextMenu(
812 IContextMenu3 *iface,
813 HMENU hMenu,
814 UINT indexMenu,
815 UINT idCmdFirst,
816 UINT idCmdLast,
817 UINT uFlags)
818 {
819 IContextMenuImpl * This = (IContextMenuImpl*)iface;
820 VALUEStruct * val;
821 NETCON_PROPERTIES * pProperties;
822
823 val = _ILGetValueStruct(This->apidl);
824 if (!val)
825 return E_FAIL;
826
827 if (INetConnection_GetProperties((INetConnection*)val->pItem, &pProperties) != NOERROR)
828 return E_FAIL;
829
830
831 if (pProperties->Status == NCS_HARDWARE_DISABLED)
832 _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_ACTIVATE, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_ACTIVATE), MFS_DEFAULT);
833 else
834 _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_DEACTIVATE, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_DEACTIVATE), MFS_ENABLED);
835
836 if (pProperties->Status == NCS_HARDWARE_DISABLED || pProperties->Status == NCS_MEDIA_DISCONNECTED || pProperties->Status == NCS_DISCONNECTED)
837 _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_STATUS, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_STATUS), MFS_GRAYED);
838 else if (pProperties->Status == NCS_CONNECTED)
839 _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_STATUS, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_STATUS), MFS_DEFAULT);
840 else
841 _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_STATUS, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_STATUS), MFS_ENABLED);
842
843 if (pProperties->Status == NCS_HARDWARE_DISABLED || pProperties->Status == NCS_MEDIA_DISCONNECTED)
844 _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_REPAIR, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_REPAIR), MFS_GRAYED);
845 else
846 _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_REPAIR, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_REPAIR), MFS_ENABLED);
847
848 _InsertMenuItemW(hMenu, indexMenu++, TRUE, -1, MFT_SEPARATOR, NULL, MFS_ENABLED);
849 _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_CREATELINK, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_CREATELINK), MFS_ENABLED);
850
851 if (pProperties->dwCharacter & NCCF_ALLOW_REMOVAL)
852 _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_DELETE, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_DELETE), MFS_ENABLED);
853 else
854 _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_DELETE, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_DELETE), MFS_GRAYED);
855
856 if (pProperties->dwCharacter & NCCF_ALLOW_RENAME)
857 _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_RENAME, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_RENAME), MFS_ENABLED);
858 else
859 _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_RENAME, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_RENAME), MFS_GRAYED);
860
861 _InsertMenuItemW(hMenu, indexMenu++, TRUE, -1, MFT_SEPARATOR, NULL, MFS_ENABLED);
862 _InsertMenuItemW(hMenu, indexMenu++, TRUE, IDS_NET_PROPERTIES, MFT_STRING, MAKEINTRESOURCEW(IDS_NET_PROPERTIES), MFS_ENABLED);
863 NcFreeNetconProperties(pProperties);
864 return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 9);
865 }
866
867 BOOL
868 CALLBACK
869 PropSheetExCallback(HPROPSHEETPAGE hPage, LPARAM lParam)
870 {
871 PROPSHEETHEADERW *pinfo = (PROPSHEETHEADERW *)lParam;
872
873 if (pinfo->nPages < MAX_PROPERTY_SHEET_PAGE)
874 {
875 pinfo->u3.phpage[pinfo->nPages++] = hPage;
876 return TRUE;
877 }
878 return FALSE;
879 }
880
881 HRESULT
882 ShowNetConnectionStatus(
883 IOleCommandTarget * lpOleCmd,
884 INetConnection * pNetConnect,
885 HWND hwnd)
886 {
887 NETCON_PROPERTIES * pProperties;
888 HRESULT hr;
889
890 if (!lpOleCmd)
891 return E_FAIL;
892
893 if (INetConnection_GetProperties(pNetConnect, &pProperties) != NOERROR)
894 return E_FAIL;
895
896 hr = IOleCommandTarget_Exec(lpOleCmd, &pProperties->guidId, 2, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
897
898 NcFreeNetconProperties(pProperties);
899 return hr;
900 }
901
902 HRESULT
903 ShowNetConnectionProperties(
904 INetConnection * pNetConnect,
905 HWND hwnd)
906 {
907 HRESULT hr;
908 CLSID ClassID;
909 PROPSHEETHEADERW pinfo;
910 HPROPSHEETPAGE hppages[MAX_PROPERTY_SHEET_PAGE];
911 INetConnectionPropertyUi * pNCP;
912 NETCON_PROPERTIES * pProperties;
913
914 if (INetConnection_GetProperties(pNetConnect, &pProperties) != NOERROR)
915 return E_FAIL;
916
917 hr = INetConnection_GetUiObjectClassId(pNetConnect, &ClassID);
918 if (FAILED(hr))
919 {
920 NcFreeNetconProperties(pProperties);
921 return hr;
922 }
923
924 hr = CoCreateInstance(&ClassID, NULL, CLSCTX_INPROC_SERVER, &IID_INetConnectionPropertyUi, (LPVOID)&pNCP);
925 if (FAILED(hr))
926 {
927 NcFreeNetconProperties(pProperties);
928 return hr;
929 }
930
931 hr = INetConnectionPropertyUi_SetConnection(pNCP, pNetConnect);
932 if (SUCCEEDED(hr))
933 {
934 ZeroMemory(&pinfo, sizeof(PROPSHEETHEADERW));
935 ZeroMemory(hppages, sizeof(hppages));
936 pinfo.dwSize = sizeof(PROPSHEETHEADERW);
937 pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE | PSH_NOAPPLYNOW;
938 pinfo.u3.phpage = hppages;
939 pinfo.hwndParent = hwnd;
940
941 pinfo.pszCaption = pProperties->pszwName;
942 hr = INetConnectionPropertyUi_AddPages(pNCP, hwnd, PropSheetExCallback, (LPARAM)&pinfo);
943 if (SUCCEEDED(hr))
944 {
945 if(PropertySheetW(&pinfo) < 0)
946 hr = E_FAIL;
947 }
948 }
949 INetConnectionPropertyUi_Release(pNCP);
950 NcFreeNetconProperties(pProperties);
951 return hr;
952 }
953
954
955 /**************************************************************************
956 * ISF_NetConnect_IContextMenu_InvokeCommand()
957 */
958 static HRESULT WINAPI ISF_NetConnect_IContextMenu3_InvokeCommand(
959 IContextMenu3 *iface,
960 LPCMINVOKECOMMANDINFO lpcmi)
961 {
962 IContextMenuImpl * This = (IContextMenuImpl*)iface;
963 VALUEStruct * val;
964
965 val = _ILGetValueStruct(This->apidl);
966 if (!val)
967 return E_FAIL;
968
969 if (lpcmi->lpVerb == MAKEINTRESOURCEA(IDS_NET_STATUS) ||
970 lpcmi->lpVerb == MAKEINTRESOURCEA(IDS_NET_STATUS-1)) //HACK for Windows XP
971 {
972 return ShowNetConnectionStatus(This->lpOleCmd, val->pItem, lpcmi->hwnd);
973 }
974 else if (lpcmi->lpVerb == MAKEINTRESOURCEA(IDS_NET_PROPERTIES) ||
975 lpcmi->lpVerb == MAKEINTRESOURCEA(10099)) //HACK for Windows XP
976 {
977 /* FIXME perform version checks */
978 return ShowNetConnectionProperties(val->pItem, lpcmi->hwnd);
979 }
980
981 return S_OK;
982 }
983
984 /**************************************************************************
985 * ISF_NetConnect_IContextMenu_GetCommandString()
986 *
987 */
988 static HRESULT WINAPI ISF_NetConnect_IContextMenu3_GetCommandString(
989 IContextMenu3 *iface,
990 UINT_PTR idCommand,
991 UINT uFlags,
992 UINT* lpReserved,
993 LPSTR lpszName,
994 UINT uMaxNameLen)
995 {
996 return E_FAIL;
997 }
998
999
1000
1001 /**************************************************************************
1002 * ISF_NetConnect_IContextMenu_HandleMenuMsg()
1003 */
1004 static HRESULT WINAPI ISF_NetConnect_IContextMenu3_HandleMenuMsg(
1005 IContextMenu3 *iface,
1006 UINT uMsg,
1007 WPARAM wParam,
1008 LPARAM lParam)
1009 {
1010 return E_NOTIMPL;
1011 }
1012
1013 static HRESULT WINAPI ISF_NetConnect_IContextMenu3_HandleMenuMsg2(
1014 IContextMenu3 *iface,
1015 UINT uMsg,
1016 WPARAM wParam,
1017 LPARAM lParam,
1018 LRESULT *plResult)
1019 {
1020 return E_NOTIMPL;
1021 }
1022
1023
1024 static const IContextMenu3Vtbl vt_ContextMenu3 =
1025 {
1026 ISF_NetConnect_IContextMenu3_QueryInterface,
1027 ISF_NetConnect_IContextMenu3_AddRef,
1028 ISF_NetConnect_IContextMenu3_Release,
1029 ISF_NetConnect_IContextMenu3_QueryContextMenu,
1030 ISF_NetConnect_IContextMenu3_InvokeCommand,
1031 ISF_NetConnect_IContextMenu3_GetCommandString,
1032 ISF_NetConnect_IContextMenu3_HandleMenuMsg,
1033 ISF_NetConnect_IContextMenu3_HandleMenuMsg2
1034 };
1035
1036 static HRESULT WINAPI ISF_NetConnect_IObjectWithSite_QueryInterface (IObjectWithSite * iface,
1037 REFIID iid, LPVOID * ppvObj)
1038 {
1039 IContextMenuImpl * This = impl_from_IObjectWithSite(iface);
1040
1041 if (IsEqualIID(iid, &IID_IObjectWithSite))
1042 {
1043 *ppvObj = (IUnknown*)&This->lpVtblObjectWithSite;
1044 return S_OK;
1045 }
1046 return E_NOINTERFACE;
1047 }
1048
1049 /************************************************************************
1050 * ISF_NetConnect_IQueryInfo_AddRef
1051 */
1052 static ULONG WINAPI ISF_NetConnect_IObjectWithSite_AddRef (IObjectWithSite * iface)
1053 {
1054 IContextMenuImpl * This = impl_from_IObjectWithSite(iface);
1055
1056 return IContextMenu2_AddRef((IContextMenu2*)This);
1057 }
1058
1059 /************************************************************************
1060 * ISF_NetConnect_IQueryInfo_Release
1061 */
1062 static ULONG WINAPI ISF_NetConnect_IObjectWithSite_Release (IObjectWithSite * iface)
1063 {
1064 IContextMenuImpl * This = impl_from_IObjectWithSite(iface);
1065
1066 return IContextMenu_Release((IContextMenu*)This);
1067 }
1068
1069 /************************************************************************
1070 * ISF_NetConnect_PersistFolder2_Release
1071 */
1072 static HRESULT WINAPI ISF_NetConnect_IObjectWithSite_GetSite (IObjectWithSite * iface, REFIID riid, PVOID *ppvSite)
1073 {
1074 HRESULT hr;
1075 IUnknown *pUnknown;
1076 IContextMenuImpl * This = impl_from_IObjectWithSite(iface);
1077
1078 if (!This->pUnknown)
1079 {
1080 *ppvSite = NULL;
1081 return E_FAIL;
1082 }
1083
1084 hr = IUnknown_QueryInterface(This->pUnknown, riid, (LPVOID*)&pUnknown);
1085 if (SUCCEEDED(hr))
1086 {
1087 IUnknown_AddRef(pUnknown);
1088 *ppvSite = pUnknown;
1089 return S_OK;
1090 }
1091
1092 *ppvSite = NULL;
1093 return hr;
1094 }
1095
1096 static HRESULT WINAPI ISF_NetConnect_IObjectWithSite_SetSite (IObjectWithSite * iface, IUnknown *pUnkSite)
1097 {
1098 IContextMenuImpl * This = impl_from_IObjectWithSite(iface);
1099
1100 if(!pUnkSite)
1101 {
1102 if (This->pUnknown)
1103 {
1104 IUnknown_Release(This->pUnknown);
1105 This->pUnknown = NULL;
1106 }
1107 }
1108 else
1109 {
1110 IUnknown_AddRef(pUnkSite);
1111 if (This->pUnknown)
1112 IUnknown_Release(This->pUnknown);
1113 This->pUnknown = pUnkSite;
1114 }
1115
1116 return S_OK;
1117 }
1118
1119
1120 static const IObjectWithSiteVtbl vt_ObjectWithSite =
1121 {
1122 ISF_NetConnect_IObjectWithSite_QueryInterface,
1123 ISF_NetConnect_IObjectWithSite_AddRef,
1124 ISF_NetConnect_IObjectWithSite_Release,
1125 ISF_NetConnect_IObjectWithSite_SetSite,
1126 ISF_NetConnect_IObjectWithSite_GetSite
1127 };
1128
1129 static HRESULT WINAPI ISF_NetConnect_IExtractIconW_QueryInterface (IExtractIconW * iface,
1130 REFIID iid, LPVOID * ppvObj)
1131 {
1132 IContextMenuImpl * This = impl_from_IExtractIcon(iface);
1133
1134 if (IsEqualIID(iid, &IID_IExtractIconW))
1135 {
1136 *ppvObj = (IUnknown*)&This->lpVtblExtractIconW;
1137 return S_OK;
1138 }
1139 return E_NOINTERFACE;
1140 }
1141
1142 /************************************************************************
1143 * ISF_NetConnect_IExtractIcon_AddRef
1144 */
1145 static ULONG WINAPI ISF_NetConnect_IExtractIconW_AddRef (IExtractIconW * iface)
1146 {
1147 IContextMenuImpl * This = impl_from_IExtractIcon(iface);
1148
1149 return IContextMenu2_AddRef((IContextMenu2*)This);
1150 }
1151
1152 /************************************************************************
1153 * ISF_NetConnect_IExtractIcon_Release
1154 */
1155 static ULONG WINAPI ISF_NetConnect_IExtractIconW_Release (IExtractIconW * iface)
1156 {
1157 IContextMenuImpl * This = impl_from_IExtractIcon(iface);
1158
1159 return IContextMenu_Release((IContextMenu*)This);
1160 }
1161
1162 /************************************************************************
1163 * ISF_NetConnect_IExtractIcon_GetIconLocation
1164 */
1165 static HRESULT WINAPI ISF_NetConnect_IExtractIconW_GetIconLocation(
1166 IExtractIconW * iface,
1167 UINT uFlags,
1168 LPWSTR szIconFile,
1169 UINT cchMax,
1170 int *piIndex,
1171 UINT *pwFlags)
1172 {
1173 VALUEStruct * val;
1174 NETCON_PROPERTIES * pProperties;
1175 IContextMenuImpl * This = impl_from_IExtractIcon(iface);
1176
1177 *pwFlags = 0;
1178 if (!GetModuleFileNameW(netshell_hInstance, szIconFile, cchMax))
1179 return E_FAIL;
1180
1181 val = _ILGetValueStruct(This->apidl);
1182 if (!val)
1183 return E_FAIL;
1184
1185 if (INetConnection_GetProperties(val->pItem, &pProperties) != NOERROR)
1186 return E_FAIL;
1187
1188 if (pProperties->Status == NCS_CONNECTED || pProperties->Status == NCS_CONNECTING)
1189 *piIndex = IDI_NET_IDLE;
1190 else
1191 *piIndex = IDI_NET_OFF;
1192
1193 NcFreeNetconProperties(pProperties);
1194
1195 return NOERROR;
1196 }
1197
1198 /************************************************************************
1199 * ISF_NetConnect_IExtractIcon_Extract
1200 */
1201 static HRESULT WINAPI ISF_NetConnect_IExtractIconW_Extract(
1202 IExtractIconW * iface,
1203 LPCWSTR pszFile,
1204 UINT nIconIndex,
1205 HICON *phiconLarge,
1206 HICON *phiconSmall,
1207 UINT nIconSize)
1208 {
1209 //IContextMenuImpl * This = impl_from_IExtractIcon(iface);
1210 if (nIconIndex == IDI_NET_IDLE)
1211 {
1212 *phiconLarge = LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_IDLE), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
1213 *phiconSmall = LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_IDLE), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
1214 return NOERROR;
1215 }
1216 else if (nIconIndex == IDI_NET_OFF)
1217 {
1218 *phiconLarge = LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_OFF), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
1219 *phiconSmall = LoadImage(netshell_hInstance, MAKEINTRESOURCE(IDI_NET_OFF), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
1220 return NOERROR;
1221 }
1222
1223 return S_FALSE;
1224 }
1225
1226 static const IExtractIconWVtbl vt_ExtractIconW =
1227 {
1228 ISF_NetConnect_IExtractIconW_QueryInterface,
1229 ISF_NetConnect_IExtractIconW_AddRef,
1230 ISF_NetConnect_IExtractIconW_Release,
1231 ISF_NetConnect_IExtractIconW_GetIconLocation,
1232 ISF_NetConnect_IExtractIconW_Extract
1233 };
1234
1235
1236
1237
1238
1239
1240
1241 /************************************************************************
1242 * ISF_NetConnect_PersistFolder2_QueryInterface
1243 */
1244 static HRESULT WINAPI ISF_NetConnect_PersistFolder2_QueryInterface (IPersistFolder2 * iface,
1245 REFIID iid, LPVOID * ppvObj)
1246 {
1247 IGenericSFImpl * This = impl_from_IPersistFolder2(iface);
1248
1249 return IShellFolder2_QueryInterface ((IShellFolder2*)This, iid, ppvObj);
1250 }
1251
1252 /************************************************************************
1253 * ISF_NetConnect_PersistFolder2_AddRef
1254 */
1255 static ULONG WINAPI ISF_NetConnect_PersistFolder2_AddRef (IPersistFolder2 * iface)
1256 {
1257 IGenericSFImpl * This = impl_from_IPersistFolder2(iface);
1258
1259 return IShellFolder2_AddRef((IShellFolder2*)This);
1260 }
1261
1262 /************************************************************************
1263 * ISF_NetConnect_PersistFolder2_Release
1264 */
1265 static ULONG WINAPI ISF_NetConnect_PersistFolder2_Release (IPersistFolder2 * iface)
1266 {
1267 IGenericSFImpl * This = impl_from_IPersistFolder2(iface);
1268
1269 return IShellFolder2_Release((IShellFolder2*)This);
1270 }
1271
1272 /************************************************************************
1273 * ISF_NetConnect_PersistFolder2_GetClassID
1274 */
1275 static HRESULT WINAPI ISF_NetConnect_PersistFolder2_GetClassID (
1276 IPersistFolder2 * iface, CLSID * lpClassId)
1277 {
1278 //IGenericSFImpl * This = impl_from_IPersistFolder2(iface);
1279
1280 if (!lpClassId)
1281 return E_POINTER;
1282
1283 *lpClassId = CLSID_NetworkConnections;
1284
1285 return S_OK;
1286 }
1287
1288 /************************************************************************
1289 * ISF_NetConnect_PersistFolder2_Initialize
1290 *
1291 * NOTES: it makes no sense to change the pidl
1292 */
1293 static HRESULT WINAPI ISF_NetConnect_PersistFolder2_Initialize (
1294 IPersistFolder2 * iface, LPCITEMIDLIST pidl)
1295 {
1296 IGenericSFImpl * This = impl_from_IPersistFolder2(iface);
1297
1298 SHFree(This->pidlRoot);
1299 This->pidlRoot = ILClone(pidl);
1300
1301 return S_OK;
1302 }
1303
1304 /**************************************************************************
1305 * ISF_NetConnect_PersistFolder2_GetCurFolder
1306 */
1307 static HRESULT WINAPI ISF_NetConnect_PersistFolder2_GetCurFolder (
1308 IPersistFolder2 * iface, LPITEMIDLIST * pidl)
1309 {
1310 IGenericSFImpl * This = impl_from_IPersistFolder2(iface);
1311
1312
1313 if (!pidl)
1314 return E_POINTER;
1315
1316 *pidl = ILClone (This->pidlRoot);
1317
1318 return S_OK;
1319 }
1320
1321 static const IPersistFolder2Vtbl vt_PersistFolder2 =
1322 {
1323 ISF_NetConnect_PersistFolder2_QueryInterface,
1324 ISF_NetConnect_PersistFolder2_AddRef,
1325 ISF_NetConnect_PersistFolder2_Release,
1326 ISF_NetConnect_PersistFolder2_GetClassID,
1327 ISF_NetConnect_PersistFolder2_Initialize,
1328 ISF_NetConnect_PersistFolder2_GetCurFolder
1329 };
1330
1331 /************************************************************************
1332 * ISF_NetConnect_ShellExecuteHookW_QueryInterface
1333 */
1334 static HRESULT WINAPI ISF_NetConnect_ShellExecuteHookW_QueryInterface (IShellExecuteHookW * iface,
1335 REFIID iid, LPVOID * ppvObj)
1336 {
1337 IGenericSFImpl * This = impl_from_IShellExecuteHookW(iface);
1338
1339 return IShellFolder2_QueryInterface ((IShellFolder2*)This, iid, ppvObj);
1340 }
1341
1342 /************************************************************************
1343 * ISF_NetConnect_ShellExecuteHookW_AddRef
1344 */
1345 static ULONG WINAPI ISF_NetConnect_ShellExecuteHookW_AddRef (IShellExecuteHookW * iface)
1346 {
1347 IGenericSFImpl * This = impl_from_IShellExecuteHookW(iface);
1348
1349 return IShellFolder2_AddRef((IShellFolder2*)This);
1350 }
1351
1352 /************************************************************************
1353 * ISF_NetConnect_PersistFolder2_Release
1354 */
1355 static ULONG WINAPI ISF_NetConnect_ShellExecuteHookW_Release (IShellExecuteHookW * iface)
1356 {
1357 IGenericSFImpl * This = impl_from_IShellExecuteHookW(iface);
1358
1359 return IShellFolder2_Release((IShellFolder2*)This);
1360 }
1361
1362
1363 /************************************************************************
1364 * ISF_NetConnect_ShellExecuteHookW_Execute
1365 */
1366 static HRESULT WINAPI ISF_NetConnect_ShellExecuteHookW_Execute (IShellExecuteHookW * iface,
1367 LPSHELLEXECUTEINFOW pei)
1368 {
1369 VALUEStruct * val;
1370 NETCON_PROPERTIES * pProperties;
1371 IGenericSFImpl * This = impl_from_IShellExecuteHookW(iface);
1372
1373 val = _ILGetValueStruct(ILFindLastID(pei->lpIDList));
1374 if (!val)
1375 return E_FAIL;
1376
1377 if (INetConnection_GetProperties((INetConnection*)val->pItem, &pProperties) != NOERROR)
1378 return E_FAIL;
1379
1380 if (pProperties->Status == NCS_CONNECTED)
1381 {
1382 NcFreeNetconProperties(pProperties);
1383 return ShowNetConnectionStatus(This->lpOleCmd, val->pItem, pei->hwnd);
1384 }
1385
1386 NcFreeNetconProperties(pProperties);
1387
1388 return S_OK;
1389 }
1390
1391
1392 static const IShellExecuteHookWVtbl vt_ShellExecuteHookW =
1393 {
1394 ISF_NetConnect_ShellExecuteHookW_QueryInterface,
1395 ISF_NetConnect_ShellExecuteHookW_AddRef,
1396 ISF_NetConnect_ShellExecuteHookW_Release,
1397 ISF_NetConnect_ShellExecuteHookW_Execute
1398 };
1399
1400 #if 0
1401 static const IPersistIDListVtbl vt_PersistIDList =
1402 {
1403 ISF_NetConnect_PersistIDList_QueryInterface,
1404 ISF_NetConnect_PersistIDList_AddRef,
1405 ISF_NetConnect_PersistIDList_Release,
1406 ISF_NetConnect_PersistIDList_GetClassID,
1407 ISF_NetConnect_PersistIDList_SetIDList,
1408 ISF_NetConnect_PersistIDList_GetIDList,
1409 };
1410 #endif
1411
1412 /************************************************************************
1413 * ISF_NetConnect_PersistFolder2_QueryInterface
1414 */
1415 static HRESULT WINAPI ISF_NetConnect_IQueryInfo_QueryInterface (IQueryInfo * iface,
1416 REFIID iid, LPVOID * ppvObj)
1417 {
1418 IContextMenuImpl * This = impl_from_IQueryInfo(iface);
1419
1420 if (IsEqualIID(iid, &IID_IQueryInfo))
1421 {
1422 *ppvObj = (IUnknown*)&This->lpVtblQueryInfo;
1423 return S_OK;
1424 }
1425
1426 return E_NOINTERFACE;
1427 }
1428
1429 /************************************************************************
1430 * ISF_NetConnect_PersistFolder2_AddRef
1431 */
1432 static ULONG WINAPI ISF_NetConnect_IQueryInfo_AddRef (IQueryInfo * iface)
1433 {
1434 IContextMenuImpl * This = impl_from_IQueryInfo(iface);
1435
1436 return IContextMenu2_AddRef((IContextMenu2*)This);
1437 }
1438
1439 /************************************************************************
1440 * ISF_NetConnect_PersistFolder2_Release
1441 */
1442 static ULONG WINAPI ISF_NetConnect_IQueryInfo_Release (IQueryInfo * iface)
1443 {
1444 IContextMenuImpl * This = impl_from_IQueryInfo(iface);
1445
1446 return IContextMenu_Release((IContextMenu*)This);
1447 }
1448
1449 /************************************************************************
1450 * ISF_NetConnect_PersistFolder2_GetClassID
1451 */
1452 static HRESULT WINAPI ISF_NetConnect_IQueryInfo_GetInfoFlags (
1453 IQueryInfo * iface, DWORD *pdwFlags)
1454 {
1455 *pdwFlags = 0;
1456
1457 return S_OK;
1458 }
1459
1460 /************************************************************************
1461 * ISF_NetConnect_PersistFolder2_Initialize
1462 *
1463 * NOTES: it makes no sense to change the pidl
1464 */
1465 static HRESULT WINAPI ISF_NetConnect_IQueryInfo_GetInfoTip (
1466 IQueryInfo * iface, DWORD dwFlags, WCHAR **ppwszTip)
1467 {
1468 // IGenericSFImpl * This = impl_from_IQueryInfo(iface);
1469
1470 *ppwszTip = NULL;
1471 return S_OK;
1472 }
1473
1474 static const IQueryInfoVtbl vt_QueryInfo =
1475 {
1476 ISF_NetConnect_IQueryInfo_QueryInterface,
1477 ISF_NetConnect_IQueryInfo_AddRef,
1478 ISF_NetConnect_IQueryInfo_Release,
1479 ISF_NetConnect_IQueryInfo_GetInfoTip,
1480 ISF_NetConnect_IQueryInfo_GetInfoFlags
1481 };
1482
1483 /**************************************************************************
1484 * ISF_NetConnect_Constructor
1485 */
1486 HRESULT WINAPI ISF_NetConnect_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
1487 {
1488 IGenericSFImpl *sf;
1489 HRESULT hr;
1490
1491 if (!ppv)
1492 return E_POINTER;
1493 if (pUnkOuter)
1494 return CLASS_E_NOAGGREGATION;
1495
1496 sf = (IGenericSFImpl *) CoTaskMemAlloc(sizeof (IGenericSFImpl));
1497 if (!sf)
1498 return E_OUTOFMEMORY;
1499
1500 sf->ref = 1;
1501 sf->lpVtbl = &vt_ShellFolder2;
1502 sf->lpVtblPersistFolder2 = &vt_PersistFolder2;
1503 sf->lpVtblShellExecuteHookW = &vt_ShellExecuteHookW;
1504
1505 hr = CoCreateInstance(&CLSID_LanConnectStatusUI, NULL, CLSCTX_INPROC_SERVER, &IID_IOleCommandTarget, (LPVOID*)&sf->lpOleCmd);
1506 if (FAILED(hr))
1507 sf->lpOleCmd = NULL;
1508 else
1509 {
1510 IOleCommandTarget_Exec(sf->lpOleCmd, &CGID_ShellServiceObject, 2, OLECMDEXECOPT_DODEFAULT, NULL, NULL);
1511 }
1512
1513 sf->pidlRoot = _ILCreateNetConnect(); /* my qualified pidl */
1514
1515 if (!SUCCEEDED (IShellFolder2_QueryInterface ((IShellFolder2*)sf, riid, ppv)))
1516 {
1517 IShellFolder2_Release((IShellFolder2*)sf);
1518 return E_NOINTERFACE;
1519 }
1520 return S_OK;
1521 }