[SHELLEXT][MYDOCS][INF] Add mydocs.dll and .mydocs file extension (#2624)
[reactos.git] / dll / shellext / netshell / connectmanager.cpp
1 /*
2 * PROJECT: ReactOS Shell
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: CNetConnectionManager class
5 * COPYRIGHT: Copyright 2008 Johannes Anderwald (johannes.anderwald@reactos.org)
6 */
7
8 #include "precomp.h"
9
10 VOID NormalizeOperStatus(MIB_IFROW *IfEntry, NETCON_PROPERTIES * Props);
11
12 /***************************************************************
13 * INetConnection Interface
14 */
15
16 HRESULT
17 WINAPI
18 CNetConnection::Initialize(PINetConnectionItem pItem)
19 {
20 m_Props = pItem->Props;
21 m_dwAdapterIndex = pItem->dwAdapterIndex;
22
23 if (pItem->Props.pszwName)
24 {
25 m_Props.pszwName = static_cast<PWSTR>(CoTaskMemAlloc((wcslen(pItem->Props.pszwName)+1)*sizeof(WCHAR)));
26 if (m_Props.pszwName)
27 wcscpy(m_Props.pszwName, pItem->Props.pszwName);
28 }
29
30 if (pItem->Props.pszwDeviceName)
31 {
32 m_Props.pszwDeviceName = static_cast<PWSTR>(CoTaskMemAlloc((wcslen(pItem->Props.pszwDeviceName)+1)*sizeof(WCHAR)));
33 if (m_Props.pszwDeviceName)
34 wcscpy(m_Props.pszwDeviceName, pItem->Props.pszwDeviceName);
35 }
36
37 return S_OK;
38 }
39
40 CNetConnection::~CNetConnection()
41 {
42 CoTaskMemFree(m_Props.pszwName);
43 CoTaskMemFree(m_Props.pszwDeviceName);
44 }
45
46 HRESULT
47 WINAPI
48 CNetConnection::Connect()
49 {
50 return E_NOTIMPL;
51 }
52
53 BOOL
54 FindNetworkAdapter(HDEVINFO hInfo, SP_DEVINFO_DATA *pDevInfo, LPWSTR pGuid)
55 {
56 DWORD dwIndex, dwSize;
57 HKEY hSubKey;
58 WCHAR szNetCfg[50];
59 WCHAR szDetail[200] = L"SYSTEM\\CurrentControlSet\\Control\\Class\\";
60
61 dwIndex = 0;
62 do
63 {
64 ZeroMemory(pDevInfo, sizeof(SP_DEVINFO_DATA));
65 pDevInfo->cbSize = sizeof(SP_DEVINFO_DATA);
66
67 /* get device info */
68 if (!SetupDiEnumDeviceInfo(hInfo, dwIndex++, pDevInfo))
69 break;
70
71 /* get device software registry path */
72 if (!SetupDiGetDeviceRegistryPropertyW(hInfo, pDevInfo, SPDRP_DRIVER, NULL, (LPBYTE)&szDetail[39], sizeof(szDetail)/sizeof(WCHAR) - 40, &dwSize))
73 break;
74
75 /* open device registry key */
76 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szDetail, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS)
77 break;
78
79 /* query NetCfgInstanceId for current device */
80 dwSize = sizeof(szNetCfg);
81 if (RegQueryValueExW(hSubKey, L"NetCfgInstanceId", NULL, NULL, (LPBYTE)szNetCfg, &dwSize) != ERROR_SUCCESS)
82 {
83 RegCloseKey(hSubKey);
84 break;
85 }
86 RegCloseKey(hSubKey);
87 if (!_wcsicmp(pGuid, szNetCfg))
88 {
89 return TRUE;
90 }
91 } while (TRUE);
92
93 return FALSE;
94 }
95
96 HRESULT
97 WINAPI
98 CNetConnection::Disconnect()
99 {
100 HKEY hKey;
101 NETCON_PROPERTIES * pProperties;
102 LPOLESTR pDisplayName;
103 WCHAR szPath[200];
104 DWORD dwSize, dwType;
105 LPWSTR pPnp;
106 HDEVINFO hInfo;
107 SP_DEVINFO_DATA DevInfo;
108 SP_PROPCHANGE_PARAMS PropChangeParams;
109 HRESULT hr;
110
111 hr = GetProperties(&pProperties);
112 if (FAILED_UNEXPECTEDLY(hr))
113 return hr;
114
115 hInfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT );
116 if (!hInfo)
117 {
118 NcFreeNetconProperties(pProperties);
119 return E_FAIL;
120 }
121
122 if (FAILED(StringFromCLSID((CLSID)pProperties->guidId, &pDisplayName)))
123 {
124 NcFreeNetconProperties(pProperties);
125 SetupDiDestroyDeviceInfoList(hInfo);
126 return E_FAIL;
127 }
128 NcFreeNetconProperties(pProperties);
129
130 if (FindNetworkAdapter(hInfo, &DevInfo, pDisplayName))
131 {
132 PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
133 PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; //;
134 PropChangeParams.StateChange = DICS_DISABLE;
135 PropChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;
136 PropChangeParams.HwProfile = 0;
137
138 if (SetupDiSetClassInstallParams(hInfo, &DevInfo, &PropChangeParams.ClassInstallHeader, sizeof(SP_PROPCHANGE_PARAMS)))
139 {
140 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hInfo, &DevInfo);
141 }
142 }
143 SetupDiDestroyDeviceInfoList(hInfo);
144
145 swprintf(szPath, L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", pDisplayName);
146 CoTaskMemFree(pDisplayName);
147
148 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
149 return E_FAIL;
150
151 dwSize = 0;
152 if (RegQueryValueExW(hKey, L"PnpInstanceID", NULL, &dwType, NULL, &dwSize) != ERROR_SUCCESS || dwType != REG_SZ)
153 {
154 RegCloseKey(hKey);
155 return E_FAIL;
156 }
157
158 pPnp = static_cast<PWSTR>(CoTaskMemAlloc(dwSize));
159 if (!pPnp)
160 {
161 RegCloseKey(hKey);
162 return E_FAIL;
163 }
164
165 if (RegQueryValueExW(hKey, L"PnpInstanceID", NULL, &dwType, (LPBYTE)pPnp, &dwSize) != ERROR_SUCCESS)
166 {
167 CoTaskMemFree(pPnp);
168 RegCloseKey(hKey);
169 return E_FAIL;
170 }
171 RegCloseKey(hKey);
172
173 swprintf(szPath, L"System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Enum\\%s", pPnp);
174 CoTaskMemFree(pPnp);
175
176 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szPath, 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
177 return E_FAIL;
178
179 dwSize = 1; /* enable = 0, disable = 1 */
180 RegSetValueExW(hKey, L"CSConfigFlags", 0, REG_DWORD, (LPBYTE)&dwSize, sizeof(DWORD));
181 RegCloseKey(hKey);
182
183 return S_OK;
184 }
185
186 HRESULT
187 WINAPI
188 CNetConnection::Delete()
189 {
190 return E_NOTIMPL;
191 }
192
193 HRESULT
194 WINAPI
195 CNetConnection::Duplicate(
196 LPCWSTR pszwDuplicateName,
197 INetConnection **ppCon)
198 {
199 return E_NOTIMPL;
200 }
201
202 HRESULT
203 WINAPI
204 CNetConnection::GetProperties(NETCON_PROPERTIES **ppProps)
205 {
206 MIB_IFROW IfEntry;
207 HKEY hKey;
208 LPOLESTR pStr;
209 WCHAR szName[140];
210 DWORD dwShowIcon, dwNotifyDisconnect, dwType, dwSize;
211 NETCON_PROPERTIES * pProperties;
212 HRESULT hr;
213
214 if (!ppProps)
215 return E_POINTER;
216
217 pProperties = static_cast<NETCON_PROPERTIES*>(CoTaskMemAlloc(sizeof(NETCON_PROPERTIES)));
218 if (!pProperties)
219 return E_OUTOFMEMORY;
220
221 CopyMemory(pProperties, &m_Props, sizeof(NETCON_PROPERTIES));
222 pProperties->pszwName = NULL;
223
224 if (m_Props.pszwDeviceName)
225 {
226 pProperties->pszwDeviceName = static_cast<LPWSTR>(CoTaskMemAlloc((wcslen(m_Props.pszwDeviceName)+1)*sizeof(WCHAR)));
227 if (pProperties->pszwDeviceName)
228 wcscpy(pProperties->pszwDeviceName, m_Props.pszwDeviceName);
229 }
230
231 *ppProps = pProperties;
232
233 /* get updated adapter characteristics */
234 ZeroMemory(&IfEntry, sizeof(IfEntry));
235 IfEntry.dwIndex = m_dwAdapterIndex;
236 if (GetIfEntry(&IfEntry) != NO_ERROR)
237 return NOERROR;
238
239 NormalizeOperStatus(&IfEntry, pProperties);
240
241
242 hr = StringFromCLSID((CLSID)m_Props.guidId, &pStr);
243 if (SUCCEEDED(hr))
244 {
245 wcscpy(szName, L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\");
246 wcscat(szName, pStr);
247 wcscat(szName, L"\\Connection");
248
249 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
250 {
251 dwSize = sizeof(dwShowIcon);
252 if (RegQueryValueExW(hKey, L"ShowIcon", NULL, &dwType, (LPBYTE)&dwShowIcon, &dwSize) == ERROR_SUCCESS && dwType == REG_DWORD)
253 {
254 if (dwShowIcon)
255 pProperties->dwCharacter |= NCCF_SHOW_ICON;
256 else
257 pProperties->dwCharacter &= ~NCCF_SHOW_ICON;
258 }
259
260 dwSize = sizeof(dwNotifyDisconnect);
261 if (RegQueryValueExW(hKey, L"IpCheckingEnabled", NULL, &dwType, (LPBYTE)&dwNotifyDisconnect, &dwSize) == ERROR_SUCCESS && dwType == REG_DWORD)
262 {
263 if (dwNotifyDisconnect)
264 pProperties->dwCharacter |= NCCF_NOTIFY_DISCONNECTED;
265 else
266 pProperties->dwCharacter &= ~NCCF_NOTIFY_DISCONNECTED;
267 }
268
269 dwSize = sizeof(szName);
270 if (RegQueryValueExW(hKey, L"Name", NULL, &dwType, (LPBYTE)szName, &dwSize) == ERROR_SUCCESS)
271 {
272 /* use updated name */
273 dwSize = wcslen(szName) + 1;
274 pProperties->pszwName = static_cast<PWSTR>(CoTaskMemAlloc(dwSize * sizeof(WCHAR)));
275 if (pProperties->pszwName)
276 CopyMemory(pProperties->pszwName, szName, dwSize * sizeof(WCHAR));
277 }
278 else
279 {
280 /* use cached name */
281 if (m_Props.pszwName)
282 {
283 pProperties->pszwName = static_cast<PWSTR>(CoTaskMemAlloc((wcslen(m_Props.pszwName)+1)*sizeof(WCHAR)));
284 if (pProperties->pszwName)
285 wcscpy(pProperties->pszwName, m_Props.pszwName);
286 }
287 }
288 RegCloseKey(hKey);
289 }
290 CoTaskMemFree(pStr);
291 }
292
293 /* Enable 'Rename' and 'Delete' for Adminstrators only */
294 if (IsUserAdmin())
295 {
296 pProperties->dwCharacter |= NCCF_ALLOW_RENAME;
297
298 /* Virtual network interfaces can be deleted */
299 if (IfEntry.dwType == IF_TYPE_TUNNEL)
300 {
301 pProperties->dwCharacter |= NCCF_ALLOW_REMOVAL;
302 }
303 }
304 else
305 {
306 pProperties->dwCharacter &= ~(NCCF_ALLOW_RENAME | NCCF_ALLOW_REMOVAL);
307 }
308
309 return S_OK;
310 }
311
312 HRESULT
313 WINAPI
314 CNetConnection::GetUiObjectClassId(CLSID *pclsid)
315 {
316 if (m_Props.MediaType == NCM_LAN)
317 {
318 CopyMemory(pclsid, &CLSID_LanConnectionUi, sizeof(CLSID));
319 return S_OK;
320 }
321
322 return E_NOTIMPL;
323 }
324
325 HRESULT
326 WINAPI
327 CNetConnection::Rename(LPCWSTR pszwDuplicateName)
328 {
329 WCHAR szName[140];
330 LPOLESTR pStr;
331 DWORD dwSize;
332 HKEY hKey;
333 HRESULT hr;
334
335 if (pszwDuplicateName == NULL || wcslen(pszwDuplicateName) == 0)
336 return S_OK;
337
338 if (m_Props.pszwName)
339 {
340 CoTaskMemFree(m_Props.pszwName);
341 m_Props.pszwName = NULL;
342 }
343
344 dwSize = (wcslen(pszwDuplicateName) + 1) * sizeof(WCHAR);
345 m_Props.pszwName = static_cast<PWSTR>(CoTaskMemAlloc(dwSize));
346 if (m_Props.pszwName == NULL)
347 return E_OUTOFMEMORY;
348
349 wcscpy(m_Props.pszwName, pszwDuplicateName);
350
351 hr = StringFromCLSID((CLSID)m_Props.guidId, &pStr);
352 if (SUCCEEDED(hr))
353 {
354 wcscpy(szName, L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\");
355 wcscat(szName, pStr);
356 wcscat(szName, L"\\Connection");
357
358 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_WRITE, &hKey) == ERROR_SUCCESS)
359 {
360 RegSetValueExW(hKey, L"Name", NULL, REG_SZ, (LPBYTE)m_Props.pszwName, dwSize);
361 RegCloseKey(hKey);
362 }
363
364 CoTaskMemFree(pStr);
365 }
366
367 return hr;
368 }
369
370 HRESULT WINAPI CNetConnection_CreateInstance(PINetConnectionItem pItem, REFIID riid, LPVOID * ppv)
371 {
372 return ShellObjectCreatorInit<CNetConnection>(pItem, riid, ppv);
373 }
374
375
376
377 CNetConnectionManager::CNetConnectionManager() :
378 m_pHead(NULL),
379 m_pCurrent(NULL)
380 {
381 }
382
383 HRESULT
384 WINAPI
385 CNetConnectionManager::EnumConnections(
386 NETCONMGR_ENUM_FLAGS Flags,
387 IEnumNetConnection **ppEnum)
388 {
389 TRACE("EnumConnections\n");
390
391 if (!ppEnum)
392 return E_POINTER;
393
394 if (Flags != NCME_DEFAULT)
395 return E_FAIL;
396
397 *ppEnum = static_cast<IEnumNetConnection*>(this);
398 AddRef();
399 return S_OK;
400 }
401
402 /***************************************************************
403 * IEnumNetConnection Interface
404 */
405
406 HRESULT
407 WINAPI
408 CNetConnectionManager::Next(
409 ULONG celt,
410 INetConnection **rgelt,
411 ULONG *pceltFetched)
412 {
413 HRESULT hr;
414
415 if (!pceltFetched || !rgelt)
416 return E_POINTER;
417
418 if (celt != 1)
419 return E_FAIL;
420
421 if (!m_pCurrent)
422 return S_FALSE;
423
424 hr = CNetConnection_CreateInstance(m_pCurrent, IID_PPV_ARG(INetConnection, rgelt));
425 m_pCurrent = m_pCurrent->Next;
426
427 return hr;
428 }
429
430 HRESULT
431 WINAPI
432 CNetConnectionManager::Skip(ULONG celt)
433 {
434 while (m_pCurrent && celt-- > 0)
435 m_pCurrent = m_pCurrent->Next;
436
437 if (celt)
438 return S_FALSE;
439 else
440 return S_OK;
441
442 }
443
444 HRESULT
445 WINAPI
446 CNetConnectionManager::Reset()
447 {
448 m_pCurrent = m_pHead;
449 return S_OK;
450 }
451
452 HRESULT
453 WINAPI
454 CNetConnectionManager::Clone(IEnumNetConnection **ppenum)
455 {
456 return E_NOTIMPL;
457 }
458
459 BOOL
460 GetAdapterIndexFromNetCfgInstanceId(PIP_ADAPTER_INFO pAdapterInfo, LPWSTR szNetCfg, PDWORD pIndex)
461 {
462 WCHAR szBuffer[50];
463 IP_ADAPTER_INFO * pCurrentAdapter;
464
465 pCurrentAdapter = pAdapterInfo;
466 while (pCurrentAdapter)
467 {
468 szBuffer[0] = L'\0';
469 if (MultiByteToWideChar(CP_ACP, 0, pCurrentAdapter->AdapterName, -1, szBuffer, sizeof(szBuffer)/sizeof(szBuffer[0])))
470 {
471 szBuffer[(sizeof(szBuffer)/sizeof(WCHAR))-1] = L'\0';
472 }
473 if (!_wcsicmp(szBuffer, szNetCfg))
474 {
475 *pIndex = pCurrentAdapter->Index;
476 return TRUE;
477 }
478 pCurrentAdapter = pCurrentAdapter->Next;
479 }
480 return FALSE;
481 }
482
483 VOID
484 NormalizeOperStatus(
485 MIB_IFROW *IfEntry,
486 NETCON_PROPERTIES * Props)
487 {
488 switch (IfEntry->dwOperStatus)
489 {
490 case MIB_IF_OPER_STATUS_NON_OPERATIONAL:
491 Props->Status = NCS_HARDWARE_DISABLED;
492 break;
493 case MIB_IF_OPER_STATUS_UNREACHABLE:
494 Props->Status = NCS_DISCONNECTED;
495 break;
496 case MIB_IF_OPER_STATUS_DISCONNECTED:
497 Props->Status = NCS_MEDIA_DISCONNECTED;
498 break;
499 case MIB_IF_OPER_STATUS_CONNECTING:
500 Props->Status = NCS_CONNECTING;
501 break;
502 case MIB_IF_OPER_STATUS_CONNECTED:
503 Props->Status = NCS_CONNECTED;
504 break;
505 case MIB_IF_OPER_STATUS_OPERATIONAL:
506 Props->Status = NCS_CONNECTED;
507 break;
508 default:
509 break;
510 }
511 }
512
513 HRESULT
514 CNetConnectionManager::EnumerateINetConnections()
515 {
516 DWORD dwSize, dwResult, dwIndex, dwAdapterIndex, dwShowIcon, dwNotifyDisconnect;
517 MIB_IFTABLE *pIfTable;
518 MIB_IFROW IfEntry;
519 IP_ADAPTER_INFO * pAdapterInfo;
520 HDEVINFO hInfo;
521 SP_DEVINFO_DATA DevInfo;
522 HKEY hSubKey;
523 WCHAR szNetCfg[50];
524 WCHAR szAdapterNetCfg[50];
525 WCHAR szDetail[200] = L"SYSTEM\\CurrentControlSet\\Control\\Class\\";
526 WCHAR szName[130] = L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
527 PINetConnectionItem pCurrent = NULL;
528
529 /* get the IfTable */
530 dwSize = 0;
531 if (GetIfTable(NULL, &dwSize, TRUE) != ERROR_INSUFFICIENT_BUFFER)
532 return E_FAIL;
533
534 pIfTable = static_cast<PMIB_IFTABLE>(CoTaskMemAlloc(dwSize));
535 if (!pIfTable)
536 return E_OUTOFMEMORY;
537
538 dwResult = GetIfTable(pIfTable, &dwSize, TRUE);
539 if (dwResult != NO_ERROR)
540 {
541 CoTaskMemFree(pIfTable);
542 return HRESULT_FROM_WIN32(dwResult);
543 }
544
545 dwSize = 0;
546 dwResult = GetAdaptersInfo(NULL, &dwSize);
547 if (dwResult!= ERROR_BUFFER_OVERFLOW)
548 {
549 CoTaskMemFree(pIfTable);
550 return HRESULT_FROM_WIN32(dwResult);
551 }
552
553 pAdapterInfo = static_cast<PIP_ADAPTER_INFO>(CoTaskMemAlloc(dwSize));
554 if (!pAdapterInfo)
555 {
556 CoTaskMemFree(pIfTable);
557 return E_OUTOFMEMORY;
558 }
559
560 dwResult = GetAdaptersInfo(pAdapterInfo, &dwSize);
561 if (dwResult != NO_ERROR)
562 {
563 CoTaskMemFree(pIfTable);
564 CoTaskMemFree(pAdapterInfo);
565 return HRESULT_FROM_WIN32(dwResult);
566 }
567
568 hInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT );
569 if (!hInfo)
570 {
571 CoTaskMemFree(pIfTable);
572 CoTaskMemFree(pAdapterInfo);
573 return E_FAIL;
574 }
575
576 dwIndex = 0;
577 do
578 {
579 ZeroMemory(&DevInfo, sizeof(SP_DEVINFO_DATA));
580 DevInfo.cbSize = sizeof(DevInfo);
581
582 /* get device info */
583 if (!SetupDiEnumDeviceInfo(hInfo, dwIndex++, &DevInfo))
584 break;
585
586 /* get device software registry path */
587 if (!SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_DRIVER, NULL, (LPBYTE)&szDetail[39], sizeof(szDetail)/sizeof(WCHAR) - 40, &dwSize))
588 break;
589
590 /* open device registry key */
591 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szDetail, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS)
592 break;
593
594 /* query NetCfgInstanceId for current device */
595 dwSize = sizeof(szNetCfg);
596 if (RegQueryValueExW(hSubKey, L"NetCfgInstanceId", NULL, NULL, (LPBYTE)szNetCfg, &dwSize) != ERROR_SUCCESS)
597 {
598 RegCloseKey(hSubKey);
599 break;
600 }
601 RegCloseKey(hSubKey);
602
603 /* get the current adapter index from NetCfgInstanceId */
604 if (!GetAdapterIndexFromNetCfgInstanceId(pAdapterInfo, szNetCfg, &dwAdapterIndex))
605 continue;
606
607 /* get detailed adapter info */
608 ZeroMemory(&IfEntry, sizeof(IfEntry));
609 IfEntry.dwIndex = dwAdapterIndex;
610 if (GetIfEntry(&IfEntry) != NO_ERROR)
611 break;
612
613 /* allocate new INetConnectionItem */
614 PINetConnectionItem pNew = static_cast<PINetConnectionItem>(CoTaskMemAlloc(sizeof(INetConnectionItem)));
615 if (!pNew)
616 break;
617
618 ZeroMemory(pNew, sizeof(INetConnectionItem));
619 pNew->dwAdapterIndex = dwAdapterIndex;
620 /* store NetCfgInstanceId */
621 CLSIDFromString(szNetCfg, &pNew->Props.guidId);
622 NormalizeOperStatus(&IfEntry, &pNew->Props);
623
624 switch (IfEntry.dwType)
625 {
626 case IF_TYPE_ETHERNET_CSMACD:
627 pNew->Props.MediaType = NCM_LAN;
628 break;
629 case IF_TYPE_IEEE80211:
630 pNew->Props.MediaType = NCM_SHAREDACCESSHOST_RAS;
631 break;
632 default:
633 break;
634 }
635 /* open network connections details */
636 wcscpy(&szName[80], szNetCfg);
637 wcscpy(&szName[118], L"\\Connection");
638
639 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS)
640 {
641 /* retrieve name of connection */
642 dwSize = sizeof(szAdapterNetCfg);
643 if (RegQueryValueExW(hSubKey, L"Name", NULL, NULL, (LPBYTE)szAdapterNetCfg, &dwSize) == ERROR_SUCCESS)
644 {
645 pNew->Props.pszwName = static_cast<PWSTR>(CoTaskMemAlloc((wcslen(szAdapterNetCfg)+1) * sizeof(WCHAR)));
646 if (pNew->Props.pszwName)
647 wcscpy(pNew->Props.pszwName, szAdapterNetCfg);
648 }
649 dwSize = sizeof(dwShowIcon);
650 if (RegQueryValueExW(hSubKey, L"ShowIcon", NULL, NULL, (LPBYTE)&dwShowIcon, &dwSize) == ERROR_SUCCESS)
651 {
652 if (dwShowIcon)
653 pNew->Props.dwCharacter |= NCCF_SHOW_ICON;
654 }
655 dwSize = sizeof(dwNotifyDisconnect);
656 if (RegQueryValueExW(hSubKey, L"IpCheckingEnabled", NULL, NULL, (LPBYTE)&dwNotifyDisconnect, &dwSize) == ERROR_SUCCESS)
657 {
658 if (dwNotifyDisconnect)
659 pNew->Props.dwCharacter |= NCCF_NOTIFY_DISCONNECTED;
660 }
661 RegCloseKey(hSubKey);
662 }
663
664 /* Get the adapter device description */
665 dwSize = 0;
666 SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_DEVICEDESC, NULL, NULL, 0, &dwSize);
667 if (dwSize != 0)
668 {
669 pNew->Props.pszwDeviceName = static_cast<PWSTR>(CoTaskMemAlloc(dwSize));
670 if (pNew->Props.pszwDeviceName)
671 SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_DEVICEDESC, NULL, (PBYTE)pNew->Props.pszwDeviceName, dwSize, &dwSize);
672 }
673
674 if (pCurrent)
675 pCurrent->Next = pNew;
676 else
677 m_pHead = pNew;
678
679 pCurrent = pNew;
680 } while (TRUE);
681
682 CoTaskMemFree(pIfTable);
683 CoTaskMemFree(pAdapterInfo);
684 SetupDiDestroyDeviceInfoList(hInfo);
685
686 m_pCurrent = m_pHead;
687 return (m_pHead != NULL ? S_OK : S_FALSE);
688 }
689
690 HRESULT CNetConnectionManager::Initialize()
691 {
692 HRESULT hr = EnumerateINetConnections();
693 if (FAILED_UNEXPECTEDLY(hr))
694 {
695 /* If something went wrong during the enumeration print an error don't enumerate anything */
696 m_pCurrent = m_pHead = NULL;
697 return S_FALSE;
698 }
699 return S_OK;
700 }
701
702 HRESULT WINAPI CNetConnectionManager_CreateInstance(REFIID riid, LPVOID * ppv)
703 {
704 #if USE_CUSTOM_CONMGR
705 return ShellObjectCreatorInit<CNetConnectionManager>(riid, ppv);
706 #else
707 return CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_ALL, riid, ppv);
708 #endif
709 }