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