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